doc@s.cc.purdue.edu (Craig Norborg) (10/03/87)
# This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # Xshar: Extended Shell Archiver. # This is part 3 out of 3. # This archive created: Sat Oct 3 01:36:26 1987 # By: Craig Norborg (Purdue University Computing Center) # Run the following text with /bin/sh to create: # script.c # vt100.c # vt100.h # xmodem.c cat << \SHAR_EOF > script.c /************************************************************* * vt100 terminal emulator - Script file support * * v2.7 870825 ACS - Wait for the reply from AbortIO(). * Use the *InfoMsg*() routines in window.c. Provide * for multiple script files on command line * (companion to the changes in init.c). Add the * ability to set shortcuts from init file. * 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(); struct SHORT_CUTS { char *cname; char *pos; }; /* Following variables are set up in init.c's InitDefaults. They tell ** us if there are any other script files listed on the command line so ** that we can execute them when a prior script is done. */ extern int script_files_todo; extern char **script_files; /**************** 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 */ void cmd_short(); /********************** 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_short, "sho", /* Set shortcuts */ 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 fn to lowercase */ 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 */ }; /* NB: The structures referenced in the structure may be found in ** init.c */ struct filecmd { char ac; /* ASCII Capture */ char as; /* ASCII Send */ char xs; /* Xmodem Send */ char xr; /* Xmodem Receive */ char kg; /* Kermit Get */ char kr; /* Kermit Receive */ char ks; /* Kermit Send */ char kb; /* Kermit Bye */ char nl; } filecmd_chars; struct baducmd { char b03; /* 0300 */ char b12; /* 1200 */ char b24; /* 2400 */ char b48; /* 4800 */ char b96; /* 9600 */ char bnl; } baudcmd_chars; struct parcmd { char no; /* NOne */ char ma; /* MArk */ char sp; /* SPace */ char ev; /* EVen */ char od; /* ODd */ char nl; } parcmd_chars; struct modcmd { char im; /* IMage */ char tx; /* TeXt */ char cn; /* CoNvert */ char nl; } modcmd_chars; extern struct scrcmd { char em; /* Execute Macro */ char ab; /* Abort Macro */ char nl; } scrcmd_chars; extern struct { char sb; /* Send Break */ char hu; /* Hang Up */ char cd; /* Change Dir */ char cs; /* Clear Screen */ char ec; /* ECho */ char wr; /* WRap */ char nk; /* Num Key */ char ac; /* App Cur */ char bs; /* BS<->DEL */ char nl; } utilcmd_chars; static struct SHORT_CUTS shortkeys[] = { /* Short-cut keys */ /* File items: */ "cap", &(filecmd_chars.ac), /* ascii capture on/off */ "asc", &(filecmd_chars.as), /* ascii send */ "xr", &(filecmd_chars.xs), /* xmodem receive file */ "xs", &(filecmd_chars.xr), /* xmodem send file */ "kg", &(filecmd_chars.kg), /* kermit get file */ "kr", &(filecmd_chars.kr), /* kermit receive file */ "ks", &(filecmd_chars.ks), /* kermit send file */ "kb", &(filecmd_chars.kb), /* kermit bye (for server) */ /* Comm items: */ "300", &(baudcmd_chars.b03), /* Set Baud Rate */ "1200", &(baudcmd_chars.b12), /* Set Baud Rate */ "2400", &(baudcmd_chars.b24), /* Set Baud Rate */ "4800", &(baudcmd_chars.b48), /* Set Baud Rate */ "9600", &(baudcmd_chars.b96), /* Set Baud Rate */ "none", &(parcmd_chars.no), /* Set Parity */ "mark", &(parcmd_chars.ma), /* Set Parity */ "space", &(parcmd_chars.sp), /* Set Parity */ "even", &(parcmd_chars.ev), /* Set Parity */ "odd", &(parcmd_chars.od), /* Set Parity */ "image", &(modcmd_chars.im), /* KERMIT transfer mode */ "text", &(modcmd_chars.tx), /* KERMIT transfer mode */ "convert", &(modcmd_chars.cn), /* KERMIT transfer mode */ /* Script items: */ "execute", &(scrcmd_chars.em), /* execute macro */ "abort", &(scrcmd_chars.ab), /* abort macro */ /* Util items: */ "sb", &(utilcmd_chars.sb), /* send break */ "hang", &(utilcmd_chars.hu), /* hang up */ "cd", &(utilcmd_chars.cd), /* change directory */ "clear", &(utilcmd_chars.cs), /* clear screen */ "ech", &(utilcmd_chars.ec), /* turn echo on or off */ "wrap", &(utilcmd_chars.wr), /* turn wrap on or off */ "numkey", &(utilcmd_chars.nk), /* turn numeric kpad on/off */ "app", &(utilcmd_chars.ac), /* turn app. cursor on/off */ "con", &(utilcmd_chars.bs), /* convert bs to del */ "swap", &(utilcmd_chars.bs), /* Swap BS and DEL */ 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; { char *sfile = NULL; if (strlen(file) == 0 || *file == '#') return(0); if ((sf = fopen(file, "r")) == NULL) { sfile = AllocMem((LONG)(strlen(file)+3), MEMF_PUBLIC|MEMF_CLEAR); strcpy(sfile, "S:"); strcat(sfile, file); if((sf = fopen(sfile, "r")) == NULL) { InfoMsg2Line("Can't open script file",file); return(0); } } script_on = TRUE; script_wait = FALSE; wait_string[0] = '\0'; on_string[0] = '\0'; on_match = FALSE; lbase = NULL; if(sfile) FreeMem(sfile, (LONG)strlen(file)+3); } /* 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; { int i,l2; /* downcase the command */ for (i=0; i<l; i++) p[i] |= ' '; /* now search for it (first in the init command list) */ if (doing_init) for (i=0; inicmds[i].func != cmd_null; ++i) { l2 = strlen(inicmds[i].cname); if (l >= 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 InfoMsg2Line("Script - unknown command:",p); 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); WaitIO(Script_Timer); /* 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) InfoMsg2Line("Script - label not found:",golabel); exit_script(); if(script_files_todo > 0) { script_files_todo--; script_start(*(script_files++)); } } exit_script() { if (script_wait == WAIT_TIMER) { /* timer not done yet */ AbortIO((char *) &Script_Timer); /* so abort it */ Wait (1L << Script_Timer_Port->mp_SigBit); /* Wait for the sig */ WaitIO(Script_Timer); /* Get my reply back */ } InfoMsg1Line("Script - terminated"); 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(); if(script_files_todo > 0) { script_files_todo--; script_start(*(script_files++)); } } } 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 InfoMsg2Line("Script - invalid baud rate: ",rate); 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 InfoMsg2Line("Script - invalid parity: ",par); 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); Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit); WaitIO(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 InfoMsg2Line("Script - invalid transfer mode: ",tmode); 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_short(par) /* Set keyboard shortcuts */ char *par; { int i, l, l2; register char *p = par; /* downcase the next word */ for (i=0; p[i] && (p[i] != ' '); i++) p[i] |= ' '; l = i; /* Find the command name. If found set the shortcut key to the ** user's value. If no value then set the key to ' ' to indicate no ** shortcur available. */ for(i = 0; shortkeys[i].cname != NULL; i++) { l2 = strlen(shortkeys[i].cname); if (l >= l2 && strncmp(p, shortkeys[i].cname, l2) == 0) { for( ; p[l] && (p[l] == ' '); l++) ; if(p[l]) *(shortkeys[i].pos) = p[l]; else *(shortkeys[i].pos) = ' '; } } } 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_convert); 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; { } SHAR_EOF cat << \SHAR_EOF > vt100.c /******************************************************************** * vt100 terminal emulator with xmodem transfer capability * * v2.7 870825 ACS - Provide handling of the msgs from the * info/status window. * 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 Parity and Word Length and support code * 860823 DBW - Integrated and rewrote lots of code * v2.0 860809 DBW - Major rewrite * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes * v1.0 860712 DBW - First version released * * use <esc> to abort xmodem or kermit transfers * * written by Michael Mounier * new version by Dave Wecker *******************************************************************/ /* all includes defines and globals */ #include "vt100.h" /**************************************************************/ /* here are all the global definitions that appear in vt100.h */ /**************************************************************/ char bufr[BufSize]; int fd, timeout = FALSE, ttime; int multi = FALSE, server; long bytes_xferred; char MyDir[60]; struct FileLock *MyDirLock = NULL; struct FileLock *StartLock = NULL; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct TextAttr myattr = { (STRPTR) "topaz.font", 8, 0, 0}; struct TextFont *myfont = NULL; struct NewScreen NewScreen = { 0,0,640,200,1, /* left, top, width, height, depth */ 0,1,HIRES, /* DetailPen, BlockPen, ViewModes */ CUSTOMSCREEN,&myattr, /* Type, Font */ (UBYTE *)"VT100", /* Title */ NULL,NULL }; /* Gadgets, Bitmap */ struct NewWindow NewWindow = { 0,0,640,200, /* left, top, width, height */ 0,1, /* detailpen, blockpen */ MENUPICK|CLOSEWINDOW|RAWKEY|ACTIVEWINDOW|INACTIVEWINDOW, SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG, NULL,NULL, /* FirstGadget, CheckMark */ (UBYTE *)NULL, NULL, /* set screen after open screen */ NULL, /* bitmap */ 640, 200, 640, 200, /* minw, minh, maxw, maxh */ CUSTOMSCREEN /* Type */ }; struct NewWindow NewReqWindow = { 10, 15, ((54*8)+4+18), ((4*8)+11+2), /* left, top, width, height */ 0, 1, /* detailpen, blockpen */ /* IDCMP Flags... */ CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE, /* Flags... */ SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT | WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, NULL, /* First gadget */ NULL, /* CheckMark */ (UBYTE *)"VT100 Info & Xfer Status", /* Title */ NULL, /* set screen after open screen */ NULL, /* bitmap */ ((5*8)+4+18), ((1*8)+11+2), 640, 200, /* minw, minh, maxw, maxh */ CUSTOMSCREEN /* Type */ }; struct IntuiText MyTitle = { 0,1,JAM2,26,0, /* front pen, back pen, mode, left, top */ &myattr, /* font */ (UBYTE *)VERSION, /* title */ NULL}; /* next text */ struct Screen *myscreen = NULL; /* ptr to applications screen */ struct Window *mywindow = NULL; /* ptr to applications window */ struct Window *reqwindow = NULL; /* ptr to requester's window */ struct ViewPort *myviewport; struct RastPort *myrastport; struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ struct Preferences *Prefs; /* preferences from GetPrefs() */ /**** String requester support ******/ char InpBuf[80],UndoBuf[80],Prompt[80]; struct IntuiText donetxt = { 1,0,JAM2,0,0, /* front pen, back pen, mode, left, top */ &myattr, /* font */ (UBYTE *)"DONE", /* question to ask */ NULL}; /* next text */ struct Gadget mydonegad = { &mystrgad,290,2,40,10, /* next,left,top,width,height */ GADGHCOMP|REQGADGET, /* flags */ RELVERIFY|ENDGADGET, /* activation */ BOOLGADGET, /* gadget type */ NULL,NULL,&donetxt, /* gad render, sel render, gad text */ 0L,NULL,2,NULL}; /* mutual exclude, special, ID, user data */ struct StringInfo mystrinfo = { (UBYTE *)InpBuf, (UBYTE *)UndoBuf, 0,80,0,0,0,0, /* initial, max, disp, undo, #chrs, dsp chrs */ 0,0,NULL,0L,NULL}; /* left,top,layer,longint,keymap */ struct Gadget mystrgad = { NULL,10,12,320,10, /* next,left,top,width,height */ GADGHCOMP|REQGADGET,/* flags */ ENDGADGET,STRGADGET,/* activation, type */ NULL,NULL,NULL, /* gad render, sel render, gad text */ 0L, /* mutual exclude */ (APTR)&mystrinfo, /* special info */ 1,NULL}; /* gadget ID, user data */ struct IntuiText mystrtxt = { 0,1,JAM2,10,2, /* front pen, back pen, mode, left, top */ &myattr, /* font */ (UBYTE *)Prompt, /* question to ask */ NULL}; /* next text */ struct Requester myrequest = { NULL,0,10,340,22, /* older requester, left, top, width, height */ 0,0,&mydonegad, /* relleft reltop, gadgets */ NULL, /* border */ &mystrtxt, /* text */ NULL,1,NULL, /* flags, back fill pen, layer */ {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}, /* pad1 */ NULL,NULL, /* image bit map, rquest window */ {0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0} /* pad2 */ }; int numreqs = 0; /* number of outstanding requestors */ int reqwinup = 0; /* Requester window is NOT displayed */ extern int reqmaxx, reqmaxy, reqmaxlen; /* Defined in window.c */ extern void ReqNewSize(); /* New req window size -- window.c */ extern void KillReq(); /* Kill requester window in window.c */ /***** menu structures *****/ struct MenuItem FileItem[FILEMAX]; struct IntuiText FileText[FILEMAX]; struct MenuItem CommItem[COMMAX]; struct IntuiText CommText[COMMAX]; struct MenuItem RSItem[RSMAX]; struct IntuiText RSText[RSMAX]; struct MenuItem ParItem[PARMAX]; struct IntuiText ParText[PARMAX]; struct MenuItem XFItem[XFMAX]; struct IntuiText XFText[XFMAX]; struct MenuItem ScriptItem[SCRIPTMAX]; struct IntuiText ScriptText[SCRIPTMAX]; struct MenuItem UtilItem[UTILMAX]; struct IntuiText UtilText[UTILMAX]; struct Menu menu[MAXMENU]; struct IOExtSer *Read_Request; char *rs_in; struct IOExtSer *Write_Request; char rs_out[2]; struct timerequest Timer; struct MsgPort *Timer_Port = NULL; struct timerequest Script_Timer; struct MsgPort *Script_Timer_Port = NULL; struct IOAudio Audio_Request; struct MsgPort *Audio_Port = NULL; UBYTE *BeepWave; UBYTE Audio_AllocMap[4] = { 1, 8, 2, 4 }; int x,y,curmode; int MINX = 0; int MAXX = 632; int MINY = 14; int MAXY = 198; int top = 14; int bot = 198; int savx = 0; int savy = 14; int savmode = 0; int nlmode = 0; int alt = 0; int savalt = 0; int a[2] = { 0, 0 }; int sa[2] = { 0, 0 }; int inesc = -1; int inctrl = -1; int private = 0; int badseq = 0; int maxcol = 79; /*************************** defaults *******************************/ int p_baud = 1200; /* baud rate */ int p_screen = 0; /* 0 = WORKBENCH, 1 = CUSTOM */ int p_wbcolors = 1; /* 0 = Custom, 1 = Workbench colors */ int p_interlace = 0; /* 0 = no interlace, 1 = interlace */ int p_depth = 2; /* number of bit planes (1 or 2) */ int p_foreground = 0x840; /* default foreground RGB color */ int p_background = 0x000; /* default background RGB color */ int p_bold = 0x000; /* default BOLD RGB color */ int p_cursor = 0x00d; /* default Cursor RGB color */ int p_lines = 24; /* number of lines on the screen */ int p_mode = 0; /* 0 = image, 1 = CRLF (for kermit) */ int p_buffer = 512; /* read buffer size (>= 512 bytes) */ int p_parity = 0; /* 0=none,1=mark,2=space,3=even,4=odd */ long p_break = 750000; /* break time (in micro seconds) */ int p_volume = 64; /* beep volume (0 = DisplayBeep) */ int p_wrap = 1; /* 0 = truncate, 1 = wrap long lines */ int p_keyapp = 0; /* 0 = numeric, 1 = application keypad */ int p_curapp = 0; /* 0 = cursor, 1 = application cursor */ int p_echo = 0; /* 0 = full duplex, 1 = half duplex */ int p_bs_del = 0; /* 0 = normal, 1 = swap bs and delete */ int p_convert = 0; /* 1 = convert filenames to lower case */ char p_keyscript = 0x7E; /* function key script introducer = ~ */ char *p_f[10] = { /* function key defaults */ "\033OP","\033OQ","\033OR","\033OS", "f5","f6","f7","f8","f9","f10" }; char *p_F[10] = { /* shifted function key defaults */ "F1","F2","F3","F4","F5", "F6","F7","F8","F9","F10"}; /* for script file */ int script_on; int script_wait; int doing_init = 0; /******************************************************/ /* Main Program */ /* */ /* This is the main body of the program. */ /******************************************************/ char lookahead[80]; FILE *tranr = NULL; FILE *trans = NULL; int capture,send; char name[80]; struct MsgPort *mySerPort; main(argc,argv) int argc; char **argv; { ULONG class, waitmask; unsigned int code, qual; int KeepGoing,i,la,dola,actual; char c,*ptr; ptr = InitDefaults(argc,argv); InitDevs(); InitFileItems(); InitCommItems(); InitScriptItems(); InitUtilItems(); InitMenu(); SetMenuStrip(mywindow,&menu[0]); PrintIText(mywindow->RPort,&MyTitle,0L,0L); MyDir[0] = '\000'; StartLock = (struct FileLock *)((ULONG)((struct Process *) (FindTask(NULL)))->pr_CurrentDir); MyDirLock = (struct FileLock *)DupLock(StartLock); KeepGoing = TRUE; capture = FALSE; send = FALSE; maxcol = MAXX / 8; la = 0; x = MINX ; y = MINY; curmode = FS_NORMAL; script_on = FALSE; script_wait= TRUE; SetAPen(mywindow->RPort,1L); cursorflip(); cursorflip(); emit(12); mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort; SendIO(Read_Request); /* see if we had a startup script */ if (ptr != NULL) script_start(ptr); reqwinup = 0; while( KeepGoing ) { /* wait for window message or serial port message */ cursorflip(); if(reqwinup) waitmask = (1L << mySerPort->mp_SigBit) | (1L << mywindow->UserPort->mp_SigBit) | (1L << Script_Timer_Port->mp_SigBit) | (1L << reqwindow->UserPort->mp_SigBit); else waitmask = (1L << mySerPort->mp_SigBit) | (1L << mywindow->UserPort->mp_SigBit) | (1L << Script_Timer_Port->mp_SigBit); if (script_wait) /* if script ready dont wait here */ Wait(waitmask); cursorflip(); /* do ascii file send */ if (send) { if ((c=getc(trans)) != EOF) { if (c == '\n') c = '\r'; sendchar(c); } else { fclose(trans); InfoMsg1Line("File Sent"); send=FALSE; } } /* see if there are any characters from the host */ if (CheckIO(Read_Request)) { WaitIO(Read_Request); c = rs_in[0] & 0x7F; doremote(c); if (script_on) chk_script(c); if (capture && c != 10) { if (c == 13) c = 10; putc(c , tranr); } Read_Request->IOSer.io_Command = SDCMD_QUERY; DoIO(Read_Request); Read_Request->IOSer.io_Command = CMD_READ; actual = (int)Read_Request->IOSer.io_Actual; if (actual > 0) { if (inesc < 0 && inctrl < 0 && a[alt] == 0 && capture == FALSE) dola = 1; else dola = 0; Read_Request->IOSer.io_Length = Read_Request->IOSer.io_Actual; DoIO(Read_Request); Read_Request->IOSer.io_Length = 1; for (i = 0; i < actual; i++) { c=rs_in[i] & 0x7f; if (script_on) chk_script(c); if (dola == 1) { if (c >= ' ' && c <= '~' && la < 80) lookahead[la++] = c; else { if (la > 0) { emitbatch(la,lookahead); la = 0; } doremote(c); dola = 0; } } else { doremote(c); if (inesc < 0 && inctrl < 0 && a[alt] == 0 && capture == FALSE) dola = 1; if (capture && c != 10) { if (c == 13) c = 10; putc(c , tranr); } } } /* dump anything left in the lookahead buffer */ if (la > 0) { emitbatch(la,lookahead); la = 0; } } SendIO(Read_Request); } while((NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) != FALSE) { class = NewMessage->Class; code = NewMessage->Code; qual = NewMessage->Qualifier; ReplyMsg( NewMessage ); switch( class ) { case CLOSEWINDOW: KeepGoing = FALSE; break; case RAWKEY: c = toasc(code,qual,0); if (p_echo) doremote(c); break; case NEWSIZE: emit(12); break; case MENUPICK: handle_menupick(class,code); break; default: PrintIText(mywindow->RPort,&MyTitle,0L,0L); break; } /* end of switch (class) */ } /* end of while ( newmessage )*/ if (!script_wait || (CheckIO(&Script_Timer) && script_wait == WAIT_TIMER)) do_script_cmd(NEXTCOMMAND); while( reqwinup && ((NewMessage = (struct IntuiMessage *) GetMsg(reqwindow->UserPort)) != FALSE) ) { class = NewMessage->Class; ReplyMsg( NewMessage ); switch( class ) { case REQCLEAR: numreqs = 0; break; case CLOSEWINDOW: KillReq(); /* Kills requester window, set reqwinup = 0 */ break; case NEWSIZE: ReqNewSize(reqwindow->Height, reqwindow->Width); break; } /* end of switch (class) */ } /* end while */ } /* end while ( keepgoing ) */ /* It must be time to quit, so we have to clean * up and exit. */ cleanup("",0); } /* end of main */ /* cleanup code */ cleanup(reason, fault) char *reason; int fault; { switch(fault) { case 0: /* quitting close everything */ KillReq(); /* Kill the requester and its window */ ClearMenuStrip( mywindow ); CloseDevice(&Audio_Request); if (MyDirLock != NULL) UnLock(MyDirLock); case 8: /* error opening audio */ DeletePort(Audio_Port); FreeMem(BeepWave,BEEPSIZE); CloseDevice(&Timer); case 7: /* error opening timer */ DeletePort(Timer_Port); CloseDevice(&Script_Timer); DeletePort(Script_Timer_Port); case 6: /* error opening write device */ DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort); FreeMem(Write_Request,(long)sizeof(*Write_Request)); CloseDevice(Read_Request); case 5: /* error opening read device */ DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort); FreeMem(Read_Request,(long)sizeof(*Read_Request)); case 4: /* error opening window */ if (myfont != NULL) CloseFont( myfont ); if (mywindow != NULL) CloseWindow( mywindow ); if (p_screen != 0) CloseScreen( myscreen ); case 3: /* error opening screen */ case 2: /* error opening graphics library */ case 1: /* error opening intuition */ default: if (*reason) puts (reason); } exit(fault); } do_capture(file) char *file; { if (capture == TRUE) { capture=FALSE; fclose(tranr); InfoMsg1Line("End File Capture"); } else { if (file == NULL) { name[0] = '\000'; req("Ascii Capture:",name,1); } else strcpy(name, file); if ((tranr=fopen(name,"w")) == 0) { capture=FALSE; InfoMsg1Line("Error Opening File"); return(FALSE); } capture=TRUE; } } do_send(file) char *file; { if (send == TRUE) { send=FALSE; fclose(trans); InfoMsg1Line("File Send Cancelled"); } else { if (file == NULL) { name[0] = '\000'; req("Ascii Send:",name,1); } else strcpy(name, file); if ((trans=fopen(name,"r")) == 0) { send=FALSE; InfoMsg1Line("Error Opening File"); return(FALSE); } send=TRUE; } } void setparams() { Read_Request->IOSer.io_Command = Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(Read_Request); DoIO(Write_Request); Read_Request->IOSer.io_Command = CMD_READ; SendIO(Read_Request); Write_Request->IOSer.io_Command = CMD_WRITE; } void hangup () { AbortIO(Read_Request); CloseDevice (Read_Request); Timer.tr_time.tv_secs=0L; Timer.tr_time.tv_micro=750000L; DoIO((char *) &Timer.tr_node); OpenDevice (SERIALNAME,NULL,Read_Request,NULL); setparams(); } void redocomm() { ClearMenuStrip( mywindow ); /* Remove old menu */ InitCommItems(); /* Re-do comm menu */ SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ } void setserbaud(baud, redomenu) int baud; LONG redomenu; { AbortIO(Read_Request); Write_Request->io_Baud = Read_Request->io_Baud = baud; setparams(); p_baud = baud; if (redomenu) redocomm(); } void redoutil() { ClearMenuStrip(mywindow); InitUtilItems(); SetMenuStrip(mywindow,&menu[0]); } void handle_menupick(class, code) ULONG class; unsigned int code; { unsigned int menunum, itemnum, subnum; if (code == MENUNULL) return; menunum = MENUNUM( code ); itemnum = ITEMNUM( code ); subnum = SUBNUM( code ); switch( menunum ) { case 0: switch( itemnum ) { case 0: do_capture(NULL); break; case 1: do_send(NULL); break; case 2: if (p_parity > 0) { InfoMsg1Line("Parity setting prevents this"); break; } name[0] = '\000'; req("Xmodem Receive:",name,1); multi_xfer(name,XMODEM_Read_File,0); break; case 3: if (p_parity > 0) { InfoMsg1Line("Parity setting prevents this"); break; } name[0] = '\000'; req("Xmodem Send:",name,1); multi_xfer(name,XMODEM_Send_File,1); break; case 4: server = TRUE; name[0] = '\000'; req("Kermit GET remote file(s):",name,1); multi_xfer(name,dokreceive,0); break; case 5: multi_xfer("",dokreceive,0); break; case 6: server = TRUE; name[0] = '\000'; req("Kermit Send local name:",name,1); multi_xfer(name,doksend,1); break; case 7: saybye(); break; } break; case 1: switch( itemnum ) { case 0: switch( subnum ) { case 0: setserbaud(300, FALSE); break; case 1: setserbaud(1200, FALSE); break; case 2: setserbaud(2400, FALSE); break; case 3: setserbaud(4800, FALSE); break; case 4: setserbaud(9600, FALSE); break; } break; case 1: /* Set Parity */ p_parity = subnum; break; case 2: /* set transfer mode */ if (subnum < 2) p_mode = subnum; else { if (p_convert) p_convert = 0; else p_convert = 1; redocomm(); } break; } break; case 2: if (!itemnum && !script_on) { name[0] = '\000'; req("Script file name:",name,1); script_start(name); } if (itemnum && script_on) exit_script(); break; case 3: switch( itemnum ) { case 0: sendbreak(); break; case 1: hangup(); break; case 2: strcpy(name,MyDir); req("Directory:",name,1); set_dir(name); break; case 3: top = MINY; bot = MAXY; savx = MINX; savy = MINY; curmode = FS_NORMAL; inesc = -1; a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0; redoutil(); emit(12); break; case 4: if (p_echo) p_echo = 0; else p_echo = 1; redoutil(); break; case 5: if (p_wrap) p_wrap = 0; else p_wrap = 1; redoutil(); break; case 6: if (p_keyapp) p_keyapp = 0; else p_keyapp = 1; redoutil(); break; case 7: if (p_curapp) p_curapp = 0; else p_curapp = 1; redoutil(); break; case 8: swap_bs_del(); redoutil(); break; } break; } /* end of switch ( menunum ) */ } SHAR_EOF cat << \SHAR_EOF > vt100.h /********************************************************************* * a terminal program that has ascii and xmodem transfer capability * * v2.7 870825 ACS - See README. * 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) * 860823 DBW - Integrated and rewrote lots of code * v2.0 860809 DBW - Major release.. LOTS of changes * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes * v1.0 860712 DBW - First version released * * use esc to abort xmodem transfer * * written by Michael Mounier * new version by Dave Wecker 860621 ********************************************************************/ /********* major version (used for title of terminal window) *********/ #define VERSION "VT100 (V2.7 ACS 870825) Terminal Window" /*********** ######## define the compiler type here ######## ********/ #define LATTICE 0 #define MANX 1 /* compiler directives to fetch the necessary header files */ #include <exec/types.h> #include <exec/exec.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #include <graphics/gfxbase.h> #include <graphics/gfx.h> #include <graphics/text.h> #include <graphics/regions.h> #include <graphics/copper.h> #include <graphics/gels.h> #include <devices/serial.h> #include <devices/keymap.h> #include <devices/inputevent.h> #include <devices/audio.h> #include <hardware/blit.h> /* for Lattice you may have to change these with: */ #include <stdio.h> /* #include <lattice/stdio.h> and */ #include <ctype.h> /* #include <lattice/ctype.h> */ #include <libraries/dos.h> #include <libraries/dosextens.h> #include <devices/timer.h> #if MANX #include <functions.h> #undef NULL #define NULL ((void *)0) #endif #define INTUITION_REV 1L #define GRAPHICS_REV 1L /* things for xmodem send and recieve */ #define GOODREAD 0 #define TIMEOUT 1 #define USERABORT 2 #define SECSIZ 0x80 #define TTIME_SHORT 5 /* number of seconds for short timeout */ #define TTIME_LONG 50 /* number of seconds for long timeout */ #define TTIME_KERMIT 10 /* number of seconds for KERMIT timeout*/ #define BufSize 0x200 /* Text buffer for XMODEM */ #define ERRORMAX 10 /* Max errors before abort */ #define RETRYMAX 10 /* Maximum retrys before abort */ #define SOH 1 /* Start of sector char */ #define EOT 4 /* end of transmission char */ #define ACK 6 /* acknowledge sector transmission */ #define NAK 21 /* error in transmission detected */ #define FILEMAX 8 /* number of file menu items */ #define COMMAX 3 /* number of communication sub menus */ #define RSMAX 5 /* speed menu items */ #define PARMAX 5 /* parity items */ #define XFMAX 3 /* transfer mode items */ #define SCRIPTMAX 2 /* script menu items */ #define UTILMAX 9 /* utility menu */ #define MAXMENU 4 /* total number of menu entries */ #define MAXGADSTR 80 /* Max size of prompts and inputs */ #define FSF_REVERSE 256 /* fake font style to flag INVERSVID mode */ /* things for script support */ #define GOTOLABEL 1 #define NEXTCOMMAND 0 #define ONCOMMAND 2 #define WAIT_TIMER 2 #define WAIT_STRING 1 /* things for 'beep' support */ #define BEEPSIZE 10L #define BEEPFREQ 1000L #define COLORCLOCK 3579545L extern struct MsgPort *CreatePort(); extern char *malloc(),*strcpy(),*fgets(); extern long ftell(); extern int multi; /* flags multi file transfers */ extern int server; extern char bufr[BufSize]; extern int fd, timeout, ttime; extern long bytes_xferred; extern char MyDir[60]; extern struct FileLock *MyDirLock; extern struct FileLock *StartLock; extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; extern struct TextAttr myattr; extern struct TextFont *myfont; extern struct NewScreen NewScreen; extern struct NewWindow NewWindow; extern struct NewWindow NewReqWindow; extern struct Screen *myscreen; extern struct Window *mywindow; extern struct Window *reqwindow; extern struct ViewPort *myviewport; extern struct RastPort *myrastport; extern struct IntuiMessage *NewMessage; extern struct Preferences *Prefs; extern char InpBuf[80],UndoBuf[80],Prompt[80]; extern struct StringInfo mystrinfo; extern struct Gadget mystrgad; extern struct IntuiText donetxt; extern struct Gadget mydonegad; extern struct IntuiText mystrtxt; extern struct Requester myrequest; extern int numreqs; extern int reqwinup; extern struct MenuItem FileItem[FILEMAX]; extern struct IntuiText FileText[FILEMAX]; extern struct MenuItem CommItem[COMMAX]; extern struct IntuiText CommText[COMMAX]; extern struct MenuItem RSItem[RSMAX]; extern struct IntuiText RSText[RSMAX]; extern struct MenuItem ParItem[PARMAX]; extern struct IntuiText ParText[PARMAX]; extern struct MenuItem XFItem[XFMAX]; extern struct IntuiText XFText[XFMAX]; extern struct MenuItem ScriptItem[SCRIPTMAX]; extern struct IntuiText ScriptText[SCRIPTMAX]; extern struct MenuItem UtilItem[UTILMAX]; extern struct IntuiText UtilText[UTILMAX]; extern struct Menu menu[MAXMENU]; extern struct timerequest Timer, Script_Timer; extern struct MsgPort *Timer_Port, *Script_Timer_Port; extern struct IOExtSer *Read_Request; extern char *rs_in; extern struct IOExtSer *Write_Request; extern char rs_out[2]; extern int x,y,curmode; extern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy; extern int savmode,nlmode,alt,savalt,a[2],sa[2]; extern int inesc,inctrl,private,badseq,maxcol; extern struct IOAudio Audio_Request; extern struct MsgPort *Audio_Port; extern UBYTE *BeepWave; extern UBYTE Audio_AllocMap[4]; extern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors; extern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode; extern int p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del; extern int p_convert; extern char p_keyscript; extern long p_break; extern char *p_f[10],*p_F[10]; extern int script_on; extern int script_wait; extern int doing_init; /* vt100.c */ extern int do_send(),do_capture(),cleanup(); extern void setserpar(), setserbaud(), setparams(), redoutil(), redocomm(), handle_menupick(); /* init.c */ extern void InitDevs(),InitFileItems(),InitCommItems(), InitScriptItems(),InitUtilItems(),InitMenu(); extern char *InitDefaults(); /* window.c */ extern void swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip(); extern int toasc(); extern void ScrollInfoMsg(), InfoMsgNoScroll(), InfoMsg1Line(), InfoMsg2Line(); /* xmodem.c */ extern void sendchar(),sendstring(),sendbreak(),multi_xfer(), No_XON(),Do_XON(); extern int readchar(),XMODEM_Read_File(),XMODEM_Send_File(); /* remote.c */ extern void doremote(),doindex(),doctrl(),doesc(),doerase(); /* kermit.c */ extern int doksend(), dokreceive(), saybye(); extern void encode(), decode(), rpar(), spar(); /* script.c */ extern int script_start(), chk_script(), exit_script(), do_script_cmd(); extern char *next_wrd(), *tostring(); /* init commands */ extern void cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(), cmd_fore(), cmd_inter(), cmd_lines(), cmd_screen(), cmd_volume(), cmd_wb(), cmd_null(), /* script commands */ cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(), cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(), cmd_ks(), cmd_on(), cmd_sb(), cmd_send(), cmd_wait(), cmd_xr(), cmd_xs(), /* init and script commands */ cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(), cmd_echo(), cmd_exit(), cmd_fnc(), cmd_key(), cmd_mode(), cmd_numkey(), cmd_parity(), cmd_swap(), cmd_wrap(); /* expand.c */ extern char **expand(); extern int set_dir(), free_expand(); SHAR_EOF cat << \SHAR_EOF > xmodem.c /************************************************************* * vt100 terminal emulator - XMODEM protocol support * * v2.7 870825 ACS - Make multi_xfer() non-recursive; on non-ESC in * readchar() re-do the main window's title. * 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 Parity and Word Length and support code * 860823 DBW - Integrated and rewrote lots of code * 860815 Steve Drew: readchar inproved with real timeouts * 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" int enablexon = TRUE; extern struct IntuiText MyTitle; static unsigned long parity_settings[4] = { 0x96696996, 0x69969669, 0x69969669, 0x96696996 }; /************************************************************ * Send a string (using sendchar below) ************************************************************/ void sendstring(s) char *s; { char c; while ((c = *s++) != '\000') sendchar(c); } /**************************************************************/ /* send char and read char functions for the xmodem function */ /************************************************************/ void sendchar(ch) int ch; { int doxon,i,j,k; doxon = enablexon; if (doxon) No_XON(); switch (p_parity) { case 0: /* no parity */ rs_out[0] = ch & 0xFF; break; case 1: /* mark */ rs_out[0] = (ch & 0x7F) | 0x80; break; case 2: /* space */ rs_out[0] = ch & 0x7F; break; case 3: /* even */ case 4: /* odd */ i = (ch >> 5) & 0x3; j = ch & 0x1F; k = ((parity_settings[i] >> j) & 0x1) << 7; if (p_parity == 3) /* even parity */ rs_out[0] = (ch & 0x7F) | k; else /* odd parity */ rs_out[0] = (ch & 0x7F) | (k ^ 0x80); } do { DoIO(Write_Request); } while(Write_Request->IOSer.io_Error != 0); if (doxon) Do_XON(); } /* send a break to the host */ void sendbreak() { AbortIO(Read_Request); Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit); WaitIO(Read_Request); Read_Request->IOSer.io_Command = SDCMD_BREAK; DoIO(Read_Request); Read_Request->IOSer.io_Command = CMD_READ; SendIO(Read_Request); } int readchar() { int rd,ch; ULONG class, waitmask; USHORT code; Timer.tr_time.tv_secs = ttime; Timer.tr_time.tv_micro = 0; SendIO((char *) &Timer.tr_node); rd = FALSE; waitmask = ((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | ( 1L << mywindow->UserPort->mp_SigBit) | ( 1L << Timer_Port->mp_SigBit)); if(reqwinup) waitmask |= (1L << reqwindow->UserPort->mp_SigBit); while (rd == FALSE) { Wait(waitmask); if (CheckIO(Read_Request)) { WaitIO(Read_Request); ch=rs_in[0]; rd = TRUE; SendIO(Read_Request); } if(reqwinup && (NewMessage=(struct IntuiMessage *)GetMsg(reqwindow->UserPort))) { class = NewMessage->Class; ReplyMsg(NewMessage); if(class == NEWSIZE) ReqNewSize(reqwindow->Height, reqwindow->Width); } if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) { class = NewMessage->Class; code = NewMessage->Code; ReplyMsg(NewMessage); if ((class == RAWKEY) && (code == 69)) { AbortIO((char *) &Timer); Wait (1L << Timer_Port->mp_SigBit); WaitIO((char *) &Timer.tr_node); InfoMsg1Line("ERROR: User aborted transfer"); timeout = USERABORT; return('\0'); } PrintIText(mywindow->RPort, &MyTitle, 0L, 0L); continue; } if (rd == FALSE && CheckIO(&Timer)) { InfoMsg1Line("ERROR: Timeout waiting for character"); timeout = TIMEOUT; return('\0'); } } /* end while */ AbortIO((char *) &Timer); Wait (1L << Timer_Port->mp_SigBit); WaitIO((char *) &Timer.tr_node); timeout = GOODREAD; return(ch & (p_parity == 0 ? 0xFF : 0x7F)); } void No_XON() { /* turn off XON/XOFF processing */ enablexon = FALSE; Write_Request->io_SerFlags |= SERF_XDISABLED; Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(Write_Request); Write_Request->IOSer.io_Command = CMD_WRITE; } void Do_XON() { /* turn on XON/XOFF processing */ enablexon = TRUE; Write_Request->io_SerFlags &= ~SERF_XDISABLED; Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(Write_Request); Write_Request->IOSer.io_Command = CMD_WRITE; } /**************************************/ /* xmodem send and recieve functions */ /************************************/ int XMODEM_Read_File(file) char *file; { int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag; unsigned int checksum, j, bufptr; char scrstr2[40]; bytes_xferred = 0L; ttime = TTIME_SHORT; if ((fd = creat(file, 0)) < 0) { InfoMsg2Line("XMODEM Can't Open File:",file); return FALSE; } else InfoMsg1Line("XMODEM Receive, <esc> in VT100 window to abort"); sectnum = errors = bufptr = 0; sendchar(NAK); firstchar = 0; No_XON(); while (firstchar != EOT && errors != ERRORMAX) { errorflag = FALSE; do { /* get sync char */ firstchar = readchar(); if (timeout != GOODREAD) { if (timeout == USERABORT || errors++ == ERRORMAX) Do_XON(); return FALSE; } } while (firstchar != SOH && firstchar != EOT); if (firstchar == SOH) { sprintf(scrstr2,"Getting Block %4d...",sectnum); InfoMsgNoScroll(scrstr2); sectcurr = readchar(); if (timeout != GOODREAD) { Do_XON(); return FALSE; } sectcomp = readchar(); if (timeout != GOODREAD) { Do_XON(); return FALSE; } if ((sectcurr + sectcomp) == 255) { if (sectcurr == ((sectnum + 1) & 0xff)) { checksum = 0; for (j = bufptr; j < (bufptr + SECSIZ); j++) { bufr[j] = readchar(); if (timeout != GOODREAD) { Do_XON(); return FALSE; } checksum = (checksum + bufr[j]) & 0xff; } if (checksum == readchar() && timeout == GOODREAD) { errors = 0; sprintf(scrstr2,"Block %4d verified",sectnum); sectnum++; bufptr += SECSIZ; bytes_xferred += SECSIZ; InfoMsgNoScroll(scrstr2); if (bufptr == BufSize) { if (write(fd, bufr, BufSize-128) == EOF) { InfoMsg1Line("XMODEM: Error Writing File"); Do_XON(); return FALSE; } bufptr = 128; for (j = 0; j < 128; j++) bufr[j] = bufr[(BufSize-128)+j]; } sendchar(ACK); } else { errorflag = TRUE; if (timeout == USERABORT) { Do_XON(); return FALSE; } } } else { /* got a duplicate sector */ if (sectcurr == (sectnum & 0xff)) { /* wait until we time out for 5secs */ do { readchar(); } while (timeout == GOODREAD); if (timeout == USERABORT) { Do_XON(); return FALSE; } InfoMsg1Line("XMODEM: Received Duplicate Sector"); sendchar(ACK); } else errorflag = TRUE; } } else errorflag = TRUE; } if (errorflag == TRUE) { errors++; InfoMsg1Line("XMODEM: Error"); sendchar(NAK); } } /* end while */ if ((firstchar == EOT) && (errors < ERRORMAX)) { sendchar(ACK); while (bufptr > 0 && (bufr[--bufptr] == 0x00 || bufr[bufptr] == 0x1A)) ; write(fd, bufr, ++bufptr); close(fd); Do_XON(); ScrollInfoMsg(1); return TRUE; } Do_XON(); return FALSE; } int XMODEM_Send_File(file) char *file; { int sectnum, bytes_to_send, size, attempts, c; unsigned checksum, j, bufptr; char scrstr2[40]; bytes_xferred = 0; ttime = TTIME_LONG; if ((fd = open(file, 0)) < 0) { InfoMsg1Line("XMODEM: Cannot Open Send File"); return FALSE; } else InfoMsg1Line("XMODEM Send, <esc> from VT100 window to abort"); attempts = 0; sectnum = 1; No_XON(); /* wait for sync char */ j=1; while (((c = readchar()) != NAK) && (j++ < ERRORMAX)) if (timeout == USERABORT) { Do_XON(); return(FALSE); } if (j >= (ERRORMAX)) { InfoMsg1Line("XMODEM: Receiver not sending NAKs"); Do_XON(); return FALSE; } while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX) { if (bytes_to_send == EOF) { InfoMsg1Line("XMODEM: Error Reading File"); Do_XON(); return FALSE; } bufptr = 0; while (bytes_to_send > 0 && attempts != RETRYMAX) { attempts = 0; sprintf(scrstr2,"Sending block %4d",sectnum); do { InfoMsgNoScroll(scrstr2); sendchar(SOH); sendchar(sectnum); sendchar(~sectnum); checksum = 0; size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send; bytes_to_send -= size; for (j = bufptr; j < (bufptr + SECSIZ); j++) if (j < (bufptr + size)) { sendchar(bufr[j]); checksum += bufr[j]; } else sendchar(0); sendchar(checksum); attempts++; c = readchar(); if (timeout == USERABORT) { InfoMsg1Line("XMODEM: ABORTED"); Do_XON(); return FALSE; } } while ((c != ACK) && (attempts != RETRYMAX)); bufptr += size; bytes_xferred += size; sprintf(scrstr2,"Sent block %4d",sectnum); InfoMsgNoScroll(scrstr2); sectnum++; } } close(fd); if (attempts == RETRYMAX) { InfoMsg1Line("XMODEM: No Acknowledgment, ABORTING"); Do_XON(); return FALSE; } else { attempts = 0; do { sendchar(EOT); attempts++; } while ((readchar() != ACK) && (attempts != RETRYMAX) && (timeout != USERABORT)) ; if (attempts == RETRYMAX) InfoMsg1Line("XMODEM: No end of file"); } Do_XON(); ScrollInfoMsg(1); return TRUE; } /* allow for multi file xfers separated by commas under kermit and XMODEM */ void multi_xfer(name,mode,do_send) char *name; int (*mode)(); int do_send; { int done = 0; int status; char *p, *name_start; timeout = USERABORT - 1; for(p=name_start=name; !done && timeout != USERABORT; name_start=++p) { if (*(name_start) == '$' && *(name_start+1) == '\0') { saybye(); return; } while(*p == ' ') p++; while(*p && *p != ',' && *p != ' ') p++; if (*p == '\0') { done = TRUE; multi = 0; } else multi = 1; *p = '\0'; status = ((*mode)(name_start, multi)); if (status == FALSE) close(fd); } server = 0; multi = 0; } SHAR_EOF