home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
019.lha
/
Aterm
/
Kermit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-10
|
39KB
|
1,499 lines
/* 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;
}