ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/cmd/ip/ppp/pppclient.b/
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);
}