summaryrefslogtreecommitdiff
path: root/appl/cmd/ip/ppp/script.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/ip/ppp/script.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/cmd/ip/ppp/script.b')
-rw-r--r--appl/cmd/ip/ppp/script.b168
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;
+}