summaryrefslogtreecommitdiff
path: root/appl/cmd/ip/ppp/pppclient.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/ip/ppp/pppclient.b')
-rw-r--r--appl/cmd/ip/ppp/pppclient.b216
1 files changed, 216 insertions, 0 deletions
diff --git a/appl/cmd/ip/ppp/pppclient.b b/appl/cmd/ip/ppp/pppclient.b
new file mode 100644
index 00000000..be321b59
--- /dev/null
+++ b/appl/cmd/ip/ppp/pppclient.b
@@ -0,0 +1,216 @@
+implement PPPClient;
+
+
+include "sys.m";
+ sys : Sys;
+include "draw.m";
+
+include "lock.m";
+include "modem.m";
+include "script.m";
+
+include "pppclient.m";
+
+include "translate.m";
+ translate : Translate;
+ Dict : import translate;
+ dict : ref Dict;
+
+#
+# Globals (these will have to be removed if we are going multithreaded)
+#
+
+pid := 0;
+modeminfo: ref Modem->ModemInfo;
+pppdir: string;
+
+ppplog(log: chan of int, errfile: string, pidc: chan of int)
+{
+ pidc <-= sys->pctl(0, nil); # set reset pid to our pid
+ src := sys->open(errfile, Sys->OREAD);
+ if (src == nil)
+ raise sys->sprint("fail: Couldn't open %s: %r", errfile);
+
+ LOGBUFMAX: con 1024;
+ buf := array[LOGBUFMAX] of byte;
+ connected := 0;
+
+ while ((count := sys->read(src, buf, LOGBUFMAX)) > 0) {
+ (n, toklist) := sys->tokenize(string buf[:count],"\n");
+ for (;toklist != nil;toklist = tl toklist) {
+ case hd toklist {
+ "no error" =>
+ log <-= s_SuccessPPP;
+ lasterror = nil;
+ connected = 1;
+ "permission denied" =>
+ lasterror = X("Username or Password Incorrect");
+ log <-= s_Error;
+ "write to hungup channel" =>
+ lasterror = X("Remote Host Hung Up");
+ log <-= s_Error;
+ * =>
+ lasterror = X(hd toklist);
+ log <-= s_Error;
+ }
+ }
+ }
+ if(count == 0 && connected && lasterror == nil){ # should change ip/pppmedium.c instead?
+ lasterror = X("Lost Connection");
+ log <-= s_Error;
+ }
+}
+
+startppp(logchan: chan of int, pppinfo: ref PPPInfo)
+{
+ ifd := sys->open("/net/ipifc/clone", Sys->ORDWR);
+ if (ifd == nil)
+ raise "fail: Couldn't open /net/ipifc/clone";
+
+ buf := array[32] of byte;
+ n := sys->read(ifd, buf, len buf);
+ if(n <= 0)
+ raise "fail: can't read from /net/ipifc/clone";
+
+ pppdir = "/net/ipifc/" + string buf[0:n];
+ pidc := chan of int;
+ spawn ppplog(logchan, pppdir + "/err", pidc);
+ pid = <-pidc;
+ logchan <-= s_StartPPP;
+
+ if (pppinfo.ipaddr == nil)
+ pppinfo.ipaddr = "-";
+# if (pppinfo.ipmask == nil)
+# pppinfo.ipmask = "255.255.255.255";
+ if (pppinfo.peeraddr == nil)
+ pppinfo.peeraddr = "-";
+ if (pppinfo.maxmtu == nil)
+ pppinfo.maxmtu = "512";
+ if (pppinfo.username == nil)
+ pppinfo.username = "-";
+ if (pppinfo.password == nil)
+ pppinfo.password = "-";
+ framing := "1";
+
+ ifc := "bind ppp "+modeminfo.path+" "+ pppinfo.ipaddr+" "+pppinfo.peeraddr+" "+pppinfo.maxmtu
+ +" "+framing+" "+pppinfo.username+" "+pppinfo.password;
+
+ # send the add command
+ if (sys->fprint(ifd, "%s", ifc) < 0) {
+ sys->print("pppclient: couldn't write %s/ctl: %r\n", pppdir);
+ raise "fail: Couldn't write /net/ipifc";
+ return;
+ }
+}
+
+connect(mi: ref Modem->ModemInfo, number: string,
+ scriptinfo: ref Script->ScriptInfo, pppinfo: ref PPPInfo, logchan: chan of int)
+{
+ sys = load Sys Sys->PATH;
+
+ translate = load Translate Translate->PATH;
+ if (translate != nil) {
+ translate->init();
+ dictname := translate->mkdictname("", "pppclient");
+ (dict, nil) = translate->opendict(dictname);
+ }
+ if (pid != 0) # yikes we are already running
+ reset();
+
+ # create a new process group
+ pid = sys->pctl( Sys->NEWPGRP, nil);
+
+ {
+ logchan <-= s_Initialized;
+
+ # open & init the modem
+ modeminfo = mi;
+ modem := load Modem Modem->PATH;
+ if (modem == nil) {
+ raise "fail: Couldn't load modem module";
+ return;
+ }
+
+ modemdev := modem->init(modeminfo);
+ logchan <-= s_StartModem;
+ modem->dial(modemdev, number);
+ logchan <-= s_SuccessModem;
+
+ # if script
+ if (scriptinfo != nil) {
+ script := load Script Script->PATH;
+ if (script == nil) {
+ raise "fail: Couldn't load script module";
+ return;
+ }
+ logchan <-= s_StartScript;
+ script->execute(modem, modemdev, scriptinfo);
+ logchan <-= s_SuccessScript;
+ }
+
+ mc := modem->close(modemdev); # keep connection open for ppp mode
+ modemdev = nil;
+ modem = nil; # unload modem module
+
+ # if ppp
+ if (pppinfo != nil)
+ startppp(logchan, pppinfo);
+ else
+ logchan <-= s_Done;
+ }
+ exception e{
+ "fail*" =>
+ lasterror = e;
+ sys->print("PPPclient: fatal exception: %s\n", e);
+ logchan <-= s_Error;
+ kill(pid, "killgrp");
+ exit;
+ }
+}
+
+reset()
+{
+ sys->print("reset...");
+ if(pid != 0){
+ kill(pid, "killgrp");
+ pid = 0;
+ }
+
+ if(pppdir != nil){ # shut down the PPP link
+ fd := sys->open(pppdir + "/ctl", Sys->OWRITE);
+ if(fd == nil || sys->fprint(fd, "unbind") < 0)
+ sys->print("pppclient: can't unbind: %r\n");
+ fd = nil;
+ pppdir = nil;
+ }
+
+ modem := load Modem Modem->PATH;
+ if (modem == nil) {
+ raise "fail: Couldn't load modem module";
+ return;
+ }
+ modemdev := modem->init(modeminfo);
+ if(modemdev != nil)
+ modem->onhook(modemdev);
+ modem = nil;
+
+ # clear error buffer
+ lasterror = nil;
+}
+
+kill(pid: int, msg: string)
+{
+ a := array of byte msg;
+ fd := sys->open("#p/"+string pid+"/ctl", Sys->OWRITE);
+ if(fd == nil || sys->write(fd, a, len a) < 0)
+ sys->print("pppclient: can't %s %d: %r\n", msg, pid);
+}
+
+# Translate a string
+
+X(s : string) : string
+{
+ if (dict== nil) return s;
+ return dict.xlate(s);
+}
+