/************************************************************* * vt100 terminal emulator - Script file support * * 860823 DBW - Integrated and rewrote lots of code * 860815 Steve Drew: Initial version written of SCRIPT.C * v2.0 860809 DBW - Major rewrite * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes * v1.0 860712 DBW - First version released * *************************************************************/ #define MODULE_SCRIPT 1 #include "vt100.h" extern char *fgets(),*malloc(); extern long ftell(); struct COMMAND { int (*func)(); char *cname; }; struct LABEL { struct LABEL *next; char *name; long pos; }; /**************** globals needed ******************/ char on_string[20]; /* string to match on for on cmd */ char wait_string[20]; /* string to match of for wait cmd */ char golabel[20]; /* label we are looking for in goto */ char on_cmd[255]; /* command to execute when on matchs*/ int onsize; /* size of on_string */ int waitsize; /* size of wait_string */ int onpos; /* position in on string for search */ int waitpos; /* pos in wait_string for search */ int on_match; /* flag set while doing on_cmd */ FILE *sf; /* file pointer for script file */ struct LABEL *lbase = NULL; /* will point to first label */ struct LABEL *labels; /* current label pointer */ int cmd_send(), cmd_wait(), cmd_on(), cmd_goto(), cmd_delay(), cmd_done(), cmd_ks(), cmd_kg(), cmd_kr(), cmd_xs(), cmd_xr(), cmd_cap(), cmd_as(), cmd_null(), cmd_kb(); char *next_wrd(), *tostring(); /********************** command table **********************************/ static struct COMMAND commands[]= { cmd_send, "SEND", /* send string to host */ cmd_wait, "WAIT", /* wait for a string from host */ cmd_on, "ON", /* on a 'string' do a cmd */ cmd_goto, "GOTO", /* goto label */ cmd_delay, "DELAY", /* delay amount of seconds */ cmd_done, "EXIT", /* exit script file */ cmd_ks, "KS", /* kermit send file */ cmd_kr, "KR", /* kermit receive file */ cmd_kg, "KG", /* kermit get file */ cmd_kb, "KB", /* kermit bye (for server) */ cmd_xs, "XS", /* xmodem send file */ cmd_xr, "XR", /* xmodem receive file */ cmd_cap, "CAPTURE", /* ascii capture on/off */ cmd_as, "ASCII_SEND", /* ascii send */ cmd_null, NULL }; /********************************************************************/ /* checks char to see if match with on string or wait_string */ /* if on string match oncmd gets executed imediately, */ /* if wait_string match script_wait is set. */ /********************************************************************/ chk_script(c) char c; { if (on_string[0] != '\0') { if (on_string[onpos] == c) { onpos++; if (onpos == onsize) { on_match = TRUE; do_script_cmd(ONCOMMAND); on_match = FALSE; return(0); } } else onpos = 0; } if (wait_string[0] != '\0') { if (wait_string[waitpos] != c) { waitpos = 0; return(0); } waitpos++; if (waitpos != waitsize) return(0); wait_string[0] = '\0'; script_wait = FALSE; } } script_start(file) char *file; { if ((sf = fopen(file, "r")) == NULL) { emits("Can't open script file\n"); return(0); } script_on = TRUE; script_wait = FALSE; wait_string[0] = '\0'; on_string[0] = '\0'; on_match = FALSE; lbase = NULL; } /* return pointer to next word. set l to size of the word */ char *next_wrd(s,l) char *s; int *l; { char *p; while(*s && (*s == ' ' || *s == 9)) s++; p = s; while(*s && (*s != ' ' && *s != 9)) s++; *l = s-p; return(p); } exe_cmd(p,l) char *p; int l; { int i; for (i=0; commands[i].func != cmd_null; ++i) if (strncmp(p, commands[i].cname, l) == 0) { (*commands[i].func)(next_wrd(p+l, &l)); return(TRUE); } emits ("\nScript - unknown command: "); emits (p); emits ("\n"); } struct LABEL *find_label(lname) char *lname; { struct LABEL *label; label = lbase; while(label != NULL) { if (strcmp(label->name, lname) == 0) return (label); label = label->next; } return(NULL); } do_script_cmd(stat) int stat; { int len,l; char line[256]; char *p; if (stat == ONCOMMAND) { /* if ON command is matched and we were */ strcpy(line,on_cmd); /* doing a DELAY then abort the delay timer,*/ p = next_wrd(line,&l); /* except if on_cmd was just a SEND. */ if (*p != 'S' && script_wait == WAIT_TIMER) { AbortIO((char *) &Script_Timer); Wait (1L << Script_Timer_Port->mp_SigBit); script_wait = FALSE; /* script will proceed after on command */ } exe_cmd(p,l); return(0); } script_wait = FALSE; while(fgets(line,256,sf) != NULL) { len = strlen(line); line[--len] = '\0'; p = next_wrd(&line[0], &l); if (*(p + l - 1) == ':') { /* its a label */ *(p + l - 1) = '\0'; if (find_label(p) == NULL) { /* it's a new label */ if (lbase == NULL) { /* it's the first label */ labels = lbase = (struct LABEL *) malloc (sizeof (struct LABEL)); } else { labels->next = (struct LABEL *) malloc (sizeof (struct LABEL)); labels = labels->next; } labels->pos = ftell(sf); labels->name = malloc(l); labels->next = NULL; strcpy(labels->name, p); if (stat == GOTOLABEL && strcmp(p, golabel) == 0) stat = NEXTCOMMAND; } if (l < len) p = next_wrd(p+l+1, &l); else return(0); } /* end of it's a label */ if (stat == GOTOLABEL || *p == '#') continue; if (*p) exe_cmd(p,l); return(0); } /* end of while */ if (stat == GOTOLABEL) { emits("\nScript - label not found: "); emits(golabel); emits("\n"); } exit_script(); } exit_script() { if (script_wait == WAIT_TIMER) /* timer not done yet */ AbortIO((char *) &Script_Timer); /* so abort it */ emits("\nScript - terminated\n"); script_on = FALSE; script_wait = TRUE; fclose(sf); } /* remove quotes terminate string & return pointer to start */ char *tostring(ptr) char *ptr; { char *s; s = ptr; if (*ptr == '"') { while(*ptr++ && *ptr !='"'); if (*ptr == '"') { *ptr = '\0'; ptr = s+1; while(*s++) if (*s == '|') *s = '\r'; return(ptr); } } if (*s == '^') { *s = *(s+1)-64; *(s+1) = '\0'; return(s); } *(s+1) = '\0'; return(s); } cmd_goto(lname) char *lname; { struct LABEL *label; /* if on_cmd was a goto kill wait state */ if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; } if ((label = find_label(lname)) == NULL) { /* is it forward */ strcpy(golabel,lname); do_script_cmd(GOTOLABEL); } else { fseek(sf,(long)(label->pos),0); } } cmd_send(str) char *str; { sendstring(tostring(str)); } cmd_wait(str) char *str; { str = tostring(str); *(str+20) = '\0'; /* 20 characters max */ strcpy(wait_string, str); waitsize = strlen(str); script_wait = WAIT_STRING; } cmd_on(str) char *str; { char *p; p = tostring(str); strcpy(on_string, p); onsize = strlen(p); *(p+onsize+2+20) = '\0'; /* 20 characters max */ strcpy(on_cmd,p+onsize+2); } cmd_delay(seconds) char *seconds; { script_wait = WAIT_TIMER; Script_Timer.tr_time.tv_secs = atoi(seconds); Script_Timer.tr_time.tv_micro = 0; SendIO((char *) &Script_Timer.tr_node); } cmd_done() { exit_script(); } cmd_ks(file) char *file; { multi_xfer(file, doksend, 1); } cmd_kr(file) char *file; { multi_xfer(file, dokreceive, 0); } cmd_kg(file) char *file; { server = TRUE; multi_xfer(file, dokreceive, 0); } cmd_kb() { saybye(); } cmd_xs(file) char *file; { multi_xfer(file, XMODEM_Send_File, 1); } cmd_xr(file) char *file; { multi_xfer(file, XMODEM_Read_File, 1); } cmd_cap(file) char *file; { do_capture(file); } cmd_as(file) char *file; { do_send(file); } cmd_null(file) char *file; { }