ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)
Program Name: vt100 (version 2.8) Submitted By: acs@uts.amdahl.com (Tony Sumrall) Summary: vt100 terminal emulator. Poster Boy: Brent Woods (ahh@j.cc.purdue.edu) Tested. Part 1 of 4. NOTES: This program was tested by our Guest Moderator, Robert Tillotson. He had a couple of problems with the program at first (a couple of Guru errors, and we think that the vt100 task hung around instead of exiting properly; not certain, though), but when we (Rob, Pat, and I) tested it a few hours ago, none of us had any problems. I dunno. It seems to work okay now. Probably some fluke or other. Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga USENET: ...!j.cc.purdue.edu!ahh ARPANET: ahh@j.cc.purdue.edu BITNET: PODUM@PURCCVM PHONE: +1 (317) 743-8421 USNAIL: 320 Brown St., #406 / West Lafayette, IN 47906 ================================================================ #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 acs other 15758 Feb 1 18:52 README # -rw-r--r-- 1 acs other 24525 Feb 1 18:52 vt100.doc # -rw-r--r-- 1 acs other 860 Feb 1 18:52 Logon # -rw-r--r-- 1 acs other 1461 Feb 1 18:53 Makefile # echo 'x - README' if test -f README; then echo 'shar: not overwriting README'; else sed 's/^X//' << '________This_Is_The_END________' > README XThis archive contains a vt100 emulator with KERMIT and XMODEM file Xtransfer protocols. Original work by Dave Wecker, V2.7-V2.8 by Tony Sumrall. X XThanks: X------- X To everyone who sent in code, suggestions and fixes! X XReleases: X--------- X v2.8 880117 ACS - See Release Notes. X v2.7 870825 ACS - See Release Notes. 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 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 v2.0 860823 DBW - Major rewrite X v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes X v1.0 860712 DBW - First version released X XUsage: X------ X Please read VT100.DOC for usage information and examples. X XRelease Notes: X-------------- Xv2.8 880117 ACS - Info/Status window automatically deselected. X - 1st menu item re-worked. Now the user need only choose Send, X Receive, Kermit Get, Kermit Bye and Capture. Protocol to send or X receive is selected via the 1st sub-menu from the 1st menu item. X - New command: XPROTO XMODEM | XMODEMCRC | ASCII | KERMIT to select X transfer protocol via scripts. X - User may capture simultaneously with sending or receiving via X a different protocol by using the Capture menu item. This item X changes to Capturing when capture is in effect. X - Kermit will transfer long packets (up to 1000 bytes). New cmd: X "KMAXPACK n" sets maximum packet length to n bytes. Remember to X increase your send and/or receive timeouts on your host!!! X - Added insert/delete character to the recognized escape sequences. X ESC [ n @ inserts n characters, ESC [ n P deletes n characters X (thanks to John Wang (jwang@ATRP.MEDIA.MIT.EDU)). He suggests X using the following termcap: X CA|vt100|amiga|Amiga termcap:al=\E[L:AL=\E[%dL:am:bl=^G:bs:cd=\E[J:\ X :ce=\E[K:cl=\E[;H\E[2J:cm=\E[%i%d;%dH:co#80:cr=^M:cs=\E[%i%d;%dr:\ X :dc=\E[P:DC=\E[%dP:dl=\E[M:DL=\E[%dM:do=^J:ho=\E[H:\ X :is=\E[1;24r\E[24;1H:ic=\E[@:IC=\E[%d@:kb=^H:kd=\E[B:\ X :ke=\E[?1l\E>:kl=\E[D:kr=\E[C:ks=\E[?1h\E=:ku=\E[A:k1=\EOP:\ X :k2=\EOQ:k3=\EOR:k4=\EOS:le=^H:li#24:mb=\E[5m:md=\E[1m:me=\E[m:\ X :mr=\E[7m:nd=\E[C:pt:rc=\E8:rf=/usr/lib/tabset/vt100:\ X :rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:sc=\E7:se=\E[m:\ X :sf=^J:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:vc#16:vt#3:xn: X - Fixed scroll regions. Now will not wrap-around out of a scroll X region. (thanks to Tad Guy (ames!xanth.cs.odu.edu!tadguy)) X - Fixed the FileLock() problem (thanks to many!). X - The "nagging requester" bug was a bug in *my* code (gasp!). Thanks X to Joel Swank (joels@tekred.TEK.COM) for finding and squashing it! X - Fixed overzealous xmodem chopping. It now strips contiguous X strings of nulls OR Ctrl-Z (not a mixture) and will avoid writing X anything if they were all chopped. Thanks to Wayne Davison X (drivax!davison--I only had to modify it a little, Wayne). Also, X when sending, it now sends a stream of nulls OR Ctrl-Zs, whichever X is NOT the last character. X - Removed an extraneous continue in readchar(). Thanks to someone! X (Sorry, I lost your name and address.) X - Now uses the default keymap. All of the old mappings have been X retained (e.g. Ctrl-2 generates Ctrl-@, Ctrl-6 generates Ctrl-^, X ALT acts as META key (i.e. sets the high-order bit)). Note, X however, that your keymap may preclude the use of the ALT key if X dead keys are defined. A future version will support specification X of a keymap different from the system map. X - New commands: SENDF file-spec and REC file which will send/receive X via the default XPROTO setting. You still have XS, KR, etc. X - New command: FONT font-name. Allows the user to specify which X 8-point font to use. If you want to use your new whippy-font, sau X FONT whippy-font. These must be 8-point fonts for now! X - Saying LINES 0 will use all available lines on the screen (useful X to you MoreRows groupies). X - P_unit may be changed in vt100.c to specify a different unit of X the serial.device to use (for expansion serial ports). As of this X writing there are no expansion serial devices...this is just in X preparation for the future. Also provided a new INIT command: X UNIT which accomplishes the same result. Xv2.7 870825 ACS - Requester is only used for input. A new window (the X Info/Xfer Status window) now shows what used to go there and the X requester now comes up in this window. The window is sizable, X draggable, closeable and front-to-backable; when re-opened it X will appear in its last location with its last dimensions. The X window ignores input but will become active when it's first X displayed as well as when a requester is put up in it. To X cancel a transfer request, first ensure that the mail VT100 X windiw is active then hit ESC in it. X - KERMIT mode has been hardened and wildcarded files can be sent X to a KERMIT that is *not* in server mode. E.g. you may say X RECEIVE to your host's KERMIT then send Foo* -- all files X starting with Foo in the current directory will be sent. X - New command line switches -i and +i. -I says don't use an init X file, +i file says use "file". User may also specify script X files on the command line which will be executed in sequence. X - New init file command SHORTCUT. See vt100.doc. X - I've included the font code. It looks for an env variable named X "font" (yes, lowercase) and, if found, uses that font for its X test. If you don't like it you may wanna remove it. I was gonna X ifdef it but I ran out of time. Remember that there's a PD set X cmd to allow Lattice users to set env vars. X - Nagging bug: On 2nd and subsequent uses of the requester, the X 1st character of the last use is redisplayed. Intuition bug? Xv2.6 870227 DBW - bug fixes for all the stuff in v2.5 X - Input requestors are now self selecting (ignore comment in 2.5) X - Added a BS<->DEL menu item and startup option (SWAP ON/OFF) X - Renamed dopen/dnext/dclose to diropen/dirnext/dirclose for LATTICE X - Added a CONVERT option that tells whether KERMIT should downcase X - MAJOR CHANGE: re write the INPUT/SCRIPT commands, see VT100.DOC X - Fixed a major problem with Set Directory causing LOCK conflicts X - Moved the Title up 1 pixel so that it doesn't get cut off anymore Xv2.5 870214 DBW - more additions (see readme file) X - All prompting now done through a string requester/gadget. X NOTE: YOU MUST SELECT THE INPUT STRING OF THE REQUESTER BEFORE X YOU CAN TYPE A RESPONSE. X - Local echo mode added (half duplex for Carolyn) X - BEEP command added to SCRIPT X - New menu/init/script items: X CLEAR SCREEN - clears the screen X ECHO - turns on/off half duplex mode X WRAP - turns on/off autowrap on long lines X NUMKEY - turns on/off numeric keypad mode X APPCUR - turns on/off application cursor mode X - Rewrote toasc() to use qualifier field (no more getting the X keyboard "stuck") X - Fixed locking of directories (should now run under workbench ok) X - Cleaned up VT100.H to really check includes on compile X - Setting font explicitly to TOPAZ 8 (no more dumb assumptions) X Xv2.4 861214 DBW - lots of fixes/additions X - Beep should now work under Lattice X - CreatePort now passes longs (as it should always have) X - Nested comments in KERMIT.C removed X - Beep volume of 0 (DisplayBeep) now works X - snum[] declaration in KERMIT.C fixed X - multi_xfer is now void and return fixed (in kermit) X - "." can no longer get "stuck" as the break key X X - RIGHT-AMIGA-keys have been added for most menu items X - The ALT key is now an EIGHTth bit shifter X - Control-@, Control-2, Control-space send the NULL character X - Control-6 now sends Control-^ X - Control-- and Control-? now sends Control-_ X - Cursor application mode (<esc>[?1h and <esc>[?1l) now work X - XMODEM now masks the eighth bit if parity is other than NONE X Xv2.3 861101 DBW - minor bug fixes: X - added p_wbcolors to allow workbench colors on custom screen X (In the init file you can specify WBCOLORS to be NO (use color X definitions in INIT FILE or VT100.H) or YES (use WORKBENCH X colors for everything)). X - "$" now sends a kermit-bye (like it says in VT100.DOC). X - made window/screen heights more reasonable X - Added ANSI insert line and delete line (<csi><num>L and X <csi><num>M) to speed up various editors (like emacs). X NOTE: This is NOT a VT100 sequence (new extension). X - ctrl-space now also sends a null (along with ^@ and ^`) X - RAWKEY fixed in WINDOW.C X - p_wrap fixed in WINDOW.C X - removed WRDMAX from VT100.H X - fixed exit with no params in SCRIPT.C X - fixed parity comparisons in KERMIT.C X - init file [n+1] changed to [nplus1] to make Lattice happy. X - cursoron(), cursoroff() changed to one routine cursorflip(). X - long lines shortened to less than 80 characters (for gateways). X - blanks following exit (or comments) now work in scripts. X Xv2.2 861012 DBW - more of the same: X - The INIT file "exit" can now chain to a script X - The SCRIPT command "exit" can now chain to another script X - Hangup menu item now works. X - Autowrap can now be set from VT100.H, VT100.INIT (<esc>[?7h l) X - Control-G is now handled with an audible beep X - Script now used "^chr" to send control characters X - The graphics "box" character (a) was added X - Control-@ and Control-` now send the NULL character X - Alternate color for BOLD has been re-instated by popular demand X - Menus have been cleaned up. X - Lattice compilation cleaned up. X - No more wordsize parameter since PARITY takes care of all cases X - Function keys can now call scripts X - Double shift keys are now handled correctly. X - Version has been added to the title bar (for bug reports). X Xv2.1 860915 DBW - new features / bug fixes X - Now identifies as a VT100 (including the response to <esc>Z) X - Cursor color now gets read in as hex (instead of decimal) X - REPORTMOUSE taken out of definitions (not needed) X - XON/XOFF now being handled by the device driver instead of me X - Literal escape characters have been replaced with \033 X - At init time the user can now specify the input BUFFER size X (typically between 512 and 2048 bytes) depending on baud rate X - Script files are now case insensitive for commands X - XMODEM now turns off the driver XON/XOFF during transfers X - Graphic rendition now done by the OS instead of me. X - Initialization files are now searched for in S: instead of C: X - Forward GOTO bug fixed in the script package. X - Keypad can now be used in both numeric and application mode X - General purpose cleanup() routine added for all exits. X - Utility menu added (sendbreak, hangup, change directory). X NOTE: hangup is not implemented yet. X - Full wild card support in file transfers (see vt100.doc). X - Kermit cleaned up with better filename handling (from host). X - Script now has CD (changed directory) and SB (send break) commands X - Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu X and scripts. (Generates parity from a table). X - Added 8th bit quoting in KERMIT when using 7 bit words (ODD or X EVEN parity). X - Break time can be set from VT100.H, VT100.INIT or a script file. X - Transfer mode (image or CRLF) can now be set from a script file. X - Control characters in escape sequences now act like a true VT100. X - F10 now works from init files. X - Right (or Left) AMIGA with period (".") sends a BREAK to the host X from the keyboard. X - XMODEM status kept down to one line for a file transfer. X Xv2.0 860823 DBW - Major rewrite: X - Emulator now compiles under either MANX or LATTICE by defining X the appropriate compiler type in VT100.H. X - Sped up code to an effective baud rate of (about) 8k. This means X that clear text at 4800 baud should be no problem. X - Added XON/XOFF generation so that characters should not get lost X any more at 9600 baud (when receiving clear text). X - Got rid of all command line switches and environment variables. X Instead upon invocation the program searches first for any file X named on the command line, then looks for VT100.INIT in the X current directory and finally searches for C:VT100.INIT. X All parameters can be set in the init file, and a sample VT100.INIT X is provided in VT100.DOC that shows all possible options. X - All parameters that are set by VT100.INIT are defined in VT100.H X (variables starting with "p_"). This allows you to compile your X own defaults into the code. X - You can now set the number of lines (for all you EMACS freaks :-). X On an interlaced screen this gives you upto a 48 line terminal. X - WORKBENCH colors are NEVER touched. X - In an attempt to keep the size down, the color palette menu item X has been removed (current). Code is about 36K in size with a X run time image (using workbench screen) of about 88k. X - Many bugs fixed including reverse scrolling with descenders, X reverse video at end of line, clearing with scrolling regions, X ... and 20 or more others. X - File capture now no longer sends the filename to the host. X - BOLD (<esc>[1m) has now been added by using an additional color X when you specify a depth of 2 (instead of 1) bitplane. X - UNDERLINE (<esc>[4m) has now been added. X - The handling of remote (host) escape sequences has been completly X re-written (thanks to Dawn Banks for all the work). X - Function keys (and shifted function keys) can now be bound to X arbitrary strings (Jim Ravan gets his macros). See VT100.DOC X for details. X - Cursor has no been reduced to the size of a normal character for X easier readability. X - XMODEM has been improved (by Steve Drew) to use a timer device X (for timeouts) and to abort immediately if the user types <ESC>. X - KERMIT has been completely re-written and appears to work fine, X thanks to the efforts of Steve Drew. X - New menu item allows script file support. Module written by X Steve Drew. See VT100.DOC for details. X XKnown problems: X--------------- X none X XSuggestions/bug fixes not implemented (as of yet): X-------------------------------------------------- X - Custom screen should use a borderless backdrop window X - Quit from keyboard should be supported (for above) X - Automatic maximum sizing of window should happen X - Screen should be resizable X - AT TIME should be implemented in scripts (besides DELAY) X - Kermit should create sub directories (when necessary) X - Use a disk font for graphic character set X - Allow the mouse to be sent to the host (for various EMACSs) X - Kermit VM/CMS (IBM) protocol support (it works for me, how about X you?) X - Allow the user to use a keymap different from the default one. X - Allow use of an "external" transfer protocol. X - Allow use of other than 8-point fonts. X XInstallation: X------------- X The files in this archive may be extracted by the bourne shell X (/bin/sh) or the shar program using the "unshar switch (-u)", X contact me if you need a copy of this version of shar. X X REMEMBER: Set the correct compiler definition in VT100.H X XFiles: X------ X README - this file X vt100.doc - documentation for the terminal emulator X makefile - make file for the emulator (under MANX AZTEC-C) X vt100.h - include file used by all other modules X window.c - manager for window and keyboard X vt100.c - main module, handles menus X remote.c - handle remote characters (vt100 emulation) X kermit.c - kermit protocol (to transfer text files on VMS X select the CRLF option on the transfer mode menu, X otherwise use image mode). X init.c - startup code X xmodem.c - xmodem protocol that understands AMIGA binary and X text file formats (automatically). X script.c - script control package X expand.c - filename expansion (wildcards) and dir setting X XContact: X-------- XPlease send bugs/comments/suggestions/praise for V2.8 to: X X Tony Sumrall at USENET: acs@amdahl.com ________This_Is_The_END________ if test `wc -l < README` -ne 314; then echo 'shar: README was damaged during transit (should have been 314 bytes)' fi fi ; : end of overwriting check echo 'x - vt100.doc' if test -f vt100.doc; then echo 'shar: not overwriting vt100.doc'; else sed 's/^X//' << '________This_Is_The_END________' > vt100.doc XThis is the documentation file for the VT100 terminal emulator originally Xby Dave Wecker. Versions 2.7-2.8 are by Tony Sumrall. I can be reached Xon USENET => acs@amdahl.com X XDave can be reached via: X X Dave Wecker at ENET: COOKIE::WECKER X ARPA: wecker%cookie.dec.com@decwrl.dec.com X USENET: {decvax|decwrl}!cookie.dec.com!wecker X SNAIL: Dave Wecker X 115 Palm Springs Drive X Colorado Springs, CO 80908 X XNote that Dave had NOTHING to do with this release. Don't bother him with Xproblem in my code. X X XMANY pieces of code/suggestions have been sent in.. X X thanks to all! X XIn particular, I'd like to thank Kim DeVaughn (kim@amdahl.com) for his Xhelp in testing this release. We went through a lot together. X XProgram startup: X---------------- X 1> vt100 [-i | +i initfile] [ scriptfile ... ] X X - -i option means don't look for an init file; +i means X look for an init file of this name. The search for the X init file will be the current directory then S:. Of X course you can always override this by saying C:file if X you like. The format for the init file is described X later in this document. X X - The init file controls the setting of initial defaults X and screen and macro definitions. X X - If none of the files (listed above) are found, the X built-in defaults (defined in VT100.C as variables, X beginning with "p_") are used. X X - All commands are either menu or script based. Scripts X are described below. X XMenus (Commands in parenthesis are default keyboard bindings: Right-Amiga-chr): X----------------------------------------------------------------------- XFile - file transfers X Protocol - Sets the protocol to be used for send/rec. X ASCII - use uncontrolled protocol X Xmodem (A-X) - use the ever-popular Xmodem Checksum X XmodemCRC - use the in demand Xmodem CRC X Kermit (A-K) - my favorite protocol X Send (A-^) - Send a file using the selected protocol X Receive (A-V) - Receive a file as above X Kermit Get (A-G) - Get files from a kermit server X Kermit Bye (A-B) - Finish with the kermit server. X Capture - Log received text to a file. Changes to X Capturing when in progress XComm Setup - Setup communications X Baud Rate - Set the terminal baud rate X 300 X 1200 (A-L) X 2400 (A-H) X 4800 X 9600 X Parity - Type of parity X NONE (A-X) X MARK X SPACE X EVEN (A-E) X ODD (A-O) X Xfer Mode X Image (A-I) - Send files verbatim (for UNIX hosts or X binary files) X Text (A-T) - Send CR LF as line terminator and strip X CR on received files (VMS text). X Convert - Should KERMIT convert fnames to lower case XScript - Script commands X Execute Macro (A-M) - Start up an asynchronous script file X Abort Execution (A-A) - Terminate a script file XUtility - Utility commands X Send Break (A-.) - send a break to the host X Hang Up - close line (not implemented yet) X Change Dir (A-D) - change the local directory (for transfers) X Clear Scrn - clear the screen (initial state) X Echo - turn on/off half duplex mode X Wrap (A-W) - turn on/off long line wrapping mode X Num Key (A-K) - turn on/off numeric keypad mode X App Cur (A-C) - turn on/off application cursor mode X BS<->DEL - swap backspace and delete keys X XKeypad mapping (in application keypad mode): X-------------------------------------------- X X AMIGA VT100 comments X ------- ------- --------------------------- X 0-9 == 0-9 X . == . X ENTER == ENTER (basically, flip the bottom X - == , 2 keys up to get a VT100) X HELP == - (only free key around) X f1-f4 == PF1-PF4 (or any rebinding you do) X arrows == arrows X XNote: Right AMIGA key in conjunction with a period (".") X will send a break to the host. X X CTRL in conjunction with an at-sign ("@") a two ("2") or a X space (" ") will send a NULL to the host. X X CTRL in conjunction with a six ("6") will send a CTRL-^ X CTRL in conjunction with a dash ("-") or question mark ("?") X will send a CTRL-_ to the host. X XMulti file Xfers: X----------------- XThe VT100 emulator supports multiple file transfers. This is Xspecified by using a comma (",") between file names when using XMODEM Xor KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file Xtransfers). X XWhen specifying a file name to recieve by default the directory path Xis stripped off of the filename when sent to the host but is kept for the Xlocal file spec. eg: X X receive file: ram:file.txt,df1:newfile.bin,$ X Xwill ask the server for file.txt and put it in ram:, and get Xnewfile.bin and put it on df1: (see explanation of "$" below). If you Xdo a single file transfer you will get another prompt for the remote Xname e.g.: X X receive file: ram:file.txt X remote file name [file.txt]: userdisk1:wantfile.txt X XThe same rules apply to sending multiple files therefore if you are Xdoing multi file transfers make sure the host server is connected to Xthe desired directory. X XIn addition KERMIT supports wildcards: X * = any number of characters X ? = any single character XExamples: X send: *.c,*.h,*.doc X get: *.c,*.h,$ X XNote that in this release, wilcarded files may be sent to a KERMIT that is X*not* in server mode (e.g. you can say "RECEIVE" to the host KERMIT and Xsend *.c files successfully). X XKERMIT receive is now smart enough to use the host filename so no Xfilename needs to be specified on the AMIGA's side (see the CONVERT option). X XIf your host is capable of sending or receiving long packets (packets in Xexcess of 94 bytes) you may set p_kmaxpack to some number <= 1000. The script Xcommand KMAXPACK can accomplish the same result. X XInitialization and Script file operation: X----------------------------------------- XAn initialization file (as described in the "Program Startup" section) Xmay contain any of the commands shown below that have the word INIT in Xtheir description below. Commands that are available from scripts have Xthe word SCRIPT in the descriptions below. All commands may be abbreviated Xto 3 letters and are case insensitive. X XThe script file can be invoked by selecting 'execute file' from the Xscript menu. At any time you can abort the script file by selecting X'Abort Execution'. You may also invoke a script from a function key if Xthe first character of the function key definition is the KEYSCRIPT Xcharacter (e.g., define F5 as "~df1:foo.script"). X XDuring the time script file is running the terminal emulation is still Xactive and you may type simulataneous to the script file. This may be Xdesired if your script file is WAITing for a string or is DELAYing for Xa period of time etc. X XInitialization and Script file Commands: X---------------------------------------- X# Commented line (INIT,SCRIPT) X Format: X # This line is a comment X------------------------------------------------------------ XAPPCUR Set the application cursor mode (INIT,SCRIPT) X Format: X APPCUR ON/OFF or YES/NO X------------------------------------------------------------ XASCII_SEND Send an ascii file to the host. (SCRIPT) X Format: X (same format as CAPTURE) X------------------------------------------------------------ XBACKGROUND Define a background color (INIT) X Format: X BACKGROUND hex three digit hex number X Example: X BACKGROUND F00 bright red background X------------------------------------------------------------ XBAUD Set baud rate (INIT,SCRIPT) X Format: X BAUD rate Sets the baud rate for send/receive X Example: X BAUD 2400 Sets the baud rate at 2400 baud X------------------------------------------------------------ XBEEP Beep at the console (SCRIPT) X Format: X BEEP X------------------------------------------------------------ XBOLD Define a color for bold (INIT) X Format: X (same as BACKGROUND) X------------------------------------------------------------ XBREAK Set the break time (for an SB command) (INIT,SCRIPT) X Format: X BREAK value Value is in micro-seconds X Example: X BREAK 750000 X------------------------------------------------------------ XBUFFER Set transmission buffer size (INIT) X Format: X BUFFER n Number of bytes to buffer X Example: X BUFFER 512 X------------------------------------------------------------ XCAPTURE To start/stop ascii file capture. (SCRIPT) X Format: X CAPTURE file Start ascii capturing X CAPTURE End ascii capturing X------------------------------------------------------------ XCD To change the local directory (SCRIPT) X Format: X CD newdir set a new directory for file transfers X Example: X CD DF1:foo/bar set the directory as specified X------------------------------------------------------------ XCONVERT Tell KERMIT whether or not to convert filenames (INIT,SCRIPT) X Format: X CONVERT ON/OFF or YES/NO X Example: X CONVERT ON Filenames will be down cased X------------------------------------------------------------ XCURSOR Define a color for the cursor (INIT) X Format: X (same as BACKGROUND) X------------------------------------------------------------ XDELAY Suspends script file for a specified time (SCRIPT) X Format: X DELAY n Suspends execution for n seconds X Example: X DELAY 2 Suspends for 2 seconds X------------------------------------------------------------ XDEPTH Define the depth of the window/screen (INIT) X Format: X DEPTH n Number of planes in window/screen X Example: X DEPTH 1 Minimum depth X DEPTH 2 Same as Workbench X------------------------------------------------------------ XECHO Turn on/off local echo (INIT,SCRIPT) X Format: X ECHO ON/OFF or YES/NO X Example: X ECHO ON Half duplex mode X------------------------------------------------------------ XEXIT Ends execution of the current script file. (INIT,SCRIPT) X Format: X EXIT Exit the current script/init file X EXIT VT100 Exit vt100 program (from SCRIPT only) X EXIT newscript Exit this file and start up newscript X Example: X EXIT DF1:FOO.BAR Exit the current file and start FOO.BAR X------------------------------------------------------------ XF Define a function key (INIT,SCRIPT) X Format: X F n string Define Function key n to be string X Example: (see SEND for string format) X F 1 "dir^M" Define F1 is the string dir<cr> X F 11 "help" Define Shifted F1 as the string help X F 20 ^C Define Shifted F10 as a control-C X------------------------------------------------------------ XFONT Specify font to use (INIT) X Format: X FONT 8-point-font-name X Example: X FONT whippy-8-point-font X------------------------------------------------------------ XFOREGROUND Define a color for the foreground (INIT) X Format: X (same as BACKGROUND) X------------------------------------------------------------ XGOTO Jumps to a different part of the script file. (SCRIPT) X Format: X GOTO label Jumps to a line beginning with label: X Jumps may be forward or backward. X Example: X FOO: Sets up a label X ... X GOTO FOO Jumps to FOO X------------------------------------------------------------ XINTERLACE Turn on/off interlace (INIT) X Format: X INTERLACE ON/OFF or YES/NO X Example: X INTERLACE ON Use interlacing X------------------------------------------------------------ XKB Send a BYE packet to a host KERMIT server. (SCRIPT) X Format: X KB Shut down server. X------------------------------------------------------------ XKEYSCRIPT Define a new keyscript character (INIT,SCRIPT) X Format: X KEYSCRIPT hex New character in hex X Example: X KEYSCRIPT 7E Use "~" as the new character X------------------------------------------------------------ XKG Gets files from host. (SCRIPT) X Format: X (same format as KS) Get from server X------------------------------------------------------------ XKMAXPACK Set maximum packet size for kermit transfers (INIT,SCRIPT) X Format: X KMAXPACK n Set maximum packet size to n X Example: X KMAXPACK 1000 Use long packets if possible. Don't forget X to increase the send/receive timeout values X on your host!!! X------------------------------------------------------------ XKR Receives a file from kermit host. (SCRIPT) X Format: X (same format as KS) Not from a server X------------------------------------------------------------ XKS Sends files via kermit to the host. (SCRIPT) X Format: X KS file Send one file X KS file1,file2,... Send multiple files X KS file1,file2,...,$ Send multiple files and shut down server X Example: X KS foo.bar sends foo.bar (note no quoting is used) X KS foo1,foo2,foo3 sends three files X KS foo1,foo2,foo3,$ sends three files and shuts down server X------------------------------------------------------------ XLINES Define number of lines in the window (INIT) X Format: X LINES n X Example: X LINES 24 Maximum for non-interlace X LINES 48 Maximum for interlaced X LINES 0 Determine the maximum number of lines X available and use it X------------------------------------------------------------ XMODE Set a transfer mode for KERMIT to use (INIT,SCRIPT) X Format: X MODE type type of transfers to perform X Example: X MODE IMAGE image mode transfers X MODE CRLF <CR><LF> text transfers (VMS Kermit). X------------------------------------------------------------ XNUMKEY Numeric keypad mode (INIT,SCRIPT) X Format: X NUMKEY ON/OFF or YES/NO X Example: X NUMKEY ON Keypad is pure numbers X------------------------------------------------------------ XON Peforms a command every time string is received (SCRIPT) X Format: X ON "string" cmd Execute cmd when string is received. X Only one ON string may be installed at a X time. X X If cmd is a GOTO and we were previously X WAITing for a string the WAIT is aborted and X execution resumes at the new label. X X If cmd is not SEND and we were previously X DELAYing, then the DELAY is aborted and the X cmd is executed, followed by the next command X after the DELAY. X X If cmd is a SEND and we were previously X DELAYing, then the DELAY is continued. X Example: X ON "LOSS CARRIER" GOTO RESTART X If modem drops carrier, try to redial X ON "--more--" SEND " " X Send a space every time --more-- is received X------------------------------------------------------------ XPARITY Sets the parity (INIT,SCRIPT) X Format: X PARITY type Set the parity type X Example: X PARITY NONE no parity X PARITY MARK mark parity X PARITY SPACE space parity X PARITY ODD odd parity X PARITY EVEN even parity X------------------------------------------------------------ XRECF Receive a file using the protocol specified in XPROTO (SCRIPT) X Format: X RECF file-spec X Example: X XPROTO XMODEMCRC Select XMODEM CRC protocol X RECF Foo Receive Foo using XMODEM CRC X------------------------------------------------------------ XSB Sends a break character to the host (SCRIPT) X Format: Note that any pending character to send X SB is aborted by this call X------------------------------------------------------------ XSCREEN Define the screen type (INIT) X Format: X SCREEN type type of screen to use X Example: X SCREEN WORKBENCH use the workbench screen X SCREEN CUSTOM use a custom screen X------------------------------------------------------------ XSEND Sends a string or character to the host. (SCRIPT) X Format: X SEND "string" Sends a string to the host. Beginning and X ending double quotes (") are required. A X carat (^) may be used to send control chars. X Two carats transmits a carat character. X SEND chr Sends a single character. X SEND ^chr Sends a single control character. The chr X is NOT case sensitve X Example: X SEND "mail" Send the string mail X SEND "dir^M" Send the string dir followed by a <CR> X SEND a Send the letter a X SEND ^C Send a control C X SEND "abc^^def" Send the string abc^def X SEND ^^ Send a control-uparrow X SEND " Send the '"' character X------------------------------------------------------------ XSENDF Send a file using the protocol specified in XPROTO (SCRIPT) X Format: X SENDF file-spec X Example: X XPROTO XMODEMCRC Select XMODEM CRC protocol X SENDF Foo Send Foo using XMODEM CRC X------------------------------------------------------------ XSHORTCUT set a new shortcut command key (INIT) X Format: X SHORTCUT cmd key Sets key "key" to be the shortcut key for X script command "cmd". A null key will X cause no shortcut to be available for this X command (menu-option). Cmd may be one of X the following: X >> File items: << X SE - Send file using XPROTO RE - Receive file using XPROTO X KG - kermit get file KB - kermit bye (for server) X CAP - ascii capture on/off X >> Mode (XPROTO) items: << X ASC - ASCII "protocol" XM - XMODEM protocol X XMC - XMODEM CRC protocol KE - Kermit protocol X >> Comm items: << X 300 - Set Baud 300 1200 - Set Baud 1200 X 2400 - Set Baud 2400 4800 - Set Baud 4800 X 9600 - Set Baud 9600 NONE - Set Parity none X MARK - Set Parity mark SPACE - Set Parity space X EVEN - Set Parity even ODD - Set Parity odd X IMAGE - KERMIT transfer mode TEXT - KERMIT transfer mode X CONVERT - KERMIT transfer mode X >> Script items: << X EXECUTE - execute macro ABORT - abort macro X >> Util items: << X SB - send break HANG - hang up X CD - change directory CLEAR - clear screen X ECH - turn echo on or off WRAP - turn wrap on or off X NUMKEY - turn numeric kpad on/off APP - turn app. cursor on/off X CON - convert bs to del SWAP - Swap BS and DEL X X Example: X SHORTCUT ASC Q set Right-Amiga-Q to be the shortcut for X ASCII_SEND. X SHORTCUT XS removes the shortcut key for sending via X XMODEM protocol X------------------------------------------------------------ XSWAP Swap the meanings of backspace and delete keys (INIT,SCRIPT) X Format: X SWAP ON/OFF or YES/NO X Example: X SWAP NO Use standard definitions X------------------------------------------------------------ XUNIT Set unit of serial device to use (INIT) X Format: X UNIT n X Example: X UNIT 1 Open unit 1 of serial.device. Generally the user X will want to specify unit 0. When multi-port serial X cards become available specify as necessary. X------------------------------------------------------------ XVOLUME Set the BELL volume (INIT) X Format: X VOLUME n X Example: X VOLUME 0 Use a visual bell X VOLUME 64 Use a loud audible bell X------------------------------------------------------------ XWAIT Suspends until a certain string is received. (SCRIPT) X Format: X WAIT "string" Same rules for string as SEND X WAIT Enter an endless wait. Usually used after X some "ON" commands have been set up. Can X still be aborted via the script menu. X Example: X WAIT "User:" Waits for the string User: X------------------------------------------------------------ XWBCOLORS Force usage of workbench colors (INIT) X Format: X WBCOLORS ON/OFF or YES/NO X Example: X WBCOLORS YES Workbebch colors will be used for all X------------------------------------------------------------ XWRAP Set long line wrapping (INIT,SCRIPT) X Format: X WRAP ON/OFF or YES/NO X Example: X WRAP ON Long lines will wrap X------------------------------------------------------------ XXBEEP Beep at end of xfer (INIT,SCRIPT) X Format: X XBEEP ON/OFF or YES/NO X Example: X XBEEP ON Beep when xfers are finished X------------------------------------------------------------ XXPROTO Set default transfer protocol (INIT,SCRIPT) X Format: X XPROTO XMODEM or XMODEMCRC or KERMIT X Example: X XPROTO KERMIT Sets transfer protocol to Kermit X------------------------------------------------------------ XXR Receives a file via XMODEM. (SCRIPT) X Format: X (same format as KS) X------------------------------------------------------------ XXS Sends a file via XMODEM. (SCRIPT) X Format: X (same format as KS) X------------------------------------------------------------ X X X---------------------------- XInitialization file example: X---------------------------- X X##################################################################### X# X# VT100 sample initialization file X# v2.8 880117 ACS X# X# Hash mark at the beginning of a line denotes a comment. X# White space (space(s) or tab(s)) delimit fields. X# Case ignored except for function key bindings. X# X# All items in this file overide variables of the same name in VT100.C X# (all variables in vt100.c have a "p_" prepended to them) X# X##################################################################### X# XAPPCUR ON # Application keypad mode is being used XBACKGROUND 000 # Colors are in hex RGB from 000 to FFF XBAUD 2400 # Anything after required fields is ignored XBOLD a00 # Color for bold highlighting (in custom) XBREAK 750000 # Break time in micro-seconds XBUFFER 512 # 512 <= Input buffer size <= 2048 XCONVERT ON # KERMIT should downcase host names XCURSOR 00a # Color for cursor (in custom screen) XDEPTH 1 # number of bit planes to use (1 or 2) XECHO OFF # Full duplex mode in use XFONT MyFont # Use my own special 8-point font XFOREGROUND 950 # Colors are only used on the custom screen XINTERLACE ON # ON for CUSTOM or interlaced workbench XKEYSCRIPT 7E # Hex value for script introducer XLINES 0 # normal <= 24 interlaced <= 48 or 0 XMODE CRLF # IMAGE or CRLF (for KERMIT transfers) XNUMKEY ON # The keypad should be numeric XPARITY NONE # NONE (= 8 bit), MARK, SPACE, ODD or EVEN XSCREEN CUSTOM # may be CUSTOM or WORKBENCH XSWAP OFF # Don't Swap the Back-space and Delete keys XVOLUME 64 # Beep Volume (0 = Visual Beep) XWBCOLORS YES # ignore custom colors and use defaults XWRAP OFF # Auto wrap ON or OFF XXBEEP ON # Beep when xfer is done XXPROTO XMODEMCRC # Send/Receive will use Xmodem CRC. X# Remove the shortcut key for the CD command. No comment on next line X# as it will be taken as the shortcut key. XSHORTCUT CD X# X# Function bindings (strings to type when any of F1 - F10 are pressed) X# f <num> = function key X# f <num>+10 = shifted function key X# X# The string specified must be the same format as the SEND command: X# ^ = control next character X# ^^ = up arrow X# X# Sample control characters: X# ^[ = escape ^M = carriage return X# ^J = line feed ^L = form feed X# X# If the first character of the string is a script introducer X# (KEYSCRIPT) then the string is interpreted as a script filename X# to be executed when the key is pressed. X# X# Examples of bindings: X# Xf 1 "^[OP" # f1-f4 = PF1 - PF4 on a VT100 Xf 2 "^[OQ" Xf 3 "^[OR" Xf 4 "^[OS" X# X# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E) X# Xf 5 "~df1:vt100_source/dialwork.script" Xf 6 "~df1:vt100_source/sendvt100.script" Xf 7 "~df1:vt100_source/getpics.script" X# Xf 8 "MAIL^M" # Reads my mail (note embedded <CR>) Xf 9 "NOTE^M" # Reads conferences Xf 11 "ATdt415-595-2479^M" # dials the FAUG BBS X# X# all done with init, now execute script as startup sequence X# Xexit df1:vt100_source/dialwork.script X X-------------------- XScript file example: X-------------------- X X################################################################### X# Script to dial work (dialwork.script) X# v2.6 870222 DBW X################################################################### X# X# Make sure that we have all the parameters we want X# X DELAY 2 X BAUD 2400 X PARITY NONE X MODE CRLF X BREAK 750000 X SB X# X# First get the modem's attention: X# XStart: X DELAY 1 X ON "Ready" GOTO Dial X SEND ^B X DELAY 2 X GOTO Start X# X# Now dial the 2400 baud line to work: X# XDial: X ON "Attached" GOTO Login X SEND "$2400!" X DELAY 30 X GOTO Start X# X# We got attached, so keep hitting return until the Gandalf terminal X# handler wakes up: X# XLogin: X ON "enter" GOTO Gandalf X DELAY 1 X SEND ^M X GOTO Login X# X# Now connect from the Gandalf to the terminal server (ts2): X# (when it asks for a password I need to type the password X# manually here) X# XGandalf: X DELAY 2 X SEND "ts2^M" X WAIT "class start" X# X# Keep sending <CR>'s until the LAT prompts for a username: X# XWaitLat: X DELAY 2 X ON "username>" GOTO Lat X SEND ^M X GOTO WaitLat X# X# Tell the LAT that it's me, and connect to the "cookie cluster" X# (my host systems). Tell the cluster my user name. X# (when it asks for a password I need to type the password X# manually here) X# XLat: X SEND "wecker^M" X DELAY 1 X SEND "connect cookie^M" X WAIT "Username:" X SEND "WECKER^M" X WAIT "at home" X SEND "^M^Mn^M" X# X# Got through all the LOGIN garbage, so let's do some work. X# X WAIT "$ " X# X# All done so stop: X# X EXIT ________This_Is_The_END________ if test `wc -l < vt100.doc` -ne 705; then echo 'shar: vt100.doc was damaged during transit (should have been 705 bytes)' fi fi ; : end of overwriting check echo 'x - Logon' if test -f Logon; then echo 'shar: not overwriting Logon'; else sed 's/^X//' << '________This_Is_The_END________' > Logon XDIAL: X DELAY 3 X SEND "ATdt555-1221^M" X ON "CONNECT" GOTO CONN X DELAY 20 X SEND " " X DELAY 1 X# X SEND "ATdt555-1222^M" X ON "CONNECT" GOTO CONN X DELAY 20 X SEND " " X DELAY 1 X# X SEND "ATdt555-1223^M" X ON "CONNECT" GOTO CONN X DELAY 20 X SEND " " X DELAY 1 X# X SEND "ATdt555-1224^M" X ON "CONNECT" GOTO CONN X DELAY 20 X SEND " " X DELAY 1 X GOTO DIAL X# XCONN: X# Send CRs till I get a login: prompt. X SEND ^M X ON "login:" GOTO LOGIN X DELAY 3 X GOTO CONN XLOGIN: X# Send my username and my "password", reply to first prompt. X SEND "acs^M" X WAIT "assword:" X SEND "mypass^M" X WAIT "#?" X SEND "1^M" X WAIT "=> " X# Go to the source directory and send EVERYTHING then get off. X SEND "cd vt100src/rel2.8^M" X WAIT "=> " X SEND "wermit^M" X WAIT "mit>" X SEND "send *^M" X XPROTO KERMIT X RECF X DELAY 5 X SEND "ex^M" X WAIT "=> " X SEND "logoff^M" X WAIT "NO CARRIER" X SEND "ATH^M" X EXIT VT100 X ________This_Is_The_END________ if test `wc -l < Logon` -ne 57; then echo 'shar: Logon was damaged during transit (should have been 57 bytes)' fi fi ; : end of overwriting check echo 'x - Makefile' if test -f Makefile; then echo 'shar: not overwriting Makefile'; else sed 's/^X//' << '________This_Is_The_END________' > Makefile X###################################################################### X# X# Makefile to build vt100 terminal emulator X# X# v2.8 880117 ACS - See the README file X# v2.7 870825 ACS - See the README 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# 860823 DBW - Integrated and rewrote lots of code X# v2.0 860809 DBW - Major release.. LOTS of changes X# v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes X# v1.0 860712 DBW - First version released X# X# X# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H X# X###################################################################### X XOBJS = vt100.o init.o window.o xmodem.o remote.o \ X kermit.o script.o expand.o X Xvt100 : vt100.syms $(OBJS) X ln -o vt100 $(OBJS) -lc X Xvt100-w : vt100.syms $(OBJS) X ln -w -o vt100-w $(OBJS) -lc X Xvt100.syms : vt100.h X cc -A +Hvt100.syms vt100.h X Xvt100.o : vt100.c X cc +Ivt100.syms vt100.c X Xinit.o : init.c X cc +Ivt100.syms init.c X Xwindow.o : window.c X cc +Ivt100.syms window.c X Xxmodem.o : xmodem.c X cc +Ivt100.syms xmodem.c X Xremote.o : remote.c X cc +Ivt100.syms remote.c X Xkermit.o : kermit.c X cc +Ivt100.syms kermit.c X Xscript.o : script.c X cc +Ivt100.syms script.c X Xexpand.o : expand.c X cc +Ivt100.syms expand.c ________This_Is_The_END________ if test `wc -l < Makefile` -ne 57; then echo 'shar: Makefile was damaged during transit (should have been 57 bytes)' fi fi ; : end of overwriting check exit 0
ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)
Program Name: vt100 (version 2.8) Submitted By: acs@uts.amdahl.com (Tony Sumrall) Summary: vt100 terminal emulator. Poster Boy: Brent Woods (ahh@j.cc.purdue.edu) Tested. Part 2 of 4 NOTES: This program was tested by our Guest Moderator, Robert Tillotson. He had a couple of problems with the program at first (a couple of Guru errors, and we think that the vt100 task hung around instead of exiting properly; not certain, though), but when we (Rob, Pat, and I) tested it a few hours ago, none of us had any problems. I dunno. It seems to work okay now. Probably some fluke or other. Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga USENET: ...!j.cc.purdue.edu!ahh ARPANET: ahh@j.cc.purdue.edu BITNET: PODUM@PURCCVM PHONE: +1 (317) 743-8421 USNAIL: 320 Brown St., #406 / West Lafayette, IN 47906 ================================================================ #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 acs other 7980 Feb 1 18:53 expand.c # -rw-r--r-- 1 acs other 19521 Feb 1 18:53 init.c # -rw-r--r-- 1 acs other 25220 Feb 1 18:54 kermit.c # echo 'x - expand.c' if test -f expand.c; then echo 'shar: not overwriting expand.c'; else sed 's/^X//' << '________This_Is_The_END________' > expand.c X/************************************************************* X * vt100 terminal emulator - Wild card and Directory support X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - Use the *InfoMsg*() routines in window.c rather X * than req(). 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 * 860830 Steve Drew Added Wild card support, X * features(expand.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 * Much of the code from this module extracted from X * Matt Dillons Shell program. (Thanxs Matt.) X *************************************************************/ X X#include "vt100.h" X Xstruct DPTR { /* Format of directory fetch ptr */ X struct FileLock *lock; /* lock on directory */ X struct FileInfoBlock *fib; /* mod'd fib for entry */ X}; X X/* X * Disk directory routines X * X * X * diropen() returns a struct DPTR, or NULL if the given file does not X * exist. stat will be set to 1 if the file is a directory. If the X * name is "", then the current directory is openned. X * X * dirnext() returns 1 until there are no more entries. The **name and X * *stat are set. *stat = 1 if the file is a directory. X * X * dirclose() closes a directory channel. X * X */ X Xstruct DPTR * Xdiropen(name, stat) Xchar *name; Xint *stat; X{ X struct DPTR *dp; X int namelen, endslash = 0; X struct FileLock *MyLock; X X MyLock = (struct FileLock *)( (ULONG) ((struct Process *) X (FindTask(NULL)))->pr_CurrentDir); X namelen = strlen(name); X if (namelen && name[namelen - 1] == '/') { X name[namelen - 1] = '\0'; X endslash = 1; X } X *stat = 0; X dp = (struct DPTR *)malloc(sizeof(struct DPTR)); X if (*name == '\0') X dp->lock = (struct FileLock *)DupLock (MyLock); X else X dp->lock = (struct FileLock *)Lock (name, ACCESS_READ); X if (endslash) X name[namelen - 1] = '/'; X if (dp->lock == NULL) { X free (dp); X return (NULL); X } X dp->fib = (struct FileInfoBlock *) X AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC); X if (!Examine (dp->lock, dp->fib)) { X dirclose (dp); X return (NULL); X } X if (dp->fib->fib_DirEntryType >= 0) X *stat = 1; X return (dp); X} X Xdirnext(dp, pname, stat) Xstruct DPTR *dp; Xchar **pname; Xint *stat; X{ X if (dp == NULL) X return (0); X if (ExNext (dp->lock, dp->fib)) { X *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1; X *pname = dp->fib->fib_FileName; X return (1); X } X return (0); X} X X Xdirclose(dp) Xstruct DPTR *dp; X{ X if (dp == NULL) X return (1); X if (dp->fib) X FreeMem (dp->fib, (long)sizeof(*dp->fib)); X if (dp->lock) X UnLock (dp->lock); X free (dp); X return (1); X} X Xfree_expand(av) Xchar **av; X{ X char **base = av; X X if (av) { X while (*av) { X free (*av); X ++av; X } X free (base); X } X} X X/* X * EXPAND(wild_name, pac) X * wild_name - char * (example: "df0:*.c") X * pac - int * will be set to # of arguments. X * X */ X X Xchar ** Xexpand(base, pac) Xchar *base; Xint *pac; X{ X char **eav = (char **)malloc (sizeof(char *)); X int eleft, eac; X X char *ptr, *name; X char *bname, *ename, *tail; X int stat, scr; X struct DPTR *dp; X X *pac = eleft = eac = 0; X base = strcpy(malloc(strlen(base)+1), base); X for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr); X for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr); X if (ptr < base) { X bname = strcpy (malloc(1), ""); X } else { X scr = ptr[1]; X ptr[1] = '\0'; X bname = strcpy (malloc(strlen(base)+1), base); X ptr[1] = scr; X } X ename = ptr + 1; X for (ptr = ename; *ptr && *ptr != '/'; ++ptr); X scr = *ptr; X *ptr = '\0'; X tail = (scr) ? ptr + 1 : NULL; X X if ((dp = diropen (bname, &stat)) == NULL || stat == 0) { X free (bname); X free (base); X free (eav); X InfoMsg1Line("Could not open directory"); X return (NULL); X } X while (dirnext (dp, &name, &stat)) { X if (compare_ok(ename, name)) { X if (tail) { X int alt_ac; X char *search, **alt_av, **scrav; X struct FileLock *lock; X X if (!stat) /* expect more dirs, but this not a dir */ X continue; X lock = (struct FileLock *)CurrentDir (dp->lock); X search = malloc(strlen(name)+strlen(tail)+2); X strcpy (search, name); X strcat (search, "/"); X strcat (search, tail); X scrav = alt_av = expand (search, &alt_ac); X CurrentDir (lock); X if (scrav) { X while (*scrav) { X if (eleft < 2) { X char **scrav = (char **) X malloc(sizeof(char *) * (eac + 10)); X movmem (eav, scrav, sizeof(char *) * (eac + 1)); X free (eav); X eav = scrav; X eleft = 10; X } X eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1); X strcpy(eav[eac], bname); X strcat(eav[eac], *scrav); X free (*scrav); X ++scrav; X --eleft, ++eac; X } X free (alt_av); X } X } else { X if (eleft < 2) { X char **scrav = (char **) X malloc(sizeof(char *) * (eac + 10)); X movmem (eav, scrav, sizeof(char *) * (eac + 1)); X free (eav); X eav = scrav; X eleft = 10; X } X eav[eac] = malloc (strlen(bname)+strlen(name)+1); X eav[eac] = strcpy(eav[eac], bname); X strcat(eav[eac], name); X --eleft, ++eac; X } X } X } X dirclose (dp); X *pac = eac; X eav[eac] = NULL; X free (bname); X free (base); X if (eac) X return (eav); X free (eav); X return (NULL); X} X X/* X * Compare a wild card name with a normal name X */ X X#define MAXB 8 X Xcompare_ok(wild, name) Xchar *wild, *name; X{ X char *w = wild; X char *n = name; X char *back[MAXB][2]; X int bi = 0; X X while (*n || *w) { X switch (*w) { X case '*': X if (bi == MAXB) { X InfoMsg1Line("Too many levels of '*'"); X return (0); X } X back[bi][0] = w; X back[bi][1] = n; X ++bi; X ++w; X continue; Xgoback: X --bi; X while (bi >= 0 && *back[bi][1] == '\0') X --bi; X if (bi < 0) X return (0); X w = back[bi][0] + 1; X n = ++back[bi][1]; X ++bi; X continue; X case '?': X if (!*n) { X if (bi) X goto goback; X return (0); X } X break; X default: X if (toupper(*n) != toupper(*w)) { X if (bi) X goto goback; X return (0); X } X break; X } X if (*n) ++n; X if (*w) ++w; X } X return (1); X} X Xset_dir(new) Xchar *new; X{ X register char *s; X int i; X struct FileLock *lock; X char temp[60]; X struct FileInfoBlock *fib; X X if (*new != '\000') { X strcpy(temp, MyDir); X s = new; X if (*s == '/') { X s++; X for (i=strlen(MyDir); X MyDir[i] != '/' && MyDir[i] != ':'; X i--); X MyDir[i+1] = '\0'; X strcat(MyDir, s); X } X else if (exists(s, ':') == 0) { X if (MyDir[strlen(MyDir)-1] != ':') X strcat(MyDir, "/"); X strcat(MyDir, s); X } X else X strcpy(MyDir, s); X X if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) { X InfoMsg2Line("Directory not found:",MyDir); X strcpy(MyDir, temp); X } X else { X fib = (struct FileInfoBlock *)AllocMem( X (long)sizeof(struct FileInfoBlock), MEMF_PUBLIC); X if (fib) { X if (Examine(lock, fib)) { X if (fib->fib_DirEntryType > 0) { X UnLock(CurrentDir(lock)); X if (MyDir[strlen(MyDir)-1] == '/') X MyDir[strlen(MyDir)-1] = '\000'; X } X else { X InfoMsg2Line("Not a Directory:",MyDir); X strcpy(MyDir,temp); X } X } X FreeMem(fib, (long)sizeof(struct FileInfoBlock)); X } X else { X InfoMsg1Line("Can't change directory...No free memory!"); X strcpy(MyDir,temp); X } X } X } X} X Xexists(s,c) Xchar *s,c; X { X while (*s != '\000') X if (*s++ == c) return(1); X return(0); X } ________This_Is_The_END________ if test `wc -l < expand.c` -ne 355; then echo 'shar: expand.c was damaged during transit (should have been 355 bytes)' fi fi ; : end of overwriting check echo 'x - init.c' if test -f init.c; then echo 'shar: not overwriting init.c'; else sed 's/^X//' << '________This_Is_The_END________' > init.c X/*************************************************************** X * vt100 - terminal emulator - initialization X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - Allow execution of all script files specified on X * command line (companion to changes in script.c). X * Rolled menu init into one routine (do_menu_init()). 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 Parity and Word Length and support code X * 860823 DBW - Integrated and rewrote lots of code 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 Xstruct Device *ConsoleDevice = NULL; Xstruct IOStdReq ConReq; Xextern APTR OrigWindowPtr; Xextern int capture; /* in vt100.c */ X X/* Used by script.c for script file chaining. */ Xint script_files_todo = 0; Xchar **script_files = NULL; X Xchar line[256]; X X/* Command key equivalences per menu. Manipulated by script.c */ X X/* Equivalences for the File menu... */ Xstruct 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 = { ' ', '^', 'V', 'G', 'B', ' ', '\0' }; X X/* Equivalences for Mode sub-menu... */ Xstruct mode_cmd { X char as; /* ascii mode */ X char xm; /* xmodem mode */ X char xmc; /* xmodemcrc mode */ X char ke; /* kermit mode */ X char nl; X} modecmd_chars = { ' ', 'X', ' ', 'K', '\0' }; X X/* Equivalences for the Baud Rate sub-menu... */ Xstruct baudcmd { 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 = { ' ', 'L', 'H', ' ', ' ', '\0' }; X X/* Equivalences for the Parity sub-menu... */ Xstruct 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 = { 'N', ' ', ' ', 'E', 'O', '\0' }; X X/* Equivalences for the Xfer Mode sub-menu... */ Xstruct modcmd { X char im; /* IMage */ X char tx; /* TeXt */ X char cn; /* CoNvert */ X char nl; X} modcmd_chars = { 'I', 'T', ' ', '\0' }; X X/* Equivalences for the Script menu... */ Xstruct scrcmd { X char em; /* Execute Macro */ X char ab; /* Abort Macro */ X char nl; X} scrcmd_chars = { 'M', 'A', '\0' }; X X/* Equivalences for the Utility menu... */ Xstruct utilcmd { 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; /* Xfer beep */ X char nl; X} utilcmd_chars = { '.', ' ', 'D', ' ', ' ', 'W', 'K', 'C', ' ', ' ', '\0' }; X Xextern char myfontname[]; X Xstatic char *filetext[] = { X "Protocol", X "Send", X "Receive", X "Kermit Get", X "Kermit BYE", X "Capture" X}; X Xstatic char *modetext[] = { X " Ascii", X " Xmodem", X " XmodemCRC", X " Kermit" X}; X Xstatic char *commtext[] = { X "Baud Rate", X "Parity ", X "Xfer Mode" X}; X Xstatic char *baudtext[] = { X " 300", X " 1200", X " 2400", X " 4800", X " 9600" X}; X Xstatic char *partext[] = { X " None ", X " Mark ", X " Space", X " Even ", X " Odd " X}; X Xstatic char *modtext[] = { X " Image ", X " Text ", X " Convert" X}; X Xstatic char *scrtext[] = { X "Execute Macro", X "Abort Execution" X}; X Xstatic char *utiltext[] = { X "Send Break", X "Hang Up", X "Change Dir", X "Clear Scrn", X " Echo", X " Wrap", X " Num Key", X " App Cur", X " BS<->DEL", X " Xfer Beep" X}; X Xstruct HowToInit { X int LeftEdge; X int Width; X ULONG Flags; X char **text; X char *cmdkeys; X}; X Xstatic struct HowToInit menu_init[] = { X { 0, 120+40, ITEMTEXT | ITEMENABLED | HIGHCOMP, X filetext, (char *)(&filecmd_chars) }, X {75, 92+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X modetext, (char *)(&modecmd_chars) }, X { 0, 88, ITEMTEXT | ITEMENABLED | HIGHCOMP, X commtext, NULL }, X { 75, 56+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X baudtext, (char *)(&baudcmd_chars) }, X { 75, 56+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X partext, (char *)(&parcmd_chars) }, X { 75, 80+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X modtext, (char *)(&modcmd_chars) }, X { 0, 160, ITEMTEXT | ITEMENABLED | HIGHCOMP, X scrtext, (char *)(&scrcmd_chars) }, X { 0, 88+40, ITEMTEXT | ITEMENABLED | HIGHCOMP, X utiltext, (char *)(&utilcmd_chars) } X}; X X#define FILE_INIT_ENTRY (&(menu_init[0])) X#define MODE_INIT_ENTRY (&(menu_init[1])) X#define COMM_INIT_ENTRY (&(menu_init[2])) X#define RS_INIT_ENTRY (&(menu_init[3])) X#define PAR_INIT_ENTRY (&(menu_init[4])) X#define XF_INIT_ENTRY (&(menu_init[5])) X#define SCRIPT_INIT_ENTRY (&(menu_init[6])) X#define UTIL_INIT_ENTRY (&(menu_init[7])) X Xvoid do_menu_init(); X Xchar *InitDefaults(argc,argv) Xint argc; Xchar **argv; X { X FILE *fd = NULL; X char *p, *t, *ifile; X int l, dont_init = 0; X X doing_init = 1; /* make sure we only allow INIT script commands */ X if (argc > 1) { X int start_of_script_files = 1; X X if(strcmp(argv[1], "-i") == 0) { /* No init file */ X dont_init = 1; X start_of_script_files = 2; X } X else if(strcmp(argv[1], "+i") == 0) { /* Use specified init file */ X start_of_script_files = 3; X if((fd=fopen(argv[2],"r")) == NULL) { X ifile = AllocMem((LONG)(strlen(argv[2])+3), MEMF_PUBLIC|MEMF_CLEAR); X strcpy(ifile, "S:"); X strcat(ifile, argv[2]); X fd = fopen(ifile, "r"); X FreeMem(ifile, (LONG)(strlen(argv[2])+3)); X ifile = NULL; X } X } X if(start_of_script_files > argc) X script_files_todo = 0; X else X script_files_todo = argc - start_of_script_files; /* # of cmdline script files left */ X script_files = &(argv[start_of_script_files]); /* Ptr to first of 'em */ X } X X if((p_font == NULL) || (p_font[0] == '\0')) X strcpy(myfontname, "topaz"); X else X strcpy(myfontname, p_font); /* Init font name */ X strcat(myfontname, ".font"); X X if(!dont_init) X if((fd == NULL) && ((fd=fopen("vt100.init","r")) == NULL)) X fd=fopen("s:vt100.init","r"); X X if(fd != NULL) { X while (fgets(line,256,fd) != 0) { X line[strlen(line)-1] = '\000'; X p = next_wrd(&line[0],&l); X if (*p) { X *p |= ' '; X if (p[1]) p[1] |= ' '; X if (*p == '#') continue; X if (*p == 'e' && p[1] == 'x') break; X exe_cmd(p,l); X } X } X fclose(fd); X } X doing_init = 0; X X IntuitionBase = (struct IntuitionBase *) X OpenLibrary("intuition.library", INTUITION_REV); X if( IntuitionBase == NULL ) X cleanup("can't open intuition",1); X X GfxBase = (struct GfxBase *) X OpenLibrary("graphics.library",GRAPHICS_REV); X if( GfxBase == NULL ) X cleanup("can't open graphics library",2); X X /* Now set up all the screen info as necessary */ X if(p_lines == 0) /* Wants to use everything available */ X if(p_interlace) X p_lines = ((GfxBase->NormalDisplayRows*2) - 6) / 8; X else X p_lines = ((GfxBase->NormalDisplayRows - 6) / 8); X X if (p_interlace == 0) { X if (p_lines > 24) p_lines = 24; X MINY = 14; X NewWindow.Height = (long)((p_lines*8)+8); X } X else { X if (p_lines > 48) p_lines = 48; X MINY = 16; X NewScreen.ViewModes |= LACE; X NewWindow.Height = (long)((p_lines*8)+10); X } X NewWindow.MinHeight = NewWindow.Height; X NewWindow.MaxHeight = NewWindow.Height; X NewWindow.TopEdge = 0L; X MAXY = ((p_lines-1)*8) + MINY; X top = MINY; X bot = MAXY; X savx = MINX; X savy = MINY; X if (p_screen == 1) { X if (p_depth > 2) p_depth = 2; X if (p_depth < 1) p_depth = 1; X NewScreen.Depth = (long)p_depth; X X NewScreen.Height = (long)((p_lines*8)+16); X X if (p_interlace == 1) X NewScreen.TopEdge = (long)(400 - NewScreen.Height); X else X NewScreen.TopEdge = (long)(208 - NewScreen.Height); X } X else { X p_depth = 2L; X NewWindow.TopEdge = 0L; X NewWindow.Screen = NULL; X NewReqWindow.Screen = NULL; X NewWindow.Type = WBENCHSCREEN; X NewReqWindow.Type = WBENCHSCREEN; X } X X /* see if we exit with a startup script */ X if (*p == 'e') { X p = next_wrd(p+l+1,&l); X if (*p) return(p); X } X if (script_files_todo > 0) { X script_files_todo--; X return(*(script_files++)); X } X return(NULL); X } X Xvoid InitDevs() X{ XUSHORT colors[4]; Xint i; XBYTE *b,*c; Xstruct Process *mproc; Xchar temp[80]; X Xif (p_screen == 1) { X if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) X cleanup("can't open screen",3); X NewWindow.Screen = myscreen; X NewReqWindow.Screen = myscreen; X } X Xif ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL) X cleanup("can't open window",4); X Xif(OpenDevice("console.device", -1L, &ConReq, 0L)) X cleanup("can't open console", 4); XConsoleDevice = ConReq.io_Device; X Xif(p_screen == 1) { /* Cause system reqs to come to this screen */ X mproc = (struct Process *)FindTask(0L); X OrigWindowPtr = mproc->pr_WindowPtr; X mproc->pr_WindowPtr = (APTR)mywindow; X} Xif ((myfont = (struct TextFont *)OpenFont(&myattr)) == NULL) { X sprintf(temp, "Can't open font %s", myfontname); X cleanup(temp, 4); X} X Xmyviewport = (struct ViewPort *)ViewPortAddress(mywindow); Xmyrastport = (struct RastPort *)mywindow->RPort; X XSetFont(myrastport,myfont); X Xif (p_depth > 1) myrequest.BackFill = 2; Xif (p_screen != 0 && p_wbcolors == 0) { X colors[0] = p_background; X colors[1] = p_foreground; X colors[2] = p_bold; X colors[3] = p_cursor; X if (p_depth == 1) X LoadRGB4(myviewport,(struct ColorMap *)colors,2L); X else X LoadRGB4(myviewport,(struct ColorMap *)colors,4L); X } X XRead_Request = (struct IOExtSer *) X AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR); XRead_Request->io_SerFlags = 0L; XRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L); Xif(OpenDevice(SERIALNAME,(LONG)p_unit,Read_Request,NULL)) X cleanup("Cant open Read device",5); Xrs_in = malloc(p_buffer+1); XRead_Request->io_SerFlags = 0L; XRead_Request->io_Baud = p_baud; XRead_Request->io_ReadLen = 8L; XRead_Request->io_WriteLen = 8L; XRead_Request->io_CtlChar = 0x11130000L; XRead_Request->io_RBufLen = p_buffer; XRead_Request->io_BrkTime = p_break; XRead_Request->IOSer.io_Command = SDCMD_SETPARAMS; XDoIO(Read_Request); XRead_Request->IOSer.io_Command = CMD_READ; XRead_Request->IOSer.io_Length = 1; XRead_Request->IOSer.io_Data = (APTR) &rs_in[0]; X XWrite_Request = (struct IOExtSer *) X AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR); Xb = (BYTE *)Read_Request; Xc = (BYTE *)Write_Request; Xfor (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++; XWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L); XWrite_Request->IOSer.io_Command = CMD_WRITE; XWrite_Request->IOSer.io_Length = 1; XWrite_Request->IOSer.io_Data = (APTR) &rs_out[0]; X XTimer_Port = CreatePort("Timer Port",0L); XScript_Timer_Port = CreatePort("Timer Port",0L); X Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) || X OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) X cleanup("can't open timer device",7); X XTimer.tr_node.io_Message.mn_ReplyPort = Timer_Port; XTimer.tr_node.io_Command = TR_ADDREQUEST; XTimer.tr_node.io_Flags = 0; XTimer.tr_node.io_Error = 0; X XScript_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port; XScript_Timer.tr_node.io_Command = TR_ADDREQUEST; XScript_Timer.tr_node.io_Flags = 0; XScript_Timer.tr_node.io_Error = 0; X XBeepWave = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR)); Xif (BeepWave != 0) BeepWave[0] = 100; X XAudio_Port = CreatePort("Audio Port",0L); X XAudio_Request.ioa_Request.io_Message.mn_ReplyPort = Audio_Port; XAudio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85; XAudio_Request.ioa_Data = Audio_AllocMap; XAudio_Request.ioa_Length = (ULONG) sizeof(Audio_AllocMap); X Xif (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL)) X cleanup("can't open audio device",8); X XAudio_Request.ioa_Request.io_Command = CMD_WRITE; XAudio_Request.ioa_Request.io_Flags = ADIOF_PERVOL; XAudio_Request.ioa_Data = BeepWave; XAudio_Request.ioa_Length = BEEPSIZE; XAudio_Request.ioa_Period = COLORCLOCK / (BEEPSIZE * BEEPFREQ); XAudio_Request.ioa_Volume = p_volume; XAudio_Request.ioa_Cycles = 100; X} X X/*****************************************************************/ X/* The following function initializes the structure arrays */ X/* needed to provide the File menu topic. */ X/*****************************************************************/ Xvoid InitFileItems() X{ X int n; X X if(capture == TRUE) X filetext[FILEMAX-1] = "Capturing"; X else X filetext[FILEMAX-1] = "Capture"; X do_menu_init(FileItem, FileText, FILE_INIT_ENTRY, FILEMAX); X FileItem[0].SubItem = ModeItem; X do_menu_init(ModeItem, ModeText, MODE_INIT_ENTRY, MODEMAX); X for( n=0; n<MODEMAX; n++ ) { X ModeItem[n].MutualExclude = (~(1 << n)); X } X if(p_xproto > MODEMAX) X p_xproto = MODEMAX-1; X ModeItem[p_xproto].Flags |= CHECKED; X} X X/****************************************************************** X/* Main Comm menu X/* set up for Baud & Parity submenus X/******************************************************************/ Xvoid InitCommItems() X{ X int n; X X do_menu_init(CommItem, CommText, COMM_INIT_ENTRY, COMMAX); X CommItem[0].SubItem = RSItem; X CommItem[1].SubItem = ParItem; X CommItem[2].SubItem = XFItem; X X/*****************************************************************/ X/* The following initializes the structure arrays */ X/* needed to provide the BaudRate Submenu topic. */ X/*****************************************************************/ X X do_menu_init(RSItem, RSText, RS_INIT_ENTRY, RSMAX); X for( n=0; n<RSMAX; n++ ) { X RSItem[n].MutualExclude = (~(1 << n)); X } X X /* select baud item chekced */ X switch (p_baud) { X case 300: n = 0; break; X case 1200: n = 1; break; X case 2400: n = 2; break; X case 4800: n = 3; break; X case 9600: n = 4; break; X default: n = 2; p_baud = 2400; X } X RSItem[n].Flags |= CHECKED; X X/* initialize text for specific menu items */ X X/*****************************************************************/ X/* The following initializes the structure arrays */ X/* needed to provide the Parity Submenu topic. */ X/*****************************************************************/ X X do_menu_init(ParItem, ParText, PAR_INIT_ENTRY, PARMAX); X for( n=0; n<PARMAX; n++ ) { X ParItem[n].MutualExclude = (~(1 << n)); X } X X /* select parity item chekced */ X ParItem[p_parity].Flags |= CHECKED; X X/*****************************************************************/ X/* The following initializes the structure arrays */ X/* initialize text for specific menu items */ X/* needed to provide the Transfer Mode menu topic. */ X/*****************************************************************/ X X do_menu_init(XFItem, XFText, XF_INIT_ENTRY, XFMAX); X X /* initialize each menu item and IntuiText with loop */ X for( n=0; n<XFMAX; n++ ) { X if (n < 2) XFItem[n].MutualExclude = 2 - n; X } X /* mode checked */ X XFItem[p_mode].Flags |= CHECKED; X if (p_convert) XFItem[2].Flags |= CHECKED; X X/* initialize text for specific menu items */ X X} /* end of InitCommItems() */ X X X/*****************************************************************/ X/* The following function initializes the structure arrays */ X/* needed to provide the Script menu topic. */ X/*****************************************************************/ Xvoid InitScriptItems() X{ X do_menu_init(ScriptItem, ScriptText, SCRIPT_INIT_ENTRY, SCRIPTMAX); X} X X/*****************************************************************/ X/* The following function initializes the structure arrays */ X/* needed to provide the Util menu topic. */ X/*****************************************************************/ Xvoid InitUtilItems() X { X int n; X X do_menu_init(UtilItem, UtilText, UTIL_INIT_ENTRY, UTILMAX); X/* initialize each menu item and IntuiText with loop */ X for( n=0; n<UTILMAX; n++ ) { X if (n > 3) UtilItem[n].Flags |= CHECKIT; X } X X if (p_echo) UtilItem[4].Flags |= CHECKED; X if (p_wrap) UtilItem[5].Flags |= CHECKED; X if (p_keyapp == 0) UtilItem[6].Flags |= CHECKED; X if (p_curapp) UtilItem[7].Flags |= CHECKED; X if (p_bs_del) UtilItem[8].Flags |= CHECKED; X if (p_xbeep) UtilItem[9].Flags |= CHECKED; X swap_bs_del(); /* Setup keys[] properly... */ X swap_bs_del(); /* ...for mode */ X} X X/****************************************************************/ X/* The following function inits the Menu structure array with */ X/* appropriate values for our simple menu. Review the manual */ X/* if you need to know what each value means. */ X/****************************************************************/ Xvoid InitMenu() X{ Xmenu[0].NextMenu = &menu[1]; Xmenu[0].LeftEdge = 5; Xmenu[0].TopEdge = 0; Xmenu[0].Width = 40; Xmenu[0].Height = 10; Xmenu[0].Flags = MENUENABLED; Xmenu[0].MenuName = "File"; /* text for menu-bar display */ Xmenu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */ X Xmenu[1].NextMenu = &menu[2]; Xmenu[1].LeftEdge = 55; Xmenu[1].TopEdge = 0; Xmenu[1].Width = 88; Xmenu[1].Height = 10; Xmenu[1].Flags = MENUENABLED; Xmenu[1].MenuName = "Comm Setup"; /* text for menu-bar display */ Xmenu[1].FirstItem = &CommItem[0]; /* pointer to first item in list */ X Xmenu[2].NextMenu = &menu[3]; Xmenu[2].LeftEdge = 153; Xmenu[2].TopEdge = 0; Xmenu[2].Width = 56; Xmenu[2].Height = 10; Xmenu[2].Flags = MENUENABLED; Xmenu[2].MenuName = "Script"; /* text for menu-bar display */ Xmenu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/ X Xmenu[3].NextMenu = NULL; Xmenu[3].LeftEdge = 225; Xmenu[3].TopEdge = 0; Xmenu[3].Width = 64; Xmenu[3].Height = 10; Xmenu[3].Flags = MENUENABLED; Xmenu[3].MenuName = "Utility"; /* text for menu-bar display */ Xmenu[3].FirstItem = &UtilItem[0]; /* pointer to first item in list*/ X} X Xvoid do_menu_init(menuitem, menutext, initentry, max) Xstruct MenuItem menuitem[]; Xstruct IntuiText menutext[]; Xstruct HowToInit *initentry; Xint max; X{ X int n, nplus1; X char **temp; X X /* initialize each menu item and IntuiText with loop */ X for( n=0; n < max; n++ ) { X nplus1 = n + 1; X temp = initentry->text; X menutext[n].IText = (UBYTE *)temp[n]; X menuitem[n].NextItem = &menuitem[nplus1]; X menuitem[n].LeftEdge = initentry->LeftEdge; X menuitem[n].TopEdge = 10 * n; X menuitem[n].Width = initentry->Width; X menuitem[n].Height = 10; X menuitem[n].Flags = initentry->Flags; X menuitem[n].MutualExclude = 0; X menuitem[n].ItemFill = (APTR)&menutext[n]; X menuitem[n].SelectFill = NULL; X if((initentry->cmdkeys != NULL) && (initentry->cmdkeys[n] != ' ')) { X menuitem[n].Command = initentry->cmdkeys[n]; X menuitem[n].Flags |= COMMSEQ; X } X else menuitem[n].Command = 0; X menuitem[n].SubItem = NULL; X menuitem[n].NextSelect = 0; X X menutext[n].FrontPen = 0; X menutext[n].BackPen = 1; X menutext[n].DrawMode = JAM2;/* render in fore and background */ X menutext[n].LeftEdge = 0; X menutext[n].TopEdge = 1; X menutext[n].ITextFont = NULL; X menutext[n].NextText = NULL; X } X menuitem[max-1].NextItem = NULL; X} ________This_Is_The_END________ if test `wc -l < init.c` -ne 666; then echo 'shar: init.c was damaged during transit (should have been 666 bytes)' fi fi ; : end of overwriting check echo 'x - kermit.c' if test -f kermit.c; then echo 'shar: not overwriting kermit.c'; else sed 's/^X//' << '________This_Is_The_END________' > kermit.c X/************************************************************* X * vt100 terminal emulator - KERMIT protocol support X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - Fixed the "multiple-send" problem in X * doksend() et al; show status using the *InfoMsg*() X * routines in window.c; fixed erroneous calls to X * spack() and rpack(); better error handling. 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 eight bit quoting X * 860830 Steve Drew Wild card support, err recovry,bugs. X * 860823 DBW - Integrated and rewrote lots of code X * 860811 Steve Drew multi filexfer, bugs, status line ect.. 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 MAXPACKSIZ 94 /* Maximum msgpkt size */ X#define CR 13 /* ASCII Carriage Return */ X#define LF 10 /* ASCII line feed */ X#define SP 32 /* ASCII space */ X#define DEL 127 /* Delete (rubout) */ X X#define MAXTRY 5 /* Times to retry a msgpkt */ X#define MYQUOTE '#' /* Quote character I will use */ X#define MYRPTQ '~' /* Repeat quote character */ X#define MYEBQ '&' /* 8th bit prefix character */ X#define MYPAD 0 /* Number of padding charss I will need */ X#define MYPCHAR 0 /* Padding character I need (NULL) */ X#define MYEOL '\n' /* End-Of-Line character I need */ X#define IDOLONG 2 /* I do LONG packets! */ X X#define tochar(ch) ((ch) + ' ') X#define unchar(ch) ((ch) - ' ') X#define ctl(ch) ((ch) ^ 64 ) X X/* Global Variables */ X Xint sending, /* Indicates that we're sending, not receiving */ X lastpkt, /* Last successful packet # sent/received */ X ulp, /* Using LONG packets */ X size, /* Size of present data */ X osize, /* Size of last data entry */ X rpsiz, /* Maximum receive msgpkt size */ X spsiz, /* Maximum send msgpkt size */ X timint, /* Time interval to wait */ X pad, /* How much padding to send */ X n, /* Packet number */ X tp, /* total packets */ X numtry, /* Times this msgpkt retried */ X retry, /* total retries */ X oldtry, /* Times previous msgpkt retried */ X sendabort, /* flag for aborting send file */ X rptflg, /* are we doing repeat quoting */ X ebqflg, /* are we doing 8th bit quoting */ X notfirst, /* is this the first file received */ X first, /* is this the first time in a file */ X rpt, /* current repeat count */ X next, /* what is the next character */ X t; /* current character */ Xlong totbytes; /* total bytes xfered on this file */ X Xchar state, /* Present state of the automaton */ X padchar, /* Padding character to send */ X eol, /* End-Of-Line character to send */ X quote, /* Quote character in incoming data */ X rptq, /* Quote character for repeats */ X ebq, /* Quote character for 8th bit quoting */ X ackpkt[MAXPACKSIZ+20], /* ACK/NAK packet buffer */ X *msgpkt, /* Message Packet buffer is AllocMem()d */ X *spackbuf, /* Dynamically allocated buffer for spack() */ X filnam[40], /* remote file name */ X snum[10], X mainmode[10]; X XFILE *fp; /* file for send/receive */ X Xchar * Xgetfname(name) /* returns ptr to start of file name from spec */ Xchar *name; X{ X int l; X X l = strlen(name); X while(l && name[l] != '/' && name[l] != ':') l--; X if (name[l] == '/' || name[l] == ':') l++; X return(name += l); X} X Xdoksend(file,more) Xchar *file; Xint more; X{ X int amount, c, wild; X char *p, **list = NULL; X X msgpkt = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR); X spackbuf = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR); X sending = 1; X if (!strcmp(file,"$")) { saybye(); return(USERABORT); } X p = file; X while(*p && *p != '*' && *p != '?') p++; X if (*p) { X wild = TRUE; X list = expand(file, &amount); X if (list == NULL) InfoMsg1Line("KERMIT: No wild card match"); X } X else { X wild = FALSE; X amount = 1; X } X /* The "multiple send" problem is brought about by attempting to X ** send multiple files in a single "batch" (via globbing, e.g. *.foo) X ** to a remote kermit that is NOT in server mode. A 'Z' packet X ** (meaning end-of-file) is sent after each of the files with a 'B' X ** packet (meaning end-of-batch) coming after the last 'Z' packet. X ** The old code reset the packet # on each iteration. We do it X ** outside of the for loop. */ X n = lastpkt = 0; X ulp = 0; /* Assume we won't use LONG packets */ X for (c = 0; c < amount; c++) { X if (wild == TRUE) p = list[c]; X else p = file; X strcpy(filnam,getfname(p)); X ttime = TTIME_KERMIT; X tp = retry = numtry = 0; totbytes = 0L; X if ((fp = fopen(p,"r")) == NULL) { X InfoMsg2Line("KERMIT: Can't open send file:", p); X continue; X } X strcpy(mainmode,"SEND"); X ClearBuffer(); X X /* This is another piece of the multiple-send fix. Sendsw() needs X ** to know 1) that this is the first file so it can send a send-init X ** packet and 2) if this is the last file so it can send a B packet X ** to indicate end-of-batch. The last piece of the multiple-send fix X ** is in sendsw() itself. */ X if ( sendsw(c == 0, c >= (amount-1)) ) /* Successful send? */ X ScrollInfoMsg(1); X fclose(fp); X } X free_expand(list); X FreeMem(spackbuf, (long)(MAXLONGPKS+20)); X FreeMem(msgpkt, (long)(MAXLONGPKS+20)); X return(TRUE); X} X Xdokreceive(file,more) Xchar *file; Xint more; X{ X int retval; X X msgpkt = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR); X spackbuf = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR); X ttime = TTIME_KERMIT; X sending = 0; X if (!strcmp(file,"$")) { saybye(); return(USERABORT); } X strcpy(filnam, file); X if (server) strcpy(mainmode,"GET"); X else strcpy(mainmode,"RECV"); X tp = lastpkt = retry = n = numtry = notfirst = 0; totbytes = 0L; X ClearBuffer(); X retval = recsw(); X FreeMem(spackbuf, (long)(MAXLONGPKS+20)); X FreeMem(msgpkt, (long)(MAXLONGPKS+20)); X return(retval); X} X Xsendsw(firstfile, lastfile) Xint firstfile, lastfile; /* Multiple-send fix */ X{ X char sinit(), sfile(), sdata(), seof(), sbreak(); X sendabort = 0; X /* Multiple-send fix. If this is the first file of the batch then enter X ** send-init state otherwise just enter send-file state. */ X if(firstfile) X state = 'S'; X else X state = 'F'; X while(TRUE) { X switch(state) { X case 'S': state = sinit(); break; X case 'F': state = sfile(); break; X case 'D': state = sdata(); break; X case 'Z': state = seof(); break; X case 'B': if (lastfile || sendabort) { X /* Multiple-send fix. If this is the last file then X ** send a B packet to indicate end-of-batch. */ X state = sbreak(); X break; X } X return(TRUE); /* Otherwise, just return. */ X case 'C': if (sendabort) return(FALSE); X else return(TRUE); X case 'E': dostats('E',"ERROR"); /* so print the err and abort */ X print_host_err(ackpkt); X return(FALSE); X case 'A': if (timeout == USERABORT) { X timeout = GOODREAD; X n = (n+1)%64; X sendabort = 1; X dostats('A',"ABORT"); X strcpy(msgpkt, "D"); X state = 'Z'; X break; X } X if (timeout == TIMEOUT) dostats('A',"TMOUT"); X else { /* protocol error dectected by us */ X dostats('A',"ERROR"); X print_our_err(); X } X return(FALSE); X default: return(FALSE); X } X } X} X Xchar sinit() X{ X int num, len; X X retry++; X if (numtry++ > MAXTRY) return('A'); X spar(msgpkt); X X spack('S',n,13,msgpkt); X switch(rpack(&len,&num,ackpkt)) { X case 'N': return(state); X case 'Y': if (n != num) return(state); X rpar(ackpkt, len); X if (eol == 0) eol = '\n'; X if (quote == 0) quote = MYQUOTE; X numtry = 0; X retry--; X n = (n+1)%64; X return('F'); X case 'E': return('E'); X case FALSE: if (timeout == USERABORT) state = 'A'; X return(state); X default: return('A'); X } X} X Xchar sfile() X{ X int num, len; X X retry++; X if (numtry++ > MAXTRY) return('A'); X X spack('F',n,strlen(filnam),filnam); X switch(rpack(&len,&num,ackpkt)) { X case 'N': X num = (--num<0 ? 63:num); X if (n != num) return(state); X case 'Y': X if (n != num) return(state); X numtry = 0; X retry--; X n = (n+1)%64; X first = 1; X size = getpkt(); X return('D'); X case 'E': X return('E'); X case FALSE: if (timeout == USERABORT) state = 'A'; X return(state); X default: X return('A'); X } X} X Xchar sdata() X{ X int num, len; X X retry++; X if (numtry++ > MAXTRY) return('A'); X X spack('D',n,size,msgpkt); X switch(rpack(&len,&num,ackpkt)) { X case 'N': X num = (--num<0 ? 63:num); X if (n != num) return(state); X case 'Y': X if (n != num) return(state); X numtry = 0; X retry--; X n = (n+1)%64; X if ((size = getpkt()) == 0) return('Z'); X return('D'); X case 'E': X return('E'); X case FALSE: if (timeout == USERABORT) state = 'A'; X return(state); X default: X return('A'); X } X} X Xchar seof() X{ X int num, len; X retry++; X if (numtry++ > MAXTRY) return('A'); X X/* if (timeout == USERABORT) {*/ /* tell host to discard file */ X/* timeout = GOODREAD; */ X/* spack('Z',n,1,"D"); */ X/* } */ X/* else */ X spack('Z',n,sendabort,msgpkt); X switch(rpack(&len,&num,ackpkt)) { X case 'N': X num = (--num<0 ? 63:num); X if (n != num) return(state); X case 'Y': X if (n != num) return(state); X numtry = 0; X dostats('Z',"DONE"); X retry--; X n = (n+1)%64; X return('B'); X case 'E': return('E'); X case FALSE: return(state); X default: return('A'); X } X} X Xchar sbreak() X{ X int num, len; X retry++; X if (numtry++ > MAXTRY) return('A'); X X spack('B',n,0,msgpkt); X switch (rpack(&len,&num,ackpkt)) { X case 'N': X num = (--num<0 ? 63:num); X if (n != num) return(state); X case 'Y': X if (n != num) return(state); X dostats('B', "DONE"); X numtry = 0; X retry--; X n = (n+1)%64; X return('C'); X case 'E': return('E'); X case FALSE: return(state); X default: return ('A'); X } X} X X/* timeout equals USERABORT so lets end the file and quit */ X/* when host receives 'Z' packet with "D" in data field he */ X/* should discard the file. */ X/* Xsabort() X{ X dostats(' ',"ABORT"); X n = (n+1)%64; X retry--; X state = 'Z'; X while (state == 'Z') state = seof(); X while (state == 'B') state = sbreak(); X return(FALSE); X} X*/ X X Xrecsw() X{ X char rinit(), rfile(), rdata(); X int first_time = 1; X X state = 'R'; X X while(TRUE) { X switch(state) { X case 'R': ulp = 0; /* Assume we won't use LONG packets */ X state = rinit(); X break; X case 'Z': X case 'F': state = rfile(first_time); first_time = 0; X break; X case 'D': state = rdata(); X break; X case 'C': return(TRUE); X case 'E': X case 'A': /* easy way to cleanly abort X should really send and ACK X with "X" in data field and X wait for host to abort but X not all kermits support X this feature. */ X if (timeout == USERABORT){ X /* send an error packet back */ X dostats('A',"ABORT"); X spack('E',n,12,"User aborted"); X } X else if (timeout == TIMEOUT) { X /* we timed out waiting */ X /* will we need to spack here ?*/ X dostats('A',"TMOUT"); X } X /* must be 'E' from host or we detected a protocol X ** error */ X else dostats('A',"ERROR"); X X if (state == 'E') print_host_err(msgpkt); X else if (timeout == GOODREAD) /* tell host why */ X print_our_err(); X /* will this kill all files ?*/ X do { X ttime = 2; X readchar(); X } while (timeout == GOODREAD); X fclose(fp); X sendstring("\r"); X return(FALSE); X default: return(FALSE); X } X } X} X Xchar rinit() X{ X int len, num, temp; X retry++; X if (numtry++ > MAXTRY) return('A'); X X if (server) spack('R',n,strlen(filnam),filnam); X else spack('N',n,0,""); X switch(rpack(&len,&num,msgpkt)) { X case 'S': X rpar(msgpkt, len); X /* Rpar() will set ulp if we can use long packets. We can't use X ** that value right away cause we've gotta ACK with normal pkts. */ X temp = ulp; ulp = 0; X spar(msgpkt); X spack('Y',n,13,msgpkt); X ulp = temp; /* Restore using long pkts flag */ X oldtry = numtry; X numtry = 0; X retry--; X n = (n+1)%64; X return('F'); X case 'E': X return('E'); X case 'N': /* Other side NAKed us... */ X return(state); /* ...so try again */ X case FALSE: X if (timeout == USERABORT) return('A'); X if (timeout == TIMEOUT) return(state); /* Resend Rec-init on a timeout */ X spack('N',n,0,""); X return(state); X default: X return('A'); X } X} X Xchar rfile(first_time) Xint first_time; X{ X int num, len, temp; X USHORT a, a7, b8; X char *fileptr, *buf; X X retry++; X if (numtry++ > MAXTRY) return('A'); X X switch(rpack(&len,&num,msgpkt)) { X case 'S': X if (oldtry++ > MAXTRY) return('A'); X if (num == ((n==0) ? 63:n-1)) { X /* Rpar() will set ulp if we can use long packets. We can't use X ** that value right away cause we've gotta ACK with normal pkts. */ X temp = ulp; ulp = 0; X spar(msgpkt); X spack('Y',num,13,msgpkt); X ulp = temp; X numtry = 0; X return(state); X } X else return('A'); X case 'Z': X if (oldtry++ > MAXTRY) return('A'); X if (num == ((n==0) ? 63:n-1)) { X spack('Y',num,0,""); X ScrollInfoMsg(1); X numtry = 0; X return(state); X } X else return('A'); X case 'F': X if (num != n) return('A'); X if(!first_time) { /* Scroll the Z packet line up */ X dostats('Z', "DONE"); X ScrollInfoMsg(1); X } X buf = msgpkt; X fileptr = filnam; X while ((a = *buf++) != '\0') { /* Terminator added by rpack() */ X if (rptflg) { X if (a == rptq) { X rpt = unchar(*buf++); X a = *buf++; X } X } X b8 = 0; X if (ebqflg) { /* 8th-bit prefixing? */ X if (a == ebq) { /* Yes, got an 8th-bit prefix? */ X b8 = 0200; /* Yes, remember this, */ X a = *buf++; /* and get the prefixed character. */ X } X } X if (a == quote) { X a = *buf++; X a7 = a & 0177; X if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a); X } X a |= b8; X if (rpt == 0) rpt = 1; X if (p_mode == 1 && a == '\r') continue; X for (; rpt > 0; rpt--) *fileptr++ = a; X *fileptr = '\0'; /* Terminate the filename */ X } X X if (p_convert) { X char *p; X p = &filnam[0]; X while (*p) { *p = tolower(*p); p++; } X } X if (notfirst) { X totbytes = 0L; X dostats('F',"RECV"); X } X else { /* is the first file so emit actual file name from host */ X notfirst++; X } X if ((fp = fopen(filnam,"w")) == NULL) { X InfoMsg2Line("KERMIT: Unable to create file:", filnam); X strcpy(msgpkt,"VT100 - Kermit - cannot create file: "); X strcat(msgpkt,filnam); X spack('E',n,strlen(msgpkt),msgpkt); /* let host know */ X dostats('E',"ERROR"); X return ('\0'); /* abort everything */ X } X spack('Y',n,0,""); X oldtry = numtry; X numtry = 0; X retry--; X n = (n+1)%64; X return('D'); X X /* totaly done server sending no more */ X case 'B': X if (num != n) return ('A'); X spack('Y',n,0,""); X dostats('B', "DONE"); X ScrollInfoMsg(1); X retry--; X return('C'); X case 'E': X return('E'); X case FALSE: X if (timeout == USERABORT) return('A'); X spack('N',n,0,""); X return(state); X default: X return ('A'); X } X} X Xchar rdata() X{ X int num, len; X retry++; X if (numtry++ > MAXTRY) return('A'); X X switch(rpack(&len,&num,msgpkt)) { X case 'D': X if (num != n) { X if (oldtry++ > MAXTRY) return('A'); X if (num == ((n==0) ? 63:n-1)) { X spack('Y',num,6,msgpkt); X numtry = 0; X return(state); X } X else return('A'); X } X decode(); X spack('Y',n,0,""); X oldtry = numtry; X numtry = 0; X retry--; X n = (n+1)%64; X return('D'); X case 'Z': X if (num != n) return('A'); X spack('Y',n,0,""); X n = (n+1)%64; X dostats('Z',"DONE"); X retry--; X fclose(fp); X return('Z'); X case 'F': X if (oldtry++ > MAXTRY) return('A'); X if (num == ((n==0) ? 63:n-1)) { X spack('Y',num,0,""); X numtry = 0; X return(state); X } X case 'E': X return('E'); X case FALSE: X if (timeout == USERABORT) return('A'); X spack('N',n,0,""); X return(state); X default: X return('A'); X } X} X X Xspack(type,num,len,data) Xchar type, *data; Xint num, len; X{ X int i; X char chksum, t; X register char *bufp; X X if(sending && (lastpkt != num)) { X tp++; X lastpkt = num; X } X dostats(type,mainmode); X bufp = spackbuf; X ClearBuffer(); X X for (i=1; i<=pad; i++) sendchar(padchar); X X *bufp++ = SOH; X if(ulp && len > (MAXPACKSIZ-3)) /* Using long packets */ X t = tochar(0); X else X t = tochar(len+3); X *bufp++ = t; chksum = t; X t = tochar(num); X *bufp++ = t; chksum += t; X *bufp++ = type; chksum += type; X if(ulp && len > (MAXPACKSIZ-3)) { /* Using long packets */ X unsigned int pl = len + 1; X X t = tochar(pl / 95); X *bufp++ = t; chksum += t; X t = tochar(pl % 95); X *bufp++ = t; chksum += t; X t = tochar((((chksum&0300) >> 6)+chksum)&077); X *bufp++ = t; chksum += t; X } X for (i=0; i<len; i++) { X *bufp++ = data[i]; chksum += data[i]; X } X chksum = (((chksum&0300) >> 6)+chksum)&077; X *bufp++ = tochar(chksum); X if (eol) X *bufp++ = eol; /* Use sender's requested end-of-line */ X if (eol != '\r') X *bufp++ = '\r'; X *bufp++ = '\n'; X *bufp = '\0'; X sendstring(spackbuf); X} X Xrpack(len,num,data) Xint *len, *num; Xchar *data; X{ X int i, done; X char type, cchksum, rchksum; X char t = '\0'; X X do { X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X } while (t != SOH); X X done = FALSE; X while (!done) { X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X cchksum = t; X *len = unchar(t)-3; X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X cchksum += t; X *num = unchar(t); X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X cchksum += t; X type = t; X if((*len == -3) && ulp) { /* Using long packets */ X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X cchksum += t; X *len = unchar(t)*95; X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X cchksum += t; X *len += unchar(t); X (*len)--; X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X if(unchar(t) != ((((cchksum&0300) >> 6)+cchksum)&077)) return(FALSE);; X cchksum += t; X } X for (i=0; i<*len; i++) { X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X cchksum = cchksum + t; X data[i] = t; X } X data[*len] = 0; X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X rchksum = unchar(t); X t = readchar(); X if (timeout != GOODREAD) return(FALSE); X if (t == SOH) continue; X done = TRUE; X } X if(type != 'B' && type != 'Z') X dostats(type,mainmode); X cchksum = (((cchksum&0300) >> 6)+cchksum)&077; X if (cchksum != rchksum) return(FALSE); X if(!sending && (*num != lastpkt)) { X tp++; X lastpkt = *num; X } X return((int)type); X} X Xgetpkt() { X int i,eof; X X static char leftover[10] = { '\0', '\0', '\0', '\0', '\0', X '\0', '\0', '\0', '\0', '\0' }; X X if (first == 1) { X first = 0; X *leftover = '\0'; X t = getc(fp); X if (t == EOF) { X first = 1; X return(size = 0); X } X totbytes++; X } X else if (first == -1) { X first = 1; X return(size = 0); X } X for (size = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ; X *leftover = '\0'; X rpt = 0; X eof = 0; X while (!eof) { X next = getc(fp); X if (next == EOF) { X first = -1; X eof = 1; X } X else totbytes++; X osize = size; X encode(t); X t = next; X if (size == spsiz-3) return(size); X if (size > spsiz-3) { X for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++) X ; X size = osize; X msgpkt[size] = '\0'; X return(size); X } X } X return(size); X} X Xvoid encode(a) Xchar a; X{ X int a7,b8; X X if (p_mode == 1 && a == '\n') { X rpt = 0; X msgpkt[size++] = quote; X msgpkt[size++] = ctl('\r'); X if (size <= spsiz-3) osize = size; X msgpkt[size++] = quote; X msgpkt[size++] = ctl('\n'); X msgpkt[size] = '\0'; X return; X } X if (rptflg) { X if (a == next && (first == 0)) { X if (++rpt < 94) return; X else if (rpt == 94) { X msgpkt[size++] = rptq; X msgpkt[size++] = tochar(rpt); X rpt = 0; X } X } X else if (rpt == 1) { X rpt = 0; X encode(a); X if (size <= spsiz-3) osize = size; X rpt = 0; X encode(a); X return; X } X else if (rpt > 1) { X msgpkt[size++] = rptq; X msgpkt[size++] = tochar(++rpt); X rpt = 0; X } X } X a7 = a & 0177; X b8 = a & 0200; X X if (ebqflg && b8) { /* Do 8th bit prefix if necessary. */ X msgpkt[size++] = ebq; X a = a7; X } X X if ((a7 < SP) || (a7==DEL)) { X msgpkt[size++] = quote; X a = ctl(a); X } X if (a7 == quote) msgpkt[size++] = quote; X if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote; X X if ((ebqflg) && (a7 == ebq)) /* Prefix the 8th bit prefix */ X msgpkt[size++] = quote; /* if doing 8th-bit prefixes */ X X msgpkt[size++] = a; X msgpkt[size] = '\0'; X} X Xvoid decode() X{ X USHORT a, a7, b8; X char *buf; X X buf = msgpkt; X rpt = 0; X X while ((a = *buf++) != '\0') { /* Terminator added by rpack() */ X if (rptflg) { X if (a == rptq) { X rpt = unchar(*buf++); X a = *buf++; X } X } X b8 = 0; X if (ebqflg) { /* 8th-bit prefixing? */ X if (a == ebq) { /* Yes, got an 8th-bit prefix? */ X b8 = 0200; /* Yes, remember this, */ X a = *buf++; /* and get the prefixed character. */ X } X } X if (a == quote) { X a = *buf++; X a7 = a & 0177; X if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a); X } X a |= b8; X if (rpt == 0) rpt = 1; X if (p_mode == 1 && a == '\r') continue; X totbytes += rpt; X for (; rpt > 0; rpt--) putc(a, fp); X } X return; X} X Xvoid spar(data) Xchar data[]; X{ X data[0] = tochar(MAXPACKSIZ); X data[1] = tochar(TTIME_KERMIT); X data[2] = tochar(MYPAD); X data[3] = ctl(MYPCHAR); X data[4] = tochar(MYEOL); X data[5] = MYQUOTE; X if ((p_parity > 0) || ebqflg) { /* 8-bit quoting... */ X data[6] = MYEBQ; /* If parity or flag on, send &. */ X if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on */ X (ebq > 0140 && ebq < 0177) || /* if other side has asked us to */ X (ebq == 'Y')) X ebqflg = 1; X } X else /* Normally, */ X data[6] = 'Y'; /* just say we're willing. */ X data[7] = '1'; X data[8] = MYRPTQ; X data[9] = tochar(IDOLONG); /* Tell 'em I do LONG packets */ X data[10] = tochar(0); /* Don't do windows */ X data[11] = tochar(p_kmaxpack / 95); X data[12] = tochar(p_kmaxpack % 95); X data[13] = '\0'; X} X Xvoid rpar(data, len) Xchar data[]; Xint len; X{ X int ospsiz; X X spsiz = unchar(data[0]); X ospsiz = spsiz; X ttime = unchar(data[1]); X pad = unchar(data[2]); X padchar = ctl(data[3]); X eol = unchar(data[4]); X quote = data[5]; X rptflg = 0; X ebqflg = 0; X if (len >= 6 && data[6] != 0) { X ebq = data[6]; X if ((ebq > 040 && ebq < 0100) || X (ebq > 0140 && ebq < 0177)) ebqflg = 1; X else if (((p_parity > 0) || ebqflg) && (ebq == 'Y')) { X ebqflg = 1; X ebq = '&'; X } X else ebqflg = 0; X } X if (len >= 8 && data[8] != 0) { X rptq = data[8]; X rptflg = ((rptq > 040 && rptq < 0100) || X (rptq > 0140 && rptq < 0177)); X } X if(len >= 9 && data[9] != 0) { X int capas; X for(capas=9; data[capas] & 1; capas++) ; /* Skip over continuations */ X if((ulp = (data[9] & IDOLONG)) == IDOLONG) { X spsiz = 500; /* Default if no packet size specified */ X if(len >= capas+3) { X spsiz = unchar((data[capas+2]) * 95) + unchar(data[capas+3]); X if(spsiz > MAXLONGPKS) X spsiz = MAXLONGPKS; X else if(spsiz < 10) /* Reasonable? */ X spsiz = 500; X } X } X } X} X Xsaybye() X{ X int len,num; X if(numreqs != 0) /* Requester's up... */ X Delay(5L); /* ...so wait for Intuition, just in case. */ X spack('G',n,1,"F"); /* shut down server no more files */ X rpack(&len,&num,ackpkt); X} X Xprint_our_err() X{ X if (retry > MAXTRY || oldtry > MAXTRY) { X InfoMsg1Line("KERMIT: Too may retries for packet"); X strcpy(msgpkt,"VT100 KERMIT: Too many retries for packet"); X } X else { X InfoMsg1Line("KERMIT: Protocol Error"); X strcpy(msgpkt,"VT100 KERMIT: Protocol Error"); X } X spack('E',n,strlen(msgpkt),msgpkt); X} X Xprint_host_err(msg) Xchar *msg; X{ X InfoMsg2Line("KERMIT: Host Error:", msg); X} X Xdostats(type,stat) Xchar type,*stat; X{ X char *statusform = "%5s %-15.15s Pkt: %4d Retr: %2d Bytes: %6ld Type: %c", X status[80]; X X if (type == 'Y' || type == 'N' || type == 'G') return; X X sprintf(status, statusform, stat, filnam, tp, retry-1, X (LONG)totbytes, type); X InfoMsgNoScroll(status); X} X XClearBuffer() X{ X AbortIO(Read_Request); X Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit); X WaitIO(Read_Request); X Read_Request->IOSer.io_Command = CMD_CLEAR; X DoIO(Read_Request); X Read_Request->IOSer.io_Command = CMD_READ; X SendIO(Read_Request); X} ________This_Is_The_END________ if test `wc -l < kermit.c` -ne 1028; then echo 'shar: kermit.c was damaged during transit (should have been 1028 bytes)' fi fi ; : end of overwriting check exit 0
ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)
Program Name: vt100 (version 2.8) Submitted By: acs@uts.amdahl.com (Tony Sumrall) Summary: vt100 terminal emulator. Poster Boy: Brent Woods (ahh@j.cc.purdue.edu) Tested. Part 3 of 4. NOTES: This program was tested by our Guest Moderator, Robert Tillotson. He had a couple of problems with the program at first (a couple of Guru errors, and we think that the vt100 task hung around instead of exiting properly; not certain, though), but when we (Rob, Pat, and I) tested it a few hours ago, none of us had any problems. I dunno. It seems to work okay now. Probably some fluke or other. Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga USENET: ...!j.cc.purdue.edu!ahh ARPANET: ahh@j.cc.purdue.edu BITNET: PODUM@PURCCVM PHONE: +1 (317) 743-8421 USNAIL: 320 Brown St., #406 / West Lafayette, IN 47906 ====================================cut here============================ #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 acs other 10384 Feb 1 18:54 remote.c # -rw-r--r-- 1 acs other 24586 Feb 1 18:55 script.c # -rw-r--r-- 1 acs other 22122 Feb 1 18:56 vt100.c # echo 'x - remote.c' if test -f remote.c; then echo 'shar: not overwriting remote.c'; else sed 's/^X//' << '________This_Is_The_END________' > remote.c X/**************************************************** X * vt100 emulator - remote character interpretation X * X * v2.8 880117 ACS - See the README file 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 X/************************************************ X* function to handle remote characters X*************************************************/ Xvoid doremote(c) Xchar c; X { X if (c == 24) { inesc = 0; inctrl = 0; 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 -= 8*p[0]; if (y<top) y = top; return; X case 'B': if (p[0]<=0) p[0] = 1; X y += 8*p[0]; if (y>bot) y = bot; return; X case 'C': if (p[0]<=0) p[0] = 1; X x += 8*p[0]; if (x>MAXX) x = MAXX; return; X case 'D': if (p[0]<=0) p[0] = 1; X x -= 8*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]*8)+MINY; x = (--p[1]*8)+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,0L, X (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]), X (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+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'? 8 : -8)) * p[0], 0L, X (long) x, (long) y-6, X (long) MAXX+7, (long) y+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]*8)+MINY; bot = (--p[1]*8)+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+2),(long)(MAXX+7),(long)(MAXY+1)); X } X else if (p[0] == 1) { X if (y > MINY) RectFill(mywindow->RPort, X (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7)); X } X else RectFill(mywindow->RPort, X (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+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)/8)+1,((x-MINX)/8)+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,0L,8L,(long)MINX,(long)(top-6), X (long)(MAXX+7),(long)(bot+1)); X if (y < bot) y += 8; X } X else { X if (y < top) if (y > MINY) y -= 8; X if (y == top) X ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6), X (long)(MAXX+7),(long)(bot+1)); X if (y > top) y -= 8; X } X return; X } X 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,-6,8,1); X break; X X case 'j': X case 'm': X case 'v': doline(4,-6,4,-2); X if (c=='j') doline(0,-2,4,-2); X else if (c=='m') doline(4,-2,8,-2); X else doline(0,-2,8,-2); X break; X X case 'k': X case 'l': X case 'w': doline(4,-2,4,1); X if (c=='k') doline(0,-2,4,-2); X else if (c=='l') doline(4,-2,8,-2); X else doline(0,-2,8,-2); X break; X X case 'n': X case 'q': doline(0,-2,8,-2); X if (c=='n') doline(4,-6,4,2); X break; X X case 't': X case 'u': X case 'x': doline(4,-6,4,1); X if (c=='t') doline(4,-2,8,-2); X else if (c=='u') doline(0,-2,4,-2); X break; X } X x = newx; X } X 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,(long)x,(long)(y-6), X (long)(MAXX+7),(long)(y+1)); X else if (p[0] == 1) RectFill(mywindow->RPort, X (long)MINX,(long)(y-6),(long)(x+7),(long)(y+1)); X else RectFill(mywindow->RPort, X (long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1)); X SetAPen(mywindow->RPort,1L); X return; X } X ________This_Is_The_END________ if test `wc -l < remote.c` -ne 398; then echo 'shar: remote.c was damaged during transit (should have been 398 bytes)' fi fi ; : end of overwriting check echo 'x - script.c' if test -f script.c; then echo 'shar: not overwriting script.c'; else sed 's/^X//' << '________This_Is_The_END________' > script.c X/************************************************************* X * vt100 terminal emulator - Script file support X * X * v2.8 880117 ACS - See the README file 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 FONTNAMESIZE 40 X#define FONTSUFFIX ".font" X#define MAXFONTVARLEN 34 /* 40 minus sizeof(".font") */ X Xchar myfontname[FONTNAMESIZE]; X Xstruct COMMAND { X void (*func)(); X char *cname; X}; X Xstruct LABEL { X struct LABEL *next; X char *name; X long pos; X}; X Xextern long atol(); 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; /* file pointer for script file */ Xstruct LABEL *lbase = NULL; /* will point to first label */ Xstruct LABEL *labels; /* current label pointer */ X Xvoid cmd_short(); X X/********************** command tables *******************************/ Xstatic struct COMMAND inicmds[] = { /* initialization commands */ X cmd_bkg, "bac", /* set background color */ X cmd_bold, "bol", /* set bold color */ X cmd_buf, "buf", /* set buffer size */ X cmd_cursor, "cur", /* set cursor color */ X cmd_depth, "dep", /* set screen depth */ X cmd_fore, "for", /* set foreground color */ X cmd_font, "fon", /* set font */ X cmd_inter, "int", /* interlace ON/OFF */ X cmd_lines, "lin", /* num lines */ X cmd_screen, "scr", /* Screen WB/CUST */ X cmd_unit, "unit", /* Unit of serial.device to use */ X cmd_volume, "vol", /* set volume */ X cmd_wb, "wb", /* use WB colors */ X cmd_short, "sho", /* Set shortcuts */ X cmd_null, NULL /* mark the end of the list */ X}; Xstatic struct COMMAND scrcmds[] = { /* script only commands */ X cmd_as, "asc", /* ascii send */ X cmd_beep, "bee", /* Beep */ X cmd_cap, "cap", /* ascii capture on/off */ X cmd_cd, "cd", /* change directory */ X cmd_delay, "del", /* delay amount of seconds */ X cmd_goto, "got", /* goto label */ X cmd_kb, "kb", /* kermit bye (for server) */ X cmd_kg, "kg", /* kermit get file */ X cmd_kr, "kr", /* kermit receive file */ X cmd_ks, "ks", /* kermit send file */ X cmd_on, "on", /* on a 'string' do a cmd */ X cmd_recf, "recf", /* receive a file from host */ X cmd_sb, "sb", /* Send a break */ X cmd_send, "send", /* send string to host */ X cmd_sendf, "sendf", /* send a file to host */ X cmd_xr, "xr", /* xmodem receive file */ X cmd_xs, "xs", /* xmodem send file */ X cmd_wait, "wait", /* wait for a host string */ X cmd_null, NULL /* mark the end of the list */ X}; Xstatic struct COMMAND commands[]= { /* generally available commands */ X cmd_appcur, "app", /* turn app. cursor on/off */ X cmd_baud, "bau", /* Set Baud Rate */ X cmd_bt, "bre", /* Set Break Time */ X cmd_conv, "con", /* convert fn to lowercase */ X cmd_echo, "ech", /* turn echo on or off */ X cmd_exit, "exi", /* exit script file */ X cmd_fnc, "f", /* define function key */ X cmd_key, "key", /* keyscript character */ X cmd_kmaxpk, "kmaxpack", /* Kermit maximum packet size */ X cmd_mode, "mod", /* KERMIT transfer mode */ X cmd_numkey, "numkey", /* turn numeric kpad on/off */ X cmd_parity, "parity", /* Set Parity */ X cmd_swap, "swap", /* Swap BS and DEL */ X cmd_wrap, "wrap", /* turn wrap on or off */ X cmd_xbeep, "xbee", /* Beep at end of xfer */ X cmd_xproto, "xproto", /* Xfer Protocol */ X cmd_null, NULL /* 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 modcmd { X char im; /* IMage */ X char tx; /* TeXt */ X char cn; /* CoNvert */ X char nl; X} modcmd_chars; X Xextern struct scrcmd { X char em; /* Execute Macro */ X char ab; /* Abort 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 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 "xm", &(modecmd_chars.xm), /* xmodem mode */ X "ke", &(modecmd_chars.ke), /* kermit mode */ X "xmc", &(modecmd_chars.xmc), /* xmodemcrc mode */ X /* Comm items: */ 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 /* Script items: */ X "execute", &(scrcmd_chars.em), /* execute macro */ X "abort", &(scrcmd_chars.ab), /* abort 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 NULL, NULL 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 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) Xchar *p; Xint l; X{ X int i,l2; X X /* downcase the command */ X for (i=0; i<l; i++) p[i] |= ' '; X X /* now search for it (first in the init command list) */ X if (doing_init) X for (i=0; inicmds[i].func != cmd_null; ++i) { X l2 = strlen(inicmds[i].cname); X if (l >= l2 && strncmp(p, inicmds[i].cname, l2) == 0) { X (*inicmds[i].func)(next_wrd(p+l, &l)); X return(TRUE); X } X } X X /* or the script command list */ X else X for (i=0; scrcmds[i].func != cmd_null; ++i) { X l2 = strlen(scrcmds[i].cname); X if (l >= l2 && strncmp(p, scrcmds[i].cname, l2) == 0) { X (*scrcmds[i].func)(next_wrd(p+l, &l)); X return(TRUE); X } X } X X /* now search for it (in the standard command list) */ X for (i=0; commands[i].func != cmd_null; ++i) { X l2 = strlen(commands[i].cname); X if (l >= l2 && strncmp(p, commands[i].cname, l2) == 0) { X (*commands[i].func)(next_wrd(p+l, &l)); X return(TRUE); X } X } X if (doing_init) { X puts("Init: unknown command:"); X puts(p); X } X else InfoMsg2Line("Script - unknown command:",p); X X return(FALSE); 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(&Script_Timer)) X AbortIO((char *) &Script_Timer); X Wait (1L << Script_Timer_Port->mp_SigBit); X WaitIO(&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 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 == '#') continue; X if (*p) exe_cmd(p,l); X return(0); X } /* end of while */ X if (stat == GOTOLABEL) 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(&Script_Timer)) X AbortIO((char *) &Script_Timer); /* so abort it */ X Wait (1L << Script_Timer_Port->mp_SigBit); /* Wait for the sig */ X WaitIO(&Script_Timer); /* Get my reply back */ X } X InfoMsg1Line("Script: terminated"); X script_on = FALSE; X script_wait = TRUE; X fclose(sf); X if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE)) X ActivateWindow(mywindow); X} X X/* remove quotes terminate string & return pointer to start */ X Xchar *tostring(ptr) Xchar *ptr; X{ X char *s1,*s2; X X s1 = ptr; X if (*ptr == '"') { X while(*ptr++ && *ptr != '"') ; X if (*ptr == '"') { X *ptr = '\0'; X ptr = s2 = ++s1; X while(*s2) { X if (*s2 != '^') *s1++ = *s2; X else if (*(s2+1) == '^') *s1++ = *s2++; X else *s1++ = ((*++s2)|' ')-96; X s2++; X } X *s1 = '\0'; X return(ptr); X } 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 Xvoid cmd_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} X Xvoid cmd_send(str) Xchar *str; X{ X sendstring(tostring(str)); X} X Xvoid cmd_wait(str) Xchar *str; X{ X str = tostring(str); X *(str+20) = '\0'; /* 20 characters max */ X strcpy(wait_string, str); X waitsize = strlen(str); X script_wait = WAIT_STRING; X} X Xvoid cmd_on(str) Xchar *str; X{ X char *p; X X p = tostring(str); X strcpy(on_string, p); X onsize = strlen(p); X *(p+onsize+2+20) = '\0'; /* 20 characters max */ X strcpy(on_cmd,p+onsize+2); X} X Xvoid cmd_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((char *) &Script_Timer.tr_node); X} X Xvoid cmd_exit(option) Xchar *option; X{ X char *p; X int l; X X if (doing_init) return; 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} X Xvoid cmd_ks(file) Xchar *file; X{ X char name[80], *p; X X name[0] = '\0'; X if(file == NULL || *file == '\0') { X req("Kermit Send:",name,1); X p = name; X } X else p = file; X multi_xfer(p, doksend, 1); X} X Xvoid cmd_kr(file) Xchar *file; X{ X char name[80]; X X name[0] = '\0'; X X multi_xfer(name, dokreceive, 0); X} X Xvoid cmd_kg(file) Xchar *file; X{ X char name[80], *p; X X name[0] = 0; X server = TRUE; X if(file == NULL || *file == '\0') { X req("Kermit GET remote file(s):", name, 1); X p = name; X } X else p = file; X multi_xfer(p, dokreceive, 0); X} X Xvoid cmd_kb() X{ X saybye(); X} X Xvoid cmd_recf(file) Xchar *file; 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 default: X cmd_kr(file); X break; X } X} X Xvoid cmd_sendf(file) Xchar *file; 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 break; X } X cmd_xs(file); X break; X case 3: /* Kermit */ X default: X cmd_ks(file); X break; X } X} X Xvoid cmd_xs(file) Xchar *file; X{ X char name[80], *p; X X name[0] = '\0'; X if(file == NULL || *file == '\0') { X req("Xmodem Send:",name,1); X p = name; X } X else p = file; X multi_xfer(p, XMODEM_Send_File, 1); X} X Xvoid cmd_xr(file) Xchar *file; X{ X char name[80], *p; X X name[0] = '\0'; X if(file == NULL || *file == '\0') { X req("Xmodem Receive:",name,1); X p = name; X } X else p = file; X multi_xfer(p, XMODEM_Read_File, 1); X} X Xvoid cmd_cd(name) Xchar *name; X{ X set_dir(name); X} X Xvoid cmd_sb(str) Xchar *str; X{ X sendbreak(); X} X Xvoid cmd_baud(rate) Xchar *rate; X{ X int i = atoi(rate); 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 if (doing_init) { X puts("Init: invalid baud rate:"); X puts(rate); X } X else InfoMsg2Line("Script: invalid baud rate: ",rate); X break; X } X} X Xvoid cmd_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 if (doing_init) { X puts("Init: invalid parity:"); X puts(par); X } X else InfoMsg2Line("Script: invalid parity: ",par); X return; X } X p_parity = i; X if (doing_init == 0) redocomm(); X X} X Xvoid cmd_bt(breaklength) Xchar *breaklength; X{ X p_break = atol(breaklength); X if (doing_init) return; X X AbortIO(Read_Request); X Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit); X WaitIO(Read_Request); X Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break; X setparams(); X} X Xvoid cmd_kmaxpk(pks) Xchar *pks; X{ X int i = atoi(pks); X X if(i <= MAXLONGPKS) X p_kmaxpack = i; X else { X if(doing_init) { X puts("Init: Kermit packet size too big:"); X puts(pks); X } X else InfoMsg2Line("Script: Kermit packet size too big: ",pks); X } X} X Xvoid cmd_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 if (doing_init) { X puts("Init: invalid transfer mode:"); X puts(tmode); X } X else X InfoMsg2Line("Script: invalid transfer mode: ",tmode); X return; X } X if (doing_init == 0) redocomm(); X} X Xvoid cmd_as(file) Xchar *file; X{ X do_send(file); X} X Xvoid cmd_cap(file) Xchar *file; X{ X do_capture(file); X} X Xvoid cmd_beep(dummy) Xchar *dummy; X{ X if (p_volume == 0) DisplayBeep(NULL); X else { X BeginIO(&Audio_Request); X WaitIO(&Audio_Request); X } 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 Xvoid cmd_echo(par) Xchar *par; X{ X setvar(par,0,&p_echo); X if (doing_init == 0) redoutil(); X} X Xvoid cmd_wrap(par) Xchar *par; X{ X setvar(par,0,&p_wrap); X if (doing_init == 0) redoutil(); X} X Xvoid cmd_xbeep(par) Xchar *par; X{ X setvar(par,0,&p_xbeep); X if (doing_init == 0) redoutil(); X} X Xvoid cmd_xproto(par) Xchar *par; X{ X int i, l = strlen(par); X char temp[40]; X X /* downcase the parameter */ X for(i=0; i<l; i++) par[i] |= ' '; X X p_xproto = MODEMAX + 1; /* Establish a default */ 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 p_xproto = MODEMAX - 1; X sprintf(temp, "XPROTO \"%.10s\" unknown, %s used", par, &(*(xprotos[p_xproto]))); X if(doing_init) { X puts("Init:"); X puts(temp); X } X else X InfoMsg2Line("Script:", temp); X } X if(doing_init == 0) redofile(); X} X Xvoid cmd_numkey(par) Xchar *par; X{ X setvar(par,1,&p_keyapp); X if (doing_init == 0) redoutil(); X} X Xvoid cmd_appcur(par) Xchar *par; X{ X setvar(par,0,&p_curapp); X if (doing_init == 0) redoutil(); X} X Xvoid cmd_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} X Xvoid cmd_bkg(par) Xchar *par; X{ X setvar(par,2,&p_background); X} X Xvoid cmd_bold(par) Xchar *par; X{ X setvar(par,2,&p_bold); X} X Xvoid cmd_buf(par) Xchar *par; X{ X setvar(par,3,&p_buffer); X} X Xvoid cmd_cursor(par) Xchar *par; X{ X setvar(par,2,&p_cursor); X} X Xvoid cmd_depth(par) Xchar *par; X{ X setvar(par,3,&p_depth); X} X Xvoid cmd_fore(par) Xchar *par; X{ X setvar(par,2,&p_foreground); X} X Xvoid cmd_font(par) Xchar *par; X{ X char temp[80]; X X /* myfontname has been initialized from p_font in InitDefaults() in X ** init.c */ X X if(*par) { X if(strlen(par) < MAXFONTVARLEN) { X strcpy(myfontname, par); X strcat(myfontname,FONTSUFFIX); X } X else { X puts("Init:"); X sprintf(temp, "Font specification too long, \"%s\" used", myfontname); X puts(temp); X } X } X myattr.ta_Name = (STRPTR)myfontname; X} X Xvoid cmd_inter(par) Xchar *par; X{ X setvar(par,0,&p_interlace); X} X Xvoid cmd_lines(par) Xchar *par; X{ X setvar(par,3,&p_lines); X} X Xvoid cmd_screen(par) Xchar *par; X{ X if ((par[0]|' ') == 'w') p_screen = 0; X else p_screen = 1; X} X Xvoid cmd_unit(par) Xchar *par; X{ X setvar(par, 3, &p_unit); X} X Xvoid cmd_wb(par) Xchar *par; X{ X setvar(par,0,&p_wbcolors); X} X Xvoid cmd_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++) 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 ** shortcur 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 if(p[l]) X *(shortkeys[i].pos) = p[l]; X else X *(shortkeys[i].pos) = ' '; X return; X } X } X if(doing_init) { X puts("Init: Unknown shortcut: "); X puts(par); X } X else X InfoMsg2Line("Script: Unknown shortcut:", par); X} X Xvoid cmd_key(par) Xchar *par; X{ X int i; X X if (sscanf(par,"%x",&i) == 1) p_keyscript = (char)(i & 0x7f); X} X Xvoid cmd_volume(par) Xchar *par; X{ X setvar(par,3,&p_volume); X} X Xvoid cmd_conv(par) Xchar *par; X{ X setvar(par,0,&p_convert); X if (doing_init == 0) redoutil(); X} X Xvoid cmd_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 (*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} X Xvoid cmd_null(dummy) Xchar *dummy; X{ } X ________This_Is_The_END________ if test `wc -l < script.c` -ne 1090; then echo 'shar: script.c was damaged during transit (should have been 1090 bytes)' fi fi ; : end of overwriting check echo 'x - vt100.c' if test -f vt100.c; then echo 'shar: not overwriting vt100.c'; else sed 's/^X//' << '________This_Is_The_END________' > vt100.c X/******************************************************************** X * vt100 terminal emulator with xmodem transfer capability X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - Provide handling of the msgs from the X * info/status window. 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 Parity and Word Length and support code X * 860823 DBW - Integrated and rewrote lots of code 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 * use <esc> to abort xmodem or kermit transfers X * X * written by Michael Mounier X * new version by Dave Wecker X *******************************************************************/ X X/* all includes defines and globals */ X#include "vt100.h" X XAPTR OrigWindowPtr; /* Used by init.c when opening a new screen */ X X/**************************************************************/ X/* here are all the global definitions that appear in vt100.h */ X/**************************************************************/ X Xchar bufr[BufSize]; Xint fd, timeout = FALSE, ttime; Xint multi = FALSE, server; Xlong bytes_xferred; Xchar MyDir[60]; XBPTR StartLock = 0; Xstruct IntuitionBase *IntuitionBase; Xstruct GfxBase *GfxBase; X Xextern char myfontname[]; /* In script.c */ X Xstruct TextAttr myattr = { X (STRPTR)(&(myfontname[0])), X 8, X 0, X 0}; Xstruct TextFont *myfont = NULL; Xstruct NewScreen NewScreen = { X 0,0,640,200,1, /* left, top, width, height, depth */ X 0,1,HIRES, /* DetailPen, BlockPen, ViewModes */ X CUSTOMSCREEN,&myattr, /* Type, Font */ X (UBYTE *)"VT100", /* Title */ X NULL,NULL }; /* Gadgets, Bitmap */ Xstruct NewWindow NewWindow = { X 0,0,640,200, /* left, top, width, height */ X 0,1, /* detailpen, blockpen */ X MENUPICK|CLOSEWINDOW|RAWKEY|ACTIVEWINDOW|INACTIVEWINDOW, X SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG, X NULL,NULL, /* FirstGadget, CheckMark */ X (UBYTE *)NULL, X NULL, /* set screen after open screen */ X NULL, /* bitmap */ X 640, 200, 640, 200, /* minw, minh, maxw, maxh */ X CUSTOMSCREEN /* Type */ X }; Xstruct NewWindow NewReqWindow = { X 10, 15, ((54*8)+4+18), ((4*8)+11+2), /* left, top, width, height */ X 0, 1, /* detailpen, blockpen */ X /* IDCMP Flags... */ X CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE, X /* Flags... */ X SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT | X WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, X X NULL, /* First gadget */ X NULL, /* CheckMark */ X (UBYTE *)"VT100 Info & Xfer Status", /* Title */ X NULL, /* set screen after open screen */ X NULL, /* bitmap */ X ((5*8)+4+18), ((1*8)+11+2), 640, 200, /* minw, minh, maxw, maxh */ X CUSTOMSCREEN /* Type */ X }; Xstruct IntuiText MyTitle = { X 0,1,JAM2,26,0, /* front pen, back pen, mode, left, top */ X &myattr, /* font */ X (UBYTE *)VERSION, /* title */ X NULL}; /* next text */ X Xstruct Screen *myscreen = NULL; /* ptr to applications screen */ Xstruct Window *mywindow = NULL; /* ptr to applications window */ Xstruct Window *reqwindow = NULL; /* ptr to requester's window */ Xstruct ViewPort *myviewport; Xstruct RastPort *myrastport; Xstruct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ Xstruct Preferences *Prefs; /* preferences from GetPrefs() */ X X/**** String requester support ******/ X Xchar InpBuf[80],UndoBuf[80],Prompt[80]; Xstruct IntuiText donetxt = { X 1,0,JAM2,0,0, /* front pen, back pen, mode, left, top */ X &myattr, /* font */ X (UBYTE *)"DONE", /* question to ask */ X NULL}; /* next text */ Xstruct Gadget mydonegad = { X &mystrgad,290,2,40,10, /* next,left,top,width,height */ X GADGHCOMP|REQGADGET, /* flags */ X RELVERIFY|ENDGADGET, /* activation */ X BOOLGADGET, /* gadget type */ X NULL,NULL,&donetxt, /* gad render, sel render, gad text */ X 0L,NULL,2,NULL}; /* mutual exclude, special, ID, user data */ Xstruct StringInfo mystrinfo = { X (UBYTE *)InpBuf, X (UBYTE *)UndoBuf, X 0,80,0,0,0,0, /* initial, max, disp, undo, #chrs, dsp chrs */ X 0,0,NULL,0L,NULL}; /* left,top,layer,longint,keymap */ Xstruct Gadget mystrgad = { X NULL,10,12,320,10, /* next,left,top,width,height */ X GADGHCOMP|REQGADGET,/* flags */ X ENDGADGET,STRGADGET,/* activation, type */ X NULL,NULL,NULL, /* gad render, sel render, gad text */ X 0L, /* mutual exclude */ X (APTR)&mystrinfo, /* special info */ X 1,NULL}; /* gadget ID, user data */ Xstruct IntuiText mystrtxt = { X 0,1,JAM2,10,2, /* front pen, back pen, mode, left, top */ X &myattr, /* font */ X (UBYTE *)Prompt, /* question to ask */ X NULL}; /* next text */ Xstruct Requester myrequest = { X NULL,5,10,340,22, /* older requester, left, top, width, height */ X 0,0,&mydonegad, /* relleft reltop, gadgets */ X NULL, /* border */ X &mystrtxt, /* text */ X NULL,1,NULL, /* flags, back fill pen, layer */ X {0,0,0,0,0,0,0,0, X 0,0,0,0,0,0,0,0, X 0,0,0,0,0,0,0,0, X 0,0,0,0,0,0,0,0}, /* pad1 */ X NULL,NULL, /* image bit map, rquest window */ X {0,0,0,0,0,0,0,0,0, X 0,0,0,0,0,0,0,0,0, X 0,0,0,0,0,0,0,0,0, X 0,0,0,0,0,0,0,0,0} /* pad2 */ X }; X Xint numreqs = 0; /* number of outstanding requestors */ Xint reqwinup = 0; /* Requester window is NOT displayed */ Xextern int reqmaxx, reqmaxy, reqmaxlen; /* Defined in window.c */ Xextern void ReqNewSize(); /* New req window size -- window.c */ Xextern void KillReq(); /* Kill requester window in window.c */ X X/***** menu structures *****/ Xstruct MenuItem FileItem[FILEMAX]; Xstruct IntuiText FileText[FILEMAX]; Xstruct MenuItem ModeItem[MODEMAX]; Xstruct IntuiText ModeText[MODEMAX]; Xstruct MenuItem CommItem[COMMAX]; Xstruct IntuiText CommText[COMMAX]; Xstruct MenuItem RSItem[RSMAX]; Xstruct IntuiText RSText[RSMAX]; Xstruct MenuItem ParItem[PARMAX]; Xstruct IntuiText ParText[PARMAX]; Xstruct MenuItem XFItem[XFMAX]; Xstruct IntuiText XFText[XFMAX]; Xstruct MenuItem ScriptItem[SCRIPTMAX]; Xstruct IntuiText ScriptText[SCRIPTMAX]; Xstruct MenuItem UtilItem[UTILMAX]; Xstruct IntuiText UtilText[UTILMAX]; Xstruct Menu menu[MAXMENU]; Xstruct IOExtSer *Read_Request; Xchar *rs_in; Xstruct IOExtSer *Write_Request; Xchar rs_out[2]; Xstruct timerequest Timer; Xstruct MsgPort *Timer_Port = NULL; Xstruct timerequest Script_Timer; Xstruct MsgPort *Script_Timer_Port = NULL; Xstruct IOAudio Audio_Request; Xstruct MsgPort *Audio_Port = NULL; XUBYTE *BeepWave; XUBYTE Audio_AllocMap[4] = { 1, 8, 2, 4 }; Xint x,y,curmode; Xint MINX = 0; Xint MAXX = 632; Xint MINY = 14; Xint MAXY = 198; Xint top = 14; Xint bot = 198; Xint savx = 0; Xint savy = 14; Xint savmode = 0; Xint nlmode = 0; Xint alt = 0; Xint savalt = 0; Xint a[2] = { 0, 0 }; Xint sa[2] = { 0, 0 }; Xint inesc = -1; Xint inctrl = -1; Xint private = 0; Xint badseq = 0; Xint maxcol = 79; X X/*************************** defaults *******************************/ Xchar *p_font = "topaz"; /* Default font. Name must be < 34 chars */ Xint p_baud = 1200; /* baud rate */ Xint p_screen = 0; /* 0 = WORKBENCH, 1 = CUSTOM */ Xint p_wbcolors = 1; /* 0 = Custom, 1 = Workbench colors */ Xint p_interlace = 0; /* 0 = no interlace, 1 = interlace */ Xint p_depth = 2; /* number of bit planes (1 or 2) */ Xint p_foreground = 0x840; /* default foreground RGB color */ Xint p_background = 0x000; /* default background RGB color */ Xint p_bold = 0x000; /* default BOLD RGB color */ Xint p_cursor = 0x00d; /* default Cursor RGB color */ Xint p_lines = 24; /* 0 == use all available (MoreRows) */ Xint p_mode = 0; /* 0 = image, 1 = CRLF (for kermit) */ Xint p_unit = 0; /* unit of serial.device to open */ Xint p_xproto = 3; /* 0=ASCII, 1=Xmodem, 2=XmodemCRC, 3 = Kermit */ Xint p_buffer = 512; /* read buffer size (>= 512 bytes) */ Xint p_parity = 0; /* 0=none,1=mark,2=space,3=even,4=odd */ Xlong p_break = 750000; /* break time (in micro seconds) */ Xint p_volume = 64; /* beep volume (0 = DisplayBeep) */ Xint p_wrap = 1; /* 0 = truncate, 1 = wrap long lines */ Xint p_keyapp = 0; /* 0 = numeric, 1 = application keypad */ Xint p_curapp = 0; /* 0 = cursor, 1 = application cursor */ Xint p_echo = 0; /* 0 = full duplex, 1 = half duplex */ Xint p_bs_del = 0; /* 0 = normal, 1 = swap bs and delete */ Xint p_convert = 0; /* 1 = convert filenames to lower case */ Xint p_kmaxpack = 1000; /* Max packet size for Kermit xfers */ X/* Must be <= 1000. <= 94 is standard, > 94 requires a kermit capable X** of long packet support. */ Xint p_xbeep = 1; /* 1 = beep at end of xfer */ Xchar p_keyscript = 0x7E; /* function key script introducer = ~ */ Xchar *p_f[10] = { /* function key defaults */ X "\033OP","\033OQ","\033OR","\033OS", X "f5","f6","f7","f8","f9","f10" }; X Xchar *p_F[10] = { /* shifted function key defaults */ X "F1","F2","F3","F4","F5", X "F6","F7","F8","F9","F10"}; X X/* for script file */ Xint script_on; Xint script_wait; Xint doing_init = 0; X X/******************************************************/ X/* Main Program */ X/* */ X/* This is the main body of the program. */ X/******************************************************/ X Xchar lookahead[80]; XFILE *tranr = NULL; XFILE *trans = NULL; Xint capture,send; Xchar name[80]; Xstruct MsgPort *mySerPort; X Xmain(argc,argv) Xint argc; Xchar **argv; X { X ULONG class, waitmask; X unsigned int code, qual; X APTR iaddr; X int KeepGoing,i,la,dola,actual, len; X char c,*ptr; X char ascstr[100]; /* Area for string returned by toasc() */ X X ptr = InitDefaults(argc,argv); X InitDevs(); X InitFileItems(); X InitCommItems(); X InitScriptItems(); X InitUtilItems(); X InitMenu(); X SetMenuStrip(mywindow,&menu[0]); X PrintIText(mywindow->RPort,&MyTitle,0L,0L); X X MyDir[0] = '\000'; X StartLock = ((struct Process *) FindTask(NULL))->pr_CurrentDir; X CurrentDir(DupLock(StartLock)); X KeepGoing = TRUE; X capture = FALSE; X send = FALSE; X maxcol = MAXX / 8; X la = 0; X x = MINX ; X y = MINY; X curmode = FS_NORMAL; X script_on = FALSE; X script_wait= TRUE; X SetAPen(mywindow->RPort,1L); X cursorflip(); X cursorflip(); X emit(12); X mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort; X SendIO(Read_Request); X X /* see if we had a startup script */ X if (ptr != NULL) script_start(ptr); X X while( KeepGoing ) X { X /* wait for window message or serial port message */ X cursorflip(); X if(reqwinup) X waitmask = (1L << mySerPort->mp_SigBit) | X (1L << mywindow->UserPort->mp_SigBit) | X (1L << Script_Timer_Port->mp_SigBit) | X (1L << reqwindow->UserPort->mp_SigBit); X else X waitmask = (1L << mySerPort->mp_SigBit) | X (1L << mywindow->UserPort->mp_SigBit) | X (1L << Script_Timer_Port->mp_SigBit); X if (script_wait) /* if script ready dont wait here */ X Wait(waitmask); X cursorflip(); X X /* do ascii file send */ X if (send) X { X if ((c=getc(trans)) != EOF) { X if (c == '\n') c = '\r'; X sendchar(c); X } X else { X fclose(trans); X InfoMsg1Line("File Sent"); X send=FALSE; X } X } X X /* see if there are any characters from the host */ X if (CheckIO(Read_Request)) { X WaitIO(Read_Request); X c = rs_in[0] & 0x7F; X doremote(c); X if (script_on) chk_script(c); X if (capture && c != 10) { X if (c == 13) c = 10; X putc(c , tranr); X } X Read_Request->IOSer.io_Command = SDCMD_QUERY; X DoIO(Read_Request); X Read_Request->IOSer.io_Command = CMD_READ; X actual = (int)Read_Request->IOSer.io_Actual; X if (actual > 0) { X if (inesc < 0 && X inctrl < 0 && X a[alt] == 0 && X capture == FALSE) dola = 1; X else dola = 0; X Read_Request->IOSer.io_Length = X Read_Request->IOSer.io_Actual; X DoIO(Read_Request); X Read_Request->IOSer.io_Length = 1; X X for (i = 0; i < actual; i++) { X c=rs_in[i] & 0x7f; X if (script_on) chk_script(c); X X if (dola == 1) { X if (c >= ' ' && c <= '~' && la < 80) X lookahead[la++] = c; X else { X if (la > 0) { X emitbatch(la,lookahead); X la = 0; X } X doremote(c); X dola = 0; X } X } X else { X doremote(c); X if (inesc < 0 && X inctrl < 0 && X a[alt] == 0 && X capture == FALSE) dola = 1; X if (capture && c != 10) { X if (c == 13) c = 10; X putc(c , tranr); X } X } X } X X /* dump anything left in the lookahead buffer */ X if (la > 0) { X emitbatch(la,lookahead); X la = 0; X } X } X SendIO(Read_Request); X } X X while((NewMessage = X (struct IntuiMessage *)GetMsg(mywindow->UserPort)) X != FALSE) { X class = NewMessage->Class; X code = NewMessage->Code; X qual = NewMessage->Qualifier; X if(class == RAWKEY) X iaddr = *((APTR *)NewMessage->IAddress); X ReplyMsg( NewMessage ); X switch( class ) X { X case CLOSEWINDOW: X KeepGoing = FALSE; X break; X X case RAWKEY: X len = toasc(&(ascstr[0]), code,qual, 100, iaddr, 0); X if (p_echo) { X ptr = &(ascstr[0]); X for(i = 0; i < len; i++) X doremote(*(ptr++)); X } X break; X X case NEWSIZE: X emit(12); X break; X X case MENUPICK: X handle_menupick(class,code); X break; X X default: X PrintIText(mywindow->RPort,&MyTitle,0L,0L); X break; X } /* end of switch (class) */ X } /* end of while ( newmessage )*/ X X if (!script_wait || X (CheckIO(&Script_Timer) && X script_wait == WAIT_TIMER)) X do_script_cmd(NEXTCOMMAND); X X while( reqwinup && X ((NewMessage = (struct IntuiMessage *) X GetMsg(reqwindow->UserPort)) != FALSE) X ) { X class = NewMessage->Class; X ReplyMsg( NewMessage ); X switch( class ) { X case REQCLEAR: X numreqs = 0; X break; X X case CLOSEWINDOW: X KillReq(); /* Kills requester window, set reqwinup = 0 */ X break; X X case NEWSIZE: X ReqNewSize(reqwindow->Height, reqwindow->Width); X break; X } /* end of switch (class) */ X } /* end while */ X } /* end while ( keepgoing ) */ X X /* It must be time to quit, so we have to clean X * up and exit. X */ X X cleanup("",0); X X} /* end of main */ X X/* cleanup code */ X Xcleanup(reason, fault) Xchar *reason; Xint fault; X { X extern struct Device *ConsoleDevice; /* In init.c */ X extern struct IOStdReq ConReq; /* In init.c */ X X switch(fault) { X case 0: /* quitting close everything */ X KillReq(); /* Kill the requester and its window */ X ClearMenuStrip( mywindow ); X CloseDevice(&Audio_Request); X UnLock(CurrentDir(StartLock)); /* back to original directory */ X X case 8: /* error opening audio */ X DeletePort(Audio_Port); X FreeMem(BeepWave,BEEPSIZE); X CloseDevice(&Timer); X X case 7: /* error opening timer */ X DeletePort(Timer_Port); X CloseDevice(&Script_Timer); X DeletePort(Script_Timer_Port); X X case 6: /* error opening write device */ X DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort); X FreeMem(Write_Request,(long)sizeof(*Write_Request)); X CloseDevice(Read_Request); X X case 5: /* error opening read device */ X DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort); X FreeMem(Read_Request,(long)sizeof(*Read_Request)); X X case 4: /* error opening window */ X if (ConsoleDevice != NULL) CloseDevice(&ConReq); X if (myfont != NULL) CloseFont( myfont ); X if (mywindow != NULL) CloseWindow( mywindow ); X if (p_screen != 0) { X struct Process *mproc; X X mproc = (struct Process *)FindTask(0L); X mproc->pr_WindowPtr = OrigWindowPtr; X CloseScreen( myscreen ); X } X X case 3: /* error opening screen */ X case 2: /* error opening graphics library */ X CloseLibrary(GfxBase); X case 1: /* error opening intuition */ X CloseLibrary(IntuitionBase); X default: X if (*reason) puts (reason); X } X exit(fault); X } X Xdo_capture(file) Xchar *file; X { X if (capture == TRUE) X { X capture=FALSE; X fclose(tranr); X InfoMsg1Line("End File Capture"); X } X else X { X if (file == NULL || *file == '\0') { X name[0] = '\000'; X req("Ascii Capture:",name,1); X } X else strcpy(name, file); X if ((tranr=fopen(name,"w")) == 0) { X capture=FALSE; X InfoMsg2Line("Error Opening File:", name); X return(FALSE); X } X capture=TRUE; X } X redofile(); X } X Xdo_send(file) Xchar *file; X { X if (send == TRUE) X { X send=FALSE; X fclose(trans); X InfoMsg1Line("File Send Cancelled"); X } X else X { X if (file == NULL || *file == '\0') { X name[0] = '\000'; X req("Ascii Send:",name,1); X } X else strcpy(name, file); X if ((trans=fopen(name,"r")) == 0) { X send=FALSE; X InfoMsg2Line("Error Opening File:", name); X return(FALSE); X } X send=TRUE; X } X } X Xvoid setparams() X { X Read_Request->IOSer.io_Command = X Write_Request->IOSer.io_Command = X SDCMD_SETPARAMS; X DoIO(Read_Request); DoIO(Write_Request); X Read_Request->IOSer.io_Command = CMD_READ; X SendIO(Read_Request); X Write_Request->IOSer.io_Command = CMD_WRITE; X } X Xvoid hangup () X { X if(!CheckIO(Read_Request)) X AbortIO(Read_Request); X Wait (1L <<mySerPort->mp_SigBit); X WaitIO(Read_Request); X CloseDevice (Read_Request); X Timer.tr_time.tv_secs=0L; X Timer.tr_time.tv_micro=750000L; X DoIO((char *) &Timer.tr_node); X OpenDevice (SERIALNAME,(LONG)p_unit,Read_Request,NULL); X setparams(); X } X Xvoid redocomm() { X ClearMenuStrip( mywindow ); /* Remove old menu */ X InitCommItems(); /* Re-do comm menu */ X SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ X} Xvoid redofile() { X ClearMenuStrip( mywindow ); /* Remove old menu */ X InitFileItems(); /* Re-do file menu */ X SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ X} X Xvoid setserbaud(baud, redomenu) Xint baud; XLONG redomenu; X { X if(!CheckIO(Read_Request)) X AbortIO(Read_Request); X Wait (1L <<mySerPort->mp_SigBit); X WaitIO(Read_Request); X Write_Request->io_Baud = Read_Request->io_Baud = baud; X setparams(); X p_baud = baud; X if (redomenu) redocomm(); X } X Xvoid redoutil() { X ClearMenuStrip(mywindow); X InitUtilItems(); X SetMenuStrip(mywindow,&menu[0]); X } X Xvoid handle_menupick(class, code) XULONG class; Xunsigned int code; X { X unsigned int menunum, itemnum, subnum, i; X X if (code == MENUNULL) return; X X menunum = MENUNUM( code ); X itemnum = ITEMNUM( code ); X subnum = SUBNUM( code ); X switch( menunum ) { X case 0: X switch( itemnum ) { X case 0: /* menunum case 0 itemnum case 0 -- Set xfer mode */ X switch( subnum ) { X case 0: /* Ascii */ X case 1: /* Xmodem */ X case 2: /* XmodemCRC */ X case 3: /* Kermit */ X i = subnum; X break; X default: X i = MODEMAX-1; X } X p_xproto = i; X redofile(); X break; X X case 1: /* menunum case 0 itemnum case 1 -- Send a file */ X name[0] = '\0'; X cmd_sendf(name); X break; X X case 2: /* menunum case 0 itemnum case 2 -- Receive a file */ X name[0] = '\000'; X cmd_recf(name); X break; X X case 3: /* menunum case 0 itemnum case 3 -- Kermit GET */ X name[0] = '\000'; X cmd_kg(name); X break; X X case 4: /* menunum case 0 itemnum case 4 -- Kermit BYE */ X saybye(); X break; X case 5: /* menunum case 0 itemnum case 5 -- ASCII capture */ X name[0] = '\0'; X do_capture(name); X break; X } /* End of itemnum switch for menunum case 0 */ X break; X X case 1: /* menunum case 1 - Comm Setup */ X switch( itemnum ) { X case 0: /* Baud */ X switch( subnum ) { X case 0: X setserbaud(300, FALSE); X break; X X case 1: X setserbaud(1200, FALSE); X break; X X case 2: X setserbaud(2400, FALSE); X break; X X case 3: X setserbaud(4800, FALSE); X break; X X case 4: X setserbaud(9600, FALSE); X break; X } /* End of subnum switch for itemnum 0 of menunum 1 */ X break; X X case 1: /* menunum case 1 itemnum 1 -- Set Parity */ X p_parity = subnum; X break; X X case 2: /* menunum case 2 itemnum 2 -- set kermit transfer mode */ X if (subnum < 2) p_mode = subnum; X else { X if (p_convert) p_convert = 0; X else p_convert = 1; X redocomm(); X } X break; X } X break; /* End of menunum case 1 */ X X case 2: /* menunum case 2 - Script */ X if (!itemnum && !script_on) { X name[0] = '\000'; X req("Script file name:",name,1); X script_start(name); X } X if (itemnum && script_on) exit_script(); X break; X X case 3: /* menunum case 3 -- Utility */ X switch( itemnum ) { X case 0: X sendbreak(); X break; X X case 1: /* menunum case 3 itemnum case 1 -- Hang Up */ X hangup(); X break; X X case 2: /* menunum case 3 itemnum case 2 -- Cd */ X strcpy(name,MyDir); X req("Directory:",name,1); X set_dir(name); X break; X X case 3: /* menunum case 3 itemnum case 3 -- Clear Screen */ X top = MINY; bot = MAXY; savx = MINX; savy = MINY; X curmode = FS_NORMAL; inesc = -1; X a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0; X redoutil(); X emit(12); X break; X X case 4: /* menunum case 3 itemnum case 4 -- Echo mode */ X if (p_echo) p_echo = 0; X else p_echo = 1; X redoutil(); X break; X X case 5: /* menunum case 3 itemnum case 5 -- Wrap mode */ X if (p_wrap) p_wrap = 0; X else p_wrap = 1; X redoutil(); X break; X X case 6: /* menunum case 3 itemnum case 6 -- NumKey */ X if (p_keyapp) p_keyapp = 0; X else p_keyapp = 1; X redoutil(); X break; X X case 7: /* menunum case 3 itemnum case 7 -- App Cur */ X if (p_curapp) p_curapp = 0; X else p_curapp = 1; X redoutil(); X break; X X case 8: /* menunum case 3 itemnum case 8 -- BS <-> DEL */ X swap_bs_del(); X redoutil(); X break; X X case 9: /* menunum case 3 itemnum case 9 -- Xfer Beep */ X if(p_xbeep) p_xbeep = 0; X else p_xbeep = 1; X redoutil(); X break; X } X X break; X } /* end of switch ( menunum ) */ X} ________This_Is_The_END________ if test `wc -l < vt100.c` -ne 805; then echo 'shar: vt100.c was damaged during transit (should have been 805 bytes)' fi fi ; : end of overwriting check exit 0
ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)
Program Name: vt100 (version 2.8) Submitted By: acs@uts.amdahl.com (Tony Sumrall) Summary: vt100 terminal emulator. Poster Boy: Brent Woods (ahh@j.cc.purdue.edu) Tested. Part 4 of 4. NOTES: This program was tested by our Guest Moderator, Robert Tillotson. He had a couple of problems with the program at first (a couple of Guru errors, and we think that the vt100 task hung around instead of exiting properly; not certain, though), but when we (Rob, Pat, and I) tested it a few hours ago, none of us had any problems. I dunno. It seems to work okay now. Probably some fluke or other. Boy, I bet people are getting pretty tired of the notes about now... Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga USENET: ...!j.cc.purdue.edu!ahh ARPANET: ahh@j.cc.purdue.edu BITNET: PODUM@PURCCVM PHONE: +1 (317) 743-8421 USNAIL: 320 Brown St., #406 / West Lafayette, IN 47906 ====================================cut here============================ #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 acs other 8096 Feb 1 18:56 vt100.h # -rw-r--r-- 1 acs other 17303 Feb 1 18:56 window.c # -rw-r--r-- 1 acs other 15067 Feb 1 18:56 xmodem.c # echo 'x - vt100.h' if test -f vt100.h; then echo 'shar: not overwriting vt100.h'; else sed 's/^X//' << '________This_Is_The_END________' > vt100.h X/********************************************************************* X * a terminal program that has ascii and xmodem transfer capability X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - See README. 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 860809 DBW - Major release.. LOTS of changes X * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes X * v1.0 860712 DBW - First version released X * X * use esc to abort xmodem transfer X * X * written by Michael Mounier X * new version by Dave Wecker 860621 X ********************************************************************/ X X/********* major version (used for title of terminal window) *********/ X#define VERSION "VT100 (V2.8 ACS 880117) Terminal Window" X X/*********** ######## define the compiler type here ######## ********/ X#define LATTICE 0 X#define MANX 1 X X/* compiler directives to fetch the necessary header files */ X#include <exec/types.h> X#include <exec/exec.h> X#include <intuition/intuition.h> X#include <intuition/intuitionbase.h> X#include <graphics/gfxbase.h> X#include <graphics/gfx.h> X#include <graphics/text.h> X#include <graphics/regions.h> X#include <graphics/copper.h> X#include <graphics/gels.h> X#include <devices/serial.h> X#include <devices/keymap.h> X#include <devices/inputevent.h> X#include <devices/audio.h> X#include <hardware/blit.h> X X /* for Lattice you may have to change these with: */ X#include <stdio.h> /* #include <lattice/stdio.h> and */ X#include <ctype.h> /* #include <lattice/ctype.h> */ X X#include <libraries/dos.h> X#include <libraries/dosextens.h> X#include <devices/timer.h> X X#if MANX X#include <functions.h> X#undef NULL X#define NULL ((void *)0) X#endif X X#define INTUITION_REV 1L X#define GRAPHICS_REV 1L X X/* things for xmodem send and recieve */ X#define GOODREAD 0 X#define TIMEOUT 1 X#define USERABORT 2 X#define SECSIZ 0x80 X#define TTIME_SHORT 5 /* number of seconds for short timeout */ X#define TTIME_LONG 50 /* number of seconds for long timeout */ X#define TTIME_KERMIT 10 /* number of seconds for KERMIT timeout*/ X#define MAXLONGPKS 1000 /* Maximum long msgpkt size */ X#define BufSize 0x200 /* Text buffer for XMODEM */ X#define ERRORMAX 10 /* Max errors before abort */ X#define RETRYMAX 10 /* Maximum retrys before abort */ X#define SOH 1 /* Start of sector char */ X#define EOT 4 /* end of transmission char */ X#define ACK 6 /* acknowledge sector transmission */ X#define NAK 21 /* error in transmission detected */ X X#define FILEMAX 6 /* number of file menu items */ X#define MODEMAX 4 /* number of mode menu items */ X#define COMMAX 3 /* number of communication sub menus */ X#define RSMAX 5 /* speed menu items */ X#define PARMAX 5 /* parity items */ X#define XFMAX 3 /* transfer mode items */ X#define SCRIPTMAX 2 /* script menu items */ X#define UTILMAX 10 /* utility menu */ X#define MAXMENU 4 /* total number of menu entries */ X X#define MAXGADSTR 80 /* Max size of prompts and inputs */ X X#define FSF_REVERSE 256 /* fake font style to flag INVERSVID mode */ X X/* things for script support */ X X#define GOTOLABEL 1 X#define NEXTCOMMAND 0 X#define ONCOMMAND 2 X X#define WAIT_TIMER 2 X#define WAIT_STRING 1 X X/* things for 'beep' support */ X#define BEEPSIZE 10L X#define BEEPFREQ 1000L X#define COLORCLOCK 3579545L X Xextern struct MsgPort *CreatePort(); Xextern char *malloc(),*strcpy(),*fgets(); Xextern long ftell(); X Xextern int multi; /* flags multi file transfers */ Xextern int server; Xextern char bufr[BufSize]; Xextern int fd, timeout, ttime; Xextern long bytes_xferred; Xextern char MyDir[60]; Xextern BPTR StartLock; Xextern struct IntuitionBase *IntuitionBase; Xextern struct GfxBase *GfxBase; Xextern struct TextAttr myattr; Xextern struct TextFont *myfont; Xextern struct NewScreen NewScreen; Xextern struct NewWindow NewWindow; Xextern struct NewWindow NewReqWindow; Xextern struct Screen *myscreen; Xextern struct Window *mywindow; Xextern struct Window *reqwindow; Xextern struct ViewPort *myviewport; Xextern struct RastPort *myrastport; Xextern struct IntuiMessage *NewMessage; Xextern struct Preferences *Prefs; Xextern char InpBuf[80],UndoBuf[80],Prompt[80]; Xextern struct StringInfo mystrinfo; Xextern struct Gadget mystrgad; Xextern struct IntuiText donetxt; Xextern struct Gadget mydonegad; Xextern struct IntuiText mystrtxt; Xextern struct Requester myrequest; Xextern int numreqs; Xextern int reqwinup; Xextern struct MenuItem FileItem[FILEMAX]; Xextern struct IntuiText FileText[FILEMAX]; Xextern struct MenuItem ModeItem[MODEMAX]; Xextern struct IntuiText ModeText[MODEMAX]; Xextern struct MenuItem CommItem[COMMAX]; Xextern struct IntuiText CommText[COMMAX]; Xextern struct MenuItem RSItem[RSMAX]; Xextern struct IntuiText RSText[RSMAX]; Xextern struct MenuItem ParItem[PARMAX]; Xextern struct IntuiText ParText[PARMAX]; Xextern struct MenuItem XFItem[XFMAX]; Xextern struct IntuiText XFText[XFMAX]; Xextern struct MenuItem ScriptItem[SCRIPTMAX]; Xextern struct IntuiText ScriptText[SCRIPTMAX]; Xextern struct MenuItem UtilItem[UTILMAX]; Xextern struct IntuiText UtilText[UTILMAX]; Xextern struct Menu menu[MAXMENU]; Xextern struct timerequest Timer, Script_Timer; Xextern struct MsgPort *Timer_Port, *Script_Timer_Port; Xextern struct IOExtSer *Read_Request; Xextern char *rs_in; Xextern struct IOExtSer *Write_Request; Xextern char rs_out[2]; Xextern int x,y,curmode; Xextern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy; Xextern int savmode,nlmode,alt,savalt,a[2],sa[2]; Xextern int inesc,inctrl,private,badseq,maxcol; Xextern struct IOAudio Audio_Request; Xextern struct MsgPort *Audio_Port; Xextern UBYTE *BeepWave; Xextern UBYTE Audio_AllocMap[4]; Xextern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors; Xextern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode; Xextern int p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del; Xextern int p_xbeep, p_xproto, p_convert, p_kmaxpack, p_unit; Xextern char p_keyscript; Xextern long p_break; Xextern char *p_font, *p_f[10],*p_F[10]; Xextern int script_on; Xextern int script_wait; Xextern int doing_init; X X/* vt100.c */ Xextern int do_send(),do_capture(),cleanup(); Xextern void setserpar(), setserbaud(), setparams(), redoutil(), redofile(), X redocomm(), handle_menupick(); X X/* init.c */ Xextern void InitDevs(),InitFileItems(),InitCommItems(), X InitScriptItems(),InitUtilItems(),InitMenu(); Xextern char *InitDefaults(); X X/* window.c */ Xextern void swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip(); Xextern int toasc(); Xextern void ScrollInfoMsg(), InfoMsgNoScroll(), InfoMsg1Line(), X InfoMsg2Line(); X X/* xmodem.c */ Xextern void sendchar(),sendstring(),sendbreak(),multi_xfer(), X No_XON(),Do_XON(); Xextern int readchar(),XMODEM_Read_File(),XMODEM_Send_File(); X X/* remote.c */ Xextern void doremote(),doindex(),doctrl(),doesc(),doerase(); X X/* kermit.c */ Xextern int doksend(), dokreceive(), saybye(); Xextern void encode(), decode(), rpar(), spar(); X X/* script.c */ Xextern int script_start(), chk_script(), exit_script(), X do_script_cmd(); Xextern char *next_wrd(), *tostring(); X X /* init commands */ Xextern void cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(), X cmd_fore(), cmd_font(), cmd_inter(), cmd_lines(), X cmd_screen(), cmd_unit(), cmd_volume(), cmd_wb(), cmd_null(), X X /* script commands */ X cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(), X cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(), X cmd_ks(), cmd_on(), cmd_recf(), cmd_sb(), cmd_send(), X cmd_sendf(), cmd_wait(), cmd_xr(), cmd_xs(), X X /* init and script commands */ X cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(), cmd_echo(), X cmd_exit(), cmd_fnc(), cmd_key(), cmd_kmode(), cmd_kmaxpk(), X cmd_mode(), cmd_numkey(), cmd_parity(), cmd_swap(), X cmd_wrap(), cmd_xbeep(), cmd_xproto(); X X/* expand.c */ Xextern char **expand(); Xextern int set_dir(), free_expand(); X ________This_Is_The_END________ if test `wc -l < vt100.h` -ne 238; then echo 'shar: vt100.h was damaged during transit (should have been 238 bytes)' fi fi ; : end of overwriting check echo 'x - window.c' if test -f window.c; then echo 'shar: not overwriting window.c'; else sed 's/^X//' << '________This_Is_The_END________' > window.c X/**************************************************** X * vt100 emulator - window/keyboard support X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - Provide an info/status window rather than using X * req(). Better error handling. 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 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 Xstatic char *infkey[] = { /* F-keys resulting from RawKeyConvert() */ X "0~", "1~", "2~", "3~", "4~", "5~", "6~", "7~", "8~", "9~", X "10~", "11~", "12~", "13~", "14~", "15~", "16~", "17~", "18~", "19~", X NULL}; X X/* Cursor keys resulting from RawKeyConvert() and their output values */ Xstatic struct { X char *in; /* in sequence */ X char *out_curapp; /* out sequence in p_curapp */ X char *out; /* out sequence !in p_curapp */ X} ckeys[] = { X "A", "OA", "[A", X "T", "OA", "[A", X "B", "OB", "[B", X "S", "OB", "[B", X "C", "OC", "[C", X " A~", "OC", "[C", X "D", "OD", "[D", X " @~", "OD", "[D", X NULL, NULL, NULL }; X X/* Numeric keypad return values excluding HELP, '-' and ENTER */ Xstatic char keypad[] = "pqrstuvwxy"; X/* Numeric keypad return values for HELP, - and ENTER */ Xstatic char speckeypad[] = "-l-.n.\015M\015\0\0\0"; X X/* For InfoMsg...may be changed by a NEWSIZE msg in vt100.c */ Xint reqminx, /* Min value for x in reqwindow (pixels) */ X reqmaxx, /* Max value for x in reqwindow (pixels) */ X reqmaxlen, /* Max # chars in reqwindow */ X reqminy, /* Min value for y in reqwindow (scan lines) */ X reqmaxy, /* Max value for y in reqwindow (scan lines) */ X reqfudge; /* Clear space between border and start of 1st char */ Xint reqy; /* Current pixel location in reqwindow */ X Xvoid ReqNewSize(), OpenReqWindow(); X X/*************************************************** X * function to swap the use of backspace and delete X ***************************************************/ X Xvoid swap_bs_del() X{ X if (p_bs_del) p_bs_del = 0; X else p_bs_del = 1; X} X X/************************************************* X * function to get file name (via a requestor) X *************************************************/ Xvoid req(prmpt,name,getinp) Xchar *prmpt,*name; Xint getinp; X { X ULONG class; X USHORT position, RemoveGadget(); X unsigned int code, qual; X int lprmpt, lname; X struct IntuiMessage *Msg; X X if(reqwinup == 0) X OpenReqWindow(); X X if(!getinp) { X InfoMsg2Line(prmpt, name); X return; X } X X lprmpt = strlen(prmpt); X lname = strlen(name); X X /* Don't use strings longer than what we've provided space for. */ X if(lprmpt > (MAXGADSTR-1)) { X emits("Prompt too long - truncated.\n"); X lprmpt = MAXGADSTR-1; X } X if(lname > (MAXGADSTR-1)) { X emits("Name too long - truncated.\n"); X lname = MAXGADSTR-1; X } X X if (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X if(class == REQCLEAR) X numreqs = 0; X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } X X /* Make sure the prompt gets updated */ X if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) { X EndRequest(&myrequest,reqwindow); X do { X Wait(1L << reqwindow->UserPort->mp_SigBit); X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } X } while (class != REQCLEAR); X numreqs = 0; X } X X /* copy in a prompt and a default */ X strncpy(Prompt,prmpt,lprmpt); Prompt[lprmpt] = '\0'; X strncpy(InpBuf,name,lname); InpBuf[lname] = '\0'; X mystrinfo.BufferPos = lname; X X if (numreqs == 1) { /* If there is a requester... reuse it */ X RefreshGadgets(&mystrgad, reqwindow, &myrequest); X Delay(2L); X } X else { /* otherwise create it */ X while(numreqs != 1) { X if (Request(&myrequest, reqwindow) == 0) { X emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n"); X emits(Prompt); emit('\n'); emits(InpBuf); emit('\n'); X return; X } X else numreqs = 1; X X do { X Wait(1L << reqwindow->UserPort->mp_SigBit); X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X if(class == REQCLEAR) X numreqs = 0; X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } X } while (class != REQSET); X } /* end while numreqs != 0 */ X } /* end else */ X X /* if we don't want input, we're done */ X if (getinp == 0 || numreqs == 0) return; X X if((reqwindow->Flags & WINDOWACTIVE) != WINDOWACTIVE) { X WindowToFront(reqwindow); X ActivateWindow(reqwindow); X do { X Wait(1L << reqwindow->UserPort->mp_SigBit); X while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } X } while (class != ACTIVEWINDOW); X } X X /* here is where we pre-select the gadget */ X if (!ActivateGadget(&mystrgad,reqwindow,&myrequest)) { X X /* wait for his/her hands to get off the keyboard (Amiga-key) */ X Delay(20L); X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X ReplyMsg(Msg); X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } X X /* try once more before giving up... */ X ActivateGadget(&mystrgad,reqwindow,&myrequest); X } X X /* wait for input to show up */ X while (1) { X if ((NewMessage = (struct IntuiMessage *) X GetMsg(reqwindow->UserPort)) == FALSE) { X Wait(1L<<reqwindow->UserPort->mp_SigBit); X continue; X } X class = NewMessage->Class; X ReplyMsg(NewMessage); X X /* the requestor got terminated... yea!! */ X if (class == REQCLEAR) break; X X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X X /* maybe this is a menu item to handle */ X/* if (class == MENUPICK) handle_menupick(class,code); */ X } X X /* all done, so return the result */ X numreqs = 0; X strcpy(name,InpBuf); X if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE)) X ActivateWindow(mywindow); X } X X/************************************************* X* function to print a string X*************************************************/ Xvoid emits(string) Xchar string[]; X { X int i; X char c; X X i=0; X while (string[i] != 0) X { X c=string[i]; X if (c == 10) emit(13); X emit(c); X i += 1; X } X } X X/************************************************* X* function to output ascii chars to window X*************************************************/ Xvoid emit(c) Xchar c; X { X static char wrap_flag = 0; /* are we at column 80? */ X X c &= 0x7F; X switch( c ) X { X case '\t': X x += 64 - ((x-MINX) % 64); X break; X X case 10: /* lf */ X doindex('D'); X break; X X case 13: /* cr */ X x = MINX; X break; X X case 8: /* backspace */ X x -= 8; X if (x < MINX) x = MINX; X break; X X case 12: /* page */ X x = MINX; X y = MINY; X SetAPen(mywindow->RPort,0L); X RectFill(mywindow->RPort,(long)MINX, X (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1)); X SetAPen(mywindow->RPort,1L); X break; X X case 7: /* bell */ X cmd_beep(0L); X break; X X default: X if (c < ' ' || c > '~') break; X if (p_wrap && wrap_flag && x >= MAXX) { X x = MINX; X doindex('D'); X if (y > MAXY) { X y = MAXY; X ScrollRaster(mywindow->RPort,0L,8L,(long)MINX, X (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1)); X } X } X Move(mywindow->RPort,(long)x,(long)y); X X if (curmode&FSF_BOLD) { X if (p_depth > 1) { X SetAPen(mywindow->RPort,(long)(2+(1^p_screen))); X SetSoftStyle(mywindow->RPort,(long)curmode,253L); X } X else SetSoftStyle(mywindow->RPort,(long)curmode,255L); X } X else SetSoftStyle(mywindow->RPort,(long)curmode,255L); X X if (curmode&FSF_REVERSE) { X SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID)); X Text(mywindow->RPort,&c,1L); X SetDrMd(mywindow->RPort,(long)JAM2); X } X else Text(mywindow->RPort,&c,1L); X X if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L); X x += 8; X } /* end of switch */ X X if (y > MAXY) { X y = MAXY; X x = MINX; X ScrollRaster(mywindow->RPort,0L,8L,(long)MINX, X (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1)); X } X if (x > MAXX) { X wrap_flag = 1; X x = MAXX; X } X else wrap_flag = 0; X } X X/************************************************* X* function to output ascii chars to window (batched) X*************************************************/ Xvoid emitbatch(la,lookahead) Xint la; Xchar *lookahead; X { X int i; X X Move(mywindow->RPort,(long)x,(long)y); X i = x / 8; X if (i+la >= maxcol) { X if (p_wrap == 0) la = maxcol - i; X else { X lookahead[la] = 0; X emits(lookahead); X return; X } X } X if (curmode&FSF_BOLD) { X if (p_depth > 1) { X SetAPen(mywindow->RPort,(long)(2+(1^p_screen))); X SetSoftStyle(mywindow->RPort,(long)curmode,253L); X } X else SetSoftStyle(mywindow->RPort,(long)curmode,255L); X } X else SetSoftStyle(mywindow->RPort,(long)curmode,255L); X X if (curmode&FSF_REVERSE) { X SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID)); X Text(mywindow->RPort,lookahead,(long)la); X SetDrMd(mywindow->RPort,(long)JAM2); X } X else Text(mywindow->RPort,lookahead,(long)la); X if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L); X x += (8 * la); X } X X/****************************** X* Manipulate cursor X******************************/ Xvoid cursorflip() X { X SetDrMd(mywindow->RPort,(long)COMPLEMENT); X SetAPen(mywindow->RPort,3L); X RectFill(mywindow->RPort, X (long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1)); X SetAPen(mywindow->RPort,1L); X SetDrMd(mywindow->RPort,(long)JAM2); X } X X/************************************************ X* function to take raw key data and convert it X* into ascii chars X**************************************************/ Xint toasc(retstr, code, qual, maxlen, ia, local) Xunsigned char *retstr; Xunsigned int code,qual; Xint local, maxlen; XAPTR ia; X{ X unsigned int ctrl, alt, npad; X int i, X cmatch, X length = 0; /* length of returned string */ X unsigned char *p = retstr; X static struct InputEvent ievent = {NULL, IECLASS_RAWKEY,0,0,0}; X X *p = '\0'; X X ctrl = qual & IEQUALIFIER_CONTROL; X alt = qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT); X npad = qual & IEQUALIFIER_NUMERICPAD; X X ievent.ie_Qualifier = qual; X X ievent.ie_Code = code; X /* get previous codes from location pointed to by IAddress X * this "magic" pointer is valid intil the IntiiMessage is X * replied X */ X ievent.ie_position.ie_addr = ia; X length = RawKeyConvert(&ievent, retstr, (LONG)maxlen, NULL); X if(length == 0) X return length; X X *(p+length) = '\0'; /* Null terminate the value */ X X if(npad && length == 1 && p_keyapp) { /* keypad (excluding HELP key)? */ X register char t = *p; X if((t >= '0') && (t <= '9')) { X if(p_keyapp) { X strcpy(p, "\033O"); X *(p+2) = keypad[t-'0']; X *(p+3) = '\0'; X length = 3; X } /* else *p is correct */ X } X else for(i = 0; speckeypad[i]; i += 3) X if(speckeypad[i] == t) { X if(p_keyapp) { X strcpy(p, "\033O"); X *(p+2) = speckeypad[i+1]; X length = 3; X } X else *p = speckeypad[i+2]; X break; X } X } else if((length == 3) && (strcmp(p, "\233?~") == 0)) { X /* HELP key -- only gen something if in app keypad mode */ X if(p_keyapp) { X strcpy(p, "\033Om"); X length = 3; X } else { X *p = '\0'; X length = 0; X } X } else if(length > 1 && retstr[0] == 0x9b) { /* cursor or F-keys? */ X cmatch = 0; X for(i = 0; ckeys[i].in && !cmatch; i++) { X if(p_curapp X && strcmp((p+1), ckeys[i].in) == 0) { X strcpy((p+1), ckeys[i].out_curapp); X *p = 0x1b; X length = strlen(ckeys[i].out_curapp)+1; X cmatch = 1; X } else if(strcmp((p+1), ckeys[i].in) == 0) { X strcpy((p+1), ckeys[i].out); X *p = 0x1b; X length = strlen(ckeys[i].out)+1; X cmatch = 1; X } X } X if(!cmatch) { /* Not cursor, try F-keys */ X for(i = 0; infkey[i]; i++) { X if(strcmp((p+1), infkey[i]) == 0) { X if(i > 9) X strcpy(p, p_F[i-10]); X else strcpy(p, p_f[i]); X if(!script_on && *p == p_keyscript) { X script_start(p+1); X *p = '\0'; X length = 0; X } X length = strlen(p); X break; X } X } X } X } else if(ctrl && (length == 1)) { X /* Control key shortcuts? */ X switch(*p) { X case '6': X *p = 30; X break; X case '2': X case ' ': /* @ done by RawKeyConvert? */ X if(!local) X *p = (alt ? 128 : 0); X break; X case '-': X case '?': X *p = 31; X break; X } X } else if(alt && !local && length == 1) X *p |= 0x80; /* Add hi bit if ALT is the only modifier */ X else if(p_bs_del && *p == 8 && length == 1) X *p = 0x7f; X else if(p_bs_del && *p == 0x7f && length == 1) X *p = 8; X X/* if (ctrl) { Are all of these taken care of? X if (c > '`' && c <= 127) c -= 96; X else if (c > '@' && c <= '_') c -= 64; X else if (c == '6') c = 30; X else if (c == '-' || c == '?') c = 31; X } */ X for(i = 0; i < length; i++) X sendchar(*(p++)); X return(length); X} X Xvoid XKillReq() X{ X struct IntuiMessage *Msg; X ULONG class; X X if(numreqs != 0) { X EndRequest(&myrequest,reqwindow); X do { X Wait(1L << reqwindow->UserPort->mp_SigBit); X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X } X } while (class != REQCLEAR); X numreqs = 0; X } X X if(reqwinup) { X /* First, clear out all pending messages */ X while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X } X NewReqWindow.LeftEdge = reqwindow->LeftEdge; /* Remember ... */ X NewReqWindow.TopEdge = reqwindow->TopEdge; /* ...where... */ X NewReqWindow.Width = reqwindow->Width; /* ...the user... */ X NewReqWindow.Height = reqwindow->Height; /* ...put it. */ X CloseWindow(reqwindow); /* Now we can close the window */ X reqwinup = 0; X } X} X Xvoid XInfoMsg2Line(header, msg) Xchar *header, *msg; X{ X ScrollInfoMsg(1); X InfoMsgNoScroll(header); X ScrollInfoMsg(1); X InfoMsgNoScroll(msg); X ScrollInfoMsg(1); X} X Xvoid XInfoMsg1Line(msg) Xchar *msg; X{ X ScrollInfoMsg(1); X InfoMsgNoScroll(msg); X ScrollInfoMsg(1); X} X X/* Output the specified data to the "info" window */ Xvoid XScrollInfoMsg(lines) Xint lines; X{ X/* ULONG class; X struct IntuiMessage *Msg; */ X int pixels = lines << 3; X X if(!reqwinup) X OpenReqWindow(); X X/* if(Msg=(struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } */ X X if ( (reqy += pixels) > reqmaxy) { X reqy = reqmaxy; X if(pixels > 0) X ScrollRaster(reqwindow->RPort, 0L, (LONG)pixels, X (LONG)reqminx, X (LONG)reqminy, X (LONG)(reqmaxx+7), X (LONG)(reqmaxy+7)); X/* Was: (LONG)(wp->Width - wp->BorderRight), X (LONG)(wp->Height - wp->BorderBottom)); */ X } X} X Xvoid XInfoMsgNoScroll(msg) Xchar *msg; X{ X LONG msglen = strlen(msg); X X if(msglen > reqmaxlen) X msglen = reqmaxlen; X X ScrollInfoMsg(0); /* Ensure that the msg willbe visible */ X X /* Position the pen at the baseline of the character (7 scan lines X ** into it). */ X Move(reqwindow->RPort, (LONG)reqminx, (LONG)(reqy+6)); X Text(reqwindow->RPort, msg, msglen); X} X Xvoid XReqNewSize(height, width) XSHORT height, width; X{ X register struct Window *wp = reqwindow; X int oldmaxy; X X /* Compute min and max for x and y coordinates. Note that for y the X ** value is for the *top* of the character, not the baseline. Text() X ** uses a baseline value and so it must be adjusted prior to the call X ** (characters are assumed to occupy an 8x8 matrix with the baseline at X ** 7). When computing the max values, calculate them so that we will X ** sufficient room for an entire character. */ X oldmaxy = reqmaxy; X reqminy = wp->BorderTop + reqfudge; X reqmaxy = (((height - reqminy - wp->BorderBottom) >> 3) << 3) X + (reqminy-8); X reqminx = wp->BorderLeft + reqfudge; X reqmaxx = (((width - reqminx - wp->BorderRight) >> 3) << 3) X + (reqminx-8); X reqmaxlen = (reqmaxx+7) / 8; X if(oldmaxy > reqmaxy) { /* Clean up the bottom of the window */ X int temp = height - wp->BorderBottom - reqmaxy; X X ScrollRaster(wp->RPort, 0L, (LONG)temp, X (LONG)reqminx, X (LONG)reqmaxy, X (LONG)(width - wp->BorderRight), X (LONG)(height - wp->BorderBottom)); X } X} X Xvoid XOpenReqWindow() X{ X struct IntuiMessage *Msg; X ULONG class; X void ReqNewSize(); X X reqwindow = OpenWindow(&NewReqWindow); X do { X Wait(1L << reqwindow->UserPort->mp_SigBit); X while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) { X class = Msg->Class; X ReplyMsg(Msg); X } X } while (class != ACTIVEWINDOW); X reqfudge = 0; /* Leave 0 pixels/scan lines between border and char */ X ReqNewSize(reqwindow->Height, reqwindow->Width); X reqy = reqminy; /* Top of character set by ReqNewSize() */ X reqwinup = 1; X if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE)) X ActivateWindow(mywindow); X} ________This_Is_The_END________ if test `wc -l < window.c` -ne 662; then echo 'shar: window.c was damaged during transit (should have been 662 bytes)' fi fi ; : end of overwriting check echo 'x - xmodem.c' if test -f xmodem.c; then echo 'shar: not overwriting xmodem.c'; else sed 's/^X//' << '________This_Is_The_END________' > xmodem.c X/************************************************************* X * vt100 terminal emulator - XMODEM protocol support X * X * v2.8 880117 ACS - See the README file X * v2.7 870825 ACS - Make multi_xfer() non-recursive; on non-ESC in X * readchar() re-do the main window's title. 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 Parity and Word Length and support code X * 860823 DBW - Integrated and rewrote lots of code X * 860815 Steve Drew: readchar inproved with real timeouts 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 Xint enablexon = TRUE; X Xextern struct IntuiText MyTitle; X Xstatic unsigned long parity_settings[4] = { X 0x96696996, X 0x69969669, X 0x69969669, X 0x96696996 }; X X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */ Xstatic unsigned short crctab[256] = { X 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, X 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, X 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, X 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, X 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, X 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, X 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, X 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, X 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, X 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, X 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, X 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, X 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, X 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, X 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, X 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, X 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, X 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, X 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, X 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, X 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, X 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, X 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, X 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, X 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, X 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, X 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, X 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, X 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, X 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, X 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, X 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 X}; X X/* X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. X * NOTE: First srgument must be in range 0 to 255. X * Second argument is referenced twice. X * X * Programmers may incorporate any or all code into their programs, X * giving proper credit within the source. Publication of the X * source routines is permitted so long as proper credit is given X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, X * Omen Technology. X */ X X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp) X X/************************************************************ X* Send a string (using sendchar below) X************************************************************/ X Xvoid sendstring(s) Xchar *s; X { X char c; X X while ((c = *s++) != '\000') sendchar(c); X } X X/**************************************************************/ X/* send char and read char functions for the xmodem function */ X/************************************************************/ Xvoid sendchar(ch) Xint ch; X { X int doxon,i,j,k; X X doxon = enablexon; X if (doxon) No_XON(); X switch (p_parity) { X case 0: /* no parity */ X rs_out[0] = ch & 0xFF; X break; X X case 1: /* mark */ X rs_out[0] = (ch & 0x7F) | 0x80; X break; X X case 2: /* space */ X rs_out[0] = ch & 0x7F; X break; X X case 3: /* even */ X case 4: /* odd */ X i = (ch >> 5) & 0x3; X j = ch & 0x1F; X k = ((parity_settings[i] >> j) & 0x1) << 7; X if (p_parity == 3) /* even parity */ X rs_out[0] = (ch & 0x7F) | k; X else /* odd parity */ X rs_out[0] = (ch & 0x7F) | (k ^ 0x80); X } X do { X DoIO(Write_Request); X } while(Write_Request->IOSer.io_Error != 0); X if (doxon) Do_XON(); X } X X/* send a break to the host */ Xvoid sendbreak() { X AbortIO(Read_Request); X Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit); X WaitIO(Read_Request); X Read_Request->IOSer.io_Command = SDCMD_BREAK; X DoIO(Read_Request); X Read_Request->IOSer.io_Command = CMD_READ; X SendIO(Read_Request); X } X Xint readchar() X { X int rd,ch; X ULONG class, waitmask; X USHORT code; X X Timer.tr_time.tv_secs = ttime; X Timer.tr_time.tv_micro = 0; X SendIO((char *) &Timer.tr_node); X X rd = FALSE; X waitmask = ((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | X ( 1L << mywindow->UserPort->mp_SigBit) | X ( 1L << Timer_Port->mp_SigBit)); X if(reqwinup) X waitmask |= (1L << reqwindow->UserPort->mp_SigBit); X while (rd == FALSE) { X Wait(waitmask); X if (CheckIO(Read_Request)) { X WaitIO(Read_Request); X ch=rs_in[0]; X rd = TRUE; X SendIO(Read_Request); X } X if(reqwinup && X (NewMessage=(struct IntuiMessage *)GetMsg(reqwindow->UserPort))) { X class = NewMessage->Class; X ReplyMsg(NewMessage); X if(class == NEWSIZE) X ReqNewSize(reqwindow->Height, reqwindow->Width); X } X if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) { X class = NewMessage->Class; X code = NewMessage->Code; X ReplyMsg(NewMessage); X if ((class == RAWKEY) && (code == 69)) { X if(!CheckIO(&Timer)) X AbortIO((char *) &Timer); X Wait (1L << Timer_Port->mp_SigBit); X WaitIO((char *) &Timer.tr_node); X InfoMsg1Line("ERROR: User aborted transfer"); X timeout = USERABORT; X return('\0'); X } X PrintIText(mywindow->RPort, &MyTitle, 0L, 0L); X/* continue; */ X } X X if (rd == FALSE && CheckIO(&Timer)) { X InfoMsg1Line("ERROR: Timeout waiting for character"); X timeout = TIMEOUT; X return('\0'); X } X } /* end while */ X if(!CheckIO(&Timer)) X AbortIO((char *) &Timer); X Wait (1L << Timer_Port->mp_SigBit); X WaitIO((char *) &Timer.tr_node); X timeout = GOODREAD; X return(ch & (p_parity == 0 ? 0xFF : 0x7F)); X } X Xvoid No_XON() { X X /* turn off XON/XOFF processing */ X enablexon = FALSE; X Write_Request->io_SerFlags |= SERF_XDISABLED; X Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; X DoIO(Write_Request); X Write_Request->IOSer.io_Command = CMD_WRITE; X } X Xvoid Do_XON() { X /* turn on XON/XOFF processing */ X enablexon = TRUE; X Write_Request->io_SerFlags &= ~SERF_XDISABLED; X Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; X DoIO(Write_Request); X Write_Request->IOSer.io_Command = CMD_WRITE; X } X X/**************************************/ X/* xmodem send and recieve functions */ X/************************************/ X Xint XMODEM_Read_File(file) Xchar *file; X{ X int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag, use_crc = 0; X int c, good_sect; X unsigned int checksum, j, bufptr; X unsigned short crc; X char scrstr2[40]; X X bytes_xferred = 0L; X ttime = TTIME_SHORT; X X if ((fd = creat(file, 0)) < 0) { X InfoMsg2Line("XMODEM Can't Open File:",file); X return FALSE; X } X else X InfoMsg1Line("XMODEM Receive, <esc> in VT100 window to abort"); X X sectnum = errors = bufptr = 0; X if(p_xproto == 2) X sendchar('C'); X else X sendchar(NAK); X firstchar = 0; X No_XON(); X while (firstchar != EOT && errors != ERRORMAX) { X errorflag = FALSE; X X do { /* get sync char */ X firstchar = readchar(); X if (timeout != GOODREAD) { X if (timeout == USERABORT || errors++ == ERRORMAX) { X Do_XON(); X return FALSE; X } X } X } while (firstchar != SOH && firstchar != EOT); X X if (firstchar == SOH) { X sprintf(scrstr2,"Getting Block %4d...",sectnum); X InfoMsgNoScroll(scrstr2); X sectcurr = readchar(); X if (timeout != GOODREAD) { Do_XON(); return FALSE; } X sectcomp = readchar(); X if (timeout != GOODREAD) { Do_XON(); return FALSE; } X if ((sectcurr + sectcomp) == 255) { X if (sectcurr == ((sectnum + 1) & 0xff)) { X checksum = 0; crc = 0; X for (j = bufptr; j < (bufptr + SECSIZ); j++) { X bufr[j] = readchar(); X if (timeout != GOODREAD) { Do_XON(); return FALSE; } X checksum = (checksum + bufr[j]) & 0xff; X crc = updcrc(((unsigned int)bufr[j] & 0xff), crc); X } X c = readchar(); X if(timeout != GOODREAD) { X errorflag = TRUE; X if(timeout == USERABORT) {Do_XON(); return FALSE; } X } X if(p_xproto == 2) { X crc = updcrc(((unsigned int)c & 0xff), crc); X c = readchar(); X if(timeout != GOODREAD) { X errorflag = TRUE; X if(timeout == USERABORT) {Do_XON(); return FALSE; } X } X crc = updcrc(((unsigned int)c & 0xff), crc); X good_sect = (crc == 0); X } else X good_sect = (checksum == c); X if (!good_sect) { X errorflag = TRUE; X if(timeout == USERABORT) { Do_XON(); return FALSE; } X } else { X errors = 0; X sprintf(scrstr2,"Block %4d verified",sectnum); X sectnum++; X bufptr += SECSIZ; X bytes_xferred += SECSIZ; X InfoMsgNoScroll(scrstr2); X if (bufptr == BufSize) { X if (write(fd, bufr, BufSize-128) == EOF) { X InfoMsg1Line("XMODEM: Error Writing File"); X Do_XON(); X return FALSE; X } X bufptr = 128; X for (j = 0; j < 128; j++) X bufr[j] = bufr[(BufSize-128)+j]; X } X sendchar(ACK); X } X } else { X /* got a duplicate sector */ X if (sectcurr == (sectnum & 0xff)) { X /* wait until we time out for 5secs */ X do { X readchar(); X } while (timeout == GOODREAD); X if (timeout == USERABORT) { X Do_XON(); X return FALSE; X } X InfoMsg1Line("XMODEM: Received Duplicate Sector"); X sendchar(ACK); X } X else errorflag = TRUE; X } X } else errorflag = TRUE; X } X if (errorflag == TRUE) { X errors++; X InfoMsg1Line("XMODEM: Error"); X if(p_xproto == 2) X sendchar('C'); X else X sendchar(NAK); X } X } /* end while */ X if ((firstchar == EOT) && (errors < ERRORMAX)) { X sendchar(ACK); X if (bufptr) { X /* use firstchar to remember the last char for chopping */ X if((firstchar = bufr[--bufptr]) == 0 || firstchar == 0x1A) X while (bufptr && bufr[--bufptr] == firstchar) X ; X bufptr++; X write(fd, bufr, bufptr); X } X close(fd); X Do_XON(); X ScrollInfoMsg(1); X return TRUE; X } X Do_XON(); X return FALSE; X} X Xint XMODEM_Send_File(file) Xchar *file; X{ X int sectnum, bytes_to_send, size, attempts, c, use_crc = 0; X unsigned checksum, j, bufptr; X unsigned short crc; X char scrstr2[40]; X bytes_xferred = 0; X ttime = TTIME_LONG; X X if ((fd = open(file, 0)) < 0) { X InfoMsg1Line("XMODEM: Cannot Open Send File"); X return FALSE; X } else X InfoMsg1Line("XMODEM Send, <esc> from VT100 window to abort"); X attempts = 0; X sectnum = 1; X No_XON(); X /* wait for sync char */ X j=1; X while (((c = readchar()) != NAK) && (c != 'C') && (j++ < ERRORMAX)) X if (timeout == USERABORT) { Do_XON(); return(FALSE); } X if (j >= (ERRORMAX)) { X InfoMsg1Line("XMODEM: Receiver not sending"); X Do_XON(); X return FALSE; X } X X if(c == 'C') X use_crc = 1; X while ((bytes_to_send = read(fd, bufr, BufSize)) && X attempts != RETRYMAX) { X if (bytes_to_send == EOF) { X InfoMsg1Line("XMODEM: Error Reading File"); X Do_XON(); X return FALSE; X } X X bufptr = 0; X while (bytes_to_send > 0 && attempts != RETRYMAX) { X attempts = 0; X sprintf(scrstr2,"Sending block %4d",sectnum); X size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send; X bytes_to_send -= size; X do { X InfoMsgNoScroll(scrstr2); X sendchar(SOH); X sendchar(sectnum); X sendchar(~sectnum); X checksum = 0; crc = 0; X for (j = bufptr; j < bufptr + size; j++) { X sendchar(bufr[j]); /* send buffer data */ X checksum += bufr[j]; X crc = updcrc(((unsigned int)bufr[j] & 0xff), crc); X } X if( size < SECSIZ ) { /* check if we need to pad */ X c = bufr[j-1] ? 0 : 0x1A; /* choose correct padding */ X j = SECSIZ - size; X checksum += j * c; X while ( j-- ) { X if(use_crc) X crc = updcrc(c, crc); X sendchar(c); /* send padding */ X } X } X if(use_crc) { X crc = updcrc(0, updcrc(0, crc)); X sendchar(crc >> 8); X sendchar(crc & 0xff); X } else X sendchar(checksum); X attempts++; X c = readchar(); X if (timeout == USERABORT) { X InfoMsg1Line("XMODEM: ABORTED"); X Do_XON(); X return FALSE; X } X } while ((c != ACK) && (attempts != RETRYMAX)); X bufptr += size; X bytes_xferred += size; X sprintf(scrstr2,"Sent block %4d",sectnum); X InfoMsgNoScroll(scrstr2); X sectnum++; X } X } X close(fd); X if (attempts == RETRYMAX) { X InfoMsg1Line("XMODEM: No Acknowledgment, ABORTING"); X Do_XON(); X return FALSE; X } else { X attempts = 0; X do { X sendchar(EOT); X attempts++; X } while ((readchar() != ACK) && X (attempts != RETRYMAX) && X (timeout != USERABORT)) ; X if (attempts == RETRYMAX) X InfoMsg1Line("XMODEM: No end of file"); X } X Do_XON(); X ScrollInfoMsg(1); X return TRUE; X} X X/* allow for multi file xfers separated by commas under X kermit and XMODEM */ X Xvoid multi_xfer(name,mode,do_send) Xchar *name; Xint (*mode)(); Xint do_send; X { X int done = 0; X int status; X char *p, *name_start; X X timeout = USERABORT - 1; X for(p=name_start=name; !done && timeout != USERABORT; name_start=++p) X { X if (*(name_start) == '$' && *(name_start+1) == '\0') { X saybye(); X return; X } X while(*p == ' ') p++; X while(*p && *p != ',' && *p != ' ') p++; X if (*p == '\0') { X done = TRUE; X multi = 0; X } X else X multi = 1; X *p = '\0'; X X status = ((*mode)(name_start, multi)); X if (status == FALSE) close(fd); X } X server = 0; X multi = 0; X if(p_xbeep) X cmd_beep(0L); X } X ________This_Is_The_END________ if test `wc -l < xmodem.c` -ne 514; then echo 'shar: xmodem.c was damaged during transit (should have been 514 bytes)' fi fi ; : end of overwriting check exit 0