home *** CD-ROM | disk | FTP | other *** search
- /* K E R M I T -- Main driver program for linking to user program */
-
- /*
- Maintenance Notes:
- ..Aug86 - Module created by Jeff Lydiatt to interface Kermit to Aterm.
- 28Dec86 - For Receive: allow for * or directory name as file name.
- If so, the host file name is used as the file name. For directory,
- the the host file name will be dumped to the requested directory.
- */
- /*
- Authors: Frank da Cruz, Bill Catchings, Jeff Damens;
- Columbia University Center for Computing Activities, 1984-85.
- Copyright (C) 1985, Trustees of Columbia University in the City of New York.
- Permission is granted to any individual or institution to use, copy, or
- redistribute this software so long as it is not sold for profit, provided this
- copyright notice is retained.
- */
- /*
- The Kermit file transfer protocol was developed at Columbia University.
- It is named after Kermit the Frog, star of the television series THE
- MUPPET SHOW; the name is used by permission of Henson Associates, Inc.
- "Kermit" is also Celtic for "free".
- */
- /*
- Thanks to Herm Fischer of Encino, CA, for extensive contributions to
- version 4, and to the following people for their contributions over the years:
-
- Larry Afrin, Clemson U
- Charles Brooks, EDN
- Bob Cattani & Chris Maio, Columbia CS Dept
- Alan Crosswell, CUCCA
- Carl Fongheiser, CWRU
- Yekta Gursel, MIT
- Jim Guyton, Rand Corp
- Stan Hanks, Rice U.
- Ken Harrenstein, SRI
- Steve Hemminger, Tektronix
- Randy Huntziger, NLM
- Martin Minow, DEC
- Tony Movshon, NYU
- Ken Poulton, HP Labs
- Frank Prindle, NADC
- Stew Rubenstein, Harvard
- Dan Schullman, DEC
- Bradley Smith, UCLA
- Dave Tweten, AMES-NAS
- Walter Underwood, Ford Aerospace
- Pieter Van Der Linden, Centre Mondial (Paris)
- Mark Vasoll & Gregg Wonderly, Oklahoma State University
- Lauren Weinstein, Vortex
-
- and many others.
- */
-
- /* Includes */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <exec/memory.h>
- #include <functions.h>
- #include <setjmp.h>
- #include "lckdeb.h"
- #include "lckerm.h"
- #include "SerialIO.h"
- #include "ConsoleIO.h"
-
- #define toupper(ch) _toupper(ch) /* Use Aztec's macro */
- #define tolower(ch) _tolower(ch) /* Use Aztec's macro */
- #define MAXWLD 500 /* Maximum wildcard filenames */
- #define ESC 27 /* Escape Character */
-
- /* Declarations for Send-Init Parameters */
-
- int spsiz, /* Biggest packet size we can send */
- rpsiz, /* Biggest we want to receive */
- timint, /* Timeout interval I use */
- rtimo, /* Timeout I want you to use */
- timef, /* Flag to override what you ask */
- npad, /* How much padding to send */
- mypadn, /* How much padding to ask for */
- chklen, /* Length of block check */
- bctr, /* Block check type requested */
- bctu, /* Block check type used */
- ebq, /* 8th bit prefix */
- ebqflg, /* 8th-bit quoting flag */
- rpt, /* Repeat count */
- rptq, /* Repeat prefix */
- rptflg, /* Repeat processing flag */
- capas; /* Capabilities */
-
- CHAR padch, /* Padding character to send */
- mypadc, /* Padding character to ask for */
- seol, /* End-Of-Line character to send */
- eol, /* End-Of-Line character to look for */
- ctlq, /* Control prefix in incoming data */
- myctlq; /* Outbound control character prefix */
-
- int wndmax, /* Maximum window size for table */
- wndsiz; /* Window size I want */
-
- /* Packet-related variables */
-
- int pktnum = 0, /* Current packet number */
- prvpkt = -1, /* Previous packet number */
- sndtyp, /* Type of packet just sent */
- size, /* Current size of output pkt data */
- osize, /* Previous output packet data size */
- maxsize, /* Max size for building data field */
- spktl; /* Length packet being sent */
-
- CHAR sndpkt[MAXPACK*2], /* Entire packet being sent */
- recpkt[RBUFL+2], /* Packet most recently received */
- data[MAXPACK+4], /* Packet data buffer */
- srvcmd[MAXPACK*2], /* Where to decode server command */
- *srvptr, /* Pointer to above */
- mystch = SOH, /* Outbound packet-start character */
- stchr = SOH; /* Incoming packet-start character */
-
- /* File-related variables */
-
- CHAR filnam[50]; /* Name of current file. */
- CHAR fildat[20]; /* File creation date */
-
- int nfils; /* Number of files in file group */
- long fsize; /* Size of current file */
-
- /* Communication line variables */
-
- CHAR ttname[50]; /* Name of communication line. */
-
- int parity, /* Parity specified, 0,'e','o',etc */
- flow = 0, /* Flow control, 1 = xon/xoff */
- speed = 300, /* Line speed */
- turn = 0, /* Line turnaround handshake flag */
- turnch = XON, /* Line turnaround character */
- duplex = 0, /* Duplex, full by default */
- escape = 034, /* Escape character for connect */
- delay = DDELAY, /* Initial delay before sending */
- cdetect = FALSE, /* Carrier detect not required */
- mdmtyp = 0; /* Modem type (initially none) */
-
-
- /* Statistics variables */
-
- long filcnt, /* Number of files in transaction */
- flci, /* Characters from line, current file */
- flco, /* Chars to line, current file */
- tlci, /* Chars from line in transaction */
- tlco, /* Chars to line in transaction */
- ffc, /* Chars to/from current file */
- tfc; /* Chars to/from files in transaction */
-
- /* Flags */
-
- int deblog, /* Flag for debug logging */
- pktlog, /* Flag for packet logging */
- seslog, /* Session logging */
- tralog, /* Transaction logging */
- displa, /* File transfer display on/off */
- stdouf, /* Flag for output to stdout */
- xflg, /* Flag for X instead of F packet */
- hcflg, /* Doing Host command */
- fncnv, /* Flag for file name conversion */
- binary, /* Flag for binary file */
- warn, /* Flag for file warning */
- quiet, /* Be quiet during file transfer */
- local, /* Flag for external tty vs stdout */
- server, /* Flag for being a server */
- cnflg, /* Connect after transaction */
- cxseen, /* Flag for cancelling a file */
- czseen, /* Flag for cancelling file group */
- filatr, /* Flag for sending file attributes */
-
- nxtcas, /* Flag for sending next attribute */
- capflg, /* Which capas are supported */
- sldwnd, /* Flag for sliding window support */
- window; /* Flag for windowing state */
-
- /* Variables passed from command parser to protocol module */
-
- CHAR sstate = 0; /* Starting state for automaton */
- CHAR *cmarg = (CHAR *)""; /* Pointer to command data */
- CHAR *cmarg2 = (CHAR *)""; /* Pointer to 2nd command data */
- CHAR **cmlist= 0;
-
- /* Variables and symbols local to this module */
-
- static CHAR debfil[50]; /* Debugging log file name */
- static CHAR pktfil[50]; /* Packet log file name */
- static CHAR sesfil[50]; /* Session log file name */
- static CHAR trafil[50]; /* Transaction log file name */
- static CHAR dirname[50]; /* Dump file to "dirname" */
-
- CHAR *strcpy(), *stpchr();
-
- static int n, /* General purpose int */
- cflg, /* Command-line connect cmd given */
- action, /* Action selected on command line*/
- repars, /* Reparse needed */
- tlevel,
- debugp = 0, /* Debug print */
- /* Take command level */
- cwdf = 0; /* CWD has been done */
-
-
- /* AtermKermit Module Static Variables */
-
- static long waitMask;
- static jmp_buf AbortEnv;
-
- /*----------------------------------------------------------------------*/
- /* SetWaitMask: Allow Waits for Timer, Console, or Serial Port. */
- /*----------------------------------------------------------------------*/
-
- static void SetWaitMask()
- {
- waitMask = ( 1L << GetConsoleSigBit() )
- | ( 1L << GetSerialSigBit() )
- | ( 1L << GetTimerSigBit() );
- }
-
- /* K I N I T -- routine to initialize variable if kermit is linked to other
- programs, returns action to take */
-
- void kinit() {
-
- void ScreenInit();
-
- /* Declarations for Send-Init Parameters */
-
- spsiz = DSPSIZ; /* Biggest packet size we can send */
- rpsiz = DRPSIZ; /* Biggest we want to receive */
- timint = DMYTIM; /* Timeout interval I use */
- rtimo = URTIME; /* Timeout I want you to use */
- timef = 0; /* Flag to override what you ask */
- npad = MYPADN; /* How much padding to send */
- mypadn = MYPADN; /* How much padding to ask for */
- chklen = 1; /* Length of block check */
- bctr = 3; /* Block check type requested */
- bctu = 1; /* Block check type used */
- ebq = MYEBQ; /* 8th bit prefix */
- ebqflg = 0; /* 8th-bit quoting flag */
- rpt = 0; /* Repeat count */
- rptq = MYRPTQ; /* Repeat prefix */
- rptflg = 0; /* Repeat processing flag */
- capas = MYCAPA; /* Capabilities */
-
- padch = MYPADC; /* Padding character to send */
- mypadc = MYPADC; /* Padding character to ask for */
- seol = MYEOL; /* End-Of-Line character to send */
- eol = MYEOL; /* End-Of-Line character to look for */
- ctlq = CTLQ; /* Control prefix in incoming data */
- myctlq = CTLQ; /* Outbound control character prefix */
- wndmax = 31; /* Maximum window size for table */
- wndsiz = 31; /* Window size I want */
-
- /* Flags */
-
- deblog = 0; /* Flag for debug logging */
- pktlog = 0; /* Flag for packet logging */
- seslog = 0; /* Session logging */
- tralog = 0; /* Transaction logging */
- displa = 1; /* File transfer display on/off */
- stdouf = 0; /* Flag for output to stdout */
- xflg = 0; /* Flag for X instead of F packet */
- hcflg = 0; /* Doing Host command */
- fncnv = 1; /* Flag for file name conversion */
- binary = 1; /* Flag for binary file */
- warn = 0; /* Flag for file warning */
- quiet = 0; /* Be quiet during file transfer */
- local = 1; /* Flag for external tty vs stdout */
- server = 0; /* Flag for being a server */
- cnflg = 0; /* Connect after transaction */
- cxseen = 0; /* Flag for cancelling a file */
- czseen = 0; /* Flag for cancelling file group */
- filatr = 0; /* Flag for sending file attributes */
- nxtcas = 1; /* Flag for sending next attribute */
- capflg = 0; /* Which capas are supported */
- sldwnd = 0; /* Flag for sliding window support */
- window = 0; /* Flag for windowing state */
-
- cmarg = (CHAR *)""; /* Initialize. */
- cmarg2 = (CHAR *)"";
- cmlist= 0;
- action = cflg = 0;
-
- speed = 300; /* set baud rate */
- duplex = 1;
- delay = DDELAY, /* Initial delay before sending */
- parity = '\0'; /* set parity e, m, n, s, or o */
- ffc = 0; /* screen() checks this for 1st time through */
- fsize = 0;
- *fildat = '\0';
- *dirname= '\0';
-
- #ifdef DEBUG
- if ( !GetLine( "\nDebug Log? ", debfil) )
- deblog = 0;
- else
- {
- deblog = 1;
- if (strcmp( debfil, "con" ) == 0)
- debopn("CON:0/0/640/100/Kermit Debug Log");
- else
- debopn( debfil );
- }
- PutChar( '\n' );
- #endif
- #ifdef TLOG
- if ( !GetLine( "\nLog File Name? ", trafil) )
- tralog = 0;
- else if ( !(tralog = zopeno( ZTFILE, trafil ) ) )
- format( PutChar, "Can't Open Log File as: %s\xFF", &trafil );
- PutChar( '\n' );
- #endif
- SetWaitMask();
- ScreenInit();
-
- }
-
- /* D O E X I T -- Exit from the program. */
-
- static void cleanup()
- {
- CursorXY( 1 , 18 ); /* Next Message starts Line 18 */
-
- if (deblog)
- { /* Close any open logs. */
- debug(F100,"Debug Log Closed","",0);
- *debfil = '\0';
- deblog = 0;
- zclose(ZDFILE);
- }
- if (tralog)
- {
- tlog(F100,"Transaction Log Closed","",0L);
- *trafil = '\0';
- tralog = 0;
- zclose(ZTFILE);
- }
- }
-
- /*----------------------------------------------------------------------*/
- /* KermitGet: external entry for Kermit Protocol get a file. */
- /*----------------------------------------------------------------------*/
-
- BOOL KermitGet( fileName )
- CHAR *fileName;
- {
- BOOL status;
- int len;
- void kinit();
- long zchki();
- kinit();
-
- /* Set up Cmarg2: Handle a '*' or directory name in fileName */
-
- cmarg2 = '\0';
- if ( zchki(fileName) == -2 /*Directory or volume*/)
- {
- strcpy(dirname, fileName);
- len = strlen( dirname) -1;
- if ( dirname[len] != ':' && dirname[len] != '/' )
- strcat( dirname, "/" );
- }
- else if ( strcmp( fileName, "*" ) != 0 )
- cmarg2 = fileName;
- sstate = 'v';
- if ( setjmp( AbortEnv) )
- status = FALSE;
- else
- {
- status = TRUE;
- wart();
- }
- cleanup();
- return status;
- }
-
- /*----------------------------------------------------------------------*/
- /* KermitPut: external entry for Kermit Protocol send a file. */
- /*----------------------------------------------------------------------*/
-
- BOOL KermitPut( fileName )
- CHAR *fileName;
- {
- BOOL status;
- void kinit();
-
- kinit();
- sstate = 's';
- nfils = 1;
- cmlist = &fileName;
- if ( setjmp( AbortEnv) )
- status = FALSE;
- else
- {
- status = TRUE;
- wart();
- }
- cleanup();
- return status;
- }
-
-
- /* C K U U S R -- "User Interface" for PC-DOS Kermit */
-
- /* F. da Cruz, Columbia University Center for Computing Activities */
- /* Modified for use with PC-DOS by: Jan A. van der Eijk, NUS Corp., July 1985 */
- /*
- Copyright (C) 1985, Trustees of Columbia University in the City of New York.
- Permission is granted to any individual or institution to use, copy, or
- redistribute this software so long as it is not sold for profit, provided this
- copyright notice is retained.
- */
-
- /* D E B O P N -- Open a debugging file */
-
- debopn(s)
- CHAR *s;
- {
- #ifdef DEBUG
- CHAR *tp;
- zclose(ZDFILE);
- deblog = zopeno(ZDFILE,s);
- if (deblog > 0)
- {
- strcpy(debfil,s);
- ztime(&tp);
- debug(F100,tp,"",0);
- }
- else
- *debfil = '\0';
- return(deblog);
- #else
- return(0);
- #endif
- }
-
- /* I N T M S G -- Issue message about terminal interrupts */
-
- intmsg(n)
- long n;
- {
- extern CHAR *chstr();
- CHAR buf[80];
-
- if ((!displa) || (quiet)) return;
- if (n == 1) {
- screen(SCR_TN,0,0L,"CTRL-F to cancel File, CTRL-R to Resend current packet");
- screen(SCR_TN,0,0L,"CTRL-B to cancel Batch, CTRL-K to abort Kermit and exit");
- screen(SCR_TN,0,0L,"CTRL-A for status report: ");
- }
- else screen(SCR_TU,0,0L," ");
- }
-
-
- /* C H K I N T -- Check for console interrupts */
-
- chkint()
- {
- int ch, cn;
-
- if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
- if ( (ch = CheckKey()) == 0)
- return 0;
- switch (ch & 0177)
- {
- case 0001: /* CTRL-A */
- break;
-
- case 0002: /* CTRL-B */
- screen(SCR_TN,0,0L,"^B - Cancelling Batch ");
- czseen = 1;
- break;
-
- case 0013: /* CTRL-K */
- case ESC: /* ESC */
- screen(SCR_TN,0,0L,"^K - Aborting Kermit ");
- errpkt("Tranfer aborted by otherside.");
- czseen = 1; cxseen = 1;
- clsif();clsof();
- longjmp(AbortEnv, BAD_EXIT);
- break;
-
- case 0006: /* CTRL-F */
- screen(SCR_TN,0,0L,"^F - Cancelling File ");
- cxseen = 1;
- break;
-
- case 0022: /* CTRL-R */
- screen(SCR_TN,0,0L,"^R - Resending ");
- resend();
- return(1);
-
- default: /* Anything else, just ignore */
- break;
- }
- return(1);
- }
-
-
- /* D E B U G -- Enter a record in the debugging log */
-
- /*
- Call with a format, two strings, and a number:
- f - Format, a bit string in range 0-7.
- If bit x is on, then argument number x is printed.
- s1 - String, argument number 1. If selected, printed as is.
- s2 - String, argument number 2. If selected, printed in brackets.
- n - Int, argument 3. If selected, printed preceded by equals sign.
-
- f=0 is special: print s1,s2, and interpret n as a char.
- */
- #ifdef DEBUG
- debug(f,s1,s2,n)
- int f, n;
- CHAR *s1, *s2;
- {
- static CHAR s[200];
- CHAR *sp = s;
-
- if (!deblog) return; /* If no debug log, don't */
- switch (f) {
-
- case F000: /* 0, print both strings, */
- sprintf(sp,"%s%s%c\n",s1,s2,n); /* and interpret n as a char */
- zsout(ZDFILE,s);
- break;
-
- case F001: /* 1, "=n" */
- sprintf(sp,"=%d\n",n);
- zsout(ZDFILE,s);
- break;
-
- case F010: /* 2, "[s2]" */
- sprintf(sp,"[%s]\n",s2);
- zsout(ZDFILE,"");
- break;
-
- case F011: /* 3, "[s2]=n" */
- sprintf(sp,"[%s]=%d\n",s2,n);
- zsout(ZDFILE,s);
- break;
-
- case F100: /* 4, "s1" */
- zsoutl(ZDFILE,s1);
- break;
-
- case F101: /* 5, "s1=n" */
- sprintf(sp,"%s=%d\n",s1,n);
- zsout(ZDFILE,s);
- break;
-
- case F110: /* 6, "s1[s2]" */
- sprintf(sp,"%s[%s]\n",s1,s2);
- zsout(ZDFILE,s);
- break;
-
- case F111: /* 7, "s1[s2]=n" */
- sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
- zsout(ZDFILE,s);
- break;
-
- default:
- sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
- zsout(ZDFILE,s);
- }
- }
- #endif
-
-
- #ifdef TLOG
- /* T L O G -- Log a record in the transaction file */
- /*
- Call with a format and 3 arguments: two strings and a number:
- f - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
- s1,s2 - String arguments 1 and 2.
- n - Int, argument 3.
- */
- tlog(f,s1,s2,n)
- int f;
- long n;
- CHAR *s1, *s2;
- {
- static CHAR s[200];
- CHAR *sp = s; int x;
-
- if (!tralog) return; /* If no transaction log, don't */
- switch (f) {
-
- case F000: /* 0 (special) "s1 n s2" */
- sprintf(sp,"%s %ld %s\n",s1,n,s2);
- zsout(ZTFILE,s);
- break;
-
- case F001: /* 1, " n" */
- sprintf(sp," %ld\n",n);
- zsout(ZTFILE,s);
- break;
-
- case F010: /* 2, "[s2]" */
- x = strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- sprintf(sp,"[%s]\n",s2);
- zsout(ZTFILE,"");
- break;
-
- case F011: /* 3, "[s2] n" */
- x = strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- sprintf(sp,"[%s] %ld\n",s2,n);
- zsout(ZTFILE,s);
- break;
-
- case F100: /* 4, "s1" */
- zsoutl(ZTFILE,s1);
- break;
-
- case F101: /* 5, "s1: n" */
- sprintf(sp,"%s: %ld\n",s1,n);
- zsout(ZTFILE,s);
- break;
-
- case F110: /* 6, "s1 s2" */
- x = strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- sprintf(sp,"%s %s\n",s1,s2);
- zsout(ZTFILE,s);
- break;
-
- case F111: /* 7, "s1 s2: n" */
- x = strlen(s2);
- if (s2[x] == '\n') s2[x] = '\0';
- sprintf(sp,"%s %s: %ld\n",s1,s2,n);
- zsout(ZTFILE,s);
- break;
-
- default:
- sprintf(sp,"\n?Invalid format for tlog() - %ld\n",n);
- zsout(ZTFILE,s);
- }
- }
- #endif
-
- ermsg(msg)
- CHAR *msg;
- { /* Print error message */
- if (!quiet)
- format( PutFormat, "\nHost: %s\n\xFF", &msg);
- tlog(F110,"Error -",msg,0L);
- }
-
-
- /*--------ScreenInit: Format the screen for Super Kermit Window*/
- static void ScreenInit()
- {
- format( PutFormat,
- "\x0C S U P E R K E R M I T S T A T U S\n\xFF");
-
- }
-
- /*--------errmsg: print an error message to screen--------------*/
-
- static void errmsg( msg )
- char *msg;
- {
- CursorXY(1, 17);
- format( PutFormat, "\x9BK%s\xFF", &msg );
- }
- /*-----perror: print system error message---------*/
-
- perror(s)
- CHAR *s;
- {
- extern int errno;
- struct p1
- {
- int errno;
- CHAR *s;
- } parm1;
-
- parm1.errno = errno;
- parm1.s = s;
- CursorXY(1, 17);
- errmsg( parm1 );
- }
-
- /* S C R E E N -- Screen display function */
-
- /* screen(f,c,n,s)
- f - argument descriptor
- c - a character or small integer
- n - a long integer
- s - a string.
- Fill in this routine with the appropriate display update for the system.
- This version is for full screen mode.
- */
- screen(f,c,n,s)
- int f;
- long n;
- CHAR c;
- CHAR *s;
- {
- static int filelen; /* length of filename */
- static int badpkts; /* number of bad packets */
- static char msg[81];
- char *msgPtr = msg;
- struct table /* x,y offsets for display */
- {
- int row;
- int col;
- };
-
- struct table *tablePtr;
- int len; /* Length of string */
- static struct table location[] =
- { { 3, 1 /* Filename */},
- { 3, 1 /* as-name */},
- { 6, 1 /* file-size */},
- {17, 1 /* x-packet data*/},
- {12, 1 /* File status */},
- {17, 1 /* packet number*/},
- {14, 1 /* packet type */},
- {17, 1 /* transaction complete */},
- {17, 1 /* error message */},
- {17, 1 /* warning message */},
- {17, 1 /* arbitrary undelimited text */},
- {17, 1 /* arbitrary new text, delimited at beginning */},
- {17, 1 /* arbitrary text, delimited at end */},
- { 6, 1 /* quantity equals (eg. "foo: 7") */},
- { 4, 1 /* Print the date */},
- };
- struct parm
- {
- CHAR *s;
- long n;
- } parm1;
-
- static char *transMode[] = { "Binary", "Ascii"};
- static char *checkMode[]=
- { "8 Bit Checksum", "16 Bit Checksum", "16 Bit CRC", "Unknown" };
- static char *onOFF[]= { "ON", "OFF" };
- char *strPtr;
-
- if (!displa || quiet) return; /* No update if display flag off */
- len = strlen(s); /* Length of string */
-
- /* Position the Cursor */
- if ( (1 <= f) && (f <= SCR_DT))
- tablePtr = &location[f-1];
- else
- tablePtr = &location[5];
- CursorXY( tablePtr->col, tablePtr->row );
-
- switch (f)
- {
-
- case SCR_FN: /* filename */
- format( PutFormat, "Transferring %s \xFF", &s );
- filelen = len+13;
- badpkts = 0;
-
- /* Transfer Mode */
- strPtr = transMode[ binary ? 0 : 1 ];
- format( PutFormat, "\n\nTransfer Mode is... %s", &strPtr );
-
- /* Window Size */
- format( PutFormat, "\n\n\nWindow Size ....... %d ", &wndsiz );
-
- /* Block Check Mode */
- if ( (1 <= bctu) && (bctu <= 3) )
- strPtr = checkMode[ bctu - 1 ];
- else
- strPtr = checkMode[ 3 ];
- format( PutFormat, "\nBlock Check Mode... %s", &strPtr );
-
- /* Compression Mode */
- strPtr = onOFF[ rptflg ? 0 : 1 ];
- format( PutFormat, "\nCompression........ %s", &strPtr );
-
- /* 8 Bit Prefixing */
- strPtr = onOFF[ ebqflg ? 0 : 1 ];
- format( PutFormat, "\n8th Bit Prefixing.. %s", &strPtr );
-
- /* File Status */
- format( PutFormat, "\nFile Status........ " );
- format( PutFormat, "\n\x9BJ\xFF" ); /* Erase rest of Display */
- return;
-
- case SCR_AN: /* as-name */
- CursorXY( tablePtr->col+filelen+1, tablePtr->row );
- format( PutFormat, "as %s\xFF", &s );
- return;
-
- case SCR_FS: /* file-size */
- format( PutFormat, "File Size.......... %ld\xFF", &n );
- return;
-
- case SCR_DT:
- sprintf( msg, "%2.2s/%2.2s/%2.2s -%s", &s[2], &s[4], &s[6], &s[8] );
- format( PutFormat, "File Creation Date. %s\xFF", &msgPtr);
- return;
-
- case SCR_XD: /* x-packet data */
- errmsg( s );
- return;
-
- case SCR_ST: /* File status */
- switch (c)
- {
- case ST_OK: /* Transferred OK */
- PutString( "\x9B20CFile Transferred OK" );
- return;
-
- case ST_DISC: /* Discarded */
- PutString( "\x9B20CFile was discarded" );
- return;
-
- case ST_INT: /* Interrupted */
- PutString( "\x9B20CTransfer is interrupted");
- return;
-
- case ST_SKIP: /* Skipped */
- format( PutFormat, "\x9B20CSkipping %s\xFF", &s );
- return;
-
- default:
- errmsg( "*** screen() called with bad status ***" );
- return;
- }
-
- case SCR_PN: /* Packet number */
- return;
-
- case SCR_PT: /* Packet type or pseudotype */
- switch ( c )
- {
- case 'D':
- format( PutFormat, "Packet #%3d,", &pktnum );
- format( PutFormat, "%7ld Bytes\xFF", &ffc );
- return;
-
- case 'E':
- sprintf( msg, "Error: %s", s);
- errmsg( msg );
- return;
-
- case 'N':
- case 'Q':
- if ( ffc > 0 )
- {
- ++badpkts;
- format( PutFormat, "\x9B25C, %3d Bad Packets\xFF",
- &badpkts );
- }
- else
- format( PutFormat, "Negotiating for Parameters ...");
- return;
-
- case 'T':
- errmsg( "Timeout" );
- return;
-
- case 'Z':
- /* Force File Size Update */
- screen( SCR_PT, 'D', 0L, "" );
- return;
-
- default :
- return;
- }
- case SCR_TC: /* transaction complete */
- PutChar(BEL);
- return;
-
- case SCR_EM: /* Error message */
- sprintf( msg, "Error: %s", s);
- errmsg( msg );
- return;
-
- case SCR_WM: /* Warning message */
- sprintf( msg, "Warning: %s", s);
- errmsg( msg );
- return;
-
- case SCR_TU: /* Undelimited text */
- case SCR_TN: /* Text delimited at beginning */
- case SCR_TZ: return; /* Text delimited at end */
- case SCR_QE: parm1.s = s; parm1.n = n;
- format( PutFormat, "%s = %ld\xFF", &parm1 );
- return;
- default:
- errmsg( "*** screen() called with bad object ***" );
- return;
- }
- }
-
- /* F. da Cruz, Columbia University Center for Computing Activities */
- /* Modified for use with MS-DOS by: Jan A. van der Eijk, NUS Corp., July 1985 */
- /* ... and for the Amiga August 86 by Jeff Lydiatt, Vancouver, BC, Canada.
- /*
- Copyright (C) 1985, Trustees of Columbia University in the City of New York.
- Permission is granted to any individual or institution to use, copy, or
- redistribute this software so long as it is not sold for profit, provided this
- copyright notice is retained.
- */
-
- /*
- Functions (n is one of the predefined file numbers from ckcker.h):
-
- zopeni(n,name) -- Opens an existing file for input.
- zopeno(n,name) -- Opens a new file for output.
- zclose(n) -- Closes a file.
- zchin(n,&c) -- Gets the next character from an input file.
- zsout(n,s) -- Write a null-terminated string to output file, buffered.
- zsoutl(n,s) -- Like zsout, but appends a line terminator.
- zsoutx(n,s,x) -- Write x characters to output file, unbuffered.
- zchout(n,c) -- Add a character to an output file, unbuffered.
- zchki(name) -- Check if named file exists and is readable, return size.
- zchko(name) -- Check if named file can be created.
- znewn(name,s) -- Make a new unique file name based on the given name.
- zdelet(name) -- Delete the named file.
- zxpand(string) -- Expands the given wildcard string into a list of files.
- znext(string) -- Returns the next file from the list in "string".
- zrtol(n1,n2) -- Convert remote filename into local form.
- zltor(n1,n2) -- Convert local filename into remote form.
- */
- /* Declarations */
-
- static FILE *fp[ZNFILS] = { /* File pointers */
- NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-
-
- static int fcount; /* Number of files in wild group */
- static CHAR *mtchs[MAXWLD], /* Matches found for filename */
- **mtchptr; /* Pointer to current match */
-
- /* C H K F N -- Internal function to verify file number is ok */
-
- /*
- Returns:
- -1: File number n is out of range
- 0: n is in range, but file is not open
- 1: n in range and file is open
- */
- static int chkfn(n)
- int n;
- {
- switch (n) {
- case ZCTERM:
- case ZSTDIO:
- case ZIFILE:
- case ZOFILE:
- case ZDFILE:
- case ZTFILE:
- case ZPFILE:
- case ZSFILE: break;
- default:
- debug(F101,"chkfn: file number out of range","",n);
- fprintf(stderr,"?File number out of range - %d\n",n);
- return(-1);
- }
- return( (fp[n] == NULL) ? 0 : 1 );
- }
-
- /* Z O P E N I -- Open an existing file for input. */
- /* Return 1 if successful */
-
- zopeni(n,name)
- register int n;
- CHAR *name;
- {
-
- debug(F111," zopeni",name,n);
- debug(F101," fp","",(int) fp[n]);
- if (chkfn(n) != 0) return(0);
- if (n == ZSTDIO) { /* Standard input? */
- fp[ZIFILE] = stdin;
- return(1);
- }
- fp[n] = fopen(name,"r"); /* Real file. */
- debug(F111," zopeni", name, (int) fp[n]);
- if (fp[n] == NULL)
- format(PutChar,"Can't open: %s\n\xFF", &name);
- return((fp[n] != NULL) ? 1 : 0);
- }
-
- /* Z O P E N O -- Open a new file for output. */
- /* Return 1 if successful */
-
- zopeno(n,name)
- register int n;
- char *name;
- {
- char xname[50];
-
- debug(F111," zopeno",name,n);
- if (chkfn(n) != 0) return(0);
- if ((n == ZCTERM) || (n == ZSTDIO)) { /* Terminal or standard output */
- fp[ZOFILE] = stdout;
- debug(F101," fp[]=stdout", "", (int) fp[n]);
- return(1);
- }
-
- *xname = '\0';
- if ( n == ZOFILE && *dirname )
- strcpy( xname, dirname );
- strcat( xname, name );
-
- fp[n] = fopen(xname,"w"); /* Real file. */
- if (fp[n] == NULL)
- perror( "zopeno" );
- if (n == ZDFILE) setbuf(fp[n],NULL); /* Make debugging file unbuffered */
- debug(F101, " fp[n]", "", (int) fp[n]);
- return((fp[n] != NULL) ? 1 : 0);
- }
-
- /* Z C L O S E -- Close the given file. */
- /* Return 1 if successful */
-
- zclose(n)
- register int n;
- {
- if (chkfn(n) < 1) return(0);
- if ((fp[n] != stdout) && (fp[n] != stdin)) fclose(fp[n]);
- fp[n] = NULL;
- return(1);
- }
-
- /* Z C H I N -- Get a character from the input file. */
-
- /* Returns -1 if EOF, 0 otherwise with character returned in argument */
-
- zchin(n,c)
- int n;
- CHAR *c;
- {
- register int a;
-
- a = getc(fp[n]);
- if (a == EOF) return(-1);
- *c = a & 0377;
- return(0);
- }
- #ifdef DEBUG
- /* Z S O U T -- Write a string to the given file, buffered. */
- /* Returns -1 if ERROR, 0 otherwise */
-
- zsout(n,s)
- register int n;
- CHAR *s;
- {
- if (chkfn(n) < 1) return(-1);
- fprintf(fp[n],s);
- return(0);
- }
- #endif
-
- /* Z S O U T L -- Write string to file, with line terminator, buffered */
- /* Returns -1 if ERROR, 0 otherwise */
-
- zsoutl(n,s)
- register int n;
- CHAR *s;
- {
- if (chkfn(n) < 1) return(-1);
- fprintf(fp[n],"%s\n",s);
- return(0);
- }
-
- #ifdef DEBUG
- /* Z S O U T X -- Write x characters to file, unbuffered. */
- /* Returns -1 if ERROR, 0 otherwise */
-
- zsoutx(n,s,x)
- register int n;
- int x;
- CHAR *s;
- {
- if (chkfn(n) < 1) return(-1);
- return(write(fileno(fp[n]),s,x));
- }
- #endif
-
- /* Z C H O U T -- Add a character to the given file. */
- /* Returns -1 if ERROR, 0 otherwise */
-
- zchout(n,c)
- register int n;
- CHAR c;
- {
- FILE *f;
-
- if (chkfn(n) < 1) return(-1);
- f = fp[n];
- if (n == ZSFILE)
- return(write(fileno(f),&c,1)); /* Use unbuffered for session log */
- else putc(c, f); /* Buffered for everything else */
- if ( ferror(f) )
- return -1;
- return 0;
- }
-
- /* Z C H K I -- Check if input file exists and is readable */
-
- /*
- Returns:
- >= 0 if the file can be read (returns the size).
- -1 if file doesn't exist or can't be accessed,
- -2 if file exists but is not readable (e.g. a directory file).
- -3 if file exists but protected against read access.
- */
- /*
- Directory files, special files, and symbolic links are not readable.
- */
- long zchki(name)
- CHAR *name;
- {
- struct FileInfoBlock *FBlock;
- long *FLock;
- long result;
-
- if ( (FLock = (struct FileLock *) Lock(name, ACCESS_READ)) == NULL)
- return -1;
-
- if ( (FBlock = (struct FileInfoBlock *)
- AllocMem( (long)sizeof(struct FileInfoBlock), (long)(MEMF_CHIP))) != NULL)
- if ( FBlock == NULL )
- result = -1;
- else
- {
- if ( !Examine( FLock, FBlock) )
- result = -1;
- else
- {
- if ( FBlock->fib_DirEntryType > 0 )
- result = -2; /* It's a directory */
- else
- result = FBlock->fib_Size;
- }
- FreeMem( FBlock, (long)sizeof(struct FileInfoBlock) );
- }
-
- UnLock( FLock );
- return result;
-
- }
-
- #ifdef DEBUG /*----Not used by Kermit----*/
-
- /* Z C H K O -- Check if output file can be created */
-
- /*
- Returns -1 if write permission for the file would be denied, 0 otherwise.
- */
- zchko(name)
- CHAR *name;
- {
- int x;
- extern int errno; /* System error code */
- extern int access(); /* Aztec Builtin Function*/
-
- x = access(name, 2); /* Check access of path. */
-
- x = 0; /* assume it is ok to open file under DOS */
- if (x != 0) {
- debug(F111,"zchko access failed:",name,errno);
- return(-1);
- } else {
- debug(F111,"zchko access ok:",name,x);
- return(0);
- }
- }
- #endif
-
- /* Z D E L E T -- Delete the named file. */
-
- zdelet(name)
- CHAR *name;
- {
- unlink(name);
- }
-
-
- /* Z R T O L -- Convert remote filename into local form */
-
- /* For Amiga, just return name2 as name. */
-
- zrtol(name,name2)
- CHAR *name;
- CHAR *name2;
- {
- strcpy( name2, name );
- }
-
-
- /* Z L T O R -- Convert filename from local format to common form. */
-
- zltor(name,name2)
- CHAR *name;
- CHAR *name2;
- {
- CHAR work[100];
- register CHAR *cp;
- register CHAR *pp;
- register int dc = 0;
-
- strcpy(work,name);
- for (cp = pp = work; *cp != '\0'; cp++)
- { /* strip path name */
- if (*cp == '/' || *cp == ':')
- {
- pp = cp;
- pp++;
- }
- else if (islower(*cp)) *cp = toupper(*cp); /* Uppercase letters */
- else if (*cp == '~') *cp = 'X'; /* Change tilde to 'X' */
- else if ((*cp == '.') && (++dc > 1)) *cp = 'X'; /* & extra dots */
- }
- cp = name2; /* If nothing before dot, */
- if (*pp == '.') *cp++ = 'X'; /* insert 'X' */
- strcpy(cp,pp);
- }
-
- /* Z N E X T -- Get name of next file from list created by zxpand(). */
- /*
- Returns >0 if there's another file, with its name copied into the arg string,
- or 0 if no more files in list.
- */
- znext(fn)
- CHAR *fn;
- {
- if (fcount-- > 0) strcpy(fn,*mtchptr++);
- else *fn = '\0';
- debug(F111,"znext",fn,fcount+1);
- return(fcount+1);
- }
-
- /* Z N E W N -- Make a new name for the given file */
-
- znewn(fn,s)
- CHAR *fn,
- **s;
- {
- /* If you really need this function on the Amiga, you might try */
- /* Aztec's mktemp, or concatenating "Temp"+TimeStamp */
-
- static CHAR *buf = (CHAR *)"Kermit.NewFile";
-
- *s = buf;
- }
-
-
- /* Z X P A N D -- Expand a wildcard string into an array of strings */
- /*
- Returns the number of files that match fn1, with data structures set up
- so that first file (if any) will be returned by the next znext() call.
- */
-
- zxpand(fn)
- CHAR *fn;
- {
- static CHAR *notImplemented = (CHAR *)"NotImplemented!";
-
- fcount = 0;
- mtchs[0] = notImplemented;
- debug(F111,"zxpand",mtchs[0],fcount);
- return(fcount);
- }
-
- /* Z F C D A T -- Put file creation date/time in str. */
- /* returns 1 if able to get date, 0 otherwise. */
-
- zfcdat(fname,str)
- CHAR *fname,
- *str;
- {
- strcpy( str, "<zfcdat: Not Implemented>" );
- return 0;
- }
-
-
- /* Z F R E E -- Return total number of free bytes on drive specified */
-
- long zfree(drive)
- CHAR *drive;
- {
- return 0x7FFFFFFF;
-
- }
-
- /* Z F P D A T -- Stamp a given file name with the given date */
-
- zfpdat(fname,dattim)
- CHAR *fname,
- *dattim;
- {
- /* Null Function on the Amiga. */
- }
-
-
- /* L C K T I O module */
-
- /* C-Kermit interrupt, terminal control & i/o functions for Amiga. */
-
- /* F. da Cruz, Columbia University Center for Computing Activities */
- /* Modified for use with PC-DOS by: Jan A. van der Eijk, NUS Corp., July 1985 */
- /* ... and for the Amiga August 1986 by Jeff Lydiatt, Vancouver, Canada. */
-
- /*
- Copyright (C) 1985, Trustees of Columbia University in the City of New York.
- Permission is granted to any individual or institution to use, copy, or
- redistribute this software so long as it is not sold for profit, provided this
- copyright notice is retained.
- */
-
- /*
- Variables available to outside world:
-
- dftty -- Pointer to default tty name string, like "/dev/tty".
- dfloc -- 0 if dftty is console, 1 if external line.
- dfprty -- Default parity
- dfflow -- Default flow control
- ckxech -- Flag for who echoes console typein:
- 1 - The program (system echo is turned off)
- 0 - The system (or front end, or terminal).
- functions that want to do their own echoing should check this flag
- before doing so.
-
- Functions for assigned communication line (either external or console tty):
-
- ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access.
- ttclos() -- Close & reset the tty, releasing any access lock.
- ttpkt(speed,flow) -- Put the tty in packet mode and set the speed.
- ttvt(speed,flow) -- Put the tty in virtual terminal mode.
- or in DIALING or CONNECTED modem control state.
- ttinl(dest,max,timo,eol)-- Timed read line from the tty.
-
- ttinc(timo) -- Timed read character from tty.
- ttchk() -- See how many characters in tty input buffer.
- ttol(string,length) -- Write a string to the tty.
- ttoc(c) -- Write a character to the tty.
- ttflui() -- Flush tty input buffer.
-
- */
-
- /*
- Functions for console terminal:
-
- conoc(c) -- Unbuffered output, one character to console.
- conol(s) -- Unbuffered output, null-terminated string to the console.
- conola(s) -- Unbuffered output, array of strings to the console.
- conxo(n,s) -- Unbuffered output, n characters to the console.
- conchk() -- Check if characters available at console (bsd 4.2).
- Check if escape char (^\) typed at console (System III/V).
- coninc(timo) -- Timed get a character from the console.
-
- Time functions
-
- msleep(m) -- Millisecond sleep
- ztime(&s) -- Return pointer to date/time string
- */
-
- /* T T O L -- Similar to "ttinl", but for writing. */
- /* returns number of characters writen to Com port */
-
- ttol(s,n)
- int n;
- register CHAR *s;
- {
- register int j = n;
-
- for(; j > 0; j--)
- SerIOWrite( *s++ );
- return n;
- }
-
- /* T T I N C -- Read a character from the communication line */
- /* return the character if possible otherwise -1 */
-
- /* Argument timo, timout in seconds */
-
- ttinc(timo)
- int timo;
- {
- UBYTE ch;
- BOOL timerOn = FALSE;
-
- do
- {
- if ( CheckSerIO() )
- {
- ch = SerIORead();
- return (int)ch;
- }
- else if ( chkint() )
- timerOn = FALSE;
- if ( !timerOn )
- {
- StartTimer( (long)timo, 0L );
- timerOn = TRUE;
- }
- Wait( waitMask );
-
- } while( !TimerExpired() );
-
- /* if not the above, the timer must have timed out */
- return -1;
- }
-
- /* T T I N L -- Read a record (up to break character) from comm line. */
- /*
- If no break character encountered within "max", return "max" characters,
- with disposition of any remaining characters undefined. Otherwise, return
- the characters that were read, including the break character, in "dest" and
- the number of characters read as the value of function, or 0 upon end of
- file, or -1 if an error occurred. Times out & returns error if not completed
- within "timo" sconds.
- */
-
- ttinl(dest,maxnum,timo,eol)
- register int maxnum;
- int timo;
- CHAR eol;
- register CHAR *dest;
- {
-
- register int i;
- register int c;
- int timeOut = timo;
-
- if ( !(1 <= timeOut && timeOut <= URTIME) )
- timeOut = DMYTIM;
- for ( i = c = 0; (i < maxnum) && (c != eol) ; i++)
- {
- c = ttinc( timeOut );
- if ( c < 0 )
- break;
- dest[i] = c; /* Store the character */
- if ( i == 0 )
- timeOut = 2;
- }
- return(i); /* Return the count. */
- }
-
- /* TTFLUI --- Flush tty input buffer */
-
- ttflui() {
-
- FlushSerIO();
- return 0;
- }
-
- /* TTFLUO --- Flush tty output buffer */
-
- ttfluo()
- {
- return 0; /* Should not do on the Amiga */
- }
-
- /* T T S O M E check if character available in receive buffer */
-
- ttsome()
- {
- if ( !CheckSerIO() )
- return(0);
- return 1;
- }
- ttchk() /* Same function as ttsome() */
- {
- return ttsome();
- }
-
- /* S L E E P wait for m seconds */
-
- sleep(m)
- int m;
- {
- if ( m )
- {
- StartTimer((long)m, 0L);
- Wait( (unsigned long)(1L << GetTimerSigBit()) );
- }
- }
-
- /* Z T I M E -- Return date/time string */
-
- ztime(s)
- CHAR **s;
- {
- static CHAR *notimp = (CHAR *)"<ztime: Not implemented>";
- /* Aterm Has it's own Clock */
- *s = notimp;
- }
-