[comp.protocols.tcp-ip.ibmpc] KA9Q diffs for compilation with MSC 4.00

tom@tnosoes.UUCP (Tom Vijlbrief) (03/14/88)

Because I got many requests I am posting the diffs to the
KA9Q package (version 871225.4)

The diffs allow compilation with Microsoft C 4.00.

I also added an rsh-client. (Read the README file for details).


I have a small problem with the original version (and this one):
Vi does not operate correctly when running a telnet session on
a Sun (SunOS 3.2). Lines which start with white space are damaged
when I move the cursor downwards. I think that somewhere newline is
mapped on carriage-return/newline. 
Another problem is that the vi commandline is not cleared.
If you have a solution I would like to hear about it.
(this is the termcap entry I use:)

x9|ibmpc|Normal IBM PC used with KA9Q TELNET:\
	:bs:am:co#80:li#25:cl=\E[2J:cm=\E[%i%2;%2H:nd=\E[C:\
	:up=\E[A:do=\E[B:ce=\E[K:xt:\
	:so=\E[7m:se=\E[0m:


===============================================================================
Tom Vijlbrief
TNO Institute for Perception
P.O. Box 23				Phone: +31 34 63 14 44
3769 DE  Soesterberg			E-mail: tnosoes!tom@mcvax.cwi.nl
The Netherlands				    or:	uunet!mcvax!tnosoes!tom
===============================================================================

#---cut here---cut here---cut here---cut here---cut here---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files.
# This archive created: Mon Mar 14 14:00:43 MET 1988
# Archived by: tnosoes!tom@mcvax.cwi.nl
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(1568 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XMicrosoft C 4.00 Changes to KA9Q
X================================
X
XThe assembler files are translated to a format suitable for the
XMASM assembler.
X
XThe clocktick rate has been increased from 1 tick per second to
X100 ticks per seconds. (This is useful for fast transmission path
Xlike ethernet).
X
XA little bug in the ping command (Concerning echo timing) has been fixed.
X
XCommand line arguments are now interpreted as NET commands.
X(It used to be the name of a startup file).
XThese commands are executed after the default startup file has been
Xread.
X
XThree additional commands has been added:
X
X	rsh host command
X
Xwill execute a shell command on the specified host by means of the 
Xrexecd(8) daemon.
X
X	uprsh file host command
X
Xacts like rsh but gives file as standard input.
X
X	buprsh file host command
X
Xacts like rsh but gives binary file as standard input.
XBefore a rsh command may be given you should identify yourself
Xby means of the name command. ("name username password").
X
X
Xexamples:
X
XDOS PROMPT> net rsh rainbow date
X
Xwill show the date on the unix host rainbow and return to DOS.
X
XDOS PROMPT> net uprsh \mail\greeting rainbow mail tom
X
Xwill mail the contents of DOS-file \mail\greeting to tom from host
Xrainbow.
X
XDOS PROMPT> net buprsh \dos\del.com rainbow cat ">" binfile
X
Xwill copy the contents of DOS-file \dos\del.com to "binfile"
Xin your home directory on host rainbow.
X
X
XThis version of the KA9Q internet package has been tested on a
XIBM-AT communicating with a Sun running SunOS 3.2 by ethernet.
XSlip has also been tested.
X
XSMTP mail has not been tested!
SHAR_EOF
if test 1568 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 1568 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'diffs'" '(45134 characters)'
if test -f 'diffs'
then
	echo shar: will not over-write existing file "'diffs'"
else
sed 's/^X//' << \SHAR_EOF > 'diffs'
X*** alloc.c	Thu Jan 21 13:09:23 1988
X--- ../msc/alloc.c	Mon Mar 14 11:27:03 1988
X***************
X*** 132,140 ****
X  	/* Find out where the break is */
X  	cp = sbrk(0);
X  	/* Now try to push it as high as possible */
X! 	for(size=256;;size += 256){
X! 		if(brk(cp + size) == -1)
X  			break;
X  	}
X  	up = (HEADER *)cp;
X  	up->s.size = size / sizeof(HEADER);
X--- 132,148 ----
X  	/* Find out where the break is */
X  	cp = sbrk(0);
X  	/* Now try to push it as high as possible */
X! #define	STEPSIZE	256
X! 	for(size=STEPSIZE;;size += STEPSIZE){
X! #if MSC
X! 		if((int) sbrk(STEPSIZE) == -1) {
X! 			size-= STEPSIZE;
X  			break;
X+ 		}
X+ #else
X+ 		if(cp + size < cp || brk(cp + size) == -1)
X+ 			break;
X+ #endif
X  	}
X  	up = (HEADER *)cp;
X  	up->s.size = size / sizeof(HEADER);
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** audit.c	Thu Jan 21 13:09:36 1988
X--- ../msc/audit.c	Mon Mar 14 11:27:15 1988
X***************
X*** 1,3 ****
X--- 1,4 ----
X+ #if !MSC
X  #include <stdio.h>
X  #include "global.h"
X  #include "mbuf.h"
X***************
X*** 107,109 ****
X--- 108,111 ----
X  		(long)bp->data,bp->cnt,
X  		(long)bp->next,(long)bp->anext);
X  }
X+ #endif
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** dirutil.c	Thu Jan 21 13:09:50 1988
X--- ../msc/dirutil.c	Mon Mar 14 11:27:27 1988
X***************
X*** 5,11 ****
X--- 5,18 ----
X   */
X  
X  #include <stdio.h>
X+ #if defined(MSC)
X+ #include <sys/types.h>
X+ #include <sys/stat.h>
X+ #define	ST_DIRECT	S_IFDIR
X+ #define	st_attr		st_mode
X+ #else
X  #include <stat.h>
X+ #endif
X  #include "global.h"
X  
X  #ifndef	FALSE
X***************
X*** 16,22 ****
X--- 23,34 ----
X  #define	TRUE	!(FALSE)
X  #endif
X  
X+ #if MSC
X+ #define REGFILE	(0x2 | 0x4 | 0x10)
X+ #else
X  #define REGFILE	(ST_HIDDEN|ST_SYSTEM|ST_DIRECT)
X+ #endif
X+ 
X  #define	SET_DTA		0x1a
X  #define	FIND_FIRST	0x4e
X  #define	FIND_NEXT	0x4f
X***************
X*** 56,61 ****
X--- 68,92 ----
X  	return fp;
X  }
X  
X+ #if MSC
X+ #include	<dos.h>
X+ 
X+ dos(ax,bx,cx,dx,si,di)
X+ {
X+   union REGS	inregs;
X+   union REGS	outregs;
X+ 
X+   inregs.h.ah= ax;
X+   inregs.x.bx= bx;
X+   inregs.x.cx= cx;
X+   inregs.x.dx= dx;
X+   inregs.x.si= si;
X+   inregs.x.di= di;
X+   intdos(&inregs,&outregs);
X+   return(outregs.x.cflag ? -1 : 0);
X+ }
X+ #endif
X+ 
X  /* wildcard filename lookup */
X  filedir(name,times,ret_str)
X  char *name;
X***************
X*** 367,373 ****
X--- 398,408 ----
X  			if(*cp == ' ')break;
X  		}
X  	}
X+ #if MSC
X+ 	if(attr & 0x10)*dest++ = '\\';
X+ #else
X  	if(attr & ST_DIRECT)*dest++ = '\\';
X+ #endif
X  	*dest = '\0';
X  }
X  void
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** files.c	Tue Jan 26 09:54:36 1988
X--- ../msc/files.c	Mon Mar 14 11:27:35 1988
X***************
X*** 1,6 ****
X  /* System-dependent definitions of various files, spool directories, etc */
X  
X! #if	defined(LATTICE)
X  /* These compilers require special open modes when reading binary files
X   * 
X   * "The single most brilliant design decision in all of UNIX was the
X--- 1,6 ----
X  /* System-dependent definitions of various files, spool directories, etc */
X  
X! #if	(defined(MSC) || defined(LATTICE) || defined(MAC))
X  /* These compilers require special open modes when reading binary files
X   * 
X   * "The single most brilliant design decision in all of UNIX was the
X*** ftp.c	Thu Jan 21 13:10:06 1988
X--- ../msc/ftp.c	Mon Mar 14 11:27:36 1988
X***************
X*** 8,13 ****
X--- 8,17 ----
X  #include "ftp.h"
X  #include "session.h"
X  
X+ #if MSC
X+ extern int doing_dir;
X+ #endif
X+ 
X  /* FTP Data channel Receive upcall handler */
X  void
X  ftpdr(tcb,cnt)
X***************
X*** 63,69 ****
X--- 67,77 ----
X  		return;
X  	}
X  	eof_flag = 0;
X+ #if MSC
X+ 	if(ftp->type == IMAGE_TYPE && !doing_dir){
X+ #else
X  	if(ftp->type == IMAGE_TYPE){
X+ #endif
X  		bp->cnt = fread(bp->data,1,cnt,ftp->fp);
X  		if(bp->cnt != cnt)
X  			eof_flag = 1;
X***************
X*** 83,89 ****
X  				break;
X  			}
X  #endif
X! #if (defined(UNIX) || defined(MAC) || defined(AMIGA))
X  			if(c == '\n'){
X  				*cp++ = '\r';
X  				bp->cnt++;
X--- 91,97 ----
X  				break;
X  			}
X  #endif
X! #if (defined(UNIX) || defined(MAC) || defined(AMIGA) || defined(MSC))
X  			if(c == '\n'){
X  				*cp++ = '\r';
X  				bp->cnt++;
XNo differences encountered
X*** ftpserv.c	Thu Jan 21 13:10:09 1988
X--- ../msc/ftpserv.c	Mon Mar 14 11:27:40 1988
X***************
X*** 10,15 ****
X--- 10,20 ----
X  #include "tcp.h"
X  #include "ftp.h"
X  
X+ #if MSC
X+ int	doing_dir= 0;
X+ #endif
X+ 
X+ 
X  /* Command table */
X  static char *commands[] = {
X  	"user",
X***************
X*** 277,282 ****
X--- 282,290 ----
X  	FILE *dir();
X  #endif
X  
X+ #if MSC
X+ 	doing_dir= 0;
X+ #endif
X  	cmd = ftp->buf;
X  	if(ftp->cnt == 0){
X  		/* Can't be a legal FTP command */
X***************
X*** 417,422 ****
X--- 425,434 ----
X  		} else if((ftp->fp = dir(file,1)) == NULLFILE){
X  			tprintf(ftp->control,nodir,file);
X  		} else {
X+ #if MSC
X+ 			doing_dir= 1;
X+ #endif
X+ 
X  			dport.address = ip_addr;
X  			dport.port = FTPD_PORT;
X  			ftp->state = SENDING_STATE;
X***************
X*** 436,441 ****
X--- 448,456 ----
X  		} else if((ftp->fp = dir(file,0)) == NULLFILE){
X  			tprintf(ftp->control,nodir,file);
X  		} else {
X+ #if MSC
X+ 			doing_dir= 1;
X+ #endif
X  			dport.address = ip_addr;
X  			dport.port = FTPD_PORT;
X  			ftp->state = SENDING_STATE;
XNo differences encountered
XNo differences encountered
X*** icmpcmd.c	Thu Jan 21 13:10:18 1988
X--- ../msc/icmpcmd.c	Mon Mar 14 11:27:43 1988
X***************
X*** 8,19 ****
X  #include "timer.h"
X  #include "ping.h"
X  
X  int
X  doicmpstat()
X  {
X- 	extern struct icmp_errors icmp_errors;
X- 	extern struct icmp_stats icmp_stats;
X- 	extern char *icmptypes[];
X  	register int i;
X  
X  	printf("ICMP: chksum err %u no space %u icmp %u bdcsts %u\n",
X--- 8,20 ----
X  #include "timer.h"
X  #include "ping.h"
X  
X+ extern struct icmp_errors icmp_errors;
X+ extern struct icmp_stats icmp_stats;
X+ extern char *icmptypes[];
X+ 
X  int
X  doicmpstat()
X  {
X  	register int i;
X  
X  	printf("ICMP: chksum err %u no space %u icmp %u bdcsts %u\n",
X***************
X*** 96,102 ****
X  		/* Inter-ping time is specified; set up timer structure */
X  		if(pp == NULLPING)
X  			pp = add_ping(dest);
X! 		pp->timer.start = atoi(argv[2]);
X  		pp->timer.func = ptimeout;
X  		pp->timer.arg = (char *)pp;
X  		pp->remote = dest;
X--- 97,103 ----
X  		/* Inter-ping time is specified; set up timer structure */
X  		if(pp == NULLPING)
X  			pp = add_ping(dest);
X! 		pp->timer.start = atoi(argv[2]) / MSPTICK;
X  		pp->timer.func = ptimeout;
X  		pp->timer.arg = (char *)pp;
X  		pp->remote = dest;
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** mac_io.c	Thu Jan 21 13:10:40 1988
X--- ../msc/mac_io.c	Mon Mar 14 13:49:06 1988
X***************
X*** 1135,1137 ****
X--- 1135,1138 ----
X  char *str;
X  {
X  	return(timez);
X+ }
X*** main.c	Thu Jan 21 13:10:42 1988
X--- ../msc/main.c	Mon Mar 14 11:28:02 1988
X***************
X*** 5,10 ****
X--- 5,13 ----
X  extern char startup[];	/* File to read startup commands from */
X  
X  #include <stdio.h>
X+ #if MSC
X+ #include	<signal.h>
X+ #endif
X  #include "config.h"
X  #include "global.h"
X  #include "mbuf.h"
X***************
X*** 63,68 ****
X--- 66,72 ----
X  
X  /* Command lookup and branch table */
X  int go(),doax25(),cmdmode(),doconnect(),dotelnet(),doexit(),doclose(),
X+ 	dorsh(), doname(),
X  	dohostname(),doreset(),dotcp(),dotrace(),doescape(),dohelp(),
X  	doroute(),doecho(),dolog(),doip(),doetherstat(),
X  	memstat(),doarp(),dosession(),doftp(),dostart(),dostop(),doattach(),
X***************
X*** 85,90 ****
X--- 89,95 ----
X  #endif	
X  	"attach",	doattach,	2,
X  		"attach <hardware> <hw specific options>", NULLCHAR,
X+ 	"buprsh",	dorsh,		4, "buprsh binfile <address> command", NULLCHAR,
X  /* This one is out of alpabetical order to allow abbreviation to "c" */
X  #ifdef	AX25
X  	"connect",	doconnect,	3,"connect interface callsign [digipeaters]",
X***************
X*** 122,127 ****
X--- 127,133 ----
X  #ifdef	AX25
X  	"mode",		domode,		2, "mode <interface>",	NULLCHAR,
X  #endif
X+ 	"name",		doname,		3, "name username password", NULLCHAR,
X  	"param",	doparam,	2, "param <interface>", NULLCHAR,
X  	"ping",		doping,		0, NULLCHAR,	NULLCHAR,
X  #ifndef UNIX /* BSD or SYS5 */
X***************
X*** 130,135 ****
X--- 136,142 ----
X  	"record",	dorecord,	0, NULLCHAR,	NULLCHAR,
X  	"reset",	doreset,	0, NULLCHAR,	NULLCHAR,
X  	"route",	doroute,	0, NULLCHAR,	NULLCHAR,
X+ 	"rsh",		dorsh,		3, "rsh <address> command", NULLCHAR,
X  	"session",	dosession,	0, NULLCHAR,	NULLCHAR,
X  	"shell",	doshell,	0, NULLCHAR,	NULLCHAR,
X  	"smtp",		dosmtp,		0, NULLCHAR,	NULLCHAR,
X***************
X*** 144,149 ****
X--- 151,157 ----
X  #endif
X  	"udp",		doudp,		0, NULLCHAR,	NULLCHAR,
X  	"upload",	doupload,	0, NULLCHAR,	NULLCHAR,
X+ 	"uprsh",	dorsh,		4, "rsh file <address> command", NULLCHAR,
X  	"?",		dohelp,		0, NULLCHAR,	NULLCHAR,
X  	NULLCHAR,	NULLFP,		0,
X  		"Unknown command; type \"?\" for list",   NULLCHAR, 
X***************
X*** 174,179 ****
X--- 182,189 ----
X  };
X  #endif
X  
X+ static int	comline= 0;
X+ 
X  main(argc,argv)
X  int argc;
X  char *argv[];
X***************
X*** 193,212 ****
X  #if	(!defined(UNIX) && !defined(AMIGA) && !defined(MAC))
X  	chktasker();
X  #endif
X! #ifdef	MSDOS
X! 	printf("KA9Q Internet Protocol Package, v%s DS = %x\n",version,
X  		getds());
X  #else
X  	printf("KA9Q Internet Protocol Package, v%s\n",version);
X- #endif
X  	printf("Copyright 1988 by Phil Karn, KA9Q\n");
X  	sessions = (struct session *)calloc(nsessions,sizeof(struct session));
X! 	if(argc > 1){
X! 		/* Read startup file named on command line */
X! 		fp = fopen(argv[1],"r");
X! 	} else {
X! 		fp = fopen(startup,"r");
X! 	}
X  	if(fp != NULLFILE){
X  		while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
X  			cmdparse(cmds,inbuf);
X--- 203,221 ----
X  #if	(!defined(UNIX) && !defined(AMIGA) && !defined(MAC))
X  	chktasker();
X  #endif
X! #ifdef	MSC
X! 	signal(SIGINT, SIG_IGN);
X! 	if (argc == 1) {
X! 	  printf("Cog.Psy. Internet Protocol Package, v%s DS = %x\n",version,
X  		getds());
X+ 	  printf("Copyright 1988 by Phil Karn, KA9Q\n");
X+ 	}
X  #else
X  	printf("KA9Q Internet Protocol Package, v%s\n",version);
X  	printf("Copyright 1988 by Phil Karn, KA9Q\n");
X+ #endif
X  	sessions = (struct session *)calloc(nsessions,sizeof(struct session));
X! 	fp = fopen(startup,"r");
X  	if(fp != NULLFILE){
X  		while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
X  			cmdparse(cmds,inbuf);
X***************
X*** 213,227 ****
X  		}
X  		fclose(fp);
X  	}		
X! 	cmdmode();
X  
X  	/* Main commutator loop */
X  	for(;;){
X  		/* Process any keyboard input */
X  		while((c = kbread()) != -1){
X  #ifdef	MSDOS
X  			/* c == -2 means the command escape key (F10) */
X  			if(c == -2){
X  				if(mode != CMD_MODE){
X  					printf("\n");
X  					cmdmode();
X--- 222,250 ----
X  		}
X  		fclose(fp);
X  	}		
X! 	if(argc > 1){
X! 		comline= 1;
X! 		*inbuf= '\0';
X! 		while (--argc > 0) {
X! 			strcat(inbuf, *++argv);
X! 			strcat(inbuf, argc == 1 ? "\n" : " ");
X! 		}
X! 		mode = CMD_MODE;
X! 		cmdparse(cmds,inbuf);
X! 	} else
X! 		cmdmode();
X  
X  	/* Main commutator loop */
X  	for(;;){
X+ 		if (comline && countsession() == 0)
X+ 			doexit(0, NULL);
X  		/* Process any keyboard input */
X  		while((c = kbread()) != -1){
X  #ifdef	MSDOS
X  			/* c == -2 means the command escape key (F10) */
X  			if(c == -2){
X+ 				if (comline)
X+ 					doexit(0, NULL);
X  				if(mode != CMD_MODE){
X  					printf("\n");
X  					cmdmode();
X***************
X*** 258,264 ****
X  				break;
X  			}
X  			if(mode == CMD_MODE){
X! 				printf(prompt);
X  				fflush(stdout);
X  			}
X  		}
X--- 281,288 ----
X  				break;
X  			}
X  			if(mode == CMD_MODE){
X! 				if (!comline)
X! 					printf(prompt);
X  				fflush(stdout);
X  			}
X  		}
X***************
X*** 298,304 ****
X  	if(mode != CMD_MODE){
X  		mode = CMD_MODE;
X  		cooked();
X! 		printf(prompt);
X  		fflush(stdout);
X  	}
X  	return 0;
X--- 322,329 ----
X  	if(mode != CMD_MODE){
X  		mode = CMD_MODE;
X  		cooked();
X! 		if (!comline)
X! 			printf(prompt);
X  		fflush(stdout);
X  	}
X  	return 0;
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** pc.c	Thu Jan 21 13:10:53 1988
X--- ../msc/pc.c	Mon Mar 14 11:28:08 1988
X***************
X*** 1,6 ****
X--- 1,8 ----
X  /* OS- and machine-dependent stuff for IBM-PC running MS-DOS */
X  #include <stdio.h>
X+ #if !MSC
X  #include <sgtty.h>
X+ #endif
X  #include "global.h"
X  #include "mbuf.h"
X  #include "internet.h"
X***************
X*** 8,13 ****
X--- 10,34 ----
X  #include "pc.h"
X  #include "cmdparse.h"
X  
X+ #if MSC
X+ #include	<dos.h>
X+ 
X+ char	*strchr(), *strrchr();
X+ char *index(p,c)
X+ char	*p, c;
X+ { return(strchr(p,c)); }
X+ 
X+ char *rindex(p,c)
X+ char	*p, c;
X+ { return(strrchr(p,c)); }
X+ 
X+ outportb(p,v)
X+ { return(outp(p,v)); }
X+ 
X+ inportb(p)
X+ { return(inp(p)); }
X+ #endif
X+ 
X  /* Interface list header */
X  struct interface *ifaces;
X  
X***************
X*** 22,28 ****
X--- 43,51 ----
X  /* Called at startup time to set up console I/O, memory heap */
X  ioinit()
X  {
X+ #if !MSC
X  	struct sgttyb ttybuf;
X+ #endif
X  	unsigned grabcore();
X  
X  	/* Interrupts use a special stack deep in data space.
X***************
X*** 40,52 ****
X--- 63,78 ----
X  	/* Put display in raw mode. Note that this breaks tab expansion,
X  	 * so you need to run NANSI.SYS or equivalent.
X  	 */
X+ #if !MSC
X  	ioctl(1,TIOCGETP,&ttybuf);
X  	ttybuf.sg_flags = RAW;
X  	ioctl(1,TIOCSETP,&ttybuf);
X+ #endif
X  }
X  /* Called just before exiting to restore console state */
X  iostop()
X  {
X+ #if !MSC
X  	struct sgttyb ttybuf;
X  
X  	setbuf(stdout,NULLCHAR);
X***************
X*** 53,58 ****
X--- 79,85 ----
X  	ioctl(1,TIOCGETP,&ttybuf);
X  	ttybuf.sg_flags &= ~RAW;
X  	ioctl(1,TIOCSETP,&ttybuf);
X+ #endif
X  	while(ifaces != NULLIF){
X  		if(ifaces->stop != NULLFP)
X  			(*ifaces->stop)(ifaces);
X***************
X*** 62,68 ****
X--- 89,102 ----
X  /* Spawn subshell */
X  doshell(argc,argv)
X  {
X+ #if MSC
X  	char *command,*getenv();
X+ 
X+ 	if((command = getenv("COMSPEC")) == NULLCHAR)
X+ 		command = "/COMMAND.COM";
X+ 	system(command);
X+ #else
X+ 	char *command,*getenv();
X  	struct sgttyb ttybuf,ttysav;
X  	int ret;
X  
X***************
X*** 79,84 ****
X--- 113,119 ----
X  		return -1;
X  	else
X  		return wait();
X+ #endif
X  }
X  
X  /* checks the time then ticks and updates ISS */
X***************
X*** 87,93 ****
X--- 122,134 ----
X  check_time()
X  {
X  	int32 iss();
X+ #ifdef MSC
X+ 	union REGS	inregs, outregs;
X+ 	register int	c, new;
X+ 	static int	old= -1;
X+ #endif
X  
X+ #ifndef MSC
X  	if(clkval != clksec()){
X  		clkval = clksec();
X  		icmpclk();	/* Call this one before tick */
X***************
X*** 94,99 ****
X--- 135,159 ----
X  		tick();
X  		(void)iss();
X  	}
X+ #else
X+ 	inregs.h.ah= 0x2c;
X+ 	intdos(&inregs,&outregs);
X+ 	c= (new= outregs.h.dl + 100 * outregs.h.dh) - old;
X+ 	if (old == -1) {
X+ 		c= 0;
X+ 		old= new;
X+ 	}
X+ 	if (c < 0)
X+ 		c+= 6000;
X+ 	if (c > 0) {
X+ 		old= new;
X+ 		while (--c >= 0) {
X+ 			icmpclk();	/* Call this one before tick */
X+ 			tick();
X+ 			(void)iss();
X+ 		}
X+ 	}
X+ #endif
X  }
X  /* Read characters from the keyboard, translating them to "real" ASCII
X   * If none are ready, return the -1 from kbraw()
XNo differences encountered
X*** session.c	Thu Jan 21 13:11:01 1988
X--- ../msc/session.c	Mon Mar 14 11:28:14 1988
X***************
X*** 10,20 ****
X--- 10,23 ----
X  #include "lapb.h"
X  #include "ftp.h"
X  #include "telnet.h"
X+ #include "rsh.h"
X  #include "session.h"
X  #include "cmdparse.h"
X  
X  struct session *sessions;
X  struct session *current;
X+ char		*malloc();
X+ 
X  char notval[] = "Not a valid control block\n";
X  char badsess[] = "Invalid session\n";
X  
X***************
X*** 69,74 ****
X--- 72,86 ----
X  			 tcpstates[s->cb.telnet->tcb->state],
X  			 s->name,s->cb.telnet->tcb->conn.remote.port);
X  			break;
X+ 		case RSH:
X+ 			printf("%c%-3d%8lx Rsh     %4d  %-13s%-s:%d",
X+ 			 (current == s)? '*':' ',
X+ 			 (int)(s - sessions),
X+ 			 (long)s->cb.rsh->tcb,
X+ 			 s->cb.rsh->tcb->rcvcnt,
X+ 			 tcpstates[s->cb.rsh->tcb->state],
X+ 			 s->name,s->cb.rsh->tcb->conn.remote.port);
X+ 			break;
X  		case FTP:
X  			printf("%c%-3d%8lx FTP     %4d  %-13s%-s:%d",
X  			 (current == s)? '*':' ',
X***************
X*** 106,112 ****
X  int
X  go()
X  {
X! 	void rcv_char(),ftpccr(),ax_rx();
X  
X  	if(current == NULLSESSION || current->type == FREE)
X  		return 0;
X--- 118,124 ----
X  int
X  go()
X  {
X! 	void rcv_char(),ftpccr(),ax_rx(),rsh_rcv();
X  
X  	if(current == NULLSESSION || current->type == FREE)
X  		return 0;
X***************
X*** 117,122 ****
X--- 129,138 ----
X  			raw();	/* Re-establish raw mode if it was set */
X  		rcv_char(current->cb.telnet->tcb,0); /* Get any pending input */
X  		break;
X+ 	case RSH:
X+ 		rsh_rcv(current->cb.rsh->errtcb,0); /* Get any pending input */
X+ 		rsh_rcv(current->cb.rsh->tcb,0); /* Get any pending input */
X+ 		break;
X  	case FTP:
X  		ftpccr(current->cb.ftp->control,0);
X  		break;
X***************
X*** 142,147 ****
X--- 158,167 ----
X  	case TELNET:
X  		close_tcp(s->cb.telnet->tcb);
X  		break;
X+ 	case RSH:
X+ 		close_tcp(s->cb.rsh->errtcb);
X+ 		close_tcp(s->cb.rsh->tcb);
X+ 		break;
X  	case FTP:
X  		close_tcp(s->cb.ftp->control);
X  		break;
X***************
X*** 168,173 ****
X--- 188,197 ----
X  	case TELNET:
X  		reset_tcp(s->cb.telnet->tcb);
X  		break;
X+ 	case RSH:
X+ 		reset_tcp(s->cb.rsh->errtcb);
X+ 		reset_tcp(s->cb.rsh->tcb);
X+ 		break;
X  	case FTP:
X  		reset_tcp(s->cb.ftp->control);
X  		break;
X***************
X*** 199,204 ****
X--- 223,234 ----
X  			return 1;
X  		}
X  		break;
X+ 	case RSH:
X+ 		if(kick_tcp(s->cb.rsh->tcb) == -1){
X+ 			printf(notval);
X+ 			return 1;
X+ 		}
X+ 		break;
X  	case FTP:
X  		if(kick_tcp(s->cb.ftp->control) == -1){
X  			printf(notval);
X***************
X*** 226,231 ****
X--- 256,273 ----
X  			return &sessions[i];
X  	return NULLSESSION;
X  }
X+ 
X+ countsession()
X+ {
X+ 	register int i;
X+ 	register int cnt= 0;
X+ 
X+ 	for(i=0;i<nsessions;i++)
X+ 		if(sessions[i].type != FREE)
X+ 			cnt++;
X+ 	return cnt;
X+ }
X+ 
X  freesession(s)
X  struct session *s;
X  {
X***************
X*** 301,306 ****
X--- 343,351 ----
X  		case TELNET:
X  			tcb = current->cb.telnet->tcb;
X  			break;
X+ 		case RSH:
X+ 			tcb = current->cb.rsh->tcb;
X+ 			break;
X  #ifdef	AX25
X  		case AX25TNC:
X  			axp = current->cb.ax25_cb;
X***************
X*** 324,330 ****
X  			printf("Can't read %s\n",argv[1]);
X  			return 1;
X  		}
X! 		current->ufile = malloc((unsigned)strlen(argv[1])+1);
X  		strcpy(current->ufile,argv[1]);
X  		/* All set, kick transmit upcall to get things rolling */
X  		switch(current->type){
X--- 369,379 ----
X  			printf("Can't read %s\n",argv[1]);
X  			return 1;
X  		}
X! 
X! 		if ((current->ufile = malloc((unsigned)strlen(argv[1])+1)) == NULLCHAR) {
X! 			printf("Out of memory!\n");
X! 			return 1;
X! 		}
X  		strcpy(current->ufile,argv[1]);
X  		/* All set, kick transmit upcall to get things rolling */
X  		switch(current->type){
X***************
X*** 334,339 ****
X--- 383,391 ----
X  			break;
X  #endif
X  		case TELNET:
X+ 			(*tcb->t_upcall)(tcb,tcb->snd.wnd - tcb->sndcnt);
X+ 			break;
X+ 		case RSH:
X  			(*tcb->t_upcall)(tcb,tcb->snd.wnd - tcb->sndcnt);
X  			break;
X  		}
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** tcpsubr.c	Thu Jan 21 13:11:32 1988
X--- ../msc/tcpsubr.c	Mon Mar 14 11:28:31 1988
X***************
X*** 85,91 ****
X  {
X  	static int32 seq;
X  
X! 	seq += 250000;
X  	return seq;
X  }
X  
X--- 85,91 ----
X  {
X  	static int32 seq;
X  
X! 	seq += 250 * MSPTICK;
X  	return seq;
X  }
X  
XNo differences encountered
XNo differences encountered
X*** telnet.c	Thu Jan 21 13:11:35 1988
X--- ../msc/telnet.c	Mon Mar 14 11:28:36 1988
X***************
X*** 151,157 ****
X--- 151,161 ----
X  				if(!tn->remote[TN_TRANSMIT_BINARY])
X  					c &= 0x7f;
X  				if(c != '\0')	/* Don't screw up ANSI driver */
X+ #if MSC
X+ 					fwrite(&c,1,1,stdout);
X+ #else
X  					putchar(c);
X+ #endif
X  				if((record = tn->session->record) != NULLFILE)
X  					putc(c,record);
X  			}
X***************
X*** 171,177 ****
X--- 175,185 ----
X  				tn->state = TS_DONT;
X  				break;
X  			case IAC:
X+ #if MSC
X+ 				fwrite(&c,1,1,stdout);
X+ #else
X  				putchar(c);
X+ #endif
X  				tn->state = TS_DATA;
X  				break;
X  			default:
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** version.c	Thu Jan 21 13:11:49 1988
X--- ../msc/version.c	Mon Mar 14 11:28:43 1988
X***************
X*** 4,8 ****
X   * Prefix is changed only by N3EUA. Persons other than KA9Q making local
X   * changes and fixes should append letters to the suffix.
X   */
X! char version[] = "871225.4";
X  
X--- 4,8 ----
X   * Prefix is changed only by N3EUA. Persons other than KA9Q making local
X   * changes and fixes should append letters to the suffix.
X   */
X! char version[] = "871225.5CP";
X  
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** config.h	Thu Jan 21 13:09:49 1988
X--- ../msc/config.h	Mon Mar 14 11:29:03 1988
X***************
X*** 6,14 ****
X  /* Hardware configuration */
X  #define	PC_EC		1	/* 3-Com 3C501 Ethernet controller */
X  #define	SLIP		1	/* Serial Line IP subnet code */
X! #define	KISS		1	/* KISS TNC code */
X! #define	HAPN		1	/* Hamilton Area Packet Network driver code */
X! #define	EAGLE		1	/* Eagle card driver */
X  #undef	PC100		1	/* PAC-COM PC-100 driver code */
X  #undef	APPLETALK	1	/* Appletalk interface (Macintosh) */
X  
X--- 6,14 ----
X  /* Hardware configuration */
X  #define	PC_EC		1	/* 3-Com 3C501 Ethernet controller */
X  #define	SLIP		1	/* Serial Line IP subnet code */
X! #undef	KISS		0	/* KISS TNC code */
X! #undef	HAPN		0	/* Hamilton Area Packet Network driver code */
X! #undef	EAGLE		0	/* Eagle card driver */
X  #undef	PC100		1	/* PAC-COM PC-100 driver code */
X  #undef	APPLETALK	1	/* Appletalk interface (Macintosh) */
X  
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** session.h	Thu Jan 21 13:11:02 1988
X--- ../msc/session.h	Mon Mar 14 11:29:22 1988
X***************
X*** 9,19 ****
X--- 9,21 ----
X  #define	TELNET	1
X  #define	FTP	2
X  #define	AX25TNC	3
X+ #define	RSH	4
X  	char *name;	/* Name of remote host */
X  	union {
X  		struct ftp *ftp;
X  		struct telnet *telnet;
X  		struct ax25_cb *ax25_cb;
X+ 		struct rsh *rsh;
X  	} cb;
X  	int (*parse)();		/* Where to hand typed input when conversing */
X  	FILE *record;		/* Receive record file */
XNo differences encountered
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** timer.h	Thu Jan 21 13:11:38 1988
X--- ../msc/timer.h	Mon Mar 14 11:29:27 1988
X***************
X*** 20,26 ****
X--- 20,30 ----
X  };
X  #define	NULLTIMER	(struct timer *)0
X  #define	MAX_TIME	(int16)65535	/* Max short integer */
X+ #ifdef MSC
X+ #define	MSPTICK		10		/* Milliseconds per tick */
X+ #else
X  #define	MSPTICK		1000		/* Milliseconds per tick */
X+ #endif
X  /* Useful user macros that hide the timer structure internals */
X  #define	set_timer(t,x)	(((t)->start) = (x)/MSPTICK)
X  #define	dur_timer(t)	((t)->start)
XNo differences encountered
XNo differences encountered
XNo differences encountered
X*** asyvec.asm	Thu Jan 21 13:09:34 1988
X--- ../msc/asyvec.asm	Wed Mar  9 16:26:02 1988
X***************
X*** 1,16 ****
X  	include lmacros.h
X! 	assume	ds:dataseg
X! 	public	sssave,spsave,intstk,doret
X  
X  	ifdef	FARPROC
X! 	extrn	doret:far,asyint_:far,getintds:far
X  	else
X! 	extrn	doret:near,asyint_:near,getintds:near
X  	endif
X  
X  ; asy0vec - asynch channel 0 interrupt handler
X! 	public	asy0vec_
X! asy0vec_ proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X--- 1,34 ----
X  	include lmacros.h
X! ;	assume	ds:dataseg
X! ;	public	sssave,spsave,intstk,doret
X! ASYVEC_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
X! ASYVEC_TEXT	ENDS
X! _DATA	SEGMENT  WORD PUBLIC 'DATA'
X! _DATA	ENDS
X! CONST	SEGMENT  WORD PUBLIC 'CONST'
X! CONST	ENDS
X! _BSS	SEGMENT  WORD PUBLIC 'BSS'
X! _BSS	ENDS
X! DGROUP	GROUP	CONST,	_BSS,	_DATA
X! 	ASSUME  CS: ASYVEC_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
X  
X+ extrn	sssave:word
X+ extrn	spsave:word
X+ extrn	intstk:byte
X+ 
X  	ifdef	FARPROC
X! 	extrn	doret:far
X! 	extrn	_asyint:far
X! 	extrn	getintds:far
X  	else
X! 	extrn	doret:near,_asyint:near,getintds:near
X  	endif
X  
X+ ASYVEC_TEXT	segment
X+ 
X  ; asy0vec - asynch channel 0 interrupt handler
X! 	public	_asy0vec
X! _asy0vec proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X***************
X*** 34,47 ****
X  
X  	mov	ax,0		; arg for service routine
X  	push	ax
X! 	call	asyint_
X  	pop	ax
X  	jmp	doret
X! asy0vec_	endp
X  
X  ; asy1vec - asynch channel 1 interrupt handler
X! 	public	asy1vec_
X! asy1vec_	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X--- 52,65 ----
X  
X  	mov	ax,0		; arg for service routine
X  	push	ax
X! 	call	_asyint
X  	pop	ax
X  	jmp	doret
X! _asy0vec	endp
X  
X  ; asy1vec - asynch channel 1 interrupt handler
X! 	public	_asy1vec
X! _asy1vec	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X***************
X*** 65,78 ****
X  
X  	mov	ax,1		; arg for service routine
X  	push	ax
X! 	call	asyint_
X  	pop	ax
X  	jmp	doret
X! asy1vec_	endp
X  
X  ; asy2vec - asynch channel 2 interrupt handler
X! 	public	asy2vec_
X! asy2vec_	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X--- 83,96 ----
X  
X  	mov	ax,1		; arg for service routine
X  	push	ax
X! 	call	_asyint
X  	pop	ax
X  	jmp	doret
X! _asy1vec	endp
X  
X  ; asy2vec - asynch channel 2 interrupt handler
X! 	public	_asy2vec
X! _asy2vec	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X***************
X*** 96,109 ****
X  
X  	mov	ax,2		; arg for service routine
X  	push	ax
X! 	call	asyint_
X  	pop	ax
X  	jmp	doret
X! asy2vec_	endp
X  
X  ; asy3vec - asynch channel 3 interrupt handler
X! 	public	asy3vec_
X! asy3vec_	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X--- 114,127 ----
X  
X  	mov	ax,2		; arg for service routine
X  	push	ax
X! 	call	_asyint
X  	pop	ax
X  	jmp	doret
X! _asy2vec	endp
X  
X  ; asy3vec - asynch channel 3 interrupt handler
X! 	public	_asy3vec
X! _asy3vec	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X***************
X*** 127,140 ****
X  
X  	mov	ax,3		; arg for service routine
X  	push	ax
X! 	call	asyint_
X  	pop	ax
X  	jmp	doret
X! asy3vec_	endp
X  
X  ; asy4vec - asynch channel 4 interrupt handler
X! 	public	asy4vec_
X! asy4vec_	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X--- 145,158 ----
X  
X  	mov	ax,3		; arg for service routine
X  	push	ax
X! 	call	_asyint
X  	pop	ax
X  	jmp	doret
X! _asy3vec	endp
X  
X  ; asy4vec - asynch channel 4 interrupt handler
X! 	public	_asy4vec
X! _asy4vec	proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X***************
X*** 158,166 ****
X  
X  	mov	ax,4		; arg for service routine
X  	push	ax
X! 	call	asyint_
X  	pop	ax
X  	jmp	doret
X! asy4vec_	endp
X  
X  	end
X--- 176,185 ----
X  
X  	mov	ax,4		; arg for service routine
X  	push	ax
X! 	call	_asyint
X  	pop	ax
X  	jmp	doret
X! _asy4vec	endp
X  
X+ ASYVEC_TEXT	ends
X  	end
XNo differences encountered
X*** ecvec.asm	Thu Jan 21 13:09:59 1988
X--- ../msc/ecvec.asm	Wed Mar  9 16:26:36 1988
X***************
X*** 1,5 ****
X! 	include lmacros.h
X  
X  ; Conditional ES save/restore macros not in lmacros.h
X  pushes	macro
X  	ifdef LONGPTR
X--- 1,16 ----
X! 	include	lmacros.h
X  
X+ ECVEC_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
X+ ECVEC_TEXT	ENDS
X+ _DATA	SEGMENT  WORD PUBLIC 'DATA'
X+ _DATA	ENDS
X+ CONST	SEGMENT  WORD PUBLIC 'CONST'
X+ CONST	ENDS
X+ _BSS	SEGMENT  WORD PUBLIC 'BSS'
X+ _BSS	ENDS
X+ DGROUP	GROUP	CONST,	_BSS,	_DATA
X+ 	ASSUME  CS: ECVEC_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
X+ 
X  ; Conditional ES save/restore macros not in lmacros.h
X  pushes	macro
X  	ifdef LONGPTR
X***************
X*** 13,32 ****
X  	endif
X  	endm
X  
X! 	assume	ds:dataseg
X! 	assume	cs:codeseg
X! 	public	sssave,spsave,intstk
X  
X  	ifdef	FARPROC
X! 	extrn	doret:far,ecint_:far,getintds:far
X  	else
X! 	extrn	doret:near,ecint_:near,getintds:near
X  	endif
X  
X  ; ec0vec - Ethernet interrupt handler
X! 	public	ec0vec_
X  
X! ec0vec_ proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X--- 24,44 ----
X  	endif
X  	endm
X  
X! extrn	sssave:word
X! extrn	spsave:word
X! extrn	intstk:byte
X  
X  	ifdef	FARPROC
X! 	extrn	doret:far,_ecint:far,getintds:far
X  	else
X! 	extrn	doret:near,_ecint:near,getintds:near
X  	endif
X  
X+ ECVEC_TEXT	segment
X  ; ec0vec - Ethernet interrupt handler
X! 	public	_ec0vec
X  
X! _ec0vec proc	far
X  	push	ds		; save on user stack
X  	call	getintds	; establish interrupt data segment
X  
X***************
X*** 50,70 ****
X  
X  	mov	ax,0		; arg for service routine
X  	push	ax
X! 	call	ecint_
X  	pop	ax
X  	jmp	doret
X! ec0vec_	endp
X  
X  ; fast buffer I/O routines -- used by 3-COM Ethernet controller
X  
X  ; outbuf - put a buffer to an output port
X! 	procdef outbuf,<<oport,word>,<obuf,ptr>,<ocnt,word>>
X  	pushf
X  	push	si
X  	pushds
X! 	mov	dx,oport
X! 	mov	cx,ocnt
X! 	ldptr	si,obuf,ds	; ds:si = obuf
X  	cld
X  
X  ; If buffer doesn't begin on a word boundary, send the first byte
X--- 62,88 ----
X  
X  	mov	ax,0		; arg for service routine
X  	push	ax
X! 	call	_ecint
X  	pop	ax
X  	jmp	doret
X! _ec0vec	endp
X  
X  ; fast buffer I/O routines -- used by 3-COM Ethernet controller
X  
X  ; outbuf - put a buffer to an output port
X! ;	procdef outbuf,<<oport,word>,<obuf,ptr>,<ocnt,word>>
X! 	public _outbuf
X! _outbuf	proc far
X! 	push	bp
X! 	mov	bp,sp
X  	pushf
X  	push	si
X  	pushds
X! 	mov	dx,[bp+6]	;oport
X! 	mov	cx,[bp+10]	;ocnt
X! ;	ldptr	si,obuf,ds	; ds:si = obuf
X! 	mov	si,[bp+8]
X! 	;mov	ds,[bp+10]
X  	cld
X  
X  ; If buffer doesn't begin on a word boundary, send the first byte
X***************
X*** 73,79 ****
X  	lodsb		; al = *si++;
X  	out	dx,al	; out(dx,al);
X  	dec	cx	; cx--;
X! 	mov	ocnt,cx	; save for later test
X  obufeven:
X  	shr	cx,1	; cx = cnt >> 1; (convert to word count)
X  ; Do the bulk of the buffer, a word at a time
X--- 91,97 ----
X  	lodsb		; al = *si++;
X  	out	dx,al	; out(dx,al);
X  	dec	cx	; cx--;
X! 	mov	[bp+10],cx	;ocnt,cx	; save for later test
X  obufeven:
X  	shr	cx,1	; cx = cnt >> 1; (convert to word count)
X  ; Do the bulk of the buffer, a word at a time
X***************
X*** 84,90 ****
X  	out	dx,al	; out(dx,hibyte(ax));
X  	loop	xb	; } while(--cx != 0); }
X  ; now check for odd trailing byte
X! onobuf:	mov	cx,ocnt
X  	test	cx,1
X  	jz	ocnteven
X  	lodsb		; al = *si++;
X--- 102,108 ----
X  	out	dx,al	; out(dx,hibyte(ax));
X  	loop	xb	; } while(--cx != 0); }
X  ; now check for odd trailing byte
X! onobuf:	mov	cx,[bp+10]	;ocnt
X  	test	cx,1
X  	jz	ocnteven
X  	lodsb		; al = *si++;
X***************
X*** 93,109 ****
X  	popds
X  	pop	si
X  	popf
X! 	pret
X! 	pend	outbuf
X  
X  ; inbuf - get a buffer from an input port
X! 	procdef inbuf,<<iport,word>,<ibuf,ptr>,<icnt,word>>
X  	pushf
X  	push	di
X  	pushes
X! 	mov	dx,iport
X! 	mov	cx,icnt
X! 	ldptr	di,ibuf,es	; es:di = ibuf (es already set in small model)
X  	cld
X  
X  ; If buffer doesn't begin on a word boundary, get the first byte
X--- 111,137 ----
X  	popds
X  	pop	si
X  	popf
X! 	mov	sp,bp
X! 	pop	bp
X! ;	pret
X! 	ret
X! ;	pend	outbuf
X! _outbuf	endp
X  
X  ; inbuf - get a buffer from an input port
X! ;	procdef inbuf,<<iport,word>,<ibuf,ptr>,<icnt,word>>
X! 	public _inbuf
X! _inbuf	proc far
X! 	push	bp
X! 	mov	bp,sp
X  	pushf
X  	push	di
X  	pushes
X! 	mov	dx,[bp+6]	;iport
X! 	mov	cx,[bp+10]	;icnt
X! ;	ldptr	di,ibuf,es	; es:di = ibuf (es already set in small model)
X! 	mov	di,[bp+8]
X! 	;mov	es,[bp+10]
X  	cld
X  
X  ; If buffer doesn't begin on a word boundary, get the first byte
X***************
X*** 112,118 ****
X  	in	al,dx	; al = in(dx);
X  	stosb		; *di++ = al
X  	dec	cx	; cx--;
X! 	mov	icnt,cx	; icnt = cx; } save for later test
X  ibufeven:
X  	shr	cx,1	; cx = cnt >> 1; (convert to word count)
X  ; Do the bulk of the buffer, a word at a time
X--- 140,146 ----
X  	in	al,dx	; al = in(dx);
X  	stosb		; *di++ = al
X  	dec	cx	; cx--;
X! 	mov	[bp+10],cx	;icnt,cx	; icnt = cx; } save for later test
X  ibufeven:
X  	shr	cx,1	; cx = cnt >> 1; (convert to word count)
X  ; Do the bulk of the buffer, a word at a time
X***************
X*** 124,130 ****
X  	stosw		; *si++ = ax; (di is word pointer)
X  	loop	rb	; } while(--cx != 0);
X  ; now check for odd trailing byte
X! inobuf:	mov	cx,icnt
X  	test	cx,1
X  	jz	icnteven
X  	in	al,dx
X--- 152,158 ----
X  	stosw		; *si++ = ax; (di is word pointer)
X  	loop	rb	; } while(--cx != 0);
X  ; now check for odd trailing byte
X! inobuf:	mov	cx,[bp+10]	;icnt
X  	test	cx,1
X  	jz	icnteven
X  	in	al,dx
X***************
X*** 133,139 ****
X  	popes
X  	pop	di
X  	popf
X! 	pret
X! 	pend	inbuf
X  
X  	end
X--- 161,173 ----
X  	popes
X  	pop	di
X  	popf
X! 	mov	sp,bp
X! 	pop	bp
X! 	ret
X! ;	pret
X! ;	pend	inbuf
X! _inbuf	endp
X! 
X! ECVEC_TEXT	ends
X  
X  	end
XNo differences encountered
XNo differences encountered
X*** pcgen.asm	Thu Jan 21 13:10:59 1988
X--- ../msc/pcgen.asm	Wed Mar  9 16:27:56 1988
X***************
X*** 1,10 ****
X! 	include lmacros.h
X! 	assume	ds:dataseg
X! 	assume	cs:codeseg
X! 	public sssave,spsave,intstk,doret
X  
X  ; common routine for interrupt return
X  
X  	ifdef	FARPROC
X  doret	proc	far
X  	else
X--- 1,22 ----
X! 	include	lmacros.h
X! ;	assume	ds:dataseg
X! ;	assume	cs:codeseg
X! PCGEN_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
X! PCGEN_TEXT	ENDS
X! _DATA	SEGMENT  WORD PUBLIC 'DATA'
X! _DATA	ENDS
X! CONST	SEGMENT  WORD PUBLIC 'CONST'
X! CONST	ENDS
X! _BSS	SEGMENT  WORD PUBLIC 'BSS'
X! _BSS	ENDS
X! DGROUP	GROUP	CONST,	_BSS,	_DATA
X! 	ASSUME  CS: PCGEN_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
X  
X+ 
X+ PCGEN_TEXT	segment
X  ; common routine for interrupt return
X  
X+ 	public doret
X  	ifdef	FARPROC
X  doret	proc	far
X  	else
X***************
X*** 32,52 ****
X  ; char vec;		/* Interrupt number */
X  ; void (*vecval)();	/* offset (and segment in large code model) */
X  
X! 	procdef	setvec,<<vec,byte>,<ipval,fptr>>
X  	mov	cs:intds,ds	; save data segment pointer
X  	mov	ah,25h
X! 	mov	al,vec
X! 	mov	dx,word ptr ipval
X  	push	ds		; save
X  ifdef	FARPROC
X! 	mov	ds,word ptr ipval+2
X  else
X! 	mov	ds,cs
X  endif
X  	int	21h
X  	pop	ds		; restore
X! 	pret
X! 	pend	setvec
X  intds	dw	0	; save loc for ds (must be in code segment)
X  
X  ; getintds - get ds to use during interrupt service
X--- 44,74 ----
X  ; char vec;		/* Interrupt number */
X  ; void (*vecval)();	/* offset (and segment in large code model) */
X  
X! ;	procdef	setvec,<<vec,byte>,<ipval,fptr>>
X! 	public _setvec
X! _setvec	proc far
X! 	push	bp
X! 	mov	bp,sp
X  	mov	cs:intds,ds	; save data segment pointer
X  	mov	ah,25h
X! 	mov	al,[bp+6]	;vec
X! 	mov	dx,word ptr [bp+8]	;ipval
X  	push	ds		; save
X  ifdef	FARPROC
X! 	mov	ds,word ptr [bp+10]	;ipval+2
X  else
X! 	;mov	ds,cs
X! 	push	cs
X! 	pop	ds
X  endif
X  	int	21h
X  	pop	ds		; restore
X! ;	pret
X! 	mov	sp,bp
X! 	pop	bp
X! 	ret
X! ;	pend	setvec
X! _setvec	endp
X  intds	dw	0	; save loc for ds (must be in code segment)
X  
X  ; getintds - get ds to use during interrupt service
X***************
X*** 67,136 ****
X  ; getvec(vecnum)
X  ; char vecnum;	/* Interrupt number */
X  
X! 	procdef	getvec,<<vecnum,byte>>
X  	mov	ah,35h
X! 	mov	al,vecnum
X  	push	es	; save, since DOS uses it for a return value
X  	int	21h
X  	mov	dx,es	; CS value into DX (C high word)
X  	mov	ax,bx	; IP value into AX (C low word)
X  	pop	es	; restore es
X! 	pret
X! 	pend	getvec
X  
X  ; clksec - return current second value
X! 	procdef	clksec
X  	mov	ah,2ch
X  	int	21h
X  	mov	al,dh
X  	mov	ah,0
X! 	pret
X! 	pend	clksec
X  
X  ; kbraw - raw, nonblocking read from console
X  ; If character is ready, return it; if not, return -1
X  
X! 	procdef	kbraw
X  	mov	ah,06h	; Direct Console I/O
X  	mov	dl,0ffh	; Read from keyboard
X  	int	21h	; Call DOS
X  	jz	nochar	; zero flag set -> no character ready
X  	mov	ah,0	; valid char is 0-255
X! 	pret
X  nochar:
X  	mov	ax,-1	; no char, return -1
X! 	pret
X! 	pend	kbraw
X  
X  ; disable - disable interrupts and return previous state: 0 = disabled,
X  ;           1 = enabled
X  
X! 	procdef	disable
X  	pushf			; save state on stack
X  	cli			; interrupts off
X  	pop	ax		; original flags -> ax
X  	and	ax,200h		; 1<<9 is IF bit
X  	jnz	ion		; nonzero -> interrupts were on
X! 	pret
X  ion:	mov	ax,1
X! 	pret
X! 	pend	disable
X  
X  ; restore - restore interrupt state: 0 = off, nonzero = on
X  
X! 	procdef	restore,<<istate,byte>>
X! 	test	istate,0ffh
X  	jz	ioff
X  	sti
X! ioff:	pret
X! 	pend	restore
X  
X  ; Halt until an interrupt occurs, then return
X! 	procdef eihalt
X  	sti	; make sure interrupts are enabled
X  	hlt
X! 	pret
X! 	pend	eihalt
X  
X  ; multitasker types
X  NONE		equ	0
X--- 89,192 ----
X  ; getvec(vecnum)
X  ; char vecnum;	/* Interrupt number */
X  
X! 	public	_getvec
X! 	_getvec	proc far
X! ;	procdef	getvec,<<vecnum,byte>>
X! 	push	bp
X! 	mov	bp,sp
X  	mov	ah,35h
X! 	mov	al,[bp+6]	;vecnum
X  	push	es	; save, since DOS uses it for a return value
X  	int	21h
X  	mov	dx,es	; CS value into DX (C high word)
X  	mov	ax,bx	; IP value into AX (C low word)
X  	pop	es	; restore es
X! ;	pret
X! 	mov	sp,bp
X! 	pop	bp
X! 	ret
X! _getvec	endp
X! ;	pend	getvec
X  
X  ; clksec - return current second value
X! 	public	_clksec
X! 	_clksec	proc far
X! ;	procdef	clksec
X  	mov	ah,2ch
X  	int	21h
X  	mov	al,dh
X  	mov	ah,0
X! ;	pret
X! 	ret
X! _clksec	endp
X! ;	pend	clksec
X  
X  ; kbraw - raw, nonblocking read from console
X  ; If character is ready, return it; if not, return -1
X  
X! 	public	_kbraw
X! 	_kbraw	proc far
X! ;	procdef	kbraw
X  	mov	ah,06h	; Direct Console I/O
X  	mov	dl,0ffh	; Read from keyboard
X  	int	21h	; Call DOS
X  	jz	nochar	; zero flag set -> no character ready
X  	mov	ah,0	; valid char is 0-255
X! ;	pret
X! 	ret
X  nochar:
X  	mov	ax,-1	; no char, return -1
X! ;	pret
X! 	ret
X! ;	pend	kbraw
X! _kbraw	endp
X  
X  ; disable - disable interrupts and return previous state: 0 = disabled,
X  ;           1 = enabled
X  
X! 	public	_disable
X! 	_disable proc far
X! ;	procdef	disable
X  	pushf			; save state on stack
X  	cli			; interrupts off
X  	pop	ax		; original flags -> ax
X  	and	ax,200h		; 1<<9 is IF bit
X  	jnz	ion		; nonzero -> interrupts were on
X! ;	pret
X! 	ret
X  ion:	mov	ax,1
X! ;	pret
X! 	ret
X! ;	pend	disable
X! _disable endp
X  
X  ; restore - restore interrupt state: 0 = off, nonzero = on
X  
X! 	public	_restore
X! 	_restore proc far
X! ;	procdef	restore,<<istate,byte>>
X! 	push	bp
X! 	mov	bp,sp
X! 	test	byte ptr [bp+6],0ffh	;istate,0ffh
X  	jz	ioff
X  	sti
X! ;ioff:	pret
X! ioff:	mov	sp,bp
X! 	pop	bp
X! 	ret
X! ;	pend	restore
X! _restore endp
X  
X  ; Halt until an interrupt occurs, then return
X! 	public	_eihalt
X! 	_eihalt proc far
X! ;	procdef eihalt
X  	sti	; make sure interrupts are enabled
X  	hlt
X! ;	pret
X! 	ret
X! ;	pend	eihalt
X! _eihalt	endp
X  
X  ; multitasker types
X  NONE		equ	0
X***************
X*** 138,144 ****
X  DESQVIEW	equ	2
X  
X  ; Relinquish processor so other task can run
X! 	procdef	giveup
X  	cmp	mtasker, DOUBLEDOS
X  	jnz	givedesqview
X  	mov	al,2		; 110 ms
X--- 194,202 ----
X  DESQVIEW	equ	2
X  
X  ; Relinquish processor so other task can run
X! 	public	_giveup
X! 	_giveup proc far
X! ;	procdef	giveup
X  	cmp	mtasker, DOUBLEDOS
X  	jnz	givedesqview
X  	mov	al,2		; 110 ms
X***************
X*** 151,161 ****
X  	mov	ax, 1000h
X  	int	15h
X  notask:
X! 	pret
X! 	pend	giveup
X  
X  ; check for a multitasker running
X! 	procdef chktasker
X  	mov	mtasker, NONE
X  	; do the doubledos test
X  	mov	ah, 0e4h
X--- 209,223 ----
X  	mov	ax, 1000h
X  	int	15h
X  notask:
X! ;	pret
X! 	ret
X! ;	pend	giveup
X! _giveup	endp
X  
X  ; check for a multitasker running
X! 	public	_chktasker
X! 	_chktasker proc far
X! ;	procdef chktasker
X  	mov	mtasker, NONE
X  	; do the doubledos test
X  	mov	ah, 0e4h
X***************
X*** 165,171 ****
X  	cmp	al, 2
X  	jnz	test_desq
X  isdos:	mov	mtasker, DOUBLEDOS
X! 	pret
X  
X  	; test for desqview
X  test_desq:
X--- 227,234 ----
X  	cmp	al, 2
X  	jnz	test_desq
X  isdos:	mov	mtasker, DOUBLEDOS
X! ;	pret
X! 	ret
X  
X  	; test for desqview
X  test_desq:
X***************
X*** 175,191 ****
X  	int	21h
X  	cmp	al, 0ffh
X  	jnz	isdesq
X! 	pret
X  isdesq:	mov	mtasker, DESQVIEW
X! 	pret
X! 	pend	chktasker
X  
X  ; getds - Read DS for debugging purposes
X! 	procdef	getds
X  	push	ds
X  	pop	ax
X! 	pret
X! 	pend	getds
X  
X  ; Internet checksum subroutine
X  ; Compute 1's-complement sum of data buffer
X--- 238,261 ----
X  	int	21h
X  	cmp	al, 0ffh
X  	jnz	isdesq
X! ;	pret
X! 	ret
X  isdesq:	mov	mtasker, DESQVIEW
X! ;	pret
X! 	ret
X! ;	pend	chktasker
X! _chktasker endp
X  
X  ; getds - Read DS for debugging purposes
X! 	public	_getds
X! 	_getds proc far
X! ;	procdef	getds
X  	push	ds
X  	pop	ax
X! ;	pret
X! 	ret
X! ;	pend	getds
X! _getds	endp
X  
X  ; Internet checksum subroutine
X  ; Compute 1's-complement sum of data buffer
X***************
X*** 194,204 ****
X  ; lcsum(buf,cnt)
X  ; unsigned short *buf;
X  ; unsigned short cnt;
X! 	procdef	lcsum,<<buf,ptr>,<cnt,word>>
X  	pushds			; save if using large model
X  	push	si
X! 	ldptr	si,buf,ds	; ds:si = buf
X! 	mov	cx,cnt		; cx = cnt
X  	clc			; clear carry
X  	cld			; autoincrement si
X  	mov	dx,0		; clear accumulated sum
X--- 264,279 ----
X  ; lcsum(buf,cnt)
X  ; unsigned short *buf;
X  ; unsigned short cnt;
X! 	public	_lcsum
X! 	_lcsum proc far
X! ;	procdef	lcsum,<<buf,ptr>,<cnt,word>>
X! 	push	bp
X! 	mov	bp,sp
X  	pushds			; save if using large model
X  	push	si
X! 	mov	si,[bp+6]	;ldptr	si,buf,ds	; ds:si = buf
X! 	;mov	ds,[bp+6]
X! 	mov	cx,[bp+8]	;cnt		; cx = cnt
X  	clc			; clear carry
X  	cld			; autoincrement si
X  	mov	dx,0		; clear accumulated sum
X***************
X*** 211,218 ****
X  	xchg	al,ah		; byte swap result (8088 is little-endian)
X  	pop	si
X  	popds			; all done
X! 	pret
X! 	pend	lcsum
X  
X  ;
X  ; This routine is a generic int 21h handler, is used only by disk free
X--- 286,297 ----
X  	xchg	al,ah		; byte swap result (8088 is little-endian)
X  	pop	si
X  	popds			; all done
X! 	mov	sp,bp
X! 	pop	bp
X! 	ret
X! ;	pret
X! ;	pend	lcsum
X! _lcsum	endp
X  
X  ;
X  ; This routine is a generic int 21h handler, is used only by disk free
X***************
X*** 229,235 ****
X  ; isfree(&ax,&bx,&cx,&dx)
X  ; unsigned short ax,bx,cx,dx;
X  ;
X! 	procdef	isfree,<<c_ax,ptr>,<c_bx,ptr>,<c_cx,ptr>,<c_dx,ptr>>
X  	push	ax
X  	push	bx
X  	push	cx
X--- 308,319 ----
X  ; isfree(&ax,&bx,&cx,&dx)
X  ; unsigned short ax,bx,cx,dx;
X  ;
X! 	public	_isfree
X! 	_isfree	proc far
X! ;	procdef	isfree,<<c_ax,ptr>,<c_bx,ptr>,<c_cx,ptr>,<c_dx,ptr>>
X! 	push	bp
X! 	mov	bp,sp
X! 	push	ds		;Shouldn't ds be saved (Tom/IZF)
X  	push	ax
X  	push	bx
X  	push	cx
X***************
X*** 237,258 ****
X  	push	bp
X  	push	si
X  	push	di
X! 	ldptr	di,c_ax,ds
X  	mov	ax,[di]
X! 	ldptr	di,c_bx,ds
X  	mov	bx,[di]
X! 	ldptr	di,c_cx,ds
X  	mov	cx,[di]
X! 	ldptr	di,c_dx,ds
X  	mov	dx,[di]
X  	int 	21h
X! 	ldptr	di,c_ax,ds
X  	mov	[di],ax
X! 	ldptr	di,c_bx,ds
X  	mov	[di],bx
X! 	ldptr	di,c_cx,ds
X  	mov	[di],cx
X! 	ldptr	di,c_dx,ds
X  	mov	[di],dx
X  	pop	di
X  	pop	si
X--- 321,350 ----
X  	push	bp
X  	push	si
X  	push	di
X! 	mov	di,[bp+6]	;ldptr	di,c_ax,ds
X! 	;mov	ds,[bp+6]
X  	mov	ax,[di]
X! 	mov	di,[bp+8]	;ldptr	di,c_bx,ds
X! 	;mov	ds,[bp+10]
X  	mov	bx,[di]
X! 	mov	di,[bp+10]	;ldptr	di,c_cx,ds
X! 	;mov	ds,[bp+14]
X  	mov	cx,[di]
X! 	mov	di,[bp+12]	;ldptr	di,c_dx,ds
X! 	;mov	ds,[bp+18]
X  	mov	dx,[di]
X  	int 	21h
X! 	mov	di,[bp+6]	;ldptr	di,c_ax,ds
X! 	;mov	ds,[bp+6]
X  	mov	[di],ax
X! 	mov	di,[bp+8]	;ldptr	di,c_bx,ds
X! 	;mov	ds,[bp+10]
X  	mov	[di],bx
X! 	mov	di,[bp+10]	;ldptr	di,c_cx,ds
X! 	;mov	ds,[bp+14]
X  	mov	[di],cx
X! 	mov	di,[bp+12]	;ldptr	di,c_dx,ds
X! 	;mov	ds,[bp+18]
X  	mov	[di],dx
X  	pop	di
X  	pop	si
X***************
X*** 261,276 ****
X  	pop	cx
X  	pop	bx
X  	pop	ax
X! 	pret
X! 	pend	isfree
X  
X! 	finish
X  
X  
X! dataseg	segment	para public 'data'
X! 	bss	sssave:word,2
X! 	bss	spsave:word,2
X! 	bss	intstk:byte,512
X! 	bss	mtasker:byte,1
X! dataseg	ends
X  	end
X--- 353,404 ----
X  	pop	cx
X  	pop	bx
X  	pop	ax
X! 	pop	ds		;restore ds (Tom/IZF)
X! 	mov	sp,bp
X! 	pop	bp
X! 	ret
X! ;	pret
X! ;	pend	isfree
X! _isfree	endp
X  
X! 	public _outportw
X! _outportw proc far
X! 	push	bp
X! 	mov	bp,sp
X! 	mov	ax,[bp+8]
X! 	mov	dx,[bp+6]
X! 	out	dx,ax
X! 	mov	sp,bp
X! 	pop	bp
X! 	ret
X! _outportw endp
X  
X+ 	public _inportw
X+ _inportw proc far
X+ 	push	bp
X+ 	mov	bp,sp
X+ 	mov	dx,[bp+6]
X+ 	in	ax,dx
X+ 	mov	sp,bp
X+ 	pop	bp
X+ 	ret
X+ _inportw endp
X  
X! ;	finish
X! 
X! PCGEN_TEXT	ends
X! 
X! _BSS	segment
X! ;dataseg	segment	para public 'data'
X! public	sssave,spsave,intstk
X! sssave	dw	0
X! spsave	dw	0
X! intstk	dw	512 dup (?)
X! mtasker	db	0
X! ;	bss	sssave:word,2
X! ;	bss	spsave:word,2
X! ;	bss	intstk:byte,512
X! ;	bss	mtasker:byte,1
X! ;dataseg	ends
X! _BSS	ends
X  	end
SHAR_EOF
if test 45134 -ne "`wc -c < 'diffs'`"
then
	echo shar: error transmitting "'diffs'" '(should have been 45134 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ka9q.lnk'" '(617 characters)'
if test -f 'ka9q.lnk'
then
	echo shar: will not over-write existing file "'ka9q.lnk'"
else
sed 's/^X//' << \SHAR_EOF > 'ka9q.lnk'
X/STACK:0x2000 main.obj+version.obj+session.obj+
Xrsh.obj+telnet.obj+tnserv.obj+smisc.obj+
Xftpserv.obj+ftpcli.obj+ftp.obj+smtpserv.obj+smtpcli.obj+
Xtcpcmd.obj+tcpuser.obj+tcptimer.obj+tcpout.obj+tcpin.obj+tcpsubr.obj+
Xudpcmd.obj+udp.obj+
Xipcmd.obj+ip.obj+iproute.obj+
Xicmpcmd.obj+icmp.obj+
Xarpcmd.obj+arp.obj+
Xeccmd.obj+ec.obj+enet.obj+
Xslip.obj+
Xtimer.obj+ttydriv.obj+cmdparse.obj+mbuf.obj+alloc.obj+netuser.obj+
Xmisc.obj+pathname.obj+audit.obj+files.obj+icmpmsg.obj+
Xtrace.obj+enetdump.obj+
Xarpdump.obj+ipdump.obj+icmpdump.obj+udpdump.obj+tcpdump.obj+
Xpc.obj+dirutil.obj+ecvec.obj+
Xasy.obj+asyvec.obj+pcgen.obj
Xnet
X
X
SHAR_EOF
if test 617 -ne "`wc -c < 'ka9q.lnk'`"
then
	echo shar: error transmitting "'ka9q.lnk'" '(should have been 617 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'lmacros.h'" '(101 characters)'
if test -f 'lmacros.h'
then
	echo shar: will not over-write existing file "'lmacros.h'"
else
sed 's/^X//' << \SHAR_EOF > 'lmacros.h'
XFARPROC	macro
X	endm
X
X;LONGPTR macro
X;	endm
X
Xpushds	macro
X;	push	ds
X	endm
X
Xpopds	macro
X;	pop	ds
X	endm
SHAR_EOF
if test 101 -ne "`wc -c < 'lmacros.h'`"
then
	echo shar: error transmitting "'lmacros.h'" '(should have been 101 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rsh.c'" '(8505 characters)'
if test -f 'rsh.c'
then
	echo shar: will not over-write existing file "'rsh.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rsh.c'
X/*
X * RSH client for the KA9Q internet protocol package.
X * March 1988, Tom Vijlbrief (mcvax!tnosoes!tom)
X *
X * Usage:
X *
X * rsh host command
X * uprsh file host command	(executes command with file as input)
X * buprsh file host command	(executes command with binary file as input)
X * name username password	(should be executed before rsh commands)
X *
X * NOTE: The rexecd(8) daemon (SunOs 3.2/Berkeley 4.2) does not
X * return diagnostics from the rexecd daemon on stderr,
X * but on stdout. This is in contradiction with the manual page (rexecd(8))
X */
X/* #define DEBUG */
X
X#include <stdio.h>
X#include "global.h"
X#include "mbuf.h"
X#include "timer.h"
X#include "internet.h"
X#include "icmp.h"
X#include "netuser.h"
X#include "tcp.h"
X#include "session.h"
X#include "rsh.h"
X
X#define	REXEC_PORT	512
X
Xextern char nospace[];
Xextern char badhost[];
X
X#define	MAXMES	1024
X
Xstatic char name[20];
Xstatic char password[20];
X
Xint
Xdoname (argc,argv)
Xint argc;
Xchar *argv[];
X{
X  strcpy(name, argv[1]);
X  strcpy(password, argv[2]);
X}
X
X
X/* Execute user rsh command */
Xint
Xdorsh (argc,argv)
Xint argc;
Xchar *argv[];
X{
X	void rsh_state(),rsh_rcv(),rsh_tx(), null_tx(), errrsh_state(), up_tx();
X	char *inet_ntoa();
X	int32 resolve();
X	int	unix_send_rsh();
X	struct session *s;
X	struct rsh *r;
X	struct tcb *tcb;
X	struct socket lsocket,fsocket;
X	struct mbuf	*qdata();
X	int		len;
X	int		up_flag;
X	int		bin_flag= 0;
X	char		*upfile, *p, *buf;
X
X	if (up_flag= (argv[0][0] == 'u' || argv[0][0] == 'b')) { /* uprsh ? */
X		if (argv[0][0] == 'b')	/*buprsh ? */
X			bin_flag= 1;
X		upfile= argv[1];
X		argc--;
X		argv++;
X	}
X
X	if (! *name) {
X		printf("specify username and password with 'name' command\n");
X		return(1);
X	}
X
X	lsocket.address = ip_addr;
X	lsocket.port = lport++;
X#ifdef DEBUG
Xprintf("Local port: %d\n", lport - 1);
X#endif
X	if((fsocket.address = resolve(argv[1])) == 0){
X		printf(badhost,argv[1]);
X		return 1;
X	}
X	fsocket.port = REXEC_PORT;
X
X	/* Allocate a session descriptor */
X	if((s = newsession()) == NULLSESSION){
X		printf("Too many sessions\n");
X		return 1;
X	}
X	if((s->name = malloc((unsigned)strlen(argv[1])+1)) != NULLCHAR)
X		strcpy(s->name,argv[1]);
X	s->type = RSH;
X	s->parse = up_flag ? NULLFP: unix_send_rsh;
X	current = s;
X
X	/* Create and initialize a rsh protocol descriptor */
X	if((r = (struct rsh *)calloc(1,sizeof(struct rsh))) == NULLRSH
X		|| (buf= malloc(MAXMES)) == NULL) {
X		printf(nospace);
X		if (r != NULLRSH)
X			free(r);
X		s->type = FREE;
X		return 1;
X	}
X	if (up_flag && (r->upf= fopen(upfile, bin_flag ? binmode[0]: "r")) == NULL) {
X		perror(upfile);
X		free(r);
X		free(buf);
X		s->type= FREE;
X		return(1);
X	}
X	r->first_byte= 1;
X	r->up= up_flag;
X	r->session = s;	/* Upward pointer */
X	s->cb.rsh = r;	/* Downward pointer */
X
X	/* compose message: */
X	sprintf(buf, "%d\001%s\001%s", lport++, name, password);
X#ifdef DEBUG
Xprintf("%s\n", buf);
X#endif
X	for (p= buf; *p; p++)
X		if (*p == '\001')
X			*p= '\0';
X	p++;
X	argv+= 2;
X	argc-= 2;
X	for (; argc > 0; argv++, argc--) {
X#ifdef DEBUG
Xprintf("%s ", *argv);
X#endif
X		if ((p + (len= strlen(*argv))) >= buf + MAXMES) {
X			printf("Shell command is too long\n");
X			free(buf);
X			s->type = FREE;
X			return 1;
X		}
X		strcpy(p, *argv);
X		p+= len;
X		*p++= ' ';
X		*p= '\0';
X	}
X
X	tcb = open_tcp(&lsocket,&fsocket,TCP_ACTIVE,0,
X	 rsh_rcv,up_flag ? up_tx : rsh_tx,rsh_state,0,(char *)r);
X
X	r->tcb = tcb;	/* Downward pointer */
X
X	lsocket.address = ip_addr;
X	lsocket.port= lport-1;
X	r->errtcb = open_tcp(&lsocket,NULLSOCK,TCP_PASSIVE,0,
X	 rsh_rcv,NULLFP,errrsh_state,0,(char *)r);
X
X	send_tcp(tcb, qdata(buf, p+1 - buf));
X
X	if (up_flag)	/* kick transmitter */
X		up_tx(tcb,256);
X
X	go();
X	return 0;
X}
X
X
Xvoid null_tx()
X{ return; }
X
X/* Process typed characters */
Xint
Xunix_send_rsh(buf,n)
Xchar *buf;
Xint16 n;
X{
X	register int	i;
X	char		*index();
X	static char	exitchar[]= /* ^Z, ^D, ^C, DEL */
X		{'\032', '\004', '\003', '\177' };
X
X	for (i=0; (i<n) && (buf[i] != '\r'); i++)
X		;
X	if (buf[i] == '\r') {
X		buf[i] = '\n';
X		n = i+1;
X	}
X	if (n > 0 && index(exitchar, buf[0]) && current != NULLSESSION
X	   && current->cb.rsh != NULLRSH && current->cb.rsh->tcb != NULLTCB)
X		close_tcp(current->cb.rsh->tcb);
X	else
X		send_rsh(buf,n);
X}
Xint
Xsend_rsh(buf,n)
Xchar *buf;
Xint16 n;
X{
X	struct mbuf *bp,*qdata();
X	if(current == NULLSESSION || current->cb.rsh == NULLRSH
X	 || current->cb.rsh->tcb == NULLTCB)
X		return;
X	/* If recording is enabled, record it */
X	if(current->record != NULLFILE)
X		fwrite(buf,1,n,current->record);
X	bp = qdata(buf,n);
X	send_tcp(current->cb.rsh->tcb,bp);
X}
X
X/* Process incoming RSH characters */
Xint
Xrsh_input(r,bp, tcb)
Xstruct rsh *r;
Xstruct mbuf *bp;
Xstruct tcb	*tcb;
X{
X  register char	*p;
X  register int	start;
X  int	i;
X  char	c;
X  FILE	*f;
X
X  if (tcb == r->errtcb) {
X	f= stderr;
X	start= 0;
X  } else {
X	f= stdout;
X	start= (r->first_byte) ? 1 : 0;
X	r->first_byte= 0;
X  }
X
X  for (p= &bp->data[start]; start < bp->cnt; start++, p++)
X	putc(*p, f);
X
X  free_mbuf(bp);
X}
X
X/* rsh receiver upcall routine */
Xvoid
Xrsh_rcv(tcb,cnt)
Xregister struct tcb *tcb;
Xint16 cnt;
X{
X	struct mbuf *bp;
X	struct rsh *r;
X	FILE *record;
X
X	if((r = (struct rsh *)tcb->user) == NULLRSH){
X		/* Unknown connection; ignore it */
X		return;
X	}
X	/* Hold output if we're not the current session */
X	if(mode != CONV_MODE || current == NULLSESSION
X	 || current->type != RSH || current->cb.rsh != r)
X		return;
X
X	if(recv_tcp(tcb,&bp,cnt) > 0)
X		rsh_input(r,bp,tcb);
X
X	fflush(stdout);
X	if((record = r->session->record) != NULLFILE)
X		fflush(record);
X}
X
Xint textread(b, cnt, f)
X
Xchar		*b;
Xint		cnt;
XFILE		*f;
X{
X  register char	*p;
X  register int	c;
X
X  for (p= b; --cnt >= 0 && (c= getc(f)) != EOF; p++)
X	*p= c;
X  return(p-b);
X}
X
X/* Handle transmit upcalls. Used for uprsh */
Xvoid
Xup_tx(tcb,cnt)
Xstruct tcb *tcb;
Xint16 cnt;
X{
X	struct rsh *r;
X	struct session *s;
X	struct mbuf *bp;
X	int size;
X
X	if((r = (struct rsh *)tcb->user) == NULLRSH
X	 || (s = r->session) == NULLSESSION)
X		return;
X	if ((bp = alloc_mbuf(cnt)) == NULLBUF)
X		return;
X	if ((size = textread(bp->data,cnt,r->upf)) > 0){
X		bp->cnt = (int16)size;
X		send_tcp(tcb,bp);
X	} else {
X		free_p(bp);
X	}
X	if(size != cnt){
X		/* Error or end-of-file */
X		fclose(r->upf);
X		close_tcp(tcb);
X	}
X}
X
X/* Handle transmit upcalls. Used only for file uploading */
Xvoid
Xrsh_tx(tcb,cnt)
Xstruct tcb *tcb;
Xint16 cnt;
X{
X	struct rsh *r;
X	struct session *s;
X	struct mbuf *bp;
X	int size;
X
X	if((r = (struct rsh *)tcb->user) == NULLRSH
X	 || (s = r->session) == NULLSESSION
X	 || s->upload == NULLFILE)
X		return;
X	if((bp = alloc_mbuf(cnt)) == NULLBUF)
X		return;
X	if((size = fread(bp->data,1,cnt,s->upload)) > 0){
X		bp->cnt = (int16)size;
X		send_tcp(tcb,bp);
X	} else {
X		free_p(bp);
X	}
X	if(size != cnt){
X		/* Error or end-of-file */
X		fclose(s->upload);
X		s->upload = NULLFILE;
X		free(s->ufile);
X		s->ufile = NULLCHAR;
X		if (r->up)
X			close_tcp(tcb);
X	}
X}
X
X/* State change upcall routine */
Xvoid
Xrsh_state(tcb,old,new)
Xregister struct tcb *tcb;
Xchar old,new;
X{
X	struct rsh *r;
X	char notify = 0;
X	extern char *tcpstates[];
X	extern char *reasons[];
X	extern char *unreach[];
X	extern char *exceed[];
X
X	/* Can't add a check for unknown connection here, it would loop
X	 * on a close upcall! We're just careful later on.
X	 */
X	r = (struct rsh *)tcb->user;
X
X	if(current != NULLSESSION && current->type == RSH && current->cb.rsh == r)
X		notify = 1;
X
X	switch(new){
X	case CLOSE_WAIT:
X		if(notify && tcb->reason != NORMAL)
X			printf("%s\n",tcpstates[new]);
X		close_tcp(tcb);
X		break;
X	case CLOSED:	/* court adjourned */
X		if(notify){
X			if (tcb->reason != NORMAL)
X				printf("%s (%s",tcpstates[new],reasons[tcb->reason]);
X			if(tcb->reason == NETWORK){
X				switch(tcb->type){
X				case DEST_UNREACH:
X					printf(": %s unreachable",unreach[tcb->code]);
X					break;
X				case TIME_EXCEED:
X					printf(": %s time exceeded",exceed[tcb->code]);
X					break;
X				}
X			}
X			if (tcb->reason != NORMAL)
X				printf(")\n");
X			cmdmode();
X		}
X		del_tcp(tcb);
X		if (r != NULLRSH)
X			free_rsh(r);
X		break;
X	default:
X		if(notify && tcb->reason != NORMAL)
X			printf("%s\n",tcpstates[new]);
X		break;
X	}
X	fflush(stdout);
X}
X/* Delete rsh structure */
Xstatic
Xfree_rsh(r)
Xstruct rsh *r;
X{
X	if(r->session != NULLSESSION)
X		freesession(r->session);
X
X	if(r != NULLRSH)
X		free((char *)r);
X}
X
X/* Err channel state change upcall routine */
Xvoid
Xerrrsh_state(tcb,old,new)
Xregister struct tcb *tcb;
Xchar old,new;
X{
X	extern char *tcpstates[];
X	extern char *reasons[];
X	extern char *unreach[];
X	extern char *exceed[];
X
X	switch(new){
X	case CLOSE_WAIT:
X		close_tcp(tcb);
X		break;
X	case CLOSED:	/* court adjourned */
X		del_tcp(tcb);
X		break;
X	}
X}
SHAR_EOF
if test 8505 -ne "`wc -c < 'rsh.c'`"
then
	echo shar: error transmitting "'rsh.c'" '(should have been 8505 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rsh.h'" '(311 characters)'
if test -f 'rsh.h'
then
	echo shar: will not over-write existing file "'rsh.h'"
else
sed 's/^X//' << \SHAR_EOF > 'rsh.h'
X/* rsh protocol control block */
Xstruct rsh {
X	struct tcb *tcb, *errtcb;
X	char state;
X	struct session *session;	/* Pointer to session structure */
X	char first_byte;		/* first byte received ? */
X	char up;			/* flags uprsh command */
X	FILE *upf;			/* stdin file for uprsh */
X};
X#define	NULLRSH	((struct rsh *) 0)
SHAR_EOF
if test 311 -ne "`wc -c < 'rsh.h'`"
then
	echo shar: error transmitting "'rsh.h'" '(should have been 311 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
===============================================================================
Tom Vijlbrief
TNO Institute for Perception
P.O. Box 23				Phone: +31 34 63 14 44
3769 DE  Soesterberg			E-mail: tnosoes!tom@mcvax.cwi.nl
The Netherlands				    or:	uunet!mcvax!tnosoes!tom
===============================================================================

mshiels@watmath.waterloo.edu (Michael A. Shiels) (03/16/88)

Te problems you are having with VI have to do with NULLs being sent by
the other end and ANSI/NANSI.SYS are putting them out as spaces. BAD BAD!!
-- 
  Michael A. Shiels (MaS Network Software)
  mshiels@watmath.waterloo.EDU
UUCP: ...path...!watmath!mshiels

karn@thumper.bellcore.com (Phil R. Karn) (03/17/88)

> Te problems you are having with VI have to do with NULLs being sent by
> the other end and ANSI/NANSI.SYS are putting them out as spaces. BAD BAD!!

Some time ago I determined this was happening and I modified telnet.c to
filter out nulls from going to the console. I also filtered out control-Zs
since under some environments (notably DoubleDos) they cause the console
to hang.

I hate having to add ugly patches to get around bugs in other people's
broken software...

Phil