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 delimiterBUFSIZE: 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;}
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;
}