wecker@cookie.dec.com.UUCP (11/23/86)
# This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # readme # vt100.doc # makefile # vt100.h # vt100.c # init.c # This archive created: Sun Nov 2 15:25:31 1986 echo shar: extracting readme sed 's/^XX//' << \SHAR_EOF > readme XXThis archive contains a vt100 emulator with KERMIT and XMODEM file XXtransfer protocols by Dave Wecker (V2.3 DBW 861101). XX XXThanks: XX------- XX To everyone who sent in code and suggestions! XX XXReleases: XX--------- XX v2.3 861101 DBW - minor buf fixes XX v2.2 861012 DBW - more of the same XX v2.1 860915 DBW - new features (see README) XX v2.0 860823 DBW - Major rewrite XX v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX v1.0 860712 DBW - First version released XX XXUsage: XX------ XX Please read VT100.DOC for usage information and examples. XX XXRelease Notes: XX-------------- XXv2.3 861101 DBW - minor bug fixes: XX XX - added p_wbcolors to allow workbench colors on custom screen XX (In the init file you can specify WBCOLORS to be NO (use color XX definitions in INIT FILE or VT100.H) or YES (use WORKBENCH XX colors for everything)). XX - "$" now sends a kermit-bye (like it says in VT100.DOC). XX - made window/screen heights more reasonable XX - Added ANSI insert line and delete line (<csi><num>L and XX <csi><num>M) to speed up various editors (like emacs). XX NOTE: This is NOT a VT100 sequence (new extension). XX - ctrl-space now also sends a null (along with ^@ and ^`) XX - RAWKEY fixed in WINDOW.C XX - p_wrap fixed in WINDOW.C XX - removed WRDMAX from VT100.H XX - fixed exit with no params in SCRIPT.C XX - fixed parity comparisons in KERMIT.C XX - init file [n+1] changed to [nplus1] to make Lattice happy. XX - cursoron(), cursoroff() changed to one routine cursorflip(). XX - long lines shortened to less than 80 characters (for gateways). XX - blanks following exit (or comments) now work in scripts. XX XXv2.2 861012 DBW - more of the same: XX XX - The INIT file "exit" command can now take an optional argument XX which is the name of a script to execute after initialization XX is complete. XX XX - The SCRIPT command "exit" takes an optional paramater which may XX be either the pathname of the next script to execute or the XX string "VT100" (which causes the emulator to exit completely). XX XX - Hangup menu item now works. XX XX - Autowrap can now be set from VT100.H, VT100.INIT and the standard XX escape sequence (<ESC>[?7h - set, <ESC>[?7l - reset) XX XX - Control-G is now handled with an audible beep (volume set with the XX VOLUME parameter in VT100.H and VT100.INIT). If the volume is set XX to 0, a visual beep (DisplayBeep) will be used instead. XX XX - Script now used "^chr" to send control characters instead of XX "|" (which was screwing up U**X users). See VT100.DOC for details. XX XX - The graphics "box" character (a) was added so bar charts now work XX in line drawing mode (e.g., monitor system on VMS). XX XX - Control-@ and Control-` now send the NULL character XX XX - Alternate color for BOLD has been re-instated by popular demand XX (instead of using SetSoftStyle) when there is more than 1 bit- XX plane. With one bit-plane, SetSoftStyle is used. XX XX - Menus have been cleaned up. XX XX - Lattice compilation cleaned up. XX XX - No more wordsize parameter since PARITY takes care of all cases XX (NONE=8bit, MARK, SPACE, EVEN ODD). XX XX - Any function key definition that begins with a KEYSCRIPT XX introducer will invoke a script from the function key: e.g., XX "~df1:foo/script.txt" (if KEYSCRIPT = 0x7E = "~") XX XX - Double shift keys are now handled correctly. XX XX - Version has been added to the title bar (for bug reports). XX XXv2.1 860915 DBW - new features / bug fixes XX XX - Now identifies as a VT100 (including the response to <esc>Z) XX - Cursor color now gets read in as hex (instead of decimal) XX - REPORTMOUSE taken out of definitions (not needed) XX - XON/XOFF now being handled by the device driver instead of me XX - Literal escape characters have been replaced with \033 XX - At init time the user can now specify the input BUFFER size XX (typically between 512 and 2048 bytes) depending on baud rate XX - Script files are now case insensitive for commands XX - XMODEM now turns off the driver XON/XOFF during transfers XX - Graphic rendition now done by the OS instead of me. XX - Initialization files are now searched for in S: instead of C: XX - Forward GOTO bug fixed in the script package. XX - Keypad can now be used in both numeric and application mode XX - General purpose cleanup() routine added for all exits. XX - Utility menu added (sendbreak, hangup, change directory). XX NOTE: hangup is not implemented yet. XX - Full wild card support in file transfers (see vt100.doc). XX - Kermit cleaned up with better filename handling (from host). XX - Script now has CD (changed directory) and SB (send break) commands XX - Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu XX and scripts. (Generates parity from a table). XX - Added 8th bit quoting in KERMIT when using 7 bit words (ODD or XX EVEN parity). XX - Break time can be set from VT100.H, VT100.INIT or a script file. XX - Transfer mode (image or CRLF) can now be set from a script file. XX - Control characters in escape sequences now act like a true VT100. XX - F10 now works from init files. XX - Right (or Left) AMIGA with period (".") sends a BREAK to the host XX from the keyboard. XX - XMODEM status kept down to one line for a file transfer. XX XXv2.0 860823 DBW - Major rewrite: XX XX - Emulator now compiles under either MANX or LATTICE by defining XX the appropriate compiler type in VT100.H. XX - Sped up code to an effective baud rate of (about) 8k. This means XX that clear text at 4800 baud should be no problem. XX - Added XON/XOFF generation so that characters should not get lost XX any more at 9600 baud (when receiving clear text). XX - Got rid of all command line switches and environment variables. XX Instead upon invocation the program searches first for any file XX named on the command line, then looks for VT100.INIT in the XX current directory and finally searches for C:VT100.INIT. XX All parameters can be set in the init file, and a sample VT100.INIT XX is provided in VT100.DOC that shows all possible options. XX - All parameters that are set by VT100.INIT are defined in VT100.H XX (variables starting with "p_"). This allows you to compile your XX own defaults into the code. XX - You can now set the number of lines (for all you EMACS freaks :-). XX On an interlaced screen this gives you upto a 48 line terminal. XX - WORKBENCH colors are NEVER touched. XX - In an attempt to keep the size down, the color palette menu item XX has been removed (current). Code is about 36K in size with a XX run time image (using workbench screen) of about 88k. XX - Many bugs fixed including reverse scrolling with descenders, XX reverse video at end of line, clearing with scrolling regions, XX ... and 20 or more others. XX - File capture now no longer sends the filename to the host. XX - BOLD (<esc>[1m) has now been added by using an additional color XX when you specify a depth of 2 (instead of 1) bitplane. XX - UNDERLINE (<esc>[4m) has now been added. XX - The handling of remote (host) escape sequences has been completly XX re-written (thanks to Dawn Banks for all the work). XX - Function keys (and shifted function keys) can now be bound to XX arbitrary strings (Jim Ravan gets his macros). See VT100.DOC XX for details. XX - Cursor has no been reduced to the size of a normal character for XX easier readability. XX - XMODEM has been improved (by Steve Drew) to use a timer device XX (for timeouts) and to abort immediately if the user types <ESC>. XX - KERMIT has been completely re-written and appears to work fine, XX thanks to the efforts of Steve Drew. XX - New menu item allows script file support. Module written by XX Steve Drew. See VT100.DOC for details. XX XXKnown problems: XX--------------- XX XX - There have been some reports of the BELL (ctrl-g) not working XX under Lattice. This is under investigation. XX XXSuggestions not implemented: XX---------------------------- XX XX - "ASCII capture uses synchronous I/O so capture of game playing XX is jerky" XX XX This change MAY be made if someone else wants to write the code. XX XX - "Beep should be in stereo" XX XX I am trying to use as FEW system resources as possible, therefore XX beep only ties up 1 of the 4 possible channels. XX XXInstallation: XX------------- XX The files in this archive may be extracted by the bourne shell XX (/bin/sh) or the shar program using the "unshar switch (-u)", XX contact me if you need a copy of this version of shar. XX XX REMEMBER: Set the correct compiler definition in VT100.H XX XXFiles: XX------ XX README - this file XX XX vt100.doc - documentation for the terminal emulator XX XX makefile - make file for the emulator (under MANX AZTEC-C) XX XX vt100.h - include file used by all other modules XX XX window.c - manager for window and keyboard XX XX vt100.c - main module, handles menus XX XX remote.c - handle remote characters (vt100 emulation) XX XX kermit.c - kermit protocol (to transfer text files on VMS XX select the CRLF option on the transfer mode menu, XX otherwise use image mode). XX XX init.c - startup code XX XX xmodem.c - xmodem protocol that understands AMIGA binary and XX text file formats (automatically). XX XX script.c - script control package XX XX expand.c - filename expansion (wildcards) and dir setting XX XXContact: XX-------- XXPlease send bugs/comments/suggestions to: XX XX Dave Wecker at ENET: COOKIE::WECKER XX ARPA: wecker%cookie.dec.com@decwrl.dec.com XX USENET: {decvax|decwrl}!cookie.dec.com!wecker XX SNAIL: Dave Wecker XX 115 Palm Springs Drive XX Colorado Springs, CO 80908 SHAR_EOF if test 9214 -ne "`wc -c readme`" then echo shar: error transmitting readme '(should have been 9214 characters)' fi echo shar: extracting vt100.doc sed 's/^XX//' << \SHAR_EOF > vt100.doc XXThis is the documentation file for the VT100 terminal emulator by Dave XXWecker (V2.3 DBW 861101). Comments/suggestions/bugs/problems/praise XXshould be sent to: XX XX Dave Wecker at ENET: COOKIE::WECKER XX ARPA: wecker%cookie.dec.com@decwrl.dec.com XX USENET: {decvax|decwrl}!cookie.dec.com!wecker XX SNAIL: Dave Wecker XX 115 Palm Springs Drive XX Colorado Springs, CO 80908 XX XXMulti-file transfer, the new version of KERMIT and script support were XXcontributed by Steve Drew (Aug 20 1986). If you wish to thank Steve XXdirectly he can be contacted through: XX XX Steve Drew at ENET: CGFSV1::DREW XX ARPA: drew%cfgsv1.dec.com@decwrl.dec.com XX USENET: decvax!decwrl!cgfsv1.dec.com!drew XX XXMany other pieces of code/suggestions have been sent in.. XX thanks to all! XX XXProgram startup: XX---------------- XX 1> vt100 [initfile] XX XX - At startup, the program will search for an initialization XX file to execute. It will first look for the specified XX "initfile", then VT100.INIT (in the current directory) XX and finally S:VT100.INIT. The format for the init file XX is described later in this document. XX XX - The init file controls the setting of initial defaults XX and screen and macro definitions. XX XX - If none of the files (listed above) are found, the XX built-in defaults (defined in VT100.H as variables, XX beginning with "p_") are used. XX XX - All commands are either menu or script based. Scripts XX are described below. XX XXMenus: XX------ XXFile - file transfers XX Ascii Capture - Begin/end a script of the current session XX Ascii Send - Type a file to the host XX Xmodem Receive - Receive a file using XMODEM protocol XX Xmodem Send - Send a file using XMODEM protocol XX Kermit Get - Receive files from a host KERMIT SERVER XX Kermit Receive - Receive files from a host KERMIT XX Kermit Send - Send files to a host KERMIT [SERVER] XX Kermit Bye - Terminate a host KERMIT SERVER XXComm Setup - Setup communications XX Baud Rate - Set the terminal baud rate XX 300, 1200, 2400, XX 4800, 9600 XX Parity XX NONE, MARK, SACE, XX EVEN, ODD - Type of parity XX Xfer Mode XX image - Send files verbatim (for UNIX hosts or XX binary files) XX CR LF - Send CR LF as line terminator and strip XX CR on received files (VMS text). XXScript - Script commands XX Execute file - Start up an asynchronous script file XX Abort Execution - Terminate a script file XXUtility - Utility commands XX Send Break - send a break to the host XX Hang Up - close line (not implemented yet) XX Change Dir - change the local directory (for transfers) XX XXKeypad mapping (in application mode): XX------------------------------------- XX XX AMIGA VT100 comments XX ------- ------- --------------------------- XX 0-9 == 0-9 XX . == . XX ENTER == ENTER (basically, flip the bottom XX - == , 2 keys up to get a VT100) XX HELP == - (only free key around) XX f1-f4 == PF1-PF4 (or any rebinding you do) XX arrows == arrows XX XXNote: Right (or Left) AMIGA key in conjunction with a period (".") XX will send a break to the host. XX XX CTRL in conjunction with either an at-sign ("@") or a backquote ("`") XX will send a NULL to the host. XX XXInitialization file example: XX---------------------------- XXHere is a (hopefully) self-explanatory VT100.INIT file with all XXoptions used: XX XX##################################################################### XX# XX# VT100 sample initialization file XX# v2.3 861101 DBW - Dave Wecker standard defaults XX# XX# Hash mark at the beginning of a line denotes a comment. XX# White space (space(s) or tab(s)) delimit fields. XX# Case ignored except for function key bindings. XX# XX# All items in this file overide variables of the same name in VT100.H XX# (all variables in vt100.h have a "p_" prepended to them) XX# XX##################################################################### XX# XXBAUD 2400 # Anything after required fields is ignored XXSCREEN CUSTOM # may be CUSTOM or WORKBENCH XXINTERLACE ON # ON for CUSTOM or interlaced workbench XXDEPTH 1 # number of bit planes to use (1 or 2) XXWBCOLORS YES # ignore custom colors and use defaults XXFOREGROUND 950 # Colors are only used on the custom screen XXBACKGROUND 000 # Colors are in hex RGB from 000 to FFF XXBOLD a00 # Color for bold highlighting (in custom) XXCURSOR 00a # Color for cursor (in custom screen) XXLINES 48 # normal <= 24 interlaced <= 48 XXMODE CRLF # IMAGE or CRLF (for KERMIT transfers) XXBUFFER 512 # 512 <= Input buffer size <= 2048 XXPARITY NONE # NONE (= 8 bit), MARK, SPACE, ODD or EVEN XXBREAK 750000 # Length for break key in microseconds XXVOLUME 64 # Beep Volume (0 = Visual Beep) XXWRAP OFF # Auto wrap ON or OFF XXKEYSCRIPT 7E # Hex value for script introducer XX# XX# Function bindings (strings to type when any of F1 - F10 are pressed) XX# f<num> = function key XX# F<num> = shifted function key XX# XX# The string specified must be delimited and uses one special char: XX# ^ = control next character XX# ^^ = up arrow XX# XX# Sample control characters: XX# ^[ = escape ^M = carriage return XX# ^J = line feed ^L = form feed XX# XX# If the first character of the string is a script introducer XX# (KEYSCRIPT) then the string is interpreted as a script filename XX# to be executed when the key is pressed. XX# XX# Examples of bindings: XX# XXf1 "^[OP" # f1-f4 = PF1 - PF4 on a VT100 XXf2 "^[OQ" XXf3 "^[OR" XXf4 "^[OS" XX# XX# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E) XX# XXf5 "~df1:vt100_source/dialwork.script" XXf6 "~df1:vt100_source/sendvt100.script" XXf7 "~df1:vt100_source/getpics.script" XX# XXf8 "MAIL^M" # Reads my mail (note embedded <CR>) XXf9 "NOTE^M" # Reads conferences XXF1 "$2400!" # dials the phone to work XXF2 "$bbs1!" # dials the phone to billboard 1 XXF3 "$bbs2!" # dials the phone to billboard 2 XXF4 "$bbs3!" # dials the phone to billboard 3 XX# XX# all done with init, now execute script as startup sequence XX# XXexit df1:vt100_source/dialwork.script XX XXMulti file Xfers: XX----------------- XXThe VT100 emulator now supports multiple file transfers. This is XXspecified by using a comma (",") between file names when using XMODEM XXor KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file XXtransfers). XX XXWhen specifying a file name to recieve by default the directory path XXis stripped of the filename when sent to the host but is kept for the XXlocal file spec. eg: XX XX receive file: ram:file.txt,df1:newfile.bin,$ XX XXwill ask the server for file.txt and put it in ram:, and get XXnewfile.bin and put it on df1: (see explanation of "$" below). If you XXdo a single file transfer you will get another prompt for the remote XXname e.g.: XX XX receive file: ram:file.txt XX remote file name[file.txt] userdisk1:wantfile.txt XX XXThe same rules apply to sending multiple files therefore if you are XXdoing multi file transfers make sure the host server is connected to XXthe desired directory. XX XXIn addition KERMIT now supports wildcards (* = any number of XXcharacters, ? = any single character). Examples: XX XX send: *.c,*.h,*.doc XX get: *.c,*.h,$ XX XXKERMIT receive is now smart enough to use the host filename so no XXfilename needs to be specified on the AMIGA's side. XX XXScript file operation: XX---------------------- XXThe script file can be invoked by selecting 'execute file' from the XXscript menu. At any time you can abort the script file by selecting XX'Abort Execution'. XX XXDuring the time script file is running the terminal emulation is still XXactive and you may type simulataneous to the script file. This may be XXdesired if your script file is WAITing for a string or is DELAYing for XXa period of time etc. XX XXScript file Commands (case insensitive): XX------------------------------------------------------------ XX# Commented line XX Format: XX # comment may not be on same line as a command. XX Example: XX # this is a comment XX------------------------------------------------------------ XXASCII_SEND Send an ascii file to the host. XX Format: XX (same format as CAPTURE) XX------------------------------------------------------------ XXBAUD Set baud rate XX Format: XX BAUD rate Sets the baud rate for send/receive XX Example: XX BAUD 2400 Sets the baud rate at 2400 baud XX------------------------------------------------------------ XXBT Set the break time (for an SB command) XX Format: XX BT value Value is in micro-seconds XX Example: XX BT 750000 XX------------------------------------------------------------ XXCAPTURE To start/stop ascii file capture. XX Format: XX CAPTURE file Start ascii capturing XX CAPTURE End ascii capturing XX Example: XX CAPTURE foo.bar Starts capture of file foo.bar XX CAPTURE Ends ascii capture of file foo.bar XX------------------------------------------------------------ XXCD To change the local directory XX Format: XX CD newdir set a new directory for file transfers XX Example: XX CD DF1:foo/bar set the directory as specified XX------------------------------------------------------------ XXDELAY Suspends script file for a specified time XX Format: XX DELAY n Suspends execution for n seconds XX Example: XX DELAY 2 Suspends for 2 seconds XX------------------------------------------------------------ XXEXIT Ends execution of the current script file. XX Format: XX EXIT Exit the current script XX EXIT VT100 Exit vt100 program XX EXIT newscript Exit this script and start up newscript XX Example: XX EXIT DF1:FOO.BAR Exit the current script and start FOO.BAR XX------------------------------------------------------------ XXGOTO Jumps to a different part of the script file. XX Format: XX GOTO label Jumps to a line beginning with label: XX Jumps may be forward or backward. XX Example: XX FOO: Sets up a label XX GOTO FOO Jumps to FOO XX------------------------------------------------------------ XXKB Send a BYE packet to a host KERMIT server (shut down server). XX Format: XX KB XX------------------------------------------------------------ XXKG Gets files from host. (which is running as a server). XX Format: XX (same format as KS) XX------------------------------------------------------------ XXKR Receives a file from kermit host (not running as server) XX Format: XX (same format as KS) XX------------------------------------------------------------ XXKS Sends files via kermit to the host. XX Format: XX KS file Send one file XX KS file1,file2,... Send multiple files XX KS file1,file2,...,$ Send multiple files and shut down server XX Example: XX KS foo.bar sends foo.bar (note no quoting is used) XX KS foo1,foo2,foo3 sends three files XX KS foo1,foo2,foo3,$ sends three files and shuts down server XX------------------------------------------------------------ XXON Peforms a command every time a string is received XX Format: XX ON "string" cmd Execute cmd when string is received. XX Only one ON string may be installed at a XX time. XX XX If cmd is a GOTO and we were previously XX WAITing for a string the WAIT is aborted and XX execution resumes at the new label. XX XX If cmd is not SEND and we were previously XX DELAYing, then the DELAY is aborted and the XX cmd is executed, followed by the next command XX after the DELAY. XX XX If cmd is a SEND and we were previously XX DELAYing, then the DELAY is continued. XX Example: XX ON "LOSS CARRIER" GOTO RESTART XX If modem drops carrier, try to redial XX ON "--more--" SEND " " XX Send a space every time --more-- is received XX------------------------------------------------------------ XXPARITY Sets the parity XX Format: XX PARITY type Set the parity type XX Example: XX PARITY NONE no parity XX PARITY MARK mark parity XX PARITY SPACE space parity XX PARITY ODD odd parity XX PARITY EVEN even parity XX------------------------------------------------------------ XXSEND Sends a string or character to the host. XX Format: XX SEND "string" Sends a string to the host. Beginning and XX ending double quotes (") are required. A XX carat (^) may be used to send control chars. XX Two carats transmits a carat character. XX SEND chr Sends a single character. XX SEND ^chr Sends a single control character. The chr XX is NOT case sensitve XX Example: XX SEND "mail" Send the string mail XX SEND "dir^M" Send the string dir followed by a <CR> XX SEND a Send the letter a XX SEND ^C Send a control C XX SEND "abc^^def" Send the string abc^def XX SEND ^^ Send a control-uparrow XX SEND " Send the '"' character XX------------------------------------------------------------ XXSB Sends a break character to the host XX Format: XX SB Note that any pending character to send XX Example: is aborted by this call XX SB XX------------------------------------------------------------ XXTM Set a transfer mode for KERMIT to use XX Format: XX TM type type of transfers to perform XX Example: XX TM IMAGE image mode transfers XX TM CRLF <CR><LF> text transfers (VMS Kermit). XX------------------------------------------------------------ XXWAIT Suspends the script file until a certain string is received. XX Format: XX WAIT "string" Same rules for string as SEND XX WAIT Enter an endless wait. Usually used after XX some "ON" commands have been set up. Can XX still aborted via the script menu. XX Example: XX WAIT "User:" Waits for the string User: XX WAIT Waits forever XX------------------------------------------------------------ XXXR Receives a file via XMODEM. XX Format: XX (same format as KS) XX------------------------------------------------------------ XXXS Sends a file via XMODEM. XX Format: XX (same format as KS) XX------------------------------------------------------------ XX XX XXScript file examples: XX-------------------- XX################################################################### XX# Script to dial work (dialwork.script) XX# v2.3 861101 DBW XX################################################################### XX# XX# Make sure that we have all the parameters we want XX# XX DELAY 2 XX BAUD 2400 XX PARITY NONE XX TM CRLF XX BT 750000 XX SB XX# XX# First get the modem's attention: XX# XXStart: XX DELAY 1 XX ON "Ready" GOTO Dial XX SEND ^B XX DELAY 2 XX GOTO Start XX# XX# Now dial the 2400 baud line to work: XX# XXDial: XX ON "Attached" GOTO Login XX SEND "$2400!" XX DELAY 30 XX GOTO Start XX# XX# We got attached, so keep hitting return until the Gandalf terminal XX# handler wakes up: XX# XXLogin: XX ON "enter" GOTO Gandalf XX DELAY 1 XX SEND ^M XX GOTO Login XX# XX# Now connect from the Gandalf to the terminal server (ts1): XX# (when it asks for a password I need to type the password XX# manually here) XX# XXGandalf: XX DELAY 2 XX SEND "ts1^M" XX WAIT "class start" XX# XX# Keep sending <CR>'s until the LAT prompts for a username: XX# XXWaitLat: XX DELAY 2 XX ON "username>" GOTO Lat XX SEND ^M XX GOTO WaitLat XX# XX# Tell the LAT that it's me, and connect to the "cookie cluster" XX# (my host systems). Tell the cluster my user name. XX# (when it asks for a password I need to type the password XX# manually here) XX# XXLat: XX SEND "wecker^M" XX DELAY 1 XX SEND "connect cookie^M" XX WAIT "Username:" XX SEND "WECKER^M" XX WAIT "at home" XX SEND "^M^M^M" XX# XX# Got through all the LOGIN garbage, so let's do some work. XX# XX WAIT "$ " XX# XX# Now go back to the LAT and connect to my workstation XX# XX SEND "^]connect child^M" XX WAIT "login:" XX SEND "wecker^M" XX WAIT "at home" XX SEND "^M^M^M" XX# XX# Leave us on VMS XX# XX SEND ^^ XX DELAY 2 XX# XX# Go run the next script XX# XX EXIT df1:vt100_source/sendvt100.script XX XX##################################################################### XX# Script to upload the terminal emulator sources (sendvt100.script) XX# v2.3 861101 DBW XX##################################################################### XX# XX# Make sure that we have all the parameters we want XX# XX DELAY 2 XX PARITY NONE XX TM IMAGE XX# XX# Get into the right directory and upload to my U**X workstation XX# XX CD df1:vt100_source XX SEND ^^ XX SEND "cd ~/amiga/vt100^M" XX SEND "rm -f *^M" XX WAIT "% " XX DELAY 2 XX# XX# Send the readme file for the terminal emulator via XMODEM: XX# XX SEND "xmodem -r readme^M" XX DELAY 3 XX XS readme XX WAIT "% " XX# XX# Send the other terminal emulator files via KERMIT: XX# XX DELAY 1 XX SEND "kermit -x^M" XX DELAY 3 XX KS vt100.doc,makefile,vt100.h,*.c XX DELAY 2 XX KB XX WAIT "% " XX# XX# We popped out of server mode, so send the compiled code XX# XX DELAY 1 XX SEND "kermit -i -x^M" XX DELAY 3 XX KS vt100 XX DELAY 2 XX KB XX WAIT "% " XX# XX# Now build the target shar files XX# XX SEND "shar -a readme vt100.doc makefile vt100.h vt100.c init.c " XX SEND "> vt100_22a.shar^M" XX SEND "shar -a script.c remote.c window.c expand.c kermit.c xmodem.c " XX SEND "> vt100_22b.shar^M" XX# XX# Time to pull copies over to VMS XX# XX SEND ^^ XX SEND "swi [wecker.amiga]^M" XX SEND "cop child::" XX SEND " XX SEND "/staff/wecker/amiga/vt100/vt100_22a.shar" XX SEND " XX SEND " []vt100_22a.shar^M" XX WAIT "$ " XX SEND "cop child::" XX SEND " XX SEND "/staff/wecker/amiga/vt100/vt100_22b.shar" XX SEND " XX SEND " []vt100_22b.shar^M" XX WAIT "$ " XX SEND "cop child::" XX SEND " XX SEND "/staff/wecker/amiga/vt100/vt100" XX SEND " XX SEND " []vt100_22.bin^M" XX WAIT "$ " XX# XX# Make them available to the world XX# XX SEND "pub vt100_22*.*^M" XX WAIT "$ " XX# XX# All done so go to the next script XX# XX EXIT df1:vt100_source/getpics.script XX XX################################################################### XX# Script to download images (getpics.script) XX# v2.3 861101 DBW XX################################################################### XX# XX# Make sure that we have all the parameters we want XX# XX DELAY 2 XX PARITY NONE XX TM CRLF XX# XX# Get into the right directory and download XX# XX CD RAY: XX SEND "swi [wecker.render]^M" XX SEND "kermit server^M" XX DELAY 3 XX KG *.img XX DELAY 2 XX KB XX WAIT "$ " XX# XX# Now get out of the emulator XX# XX EXIT VT100 XX SHAR_EOF if test 17237 -ne "`wc -c vt100.doc`" then echo shar: error transmitting vt100.doc '(should have been 17237 characters)' fi echo shar: extracting makefile sed 's/^XX//' << \SHAR_EOF > makefile XX###################################################################### XX# XX# Makefile to build vt100 terminal emulator XX# XX# v2.3 861101 DBW - minor bug fixes XX# v2.2 861012 DBW - more of the same XX# v2.1 860915 DBW - new features (see README) XX# 860823 DBW - Integrated and rewrote lots of code XX# v2.0 860809 DBW - Major release.. LOTS of changes XX# v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX# v1.0 860712 DBW - First version released XX# XX# XX# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H XX# XX###################################################################### XX XXOBJS = vt100.o init.o window.o xmodem.o remote.o \ XX kermit.o script.o expand.o XX XXINCL = vt100.h XX#INCL = XX XXvt100 : $(OBJS) XX copy df0:lib/c.lib ram: XX ln -v -o vt100 $(OBJS) ram:c.lib XX delete ram:#?.lib XX XXvt100.o : vt100.c $(INCL) XX cc +Hvt100.syms vt100.c XX XXinit.o : init.c $(INCL) XX cc +Ivt100.syms init.c XX XXwindow.o : window.c $(INCL) XX cc +Ivt100.syms window.c XX XXxmodem.o : xmodem.c $(INCL) XX cc +Ivt100.syms xmodem.c XX XXremote.o : remote.c $(INCL) XX cc +Ivt100.syms remote.c XX XXkermit.o : kermit.c $(INCL) XX cc +Ivt100.syms kermit.c XX XXscript.o : script.c $(INCL) XX cc +Ivt100.syms script.c XX XXexpand.o : expand.c $(INCL) XX cc +Ivt100.syms expand.c XX XX SHAR_EOF if test 1233 -ne "`wc -c makefile`" then echo shar: error transmitting makefile '(should have been 1233 characters)' fi echo shar: extracting vt100.h sed 's/^XX//' << \SHAR_EOF > vt100.h XX/********************************************************************* XX * a terminal program that has ascii and xmodem transfer capability XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860823 DBW - Integrated and rewrote lots of code XX * v2.0 860809 DBW - Major release.. LOTS of changes XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX * use esc to abort xmodem transfer XX * XX * written by Michael Mounier XX * new version by Dave Wecker 860621 XX ********************************************************************/ XX XX/* ######## define the compiler type here ######## */ XX#define LATTICE 0 XX#define MANX 1 XX XX/* compiler diretives to fetch the necessary header files */ XX#include <exec/types.h> XX#include <exec/exec.h> XX#include <intuition/intuition.h> XX#include <intuition/intuitionbase.h> XX#include <graphics/gfxbase.h> XX#include <graphics/gfx.h> XX#include <graphics/text.h> XX#include <graphics/regions.h> XX#include <graphics/copper.h> XX#include <graphics/gels.h> XX#include <devices/serial.h> XX#include <devices/keymap.h> XX#include <devices/audio.h> XX#include <hardware/blit.h> XX#include <stdio.h> XX#include <ctype.h> XX#include <libraries/dos.h> XX#include <libraries/dosextens.h> XX#include <devices/timer.h> XX XX#if MANX XX#include <functions.h> XX#undef NULL XX#define NULL ((void *)0) XX#endif XX XX#define INTUITION_REV 1L XX#define GRAPHICS_REV 1L XX XX/* things for xmodem send and recieve */ XX#define GOODREAD 0 XX#define TIMEOUT 1 XX#define USERABORT 2 XX#define SECSIZ 0x80 XX#define TTIME_SHORT 5 /* number of seconds for short timeout */ XX#define TTIME_LONG 50 /* number of seconds for long timeout */ XX#define TTIME_KERMIT 10 /* number of seconds for KERMIT timeout*/ XX#define BufSize 0x200 /* Text buffer for XMODEM */ XX#define ERRORMAX 10 /* Max errors before abort */ XX#define RETRYMAX 10 /* Maximum retrys before abort */ XX#define SOH 1 /* Start of sector char */ XX#define EOT 4 /* end of transmission char */ XX#define ACK 6 /* acknowledge sector transmission */ XX#define NAK 21 /* error in transmission detected */ XX XX#define FILEMAX 8 /* number of file menu items */ XX#define COMMAX 3 /* number of communication sub menus */ XX#define RSMAX 5 /* speed menu items */ XX#define PARMAX 5 /* parity items */ XX#define XFMAX 2 /* transfer mode items */ XX#define SCRIPTMAX 2 /* script menu items */ XX#define UTILMAX 3 /* utility menu */ XX#define MAXMENU 4 /* total number of menu entries */ XX XX#define FSF_REVERSE 256 /* fake font style to flag INVERSVID mode */ XX XX/* things for script support */ XX XX#define GOTOLABEL 1 XX#define NEXTCOMMAND 0 XX#define ONCOMMAND 2 XX XX#define WAIT_TIMER 2 XX#define WAIT_STRING 1 XX XX/* things for 'beep' support */ XX#define BEEPSIZE 10L XX#define BEEPFREQ 1000L XX#define COLORCLOCK 3579545L XX XXextern struct MsgPort *CreatePort(); XXextern char *malloc(),*strcpy(),*fgets(); XXextern long ftell(); XX XX#ifdef MODULE_MAIN XXchar bufr[BufSize]; XXint fd, timeout = FALSE, ttime; XXint multi = FALSE, server; XXlong bytes_xferred; XXchar MyDir[60]; XXstruct IntuitionBase *IntuitionBase; XXstruct GfxBase *GfxBase; XX XXstruct NewScreen NewScreen = { XX 0L,0L,640L,200L,1L, /* left, top, width, height, depth */ XX 0,1,HIRES, /* DetailPen, BlockPen, ViewModes */ XX CUSTOMSCREEN,NULL, /* Type, Font */ XX (UBYTE *)"VT100", /* Title */ XX NULL,NULL }; /* Gadgets, Bitmap */ XX XXstruct NewWindow NewWindow = { XX 0,0L,640L,200L, /* left, top, width, height */ XX 0,1, /* detailpen, blockpen */ XX MENUPICK | CLOSEWINDOW | RAWKEY | NEWSIZE, XX SMART_REFRESH | ACTIVATE | BORDERLESS | XX WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, /* Flags */ XX NULL,NULL, /* FirstGadget, CheckMark */ XX (UBYTE *) XX"VT100 (v2.3 861101 DBW) Terminal Window " XX ,NULL, /* set screen after open screen */ XX NULL, /* bitmap */ XX 640L, 200L, 640L, 200L,/* minw, minh, maxw, maxh */ XX CUSTOMSCREEN /* Type */ XX}; XX XXstruct Screen *myscreen; /* ptr to applications screen */ XXstruct Window *mywindow; /* ptr to applications window */ XXstruct ViewPort *myviewport; XXstruct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ XXstruct Preferences *Prefs; /* preferences from GetPrefs() */ XX XXstruct MenuItem FileItem[FILEMAX]; XXstruct IntuiText FileText[FILEMAX]; XXstruct MenuItem CommItem[COMMAX]; XXstruct IntuiText CommText[COMMAX]; XXstruct MenuItem RSItem[RSMAX]; XXstruct IntuiText RSText[RSMAX]; XXstruct MenuItem ParItem[PARMAX]; XXstruct IntuiText ParText[PARMAX]; XXstruct MenuItem XFItem[XFMAX]; XXstruct IntuiText XFText[XFMAX]; XXstruct MenuItem ScriptItem[SCRIPTMAX]; XXstruct IntuiText ScriptText[SCRIPTMAX]; XXstruct MenuItem UtilItem[UTILMAX]; XXstruct IntuiText UtilText[UTILMAX]; XXstruct Menu menu[MAXMENU]; XXstruct IOExtSer *Read_Request; XXchar *rs_in; XXstruct IOExtSer *Write_Request; XXchar rs_out[2]; XXstruct timerequest Timer; XXstruct MsgPort *Timer_Port = NULL; XXstruct timerequest Script_Timer; XXstruct MsgPort *Script_Timer_Port = NULL; XXstruct IOAudio Audio_Request; XXstruct MsgPort *Audio_Port = NULL; XXUBYTE *BeepWave; XXUBYTE Audio_AllocMap[4] = { 1, 8, 2, 4 }; XXint want_message; XXint x,y,curmode,keyapp; XXint MINX = 0; XXint MAXX = 632; XXint MINY = 14; XXint MAXY = 198; XXint top = 14; XXint bot = 198; XXint savx = 0; XXint savy = 14; XXint savmode = 0; XXint nlmode = 0; XXint alt = 0; XXint savalt = 0; XXint a[2] = { 0, 0 }; XXint sa[2] = { 0, 0 }; XXint inesc = -1; XXint inctrl = -1; XXint private = 0; XXint badseq = 0; XXchar *blanks = XX " "; XXint maxcol = 79; XX XX/*************************** defaults *******************************/ XXint p_baud = 2400; /* baud rate */ XXint p_screen = 1; /* 0 = WORKBENCH, 1 = CUSTOM */ XXint p_wbcolors = 1; /* 0 = Custom, 1 = Workbench colors */ XXint p_interlace = 1; /* 0 = no interlace, 1 = interlace */ XXint p_depth = 1; /* number of bit planes (1 or 2) */ XXint p_foreground = 0x950; /* default foreground RGB color */ XXint p_background = 0x000; /* default background RGB color */ XXint p_bold = 0x900; /* default BOLD RGB color */ XXint p_cursor = 0x009; /* default Cursor RGB color */ XXint p_lines = 48; /* number of lines on the screen */ XXint p_mode = 1; /* 0 = image, 1 = CRLF (for kermit) */ XXint p_buffer = 512; /* read buffer size (>= 512 bytes) */ XXint p_parity = 0; /* 0=none,1=mark,2=space,3=even,4=odd */ XXlong p_break = 750000; /* break time (in micro seconds) */ XXint p_volume = 64; /* beep volume (0 = DisplayBeep) */ XXint p_wrap = 0; /* 0 = truncate, 1 = wrap long lines */ XXchar p_keyscript = 0x7E; /* function key script introducer = ~ */ XXchar *p_f[10] = { /* function key defaults */ XX "\033OP","\033OQ","\033OR","\033OS", XX "f5","f6","f7","f8","f9","f10" }; XX XXchar *p_F[10] = { /* shifted function key defaults */ XX "F1","F2","F3","F4","F5", XX "F6","F7","F8","F9","F10"}; XX XX/* for script file */ XXint script_on; XXint script_wait; XXvoid setserbaud(), setparams(), handle_menupick(); XX XX#else /* not MODULE_MAIN */ XX XXextern int multi; /* flags multi file transfers */ XXextern int server; XXextern int want_message; XXextern char bufr[BufSize]; XXextern int fd, timeout, ttime; XXextern long bytes_xferred; XXextern char MyDir[60]; XX XXextern struct IntuitionBase *IntuitionBase; XXextern struct GfxBase *GfxBase; XX XXextern struct NewScreen NewScreen; XXextern struct NewWindow NewWindow; XXextern struct Screen *myscreen; XXextern struct Window *mywindow; XXextern struct ViewPort *myviewport; XXextern struct IntuiMessage *NewMessage; XXextern struct Preferences *Prefs; XXextern struct MenuItem FileItem[FILEMAX]; XXextern struct IntuiText FileText[FILEMAX]; XXextern struct MenuItem CommItem[COMMAX]; XXextern struct IntuiText CommText[COMMAX]; XXextern struct MenuItem RSItem[RSMAX]; XXextern struct IntuiText RSText[RSMAX]; XXextern struct MenuItem ParItem[PARMAX]; XXextern struct IntuiText ParText[PARMAX]; XXextern struct MenuItem XFItem[XFMAX]; XXextern struct IntuiText XFText[XFMAX]; XXextern struct MenuItem ScriptItem[SCRIPTMAX]; XXextern struct IntuiText ScriptText[SCRIPTMAX]; XXextern struct MenuItem UtilItem[UTILMAX]; XXextern struct IntuiText UtilText[UTILMAX]; XXextern struct Menu menu[MAXMENU]; XXextern struct timerequest Timer, Script_Timer; XXextern struct MsgPort *Timer_Port, *Script_Timer_Port; XXextern struct IOExtSer *Read_Request; XXextern char *rs_in; XXextern struct IOExtSer *Write_Request; XXextern char rs_out[2]; XXextern int x,y,curmode,keyapp; XXextern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy; XXextern int savmode,nlmode,alt,savalt,a[2],sa[2]; XXextern int inesc,inctrl,private,badseq,maxcol; XXextern char *blanks; XXextern struct IOAudio Audio_Request; XXextern struct MsgPort *Audio_Port; XXextern UBYTE *BeepWave; XXextern UBYTE Audio_AllocMap[]; XX XXextern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors; XXextern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode; XXextern int p_parity,p_volume,p_wrap,p_keyscript; XXextern long p_break; XXextern char *p_f[10],*p_F[10]; XXextern int script_on; XXextern int script_wait; XX XXextern int do_send(),do_capture(),cleanup(); XXextern void setserpar(), setserbaud(), setparams(), XX handle_menupick(); XX XX#endif /* not MODULE_MAIN */ XX XX#ifndef MODULE_INIT XXextern void InitDevs(),InitFileItems(),InitCommItems(), XX InitScriptItems(),InitUtilItems(),InitMenu(); XXextern char *InitDefaults(); XX#endif XX XX#ifndef MODULE_WINDOW XXextern void filename(),emits(),emit(),emitbatch(),cursorflip(); XXextern int toasc(); XX#endif XX XX#ifndef MODULE_XMODEM XXextern void sendchar(),sendstring(),sendbreak(); XXextern int readchar(),XMODEM_Read_File(),XMODEM_Send_File(); XX#endif XX XX#ifndef MODULE_REMOTE XXextern void doremote(),doindex(); XX#endif XX XX#ifndef MODULE_KERMIT XXextern int doksend(),dokreceive(), multi_xfer(), saybye(); XX#endif XX XX#ifndef MODULE_SCRIPT XXextern int script_start(), chk_script(), exit_script(), XX do_script_cmd(); XX#endif XX XX#ifndef MODULE_EXPAND XXextern char **expand(); XXextern int set_dir(), free_expand(); XX#endif XX SHAR_EOF if test 10203 -ne "`wc -c vt100.h`" then echo shar: error transmitting vt100.h '(should have been 10203 characters)' fi echo shar: extracting vt100.c sed 's/^XX//' << \SHAR_EOF > vt100.c XX/******************************************************************** XX * vt100 terminal emulator with xmodem transfer capability XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860901 ACS - Added Parity and Word Length and support code XX * 860823 DBW - Integrated and rewrote lots of code XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX * use <esc> to abort xmodem or kermit transfers XX * XX * written by Michael Mounier XX * new version by Dave Wecker XX *******************************************************************/ XX XX/* all includes defines and globals */ XX#define MODULE_MAIN 1 XX#include "vt100.h" XX XX/******************************************************/ XX/* Main Program */ XX/* */ XX/* This is the main body of the program. */ XX/******************************************************/ XX XXchar lookahead[80]; XXFILE *tranr = NULL; XXFILE *trans = NULL; XXint capture,send; XXchar name[80]; XXstruct MsgPort *mySerPort; XX XXmain(argc,argv) XXint argc; XXchar **argv; XX { XX ULONG class; XX unsigned int code; XX int KeepGoing,i,la,dola,actual; XX char c,*ptr; XX XX ptr = InitDefaults(argc,argv); XX InitDevs(); XX InitFileItems(); XX InitCommItems(); XX InitScriptItems(); XX InitUtilItems(); XX InitMenu(); XX SetMenuStrip(mywindow,&menu[0]); XX XX MyDir[0] = '\000'; XX KeepGoing = TRUE; XX capture = FALSE; XX send = FALSE; XX maxcol = MAXX / 8; XX la = 0; XX x = MINX ; XX y = MINY; XX curmode = FS_NORMAL; XX keyapp = 0; XX script_on = FALSE; XX script_wait= TRUE; XX SetAPen(mywindow->RPort,1L); XX cursorflip(); XX cursorflip(); XX emit(12); XX mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort; XX SendIO(Read_Request); XX XX /* see if we had a startup script */ XX if (ptr != NULL) script_start(ptr); XX XX while( KeepGoing ) XX { XX /* wait for window message or serial port message */ XX cursorflip(); XX if (script_wait) /* if script ready dont wait here */ XX Wait( XX (1L << mySerPort->mp_SigBit) | XX (1L << mywindow->UserPort->mp_SigBit) | XX (1L << Script_Timer_Port->mp_SigBit)); XX cursorflip(); XX XX /* do ascii file send */ XX if (send) XX { XX if ((c=getc(trans)) != EOF) { XX if (c == '\n') c = '\r'; XX sendchar(c); XX } XX else { XX fclose(trans); XX emits("\nFile Sent\n"); XX send=FALSE; XX } XX } XX XX /* see if there are any characters from the host */ XX if (CheckIO(Read_Request)) { XX WaitIO(Read_Request); XX c = rs_in[0] & 0x7F; XX doremote(c); XX if (script_on) chk_script(c); XX if (capture && c != 10) { XX if (c == 13) c = 10; XX putc(c , tranr); XX } XX Read_Request->IOSer.io_Command = SDCMD_QUERY; XX DoIO(Read_Request); XX Read_Request->IOSer.io_Command = CMD_READ; XX actual = (int)Read_Request->IOSer.io_Actual; XX if (actual > 0) { XX if (inesc < 0 && XX inctrl < 0 && XX a[alt] == 0 && XX capture == FALSE) dola = 1; XX else dola = 0; XX Read_Request->IOSer.io_Length = XX Read_Request->IOSer.io_Actual; XX DoIO(Read_Request); XX Read_Request->IOSer.io_Length = 1; XX XX for (i = 0; i < actual; i++) { XX c=rs_in[i] & 0x7f; XX if (script_on) chk_script(c); XX XX if (dola == 1) { XX if (c >= ' ' && c <= '~' && la < 80) XX lookahead[la++] = c; XX else { XX if (la > 0) { XX emitbatch(la,lookahead); XX la = 0; XX } XX doremote(c); XX dola = 0; XX } XX } XX else { XX doremote(c); XX if (inesc < 0 && XX inctrl < 0 && XX a[alt] == 0 && XX capture == FALSE) dola = 1; XX if (capture && c != 10) { XX if (c == 13) c = 10; XX putc(c , tranr); XX } XX } XX } XX XX /* dump anything left in the lookahead buffer */ XX if (la > 0) { XX emitbatch(la,lookahead); XX la = 0; XX } XX } XX SendIO(Read_Request); XX } XX XX while((NewMessage = XX (struct IntuiMessage *)GetMsg(mywindow->UserPort)) XX != FALSE) { XX class = NewMessage->Class; XX code = NewMessage->Code; XX ReplyMsg( NewMessage ); XX switch( class ) XX { XX case CLOSEWINDOW: XX KeepGoing = FALSE; XX break; XX XX case RAWKEY: XX c = toasc(code,0); XX break; XX XX case NEWSIZE: XX emit(12); XX break; XX XX case MENUPICK: XX handle_menupick(class,code); XX break; XX } /* end of switch (class) */ XX } /* end of while ( newmessage )*/ XX XX if (!script_wait || XX (CheckIO(&Script_Timer) && XX script_wait == WAIT_TIMER)) XX do_script_cmd(NEXTCOMMAND); XX } /* end while ( keepgoing ) */ XX XX /* It must be time to quit, so we have to clean XX * up and exit. XX */ XX XX cleanup("",0); XX XX } /* end of main */ XX XX/* cleanup code */ XX XXcleanup(reason, fault) XXchar *reason; XXint fault; XX { XX switch(fault) { XX case 0: /* quitting close everything */ XX ClearMenuStrip( mywindow ); XX CloseDevice(&Audio_Request); XX XX case 8: /* error opening audio */ XX DeletePort(Audio_Port); XX FreeMem(BeepWave,BEEPSIZE); XX CloseDevice(&Timer); XX XX case 7: /* error opening timer */ XX DeletePort(Timer_Port); XX CloseDevice(&Script_Timer); XX DeletePort(Script_Timer_Port); XX XX case 6: /* error opening write device */ XX DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort); XX FreeMem(Write_Request,(long)sizeof(*Write_Request)); XX CloseDevice(Read_Request); XX XX case 5: /* error opening read device */ XX DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort); XX FreeMem(Read_Request,(long)sizeof(*Read_Request)); XX CloseWindow( mywindow ); XX XX case 4: /* error opening window */ XX if (p_screen != 0) CloseScreen( myscreen ); XX XX case 3: /* error opening screen */ XX case 2: /* error opening graphics library */ XX case 1: /* error opening intuition */ XX default: XX if (*reason) puts (reason); XX } XX exit(fault); XX } XX XXdo_capture(file) XXchar *file; XX { XX if (capture == TRUE) XX { XX capture=FALSE; XX fclose(tranr); XX emits("\nEnd File Capture\n"); XX } XX else XX { XX if (file == NULL) { XX emits("\nAscii Capture:"); XX filename(name); XX } XX else strcpy(name, file); XX if ((tranr=fopen(name,"w")) == 0) { XX capture=FALSE; XX emits("\nError Opening File\n"); XX return(FALSE); XX } XX capture=TRUE; XX } XX } XX XXdo_send(file) XXchar *file; XX { XX if (send == TRUE) XX { XX send=FALSE; XX fclose(trans); XX emits("\nFile Send Cancelled\n"); XX } XX else XX { XX if (file == NULL) { XX emits("\nAscii Send:"); XX filename(name); XX } XX else strcpy(name, file); XX if ((trans=fopen(name,"r")) == 0) { XX send=FALSE; XX emits("\nError Opening File\n"); XX return(FALSE); XX } XX send=TRUE; XX } XX } XX XXvoid setparams() XX { XX Read_Request->IOSer.io_Command = XX Write_Request->IOSer.io_Command = XX SDCMD_SETPARAMS; XX DoIO(Read_Request); DoIO(Write_Request); XX Read_Request->IOSer.io_Command = CMD_READ; XX SendIO(Read_Request); XX Write_Request->IOSer.io_Command = CMD_WRITE; XX } XX XXvoid hangup () XX { XX AbortIO(Read_Request); XX CloseDevice (Read_Request); XX Timer.tr_time.tv_secs=0L; XX Timer.tr_time.tv_micro=750000L; XX DoIO((char *) &Timer.tr_node); XX OpenDevice (SERIALNAME,NULL,Read_Request,NULL); XX setparams(); XX } XX XXvoid setserbaud(baud, redomenu) XXint baud; XXLONG redomenu; XX { XX AbortIO(Read_Request); XX Write_Request->io_Baud = Read_Request->io_Baud = baud; XX setparams(); XX p_baud = baud; XX if (redomenu) { XX ClearMenuStrip( mywindow ); /* Remove old menu */ XX InitCommItems(); /* Re-do comm menu */ XX SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ XX } XX } XX XXvoid handle_menupick(class, code) XXULONG class; XXunsigned int code; XX { XX unsigned int menunum, itemnum, subnum; XX XX if (code == MENUNULL) return; XX XX menunum = MENUNUM( code ); XX itemnum = ITEMNUM( code ); XX subnum = SUBNUM( code ); XX switch( menunum ) { XX case 0: XX switch( itemnum ) { XX case 0: XX do_capture(NULL); XX break; XX XX case 1: XX do_send(NULL); XX break; XX XX case 2: XX if (p_parity > 0) { XX emits("\nParity setting prevents this\n"); XX break; XX } XX emits("\nXmodem Receive:"); XX filename(name); XX multi_xfer(name,XMODEM_Read_File,0); XX break; XX XX case 3: XX if (p_parity > 0) { XX emits("\nParity setting prevents this\n"); XX break; XX } XX emits("\nXmodem Send:"); XX filename(name); XX multi_xfer(name,XMODEM_Send_File,1); XX break; XX XX case 4: XX server = TRUE; XX emits("\nKermit GET remote file(s):"); XX filename(name); XX multi_xfer(name,dokreceive,0); XX break; XX XX case 5: XX multi_xfer("",dokreceive,0); XX break; XX XX case 6: XX server = TRUE; XX emits("\nKermit Send local name:"); XX filename(name); XX multi_xfer(name,doksend,1); XX break; XX XX case 7: XX saybye(); XX break; XX } XX break; XX XX case 1: XX switch( itemnum ) { XX case 0: XX switch( subnum ) { XX case 0: XX setserbaud(300, FALSE); XX break; XX XX case 1: XX setserbaud(1200, FALSE); XX break; XX XX case 2: XX setserbaud(2400, FALSE); XX break; XX XX case 3: XX setserbaud(4800, FALSE); XX break; XX XX case 4: XX setserbaud(9600, FALSE); XX break; XX } XX break; XX XX case 1: XX /* Set Parity */ XX p_parity = subnum; XX break; XX XX case 2: XX /* set transfer mode */ XX p_mode = subnum; XX break; XX } XX break; XX XX case 2: XX if (!itemnum && !script_on) { XX emits("Script file name: "); XX filename(name); XX script_start(name); XX } XX if (itemnum && script_on) exit_script(); XX break; XX XX case 3: XX switch( itemnum ) { XX case 0: XX sendbreak(); XX break; XX XX case 1: XX hangup(); XX break; XX XX case 2: XX emits("\nDirectory ["); XX emits(MyDir); XX emits("]: "); XX filename(name); XX set_dir(name); XX break; XX } XX XX break; XX } /* end of switch ( menunum ) */ XX } XX SHAR_EOF if test 10048 -ne "`wc -c vt100.c`" then echo shar: error transmitting vt100.c '(should have been 10048 characters)' fi echo shar: extracting init.c sed 's/^XX//' << \SHAR_EOF > init.c XX/*************************************************************** XX * vt100 - terminal emulator - initialization XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860901 ACS - Added Parity and Word Length and support code XX * 860823 DBW - Integrated and rewrote lots of code XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX ***************************************************************/ XX XX#define MODULE_INIT 1 XX#include "vt100.h" XX XXchar line[256]; XX XXchar *InitDefaults(argc,argv) XXint argc; XXchar **argv; XX { XX FILE *fd; XX char scr[32],delim,macro[256],c0,*ptr,*ptr2; XX int i,j,k; XX long li; XX XX if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) || XX (fd=fopen("vt100.init","r")) != 0 || XX (fd=fopen("s:vt100.init","r")) != 0) { XX while (fgets(line,256,fd) != 0) { XX if ((c0 = line[0]) == '#') continue; XX if ((c0|' ') == 'e') break; XX switch (c0|' ') { XX case 'b': XX if ((line[1]|' ') == 'o') { XX /* bold color */ XX if (sscanf(line,"%s %x",scr,&i) == 2) p_bold = i; XX break; XX } XX if ((line[1]|' ') == 'u') { XX /* buffer size */ XX if (sscanf(line,"%s %d",scr,&i) == 2) p_buffer = i; XX if (p_buffer < 512) p_buffer = 512; XX break; XX } XX if ((line[1]|' ') == 'r') { XX /* break time */ XX if (sscanf(line,"%s %ld",scr,&li) == 2) p_break = li; XX break; XX } XX if ((line[1]|' ') != 'a') break; XX switch(line[2]|' ') { XX /* baud rate */ XX case 'u': XX if (sscanf(line,"%s %d",scr,&i) == 2) XX switch (i) { XX case 300: XX case 1200: XX case 2400: XX case 4800: XX case 9600: p_baud = i; break; XX } XX break; XX XX /* background */ XX case 'c': XX if (sscanf(line,"%s %x",scr,&i) == 2) p_background = i; XX break; XX } XX break; XX XX /* screen type */ XX case 's': XX if (sscanf(line,"%s %s",scr,scr) == 2) { XX if ((scr[0]|' ') == 'w') p_screen = 0; XX else p_screen = 1; XX } XX break; XX XX /* number of lines */ XX case 'l': XX if (sscanf(line,"%s %d",scr,&i) == 2) p_lines = i; XX break; XX XX /* screen depth */ XX case 'd': XX if (sscanf(line,"%s %d",scr,&i) == 2) p_depth = i; XX break; XX XX /* cursor color */ XX case 'c': XX if (sscanf(line,"%s %x",scr,&i) == 2) p_cursor = i; XX break; XX XX /* interlace type */ XX case 'i': XX if (sscanf(line,"%s %s",scr,scr) == 2) { XX if ((scr[1]|' ') == 'n') p_interlace = 1; XX else p_interlace = 0; XX } XX break; XX XX case 'f': XX switch (line[1]|' ') { XX XX /* foreground color */ XX case 'o': XX if (sscanf(line,"%s %x",scr,&i) == 2) p_foreground = i; XX break; XX XX /* function key */ XX default: XX if (sscanf(&line[1],"%d",&i) != 1) break; XX if (i < 1 || i > 10) break; XX delim = 0; XX for (j=(i==10?3:2); line[j] != 0 && XX (line[j] == ' ' || line[j] == '\t'); j++) ; XX if (line[j] == 0) { XX if (c0 == 'f') p_f[i-1] = NULL; XX else p_F[i-1] = NULL; XX break; XX } XX delim = line[j]; XX k = 0; XX macro[0] = 0; XX while (line[++j] != delim) { XX if (line[j] == 0) { XX if (fgets(line,256,fd) == 0) { XX line[0] = delim; XX line[1] = 0; XX } XX j = -1; XX continue; XX } XX if (line[j] == '^' && line[++j] != '^') XX macro[k++] = (line[j]|' ') - 0x60; XX else if (line[j] != '\n') macro[k++] = line[j]; XX macro[k] = 0; XX } XX ptr = malloc(k+1); XX if (c0 == 'f') p_f[i-1] = ptr; XX else p_F[i-1] = ptr; XX strcpy(ptr,macro); XX break; XX } XX break; XX XX case 'k': XX /*keyscript*/ XX if (sscanf(line,"%s %x",scr,&i) == 2) XX p_keyscript = i & 0x7F; XX break; XX XX case 'm': XX if (sscanf(line,"%s %s",scr,scr) == 2) { XX if ((scr[0]|' ') == 'i') p_mode = 0; XX else p_mode = 1; XX } XX break; XX XX case 'p': /*parity*/ XX if (sscanf(line,"%s %s",scr,scr) == 2) XX switch(*scr|' ') { XX case 'n': p_parity = 0; break; XX case 'm': p_parity = 1; break; XX case 's': p_parity = 2; break; XX case 'e': p_parity = 3; break; XX case 'o': p_parity = 4; break; XX } XX break; XX XX case 'v': /*volume*/ XX if (sscanf(line,"%s %d",scr,&i) == 2) XX if (i > 0) p_volume = i; XX break; XX XX case 'w': XX /*wrap*/ XX if ((line[1]|' ') == 'r') { XX if (sscanf(line,"%s %s",scr,scr) == 2) { XX if ((scr[1]|' ') == 'n') p_wrap = 1; XX else p_wrap = 0; XX } XX } XX XX /* workbench or custom colors */ XX else if ((line[1]|' ') == 'b' && XX sscanf(line,"%s %s",scr,scr) == 2) { XX if ((scr[0]|' ') == 'n') p_wbcolors = 0; XX else p_wbcolors = 1; XX } XX break; XX } XX } XX fclose(fd); XX } XX /* Now set up all the screen info as necessary */ XX if (p_interlace == 0) { XX if (p_lines > 24) p_lines = 24; XX MINY = 14; XX NewWindow.Height = (long)((p_lines*8)+8); XX } XX else { XX if (p_lines > 48) p_lines = 48; XX MINY = 16; XX NewScreen.ViewModes |= LACE; XX NewWindow.Height = (long)((p_lines*8)+10); XX } XX NewWindow.MinHeight = NewWindow.Height; XX NewWindow.MaxHeight = NewWindow.Height; XX NewWindow.TopEdge = 0L; XX MAXY = ((p_lines-1)*8) + MINY; XX top = MINY; XX bot = MAXY; XX savx = MINX; XX savy = MINY; XX if (p_screen == 1) { XX if (p_depth > 2) p_depth = 2; XX if (p_depth < 1) p_depth = 1; XX NewScreen.Depth = (long)p_depth; XX NewScreen.Height = (long)((p_lines*8)+16); XX if (p_interlace == 1) XX NewScreen.TopEdge = (long)(400 - NewScreen.Height); XX else XX NewScreen.TopEdge = (long)(208 - NewScreen.Height); XX } XX else { XX p_depth = 2L; XX NewWindow.TopEdge = 0L; XX NewWindow.Screen = NULL; XX NewWindow.Type = WBENCHSCREEN; XX } XX /* see if we exit with a startup script */ XX if ((c0|' ') == 'e') { XX ptr = &line[0]; XX while (*ptr != '\000' && *ptr != ' ' && *ptr != '\t') ptr++; XX if (*ptr == '\000') return(NULL); XX while (*ptr != '\000' && (*ptr == ' ' || *ptr == '\t')) ptr++; XX if (*ptr == '\000') return(NULL); XX ptr2 = ptr; XX while (*ptr2 != '\000' && *ptr2 != ' ' && XX *ptr2 != '\t' && *ptr2 != '\n') ptr2++; XX *ptr2 = '\000'; XX return(ptr); XX } XX else return(NULL); XX } XX XXvoid InitDevs() XX{ XXUSHORT colors[4]; XXint i; XXBYTE *b,*c; XX XXIntuitionBase = (struct IntuitionBase *) XX OpenLibrary("intuition.library", INTUITION_REV); XXif( IntuitionBase == NULL ) XX cleanup("can't open intuition",1); XX XXGfxBase = (struct GfxBase *) XX OpenLibrary("graphics.library",GRAPHICS_REV); XXif( GfxBase == NULL ) XX cleanup("can't open graphics library",2); XX XXif (p_screen == 1) { XX if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) XX cleanup("can't open screen",3); XX NewWindow.Screen = myscreen; XX } XX XXif(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL) XX cleanup("can't open window",4); XX XXmyviewport = (struct ViewPort *)ViewPortAddress(mywindow); XX XXif (p_screen != 0 && p_wbcolors == 0) { XX colors[0] = p_background; XX colors[1] = p_foreground; XX colors[2] = p_bold; XX colors[3] = p_cursor; XX if (p_depth == 1) XX LoadRGB4(myviewport,(struct ColorMap *)colors,2L); XX else XX LoadRGB4(myviewport,(struct ColorMap *)colors,4L); XX } XX XXRead_Request = (struct IOExtSer *) XX AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR); XXRead_Request->io_SerFlags = 0L; XXRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0,0); XXif(OpenDevice(SERIALNAME,NULL,Read_Request,NULL)) XX cleanup("Cant open Read device",5); XXrs_in = malloc(p_buffer+1); XXRead_Request->io_SerFlags = 0L; XXRead_Request->io_Baud = p_baud; XXRead_Request->io_ReadLen = 8L; XXRead_Request->io_WriteLen = 8L; XXRead_Request->io_CtlChar = 0x11130000L; XXRead_Request->io_RBufLen = p_buffer; XXRead_Request->io_BrkTime = p_break; XXRead_Request->IOSer.io_Command = SDCMD_SETPARAMS; XXDoIO(Read_Request); XXRead_Request->IOSer.io_Command = CMD_READ; XXRead_Request->IOSer.io_Length = 1; XXRead_Request->IOSer.io_Data = (APTR) &rs_in[0]; XX XXWrite_Request = (struct IOExtSer *) XX AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR); XXb = (BYTE *)Read_Request; XXc = (BYTE *)Write_Request; XXfor (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++; XXWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0,0); XXWrite_Request->IOSer.io_Command = CMD_WRITE; XXWrite_Request->IOSer.io_Length = 1; XXWrite_Request->IOSer.io_Data = (APTR) &rs_out[0]; XX XXTimer_Port = CreatePort("Timer Port",0); XXScript_Timer_Port = CreatePort("Timer Port",0); XX XXif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) || XX OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) XX cleanup("can't open timer device",7); XX XXTimer.tr_node.io_Message.mn_ReplyPort = Timer_Port; XXTimer.tr_node.io_Command = TR_ADDREQUEST; XXTimer.tr_node.io_Flags = 0; XXTimer.tr_node.io_Error = 0; XX XXScript_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port; XXScript_Timer.tr_node.io_Command = TR_ADDREQUEST; XXScript_Timer.tr_node.io_Flags = 0; XXScript_Timer.tr_node.io_Error = 0; XX XXBeepWave = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR)); XXif (BeepWave != 0) BeepWave[0] = 100; XX XXAudio_Port = CreatePort("Audio Port",0); XX XXAudio_Request.ioa_Request.io_Message.mn_ReplyPort = Audio_Port; XXAudio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85; XXAudio_Request.ioa_Data = Audio_AllocMap; XXAudio_Request.ioa_Length = (ULONG) sizeof(Audio_AllocMap); XX XXif (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL)) XX cleanup("can't open audio device",8); XX XXAudio_Request.ioa_Request.io_Command = CMD_WRITE; XXAudio_Request.ioa_Request.io_Flags = ADIOF_PERVOL; XXAudio_Request.ioa_Data = BeepWave; XXAudio_Request.ioa_Length = BEEPSIZE; XXAudio_Request.ioa_Period = COLORCLOCK / (BEEPSIZE * BEEPFREQ); XXAudio_Request.ioa_Volume = p_volume; XXAudio_Request.ioa_Cycles = 100; XX} XX XX/*****************************************************************/ XX/* The following function initializes the structure arrays */ XX/* needed to provide the File menu topic. */ XX/*****************************************************************/ XXvoid InitFileItems() XX{ XXint n,nplus1; XX XX/* initialize each menu item and IntuiText with loop */ XXfor( n=0; n<FILEMAX; n++ ) XX { XX nplus1 = n + 1; XX FileItem[n].NextItem = &FileItem[nplus1]; XX FileItem[n].LeftEdge = 0; XX FileItem[n].TopEdge = 10 * n; XX FileItem[n].Width = 120; XX FileItem[n].Height = 10; XX FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP; XX FileItem[n].MutualExclude = 0; XX FileItem[n].ItemFill = (APTR)&FileText[n]; XX FileItem[n].SelectFill = NULL; XX FileItem[n].Command = 0; XX FileItem[n].SubItem = NULL; XX FileItem[n].NextSelect = 0; XX XX FileText[n].FrontPen = 0; XX FileText[n].BackPen = 1; XX FileText[n].DrawMode = JAM2;/* render in fore and background */ XX FileText[n].LeftEdge = 0; XX FileText[n].TopEdge = 1; XX FileText[n].ITextFont = NULL; XX FileText[n].NextText = NULL; XX } XXFileItem[FILEMAX-1].NextItem = NULL; XX XX/* initialize text for specific menu items */ XX XXFileText[0].IText = (UBYTE *)"Ascii Capture"; XXFileText[1].IText = (UBYTE *)"Ascii Send"; XXFileText[2].IText = (UBYTE *)"Xmodem Receive"; XXFileText[3].IText = (UBYTE *)"Xmodem Send"; XXFileText[4].IText = (UBYTE *)"Kermit Get"; XXFileText[5].IText = (UBYTE *)"Kermit Receive"; XXFileText[6].IText = (UBYTE *)"Kermit Send"; XXFileText[7].IText = (UBYTE *)"Kermit BYE"; XX} XX XX/****************************************************************** XX/* Main Comm menu XX/* set up for Baud & Parity submenus XX/******************************************************************/ XXvoid InitCommItems() XX{ XXint n,nplus1; XX XX/* initialize each menu item and IntuiText with loop */ XXfor( n=0; n<COMMAX; n++ ) XX { XX nplus1 = n + 1; XX CommItem[n].NextItem = &CommItem[nplus1]; XX CommItem[n].LeftEdge = 0; XX CommItem[n].TopEdge = 10 * n; XX CommItem[n].Width = 88; XX CommItem[n].Height = 10; XX CommItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ; XX CommItem[n].MutualExclude = 0; XX CommItem[n].ItemFill = (APTR)&CommText[n]; XX CommItem[n].SelectFill = NULL; XX CommItem[n].Command = 0; XX CommItem[n].NextSelect = 0; XX XX CommText[n].FrontPen = 0; XX CommText[n].BackPen = 1; XX CommText[n].DrawMode = JAM2; XX CommText[n].LeftEdge = 0; XX CommText[n].TopEdge = 1; XX CommText[n].ITextFont = NULL; XX CommText[n].NextText = NULL; XX } XXCommItem[COMMAX-1].NextItem = NULL; XX XXCommText[0].IText = (UBYTE *)"Baud Rate"; XXCommText[1].IText = (UBYTE *)"Parity "; XXCommText[2].IText = (UBYTE *)"Xfer Mode"; XXCommItem[0].SubItem = RSItem; XXCommItem[1].SubItem = ParItem; XXCommItem[2].SubItem = XFItem; XX XX/*****************************************************************/ XX/* The following initializes the structure arrays */ XX/* needed to provide the BaudRate Submenu topic. */ XX/*****************************************************************/ XX XXfor( n=0; n<RSMAX; n++ ) XX { XX nplus1 = n + 1; XX RSItem[n].NextItem = &RSItem[nplus1]; XX RSItem[n].LeftEdge = 75; XX RSItem[n].TopEdge = 10 * n; XX RSItem[n].Width = 56; XX RSItem[n].Height = 10; XX RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT; XX RSItem[n].MutualExclude = (~(1 << n)); XX RSItem[n].ItemFill = (APTR)&RSText[n]; XX RSItem[n].SelectFill = NULL; XX RSItem[n].Command = 0; XX RSItem[n].SubItem = NULL; XX RSItem[n].NextSelect = 0; XX XX RSText[n].FrontPen = 0; XX RSText[n].BackPen = 1; XX RSText[n].DrawMode = JAM2; /* render in fore and background */ XX RSText[n].LeftEdge = 0; XX RSText[n].TopEdge = 1; XX RSText[n].ITextFont = NULL; XX RSText[n].NextText = NULL; XX } XXRSItem[RSMAX-1].NextItem = NULL; XX XX/* select baud item chekced */ XXswitch (p_baud) { XX case 300: n = 0; break; XX case 1200: n = 1; break; XX case 2400: n = 2; break; XX case 4800: n = 3; break; XX case 9600: n = 4; break; XX default: n = 2; p_baud = 2400; XX } XXRSItem[n].Flags |= CHECKED; XX XX/* initialize text for specific menu items */ XXRSText[0].IText = (UBYTE *)" 300"; XXRSText[1].IText = (UBYTE *)" 1200"; XXRSText[2].IText = (UBYTE *)" 2400"; XXRSText[3].IText = (UBYTE *)" 4800"; XXRSText[4].IText = (UBYTE *)" 9600"; XX XX/*****************************************************************/ XX/* The following initializes the structure arrays */ XX/* needed to provide the Parity Submenu topic. */ XX/*****************************************************************/ XX XXfor( n=0; n<PARMAX; n++ ) XX { XX nplus1 = n + 1; XX ParItem[n].NextItem = &ParItem[nplus1]; XX ParItem[n].LeftEdge = 75; XX ParItem[n].TopEdge = 10 * n; XX ParItem[n].Width = 56; XX ParItem[n].Height = 10; XX ParItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT; XX ParItem[n].MutualExclude = (~(1 << n)); XX ParItem[n].ItemFill = (APTR)&ParText[n]; XX ParItem[n].SelectFill = NULL; XX ParItem[n].Command = 0; XX ParItem[n].SubItem = NULL; XX ParItem[n].NextSelect = 0; XX XX ParText[n].FrontPen = 0; XX ParText[n].BackPen = 1; XX ParText[n].DrawMode = JAM2;/* render in fore and background */ XX ParText[n].LeftEdge = 0; XX ParText[n].TopEdge = 1; XX ParText[n].ITextFont = NULL; XX ParText[n].NextText = NULL; XX } XXParItem[PARMAX-1].NextItem = NULL; XX XX/* select parity item chekced */ XXParItem[p_parity].Flags |= CHECKED; XX XX/* initialize text for specific menu items */ XXParText[0].IText = (UBYTE *)" None "; XXParText[1].IText = (UBYTE *)" Mark "; XXParText[2].IText = (UBYTE *)" Space"; XXParText[3].IText = (UBYTE *)" Even "; XXParText[4].IText = (UBYTE *)" Odd "; XX XX/*****************************************************************/ XX/* The following initializes the structure arrays */ XX/* needed to provide the Transfer Mode menu topic. */ XX/*****************************************************************/ XX XX/* initialize each menu item and IntuiText with loop */ XXfor( n=0; n<XFMAX; n++ ) XX { XX nplus1 = n + 1; XX XFItem[n].NextItem = &XFItem[nplus1]; XX XFItem[n].LeftEdge = 75; XX XFItem[n].TopEdge = 10 * n; XX XFItem[n].Width = 80; XX XFItem[n].Height = 10; XX XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT; XX XFItem[n].MutualExclude = (~(1 << n)); XX XFItem[n].ItemFill = (APTR)&XFText[n]; XX XFItem[n].SelectFill = NULL; XX XFItem[n].Command = 0; XX XFItem[n].SubItem = NULL; XX XFItem[n].NextSelect = 0; XX XX XFText[n].FrontPen = 0; XX XFText[n].BackPen = 1; XX XFText[n].DrawMode = JAM2; XX XFText[n].LeftEdge = 0; XX XFText[n].TopEdge = 1; XX XFText[n].ITextFont = NULL; XX XFText[n].NextText = NULL; XX } XXXFItem[XFMAX-1].NextItem = NULL; XX/* mode checked */ XXXFItem[p_mode].Flags |= CHECKED; XX XX/* initialize text for specific menu items */ XXXFText[0].IText = (UBYTE *)" image"; XXXFText[1].IText = (UBYTE *)" CR LF"; XX XX} /* end of InitCommItems() */ XX XX XX/*****************************************************************/ XX/* The following function initializes the structure arrays */ XX/* needed to provide the Script menu topic. */ XX/*****************************************************************/ XXvoid InitScriptItems() XX{ XXint n,nplus1; XX XX/* initialize each menu item and IntuiText with loop */ XXfor( n=0; n<SCRIPTMAX; n++ ) XX { XX nplus1 = n + 1; XX ScriptItem[n].NextItem = &ScriptItem[nplus1]; XX ScriptItem[n].LeftEdge = 0; XX ScriptItem[n].TopEdge = 10 * n; XX ScriptItem[n].Width = 128; XX ScriptItem[n].Height = 10; XX ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP; XX ScriptItem[n].MutualExclude = 0; XX ScriptItem[n].ItemFill = (APTR)&ScriptText[n]; XX ScriptItem[n].SelectFill = NULL; XX ScriptItem[n].Command = 0; XX ScriptItem[n].SubItem = NULL; XX ScriptItem[n].NextSelect = 0; XX XX ScriptText[n].FrontPen = 0; XX ScriptText[n].BackPen = 1; XX ScriptText[n].DrawMode = JAM2;/* render in fore and background */ XX ScriptText[n].LeftEdge = 0; XX ScriptText[n].TopEdge = 1; XX ScriptText[n].ITextFont = NULL; XX ScriptText[n].NextText = NULL; XX } XXScriptItem[SCRIPTMAX-1].NextItem = NULL; XX XX/* initialize text for specific menu items */ XXScriptText[0].IText = (UBYTE *)"Execute file"; XXScriptText[1].IText = (UBYTE *)"Abort Execution"; XX} XX XX/*****************************************************************/ XX/* The following function initializes the structure arrays */ XX/* needed to provide the Util menu topic. */ XX/*****************************************************************/ XXvoid InitUtilItems() XX{ XXint n,nplus1; XX XX/* initialize each menu item and IntuiText with loop */ XXfor( n=0; n<UTILMAX; n++ ) XX { XX nplus1 = n + 1; XX UtilItem[n].NextItem = &UtilItem[nplus1]; XX UtilItem[n].LeftEdge = 0; XX UtilItem[n].TopEdge = 10 * n; XX UtilItem[n].Width = 88; XX UtilItem[n].Height = 10; XX UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP; XX UtilItem[n].MutualExclude = 0; XX UtilItem[n].ItemFill = (APTR)&UtilText[n]; XX UtilItem[n].SelectFill = NULL; XX UtilItem[n].Command = 0; XX UtilItem[n].SubItem = NULL; XX UtilItem[n].NextSelect = 0; XX XX UtilText[n].FrontPen = 0; XX UtilText[n].BackPen = 1; XX UtilText[n].DrawMode = JAM2;/* render in fore and background */ XX UtilText[n].LeftEdge = 0; XX UtilText[n].TopEdge = 1; XX UtilText[n].ITextFont = NULL; XX UtilText[n].NextText = NULL; XX } XX XX/* until we know how to toggle DTR */ XX/* UtilItem[1].Flags ^= ITEMENABLED; */ XX XXUtilItem[UTILMAX-1].NextItem = NULL; XX XX/* initialize text for specific menu items */ XXUtilText[0].IText = (UBYTE *)"Send Break"; XXUtilText[1].IText = (UBYTE *)"Hang Up"; XXUtilText[2].IText = (UBYTE *)"Change Dir"; XX} XX XX/****************************************************************/ XX/* The following function inits the Menu structure array with */ XX/* appropriate values for our simple menu. Review the manual */ XX/* if you need to know what each value means. */ XX/****************************************************************/ XXvoid InitMenu() XX{ XXmenu[0].NextMenu = &menu[1]; XXmenu[0].LeftEdge = 5; XXmenu[0].TopEdge = 0; XXmenu[0].Width = 40; XXmenu[0].Height = 10; XXmenu[0].Flags = MENUENABLED; XXmenu[0].MenuName = "File"; /* text for menu-bar display */ XXmenu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */ XX XXmenu[1].NextMenu = &menu[2]; XXmenu[1].LeftEdge = 55; XXmenu[1].TopEdge = 0; XXmenu[1].Width = 88; XXmenu[1].Height = 10; XXmenu[1].Flags = MENUENABLED; XXmenu[1].MenuName = "Comm Setup"; /* text for menu-bar display */ XXmenu[1].FirstItem = &CommItem[0]; /* pointer to first item in list */ XX XXmenu[2].NextMenu = &menu[3]; XXmenu[2].LeftEdge = 153; XXmenu[2].TopEdge = 0; XXmenu[2].Width = 56; XXmenu[2].Height = 10; XXmenu[2].Flags = MENUENABLED; XXmenu[2].MenuName = "Script"; /* text for menu-bar display */ XXmenu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/ XX XXmenu[3].NextMenu = NULL; XXmenu[3].LeftEdge = 225; XXmenu[3].TopEdge = 0; XXmenu[3].Width = 64; XXmenu[3].Height = 10; XXmenu[3].Flags = MENUENABLED; XXmenu[3].MenuName = "Utility"; /* text for menu-bar display */ XXmenu[3].FirstItem = &UtilItem[0]; /* pointer to first item in list*/ XX} XX SHAR_EOF if test 20847 -ne "`wc -c init.c`" then echo shar: error transmitting init.c '(should have been 20847 characters)' fi # End of shell archive exit 0
wecker@cookie.dec.com.UUCP (11/23/86)
# This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # script.c # remote.c # window.c # expand.c # kermit.c # xmodem.c # This archive created: Sun Nov 2 15:25:36 1986 echo shar: extracting script.c sed 's/^XX//' << \SHAR_EOF > script.c XX/************************************************************* XX * vt100 terminal emulator - Script file support XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860901 ACS - Added BAUD, PARITY and WORD commands & handling XX * 860823 DBW - Integrated and rewrote lots of code XX * 860815 Steve Drew: Initial version written of SCRIPT.C XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX *************************************************************/ XX XX#define MODULE_SCRIPT 1 XX XX#include "vt100.h" XX XXstruct COMMAND { XX void (*func)(); XX char *cname; XX }; XX XXstruct LABEL { XX struct LABEL *next; XX char *name; XX long pos; XX }; XX XXextern long atol(); XX XX/**************** globals needed ******************/ XX XXchar on_string[20]; /* string to match on for on cmd */ XXchar wait_string[20]; /* string to match of for wait cmd */ XXchar golabel[20]; /* label we are looking for in goto */ XXchar on_cmd[20]; /* command to execute when on matchs*/ XXint onsize; /* size of on_string */ XXint waitsize; /* size of wait_string */ XXint onpos; /* position in on string for search */ XXint waitpos; /* pos in wait_string for search */ XXint on_match; /* flag set while doing on_cmd */ XXFILE *sf; /* file pointer for script file */ XXstruct LABEL *lbase = NULL; /* will point to first label */ XXstruct LABEL *labels; /* current label pointer */ XX XXvoid cmd_send(), cmd_wait(), cmd_on(), cmd_goto(), cmd_delay(), XX cmd_done(), cmd_ks(), cmd_kg(), cmd_kr(), cmd_xs(), cmd_xr(), XX cmd_cap(), cmd_as(), cmd_null(), cmd_kb(), cmd_cd(), cmd_sb(), XX cmd_baud(), cmd_word(), cmd_parity(), cmd_bt(), cmd_tm(); XX XXchar *next_wrd(), *tostring(); XX XX XX/********************** command table *******************************/ XX XXstatic struct COMMAND commands[]= { XX cmd_send, "send", /* send string to host */ XX cmd_wait, "wait", /* wait for a string from host */ XX cmd_on, "on", /* on a 'string' do a cmd */ XX cmd_goto, "goto", /* goto label */ XX cmd_delay, "delay", /* delay amount of seconds */ XX cmd_done, "exit", /* exit script file */ XX cmd_ks, "ks", /* kermit send file */ XX cmd_kr, "kr", /* kermit receive file */ XX cmd_kg, "kg", /* kermit get file */ XX cmd_kb, "kb", /* kermit bye (for server) */ XX cmd_xs, "xs", /* xmodem send file */ XX cmd_xr, "xr", /* xmodem receive file */ XX cmd_cap, "capture", /* ascii capture on/off */ XX cmd_as, "ascii_send", /* ascii send */ XX cmd_cd, "cd", /* change directory */ XX cmd_sb, "sb", /* Send a break */ XX cmd_baud, "baud", /* Set Baud Rate */ XX cmd_parity, "parity", /* Set Parity */ XX cmd_bt, "bt", /* Set Break Time */ XX cmd_tm, "tm", /* Set KERMIT transfer mode */ XX cmd_null, NULL /* mark the end of the list */ XX }; XX XX/********************************************************************/ XX/* checks char to see if match with on string or wait_string */ XX/* if on string match oncmd gets executed imediately, */ XX/* if wait_string match script_wait is set. */ XX/********************************************************************/ XX XXchk_script(c) XXchar c; XX { XX if (on_string[0] != '\0') { XX if (on_string[onpos] == c) { XX onpos++; XX if (onpos == onsize) { XX on_match = TRUE; XX do_script_cmd(ONCOMMAND); XX on_match = FALSE; XX return(0); XX } XX } XX else onpos = 0; XX } XX if (wait_string[0] != '\0') { XX if (wait_string[waitpos] != c) { XX waitpos = 0; XX return(0); XX } XX waitpos++; XX if (waitpos != waitsize) return(0); XX wait_string[0] = '\0'; XX script_wait = FALSE; XX } XX } XX XXscript_start(file) XXchar *file; XX { XX if (strlen(file) == 0 || *file == '#') return(0); XX if ((sf = fopen(file, "r")) == NULL) { XX emits("Can't open script file\n"); XX return(0); XX } XX script_on = TRUE; XX script_wait = FALSE; XX wait_string[0] = '\0'; XX on_string[0] = '\0'; XX on_match = FALSE; XX lbase = NULL; XX } XX XX/* return pointer to next word. set l to size of the word */ XX XXchar *next_wrd(s,l) XXchar *s; XXint *l; XX { XX char *p; XX while(*s && (*s == ' ' || *s == 9)) s++; XX p = s; XX while(*s && (*s != ' ' && *s != 9)) s++; XX *l = s-p; XX return(p); XX } XX XXexe_cmd(p,l) XXchar *p; XXint l; XX { XX int i; XX XX /* downcase the command */ XX for (i=0; i<l; i++) p[i] |= ' '; XX XX /* now search for it */ XX for (i=0; commands[i].func != cmd_null; ++i) XX if (strncmp(p, commands[i].cname, l) == 0) { XX (*commands[i].func)(next_wrd(p+l, &l)); XX return(TRUE); XX } XX emits ("\nScript - unknown command: "); XX emits (p); XX emits ("\n"); XX return(FALSE); XX } XX XXstruct LABEL *find_label(lname) XXchar *lname; XX { XX struct LABEL *label; XX XX label = lbase; XX while(label != NULL) { XX if (strcmp(label->name, lname) == 0) return (label); XX label = label->next; XX } XX return(NULL); XX } XX XXdo_script_cmd(stat) XXint stat; XX { XX int len,l; XX char line[256]; XX char *p; XX XX /* if ON command is matched and we were */ XX /* doing a DELAY then abort the delay timer,*/ XX /* except if on_cmd was just a SEND. */ XX if (stat == ONCOMMAND) { XX strcpy(line,on_cmd); XX p = next_wrd(line,&l); XX if (*p != 'S' && script_wait == WAIT_TIMER) { XX AbortIO((char *) &Script_Timer); XX Wait (1L << Script_Timer_Port->mp_SigBit); XX XX /* script will proceed after on command */ XX script_wait = FALSE; XX } XX exe_cmd(p,l); XX return(0); XX } XX script_wait = FALSE; XX while(fgets(line,256,sf) != NULL) { XX len = strlen(line); XX line[--len] = '\0'; XX p = next_wrd(&line[0], &l); XX if (*(p + l - 1) == ':') { /* its a label */ XX *(p + l - 1) = '\0'; XX if (find_label(p) == NULL) { /* it's a new label */ XX if (lbase == NULL) { /* it's the first label */ XX labels = lbase = (struct LABEL *) XX malloc(sizeof (struct LABEL)); XX } XX else { XX labels->next = (struct LABEL *) XX malloc(sizeof (struct LABEL)); XX labels = labels->next; XX } XX labels->pos = ftell(sf); XX labels->name = malloc(l); XX labels->next = NULL; XX strcpy(labels->name, p); XX if (stat == GOTOLABEL && strcmp(p, golabel) == 0) XX stat = NEXTCOMMAND; XX } XX p = next_wrd(p+l+1, &l); XX } /* end of it's a label */ XX if (stat == GOTOLABEL || *p == '#') continue; XX if (*p) exe_cmd(p,l); XX return(0); XX } /* end of while */ XX if (stat == GOTOLABEL) { XX emits("\nScript - label not found: "); XX emits(golabel); XX emits("\n"); XX } XX exit_script(); XX } XX XXexit_script() XX { XX if (script_wait == WAIT_TIMER) /* timer not done yet */ XX AbortIO((char *) &Script_Timer); /* so abort it */ XX emits("\nScript - terminated\n"); XX script_on = FALSE; XX script_wait = TRUE; XX fclose(sf); XX } XX XX/* remove quotes terminate string & return pointer to start */ XX XXchar *tostring(ptr) XXchar *ptr; XX { XX char *s1,*s2; XX XX s1 = ptr; XX if (*ptr == '"') { XX while(*ptr++ && *ptr != '"') ; XX if (*ptr == '"') { XX *ptr = '\0'; XX ptr = s2 = ++s1; XX while(*s2) { XX if (*s2 != '^') *s1++ = *s2; XX else if (*(s2+1) == '^') *s1++ = *s2++; XX else *s1++ = ((*++s2)|' ')-96; XX s2++; XX } XX *s1 = '\0'; XX return(ptr); XX } XX } XX if (*s1 == '^') { XX *s1 = (*(s1+1)|' ')-96; XX *(s1+1) = '\0'; XX return(s1); XX } XX *(s1+1) = '\0'; XX return(s1); XX } XX XX/***************************** SCRIPT COMMANDS ********************/ XX XXvoid cmd_goto(lname) XXchar *lname; XX { XX struct LABEL *label; XX /* if on_cmd was a goto kill wait state */ XX if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; } XX if ((label = find_label(lname)) == NULL) { /* is it forward */ XX strcpy(golabel,lname); XX do_script_cmd(GOTOLABEL); XX } XX else { XX fseek(sf,(long)(label->pos),0); XX } XX } XX XXvoid cmd_send(str) XXchar *str; XX { XX sendstring(tostring(str)); XX } XX XXvoid cmd_wait(str) XXchar *str; XX { XX str = tostring(str); XX *(str+20) = '\0'; /* 20 characters max */ XX strcpy(wait_string, str); XX waitsize = strlen(str); XX script_wait = WAIT_STRING; XX } XX XXvoid cmd_on(str) XXchar *str; XX { XX char *p; XX XX p = tostring(str); XX strcpy(on_string, p); XX onsize = strlen(p); XX *(p+onsize+2+20) = '\0'; /* 20 characters max */ XX strcpy(on_cmd,p+onsize+2); XX } XX XXvoid cmd_delay(seconds) XXchar *seconds; XX { XX script_wait = WAIT_TIMER; XX Script_Timer.tr_time.tv_secs = atoi(seconds); XX Script_Timer.tr_time.tv_micro = 0; XX SendIO((char *) &Script_Timer.tr_node); XX } XX XXvoid cmd_done(option) XXchar *option; XX { XX char *p; XX int l; XX XX if (*option) { XX p = next_wrd(option,&l); XX *(p+l) = '\000'; XX if (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0) XX cleanup("Exit vt100 from script",0); XX exit_script(); XX script_start(p); XX } XX else exit_script(); XX } XX XXvoid cmd_ks(file) XXchar *file; XX { XX multi_xfer(file, doksend, 1); XX } XX XXvoid cmd_kr(file) XXchar *file; XX { XX multi_xfer(file, dokreceive, 0); XX } XX XXvoid cmd_kg(file) XXchar *file; XX { XX server = TRUE; XX multi_xfer(file, dokreceive, 0); XX } XX XXvoid cmd_kb() XX { XX saybye(); XX } XX XXvoid cmd_xs(file) XXchar *file; XX { XX multi_xfer(file, XMODEM_Send_File, 1); XX } XX XXvoid cmd_xr(file) XXchar *file; XX { XX multi_xfer(file, XMODEM_Read_File, 1); XX } XX XXvoid cmd_cap(file) XXchar *file; XX { XX do_capture(file); XX } XX XXvoid cmd_as(file) XXchar *file; XX { XX do_send(file); XX } XX XXvoid cmd_cd(name) XXchar *name; XX { XX set_dir(name); XX } XX XXvoid cmd_sb(str) XXchar *str; XX { XX sendbreak(); XX } XX XXvoid cmd_baud(rate) XXchar *rate; XX { XX int i = atoi(rate); XX XX switch( i ) XX { XX case 300: XX case 1200: XX case 2400: XX case 4800: XX case 9600: XX setserbaud(i, TRUE); XX break; XX XX default: XX emits("\nScript - invalid baud rate: "); XX emits(rate); XX emits("\n"); XX break; XX } XX } XX XXvoid cmd_parity(par) XXchar *par; XX { XX int i; XX XX switch( *par|' ' ) XX { XX case 'n': i = 0; break; XX case 'm': i = 1; break; XX case 's': i = 2; break; XX case 'e': i = 3; break; XX case 'o': i = 4; break; XX XX default: XX emits("\nScript - invalid parity: "); XX emits(par); XX emits("\n"); XX return; XX } XX p_parity = i; XX ClearMenuStrip( mywindow ); /* Remove old menu */ XX InitCommItems(); /* Re-do comm menu */ XX SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ XX } XX XXvoid cmd_bt(breaklength) XXchar *breaklength; XX { XX long i = atol(breaklength); XX AbortIO(Read_Request); XX Read_Request->io_BrkTime = Write_Request->io_BrkTime = i; XX setparams(); XX } XX XXvoid cmd_tm(tmode) XXchar *tmode; XX { XX switch (*tmode|' ') { XX case 'i': XX p_mode = 0; XX break; XX XX case 'c': XX p_mode = 1; XX break; XX XX default: XX emits("\nScript - invalid transfer mode: "); XX emits(tmode); XX emits("\n"); XX return; XX } XX XX ClearMenuStrip(mywindow); XX InitCommItems(); /* Re-do comm menu */ XX SetMenuStrip(mywindow,&menu[0]); XX } XX XXvoid cmd_null(file) XXchar *file; XX { XX } SHAR_EOF if test 11718 -ne "`wc -c script.c`" then echo shar: error transmitting script.c '(should have been 11718 characters)' fi echo shar: extracting remote.c sed 's/^XX//' << \SHAR_EOF > remote.c XX/**************************************************** XX * vt100 emulator - remote character interpretation XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860823 DBW - Integrated and rewrote lots of code XX * v2.0 860803 DRB - Rewrote the control sequence parser XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX ****************************************************/ XX XX#define MODULE_REMOTE 1 XX#include "vt100.h" XX XXstatic int p[10]; XXstatic int numpar; XXstatic char escseq[40]; XX XXvoid doctrl(); XXvoid doesc(); /* force correct denomination */ XXvoid doerase(); XXvoid doindex(); XX XX/************************************************ XX* function to handle remote characters XX*************************************************/ XXvoid doremote(c) XXchar c; XX { XX if (c == 24) { inesc = 0; inctrl = 0; return; } XX if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; } XX if (inctrl >= 0 && c >= ' ') { doctrl(c); return; } XX if (c == 10 || c == 11 || c == 12) { XX if (nlmode) doindex('E'); else doindex('D'); XX return; XX } XX if (c == 13) { XX if (!nlmode) emit(c); XX return; XX } XX if (c == 15) { alt = 0; return; } XX if (c == 14) { alt = 1; return; } XX if (a[alt] && c > 94 && c < 127) { doalt(c); return; } XX emit(c); XX } XX XXvoid doesc(c) XXchar c; XX{ XX if (inesc < 0) { inesc = 0; return; } XX if (c == 27 || c == 24) { inesc = -1; return; } XX if (c < ' ' || c == 127) return; /* Ignore control chars */ XX XX /* Collect intermediates */ XX if (c < '0') {escseq[inesc++] = c; return; } XX XX /* by process of elimination, we have a final character. XX Put it in the buffer, and dispatch on the first character XX in the buffer */ XX XX escseq[inesc] = c; XX inesc = -1; /* No longer collecting a sequence */ XX switch (escseq[0]) /* Dispatch on the first received */ XX { XX case '[': /* Control sequence introducer */ XX numpar = 0; /* No parameters yet */ XX private = 0; /* Not a private sequence (yet?) */ XX badseq = 0; /* Good until proven bad */ XX p[0] = p[1] = 0; /* But default the first parameter */ XX inctrl = 0; /* We are in a control sequence */ XX return; /* All done for now ... */ XX XX case 'D': case 'E': case 'M': /* Some kind of index */ XX doindex (c); /* Do the index */ XX return; /* Return */ XX XX case '7': /* Save cursor position */ XX savx = x; savy = y; savmode = curmode; savalt = alt; XX sa[0] = a[0]; sa[1] = a[1]; XX return; XX XX case '8': /* Restore cursor position */ XX x = savx; y = savy; alt = savalt; curmode = savmode; XX a[0] = sa[0]; a[1] = sa[1]; XX return; XX XX case 'c': /* Reset */ XX top = MINY; bot = MAXY; savx = MINX; savy = MINY; XX curmode = FS_NORMAL; keyapp = FALSE; XX inesc = -1; XX a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0; XX emit(12); XX return; XX XX case '(': /* Change character set */ XX if (c == '0' || c == '2') a[0] = 1; else a[0] = 0; XX return; XX XX case ')': /* Change the other character set */ XX if (c == '0' || c == '2') a[1] = 1; else a[1] = 0; XX return; XX XX case '=': /* set keypad application mode */ XX keyapp = TRUE; XX return; XX XX case '>': /* reset application mode */ XX keyapp = FALSE; XX return; XX XX case 'Z': XX sendchar(27); sendstring("[?1;7c"); return; XX XX /* If we didn't match anything, we can just return, happy in the XX knowledge that we've at least eaten the whole sequence */ XX XX } /* End of switch */ XX return; XX} XX XXvoid doctrl(c) XXchar c; XX{ XX int i; XX XX if (c == 27 || c == 24) { inctrl = -1; return; } XX if (c < ' ' || c == 127) return; /* Ignore control chars */ XX XX /* First, look for some parameter characters. If the very first XX parameter character isn't a digit, then we have a XX private sequence */ XX XX if (c >= '0' && c < '@') XX { XX /* can't have parameters after intermediates */ XX if (inctrl > 0) {badseq++ ; return; } XX switch (c) XX { XX case '0': case '1': case '2': case '3': case '4': XX case '5': case '6': case '7': case '8': case '9': XX p[numpar] = p[numpar] * 10 + (c - '0'); XX return; XX XX case ';': XX p[++numpar] = 0; /* Start a new parameter */ XX return; XX XX case '<': case '=': case '>': case '?': /* Can only mean private */ XX XX /* Only allowed BEFORE parameters */ XX if (inctrl == 0) private = c; XX return; XX XX /* if we come here, it's a bad sequence */ XX } XX badseq++; /* Flag the bad sequence */ XX } XX XX if (c < '0') /* Intermediate character */ XX { XX escseq[inctrl++] = c; /* Save the intermediate character */ XX return; XX } XX XX /* if we get here, we have the final character. Put it in the XX escape sequence buffer, then dispatch the control sequence */ XX XX numpar++; /* Reflect the real number of parameters */ XX escseq[inctrl++] = c; /* Store the final character */ XX escseq[inctrl] = '\000'; /* Tie off the buffer */ XX inctrl = -1; /* End of the control sequence scan */ XX XX /* Don't know how to do most private sequences right now, XX so just punt them */ XX XX if ((private != 0 && private != '?') || badseq != 0) return; XX if (private == '?' && escseq[0] != 'h' && XX escseq[0] != 'l') return; XX XX switch (escseq[0]) /* Dispatch on first intermediate or final */ XX { XX case 'A': if (p[0]<=0) p[0] = 1; XX y -= 8*p[0]; if (y<top) y = top; return; XX case 'B': if (p[0]<=0) p[0] = 1; XX y += 8*p[0]; if (y>bot) y = bot; return; XX case 'C': if (p[0]<=0) p[0] = 1; XX x += 8*p[0]; if (x>MAXX) x = MAXX; return; XX case 'D': if (p[0]<=0) p[0] = 1; XX x -= 8*p[0]; if (x<MINX) x = MINX; return; XX XX case 'H': case 'f': /* Cursor position */ XX if (p[0] <= 0) p[0] = 1; XX if (p[1] <= 0) p[1] = 1; XX y = (--p[0]*8)+MINY; x = (--p[1]*8)+MINX; XX if (y > MAXY) y = MAXY; XX if (x > MAXX) x = MAXX; XX if (y < MINY) y = MINY; XX if (x < MINX) x = MINX; XX return; XX XX case 'L': /* ANSI insert line */ XX case 'M': /* ANSI delete line */ XX if (p[0] <= 0) p[0] = 1; XX ScrollRaster(mywindow->RPort,0L, XX (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]), XX (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1); XX return; XX XX case 'r': /* Set scroll region */ XX if (p[0] <= 0) p[0] = 1; XX if (p[1] <= 0) p[1] = p_lines; XX top = (--p[0]*8)+MINY; bot = (--p[1]*8)+MINY; XX if (top < MINY) top = MINY; XX if (bot > MAXY) bot = MAXY; XX if (top > bot) { top = MINY; bot = MAXY; } XX x = MINX; y = MINY; XX return; XX XX case 'm': /* Set graphic rendition */ XX for (i=0;i<numpar;i++) { XX if (p[i] < 0) p[i] = 0; XX switch (p[i]) { XX case 0: XX curmode = FS_NORMAL; XX break; XX XX case 1: XX curmode |= FSF_BOLD; XX break; XX XX case 4: XX curmode |= FSF_UNDERLINED; XX break; XX XX case 5: XX curmode |= FSF_ITALIC; XX break; XX XX default: XX curmode |= FSF_REVERSE; XX break; XX } XX } XX return; XX XX case 'K': /* Erase in line */ XX doerase(); XX return; XX XX case 'J': /* Erase in display */ XX if (p[0] < 0) p[0] = 0; XX SetAPen(mywindow->RPort,0L); XX if (p[0] == 0) { XX if (y < MAXY) RectFill(mywindow->RPort, XX (long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1)); XX } XX else if (p[0] == 1) { XX if (y > MINY) RectFill(mywindow->RPort, XX (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7)); XX } XX else RectFill(mywindow->RPort, XX (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1)); XX SetAPen(mywindow->RPort,1L); XX doerase(); return; XX XX case 'h': /* Set parameter */ XX if (private == 0 && p[0] == 20) nlmode = 1; XX else if (private == '?' && p[0] == 7) p_wrap = 1; XX return; XX XX case 'l': /* Reset parameter */ XX if (private == 0 && p[0] == 20) nlmode = 0; XX else if (private == '?' && p[0] == 7) p_wrap = 0; XX return; XX XX case 'x': XX sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return; XX XX case 'n': XX if (p[0] == 6) { XX sendchar(27); XX sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1); XX sendstring(escseq); return; XX } XX sendchar(27); sendstring("[0n"); return; XX XX case 'c': XX sendchar(27); sendstring("[?1;7c"); return; XX } XX XX /* Don't know how to do this one, so punt it */ XX} XX XXvoid doindex(c) XXchar c; XX { XX if (c != 'M') { XX if (c == 'E') x = MINX; XX if (y > bot) if (y < MAXY) y += 8; XX if (y == bot) XX ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,(long)(top-6), XX (long)(MAXX+7),(long)(bot+1)); XX if (y < bot) y += 8; XX } XX else { XX if (y < top) if (y > MINY) y -= 8; XX if (y == top) XX ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6), XX (long)(MAXX+7),(long)(bot+1)); XX if (y > top) y -= 8; XX } XX return; XX } XX XXdoalt(c) XXchar c; XX { XX int oldx,newx; XX inesc = -1; XX oldx = x; emit(' '); newx = x; XX x = oldx; XX SetAPen(mywindow->RPort,1L); XX switch (c) { XX case 'a': XX doline(0,-6,8,1); XX break; XX XX case 'j': XX case 'm': XX case 'v': doline(4,-6,4,-2); XX if (c=='j') doline(0,-2,4,-2); XX else if (c=='m') doline(4,-2,8,-2); XX else doline(0,-2,8,-2); XX break; XX XX case 'k': XX case 'l': XX case 'w': doline(4,-2,4,1); XX if (c=='k') doline(0,-2,4,-2); XX else if (c=='l') doline(4,-2,8,-2); XX else doline(0,-2,8,-2); XX break; XX XX case 'n': XX case 'q': doline(0,-2,8,-2); XX if (c=='n') doline(4,-6,4,2); XX break; XX XX case 't': XX case 'u': XX case 'x': doline(4,-6,4,1); XX if (c=='t') doline(4,-2,8,-2); XX else if (c=='u') doline(0,-2,4,-2); XX break; XX } XX x = newx; XX } XX XXdoline(x1,y1,x2,y2) { XX RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1), XX (long)(x+x2),(long)(y+y2)); XX } XX XXvoid doerase() XX { XX if (p[0] < 0) p[0] = 0; XX SetAPen(mywindow->RPort,0L); XX if (p[0] == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6), XX (long)(MAXX+7),(long)(y+1)); XX else if (p[0] == 1) RectFill(mywindow->RPort, XX (long)MINX,(long)(y-6),(long)(x+7),(long)(y+1)); XX else RectFill(mywindow->RPort, XX (long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1)); XX SetAPen(mywindow->RPort,1L); XX return; XX } XX SHAR_EOF if test 9827 -ne "`wc -c remote.c`" then echo shar: error transmitting remote.c '(should have been 9827 characters)' fi echo shar: extracting window.c sed 's/^XX//' << \SHAR_EOF > window.c XX/**************************************************** XX * vt100 emulator - window/keyboard support XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860823 DBW - Integrated and rewrote lots of code XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX ****************************************************/ XX XX#define MODULE_WINDOW 1 XX#include "vt100.h" XX XX/* keyboard definitions for toasc() */ XXstatic char keys[75] = { XX '`','1','2','3','4','5','6','7','8','9','0','-' , XX '=','\\', 0, '0','q','w','e','r','t','y','u','i','o' , XX 'p','[',']', 0, '1','2','3','a','s','d','f','g','h' , XX 'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v', XX 'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8, XX '\t',13,13,27,127,0,0,0,'-' } ; XX XX/* forward declarations for LATTICE */ XXvoid filename(); XXvoid emits(); XXvoid emit(); XXvoid emitbatch(); XXvoid cursorflip(); XX XX/************************************************* XX* function to get file name XX*************************************************/ XXvoid filename(name) XXchar name[]; XX { XX char c; XX ULONG class; XX unsigned int code; XX int keepgoing,i; XX keepgoing = TRUE; XX i=0; XX while (keepgoing) { XX while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) ) XX { XX class = NewMessage->Class; XX code = NewMessage->Code; XX ReplyMsg( NewMessage ); XX if (class==RAWKEY) XX { XX c = toasc(code,1); XX name[i]=c; XX if (name[i] != 0) XX { XX if (name[i] == 13) XX { XX name[i]=0; XX keepgoing = FALSE; XX } XX else XX { XX if (name[i] == 8 || name[i] == 127) XX { XX i -= 2; XX if (i < -1) i = -1; XX else { XX if (x == MINX) { y -= 8; x = MAXX; } XX emit(8); XX emit(32); XX emit(8); XX } XX } XX else XX emit(c); XX if (x == MAXX) emits("\n"); XX } XX i += 1; XX } XX } XX } /* end of new message loop */ XX } /* end of god knows what */ XX emit(13); XX emit(10); XX } /* end of function */ XX XX XX/************************************************* XX* function to print a string XX*************************************************/ XXvoid emits(string) XXchar string[]; XX { XX int i; XX char c; XX XX i=0; XX while (string[i] != 0) XX { XX c=string[i]; XX if (c == 10) emit(13); XX emit(c); XX i += 1; XX } XX } XX XX/************************************************* XX* function to output ascii chars to window XX*************************************************/ XXvoid emit(c) XXchar c; XX { XX static char wrap_flag = 0; /* are we at column 80? */ XX XX c &= 0x7F; XX switch( c ) XX { XX case '\t': XX x += 64 - ((x-MINX) % 64); XX break; XX XX case 10: /* lf */ XX y += 8; XX break; XX XX case 13: /* cr */ XX x = MINX; XX break; XX XX case 8: /* backspace */ XX x -= 8; XX if (x < MINX) x = MINX; XX break; XX XX case 12: /* page */ XX x = MINX; XX y = MINY; XX SetAPen(mywindow->RPort,0L); XX RectFill(mywindow->RPort,(long)MINX, XX (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1)); XX SetAPen(mywindow->RPort,1L); XX break; XX XX case 7: /* bell */ XX if (p_volume == 0) DisplayBeep(NULL); XX else { XX BeginIO(&Audio_Request); XX WaitIO(&Audio_Request); XX } XX break; XX XX default: XX if (c < ' ' || c > '~') break; XX if (p_wrap && wrap_flag && x >= MAXX) { XX x = MINX; XX y += 8; XX if (y > MAXY) { XX y = MAXY; XX ScrollRaster(mywindow->RPort,0L,8L,(long)MINX, XX (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1)); XX } XX } XX Move(mywindow->RPort,(long)x,(long)y); XX XX if (curmode&FSF_BOLD) { XX if (p_depth > 1) { XX SetAPen(mywindow->RPort,(long)(2+(1^p_screen))); XX SetSoftStyle(mywindow->RPort,(long)curmode,253L); XX } XX else SetSoftStyle(mywindow->RPort,(long)curmode,255L); XX } XX else SetSoftStyle(mywindow->RPort,(long)curmode,255L); XX XX if (curmode&FSF_REVERSE) { XX SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID)); XX Text(mywindow->RPort,&c,1L); XX SetDrMd(mywindow->RPort,(long)JAM2); XX } XX else Text(mywindow->RPort,&c,1L); XX XX if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L); XX x += 8; XX } /* end of switch */ XX XX if (y > MAXY) { XX y = MAXY; XX x = MINX; XX ScrollRaster(mywindow->RPort,0L,8L,(long)MINX, XX (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1)); XX } XX if (x > MAXX) { XX wrap_flag = 1; XX x = MAXX; XX } XX else wrap_flag = 0; XX } XX XX/************************************************* XX* function to output ascii chars to window (batched) XX*************************************************/ XXvoid emitbatch(la,lookahead) XXint la; XXchar *lookahead; XX { XX int i; XX XX Move(mywindow->RPort,(long)x,(long)y); XX i = x / 8; XX if (i+la >= maxcol) { XX if (p_wrap == 0) la = maxcol - i; XX else { XX lookahead[la] = 0; XX emits(lookahead); XX return; XX } XX } XX if (curmode&FSF_BOLD) { XX if (p_depth > 1) { XX SetAPen(mywindow->RPort,(long)(2+(1^p_screen))); XX SetSoftStyle(mywindow->RPort,(long)curmode,253L); XX } XX else SetSoftStyle(mywindow->RPort,(long)curmode,255L); XX } XX else SetSoftStyle(mywindow->RPort,(long)curmode,255L); XX XX if (curmode&FSF_REVERSE) { XX SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID)); XX Text(mywindow->RPort,lookahead,(long)la); XX SetDrMd(mywindow->RPort,(long)JAM2); XX } XX else Text(mywindow->RPort,lookahead,(long)la); XX if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L); XX x += (8 * la); XX } XX XX/****************************** XX* Manipulate cursor XX******************************/ XXvoid cursorflip() XX { XX SetDrMd(mywindow->RPort,(long)COMPLEMENT); XX SetAPen(mywindow->RPort,3L); XX RectFill(mywindow->RPort, XX (long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1)); XX SetAPen(mywindow->RPort,1L); XX SetDrMd(mywindow->RPort,(long)JAM2); XX } XX XX/************************************************ XX* function to take raw key data and convert it XX* into ascii chars XX**************************************************/ XXint toasc(code,local) XXunsigned int code; XXint local; XX { XX static int ctrl = 0; XX static int shift = 0; XX static int capsl = 0; XX static int amiga = 0; XX char c = 0, keypad = 0; XX char *ptr; XX XX switch ( code ) XX { XX case 98: capsl = 1; c = 0;break; XX case 226: capsl = 0; c = 0;break; XX case 99: ctrl = 1; c = 0;break; XX case 227: ctrl = 0; c = 0;break; XX case 96: XX case 97: if(++shift > 2) shift = 0; c = 0; break; XX case 224: XX case 225: if (--shift < 0) shift = 0; c = 0;break; XX case 102: XX case 103: if (++amiga > 2) amiga = 0; c = 0; break; XX case 230: XX case 231: if (--amiga < 0) amiga = 0; c = 0; break; XX case 0x50: XX case 0x51: XX case 0x52: XX case 0x53: XX case 0x54: XX case 0x55: XX case 0x56: XX case 0x57: XX case 0x58: XX case 0x59: c = 0; XX if (shift) ptr = p_F[code - 0x50]; XX else ptr = p_f[code - 0x50]; XX if (!script_on && *ptr == p_keyscript) XX script_start(++ptr); XX else sendstring(ptr); XX break; XX case 0x0f: c = (keyapp) ? 'p' : '0'; keypad = TRUE; break; XX case 0x1d: c = (keyapp) ? 'q' : '1'; keypad = TRUE; break; XX case 0x1e: c = (keyapp) ? 'r' : '2'; keypad = TRUE; break; XX case 0x1f: c = (keyapp) ? 's' : '3'; keypad = TRUE; break; XX case 0x2d: c = (keyapp) ? 't' : '4'; keypad = TRUE; break; XX case 0x2e: c = (keyapp) ? 'u' : '5'; keypad = TRUE; break; XX case 0x2f: c = (keyapp) ? 'v' : '6'; keypad = TRUE; break; XX case 0x3d: c = (keyapp) ? 'w' : '7'; keypad = TRUE; break; XX case 0x3e: c = (keyapp) ? 'x' : '8'; keypad = TRUE; break; XX case 0x3f: c = (keyapp) ? 'y' : '9'; keypad = TRUE; break; XX case 0x43: c = (keyapp) ? 'M' : 13 ; keypad = TRUE; break; XX case 0x4a: c = (keyapp) ? 'l' : '-'; keypad = TRUE; break; XX case 0x5f: sendstring("\033Om") ;break; XX case 0x3c: c = (keyapp) ? 'n' : '.'; keypad = TRUE; break; XX case 0x4c: XX case 0x4d: XX case 0x4e: XX case 0x4f: sendchar(27); /* cursor keys */ XX if (keyapp) sendchar('O'); XX else sendchar('['); XX sendchar(code - 11); XX break; XX XX default: XX if (code < 75) c = keys[code]; XX else c = 0; XX } XX XX if (keypad) { XX if (keyapp) sendstring("\033O"); XX sendchar(c); XX return(0); XX } XX XX /* add modifiers to the keys */ XX XX if (c != 0) { XX if (shift) { XX if ((c <= 'z') && (c >= 'a')) c -= 32; XX else XX switch( c ) { XX case '[': c = '{'; break; XX case ']': c = '}'; break; XX case '\\': c = '|'; break; XX case '\'': c = '"'; break; XX case ';': c = ':'; break; XX case '/': c = '?'; break; XX case '.': c = '>'; break; XX case ',': c = '<'; break; XX case '`': c = '~'; break; XX case '=': c = '+'; break; XX case '-': c = '_'; break; XX case '1': c = '!'; break; XX case '2': c = '@'; break; XX case '3': c = '#'; break; XX case '4': c = '$'; break; XX case '5': c = '%'; break; XX case '6': c = '^'; break; XX case '7': c = '&'; break; XX case '8': c = '*'; break; XX case '9': c = '('; break; XX case '0': c = ')'; break; XX default: break; XX } XX } XX else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32; XX } XX if (ctrl) { XX if (c > '`' && c <= 127) c -= 96; XX else if (c > '@' && c <= '_') c -= 64; XX } XX if (amiga && c == '.') { XX if (!local) sendbreak(); XX c = 0; XX } XX else if (ctrl && (c == '@' || c == '`' || c == ' ')) { XX if (!local) sendchar(0); XX c = 0; XX } XX else if (c != 0 && (!local)) sendchar(c); XX return((int)c); XX } XX SHAR_EOF if test 9137 -ne "`wc -c window.c`" then echo shar: error transmitting window.c '(should have been 9137 characters)' fi echo shar: extracting expand.c sed 's/^XX//' << \SHAR_EOF > expand.c XX/************************************************************* XX * vt100 terminal emulator - Wild card and Directory support XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860830 Steve Drew Added Wild card support, XX * features(expand.c) XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX * Much of the code from this module extracted from XX * Matt Dillons Shell program. (Thanxs Matt.) XX *************************************************************/ XX XX#define MODULE_EXPAND 1 XX#include "vt100.h" XX XXstruct DPTR { /* Format of directory fetch ptr */ XX struct FileLock *lock; /* lock on directory */ XX struct FileInfoBlock *fib; /* mod'd fib for entry */ XX}; XX XX/* XX * Disk directory routines XX * XX * XX * dopen() returns a struct DPTR, or NULL if the given file does not XX * exist. stat will be set to 1 if the file is a directory. If the XX * name is "", then the current directory is openned. XX * XX * dnext() returns 1 until there are no more entries. The **name and XX * *stat are set. *stat = 1 if the file is a directory. XX * XX * dclose() closes a directory channel. XX * XX */ XX XXstruct DPTR * XXdopen(name, stat) XXchar *name; XXint *stat; XX{ XX struct DPTR *dp; XX int namelen, endslash = 0; XX struct FileLock *MyLock; XX XX MyLock = (struct FileLock *)( (ULONG) ((struct Process *) XX (FindTask(NULL)))->pr_CurrentDir); XX namelen = strlen(name); XX if (namelen && name[namelen - 1] == '/') { XX name[namelen - 1] = '\0'; XX endslash = 1; XX } XX *stat = 0; XX dp = (struct DPTR *)malloc(sizeof(struct DPTR)); XX if (*name == '\0') XX dp->lock = (struct FileLock *)DupLock (MyLock); XX else XX dp->lock = (struct FileLock *)Lock (name, ACCESS_READ); XX if (endslash) XX name[namelen - 1] = '/'; XX if (dp->lock == NULL) { XX free (dp); XX return (NULL); XX } XX dp->fib = (struct FileInfoBlock *) XX AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC); XX if (!Examine (dp->lock, dp->fib)) { XX dclose (dp); XX return (NULL); XX } XX if (dp->fib->fib_DirEntryType >= 0) XX *stat = 1; XX return (dp); XX} XX XXdnext(dp, pname, stat) XXstruct DPTR *dp; XXchar **pname; XXint *stat; XX{ XX if (dp == NULL) XX return (0); XX if (ExNext (dp->lock, dp->fib)) { XX *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1; XX *pname = dp->fib->fib_FileName; XX return (1); XX } XX return (0); XX} XX XX XXdclose(dp) XXstruct DPTR *dp; XX{ XX if (dp == NULL) XX return (1); XX if (dp->fib) XX FreeMem (dp->fib, (long)sizeof(*dp->fib)); XX if (dp->lock) XX UnLock (dp->lock); XX free (dp); XX return (1); XX} XX XXfree_expand(av) XXchar **av; XX{ XX char **base = av; XX XX if (av) { XX while (*av) { XX free (*av); XX ++av; XX } XX free (base); XX } XX} XX XX/* XX * EXPAND(wild_name, pac) XX * wild_name - char * (example: "df0:*.c") XX * pac - int * will be set to # of arguments. XX * XX */ XX XX XXchar ** XXexpand(base, pac) XXchar *base; XXint *pac; XX{ XX char **eav = (char **)malloc (sizeof(char *)); XX int eleft, eac; XX XX char *ptr, *name; XX char *bname, *ename, *tail; XX int stat, scr; XX struct DPTR *dp; XX XX *pac = eleft = eac = 0; XX base = strcpy(malloc(strlen(base)+1), base); XX for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr); XX for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr); XX if (ptr < base) { XX bname = strcpy (malloc(1), ""); XX } else { XX scr = ptr[1]; XX ptr[1] = '\0'; XX bname = strcpy (malloc(strlen(base)+1), base); XX ptr[1] = scr; XX } XX ename = ptr + 1; XX for (ptr = ename; *ptr && *ptr != '/'; ++ptr); XX scr = *ptr; XX *ptr = '\0'; XX tail = (scr) ? ptr + 1 : NULL; XX XX if ((dp = dopen (bname, &stat)) == NULL || stat == 0) { XX free (bname); XX free (base); XX free (eav); XX emits ("Could not open directory"); XX return (NULL); XX } XX while (dnext (dp, &name, &stat)) { XX if (compare_ok(ename, name)) { XX if (tail) { XX int alt_ac; XX char *search, **alt_av, **scrav; XX struct FileLock *lock; XX XX if (!stat) /* expect more dirs, but this not a dir */ XX continue; XX lock = (struct FileLock *)CurrentDir (dp->lock); XX search = malloc(strlen(name)+strlen(tail)+2); XX strcpy (search, name); XX strcat (search, "/"); XX strcat (search, tail); XX scrav = alt_av = expand (search, &alt_ac); XX CurrentDir (lock); XX if (scrav) { XX while (*scrav) { XX if (eleft < 2) { XX char **scrav = (char **) XX malloc(sizeof(char *) * (eac + 10)); XX movmem (eav, scrav, sizeof(char *) * (eac + 1)); XX free (eav); XX eav = scrav; XX eleft = 10; XX } XX eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1); XX strcpy(eav[eac], bname); XX strcat(eav[eac], *scrav); XX free (*scrav); XX ++scrav; XX --eleft, ++eac; XX } XX free (alt_av); XX } XX } else { XX if (eleft < 2) { XX char **scrav = (char **) XX malloc(sizeof(char *) * (eac + 10)); XX movmem (eav, scrav, sizeof(char *) * (eac + 1)); XX free (eav); XX eav = scrav; XX eleft = 10; XX } XX eav[eac] = malloc (strlen(bname)+strlen(name)+1); XX eav[eac] = strcpy(eav[eac], bname); XX strcat(eav[eac], name); XX --eleft, ++eac; XX } XX } XX } XX dclose (dp); XX *pac = eac; XX eav[eac] = NULL; XX free (bname); XX free (base); XX if (eac) XX return (eav); XX free (eav); XX return (NULL); XX} XX XX/* XX * Compare a wild card name with a normal name XX */ XX XX#define MAXB 8 XX XXcompare_ok(wild, name) XXchar *wild, *name; XX{ XX char *w = wild; XX char *n = name; XX char *back[MAXB][2]; XX int bi = 0; XX XX while (*n || *w) { XX switch (*w) { XX case '*': XX if (bi == MAXB) { XX emits ("Too many levels of '*'"); XX return (0); XX } XX back[bi][0] = w; XX back[bi][1] = n; XX ++bi; XX ++w; XX continue; XXgoback: XX --bi; XX while (bi >= 0 && *back[bi][1] == '\0') XX --bi; XX if (bi < 0) XX return (0); XX w = back[bi][0] + 1; XX n = ++back[bi][1]; XX ++bi; XX continue; XX case '?': XX if (!*n) { XX if (bi) XX goto goback; XX return (0); XX } XX break; XX default: XX if (toupper(*n) != toupper(*w)) { XX if (bi) XX goto goback; XX return (0); XX } XX break; XX } XX if (*n) ++n; XX if (*w) ++w; XX } XX return (1); XX} XX XXset_dir(new) XXchar *new; XX{ XX register char *s; XX int i; XX struct FileLock *lock; XX char temp[60]; XX struct FileInfoBlock fib; XX XX if (*new != '\000') { XX strcpy(temp, MyDir); XX s = new; XX if (*s == '/') { XX s++; XX for (i=strlen(MyDir); XX MyDir[i] != '/' && MyDir[i] != ':'; XX i--); XX MyDir[i+1] = '\0'; XX strcat(MyDir, s); XX } XX else if (exists(s, ':') == 0) { XX if (MyDir[strlen(MyDir)-1] != ':') XX strcat(MyDir, "/"); XX strcat(MyDir, s); XX } XX else XX strcpy(MyDir, s); XX XX if ((lock = (struct FileLock *)Lock(MyDir)) == 0) { XX emits("Directory not found\n"); XX strcpy(MyDir, temp); XX } XX else { XX if (Examine(lock, &fib)) { XX if (fib.fib_DirEntryType > 0) { XX if (lock = (struct FileLock *)CurrentDir(lock)) XX UnLock(lock); XX if (MyDir[strlen(MyDir)-1] == '/') XX MyDir[strlen(MyDir)-1] = '\0'; XX } XX else { XX emits("Not a Directory\n"); XX strcpy(MyDir,temp); XX } XX } XX } XX } XX} XX XXexists(s,c) XXchar *s,c; XX { XX while (*s != '\000') XX if (*s++ == c) return(1); XX return(0); XX } SHAR_EOF if test 8298 -ne "`wc -c expand.c`" then echo shar: error transmitting expand.c '(should have been 8298 characters)' fi echo shar: extracting kermit.c sed 's/^XX//' << \SHAR_EOF > kermit.c XX/************************************************************* XX * vt100 terminal emulator - KERMIT protocol support XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860901 ACS - Added eight bit quoting XX * 860830 Steve Drew Wild card support, err recovry,bugs. XX * 860823 DBW - Integrated and rewrote lots of code XX * 860811 Steve Drew multi filexfer, bugs, status line ect.. XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX *************************************************************/ XX XX#define MODULE_KERMIT 1 XX#include "vt100.h" XX XX#define CONVERTNAME TRUE /* file name to lower case for receive */ XX#define MAXPACKSIZ 94 /* Maximum msgpkt size */ XX#define CR 13 /* ASCII Carriage Return */ XX#define LF 10 /* ASCII line feed */ XX#define SP 32 /* ASCII space */ XX#define DEL 127 /* Delete (rubout) */ XX XX#define MAXTRY 5 /* Times to retry a msgpkt */ XX#define MYQUOTE '#' /* Quote character I will use */ XX#define MYRPTQ '~' /* Repeat quote character */ XX#define MYEBQ '&' /* 8th bit prefix character */ XX#define MYPAD 0 /* Number of padding charss I will need */ XX#define MYPCHAR 0 /* Padding character I need (NULL) */ XX#define MYEOL '\n' /* End-Of-Line character I need */ XX XX#define tochar(ch) ((ch) + ' ') XX#define unchar(ch) ((ch) - ' ') XX#define ctl(ch) ((ch) ^ 64 ) XX XX/* Global Variables */ XX XXint XX size, /* Size of present data */ XX osize, /* Size of last data entry */ XX rpsiz, /* Maximum receive msgpkt size */ XX spsiz, /* Maximum send msgpkt size */ XX timint, /* Time interval to wait */ XX pad, /* How much padding to send */ XX n, /* Packet number */ XX tp, /* total packets */ XX numtry, /* Times this msgpkt retried */ XX retry, /* total retries */ XX oldtry, /* Times previous msgpkt retried */ XX sendabort, /* flag for aborting send file */ XX rptflg, /* are we doing repeat quoting */ XX ebqflg, /* are we doing 8th bit quoting */ XX notfirst, /* is this the first file received */ XX first, /* is this the first time in a file */ XX rpt, /* current repeat count */ XX next, /* what is the next character */ XX t; /* current character */ XXlong XX totbytes; /* total bytes xfered on this file */ XX XXchar XX state, /* Present state of the automaton */ XX padchar, /* Padding character to send */ XX eol, /* End-Of-Line character to send */ XX quote, /* Quote character in incoming data */ XX rptq, /* Quote character for repeats */ XX ebq, /* Quote character for 8th bit quoting */ XX ackpkt[MAXPACKSIZ+20], /* ACK/NAK packet buffer */ XX msgpkt[MAXPACKSIZ+20], /* Message Packet buffer */ XX filnam[40]; /* remote file name */ XX snum[10]; XX XXvoid encode(), decode(), rpar(), spar(); XX XXFILE *fp; /* file for send/receive */ XX XXchar * XXgetfname(name) /* returns ptr to start of file name from spec */ XXchar *name; XX { XX int l; XX XX l = strlen(name); XX while(l && name[l] != '/' && name[l] != ':') l--; XX if (name[l] == '/' || name[l] == ':') l++; XX return(name += l); XX } XX XXdoksend(file,more) XXchar *file; XXint more; XX { XX int amount, c, wild; XX char *p, **list = NULL; XX XX if (!strcmp(file,"$")) { saybye(); return(2); } XX want_message = FALSE; /* tell readchar no error msgs */ XX p = file; XX while(*p && *p != '*' && *p != '?') p++; XX if (*p) { XX wild = TRUE; XX list = expand(file, &amount); XX if (list == NULL) emits("No wild card match\n"); XX } XX else { XX wild = FALSE; XX amount = 1; XX } XX for (c = 0; c < amount; c++) { XX if (wild == TRUE) p = list[c]; XX else p = file; XX strcpy(filnam,getfname(p)); XX ttime = TTIME_KERMIT; XX tp = retry = n = numtry = 0; totbytes = 0L; XX statusline(); XX if ((fp = fopen(p,"r")) == NULL) { XX emits("ERROR"); XX emits("\nVT100 - Kermit - Cannot open send file: "); XX emits(p); XX curmode = FS_NORMAL; XX continue; XX } XX emits("SEND"); XX ClearBuffer(); XX if (sendsw()) { x = 600; emits("DONE"); } XX fclose(fp); XX curmode = FS_NORMAL; XX } XX free_expand(list); XX return TRUE; XX } XX XXdokreceive(file,more) XXchar *file; XXint more; XX { XX int retval; XX XX ttime = TTIME_KERMIT; XX if (!strcmp(file,"$")) { saybye(); return(2); } XX strcpy(filnam, file); XX statusline(); XX if (server) emits("GET "); XX else emits("RECV"); XX tp = retry = n = numtry = notfirst = 0; totbytes = 0L; XX want_message = FALSE; /* no error msgs status bar instead */ XX ClearBuffer(); XX retval = recsw(); XX curmode = FS_NORMAL; XX return(retval); XX } XX XXsendsw() XX { XX char sinit(), sfile(), sdata(), seof(), sbreak(); XX sendabort = 0; XX state = 'S'; XX while(TRUE) { XX switch(state) { XX case 'S': state = sinit(); break; XX case 'F': state = sfile(); break; XX case 'D': state = sdata(); break; XX case 'Z': state = seof(); break; XX case 'B': state = sbreak(); break; XX case 'C': if (sendabort) return FALSE; XX else return TRUE; XX case 'E': x = 600; /* host sent us error packet */ XX emits("ERROR"); /* so print the err and abort */ XX print_host_err(ackpkt); XX return(FALSE); XX case 'A': x = 600; XX if (timeout == USERABORT) { XX timeout = GOODREAD; XX n = (n+1)%64; XX sendabort = 1; XX emits("ABORT"); XX strcpy(msgpkt, "D"); XX state = 'Z'; XX break; XX } XX if (timeout == TIMEOUT) emits("TMOUT"); XX else { /* protocol error dectected by us */ XX emits("ERROR"); XX print_our_err(); XX } XX return(FALSE); XX default: return(FALSE); XX } XX } XX } XX XXchar sinit() XX { XX int num, len; XX XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX spar(msgpkt); XX XX spack('S',n,9,msgpkt); XX switch(rpack(&len,&num,ackpkt)) { XX case 'N': return(state); XX case 'Y': if (n != num) return(state); XX rpar(ackpkt); XX if (eol == 0) eol = '\n'; XX if (quote == 0) quote = MYQUOTE; XX numtry = 0; XX retry--; XX n = (n+1)%64; XX return('F'); XX case 'E': return('E'); XX case FALSE:if (timeout == USERABORT) state = 'A'; XX return(state); XX default: return('A'); XX } XX } XX XXchar sfile() XX { XX int num, len; XX XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX spack('F',n,strlen(filnam),filnam); XX switch(rpack(&len,&num,ackpkt)) { XX case 'N': XX num = (--num<0 ? 63:num); XX if (n != num) return(state); XX case 'Y': XX if (n != num) return(state); XX numtry = 0; XX retry--; XX n = (n+1)%64; XX first = 1; XX size = getpkt(); XX return('D'); XX case 'E': XX return('E'); XX case FALSE: if (timeout == USERABORT) state = 'A'; XX return(state); XX default: XX return('A'); XX } XX } XX XXchar sdata() XX { XX int num, len; XX XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX spack('D',n,size,msgpkt); XX switch(rpack(&len,&num,ackpkt)) { XX case 'N': XX num = (--num<0 ? 63:num); XX if (n != num) return(state); XX case 'Y': XX if (n != num) return(state); XX numtry = 0; XX retry--; XX n = (n+1)%64; XX if ((size = getpkt()) == 0) return('Z'); XX return('D'); XX case 'E': XX return('E'); XX case FALSE: if (timeout == USERABORT) state = 'A'; XX return(state); XX default: XX return('A'); XX } XX } XX XXchar seof() XX { XX int num, len; XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX/* if (timeout == USERABORT) { /* tell host to discard file */ XX/* timeout = GOODREAD; XX spack('Z',n,1,"D"); XX } XX else */ spack('Z',n,sendabort,msgpkt); XX switch(rpack(&len,&num,ackpkt)) { XX case 'N': XX num = (--num<0 ? 63:num); XX if (n != num) return(state); XX case 'Y': XX if (n != num) return(state); XX numtry = 0; XX retry--; XX n = (n+1)%64; XX return('B'); XX case 'E': XX return('E'); XX case FALSE: return(state); XX default: XX return('A'); XX } XX } XX XXchar sbreak() XX { XX int num, len; XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX spack('B',n,0,msgpkt); XX switch (rpack(&len,&num,ackpkt)) { XX case 'N': XX num = (--num<0 ? 63:num); XX if (n != num) return(state); XX case 'Y': XX if (n != num) return(state); XX numtry = 0; XX retry--; XX n = (n+1)%64; XX return('C'); XX case 'E': XX return('E'); XX case FALSE: return(state); XX default: return ('A'); XX } XX } XX XX/* timeout equals USERABORT so lets end the file and quit */ XX/* when host receives 'Z' packet with "D" in data field he */ XX/* should discard the file. */ XX/* XXsabort() XX { XX emits("ABORT"); XX n = (n+1)%64; XX retry--; XX state = 'Z'; XX while (state == 'Z') state = seof(); XX while (state == 'B') state = sbreak(); XX return(FALSE); XX } XX*/ XX XX XXrecsw() XX { XX char rinit(), rfile(), rdata(); XX XX state = 'R'; XX XX while(TRUE) { XX switch(state) { XX case 'R': state = rinit(); break; XX case 'Z': XX case 'F': state = rfile(); break; XX case 'D': state = rdata(); break; XX case 'C': return(TRUE); XX case 'E': XX case 'A': x = 600; XX /* easy way to cleanly abort XX should really send and ACK XX with "X" in data field and XX wait for host to abort but XX not all kermits support XX this feature. */ XX if (timeout == USERABORT){ XX /* send an error packet back */ XX emits("ABORT"); XX spack('E',n,12,"User aborted"); XX } XX else if (timeout == TIMEOUT) { XX /* we timed out waiting */ XX /* will we need to spack here ?*/ XX emits("TMOUT"); XX } XX /* must be 'E' from host or we XX detected a protocol error */ XX else emits("ERROR"); XX XX if (state == 'E') print_host_err(msgpkt); XX XX else if (timeout == GOODREAD) /* tell host why */ XX print_our_err(); XX /* will this kill all files ?*/ XX do { XX ttime = 2; XX readchar(); XX } while (timeout == GOODREAD); XX fclose(fp); XX sendstring("\r"); XX return(FALSE); XX default: return(FALSE); XX } XX } XX } XX XX XX XXchar rinit() XX { XX int len, num; XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX if (server) spack('R',n,strlen(filnam),filnam); XX else spack('N',n,0,0); XX switch(rpack(&len,&num,msgpkt)) { XX case 'S': XX rpar(msgpkt); XX spar(msgpkt); XX spack('Y',n,9,msgpkt); XX oldtry = numtry; XX numtry = 0; XX retry--; XX n = (n+1)%64; XX return('F'); XX case 'E': XX return('E'); XX case FALSE: XX if (timeout == USERABORT) return('A'); XX spack('N',n,0,0); XX return(state); XX default: XX return('A'); XX } XX } XX XXchar rfile() XX { XX int num, len; XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX switch(rpack(&len,&num,msgpkt)) { XX case 'S': XX if (oldtry++ > MAXTRY) return('A'); XX if (num == ((n==0) ? 63:n-1)) { XX spar(msgpkt); XX spack('Y',num,9,msgpkt); XX numtry = 0; XX return(state); XX } XX else return('A'); XX case 'Z': XX if (oldtry++ > MAXTRY) return('A'); XX if (num == ((n==0) ? 63:n-1)) { XX spack('Y',num,0,0); XX numtry = 0; XX return(state); XX } XX else return('A'); XX case 'F': XX if (num != n) return('A'); XX strcpy(filnam,msgpkt); XX if (CONVERTNAME) { XX char *p; XX p = &filnam[0]; XX while (*p) { *p = tolower(*p); p++; } XX } XX if (notfirst) { XX curmode = FS_NORMAL; XX totbytes = 0L; XX statusline(); XX emits("RECV"); XX } XX /* is the first file so emit actual file name from host */ XX else { XX x = 48; emits(" "); XX x = 48; emits(filnam); XX notfirst++; XX } XX if ((fp = fopen(filnam,"w")) == NULL) { XX strcpy(msgpkt,"VT100 - Kermit - Unable to create file: "); XX strcat(msgpkt,filnam); XX spack('E',n,strlen(msgpkt),msgpkt); /* let host know */ XX x = 600; emits("ERROR"); XX emits("\n"); XX emits(msgpkt); /* let user know */ XX return ('\0'); /* abort everything */ XX } XX spack('Y',n,0,0); XX oldtry = numtry; XX numtry = 0; XX retry--; XX n = (n+1)%64; XX return('D'); XX XX /* totaly done server sending no more */ XX case 'B': XX if (num != n) return ('A'); XX spack('Y',n,0,0); XX retry--; XX return('C'); XX case 'E': XX return('E'); XX case FALSE: XX if (timeout == USERABORT) return('A'); XX spack('N',n,0,0); XX return(state); XX default: XX return ('A'); XX } XX } XX XXchar rdata() XX { XX int num, len; XX retry++; XX if (numtry++ > MAXTRY) return('A'); XX XX switch(rpack(&len,&num,msgpkt)) { XX case 'D': XX if (num != n) { XX if (oldtry++ > MAXTRY) return('A'); XX if (num == ((n==0) ? 63:n-1)) { XX spack('Y',num,6,msgpkt); XX numtry = 0; XX return(state); XX } XX else return('A'); XX } XX decode(); XX spack('Y',n,0,0); XX oldtry = numtry; XX numtry = 0; XX retry--; XX n = (n+1)%64; XX return('D'); XX case 'Z': XX if (num != n) return('A'); XX spack('Y',n,0,0); XX n = (n+1)%64; XX retry--; XX x = 600; XX emits("DONE"); XX fclose(fp); XX return('Z'); XX case 'F': XX if (oldtry++ > MAXTRY) return('A'); XX if (num == ((n==0) ? 63:n-1)) { XX spack('Y',num,0,0); XX numtry = 0; XX return(state); XX } XX case 'E': XX return('E'); XX case FALSE: XX if (timeout == USERABORT) return('A'); XX spack('N',n,0,0); XX return(state); XX default: XX return('A'); XX } XX } XX XX XXspack(type,num,len,data) XXchar type, *data; XXint num, len; XX { XX int i; XX char chksum, buffer[100]; XX register char *bufp; XX XX dostats(type); XX bufp = buffer; XX ClearBuffer(); XX for (i=1; i<=pad; i++) sendchar(padchar); XX XX *bufp++ = SOH; XX *bufp++ = tochar(len+3); XX chksum = tochar(len+3); XX *bufp++ = tochar(num); XX chksum += tochar(num); XX *bufp++ = type; XX chksum += type; XX XX for (i=0; i<len; i++) { XX *bufp++ = data[i]; XX chksum += data[i]; XX } XX chksum = (((chksum&0300) >> 6)+chksum)&077; XX *bufp++ = tochar(chksum); XX *bufp++ = '\r'; XX *bufp++ = '\n'; XX *bufp = 0; XX sendstring(buffer); XX } XX XXrpack(len,num,data) XXint *len, *num; XXchar *data; XX { XX int i, done; XX char type, cchksum, rchksum; XX char t = '\0'; XX XX do { XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX } while (t != SOH); XX XX done = FALSE; XX while (!done) { XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX if (t == SOH) continue; XX cchksum = t; XX *len = unchar(t)-3; XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX if (t == SOH) continue; XX cchksum = cchksum + t; XX *num = unchar(t); XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX if (t == SOH) continue; XX cchksum = cchksum + t; XX type = t; XX for (i=0; i<*len; i++) { XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX if (t == SOH) continue; XX cchksum = cchksum + t; XX data[i] = t; XX } XX data[*len] = 0; XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX rchksum = unchar(t); XX t = readchar(); XX if (timeout != GOODREAD) return(FALSE); XX if (t == SOH) continue; XX done = TRUE; XX } XX dostats(type); XX cchksum = (((cchksum&0300) >> 6)+cchksum)&077; XX if (cchksum != rchksum) return(FALSE); XX return((int)type); XX } XX XXgetpkt() { XX int i,eof; XX XX static char leftover[10] = { '\0', '\0', '\0', '\0', '\0', XX '\0', '\0', '\0', '\0', '\0' }; XX XX if (first == 1) { XX first = 0; XX *leftover = '\0'; XX t = getc(fp); XX if (t == EOF) { XX first = 1; XX return(size = 0); XX } XX totbytes++; XX } XX else if (first == -1) { XX first = 1; XX return(size = 0); XX } XX for (size = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ; XX *leftover = '\0'; XX rpt = 0; XX eof = 0; XX while (!eof) { XX next = getc(fp); XX if (next == EOF) { XX first = -1; XX eof = 1; XX } XX else totbytes++; XX osize = size; XX encode(t); XX t = next; XX if (size == spsiz-3) return(size); XX if (size > spsiz-3) { XX for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++) ; XX size = osize; XX msgpkt[size] = '\0'; XX return(size); XX } XX } XX return(size); XX } XX XXvoid encode(a) XXchar a; XX { XX int a7,b8; XX XX if (p_mode == 1 && a == '\n') { XX rpt = 0; XX msgpkt[size++] = quote; XX msgpkt[size++] = ctl('\r'); XX if (size <= spsiz-3) osize = size; XX msgpkt[size++] = quote; XX msgpkt[size++] = ctl('\n'); XX msgpkt[size] = '\0'; XX return; XX } XX if (rptflg) { XX if (a == next && (first == 0)) { XX if (++rpt < 94) return; XX else if (rpt == 94) { XX msgpkt[size++] = rptq; XX msgpkt[size++] = tochar(rpt); XX rpt = 0; XX } XX } XX else if (rpt == 1) { XX rpt = 0; XX encode(a); XX if (size <= spsiz-3) osize = size; XX rpt = 0; XX encode(a); XX return; XX } XX else if (rpt > 1) { XX msgpkt[size++] = rptq; XX msgpkt[size++] = tochar(++rpt); XX rpt = 0; XX } XX } XX a7 = a & 0177; XX b8 = a & 0200; XX XX if (ebqflg && b8) { /* Do 8th bit prefix if necessary. */ XX msgpkt[size++] = ebq; XX a = a7; XX } XX XX if ((a7 < SP) || (a7==DEL)) { XX msgpkt[size++] = quote; XX a = ctl(a); XX } XX if (a7 == quote) msgpkt[size++] = quote; XX if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote; XX XX if ((ebqflg) && (a7 == ebq)) /* Prefix the 8th bit prefix */ XX msgpkt[size++] = quote; /* if doing 8th-bit prefixes */ XX XX msgpkt[size++] = a; XX msgpkt[size] = '\0'; XX } XX XXvoid decode() XX { XX USHORT a, a7, b8; XX char *buf; XX XX buf = msgpkt; XX rpt = 0; XX XX while ((a = *buf++) != '\0') { XX if (rptflg) { XX if (a == rptq) { XX rpt = unchar(*buf++); XX a = *buf++; XX } XX } XX b8 = 0; XX if (ebqflg) { /* 8th-bit prefixing? */ XX if (a == ebq) { /* Yes, got an 8th-bit prefix? */ XX b8 = 0200; /* Yes, remember this, */ XX a = *buf++; /* and get the prefixed character. */ XX } XX } XX if (a == quote) { XX a = *buf++; XX a7 = a & 0177; XX if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a); XX } XX a |= b8; XX if (rpt == 0) rpt = 1; XX if (p_mode == 1 && a == '\r') continue; XX totbytes += rpt; XX for (; rpt > 0; rpt--) putc(a, fp); XX } XX return; XX } XX XXvoid spar(data) XXchar data[]; XX { XX data[0] = tochar(MAXPACKSIZ); XX data[1] = tochar(TTIME_KERMIT); XX data[2] = tochar(MYPAD); XX data[3] = ctl(MYPCHAR); XX data[4] = tochar(MYEOL); XX data[5] = MYQUOTE; XX if ((p_parity > 0) || ebqflg) { /* 8-bit quoting... */ XX data[6] = MYEBQ; /* If parity or flag on, send &. */ XX if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on */ XX (ebq > 0140 && ebq < 0177) || /* if other side has asked us to */ XX (ebq == 'Y')) ebqflg = 1; XX } XX else /* Normally, */ XX data[6] = 'Y'; /* just say we're willing. */ XX data[7] = '1'; XX data[8] = MYRPTQ; XX data[9] = '\0'; XX } XX XXvoid rpar(data) XXchar data[]; XX { XX spsiz = unchar(data[0]); XX ttime = unchar(data[1]); XX pad = unchar(data[2]); XX padchar = ctl(data[3]); XX eol = unchar(data[4]); XX quote = data[5]; XX rptflg = 0; XX ebqflg = 0; XX if (data[6] == 0) return; XX ebq = data[6]; XX if ((ebq > 040 && ebq < 0100) || XX (ebq > 0140 && ebq < 0177)) ebqflg = 1; XX else if (((p_parity > 0) || ebqflg) && (ebq == 'Y')) { XX ebqflg = 1; XX ebq = '&'; XX } XX else ebqflg = 0; XX if (data[7] == 0) return; XX if (data[8] == 0) return; XX rptq = data[8]; XX rptflg = ((rptq > 040 && rptq < 0100) || XX (rptq > 0140 && rptq < 0177)); XX } XX XXsaybye() XX { XX int len,num; XX spack('G',n,1,"F"); /* shut down server no more files */ XX rpack(&len,&num,ackpkt); XX } XX XXprint_our_err() XX { XX if (retry > MAXTRY || oldtry > MAXTRY) XX strcpy(msgpkt,"VT100 - Kermit - Too many retries for packet"); XX else XX strcpy(msgpkt,"VT100 - Kermit - Protocol Error"); XX spack('E',n,strlen(msgpkt)); XX emits("\n"); XX emits(msgpkt); XX } XX XXprint_host_err(msg) XX char *msg; XX { XX curmode = FS_NORMAL; XX emits("\n"); XX emits("Host Error: "); XX curmode = FSF_BOLD; XX emits(msg); XX } XX XXstatusline() XX { XX emits ("\nFile: Pckt: Pckt No: "); XX emits ("Retrn: Bytes: Stat: "); XX x = 48; XX curmode = FSF_BOLD; XX emits (filnam); XX x = 600; XX return(0); XX } XX XXdostats(type) XXchar type; XX { XX if (type != 'Y' && type != 'N' && type != 'G') { XX x = 224; XX emit(type); XX x = 312; XX sprintf(snum,"%4d",n+(tp * 64)); XX emits(snum); XX if (n==63) tp++; XX x = 408; XX sprintf(snum,"%2d",retry-1); XX emits(snum); XX x = 488; XX sprintf(snum,"%6ld",(long)totbytes); XX emits(snum); XX } XX } XX XX/* allow for multi file xfers separated by commas under XX kermit and XMODEM */ XX XXmulti_xfer(name,mode,do_send) XXchar *name; XXint (*mode)(); XXint do_send; XX { XX int done = 0; XX int status; XX char *p; XX XX if (name[0] == '$' && name[1] == '\0') { XX saybye(); XX return(); XX } XX p = name; XX while(*p == ' ') p++; XX while(*p && *p != ',' && *p != ' ') p++; XX if (*p == '\0') done = TRUE; XX else multi = 1; XX *p = '\0'; XX XX status = ((*mode)(name, multi)); XX if (status == TRUE && want_message) { XX if (do_send) emits("Sent File: "); XX else emits("Received File: "); XX emits(name); XX emits("\n"); XX } XX else if (status == FALSE && want_message) XX { XX close(fd); XX if (do_send) emits("Send Failed: "); XX else emits("Receive Failed: "); XX emits(name); XX emits("\n"); XX } XX if (!done && timeout != USERABORT) multi_xfer(++p, mode, do_send); XX else emits("\n"); XX server = 0; XX multi = 0; XX } XX XXClearBuffer() XX { XX AbortIO(Read_Request); XX Read_Request->IOSer.io_Command = CMD_CLEAR; XX DoIO(Read_Request); XX Read_Request->IOSer.io_Command = CMD_READ; XX SendIO(Read_Request); XX } XX SHAR_EOF if test 23717 -ne "`wc -c kermit.c`" then echo shar: error transmitting kermit.c '(should have been 23717 characters)' fi echo shar: extracting xmodem.c sed 's/^XX//' << \SHAR_EOF > xmodem.c XX/************************************************************* XX * vt100 terminal emulator - XMODEM protocol support XX * XX * v2.3 861101 DBW - minor bug fixes XX * v2.2 861012 DBW - more of the same XX * v2.1 860915 DBW - new features (see README) XX * 860901 ACS - Added Parity and Word Length and support code XX * 860823 DBW - Integrated and rewrote lots of code XX * 860815 Steve Drew: readchar inproved with real timeouts XX * v2.0 860809 DBW - Major rewrite XX * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes XX * v1.0 860712 DBW - First version released XX * XX *************************************************************/ XX XX#define MODULE_XMODEM 1 XX#include "vt100.h" XX XXint enablexon = TRUE; XX XX/* forward declarations for LATTICE */ XXvoid sendstring(); XXvoid sendchar(); XXvoid sendbreak(); XXvoid No_XON(); XXvoid Do_XON(); XX XXstatic unsigned long parity_settings[4] = { XX 0x96696996, XX 0x69969669, XX 0x69969669, XX 0x96696996 }; XX XX/************************************************************ XX* Send a string (using sendchar below) XX************************************************************/ XX XXvoid sendstring(s) XXchar *s; XX { XX char c; XX XX while ((c = *s++) != '\000') sendchar(c); XX } XX XX/**************************************************************/ XX/* send char and read char functions for the xmodem function */ XX/************************************************************/ XXvoid sendchar(ch) XXint ch; XX { XX int doxon,i,j,k; XX XX doxon = enablexon; XX if (doxon) No_XON(); XX switch (p_parity) { XX case 0: /* no parity */ XX rs_out[0] = ch & 0xFF; XX break; XX XX case 1: /* mark */ XX rs_out[0] = (ch & 0x7F) | 0x80; XX break; XX XX case 2: /* space */ XX rs_out[0] = ch & 0x7F; XX break; XX XX case 3: /* even */ XX case 4: /* odd */ XX i = (ch >> 5) & 0x3; XX j = ch & 0x1F; XX k = ((parity_settings[i] >> j) & 0x1) << 7; XX if (p_parity == 3) /* even parity */ XX rs_out[0] = (ch & 0x7F) | k; XX else /* odd parity */ XX rs_out[0] = (ch & 0x7F) | (k ^ 0x80); XX } XX DoIO(Write_Request); XX if (doxon) Do_XON(); XX } XX XX/* send a break to the host */ XXvoid sendbreak() { XX AbortIO(Read_Request); XX Read_Request->IOSer.io_Command = SDCMD_BREAK; XX DoIO(Read_Request); XX Read_Request->IOSer.io_Command = CMD_READ; XX SendIO(Read_Request); XX } XX XXint readchar() XX { XX int rd,ch; XX XX Timer.tr_time.tv_secs = ttime; XX Timer.tr_time.tv_micro = 0; XX SendIO((char *) &Timer.tr_node); XX XX rd = FALSE; XX while (rd == FALSE) XX { XX Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | XX ( 1L << mywindow->UserPort->mp_SigBit) | XX ( 1L << Timer_Port->mp_SigBit)); XX if (CheckIO(Read_Request)) XX { XX WaitIO(Read_Request); XX ch=rs_in[0]; XX rd = TRUE; XX SendIO(Read_Request); XX } XX if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) { XX if ((NewMessage->Class == RAWKEY) && (NewMessage->Code == 69)) XX { XX AbortIO((char *) &Timer); XX Wait (1L << Timer_Port->mp_SigBit); XX if (want_message) XX emits("\nUser aborted transfer\n"); XX timeout = USERABORT; XX return('\0'); XX } XX continue; XX } XX if (rd == FALSE && CheckIO(&Timer)) { XX if (want_message) XX emits("\nTimeout waiting for character\n"); XX timeout = TIMEOUT; XX return('\0'); XX } XX } /* end while */ XX AbortIO((char *) &Timer); XX Wait (1L << Timer_Port->mp_SigBit); XX timeout = GOODREAD; XX return(ch & 0xFF); XX } XX XXvoid No_XON() { XX XX /* turn off XON/XOFF processing */ XX enablexon = FALSE; XX Write_Request->io_SerFlags |= SERF_XDISABLED; XX Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; XX DoIO(Write_Request); XX Write_Request->IOSer.io_Command = CMD_WRITE; XX } XX XXvoid Do_XON() { XX /* turn on XON/XOFF processing */ XX enablexon = TRUE; XX Write_Request->io_SerFlags &= ~SERF_XDISABLED; XX Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; XX DoIO(Write_Request); XX Write_Request->IOSer.io_Command = CMD_WRITE; XX } XX XX/**************************************/ XX/* xmodem send and recieve functions */ XX/************************************/ XX XXint XMODEM_Read_File(file) XXchar *file; XX { XX int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag; XX unsigned int checksum, j, bufptr; XX char numb[10]; XX bytes_xferred = 0L; XX ttime = TTIME_SHORT; XX want_message = TRUE; /* tell readchar to print any error msgs */ XX XX if ((fd = creat(file, 0)) < 0) XX { XX emits("Cannot Open File\n"); XX return FALSE; XX } XX else XX emits("Receiving File\n\nType <ESC> to abort transfer\n"); XX XX sectnum = errors = bufptr = 0; XX sendchar(NAK); XX firstchar = 0; XX No_XON(); XX while (firstchar != EOT && errors != ERRORMAX) XX { XX errorflag = FALSE; XX XX do { /* get sync char */ XX firstchar = readchar(); XX if (timeout != GOODREAD) { XX if (timeout == USERABORT || errors++ == ERRORMAX) XX Do_XON(); XX return FALSE; XX } XX } while (firstchar != SOH && firstchar != EOT); XX XX if (firstchar == SOH) XX { XX emits(blanks); XX emits("\rGetting Block "); XX sprintf(numb, "%d", sectnum); XX emits(numb); XX emits("..."); XX sectcurr = readchar(); XX if (timeout != GOODREAD) { Do_XON(); return FALSE; } XX sectcomp = readchar(); XX if (timeout != GOODREAD) { Do_XON(); return FALSE; } XX if ((sectcurr + sectcomp) == 255) XX { XX if (sectcurr == ((sectnum + 1) & 0xff)) XX { XX checksum = 0; XX for (j = bufptr; j < (bufptr + SECSIZ); j++) XX { XX bufr[j] = readchar(); XX if (timeout != GOODREAD) { Do_XON(); return FALSE; } XX checksum = (checksum + bufr[j]) & 0xff; XX } XX if (checksum == readchar() && timeout == GOODREAD) XX { XX errors = 0; XX sectnum++; XX bufptr += SECSIZ; XX bytes_xferred += SECSIZ; XX emits("verified\r"); XX if (bufptr == BufSize) XX { XX if (write(fd, bufr, BufSize-128) == EOF) XX { XX emits("\nError Writing File\n"); XX Do_XON(); XX return FALSE; XX } XX bufptr = 128; XX for (j = 0; j < 128; j++) XX bufr[j] = bufr[(BufSize-128)+j]; XX } XX sendchar(ACK); XX } XX else XX { XX errorflag = TRUE; XX if (timeout == USERABORT) { Do_XON(); return FALSE; } XX } XX } XX else XX { XX /* got a duplicate sector */ XX if (sectcurr == (sectnum & 0xff)) XX { XX /* wait until we time out for 5secs */ XX do { XX readchar(); XX } while (timeout == GOODREAD); XX if (timeout == USERABORT) { XX Do_XON(); XX return FALSE; XX } XX emits("\nReceived Duplicate Sector\n"); XX sendchar(ACK); XX } XX else errorflag = TRUE; XX } XX } XX else errorflag = TRUE; XX } XX if (errorflag == TRUE) XX { XX errors++; XX emits("\nError\n"); XX sendchar(NAK); XX } XX } /* end while */ XX if ((firstchar == EOT) && (errors < ERRORMAX)) XX { XX sendchar(ACK); XX while (bufptr > 0 && (bufr[--bufptr] == 0x00 || XX bufr[bufptr] == 0x1A)) ; XX write(fd, bufr, ++bufptr); XX close(fd); XX Do_XON(); XX return TRUE; XX } XX Do_XON(); XX return FALSE; XX } XX XXint XMODEM_Send_File(file) XXchar *file; XX { XX int sectnum, bytes_to_send, size, attempts, c; XX unsigned checksum, j, bufptr; XX char numb[10]; XX bytes_xferred = 0; XX ttime = TTIME_LONG; XX want_message = TRUE; /* tell readchar to print any error msgs */ XX XX if ((fd = open(file, 0)) < 0) { XX emits("Cannot Open Send File\n"); XX return FALSE; XX } XX else XX emits("Sending File\n\nType <ESC> to abort transfer\n"); XX attempts = 0; XX sectnum = 1; XX No_XON(); XX /* wait for sync char */ XX j=1; XX while (((c = readchar()) != NAK) && (j++ < ERRORMAX)) XX if (timeout == USERABORT) { Do_XON(); return(FALSE); } XX if (j >= (ERRORMAX)) XX { XX emits("\nReceiver not sending NAKs\n"); XX Do_XON(); XX return FALSE; XX } XX XX while ((bytes_to_send = read(fd, bufr, BufSize)) && XX attempts != RETRYMAX) XX { XX if (bytes_to_send == EOF) XX { XX emits("\nError Reading File\n"); XX Do_XON(); XX return FALSE; XX } XX XX bufptr = 0; XX while (bytes_to_send > 0 && attempts != RETRYMAX) XX { XX attempts = 0; XX emits(blanks); XX emits("\rBlock "); XX sprintf(numb, "%d ", sectnum); XX emits(numb); XX do { XX emits("."); XX sendchar(SOH); XX sendchar(sectnum); XX sendchar(~sectnum); XX checksum = 0; XX size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send; XX bytes_to_send -= size; XX for (j = bufptr; j < (bufptr + SECSIZ); j++) XX if (j < (bufptr + size)) { XX sendchar(bufr[j]); XX checksum += bufr[j]; XX } XX else sendchar(0); XX sendchar(checksum); XX attempts++; XX c = readchar(); XX if (timeout == USERABORT) { XX emits("\n"); XX Do_XON(); XX return FALSE; XX } XX } while ((c != ACK) && (attempts != RETRYMAX)); XX bufptr += size; XX bytes_xferred += size; XX emits(" sent\r"); XX sectnum++; XX } XX } XX close(fd); XX if (attempts == RETRYMAX) XX { XX emits("\nNo Acknowledgment Of Sector, Aborting\n"); XX Do_XON(); XX return FALSE; XX } XX else XX { XX attempts = 0; XX do { XX sendchar(EOT); XX attempts++; XX } while ((readchar() != ACK) && XX (attempts != RETRYMAX) && XX (timeout != USERABORT)) ; XX if (attempts == RETRYMAX) XX emits("\nNo Acknowledgment Of End Of File\n"); XX } XX Do_XON(); XX return TRUE; XX } XX SHAR_EOF if test 9256 -ne "`wc -c xmodem.c`" then echo shar: error transmitting xmodem.c '(should have been 9256 characters)' fi # End of shell archive exit 0
candym@calgary.UUCP (Mike Candy) (11/26/86)
Part 2/2 of DBW's VT100 program V2.3 made it, but a local black hole seems to have swallowed Part 1/2. I'd appreciate it if somebody could E-Mail me a copy. Thanks in advance. -- ____________________________________________________________________________ Mike Candy UUCP: ..!{ubc-vision,ihnp4}!alberta!calgary!candym BIX: mrcandy (not checked very often)