/************************************************************* * vt100 terminal emulator - Script file support * * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 * v2.5 870214 DBW - more additions (see readme file) * v2.4 861214 DBW - lots of fixes/additions (see readme file) * v2.3 861101 DBW - minor bug fixes * v2.2 861012 DBW - more of the same * v2.1 860915 DBW - new features (see README) * 860901 ACS - Added BAUD, PARITY and WORD commands & handling * 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 * *************************************************************/ #include "vt100.h" struct COMMAND { void (*func)(); char *cname; }; struct LABEL { struct LABEL *next; char *name; long pos; }; extern long atol(); /**************** 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[20]; /* 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 */ /********************** command tables *******************************/ static struct COMMAND inicmds[] = { /* initialization commands */ cmd_bkg, "bac", /* set background color */ cmd_bold, "bol", /* set bold color */ cmd_buf, "buf", /* set buffer size */ cmd_cursor, "cur", /* set cursor color */ cmd_depth, "dep", /* set screen depth */ cmd_fore, "for", /* set foreground color */ cmd_inter, "int", /* interlace ON/OFF */ cmd_lines, "lin", /* num lines */ cmd_screen, "scr", /* Screen WB/CUST */ cmd_volume, "vol", /* set volume */ cmd_wb, "wb", /* use WB colors */ cmd_null, NULL /* mark the end of the list */ }; static struct COMMAND scrcmds[] = { /* script only commands */ cmd_as, "asc", /* ascii send */ cmd_beep, "bee", /* Beep */ cmd_cap, "cap", /* ascii capture on/off */ cmd_cd, "cd", /* change directory */ cmd_delay, "del", /* delay amount of seconds */ cmd_goto, "got", /* goto label */ cmd_kb, "kb", /* kermit bye (for server) */ cmd_kg, "kg", /* kermit get file */ cmd_kr, "kr", /* kermit receive file */ cmd_ks, "ks", /* kermit send file */ cmd_on, "on", /* on a 'string' do a cmd */ cmd_sb, "sb", /* Send a break */ cmd_send, "send", /* send string to host */ cmd_wait, "wait", /* wait for a host string */ cmd_xr, "xr", /* xmodem receive file */ cmd_xs, "xs", /* xmodem send file */ cmd_null, NULL /* mark the end of the list */ }; static struct COMMAND commands[]= { /* generally available commands */ cmd_appcur, "app", /* turn app. cursor on/off */ cmd_baud, "bau", /* Set Baud Rate */ cmd_bt, "bre", /* Set Break Time */ cmd_conv, "con", /* convert bs to del */ cmd_echo, "ech", /* turn echo on or off */ cmd_exit, "exi", /* exit script file */ cmd_fnc, "f", /* define function key */ cmd_key, "key", /* keyscript character */ cmd_mode, "mod", /* KERMIT transfer mode */ cmd_numkey, "numkey", /* turn numeric kpad on/off */ cmd_parity, "parity", /* Set Parity */ cmd_swap, "swap", /* Swap BS and DEL */ cmd_wrap, "wrap", /* turn wrap on or off */ cmd_null, NULL /* mark the end of the list */ }; /********************************************************************/ /* 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 (strlen(file) == 0 || *file == '#') return(0); if ((sf = fopen(file, "r")) == NULL) { req("Can't open script file",file,0); 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 == '\t')) s++; p = s; while(*s && (*s != ' ' && *s != '\t')) s++; *l = s-p; return(p); } exe_cmd(p,l) char *p; int l; { register int i,l2; /* downcase the command */ for (i=0; i= l2 && strncmp(p, inicmds[i].cname, l2) == 0) { (*inicmds[i].func)(next_wrd(p+l, &l)); return(TRUE); } } /* or the script command list */ else for (i=0; scrcmds[i].func != cmd_null; ++i) { l2 = strlen(scrcmds[i].cname); if (l >= l2 && strncmp(p, scrcmds[i].cname, l2) == 0) { (*scrcmds[i].func)(next_wrd(p+l, &l)); return(TRUE); } } /* now search for it (in the standard command list) */ for (i=0; commands[i].func != cmd_null; ++i) { l2 = strlen(commands[i].cname); if (l >= l2 && strncmp(p, commands[i].cname, l2) == 0) { (*commands[i].func)(next_wrd(p+l, &l)); return(TRUE); } } if (doing_init) { puts("INIT - unknown command:"); puts(p); } else req("Script - unknown command:",p,0); return(FALSE); } 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 ON command is matched and we were */ /* doing a DELAY then abort the delay timer,*/ /* except if on_cmd was just a SEND. */ if (stat == ONCOMMAND) { strcpy(line,on_cmd); p = next_wrd(line,&l); if (*p != 'S' && script_wait == WAIT_TIMER) { AbortIO((char *) &Script_Timer); Wait (1L << Script_Timer_Port->mp_SigBit); /* script will proceed after on command */ script_wait = FALSE; } 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; } p = next_wrd(p+l+1, &l); } /* 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) req("Script - label not found: ",golabel,0); exit_script(); } exit_script() { if (script_wait == WAIT_TIMER) /* timer not done yet */ AbortIO((char *) &Script_Timer); /* so abort it */ req("Script - terminated","",0); script_on = FALSE; script_wait = TRUE; fclose(sf); } /* remove quotes terminate string & return pointer to start */ char *tostring(ptr) char *ptr; { char *s1,*s2; s1 = ptr; if (*ptr == '"') { while(*ptr++ && *ptr != '"') ; if (*ptr == '"') { *ptr = '\0'; ptr = s2 = ++s1; while(*s2) { if (*s2 != '^') *s1++ = *s2; else if (*(s2+1) == '^') *s1++ = *s2++; else *s1++ = ((*++s2)|' ')-96; s2++; } *s1 = '\0'; return(ptr); } } if (*s1 == '^') { *s1 = (*(s1+1)|' ')-96; *(s1+1) = '\0'; return(s1); } *(s1+1) = '\0'; return(s1); } /***************************** SCRIPT COMMANDS ********************/ void 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); } } void cmd_send(str) char *str; { sendstring(tostring(str)); } void 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; } void 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); } void 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); } void cmd_exit(option) char *option; { char *p; int l; if (doing_init) return; if (*option) { p = next_wrd(option,&l); *(p+l) = '\000'; if (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0) cleanup("Exit vt100 from script",0); exit_script(); script_start(p); } else exit_script(); } void cmd_ks(file) char *file; { multi_xfer(file, doksend, 1); } void cmd_kr(file) char *file; { multi_xfer(file, dokreceive, 0); } void cmd_kg(file) char *file; { server = TRUE; multi_xfer(file, dokreceive, 0); } void cmd_kb() { saybye(); } void cmd_xs(file) char *file; { multi_xfer(file, XMODEM_Send_File, 1); } void cmd_xr(file) char *file; { multi_xfer(file, XMODEM_Read_File, 1); } void cmd_cap(file) char *file; { do_capture(file); } void cmd_as(file) char *file; { do_send(file); } void cmd_cd(name) char *name; { set_dir(name); } void cmd_sb(str) char *str; { sendbreak(); } void cmd_baud(rate) char *rate; { int i = atoi(rate); switch( i ) { case 300: case 1200: case 2400: case 4800: case 9600: if (doing_init) p_baud = i; else setserbaud(i, TRUE); break; default: if (doing_init) { puts("INIT - invalid baud rate:"); puts(rate); } else req("Script - invalid baud rate: ",rate,0); break; } } void cmd_parity(par) char *par; { int i; switch( *par|' ' ) { case 'n': i = 0; break; case 'm': i = 1; break; case 's': i = 2; break; case 'e': i = 3; break; case 'o': i = 4; break; default: if (doing_init) { puts("INIT - invalid parity:"); puts(par); } else req("Script - invalid parity: ",par,0); return; } p_parity = i; if (doing_init) return; ClearMenuStrip( mywindow ); /* Remove old menu */ InitCommItems(); /* Re-do comm menu */ SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ } void cmd_bt(breaklength) char *breaklength; { p_break = atol(breaklength); if (doing_init) return; AbortIO(Read_Request); Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break; setparams(); } void cmd_mode(tmode) char *tmode; { switch (*tmode|' ') { case 'i': p_mode = 0; break; case 'c': p_mode = 1; break; default: if (doing_init) { puts("INIT - invalid transfer mode: "); puts(tmode); } else req("Script - invalid transfer mode: ",tmode,0); return; } if (doing_init) return; ClearMenuStrip(mywindow); InitCommItems(); /* Re-do comm menu */ SetMenuStrip(mywindow,&menu[0]); } void cmd_beep(dummy) char *dummy; { if (p_volume == 0) DisplayBeep(NULL); else { BeginIO(&Audio_Request); WaitIO(&Audio_Request); } } void setvar(par,typ,var) char *par; int typ,*var; { int i; switch (typ) { case 0: /* ON/OFF or YES/NO */ case 1: /* not case */ if ((par[1]|' ') == 'n' || (par[0]|' ') == 'y') *var = 1-typ; else *var = typ; break; case 2: /* read hex number */ if (sscanf(par,"%x",&i) == 1) *var = i; break; case 3: /* read decimal number */ if (sscanf(par,"%d",&i) == 1) *var = i; break; } } void cmd_echo(par) char *par; { setvar(par,0,&p_echo); if (doing_init == 0) redoutil(); } void cmd_wrap(par) char *par; { setvar(par,0,&p_wrap); if (doing_init == 0) redoutil(); } void cmd_numkey(par) char *par; { setvar(par,1,&p_keyapp); if (doing_init == 0) redoutil(); } void cmd_appcur(par) char *par; { setvar(par,0,&p_curapp); if (doing_init == 0) redoutil(); } void cmd_swap(par) char *par; { setvar(par,0,&p_bs_del); if (doing_init == 0) redoutil(); } void cmd_bkg(par) char *par; { setvar(par,2,&p_background); } void cmd_bold(par) char *par; { setvar(par,2,&p_bold); } void cmd_buf(par) char *par; { setvar(par,3,&p_buffer); } void cmd_cursor(par) char *par; { setvar(par,2,&p_cursor); } void cmd_depth(par) char *par; { setvar(par,3,&p_depth); } void cmd_fore(par) char *par; { setvar(par,2,&p_foreground); } void cmd_inter(par) char *par; { setvar(par,0,&p_interlace); } void cmd_lines(par) char *par; { setvar(par,3,&p_lines); } void cmd_screen(par) char *par; { if ((par[0]|' ') == 'w') p_screen = 0; else p_screen = 1; } void cmd_wb(par) char *par; { setvar(par,0,&p_wbcolors); } void cmd_key(par) char *par; { int i; if (sscanf(par,"%x",&i) == 1) p_keyscript = (char)(i & 0x7f); } void cmd_volume(par) char *par; { setvar(par,3,&p_volume); } void cmd_conv(par) char *par; { setvar(par,0,&p_bs_del); if (doing_init == 0) redoutil(); } void cmd_fnc(par) char *par; { char *s; int l; int i = atoi(par); s = par; if (*s) s = next_wrd(s,&l); /* skip key number */ if (*s) s = next_wrd(s+l+1,&l); /* point at desired string */ if (*s) s = tostring(s); /* convert the string */ if (*s && i > 0 && i < 21) { if (i > 10) { p_F[i-11] = malloc(strlen(s)+1); strcpy(p_F[i-11],s); } else { p_f[i-1] = malloc(strlen(s)+1); strcpy(p_f[i-1],s); } } } void cmd_null(dummy) char *dummy; { }