diff options
Diffstat (limited to 'appl/cmd/ip/ppp/script.b')
| -rw-r--r-- | appl/cmd/ip/ppp/script.b | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/appl/cmd/ip/ppp/script.b b/appl/cmd/ip/ppp/script.b new file mode 100644 index 00000000..8be184a4 --- /dev/null +++ b/appl/cmd/ip/ppp/script.b @@ -0,0 +1,168 @@ +implement Script; + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "string.m"; + str: String; + +include "lock.m"; +include "modem.m"; + modem: Modem; + +include "script.m"; + +delim: con "-"; # expect-send delimiter +BUFSIZE: con (1024 * 32); + +execute( modmod: Modem, m: ref Modem->Device, scriptinfo: ref ScriptInfo ) +{ + sys= load Sys Sys->PATH; + str= load String String->PATH; + if (str == nil) { + raise "fail: couldn't load string module"; + return; + } + modem = modmod; + + if (scriptinfo.path != nil) { + sys->print("Executing Script %s\n",scriptinfo.path); + # load the script + scriptinfo.content = scriptload(scriptinfo.path); + } else { + sys->print("Executing Inline Script\n"); + } + + # Check for timeout variable + + if (scriptinfo.timeout == 0) + scriptinfo.timeout = 20; + + tend := sys->millisec() + 1000*scriptinfo.timeout; + + conv := scriptinfo.content; + + while (conv != nil) { + e, s: string = nil; + p := hd conv; + conv = tl conv; + if (len p == 0) + continue; + sys->print("script: %s\n",p); + if (p[0] == '-') { # just send + if (len p == 1) + continue; + s = p[1:]; + } else { + (n, esl) := sys->tokenize(p, delim); + if (n > 0) { + e = hd esl; + esl = tl esl; + if (n > 1) + s = hd esl; + } + } + if (e != nil) { + if (match(m, special(e,scriptinfo), tend-sys->millisec()) == 0) { + sys->print("script: match failed\n"); + raise "fail: Script Failed"; + return; + } + } + if (s != nil) + modem->send(m, special(s, scriptinfo)); + } + + sys->print("script: done!\n"); +} + +match(m: ref Modem->Device, s: string, timo: int): int +{ + for(;;) { + c := modem->getc(m, timo); + if (c == '\r') + c = '\n'; + sys->print("%c",c); + if (c == 0) + return 0; + head: + while(c == s[0]) { + i := 1; + while(i < len s) { + c = modem->getc(m, timo); + if (c == '\r') + c = '\n'; + sys->print("%c",c); + if(c == 0) + return 0; + if(c != s[i]) + continue head; + i++; + } + return 1; + } + if(c == '~') + return 1; # assume PPP for now + } +} + +# +# Expand special script sequences +# +special(s: string, scriptinfo: ref ScriptInfo ): string +{ + if (s == "$username") # special variable + s = scriptinfo.username; + else if (s == "$password") + s = scriptinfo.password; + + return deparse(s); +} + +deparse(s : string) : string +{ + r: string = ""; + for(i:=0; i < len s; i++) { + c := s[i]; + if (c == '\\' && i+1 < len s) { + c = s[++i]; + case c { + 't' => c = '\t'; + 'n' => c = '\n'; + 'r' => c = '\r'; + 'b' => c = '\b'; + 'a' => c = '\a'; + 'v' => c = '\v'; + '0' => c = '\0'; + '$' => c = '$'; + 'u' => + if (i+4 < len s) { + i++; + (c, nil) = str->toint(s[i:i+4], 16); + i+=3; + } + } + } + r[len r] = c; + } + return r; +} + +scriptload( path: string) :list of string +{ + dfd := sys->open(path, Sys->OREAD); + if (dfd == nil) { + raise "fail: Script file ("+path+") not found"; + return nil; + } + + scriptbuf := array[BUFSIZE] of byte; + scriptlen := sys->read(dfd, scriptbuf, len scriptbuf); + if(scriptlen < 0) + raise "fail: can't read script: "+sys->sprint("%r"); + + (nil, scriptlist) := sys->tokenize(string scriptbuf[0:scriptlen], "\n"); + return scriptlist; +} |
