page%swap@Sun.COM (Bob Page) (10/20/89)
Submitted-by: acs@pccuts.pcc.amdahl.com (Tony Sumrall) Posting-number: Volume 89, Issue 184 Archive-name: comm/vt100r29.7 # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # kermitproto.h # mouse.doc # newkermit.c # remote.c # rexx.c # script.c # This is archive 7 of a 9-part kit. # This archive created: Thu Oct 19 22:30:32 1989 echo "extracting kermitproto.h" sed 's/^X//' << \SHAR_EOF > kermitproto.h X/* X * Include file for kermitproto.w. You probably don't want to change X * any of the following manifest constants. X * this module. X */ X#define MAXSP 2048 /* Maximum length packet to send */ X#define MAXRP 1024 /* Maximum length packet to receive */ X#define DRPSIZ 94 /* Default data size of received packet */ X#define DSPSIZ 94 /* Default data size of sent packet */ X#define MAXWS 1 /* Maximum window size for sliding windows */ X#define NULL 0L X X/* X * The following defines change the names of some things as an example X * of how you can interface kermitproto.w to your own code. X * X * WARNING WILL ROBINSON: These are highly specific to the Amiga X * terminal emulator program "VT100" by Dave Wecker et. al. and must X * certainly change for your code. X */ X X#define parity p_parity /* parity on? */ X#define text p_mode /* Text or binary mode? */ X#define convert p_convert /* Convert files to lower case? */ X#define urpsiz p_kmaxpack /* Kermit maximum packet size */ X SHAR_EOF echo "extracting mouse.doc" sed 's/^X//' << \SHAR_EOF > mouse.doc X Mousing around with VT100 X XBy default, this version of VT100 sends the following sequence when Xthe user presses the left (selection) button on the Amiga mouse: X X <ESC> M (yes, a real capital M) <quals> <column> <line> X Xwhere column and line are bytes that represent the x, y coordinates of Xthe mouse click (offset by 32; a click on (0, 0) results in sending Xtwo space characters), and quals is like so: X X bit 0 control key X bit 1 shift key X bit 2 meta (alt) key X bit 3 caps lock X bit 4 mouse down event X bit 5 mouse up event X bit 6 always on (making qual a printable value) X XFor example, clicking on column 1, row 1 results in the escape sequence X X <ESC> M P <SPC> <SPC> X XIn the startup file and scripts, the command MOUSE accepts the following Xfour parameters: X X UP send a mouse event only when user releases the select button X DOWN send an event only when user presses the select button X BOTH send both up- and downward clicks X OFF don't send mouse clicks X X XThe function key setup has been extended to handle "fm" (along with X"f1", "f2", etc.) so you can specify the string preceeding mouse Xevents. For example, X X F M "^[Oz" X XIn a script or the startup file would rebind the "mouse" function key to Xsend X <ESC> O z SHAR_EOF echo "extracting newkermit.c" sed 's/^X//' << \SHAR_EOF > newkermit.c X/* :ts=8 */ X X/* X * These are the new interfaces between vt100 and the new Kermit protocol X * module. X */ X X#include "vt100.h" /* Get defines and so on */ X/* X * Here are the declarations for our communication with kermitproto.c X */ X Xextern int cx, cz; /* Abort flags */ X Xextern char start; /* Start state for Kermit */ Xchar *cmarg; /* Command argument for server */ X X/* X * The below variables have to do with the status of the communcation X * so far. They should be maintained over in kermitproto.w so that X * things like the number of bytes sent and the packet type can be X * printed as status. X */ Xstatic int npackets, /* Number of packets sent so far */ X naks; /* Number of naks */ X X Xstatic char message[80]; /* Message line to output */ X X/* X * Do Kermit sending. This expands wild cards into local variables for X * gnfile() below. X */ X Xstatic int nfiles, wild; Xstatic char **lp, **list; X Xdoksend(file,more) Xchar *file; Xint more; X{ X char *p; X X list = NULL; X p = file; X while(*p && *p != '*' && *p != '?') p++; X if (*p) { X wild = 1; X list = expand(file, &nfiles); X if (list == NULL) { X InfoMsg1Line("KERMIT: No wild card match"); X return FALSE; X } X } X else { X nfiles = 1; X wild = 0; X list = (char **) malloc(sizeof(char *)); X *list = (char *) malloc(strlen(file) + 1); X strcpy(*list, file); X } X lp = list; X start = 's'; /* Set start state to send */ X npackets = naks = 0; X message[0] = '\0'; X proto(); /* Call protocol */ X if (wild == 1) X free_expand(list); X else { X free((void *) *list); X free((void *) list); X } X return TRUE; X} X X/* X * gnfile(s, n) char *s; int n; X * X * Returns in string s the name of the next file for Kermit to process, X * which can be up to n characters in length. Returns a positive value X * if there are more files, 0 if not. X */ Xint Xgnfile(s, n) Xchar *s; Xint n; X{ X if (--nfiles >= 0) { X strncpy(s, *lp, n); X lp++; X return 1; X } else X return 0; X} X X/* X * Do Kermit receiving. The file and more arguments in this routine are X * for Get'ting files when the remote machine is the server. X */ Xdokreceive(file,more) Xchar *file; Xint more; X{ X naks = npackets = 0; X message[0] = '\0'; /* Initialize */ X if (!server) X start = 'v'; /* Start state to receive */ X else { X cmarg = file; /* Files to get from remote */ X start = 'r'; /* Start state to get */ X } X proto(); X return TRUE; X} X X/* kermit_directory()--request a remote directory from a Kermit server. X */ X X#define tochar(c) ((c) + 32) X Xvoid Xkermit_directory(dir) Xchar *dir; X{ X char command[80]; X X strcpy(command, "D"); /* Generic directory command */ X command[1] = tochar(strlen(dir)); /* Length of directory name */ X strcpy(&command[2], dir); /* The directory itself */ X cmarg = command; X start = 'g'; /* Generic command start state */ X naks = npackets = 0; X proto(); X} X X/* X * saybye()--send a FINISH command to a remote Kermit server. This is X * in fact what the original VT100 saybye() does. A true Kermit BYE X * command would mean changing the "F" below to "L", and it would actually X * log out the remote host as well as shut down the Kermit server. X */ Xvoid Xsaybye() X{ X static char bye_command[] = "F"; X X cmarg = &bye_command[0]; X start = 'g'; /* Generic command start state */ X naks = npackets = 0; X proto(); X return /* TRUE */; X} X X/* X * ttinl(dest, max, eol, timelimit) X * X * Read up to max characters from serial port into the array pointed X * to by dest. Return value is the number of characters received. X * If eol is greater than 0, terminate read upon first X * eol character received. If timelimit is greater than 0, wait at X * most timelimit seconds for the characters. The array is null X * terminated; in addition, if we do see an eol, we overwrite it X * with the NULL and the returned character count does not include it. X * (This behavior is required by the code in the C Kermit book but is X * not explicitly stated there.) X * X * This version is most unsatisfactory as it does I/O one character X * at a time, but extensive changes in the rest of VT100 would be X * needed in order to use a multi-character read. X */ X Xstatic int pushedser = -1; /* pushed character */ X Xint ttinl(dest, max, eol, timelimit) Xchar *dest; Xint max, eol, timelimit; X{ X int i; X void ttflui(); X X if (timelimit > 0) X ttime = timelimit; X else X ttime = 30; /* Maximum timeout if not given */ X for (i = 0; i < max; i++) { X dest[i] = readchar(); X if (timeout != GOODREAD) { X if (timeout == USERABORT) { /* User abort requested */ X if (cx == 1) X start = 'a'; /* Second escape--abort mess */ X else X cx = cz = 1; /* Set abort flags */ X continue; /* Continue receiving anyway */ X } else { X i = -1; /* Some other error. */ X break; X } X } X if (eol > 0 && dest[i] == eol) X break; X ttime = 2; /* Intrapacket timeout */ X } X if (i >= 0) X dest[i] = '\0'; /* Null terminate what we got */ X else X dest[0] = '\0'; X return i; /* Return length or failure */ X} X X/* X * ttol(out, n) X * X * Send n characters pointed to by out through the serial port using X * current settings of word length, parity, and flow control. Return X * X * X * Here I bypass sendchar() and go direct to the low level. X */ Xint Xttol(out, n) Xchar *out; Xint n; X{ X int retval; X X Write_Request->IOSer.io_Data = (APTR) out; X Write_Request->IOSer.io_Length = n; X Write_Request->IOSer.io_Command = CMD_WRITE; X SendIO((struct IORequest *)Write_Request); X retval = WaitIO((struct IORequest *)Write_Request); X /* X * Restore old values. X */ X Write_Request->IOSer.io_Data = (APTR) rs_out; X Write_Request->IOSer.io_Length = 1; X if (retval != 0) X return -1; X else X return ((int)Write_Request->IOSer.io_Actual); X} X X/* X * ttflui() X * X * Remove any pending characters from the serial port. X * X * Even worse than ttinl() and ttol(), this reads characters with a minimal X * timeout until there aren't any more. Note that I also changed readchar() X * in xmodem.c to check if ttime is 0, and if it is, to set its timeout to X * 100,000 ticks (0.1 seconds). I also removed the InfoMsg1Line call which X * warned about timeouts so this would work. Ideally, ttinl() should do X * a single CMD_READ in ReadRequest, and ttflui() should AbortIO() it. X */ Xvoid Xttflui() X{ X int c; X X ttime = 0; X do { X c = readchar(); X } while (timeout == GOODREAD); X} X Xvoid Xsleep(seconds) int seconds; X{ X if (seconds > 0) X Delay(seconds*TICKS_PER_SECOND); X} X X/* X * Now here are tmsg() and tchar() for putting out warnings. What I've done X * is to use tchar()'s argument as a flag to put out whatever status we need. X * tmsg()'s argument is put out as a message line. X */ X X/* X * tchar(c)--put the single character c onto the user's screen as part X * of Kermit's communication to said user. X */ Xvoid Xtchar(c) Xchar c; X{ X char status[80]; X void tmsg(); X X switch (c) { X case '.': X npackets++; X break; X case '%': X naks++; X break; X default: X status[0] = c; X status[1] = '\0'; X tmsg(status); /* Output unknown chars */ X return; X } X sprintf(status, "Packets: %4d Retries: %4d", npackets, naks); X InfoMsgNoScroll(status); X} X X/* X * tmsg(s) char *s;--Put a message string onto the user's screen as part X * of the communication from Kermit. X * X * I put out a message using InfoMsg. We store it up until we get a newline, X * then we scroll and put it out. X */ X Xvoid Xtmsg(more_message) Xchar *more_message; X{ X /* X * If new message won't fit, put out message so far and copy it. X * Otherwise, just catenate new message to old. X */ X if (strlen(more_message) + strlen(message) < sizeof(message)) { X strcat(message,more_message); X } else { X InfoMsg1Line(message); X strcpy(message,more_message); X } X} X X/* X * tmsgl(s) char *s;--Put out a newline-terminated message to the user's X * screen as part of Kermit communication. X */ Xvoid Xtmsgl(more_message) Xchar *more_message; X{ X tmsg(more_message); X InfoMsg1Line(message); X message[0] = '\0'; X} X SHAR_EOF echo "extracting remote.c" sed 's/^X//' << \SHAR_EOF > remote.c X/**************************************************** X * vt100 emulator - remote character interpretation X * :ts=8 X * X * V2.9 ACS - CAN was not cancelling a control sequence (thanks X * to Bill Kinnersly. X * V2.8 Insert/delete character (@/P) by John Wang X * (jwang@ATRP.MEDIA.MIT.EDU) X * v2.7 870227 ACS - No changes to this routine. X * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 X * v2.5 870214 DBW - more additions (see readme file) X * v2.4 861214 DBW - lots of fixes/additions (see readme file) X * v2.3 861101 DBW - minor bug fixes X * v2.2 861012 DBW - more of the same X * v2.1 860915 DBW - new features (see README) X * 860823 DBW - Integrated and rewrote lots of code X * v2.0 860803 DRB - Rewrote the control sequence parser X * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes X * v1.0 860712 DBW - First version released X * X ****************************************************/ X X#include "vt100.h" X Xstatic int p[10]; Xstatic int numpar; Xstatic char escseq[40]; X Xstatic void doalt(), doline(); X X/************************************************ X* function to handle remote characters X*************************************************/ Xvoid doremote(c) Xchar c; X { X if (c == 24) { inesc = -1; inctrl = -1; return; } X if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; } X if (inctrl >= 0 && c >= ' ') { doctrl(c); return; } X if (c == 10 || c == 11 || c == 12) { X if (nlmode) doindex('E'); else doindex('D'); X return; X } X if (c == 13) { X if (!nlmode) emit(c); X return; X } X if (c == 15) { alt = 0; return; } X if (c == 14) { alt = 1; return; } X if (a[alt] && c > 94 && c < 127) { doalt(c); return; } X emit(c); X } X Xvoid doesc(c) Xchar c; X{ X if (inesc < 0) { inesc = 0; return; } X if (c == 27 || c == 24) { inesc = -1; return; } X if (c < ' ' || c == 127) return; /* Ignore control chars */ X X /* Collect intermediates */ X if (c < '0') {escseq[inesc++] = c; return; } X X /* by process of elimination, we have a final character. X Put it in the buffer, and dispatch on the first character X in the buffer */ X X escseq[inesc] = c; X inesc = -1; /* No longer collecting a sequence */ X switch (escseq[0]) /* Dispatch on the first received */ X { X case '[': /* Control sequence introducer */ X numpar = 0; /* No parameters yet */ X private = 0; /* Not a private sequence (yet?) */ X badseq = 0; /* Good until proven bad */ X p[0] = p[1] = 0; /* But default the first parameter */ X inctrl = 0; /* We are in a control sequence */ X return; /* All done for now ... */ X X case 'D': case 'E': case 'M': /* Some kind of index */ X doindex (c); /* Do the index */ X return; /* Return */ X X case '7': /* Save cursor position */ X savx = x; savy = y; savmode = curmode; savalt = alt; X sa[0] = a[0]; sa[1] = a[1]; X return; X X case '8': /* Restore cursor position */ X x = savx; y = savy; alt = savalt; curmode = savmode; X a[0] = sa[0]; a[1] = sa[1]; X return; X X case 'c': /* Reset */ X top = MINY; bot = MAXY; savx = MINX; savy = MINY; X curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0; X inesc = -1; X a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0; X redoutil(); X emit(12); X return; X X case '(': /* Change character set */ X if (c == '0' || c == '2') a[0] = 1; else a[0] = 0; X return; X X case ')': /* Change the other character set */ X if (c == '0' || c == '2') a[1] = 1; else a[1] = 0; X return; X X case '=': /* set keypad application mode */ X p_keyapp = 1; X redoutil(); X return; X X case '>': /* reset application mode */ X p_keyapp = 0; X redoutil(); X return; X X case 'Z': X sendchar(27); sendstring("[?1;7c"); return; X X /* If we didn't match anything, we can just return, happy in the X knowledge that we've at least eaten the whole sequence */ X X } /* End of switch */ X return; X} X Xvoid doctrl(c) Xchar c; X{ X int i; X X if (c == 27 || c == 24) { inctrl = -1; return; } X if (c < ' ' || c == 127) return; /* Ignore control chars */ X X /* First, look for some parameter characters. If the very first X parameter character isn't a digit, then we have a X private sequence */ X X if (c >= '0' && c < '@') X { X /* can't have parameters after intermediates */ X if (inctrl > 0) {badseq++ ; return; } X switch (c) X { X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X p[numpar] = p[numpar] * 10 + (c - '0'); X return; X X case ';': X p[++numpar] = 0; /* Start a new parameter */ X return; X X case '<': case '=': case '>': case '?': /* Can only mean private */ X X /* Only allowed BEFORE parameters */ X if (inctrl == 0) private = c; X return; X X /* if we come here, it's a bad sequence */ X } X badseq++; /* Flag the bad sequence */ X } X X if (c < '0') /* Intermediate character */ X { X escseq[inctrl++] = c; /* Save the intermediate character */ X return; X } X X /* if we get here, we have the final character. Put it in the X escape sequence buffer, then dispatch the control sequence */ X X numpar++; /* Reflect the real number of parameters */ X escseq[inctrl++] = c; /* Store the final character */ X escseq[inctrl] = '\000'; /* Tie off the buffer */ X inctrl = -1; /* End of the control sequence scan */ X X /* Don't know how to do most private sequences right now, X so just punt them */ X X if ((private != 0 && private != '?') || badseq != 0) return; X if (private == '?' && escseq[0] != 'h' && X escseq[0] != 'l') return; X X switch (escseq[0]) /* Dispatch on first intermediate or final */ X { X case 'A': if (p[0]<=0) p[0] = 1; X y -= Ysize*p[0]; if (y<top) y = top; return; X case 'B': if (p[0]<=0) p[0] = 1; X y += Ysize*p[0]; if (y>bot) y = bot; return; X case 'C': if (p[0]<=0) p[0] = 1; X x += Ysize*p[0]; if (x>MAXX) x = MAXX; return; X case 'D': if (p[0]<=0) p[0] = 1; X x -= Ysize*p[0]; if (x<MINX) x = MINX; return; X X case 'H': case 'f': /* Cursor position */ X if (p[0] <= 0) p[0] = 1; X if (p[1] <= 0) p[1] = 1; X y = (--p[0]*Ysize)+MINY; x = (--p[1]*Ysize)+MINX; X if (y > MAXY) y = MAXY; X if (x > MAXX) x = MAXX; X if (y < MINY) y = MINY; X if (x < MINX) x = MINX; X return; X X case 'L': /* ANSI insert line */ X case 'M': /* ANSI delete line */ X if (p[0] <= 0) p[0] = 1; X ScrollRaster(mywindow->RPort, X 0L, (long)((escseq[0] == 'M' ? Ysize : -Ysize) * p[0]), X (long)MINX, (long)(y-BaseLine), X (long)(MAXX+Xsize-1), (long)bot+Ysize-BaseLine-1 ); X return; X X case '@': /* Insert characters */ X case 'P': /* Delete characters */ X if (p[0] <= 0) p[0] = 1; X ScrollRaster(mywindow->RPort, X (long) ((escseq[0] == 'P'? Ysize : -Ysize)) * p[0], 0L, X (long) x, (long)(y - BaseLine), X (long) MAXX+Xsize-1, (long)(y+Ysize-BaseLine-1) ); X return; X X case 'r': /* Set scroll region */ X if (p[0] <= 0) p[0] = 1; X if (p[1] <= 0) p[1] = p_lines; X top = (--p[0]*Ysize)+MINY; bot = (--p[1]*Ysize)+MINY; X if (top < MINY) top = MINY; X if (bot > MAXY) bot = MAXY; X if (top > bot) { top = MINY; bot = MAXY; } X x = MINX; y = MINY; X return; X X case 'm': /* Set graphic rendition */ X for (i=0;i<numpar;i++) { X if (p[i] < 0) p[i] = 0; X switch (p[i]) { X case 0: X curmode = FS_NORMAL; X break; X X case 1: X curmode |= FSF_BOLD; X break; X X case 4: X curmode |= FSF_UNDERLINED; X break; X X case 5: X curmode |= FSF_ITALIC; X break; X X default: X curmode |= FSF_REVERSE; X break; X } X } X return; X X case 'K': /* Erase in line */ X doerase(); X return; X X case 'J': /* Erase in display */ X if (p[0] < 0) p[0] = 0; X SetAPen(mywindow->RPort,0L); X if (p[0] == 0) { X if (y < MAXY) RectFill(mywindow->RPort, X (long)MINX,(long)(y+(Ysize-BaseLine)), X (long)(MAXX+Xsize-1), X (long)(MAXY+(Ysize-BaseLine-1))); X } X else if (p[0] == 1) { X if (y > MINY) RectFill(mywindow->RPort, X (long)MINX, X (long)(MINY-BaseLine), X (long)(MAXX+Xsize-1), X (long)(y-BaseLine-1)); X } X else RectFill(mywindow->RPort, X (long)MINX, X (long)(MINY-BaseLine), X (long)(MAXX+Xsize-1), X (long)(MAXY+(Ysize-BaseLine-1))); X SetAPen(mywindow->RPort,1L); X doerase(); return; X X case 'h': /* Set parameter */ X if (private == 0 && p[0] == 20) nlmode = 1; X else if (private == '?') { X if (p[0] == 7) p_wrap = 1; X else if (p[0] == 1) p_curapp = 1; X redoutil(); X } X return; X X case 'l': /* Reset parameter */ X if (private == 0 && p[0] == 20) nlmode = 0; X else if (private == '?') { X if (p[0] == 7) p_wrap = 0; X else if (p[0] == 1) p_curapp = 0; X redoutil(); X } X return; X X case 'x': X sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return; X X case 'n': X if (p[0] == 6) { X sendchar(27); X sprintf(escseq,"[%d;%dR",((y-MINY)/Ysize)+1,((x-MINX)/Xsize)+1); X sendstring(escseq); return; X } X sendchar(27); sendstring("[0n"); return; X X case 'c': X sendchar(27); sendstring("[?1;7c"); return; X } X X /* Don't know how to do this one, so punt it */ X} X Xvoid doindex(c) Xchar c; X { X if (c != 'M') { X if (c == 'E') x = MINX; X if (y > bot) if (y < MAXY) y += 8; X if (y == bot) X ScrollRaster(mywindow->RPort, X 0L, (long)Ysize, X (long)MINX, (long)(top-BaseLine), X (long)(MAXX+Xsize-1), (long)(bot+(Ysize-BaseLine-1)) ); X if (y < bot) y += Ysize; X } X else { X if (y < top) if (y > MINY) y -= BaseLine; X if (y == top) X ScrollRaster(mywindow->RPort,0L, X (long)-Ysize, X (long)MINX, X (long)(top-BaseLine), X (long)(MAXX+Xsize-1), X (long)(bot+(Ysize-BaseLine-1))); X if (y > top) y -= Ysize; X } X return; X } X Xstatic void Xdoalt(c) Xchar c; X { X int oldx,newx; X inesc = -1; X oldx = x; emit(' '); newx = x; X x = oldx; X SetAPen(mywindow->RPort,1L); X switch (c) { X case 'a': X doline(0,-BaseLine,Xsize,1); X break; X X case 'j': X case 'm': X case 'v': doline(Xsize/2,-BaseLine,Xsize/2,-(Ysize-BaseLine)); X if (c=='j') doline(0,-(Ysize-BaseLine),Xsize/2,-(Ysize-BaseLine)); X else if (c=='m') doline(Xsize/2,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine)); X else doline(0,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine)); X break; X X case 'k': X case 'l': X case 'w': doline(Xsize/2,-(Ysize-BaseLine),Xsize/2,1); X if (c=='k') doline(0,-(Ysize-BaseLine),Xsize/2,-(Ysize-BaseLine)); X else if (c=='l') doline(Xsize/2,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine)); X else doline(0,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine)); X break; X X case 'n': X case 'q': doline(0,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine)); X if (c=='n') doline(Xsize/2,-BaseLine,Xsize/2,Ysize-BaseLine); X break; X X case 't': X case 'u': X case 'x': doline(Xsize/2,-BaseLine,Xsize/2,1); X if (c=='t') doline(Xsize/2,-(Ysize-BaseLine),Xsize,-(Ysize-BaseLine)); X else if (c=='u') doline(0,-(Ysize-BaseLine),Xsize/2,-(Ysize-BaseLine)); X break; X } X x = newx; X} X Xstatic void Xdoline(x1,y1,x2,y2) { X RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1), X (long)(x+x2),(long)(y+y2)); X} X Xvoid doerase() X { X if (p[0] < 0) p[0] = 0; X SetAPen(mywindow->RPort,0L); X if (p[0] == 0) RectFill(mywindow->RPort, X (long)x, X (long)(y-BaseLine), X (long)(MAXX+Xsize-1), X (long)(y+(Ysize-BaseLine-1))); X else if (p[0] == 1) RectFill(mywindow->RPort, X (long)MINX, X (long)(y-BaseLine), X (long)(x+Xsize-1), X (long)(y+(Ysize-BaseLine-1))); X else RectFill(mywindow->RPort, X (long)MINX, X (long)(y-BaseLine), X (long)(MAXX+Xsize-1), X (long)(y+(Ysize-BaseLine-1))); X SetAPen(mywindow->RPort,1L); X return; X } X SHAR_EOF echo "extracting rexx.c" sed 's/^X//' << \SHAR_EOF > rexx.c X/************************************************************* X * vt100 terminal emulator - AREXX support X * :ts=8 X * X * v2.9 ACS - New with this version. X * X *************************************************************/ X X#ifdef AREXX X X#include "vt100.h" X Xint RexxReplies = 0; /* # outstanding replies */ X Xextern int doing_init; /* in init.c */ X Xextern char *extension; /* in vt100.c */ X X#define AREXXCOMMAND 2 X/* Derived from: X * X * REXX.C X * X * (c) Copyright 1987 by Kim DeVaughn, All Rights Reserved X * X * ARexx interface code, etc. X * X */ X Xdo_rx(cmd, implied) Xchar *cmd; Xint implied; X{ X int len, ret = 0; X char *p; X register struct RexxMsg *RexxMsg; X struct MsgPort *RexxPort; X X if(cmd == NULL || *cmd == '\0') X return ret; X X if(RexxSysBase == NULL) { X if((RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L)) == NULL) X return NORXLIB; X if( (ret = makerexxport()) != 0) X return ret; X } X X for(len = 0, p = cmd; *p != '\n' && *p != '\0'; p++, len++) X ; X X Forbid(); X if((RexxPort = FindPort(RXSDIR))) { X if((RexxMsg = CreateRexxMsg(FromRexxPort, extension, HostName)) && X (ARG0(RexxMsg) = (STRPTR)CreateArgstring(cmd, (LONG)len)) ) { X ARG1(RexxMsg) = (STRPTR)AREXXCOMMAND; X RexxMsg->rm_Action = RXCOMM; X PutMsg(RexxPort, (struct Message *)RexxMsg); X RexxReplies++; X } else X ret = NORXMSG; X } else X ret = NORXPORT; X Permit(); X return ret; X} X Xvoid Xprocessrexxmsg(RexxMsg) Xregister struct RexxMsg *RexxMsg; X{ X extern char *next_wrd(); X register char *arg0 = NULL, *arg1 = NULL; X char *command = NULL, X *message = NULL, X *errmsg = "AREXX macro not found: ", X *MacDone = "AREXX macro complete: ", X *NoMem = "processrexxmsg: Can't allocate memory for message."; X int len = 0; X X arg0 = (char *)ARG0(RexxMsg); X arg1 = (char *)ARG1(RexxMsg); X if(arg0 && *arg0) X command = next_wrd(arg0, &len); X X if(RexxMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) { X /* Got some kind of reply so we'll assume that the AREXX lib is X ** available. If it's a "command not found" then tell the user. If X ** it's a command FROM VT100 (marked by AREXXCOMMAND in ARG1) and we X ** have no outstanding replies then it must mean that a previously X ** issued AREXX command FROM VT100 has completed, tell the user. X ** Otherwise, we can just toss the reply. X **/ X X if(--RexxReplies <= 0) X RexxReplies = 0; X X if(RexxMsg->rm_Result1 == 5 && RexxMsg->rm_Result2 == 1) { X LONG memlen = strlen(errmsg) + len + 1; X X if(message = AllocMem(memlen, MEMF_PUBLIC | MEMF_CLEAR)) { X strcpy(message, errmsg); X strncat(message, command, len); X if(doing_init) { X puts("Init:"); X puts(message); X } else X InfoMsg2Line("Script:", message); X FreeMem(message, memlen); X } else { X if(doing_init) { X puts("Init:"); X puts(NoMem); X } else X InfoMsg2Line("Script:", NoMem); X } X } X X if(arg1 == (char *)AREXXCOMMAND) { X if(RexxReplies == 0 && command) { X LONG memlen = strlen(MacDone) + strlen(command) + 1; X X if(message = AllocMem(memlen, MEMF_PUBLIC | MEMF_CLEAR)) { X strcpy(message, MacDone); X strcat(message, command); X if(doing_init) { X puts("Init:"); X puts(message); X } else X InfoMsg1Line(message); X FreeMem(message, memlen); X } else { X if(doing_init) { X puts("Init:"); X puts(NoMem); X } else X InfoMsg2Line("Script:", NoMem); X } X } X } X X DeleteArgstring(arg0); X ARG0(RexxMsg) = NULL; X ARG1(RexxMsg) = NULL; X DeleteRexxMsg(RexxMsg); X X return; X } else if(RexxMsg->rm_Action == RXCOMM) { X int ret; X LONG memlen = strlen(arg0) + 1; X X CmdFromRexx = 1; /* Tell everyone from whence it came */ X command = AllocMem(memlen, MEMF_PUBLIC | MEMF_CLEAR); X strcpy(command, arg0); X next_wrd(command, &len); X X RexxMsg->rm_Result1 = exe_cmd(command, len); X CmdFromRexx = 0; X FreeMem(command, memlen); X } else { X RexxMsg->rm_Result1 = 5; X RexxMsg->rm_Result2 = 1; X } X ReplyMsg((struct Message *)RexxMsg); X} X#endif /* AREXX */ SHAR_EOF echo "extracting script.c" sed 's/^X//' << \SHAR_EOF > script.c X/************************************************************* X * vt100 terminal emulator - Script file support X * :ts=8 X * X * v2.9 ACS - Add support for font size, external transfer program X * support, new ASIS option to LACE cmd and AREXX support. X * v2.8a 880331 ACS - Allow comments on XPROTO and FONT. X * v2.7 870825 ACS - Wait for the reply from AbortIO(). X * Use the *InfoMsg*() routines in window.c. Provide X * for multiple script files on command line X * (companion to the changes in init.c). Add the X * ability to set shortcuts from init file. X * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 X * v2.5 870214 DBW - more additions (see readme file) X * v2.4 861214 DBW - lots of fixes/additions (see readme file) X * v2.3 861101 DBW - minor bug fixes X * v2.2 861012 DBW - more of the same X * v2.1 860915 DBW - new features (see README) X * 860901 ACS - Added BAUD, PARITY and WORD commands & handling X * 860823 DBW - Integrated and rewrote lots of code X * 860815 Steve Drew: Initial version written of SCRIPT.C X * v2.0 860809 DBW - Major rewrite X * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes X * v1.0 860712 DBW - First version released X * X *************************************************************/ X X#include "vt100.h" X X#define DNMAXLEN 9 X Xextern struct MsgPort *mySerPort; /* in vt100.c */ X Xstruct COMMAND { X int (*func)(); X char *cname; X int minlen; X int validfrom; X}; X X#define INIT 1 X#define SCRIPT 2 X#define NONREXX 4 X#define REXXONLY 8 X Xstruct LABEL { X struct LABEL *next; X char *name; X long pos; X}; X Xextern long atol(); X X#if MANX Xextern char *index(); X#endif /* MANX */ X X#if LATTICE X#define index(a,b) stpchr(a,b) X#endif /* LATTICE */ X Xstruct SHORT_CUTS { X char *cname; X char *pos; X}; X X/* Following variables are set up in init.c's InitDefaults. They tell X** us if there are any other script files listed on the command line so X** that we can execute them when a prior script is done. */ X Xextern int script_files_todo; Xextern char **script_files; X X/**************** globals needed ******************/ X Xchar on_string[20]; /* string to match on for on cmd */ Xchar wait_string[20]; /* string to match of for wait cmd */ Xchar golabel[20]; /* label we are looking for in goto */ Xchar on_cmd[20]; /* command to execute when on matchs*/ Xint onsize; /* size of on_string */ Xint waitsize; /* size of wait_string */ Xint onpos; /* position in on string for search */ Xint waitpos; /* pos in wait_string for search */ Xint on_match; /* flag set while doing on_cmd */ XFILE *sf = NULL; /* file pointer for script file */ Xstruct LABEL *lbase = NULL; /* will point to first label */ Xstruct LABEL *labels; /* current label pointer */ Xchar errmsg[80]; /* Error msg from routines */ X#if AREXX Xint implied_rexx; /* cmd_rx() invoked as impled cmd */ X#endif /* AREXX */ X X/************************ command table *********************************/ Xstatic struct COMMAND commands[] = { Xcmd_appcur, "appcursor", 3, INIT|SCRIPT, /* turn app. cursor on/off */ Xcmd_as, "ascii", 3, SCRIPT, /* ascii send */ Xcmd_ac, "autochop", 3, INIT|SCRIPT, /* XMODEM autochop */ Xcmd_bkg, "background", 3, INIT, /* set background color */ Xcmd_baud, "baud", 3, INIT|SCRIPT, /* Set Baud Rate */ Xcmd_beep, "beep", 3, SCRIPT, /* Beep */ Xcmd_bold, "bold", 3, INIT, /* set bold color */ Xcmd_bt, "breaktime", 3, INIT|SCRIPT, /* Set Break Time */ Xcmd_buf, "buffer", 3, INIT, /* set buffer size */ Xcmd_cap, "capture", 3, SCRIPT, /* ascii capture on/off */ Xcmd_cd, "cd", 2, SCRIPT, /* change directory */ Xcmd_conv, "convert", 4, INIT|SCRIPT, /* convert fn to lowercase */ Xcmd_cursor, "cursor", 3, INIT, /* set cursor color */ Xcmd_delay, "delay", 3, SCRIPT, /* delay amount of seconds */ Xcmd_depth, "depth", 3, INIT, /* set screen depth */ Xcmd_device, "device", 3, INIT, /* set serial device name */ Xcmd_display, "display", 3, SCRIPT, /* Display data on screen */ Xcmd_echo, "echo", 3, INIT|SCRIPT, /* turn echo on or off */ Xcmd_exit, "exit", 3, INIT|SCRIPT|NONREXX, /* exit script file */ Xcmd_ext, "external", 4, INIT|SCRIPT, /* external xfer pgms */ Xcmd_fnc, "f", 1, INIT|SCRIPT, /* define function key */ Xcmd_font, "font", 3, INIT, /* set font */ Xcmd_fonts, "fontsize", 5, INIT, /* set fontsize */ Xcmd_fore, "foreground", 3, INIT, /* set foreground color */ X#if AREXX Xcmd_fwd, "forward", 3, REXXONLY, /* forward data to rexx */ X#endif /* AREXX */ Xcmd_goto, "goto", 3, SCRIPT|NONREXX,/* goto label */ Xcmd_inter, "interlace", 3, INIT, /* interlace ON/OFF */ Xcmd_kb, "kb", 2, SCRIPT, /* kermit bye (for server) */ Xcmd_key, "keyscript", 3, INIT|SCRIPT, /* keyscript character */ Xcmd_kg, "kg", 2, SCRIPT, /* kermit get file */ Xcmd_kmaxpk, "kmaxpack", 8, INIT|SCRIPT, /* Kermit maximum packet size */ Xcmd_kr, "kr", 2, SCRIPT, /* kermit receive file */ Xcmd_ks, "ks", 2, SCRIPT, /* kermit send file */ Xcmd_lines, "lines", 3, INIT, /* num lines */ Xcmd_mode, "mode", 3, INIT|SCRIPT, /* KERMIT transfer mode */ Xcmd_mouse, "mouse", 3, INIT|SCRIPT, /* Mouse control */ Xcmd_msg, "msg", 3, SCRIPT, /* Display a message */ Xcmd_numkey, "numkey", 6, INIT|SCRIPT, /* turn numeric kpad on/off */ Xcmd_on, "on", 2, SCRIPT, /* on a 'string' do a cmd */ Xcmd_parity, "parity", 6, INIT|SCRIPT, /* Set Parity */ Xcmd_recf, "recfile", 4, SCRIPT, /* receive a file from host */ Xcmd_rx, "rx", 2, INIT|SCRIPT, /* Specific invocation */ Xcmd_sb, "sb", 2, SCRIPT, /* Send a break */ Xcmd_screen, "screen", 3, INIT, /* Screen WB/CUST */ Xcmd_send, "send", 4, SCRIPT, /* send string to host */ Xcmd_sendf, "sendfile", 5, SCRIPT, /* send a file to host */ Xcmd_share, "shareserial", 5, INIT|SCRIPT, /* ShareSerial device */ Xcmd_short, "shortcut", 3, INIT, /* Set shortcuts */ Xcmd_swap, "swap", 4, INIT|SCRIPT, /* Swap BS and DEL */ Xcmd_unit, "unit", 4, INIT, /* Unit of serial.device to use */ Xcmd_volume, "volume", 3, INIT, /* set volume */ Xcmd_wait, "wait", 4, SCRIPT|NONREXX, /* wait for a host string */ Xcmd_wb, "wbcolors", 3, INIT, /* use WB colors */ Xcmd_wrap, "wrap", 4, INIT|SCRIPT, /* turn wrap on or off */ Xcmd_xbeep, "xbeep", 4, INIT|SCRIPT, /* Beep at end of xfer */ Xcmd_xproto, "xprotocol", 5, INIT|SCRIPT, /* Xfer Protocol */ Xcmd_xr, "xr", 2, SCRIPT, /* xmodem receive file */ Xcmd_xs, "xs", 2, SCRIPT, /* xmodem send file */ Xcmd_null, NULL, 0, 0 /* mark the end of the list */ X}; X Xchar *xprotos[] = { /* Order *must* be same as corresponding p_xproto values */ X "ascii", "xmodem", "xmodemcrc", "kermit" }; X X/* NB: The structures referenced in the structure may be found in X** init.c */ Xextern struct filecmd { X char mo; /* Mode */ X char se; /* Send */ X char re; /* Receive */ X char kg; /* Kermit Get */ X char kb; /* Kermit Bye */ X char ca; /* Capture or Capturing */ X char nl; X} filecmd_chars; X Xextern struct mode_cmd { X char as; /* ascii mode */ X char xm; /* xmodem mode */ X char xmc; /* xmodem crc mode */ X char ke; /* kermit mode */ X char nl; X} modecmd_chars; X Xextern struct baducmd { X char b03; /* 0300 */ X char b12; /* 1200 */ X char b24; /* 2400 */ X char b48; /* 4800 */ X char b96; /* 9600 */ X char bnl; X} baudcmd_chars; X Xextern struct parcmd { X char no; /* NOne */ X char ma; /* MArk */ X char sp; /* SPace */ X char ev; /* EVen */ X char od; /* ODd */ X char nl; X} parcmd_chars; X Xextern struct commcmd { X char nl0; /* Baud Sub-Item */ X char nl1; /* Parity Sub-Item */ X char nl2; /* Xfer mode Sub-Item */ X char sh; /* Shared item */ X char nl; X} commcmd_chars; X Xextern struct modcmd { X char im; /* IMage */ X char tx; /* TeXt */ X char cn; /* CoNvert */ X char ac; /* AutoChop */ X char nl; X} modcmd_chars; X Xextern struct scrcmd { X char em; /* Execute Macro */ X char ab; /* Abort Macro */ X char rx; /* AREXX Macro */ X char nl; X} scrcmd_chars; X Xextern struct { X char sb; /* Send Break */ X char hu; /* Hang Up */ X char cd; /* Change Dir */ X char cs; /* Clear Screen */ X char ec; /* ECho */ X char wr; /* WRap */ X char nk; /* Num Key */ X char ac; /* App Cur */ X char bs; /* BS<->DEL */ X char xb; /* Beep at end of Xfer */ X char mu; /* Mouse up events */ X char md; /* Mouse down events */ X char nl; X} utilcmd_chars; X Xstatic struct SHORT_CUTS shortkeys[] = { /* Short-cut keys */ X /* File items: */ X "se", &(filecmd_chars.se), /* Send file */ X "re", &(filecmd_chars.re), /* Receive file */ X "kb", &(filecmd_chars.kb), /* kermit bye (for server) */ X "kg", &(filecmd_chars.kg), /* kermit get (for server) */ X "cap", &(filecmd_chars.ca), /* Capture */ X /* Mode items: */ X "asc", &(modecmd_chars.as), /* ascii mode */ X "xmc", &(modecmd_chars.xmc), /* xmodemcrc mode */ X "xm", &(modecmd_chars.xm), /* xmodem mode */ X "ke", &(modecmd_chars.ke), /* kermit mode */ X /* Comm items: */ X "share", &(commcmd_chars.sh), /* Shared */ X "300", &(baudcmd_chars.b03), /* Set Baud Rate */ X "1200", &(baudcmd_chars.b12), /* Set Baud Rate */ X "2400", &(baudcmd_chars.b24), /* Set Baud Rate */ X "4800", &(baudcmd_chars.b48), /* Set Baud Rate */ X "9600", &(baudcmd_chars.b96), /* Set Baud Rate */ X "none", &(parcmd_chars.no), /* Set Parity */ X "mark", &(parcmd_chars.ma), /* Set Parity */ X "space", &(parcmd_chars.sp), /* Set Parity */ X "even", &(parcmd_chars.ev), /* Set Parity */ X "odd", &(parcmd_chars.od), /* Set Parity */ X "image", &(modcmd_chars.im), /* KERMIT transfer mode */ X "text", &(modcmd_chars.tx), /* KERMIT transfer mode */ X "convert", &(modcmd_chars.cn), /* KERMIT transfer mode */ X "autochop", &(modcmd_chars.ac), /* XMODEM autochop */ X /* Script items: */ X "execute", &(scrcmd_chars.em), /* execute macro */ X "abort", &(scrcmd_chars.ab), /* abort macro */ X "rx", &(scrcmd_chars.rx), /* rexx macro */ X /* Util items: */ X "sb", &(utilcmd_chars.sb), /* send break */ X "hang", &(utilcmd_chars.hu), /* hang up */ X "cd", &(utilcmd_chars.cd), /* change directory */ X "clear", &(utilcmd_chars.cs), /* clear screen */ X "ech", &(utilcmd_chars.ec), /* turn echo on or off */ X "wrap", &(utilcmd_chars.wr), /* turn wrap on or off */ X "numkey", &(utilcmd_chars.nk), /* turn numeric kpad on/off */ X "app", &(utilcmd_chars.ac), /* turn app. cursor on/off */ X "con", &(utilcmd_chars.bs), /* convert bs to del */ X "swap", &(utilcmd_chars.bs), /* Swap BS and DEL */ X "xbeep", &(utilcmd_chars.xb), /* Beep at end of xfer */ X "mouseup", &(utilcmd_chars.mu), /* Mouse up events */ X "mousedn", &(utilcmd_chars.md), /* Mouse dn events */ X NULL, NULL X}; X Xstatic int cmd_from_script; /* != 0 iff cmd from a script */ X X X/********************************************************************/ X/* checks char to see if match with on string or wait_string */ X/* if on string match oncmd gets executed imediately, */ X/* if wait_string match script_wait is set. */ X/********************************************************************/ X Xchk_script(c) Xchar c; X{ X if (on_string[0] != '\0') { X if (on_string[onpos] == c) { X onpos++; X if (onpos == onsize) { X on_match = TRUE; X do_script_cmd(ONCOMMAND); X on_match = FALSE; X on_string[0] = '\0'; X on_cmd[0] = '\0'; X onpos = 0; X return(0); X } X } X else onpos = 0; X } X if (wait_string[0] != '\0') { X if (wait_string[waitpos] != c) { X waitpos = 0; X return(0); X } X waitpos++; X if (waitpos != waitsize) return(0); X wait_string[0] = '\0'; X script_wait = FALSE; X } X} X Xscript_start(file) Xchar *file; X{ X char *sfile = NULL; X X if (strlen(file) == 0 || *file == '#') return(0); X if ((sf = fopen(file, "r")) == NULL) { X sfile = AllocMem((LONG)(strlen(file)+3), MEMF_PUBLIC|MEMF_CLEAR); X strcpy(sfile, "S:"); X strcat(sfile, file); X if((sf = fopen(sfile, "r")) == NULL) { X InfoMsg2Line("Can't open script file",file); X return(0); X } X } X script_on = TRUE; X script_wait = FALSE; X wait_string[0] = '\0'; X on_string[0] = '\0'; X on_match = FALSE; X lbase = NULL; X if(sfile) X FreeMem(sfile, (LONG)strlen(file)+3); X} X X/* return pointer to next word. set l to size of the word */ X Xchar *next_wrd(s,l) Xchar *s; Xint *l; X{ X char *p; X X while(*s && (*s == ' ' || *s == '\t')) s++; X p = s; X while(*s && (*s != ' ' && *s != '\t')) s++; X *l = s-p; X return(p); X} X Xexe_cmd(p,l) Xregister char *p; Xint l; X{ X int i, l2, cmdrc = CMDOK; X register struct COMMAND *cmd; X X /* downcase the command */ X for (i=0; i<l; i++) p[i] |= ' '; X X errmsg[0] = '\0'; X X /* now search for it */ X for (cmd = commands; cmd->func != cmd_null; cmd++) { X int validfrom = cmd->validfrom; X X if(*p != cmd->cname[0]) X continue; X X l2 = strlen(cmd->cname); X if(l >= cmd->minlen && l <= l2 X && strncmp(p, cmd->cname, l) == 0) { X if( (!doing_init && (validfrom == INIT)) X || (((validfrom & NONREXX) == NONREXX) && CmdFromRexx) X || (((validfrom & REXXONLY) == REXXONLY) && !CmdFromRexx) ) X return(CMDBS); X X cmd_from_script = 1; X cmdrc = (*(cmd->func))(next_wrd(p+l, &l)); X cmd_from_script = 0; X if(errmsg[0]) X if(doing_init) { X puts("Init:"); X puts(errmsg); X } else X InfoMsg2Line("Script:", errmsg); X return(cmdrc); X } X } X#if AREXX X if(implied_rexx == 0 && RexxSysBase != NULL) { X implied_rexx = 1; X cmdrc = cmd_rx(p); X implied_rexx = 0; X return(cmdrc); X } X#endif /* AREXX */ X X if (doing_init) { X puts("Init: unknown command:"); X puts(p); X } else X InfoMsg2Line("Script - unknown command:",p); X X return(CMDNF); X} X Xstruct LABEL *find_label(lname) Xchar *lname; X{ X struct LABEL *label; X X label = lbase; X while(label != NULL) { X if (strcmp(label->name, lname) == 0) return (label); X label = label->next; X } X return(NULL); X} X Xdo_script_cmd(stat) Xint stat; X{ X int len,l; X char line[256]; X char *p; X X /* if ON command is matched and we were */ X /* doing a DELAY then abort the delay timer,*/ X /* except if on_cmd was just a SEND. */ X if (stat == ONCOMMAND) { X strcpy(line,on_cmd); X p = next_wrd(line,&l); X if (*p != 's' && script_wait == WAIT_TIMER) { X if(!CheckIO((struct IORequest *)&Script_Timer)) X AbortIO((struct IORequest *)&Script_Timer); X Wait (1L << Script_Timer_Port->mp_SigBit); X WaitIO((struct IORequest *)&Script_Timer); X X /* script will proceed after on command */ X script_wait = FALSE; X } X exe_cmd(p,l); X return(0); X } X script_wait = FALSE; X X if(CmdFromRexx) X return; X X while(fgets(line,256,sf) != NULL) { X len = strlen(line); X line[--len] = '\0'; X p = next_wrd(&line[0], &l); X if (*(p + l - 1) == ':') { /* its a label */ X *(p + l - 1) = '\0'; X if (find_label(p) == NULL) { /* it's a new label */ X if (lbase == NULL) { /* it's the first label */ X labels = lbase = (struct LABEL *) X malloc(sizeof (struct LABEL)); X } X else { X labels->next = (struct LABEL *) X malloc(sizeof (struct LABEL)); X labels = labels->next; X } X labels->pos = ftell(sf); X labels->name = malloc(l); X labels->next = NULL; X strcpy(labels->name, p); X if (stat == GOTOLABEL && strcmp(p, golabel) == 0) X stat = NEXTCOMMAND; X } X p = next_wrd(p+l+1, &l); X } /* end of it's a label */ X if (stat == GOTOLABEL || *p == '#') X continue; X if (*p) X exe_cmd(p,l); X return(0); X } /* end of while */ X if (stat == GOTOLABEL) X InfoMsg2Line("Script: label not found:",golabel); X exit_script(); X if(script_files_todo > 0) { X script_files_todo--; X script_start(*(script_files++)); X } X} X Xexit_script() X{ X if (script_wait == WAIT_TIMER) { /* timer not done yet */ X if(!CheckIO((struct IORequest *)&Script_Timer)) X AbortIO((struct IORequest *)&Script_Timer); /* so abort it */ X Wait (1L << Script_Timer_Port->mp_SigBit); /* Wait for the sig */ X WaitIO((struct IORequest *)&Script_Timer); /* Get my reply back */ X } X InfoMsg1Line("Script: terminated"); X script_on = FALSE; X script_wait = TRUE; X on_match = FALSE; X wait_string[0] = '\0'; X on_string[0] = '\0'; X on_cmd[0] = '\0'; X fclose(sf); X sf = NULL; X if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE)) X ActivateWindow(mywindow); X return 0; X} X X/* remove quotes terminate string & return pointer to start */ X Xchar *tostring(ptr) Xchar *ptr; X{ X register char *s1, *s2; X X if(*ptr == '\0') X return ptr; X X s1 = ptr; X if (*ptr == '"') { X while(*ptr++) { X if(*ptr == '"') X if(*(ptr+1) == '"') X ptr++; X else X break; X } X /* Only 2 ways out: encounter an single " or hit \0. */ X if (*ptr == '"') X *ptr = '\0'; X ptr = s2 = ++s1; X while(*s2) { X switch(*s2) { X case '"': X if(*(s2+1) == '"') X *s1++ = *s2++; X break; X case '^': X if(*(s2+1) == '^') X *s1++ = *s2++; X else X *s1++ = ((*++s2) | ' ') - 96; X break; X default: X *s1++ = *s2; X break; X } X s2++; X } X *s1 = '\0'; X return(ptr); X } X if (*s1 == '^') { X *s1 = (*(s1+1)|' ')-96; X *(s1+1) = '\0'; X return(s1); X } X *(s1+1) = '\0'; X return(s1); X} X X/***************************** SCRIPT COMMANDS ********************/ X Xcmd_goto(lname) Xchar *lname; X{ X struct LABEL *label; X /* if on_cmd was a goto kill wait state */ X if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; } X if ((label = find_label(lname)) == NULL) { /* is it forward */ X strcpy(golabel,lname); X do_script_cmd(GOTOLABEL); X } X else { X fseek(sf,(long)(label->pos),0); X } X return 0; X} X Xcmd_send(str) Xchar *str; X{ X register char *p = tostring(str); X int i, len = strlen(p); X X if(p_echo) X for(i = 0; i < len; i++) { X doremote(*p); X sendchar(*(p++)); X } X else X sendstring(p); X return 0; X} X Xcmd_wait(str) Xchar *str; X{ X int waitstrsize = sizeof(wait_string) - 1; X X str = tostring(str); X strncpy(wait_string, str, waitstrsize); X wait_string[waitstrsize] = '\0'; X waitsize = strlen(wait_string); X script_wait = WAIT_STRING; X return 0; X} X Xcmd_on(str) Xchar *str; X{ X char *p; X X p = tostring(str); X if( (onsize = strlen(p)) == 0) { X on_string[0] = '\0'; X on_cmd[0] = '\0'; X } else { X int onstrsize = sizeof(on_string) - 1, X oncmdsize = sizeof(on_cmd) - 1, X len; X X strncpy(on_string, p, onstrsize); X on_string[onstrsize] = '\0'; X p = next_wrd(p+onsize+1, &len); X strncpy(on_cmd, p, oncmdsize); X on_cmd[oncmdsize] = '\0'; X } X return 0; X} X Xcmd_delay(seconds) Xchar *seconds; X{ X script_wait = WAIT_TIMER; X Script_Timer.tr_time.tv_secs = atoi(seconds); X Script_Timer.tr_time.tv_micro = 0; X SendIO((struct IORequest *)&Script_Timer.tr_node); X return 0; X} X Xcmd_exit(option) Xchar *option; X{ X char *p; X int l; X X if (doing_init) X return 0; X X if (*option) { X p = next_wrd(option,&l); X *(p+l) = '\000'; X if (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0) X cleanup("Exit vt100 from script",0); X exit_script(); X script_start(p); X } X else { X exit_script(); X if(script_files_todo > 0) { X script_files_todo--; X script_start(*(script_files++)); X } X } X return 0; X} X Xcmd_ext(parms) Xchar *parms; X{ X struct ExternalXfer *cexp; X int i, j, len, nxfer, ci_strcmp(), cmdrc = CMDOK; X char *p, temp[80], bound, *send, *dn; X unsigned long mem_type = MEMF_PUBLIC | MEMF_CLEAR; X X parms = next_wrd(parms, &len); /* Step to start of display name */ X if(len <= 0) { /* No next word...error */ X strcpy(errmsg, "No display name for EXT command."); X return CMDFAIL; X } X X dn = parms; /* Remember start of display name */ X parms += len; /* Step to end of word */ X *(parms++) = '\0'; /* Mark end of display name and step beyond it */ X if(len > DNMAXLEN) { X *(dn+DNMAXLEN) = '\0'; X sprintf(temp, "Display name more than %d chars, 1st %d used in EXT %s", X DNMAXLEN, DNMAXLEN, dn); X if(doing_init) { X puts("Init:"); X puts(temp); X } else X InfoMsg2Line("Script:", temp); X cmdrc = CMDWARN; X } X X parms = next_wrd(parms, &len); /* Step to start of SEND cmd */ X X /* Find a matching ExternalXfer structure based on display name */ X for(i = 0; i < NumExts; i++) { X if(ci_strcmp(ExtXfer[i]->downname, dn) == 0) X if(len > 0) /* Replace this entry */ X break; X else { /* remove this entry from the list */ X struct ExternalXfer *p = ExtXfer[i]; X FreeMem(p->dispname, (long)(strlen(p->dispname)+1)); X FreeMem(p->downname, (long)(strlen(p->downname)+1)); X FreeMem(p->send, (long)(strlen(p->send)+1)); X FreeMem(p->receive, (long)(strlen(p->receive)+1)); X FreeMem(p, (long)sizeof(struct ExternalXfer)); X ExtXfer[i] = NULL; X for(j = i+1; j < NumExts; j++) X ExtXfer[j-1] = ExtXfer[j]; X NumExts--; X if(!doing_init) X InitFileItems(); X return; X } X } X nxfer = i; /* Remember index of match or where to put new... */ X cexp = ExtXfer[nxfer]; /* ...and its location. */ X X bound = *(parms++); /* Remember starting quote for SEND command and step over it */ X if((p = index(parms, bound)) == NULL) { X sprintf(errmsg, "No ending quote for SEND cmd in EXT %s", dn); X return CMDFAIL; X } X *p = '\0'; /* Replace ending quote with NULL */ X send = parms; /* Remember start of SEND cmd... */ X parms = ++p; /* ...and step over the NULL */ X X parms = next_wrd(parms, &len); /* Step to start of RECEIVE cmd */ X if(len <= 0) { X sprintf(errmsg, "No RECEIVE command for EXT %s", dn); X return CMDFAIL; X } X bound = *(parms++); X if((p =index(parms, bound)) == NULL) { X sprintf(errmsg, "No ending quote for RECEIVE cmd in EXT %s", dn); X return CMDFAIL; X } X *p = '\0'; X X if(cexp) { /* changing a current entry */ X FreeMem(cexp->dispname, (long)(strlen(cexp->dispname)+1)); X FreeMem(cexp->downname, (long)(strlen(cexp->downname)+1)); X FreeMem(cexp->send, (long)(strlen(cexp->send)+1)); X FreeMem(cexp->receive, (long)(strlen(cexp->receive)+1)); X cexp->cmdkey = '\0'; X } else if(nxfer >= EXTMAX) { X sprintf(errmsg, "EXT %s would add more than %d external protocols", X dn, EXTMAX); X return CMDFAIL; X } else { X cexp = (struct ExternalXfer *) X AllocMem((long)sizeof(struct ExternalXfer), mem_type); X ExtXfer[nxfer] = cexp; X NumExts++; X } X X /* Initialize the new ExternalXfer entry. Leave room in dispname for X ** a checkmark (2 character widths). */ X len = strlen(dn); X cexp->dispname = (char *)AllocMem((long)len+3, mem_type); X strcpy(cexp->dispname, " "); X strcat(cexp->dispname, dn); X cexp->downname = (char *)AllocMem((long)len+1, mem_type); X for(i = 0; i < len; i++) X cexp->downname[i] = dn[i] | ' '; X cexp->send = (char *)AllocMem((long)strlen(send)+1, mem_type); X strcpy(cexp->send, send); X cexp->receive = (char *)AllocMem((long)strlen(parms)+1, mem_type); X strcpy(cexp->receive, parms); X X if(!doing_init) X InitFileItems(); X return cmdrc; X} X Xcmd_ks(file) Xchar *file; X{ X char name[MAXGADSTR], *p; X X if(file) X strcpy(name, file); X else X name[0] = '\0'; X X if(file == NULL || *file == '\0' || !cmd_from_script) { X req("Kermit Send:",name,1); X p = name; X if(file && !cmd_from_script) X strcpy(file, name); X } else X p = file; X multi_xfer(p, doksend, 1); X return CMDOK; X} X Xcmd_kr(file) Xchar *file; X{ X char name[80]; X X name[0] = '\0'; X X multi_xfer(name, dokreceive, 0); X return CMDOK; X} X Xcmd_kg(file) Xchar *file; X{ X char name[MAXGADSTR], *p; X X if(file) X strcpy(name, file); X else X name[0] = '\0'; X X server = TRUE; X if(file == NULL || *file == '\0' || !cmd_from_script) { X req("Kermit GET remote file(s):", name, 1); X p = name; X if(file && !cmd_from_script) X strcpy(file, name); X } else X p = file; X multi_xfer(p, dokreceive, 0); X return CMDOK; X} X Xcmd_kb() X{ X saybye(); X return CMDOK; X} X Xcmd_recf(file) Xchar *file; X{ X int cmdrc = CMDOK; X X switch(p_xproto) { X case 0: /* Ascii */ X do_capture(file); X break; X case 1: /* Xmodem */ X case 2: /* XmodemCRC */ X if(p_parity > 0) { X InfoMsg1Line("Parity setting prevents XMODEM receive."); X break; X } X cmd_xr(file); X break; X case 3: /* Kermit */ X cmd_kr(file); X break; X default: X if(p_xproto > MODEMAX + NumExts - 1) X cmd_kr(file); X else X cmdrc = do_ext(ExtXfer[p_xproto-MODEMAX], X ExtXfer[p_xproto-MODEMAX]->receive, X file); X } X return cmdrc; X} X Xcmd_sendf(file) Xchar *file; X{ X int cmdrc = CMDOK; X X switch(p_xproto) { X case 0: /* Ascii */ X do_send(file); X break; X case 1: /* Xmodem */ X case 2: /* XmodemCRC */ X if(p_parity > 0) { X InfoMsg1Line("Parity setting prevents XMODEM send."); X cmdrc = CMDFAIL; X break; X } X cmd_xs(file); X break; X case 3: /* Kermit */ X cmd_ks(file); X break; X default: X if(p_xproto > MODEMAX + NumExts - 1) X cmd_ks(file); X else X cmdrc = do_ext(ExtXfer[p_xproto-MODEMAX], X ExtXfer[p_xproto-MODEMAX]->send, X file); X } X return cmdrc; X} X Xcmd_xs(file) Xchar *file; X{ X char name[MAXGADSTR], *p; X X if(file) X strcpy(name, file); X else X name[0] = '\0'; X X if(file == NULL || *file == '\0' || !cmd_from_script) { X req("Xmodem Send:",name,1); X p = name; X if(file && !cmd_from_script) X strcpy(file, name); X } else X p = file; X multi_xfer(p, XMODEM_Send_File, 1); X return CMDOK; X} X Xcmd_xr(file) Xchar *file; X{ X char name[MAXGADSTR], *p; X X if(file) X strcpy(name, file); X else X name[0] = '\0'; X X if(file == NULL || *file == '\0' || !cmd_from_script) { X req("Xmodem Receive:",name,1); X p = name; X if(file && !cmd_from_script) X strcpy(file, name); X } else X p = file; X multi_xfer(p, XMODEM_Read_File, 1); X return CMDOK; X} X Xcmd_cd(name) Xchar *name; X{ X set_dir(name); X return CMDOK; X} X Xcmd_sb(str) Xchar *str; X{ X sendbreak(); X return CMDOK; X} X Xcmd_baud(rate) Xchar *rate; X{ X int i = atoi(rate), X cmdrc = CMDOK; X X switch( i ) { X case 300: X case 1200: X case 2400: X case 4800: X case 9600: X if (doing_init) p_baud = i; X else setserbaud(i, TRUE); X break; X X default: X strcpy(errmsg, "Invalid baud rate: "); X strcat(errmsg, rate); X cmdrc = CMDFAIL; X break; X } X return cmdrc; X} X Xcmd_parity(par) Xchar *par; X{ X int i; X X switch( *par|' ' ) { X case 'n': i = 0; break; X case 'm': i = 1; break; X case 's': i = 2; break; X case 'e': i = 3; break; X case 'o': i = 4; break; X X default: X strcpy(errmsg, "Init: invalid parity: "); X strcat(errmsg, par); X return CMDFAIL; X } X p_parity = i; X if (doing_init == 0) X redocomm(); X return CMDOK; X} X X#if AREXX Xcmd_rx(cmd) Xchar *cmd; X{ X int cmdrc = CMDOK, X ret = do_rx(cmd, implied_rexx); X char *msg = NULL; X X errmsg[0] = '\0'; X if(ret) { X cmdrc = CMDFAIL; X if(doing_init) X printf("Init:\n%s\n", rexxerrmsgs[ret]); X else X InfoMsg2Line("Script:", rexxerrmsgs[ret]); X } X return cmdrc; X} X#else Xcmd_rx(cmd) Xchar *cmd; X{ X char *msg = "AREXX not compiled into this version."; X X if(doing_init) X printf("Init:\n%s\n", msg); X else X InfoMsg2Line("Script:", msg); X return CMDFAIL; X} X#endif X Xcmd_bt(breaklength) Xchar *breaklength; X{ X p_break = atol(breaklength); X if (doing_init) X return CMDOK; X X AbortIO((struct IORequest *)Read_Request); X Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit); X WaitIO((struct IORequest *)Read_Request); X Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break; X setparams(); X return CMDOK; X} X Xcmd_kmaxpk(pks) Xchar *pks; X{ X int i = atoi(pks), X cmdrc = CMDOK; X X if(i <= MAXLONGPKS) X p_kmaxpack = i; X else { X sprintf(errmsg, "Kermit packet size too big: %d", pks); X cmdrc = CMDFAIL; X } X return cmdrc; X} X Xcmd_mode(tmode) Xchar *tmode; X{ X switch (*tmode|' ') { X case 'i': X p_mode = 0; X break; X X case 'c': X p_mode = 1; X break; X X default: X strcpy(errmsg, "Init: invalid transfer mode: "); X strcat(errmsg, tmode); X return CMDFAIL; X } X if (doing_init == 0) X redocomm(); X return CMDOK; X} X Xcmd_as(file) Xchar *file; X{ X do_send(file); X return CMDOK; X} X Xcmd_cap(file) Xchar *file; X{ X do_capture(file); X return CMDOK; X} X Xcmd_beep(dummy) Xchar *dummy; X{ X if (p_volume == 0) X DisplayBeep(NULL); X else { X BeginIO((struct IORequest *)&Audio_Request); X WaitIO((struct IORequest *)&Audio_Request); X } X return CMDOK; X} X Xvoid setvar(par,typ,var) Xchar *par; Xint typ,*var; X{ X int i; X X switch (typ) { X case 0: /* ON/OFF or YES/NO */ X case 1: /* not case */ X if ((par[1]|' ') == 'n' || (par[0]|' ') == 'y') *var = 1-typ; X else *var = typ; X break; X X case 2: /* read hex number */ X if (sscanf(par,"%x",&i) == 1) *var = i; X X break; X X case 3: /* read decimal number */ X if (sscanf(par,"%d",&i) == 1) *var = i; X break; X } X} X Xcmd_ac(par) Xchar *par; X{ X setvar(par,0,&p_autochop); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_echo(par) Xchar *par; X{ X setvar(par,0,&p_echo); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_wrap(par) Xchar *par; X{ X setvar(par,0,&p_wrap); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_share(parm) Xchar *parm; X{ X int oldval = p_shared; X X setvar(parm, 0, &p_shared); X X if(Read_Request && (oldval ^ p_shared)) { X /* Port is going from shared->exclusive or vice-versa. Close it and X ** re-open */ X if(!CheckIO((struct IORequest *)Read_Request)) X AbortIO((struct IORequest *)Read_Request); X Wait (1L <<mySerPort->mp_SigBit); X WaitIO((struct IORequest *)Read_Request); X CloseDevice((struct IORequest *)Read_Request); X if(p_shared) X Read_Request->io_SerFlags |= SERF_SHARED; X else X Read_Request->io_SerFlags &= (-1L ^ SERF_SHARED); X if(OpenDevice(mysername,(LONG)p_unit,(struct IORequest *)Read_Request,NULL)) X cleanup("Can't re-open Read device",0); X InitCommItems(); X setparams(); X } X return CMDOK; X} X Xcmd_xbeep(par) Xchar *par; X{ X setvar(par,0,&p_xbeep); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_xproto(par) Xchar *par; X{ X int i, len, save, cmdrc = CMDOK; X X next_wrd(par, &len); X X p_xproto = MODEMAX + 1; /* Establish an out of bounds default */ X X if(len) { X par[len] = '\0'; X X /* downcase the parameter */ X for(i = 0; i < len; i++) par[i] |= ' '; X X for(i = 0; i < MODEMAX; i++) X if(strcmp(par, &(*(xprotos[i]))) == 0) { X p_xproto = i; X break; X } X } X if(p_xproto >= MODEMAX) { X /* Not a built-in protocol...check the defined external protocols */ X p_xproto = 0; X if(len > DNMAXLEN) { X save = *(par+DNMAXLEN); X *(par+DNMAXLEN) = '\0'; X } X for(i = 0; i < NumExts; i++) { X if(strcmp(par, ExtXfer[i]->downname) == 0) { X p_xproto = MODEMAX + i; X break; X } X } X X if(p_xproto == 0) { X p_xproto = MODEMAX - 1; X if(len > DNMAXLEN) X *(par+DNMAXLEN) = save; X sprintf(errmsg, "XPROTO beginning \"%.10s\" unknown, %s used", X par, &(*(xprotos[p_xproto]))); X cmdrc = CMDFAIL; X } X } X if(!doing_init) X redofile(); X return cmdrc; X} X Xcmd_numkey(par) Xchar *par; X{ X setvar(par,1,&p_keyapp); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_appcur(par) Xchar *par; X{ X setvar(par,0,&p_curapp); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_swap(par) Xchar *par; X{ X setvar(par,0,&p_bs_del); X if (doing_init == 0) X redoutil(); /* Calls InitUtilItems which does swap_bs_del() */ X else { X swap_bs_del(); /* Setup keys[] properly... */ X swap_bs_del(); /* ...for new mode */ X } X return CMDOK; X} X Xcmd_bkg(par) Xchar *par; X{ X setvar(par,2,&p_background); X return CMDOK; X} X Xcmd_bold(par) Xchar *par; X{ X setvar(par,2,&p_bold); X return CMDOK; X} X Xcmd_buf(par) Xchar *par; X{ X setvar(par,3,&p_buffer); X return CMDOK; X} X Xcmd_cursor(par) Xchar *par; X{ X setvar(par,2,&p_cursor); X return CMDOK; X} X Xcmd_depth(par) Xchar *par; X{ X setvar(par,3,&p_depth); X return CMDOK; X} X Xcmd_device(par) Xchar *par; X{ X int len, cmdrc = CMDOK; X char temp[80]; X X next_wrd(par, &len); X if(len > SERNAMESIZE) { X printf(temp, "Init:\nDevice parm too long, %s used", SERIALNAME); X strcpy(mysername, SERIALNAME); X cmdrc = CMDFAIL; X } else X strcpy(mysername, par); X return cmdrc; X} X Xcmd_display(str) Xchar *str; X{ X register char *p; X X for(p = tostring(str); *p; p++) X doremote(*p); X X return CMDOK; X} X Xcmd_fore(par) Xchar *par; X{ X setvar(par,2,&p_foreground); X return CMDOK; X} X X#if AREXX X/* This routine *depends* on the fact that the FORWARD command is only X** valid from AREXX. It then assumes that it can open RXSNAME. X**/ Xcmd_fwd(par) Xchar *par; X{ X int i; X X if(ForwardPortName != NULL) { X FreeMem(ForwardPortName, (LONG)strlen(ForwardPortName) + 1); X ForwardPortName = NULL; X } X X forwarding = 0; X X if(RexxSysBase == NULL) { X RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L); X if( (i = makerexxport()) != 0) { X strcpy(errmsg, rexxerrmsgs[i]); X return CMDFAIL; X } X } X X if(par && *par) { X if(ForwardPortName = AllocMem((LONG)strlen(par)+1, X MEMF_PUBLIC | MEMF_CLEAR)) { X strcpy(ForwardPortName, par); X forwarding = 1; X } else { X strcpy(errmsg, "Can't allocate memory for an AREXX forward port"); X return CMDFAIL; X } X } X X return CMDOK; X} X#else Xcmd_fwd(par) X{ X return CMDFAIL; X} X#endif /* AREXX */ X Xcmd_font(par) Xchar *par; X{ X char temp[80]; X int len, cmdrc = CMDOK; X X next_wrd(par, &len); X X temp[0] = '\0'; X X /* myfontname has been initialized from p_font in InitDefaults() in X ** init.c */ X X if(!len) { X sprintf(temp, "Init:\nNo font specified, \"%s\" used", myfontname); X cmdrc = CMDWARN; X } else { X if(*par && len) { X if(len < MAXFONTVARLEN) { X par[len] = '\0'; X strcpy(myfontname, par); X strcat(myfontname,FONTSUFFIX); X } else { X sprintf(temp, "Init:\nFont specification too long, \"%s\" used", X myfontname); X cmdrc = CMDWARN; X } X } X } X myattr.ta_Name = (STRPTR)myfontname; X if(*temp) X puts(temp); X return cmdrc; X} X Xcmd_fonts(par) Xchar *par; X{ X char temp[80]; X int len, size, cmdrc = CMDOK; X X next_wrd(par, &len); X X temp[0] = '\0'; X X /* myfontname has been initialized from p_font in InitDefaults() in X ** init.c */ X X if(!len) { X strcpy(temp, "Init:\nNo font size specified, \"8\" used"); X cmdrc = CMDWARN; X } else { X if(*par && len) { X size = atoi(par); X if(size > 0) X myattr.ta_YSize = size; X else { X myattr.ta_YSize = 8; X sprintf(temp, "Init:\nFont size \"%s\" invalid, \"8\" used", X par); X cmdrc = CMDWARN; X } X } X } X if(*temp) X puts(temp); X return cmdrc; X} X Xcmd_inter(par) Xchar *par; X{ X if(strcmp(par, "asis") == 0) X p_interlace = 2; X else X setvar(par,0,&p_interlace); X return CMDOK; X} X Xcmd_mouse(par) Xchar *par; X{ X switch (par[0]|' ') { X case 'b': X p_mouse_up = p_mouse_down = 1; /* send both */ X break; X X case 'o': X p_mouse_up = p_mouse_down = 0; /* mouse off */ X break; X X case 'u': X p_mouse_up = 1; /* up only */ X p_mouse_down = 0; X break; X X case 'd': /* down only */ X p_mouse_down = 1; X p_mouse_up = 0; X break; X default: X return CMDFAIL; X } X return CMDOK; X} X Xcmd_msg(par) Xchar *par; X{ X register char *p, *s; X int newline = 1; /* Whether we need to scroll */ X X for(s = p = tostring(par); *p; p++) { X if(*p == '\n') { X *p = '\0'; X InfoMsgNoScroll(s); X ScrollInfoMsg(1); X newline = 0; X s = p + 1; X } else if(*p == '\r') { X *p = '\0'; X InfoMsgNoScroll(s); X newline = 0; X s = p + 1; X } else X newline = 1; X } X if(*s) X InfoMsgNoScroll(s); X X if(newline) X ScrollInfoMsg(1); X return CMDOK; X} X Xcmd_lines(par) Xchar *par; X{ X setvar(par,3,&p_lines); X return CMDOK; X} X Xcmd_screen(par) Xchar *par; X{ X if ((par[0]|' ') == 'w') p_screen = 0; X else p_screen = 1; X return CMDOK; X} X Xcmd_unit(par) Xchar *par; X{ X setvar(par, 3, &p_unit); X return CMDOK; X} X Xcmd_wb(par) Xchar *par; X{ X setvar(par,0,&p_wbcolors); X return CMDOK; X} X Xcmd_short(par) /* Set keyboard shortcuts */ Xchar *par; X{ X int i, l, l2; X register char *p = par; X X /* downcase the next word */ X for (i=0; p[i] && (p[i] != ' ') && (p[i] != '\t'); i++) X p[i] |= ' '; X l = i; X X /* Find the command name. If found set the shortcut key to the X ** user's value. If no value then set the key to ' ' to indicate no X ** shortcut available. */ X for(i = 0; shortkeys[i].cname != NULL; i++) { X l2 = strlen(shortkeys[i].cname); X if (l >= l2 && strncmp(p, shortkeys[i].cname, l2) == 0) { X for( ; p[l] && ((p[l] == ' ') || (p[l] == '\t')) ; l++) X ; X if(p[l]) X *(shortkeys[i].pos) = p[l]; X else X *(shortkeys[i].pos) = ' '; X return CMDOK; X } X } X X /* Not a "normal" item so try an ExternalXfer item */ X p = next_wrd(par, &l); X if(l > 0) { X *(p+l) = '\0'; X for(i = 0; i < NumExts; i++) X if(strcmp(p, ExtXfer[i]->downname) == 0) { X p = next_wrd(p+l+1, &l); X if(l <= 0) X break; X ExtXfer[i]->cmdkey = *p; X return CMDOK; X } X } X X sprintf(errmsg, "Unknown shortcut: %s", par); X return CMDFAIL; X} X Xcmd_key(par) Xchar *par; X{ X int i; X X if (sscanf(par,"%x",&i) == 1) X p_keyscript = (char)(i & 0x7f); X return CMDOK; X} X Xcmd_volume(par) Xchar *par; X{ X setvar(par,3,&p_volume); X return CMDOK; X} X Xcmd_conv(par) Xchar *par; X{ X setvar(par,0,&p_convert); X if (doing_init == 0) X redoutil(); X return CMDOK; X} X Xcmd_fnc(par) Xchar *par; X{ X char *s; X int l; X int i = atoi(par); X X s = par; X if (*s) s = next_wrd(s,&l); /* skip key number */ X if (*s) s = next_wrd(s+l+1,&l); /* point at desired string */ X if (*s) s = tostring(s); /* convert the string */ X if(*par == 'm') { /* Mouse prefix */ X p_f[10] = malloc(strlen(s) + 1); X strcpy(p_f[10], s); X } else if (*s && i > 0 && i < 21) { X if (i > 10) { X p_F[i-11] = malloc(strlen(s)+1); X strcpy(p_F[i-11],s); X } X else { X p_f[i-1] = malloc(strlen(s)+1); X strcpy(p_f[i-1],s); X } X } X return CMDOK; X} X Xcmd_null(dummy) Xchar *dummy; X{ X return CMDOK; X} X X/* Case-insensitive strcmp() */ Xci_strcmp(p1, p2) Xchar *p1, *p2; X{ X while( *p1 && ((*p1 | ' ') == (*p2 | ' ')) ) { X ++p1; X ++p2; X } X return(*p1 != *p2); X} X Xdo_ext(exp, pgmname, file) Xstruct ExternalXfer *exp; Xchar *pgmname, *file; X{ X char *local = "@LOCAL", X *remote = "@REMOTE", X *command, X localfn[MAXGADSTR], X remotefn[MAXGADSTR], X *p, X *p1; X int len = 0, X locallen = strlen(local), X remotelen = strlen(remote); X X if(file) X strcpy(localfn, file); X else X localfn[0] = '\0'; X remotefn[0] = '\0'; X X /* Get the initial length of the command then go through the user's X ** command string looking for @LOCAL and @REMOTE. When we encounter one of X ** these strings then, if we don't already have the appropriate filename, X ** we'll put up a requester asking for it. Whether we put up the requester X ** or not we must still account for the length of the replacement filename X ** so that when we AllocMem() for the command we'll only get what we need. X */ X len = strlen(pgmname) + 1; X for(p = pgmname; *p; p++) { X if(*p == '@') X if(strncmp(p+1, local+1, locallen-1) == 0) { X if(!cmd_from_script || localfn[0] == '\0') X req("Local file name:", localfn, 1); X if(!localfn[0]) /* No filename specified */ X return CMDFAIL; X if(file && !cmd_from_script) X strcpy(file, localfn); X len += strlen(localfn); X len -= locallen; X p += locallen; X } else if(strncmp(p+1, remote+1, remotelen-1) == 0) { X req("Remote file name:", remotefn, 1); X if(!remotefn[0]) /* No filename specified */ X return CMDFAIL; X len += strlen(remotefn); X len -= remotelen; X p += remotelen; X } X } /* for p = pgmname */ X X /* Allocate space for the command and copy the command string to it X ** replacing @LOCAL and @REMOTE with localfn and remotefn, respectively */ X command = AllocMem((long)len, MEMF_PUBLIC | MEMF_CLEAR); X if(localfn[0] || remotefn[0]) { X for(p = pgmname, p1 = p; *p; p++) { X if(strncmp(p, local, locallen) == 0) { X strncat(command, p1, p - p1); X strcat(command, localfn); X p += locallen; X p1 = p; X } else if(strncmp(p, remote, remotelen) == 0) { X strncat(command, p1, p - p1); X strcat(command, remotefn); X p += remotelen; X p1 = p; X } X } X strcat(command, p1); /* Don't forget the tail of the command! */ X } else strcpy(command, pgmname); X X /* Close down VT100's use of the serial port */ X if(!CheckIO((struct IORequest *)Read_Request)) X AbortIO((struct IORequest *)Read_Request); X Wait (1L <<mySerPort->mp_SigBit); X WaitIO((struct IORequest *)Read_Request); X if(!p_shared) X CloseDevice((struct IORequest *)Read_Request); X X Execute(command, 0L, 0L); /* Invoke the external xfer pgm */ X FreeMem(command, (long)len); X if(!p_shared && OpenDevice(mysername,(LONG)p_unit,(struct IORequest *)Read_Request,NULL)) X cleanup("Can't re-open Read device",0); X setparams(); X return CMDOK; X} SHAR_EOF echo "End of archive 7 (of 9)" # if you want to concatenate archives, remove anything after this line exit