*** gcmdline.c	Sun Dec 26 20:05:38 1999
--- ../gkermit68/GCMDLINE.C	Tue Mar 12 23:10:51 2002
***************
*** 35,41 ****
  
  extern int nfils, parity, text, backup, rpsiz, urpsiz, timint;
  extern int literal, quiet, keep, streamok, nomodes, manual, xonxoff, noxonxoff;
! extern char ttname[], *cmerrp, *cmarg, *cmarg2;
  extern FILE * db;
  
  /* Variables exported from this module */
--- 35,41 ----
  
  extern int nfils, parity, text, backup, rpsiz, urpsiz, timint;
  extern int literal, quiet, keep, streamok, nomodes, manual, xonxoff, noxonxoff;
! extern char ttname[], *cmarg, *cmarg2;
  extern FILE * db;
  
  /* Variables exported from this module */
***************
*** 193,198 ****
--- 193,202 ----
  	    text = 0;
  	    break;
  
+ #ifdef CPM68K
+ 	  /* CP/M doesn't support case-sensitive args so allow 't' */
+ 	  case 't':
+ #endif
  	  case 'T':			/* Text file transfer */
  	    manual = 1;
  	    text = 1;
***************
*** 228,235 ****
  	    }
  	    if (db) {
  		extern char * versio, * build;
! 		if (!versio) versio = "";
! 		if (!build) build = "";
  		debug = 1;
  		setbuf(db,NULL);
  		fprintf(db,"%s: %s\n",
--- 232,239 ----
  	    }
  	    if (db) {
  		extern char * versio, * build;
! 		if (versio == (char *)NULL) versio = "";
! 		if (build == (char *)NULL) build = "";
  		debug = 1;
  		setbuf(db,NULL);
  		fprintf(db,"%s: %s\n",
***************
*** 237,243 ****
--- 241,249 ----
  			(*build ? build : "BUILD UNKNOWN")
  			);
  		fprintf(db,"MAXPATHLEN = %d\n",MAXPATHLEN);
+ #ifndef NOGETENV
  		if (gptr) fprintf(db,"GKERMIT=\"%s\"\n",gptr);
+ #endif
  	    }
  	    break;
  
***************
*** 334,344 ****
  VOID
  usage() {
      extern char * versio, * build, * url, * email;
!     if (!versio) versio = "";
      if (!*versio) versio = "gkermit UNKNOWN VERSION";
!     if (!build) build = "UNKNOWN BUILD";
!     if (!url) url = "";
!     if (!email) email = "";
      fprintf(stderr,"%s: %s.\n",versio,build);
      fprintf(stderr,"Usage:  gkermit [ options ]\n");
      fprintf(stderr,"Options:\n");
--- 340,350 ----
  VOID
  usage() {
      extern char * versio, * build, * url, * email;
!     if (versio == (char *)NULL) versio = "";
      if (!*versio) versio = "gkermit UNKNOWN VERSION";
!     if (build == (char *)NULL) build = "UNKNOWN BUILD";
!     if (url == (char *)NULL) url = "";
!     if (email == (char *)NULL) email = "";
      fprintf(stderr,"%s: %s.\n",versio,build);
      fprintf(stderr,"Usage:  gkermit [ options ]\n");
      fprintf(stderr,"Options:\n");
*** gkermit.h	Sun Dec 26 21:25:52 1999
--- ../gkermit68/GKERMIT.H	Thu Mar 14 22:03:37 2002
***************
*** 27,36 ****
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  
! #ifndef _GKERMIT_H
! #define _GKERMIT_H
  
  #include <stdio.h>
  
  /* Kermit protocol definitions */
  
--- 27,39 ----
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  
! #ifndef _GKERM_H
! #define _GKERM_H
  
+ /* avoid including stdio twice on CP/M-68K */
+ #ifndef CPM68K
  #include <stdio.h>
+ #endif
  
  /* Kermit protocol definitions */
  
***************
*** 90,96 ****
--- 93,101 ----
  #ifdef __STDC__
  #define VOID void
  #else
+ #ifndef CPM68K		/* CP/M-68K 1.3 has void */
  #define VOID int
+ #endif
  #endif /* __STDC__ */
  
  /* SVORPOSIX = System V or POSIX */
***************
*** 231,236 ****
--- 236,248 ----
  _MYPROTOTYPE( VOID usage, (void) );	/* Give usage message */
  _MYPROTOTYPE( int gwart, (void) );	/* State table switcher */
  
+ #ifdef CPM68K
+ /* function prototypes for CP/M-68K */
+ _MYPROTOTYPE( FILE *fopen, (void) );
+ _MYPROTOTYPE( FILE *fopenb, (void) );
+ _MYPROTOTYPE( char *malloc, (void) );
+ #endif
+ 
  /* Externs */
  
  extern int errno;
***************
*** 238,243 ****
  extern int debug;
  #endif /* _GKERMIT_C */
  
! #endif /* _GKERMIT_H */
  
  /* End gkermit.h */
--- 250,255 ----
  extern int debug;
  #endif /* _GKERMIT_C */
  
! #endif /* _GKERM_H */
  
  /* End gkermit.h */
*** gproto.w	Sun Dec 26 20:05:38 1999
--- ../gkermit68/GPROTO.W	Thu Mar 14 22:05:11 2002
***************
*** 33,39 ****
  _MYPROTOTYPE( int closof, (void) );	/* Close output file */
  _MYPROTOTYPE( VOID errpkt, (char *) );	/* Send Error packet */
  
! extern char * xdata, *rdatap, **cmlist, *cmarg, *rpar(), strbuf[], filnam[];
  extern int start, bctu, bctr, delay, cx, cz, failure, attributes, datalen;
  extern int streamok, streaming, timint;
  extern FILE * db;
--- 33,39 ----
  _MYPROTOTYPE( int closof, (void) );	/* Close output file */
  _MYPROTOTYPE( VOID errpkt, (char *) );	/* Send Error packet */
  
! extern char * xdata, *rdatap, **cmlist, *cmarg, *rpar(), filnam[];
  extern int start, bctu, bctr, delay, cx, cz, failure, attributes, datalen;
  extern int streamok, streaming, timint;
  extern FILE * db;
***************
*** 41,47 ****
  static int x;
  
  static VOID
! streamon() {				/* Start streaming if negotiated */
      x = 0;
      if (streamok > 0) {
  	streaming = 1;
--- 41,47 ----
  static int x;
  
  static VOID
! stremon() {				/* Start streaming if negotiated */
      x = 0;
      if (streamok > 0) {
  	streaming = 1;
***************
*** 72,78 ****
          if (sfile() < 0) {		/* Yes, open it, send F packet, */
  	    errpkt("sfile");
  	} else {			/* No error */
! 	    streamon();
  	    BEGIN ssfil;
  	}
      } else {				/* No files to send, */
--- 72,78 ----
          if (sfile() < 0) {		/* Yes, open it, send F packet, */
  	    errpkt("sfile");
  	} else {			/* No error */
! 	    stremon();
  	    BEGIN ssfil;
  	}
      } else {				/* No files to send, */
***************
*** 148,154 ****
      spar(rdatap);			/* Set parameters from it */
      ack1(rpar());			/* ACK with our parameters */
      bctu = bctr;			/* Switch to negotiated block check */
!     streamon();
      BEGIN srfil;			/* Wait for file or EOT */
  }
  
--- 148,154 ----
      spar(rdatap);			/* Set parameters from it */
      ack1(rpar());			/* ACK with our parameters */
      bctu = bctr;			/* Switch to negotiated block check */
!     stremon();
      BEGIN srfil;			/* Wait for file or EOT */
  }
  
***************
*** 160,166 ****
      } else {
  	encstr(filnam);
  	ack1(xdata);
! 	streamon();
  	BEGIN sratt;
      }
  }
--- 160,166 ----
      } else {
  	encstr(filnam);
  	ack1(xdata);
! 	stremon();
  	BEGIN sratt;
      }
  }
*** gunixio.c	Sun Dec 26 23:32:26 1999
--- ../gkermit68/GUNIXIO.C	Tue Mar 12 23:10:51 2002
***************
*** 70,79 ****
--- 70,83 ----
  #endif /* POSIX */
  
  #include <ctype.h>			/* Character types */
+ #ifndef CPM68K
  #include <sys/types.h>			/* Needed e.g. by <stat.h> */
+ #endif
  #include <signal.h>			/* Interrupts */
  #include <setjmp.h>			/* Longjumps */
+ #ifndef CPM68K
  #include <sys/stat.h>			/* File exist, file size */
+ #endif
  #include <errno.h>			/* Error symbols */
  #include "gkermit.h"			/* gkermit definitions */
  
***************
*** 142,147 ****
--- 146,175 ----
  #endif /* USE_GETCHAR */
  #endif /* DUMBIO */
  
+ #ifdef CPM68K
+ 
+ /* extracted from <osif.h> (including it in full results in name clashes) */
+ #define __OSIF(fn,arg) __BDOS((fn),(LONG)(arg))	/* CPM68K does it this way  */
+ #define EXIT		0	/* Exit to BDOS             */
+ #define CONIN		1	/* direct echoing con input */
+ #define CONOUT		2	/* Direct console output    */
+ #define LSTOUT		5	/* Direct list device output*/
+ #define CONIO		6	/* Direct console I/O       */
+ #define C_WRITESTR	9	/* Console string output    */
+ #define CONBUF		10	/* Read console buffer      */
+ #define C_STAT		11	/* Get console status       */
+ #define S_BDOSVER	12	/* Get System BDOS Ver Num  */
+ /* end of extract from <osif.h> */
+ 
+ #define SCOUNT	163000		/* sleep time constant for a 33MHz 68020 */
+ #define ACOUNT	10000		/* alarm time constant */
+ static int atime;
+ static long acount;
+ 
+ extern int text;		/* 0=binary, 1=text */
+ 
+ #endif /* CPM68K */
+ 
  /* Header file deficiencies section... */
  
  #ifndef R_OK
***************
*** 271,277 ****
  
  VOID
  logerr(s) char * s; {			/* Log text and errno */
!     if (!s) s = "";
      if (!debug) return;
      if (db) fprintf(db,"%s: errno = %d\n",s,errno);
  }
--- 299,305 ----
  
  VOID
  logerr(s) char * s; {			/* Log text and errno */
!     if (s == (char *)NULL) s = "";
      if (!debug) return;
      if (db) fprintf(db,"%s: errno = %d\n",s,errno);
  }
***************
*** 473,480 ****
--- 501,512 ----
      }
  #else
      if (xonxoff) {
+ #ifdef CPM68K
+ 	if (debug) fprintf(db,"ttpkt CPM68K can't do Xon/Xoff!\n");
+ #else
  	ttraw.sg_flags |= TANDEM;
  	if (debug) fprintf(db,"ttpkt BSD Xon/Xoff\n");
+ #endif /* CPM68K */
      }
  #endif /* SETXONXOFF */
      ttraw.sg_flags &= ~(ECHO|CRMOD);    /* No echo, etc */
***************
*** 550,556 ****
--- 582,590 ----
      x = ioctl(0,TCFLSH,0);
  #else
  #ifdef BSD
+ #ifndef CPM68K
      x = ioctl(0,TIOCFLUSH,&n);
+ #endif /* CPM68K */
  #endif /* BSD */
  #endif /* SYSV */
  #endif /* POSIX */
***************
*** 569,575 ****
  
   Call with:
     dest - where to put it
!    max  - maximum length
     timo - timeout (seconds, 0 = none)
     eol  - packet terminator
     turn - half-duplex line turnaround character to wait for, 0 = none
--- 603,609 ----
  
   Call with:
     dest - where to put it
!    maxl - maximum length
     timo - timeout (seconds, 0 = none)
     eol  - packet terminator
     turn - half-duplex line turnaround character to wait for, 0 = none
***************
*** 582,590 ****
  
  int
  #ifdef __STDC__
! ttinl(char * dest, int max, int timo, char eol, char soh, int turn)
  #else
! ttinl(dest,max,timo,eol,soh,turn) int max, timo, turn; char eol, soh, *dest;
  #endif /* __STDC__ */
  {
      int n = 0, x = 0, flag = 0, rc = 0, ccn = 0; /* Local variables */
--- 616,624 ----
  
  int
  #ifdef __STDC__
! ttinl(char * dest, int maxl, int timo, char eol, char soh, int turn)
  #else
! ttinl(dest,maxl,timo,eol,soh,turn) int maxl, timo, turn; char eol, soh, *dest;
  #endif /* __STDC__ */
  {
      int n = 0, x = 0, flag = 0, rc = 0, ccn = 0; /* Local variables */
***************
*** 607,617 ****
--- 641,665 ----
      } else {				/* Otherwise... */
  	while (1) {			/* Read until we have a packet */
  #ifdef DUMBIO
+ #ifdef CPM68K
+ 	    /* use direct console I/O in order to implement a
+ 	     * timeout counter
+ 	     */
+ 	    if (timo) {
+ 	        if (__OSIF(CONIO, 0xfe) == 0) {
+ 		    /* no char ready, decrement timeout counter */
+ 		    tttimo();
+ 		    continue;
+ 		}
+ 	    }
+ 	    c = (char)__OSIF(CONIO, 0xff);	/* blocking read */
+ #else
  	    x = read(0,&c,1);		/* Dumb blocking read byte loop */
  	    if (x < 0) {
  		logerr("ttinl XX read 1");
  		rc = -2;
  	    }
+ #endif CPM68K
  #else
  #ifdef USE_GETCHAR
  	    errno = 0;
***************
*** 710,716 ****
  	      continue;			/* Skip stuff between packets */
  	    flag = 1;			/* Have SOH */
  
! 	    if (n >= max) {
  		if (debug) fprintf(db,"ttinl overflow\n");
  		rc = -2;
  		goto xttinl;
--- 758,764 ----
  	      continue;			/* Skip stuff between packets */
  	    flag = 1;			/* Have SOH */
  
! 	    if (n >= maxl) {
  		if (debug) fprintf(db,"ttinl overflow\n");
  		rc = -2;
  		goto xttinl;
***************
*** 822,829 ****
--- 870,879 ----
      while (n > 0) {			/* Send the packet with write() */
  	i = write(1,&s[m],n);		/* Allowing for partial results */
  	if (i < 0) {
+ #ifdef EWOULDBLOCK
  	    if (errno == EWOULDBLOCK)	/* and even no results at all.. */
  	      continue;
+ #endif
  	    logerr("ttol write");
  	    return(-1);
  	}
***************
*** 853,858 ****
--- 903,933 ----
  
  long
  zchki(fn) char * fn; {			/* Check if file is readable */
+ #ifdef CPM68K
+     int fd;
+     long fsize, _filesz();
+ 
+     /* CP/M-68K doesn't have stat().
+      * Instead, we have to open the file and then use _filesz().
+      */
+     if (fn == (char *)NULL)
+ 	return(-1);
+     errno = 0;
+     if (text)
+ 	fd = open(fn,0);		/* text mode */
+     else
+ 	fd = openb(fn,0);		/* binary mode */
+     if (fd == -1) {
+ 	if (debug)
+ 	  fprintf(db,"zchki open %s errno = %d\n",fn,errno);
+ 	return(-1);
+     }
+     fsize = _filesz(fd);
+     close(fd);
+     if (debug)
+       fprintf(db,"zchki fsize = %ld\n",fsize);	/* GH */
+     return(fsize);
+ #else	/* CPM68K */
      struct stat buf;
      if (!fn) return(-1);
      if (stat(fn,&buf) < 0)
***************
*** 869,874 ****
--- 944,950 ----
  	return(-2);
      }
      return(buf.st_size);
+ #endif	/* CPM68K */
  }
  
  int
***************
*** 876,882 ****
      int i, x;
      char * s;
  
!     if (!fn)				/* Defend against empty name */
        fn = "";
      if (!*fn)
        return(-1);
--- 952,958 ----
      int i, x;
      char * s;
  
!     if (fn == (char *)NULL)		/* Defend against empty name */
        fn = "";
      if (!*fn)
        return(-1);
***************
*** 899,912 ****
--- 975,1004 ----
  	  s = ".";
      }
      errno = 0;
+ #ifdef CPM68K
+     /* checking for write access to '.' is meaningless */
+     if (*s == '.') {
+ 	x = 0;
+     } else {
+         x = access(s,W_OK);		/* Check access of path. */
+     }
+ #else
      x = access(s,W_OK);			/* Check access of path. */
+ #endif
      if (debug) fprintf(db,"zchko(%s) x = %d errno = %d\n",s,x,errno);
      return((x < 0) ? -1 : 0);           /* and return. */
  }
  
  int
  zopeni(name) char *name; {		/* Open existing file for input */
+ #ifdef CPM68K
+     if (text)
+ 	ifp = fopen(name,"r");		/* open in text mode */
+     else
+ 	ifp = fopenb(name,"r");		/* open in binary mode */
+ #else
      ifp = fopen(name,"r");
+ #endif
      if (debug) fprintf(db,"zopeni %s: %d\n",name, ifp ? 0 : errno);
      filelength = zchki(name);
      if (filelength < 0)
***************
*** 919,925 ****
--- 1011,1024 ----
  int
  zopeno(name) char *name; {		/* Open new file for output */
      errno = 0;
+ #ifdef CPM68K
+     if (text)
+ 	ofp = fopen(name,"w");		/* text mode */
+     else
+ 	ofp = fopenb(name,"w");		/* binary mode */
+ #else
      ofp = fopen(name,"w");
+ #endif
      if (debug) fprintf(db,"zopeno %s: %d\n",name, ofp ? 0 : errno);
      if (ofp) {
  	strncpy(ofile,name,MAXPATHLEN);
***************
*** 998,1013 ****
  
  int
  zbackup(fn) char * fn; {		/* Back up existing file */
      struct stat buf;
      int i, j, k, x, state, flag;
      char *p, newname[MAXPATHLEN+12];
  
!     if (!fn)				/* Watch out for null pointers. */
        return(-1);
      if (!*fn)				/* And empty names. */
        return(-1);
      if (stat(fn,&buf) < 0)		/* If file doesn't exist */
        return(0);			/* no need to back it up. */
  
      i = strlen(fn);			/* Get length */
      if (i > MAXPATHLEN)			/* Guard buffer */
--- 1097,1120 ----
  
  int
  zbackup(fn) char * fn; {		/* Back up existing file */
+ #ifndef CPM68K
      struct stat buf;
+ #endif
      int i, j, k, x, state, flag;
      char *p, newname[MAXPATHLEN+12];
  
!     if (fn == (char *)NULL)		/* Watch out for null pointers. */
        return(-1);
      if (!*fn)				/* And empty names. */
        return(-1);
+ #ifdef CPM68K
+     /* CP/M-68K doesn't have stat(), use access() instead */
+     if (access(fn,0) < 0)
+ 	return(0);
+ #else
      if (stat(fn,&buf) < 0)		/* If file doesn't exist */
        return(0);			/* no need to back it up. */
+ #endif
  
      i = strlen(fn);			/* Get length */
      if (i > MAXPATHLEN)			/* Guard buffer */
***************
*** 1057,1064 ****
--- 1164,1183 ----
  	if ((x + k + 3) > MAXPATHLEN)
  	  x = MAXPATHLEN - k - 3;
  	sprintf(&newname[x],".~%d~",i); /* Make a backup name */
+ #ifdef CPM68K
+ 	if (access(newname,0) < 0) {
+ #else
  	if (stat(newname,&buf) < 0) {	/* If it doesn't exist */
+ #endif
  	    errno = 0;
+ #ifdef CPM68K
+ 	/* CP/M-68K doesn' have link(), use rename() instead */
+ 	    if (rename(fn,newname) < 0) {
+ 		if (debug)
+ 		  fprintf(db,"zbackup failed: rename(%s,%s): %d\n",fn,newname,errno);
+ 		return(-1);
+ 
+ #else
  	    if (link(fn,newname) <  0) { /* Rename old file to backup name */
  		if (debug)
  		  fprintf(db,"zbackup failed: link(%s): %d\n",newname,errno);
***************
*** 1067,1072 ****
--- 1186,1192 ----
  		if (debug)
  		  fprintf(db,"zbackup failed: unlink(%s): %d\n",fn,errno);
  		return(-1);
+ #endif
  	    } else {
  		if (debug)
  		  fprintf(db,"zbackup %s: OK\n",newname);
***************
*** 1084,1089 ****
--- 1204,1211 ----
      int acase = 0, flag = 0, n = 0;
      char * p;
  
+     if (debug)
+       fprintf(db, "zrtol pktnam=%s\n", pktnam);	/* GH */
      if (literal) {
  	strncpy(lclnam,pktnam,maxlen);
      } else {
***************
*** 1170,1172 ****
--- 1292,1348 ----
      zincnt--;				/* Return first byte. */
      return(*zinptr++ & 0xff);
  }
+ #ifdef CPM68K
+ /*
+  * a crude sleep()
+  */
+ sleep(sec) int sec;
+ {
+     int i, a, b, c;
+     long j;
+ 
+     a = 101;
+     b = 101;
+     for (i = 0; i < sec; i++) {
+         for (j = 0; j < SCOUNT; j++) {
+             c = a * b;    /* compiles to 'muls' */
+             b = c / a;    /* compiles to 'divs' */
+         }
+     }
+     return(0);
+ }
+ /*
+  * CP/M-68K has no timers so doesn't support a real alarm()
+  * function. This just sets the timeout for tttimo()
+  */
+ alarm(sec) int sec;
+ {
+     atime = sec;
+     acount = ACOUNT;
+     return(0);
+ }
+ /*
+  * timer for ttinl()
+  */
+ tttimo()
+ {
+     int a, b, c;
+ 
+     if (atime == 0) {
+ 	return(0);		/* no alarm set */
+     }
+     a = 101;
+     b = 101;
+     c = a * b;    		/* compiles to 'muls' */
+     b = c / a;    		/* compiles to 'divs' */
+     if (--acount == 0) {
+         if (--atime == 0) {
+ 	    timerh(0);		/* timeout */
+ 	}
+ 	acount = ACOUNT;	/* reload timer */
+     }
+     return(0);
+ }
+ 
+ #endif /* CPM68K */
+ 
*** gwart.c	Fri Dec 17 17:04:22 1999
--- ../gkermit68/GWART.C	Thu Mar 14 22:08:30 2002
***************
*** 437,443 ****
  	    fprintf(stderr,"Can't open %s\n",argv[1]);
  	    fatal("unreadable input file");
  	}
!     } else infile = stdin;
  
      if (argc > 2) {
  	if ((outfile = fopen(argv[2],"w")) == NULL) {
--- 437,443 ----
  	    fprintf(stderr,"Can't open %s\n",argv[1]);
  	    fatal("unreadable input file");
  	}
!     } else infile = (FILE *)stdin;
  
      if (argc > 2) {
  	if ((outfile = fopen(argv[2],"w")) == NULL) {
