[comp.sys.handhelds] pf-bootstrap-v1.1a part 7 of 9

dan@i10s7.ira.uka.de (Dan Mosedale) (05/17/91)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 9)."
# Contents:  pf-bootstrap-v1.1a/tipx-p1/tip.c
#   pf-bootstrap-v1.1a/xmodem-3.9/receive.c
# Wrapped by dan@nostromo on Fri May 17 02:31:43 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'pf-bootstrap-v1.1a/tipx-p1/tip.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pf-bootstrap-v1.1a/tipx-p1/tip.c'\"
else
echo shar: Extracting \"'pf-bootstrap-v1.1a/tipx-p1/tip.c'\" \(16153 characters\)
sed "s/^X//" >'pf-bootstrap-v1.1a/tipx-p1/tip.c' <<'END_OF_FILE'
Xchar *tipx_rev = "x1.21";
X#define PATCHLEVEL 1
X/*
X * Copyright (c) 1983 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X/*
X * Modifications by Warren Tucker <wht%n4hgf.uucp@emory.mathcs.emory.edu>
X * for eight-bit transparent pass through and file transfer protocols
X * are unencumbered in any way. They are yours, ours, everybody's, nobody's.
X */
X/*+:EDITS:*/
X/*:05-08-1990-15:05-wht@n4hgf-rawthru */
X/*:05-08-1990-15:00-wht@n4hgf-move tip.c original to tip-orig.c */
X
X#ifndef lint
Xchar copyright[] =
X"@(#) Copyright(c) 1983 The Regents of the University of California.\n\
X All rights reserved.\n";
X#endif /* not lint */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)tip.c 5.8 (Berkeley) 9/2/88 (mod by wht@n4hgf)";
X#endif /* not lint */
X
X/*
X * tip - UNIX link to other systems
X *  tip [-psv] [-speed] system-name [data]
X * or
X *  cu phone-number [-s speed] [-l line] [-a acu]
X */
X#include "tip.h"
X
X/*
X * Baud rate mapping table
X */
Xint bauds[] = 
X{
X	0,50,75,110,134,150,200,300,600,
X	1200,1800,2400,4800,9600,19200,38400,-1
X};
X
X#ifdef TIPX
Xint rawthru = 0;
Xchar *rawthru_msg = "\r\n--> raw tip:  3 ~ rapidly for ~ equivalent\r\n";
Xchar *no_rawthru_msg = "\r\n--> normal tip: 1 ~ == ~\r\n";
Xextern char opened_tty[];
X#endif
X
Xint page;
Xint disc = OTTYDISC;		/* tip normally runs this way */
Xsigfunc_t	intprompt();
Xsigfunc_t	timeout();
Xsigfunc_t	cleanup();
Xchar *login();
Xchar *sname();
Xchar PNbuf[256];			/* This limits the size of a number */
Xstruct sgttyb ttyarg;
X
X#ifdef TIPX
Xtypedef struct b_to_br
X{
X	char *baud_rate;
X	int B_code;
X} B_TO_BR;
X
XB_TO_BR speeds[] = 	/* ordered to put less common rates later in table */
X{					/* and the vagaries of baud rates above 9600 "handled" */
X	"2400",	B2400,
X	"1200",	B1200,
X	"9600",	B9600,
X#if defined(B19200)
X	"19200",B19200,
X#endif
X#if defined(B38400)
X	"38400",B38400,
X#endif
X	"4800",	B4800,
X	"300",	B300,
X	"110",	B110,
X	"600",	B600,
X	"75",	B75,
X	"50",	B50,
X	"HUP",	B0,
X	"EXTA",	EXTA,
X	"EXTB",	EXTB,
X
X	(char *)0,0
X};
X#endif /* TIPX */
X
X/*+-------------------------------------------------------------------------
X	B_to_baud_rate(code) - convert CBAUD B_ code to baud rate string
X--------------------------------------------------------------------------*/
X#ifdef TIPX
Xchar *
XB_to_baud_rate(code)
Xint code;
X{
Xregister int n;
X
X	for(n=0; speeds[n].baud_rate; n++)
X		if(speeds[n].B_code == code)
X			return(speeds[n].baud_rate);
X	return("-----");
X}	/* end of B_to_baud_rate */
X#endif /* TIPX */
X
Xmain(argc,argv)
Xchar *argv[];
X{
X	int uuid;
X	char *system = NOSTR;
X	char *data = NOSTR;
X	register int i;
X	register char *p;
X	char sbuf[12];
X
X	uid = getuid();
X	gid = getgid();
X	euid = geteuid();	/* should be root */
X	egid = getegid();
X	uuid = getuucpuid();
X
X	if(equal(sname(argv[0]),"cu"))
X	{
X		setreuid(uid,uuid);
X		cumode = 1;
X		cumain(argc,argv);
X		goto cucommon;
X	}
X
X	if(argc < 2)
X	{
X		fprintf(stderr,"usage: tip [-psv] [-speed] [system-name] [data]\n");
X		exit(1);
X	}
X
X	for(; argc > 1; argv++,argc--)
X	{
X		if(argv[1][0] != '-')
X		{
X			if(system)
X				data = argv[1];
X			else
X				system = argv[1];
X		}
X		else switch(argv[1][1])
X		{
X
X		case 'p':
X			page++;
X			break;
X		case 's':
X			slip++;
X			break;
X		case 'v':
X			vflag++;
X			break;
X
X		case '0':
X		case '1':
X		case '2':
X		case '3':
X		case '4':
X		case '5':
X		case '6':
X		case '7':
X		case '8':
X		case '9':
X			BR = atoi(&argv[1][1]);
X			break;
X
X		default:
X			fprintf(stderr,"tip: %s, unknown option\n",argv[1]);
X			break;
X		}
X	}
X	if(!isatty(0) && !slip && !page)
X	{
X		fprintf(stderr,"tip: warning: input is not a tty\n");
X	}
X	if(slip)
X	{
X		setreuid(euid,uuid);
X		uid = 0;
X	}
X	else 
X	{
X		setreuid(uid,uuid);
X	}
X	euid = uuid;
X
X	if(system == NOSTR)
X		goto notnumber;
X	if(isalpha(*system))
X		goto notnumber;
X	/*
X	 * System name is really a phone number...
X	 * Copy the number then stomp on the original (in case the number
X	 *	is private, we don't want 'ps' or 'w' to find it).
X	 */
X	if(strlen(system) > sizeof PNbuf - 1)
X	{
X		fprintf(stderr,"tip: phone number too long (max = %d bytes)\n",
X		    sizeof PNbuf - 1);
X		exit(1);
X	}
X	strncpy( PNbuf,system,sizeof PNbuf - 1 );
X	for(p = system; *p; p++)
X		*p = '\0';
X	PN = PNbuf;
X	(void)sprintf(sbuf,"tip%d",BR);
X	system = sbuf;
X
Xnotnumber:
X	signal(SIGINT,cleanup);
X	signal(SIGQUIT,cleanup);
X	signal(SIGHUP,cleanup);
X	signal(SIGTERM,cleanup);
X	signal(SIGPIPE,cleanup);
X
X	if((i = hunt(system)) == 0)
X	{
X		printf("all ports busy\n");
X		exit(3);
X	}
X	if(i == -1)
X	{
X		printf("link down\n");
X		(void)uu_unlock(uucplock);
X		exit(3);
X	}
X	setbuf(stdout,NULL);
X	loginit();
X
X	/*
X	 * Kludge, their's no easy way to get the initialization
X	 *   in the right order, so force it here
X	 */
X	if((PH = getenv("PHONES")) == NOSTR)
X		PH = "/etc/phones";
X	vinit();				/* init variables */
X	setparity("none");			/* set the parity table */
X	if((i = speed(number(value(BAUDRATE)))) == NULL)
X	{
X		printf("tip: bad baud rate %d\n",number(value(BAUDRATE)));
X		(void)uu_unlock(uucplock);
X		exit(3);
X	}
X
X	if(slip)
X	{
X		if(SA == NOSTR)
X		{
X			printf("tip: local addr not set\n");
X			uu_unlock(uucplock);
X			exit(3);
X		}
X		if(DA == NOSTR)
X		{
X			printf("tip: destination addr not set\n");
X			uu_unlock(uucplock);
X			exit(3);
X		}
X		if(SM == NOSTR)
X		{
X			printf("tip: slip netmask not set\n");
X			uu_unlock(uucplock);
X			exit(3);
X		}
X	}
X
X	/*
X	 * Now that we have the logfile and the ACU open
X	 *  return to the real uid and gid.  These things will
X	 *  be closed on exit.  Swap real and effective uid's
X	 *  so we can get the original permissions back
X	 *  for removing the uucp lock.
X	 */
X	user_uid();	/* in the case of slip, we are now priviliged */
X
X	/*
X	 * Hardwired connections require the
X	 *  line speed set before they make any transmissions
X	 *  (this is particularly true of things like a DF03-AC)
X	 */
X	if(HW)
X		ttysetup(i);
X	if(p = lconnect())
X	{
X		printf("\07%s\n[EOT]\n",p);
X		daemon_uid();
X		(void)uu_unlock(uucplock);
X		exit(1);
X	}
X	if(!HW)
X		ttysetup(i);
X
X
X	if(LS != NOSTR)
X	{
X		fprintf(stderr,"\07[Logging in...]\r\n");
X		if(p = login())
X		{
X			printf("\07%s\n[EOT]\n",p);
X			daemon_uid();
X			(void)uu_unlock(uucplock);
X			exit(1);
X		}
X	}
X
X	if(page)
X	{
X		i = sendpage(data);
X		daemon_uid();
X		(void)uu_unlock(uucplock);
X		exit(i);
X	}
X
X	if(slip)
X	{
X		i = runslip();
X		daemon_uid();
X		(void)uu_unlock(uucplock);
X		exit(i);
X	}
X
Xcucommon:
X	/*
X	 * From here down the code is shared with
X	 * the "cu" version of tip.
X	 */
X
X	ioctl(0,TIOCGETP,(char *)&defarg);
X	ioctl(0,TIOCGETC,(char *)&defchars);
X	ioctl(0,TIOCGLTC,(char *)&deflchars);
X	ioctl(0,TIOCGETD,(char *)&odisc);
X	arg = defarg;
X#ifdef TIPX
X	arg.sg_flags = CBREAK;
X#else
X	arg.sg_flags = ANYP | CBREAK;
X#endif
X	tchars = defchars;
X	tchars.t_intrc = tchars.t_quitc = -1;
X	ltchars = deflchars;
X	ltchars.t_suspc = ltchars.t_dsuspc = ltchars.t_flushc
X	    = ltchars.t_lnextc = -1;
X	raw();
X
X	pipe(fildes);
X	pipe(repdes);
X	signal(SIGALRM,timeout);
X
X	/*
X	 * Everything's set up now:
X	 *	connection established (hardwired or dialup)
X	 *	line conditioned (baud rate, mode, etc.)
X	 *	internal data structures (variables)
X	 * so, fork one process for local side and one for remote.
X	 */
X#ifdef TIPX
X	printf("tipx (tip 4.3 mod by wht@n4hgf %s.%02d) connected to %s\r\n",
X		tipx_rev,PATCHLEVEL,opened_tty);
X	fputs("Copyright (c) 1983 The Regents of the University of California.\r\n",
X		stdout);
X	printf("line speed = %s, tandem = %s\r\n",
X		B_to_baud_rate(ttyarg.sg_ospeed),
X		(ttyarg.sg_flags & TANDEM) ? "yes" : "no");
X#else
X	printf(cumode ? "Connected\r\n" : "\07connected\r\n");
X#endif
X	if(pid = fork())
X		tipin();
X	else
X		tipout();
X	/*NOTREACHED*/
X}
X
Xsigfunc_t
Xcleanup()
X{
X
X	daemon_uid();
X	(void)uu_unlock(uucplock);
X	if(pid)
X	{
X		(void) kill(pid,SIGTERM);
X		unraw();
X	}
X	else if(odisc)
X		ioctl(0,TIOCSETD,(char *)&odisc);
X	exit(0);
X}
X
X/*
X * Muck with user ID's.  We are setuid to the owner of the lock
X * directory when we start.  user_uid() reverses real and effective
X * ID's after startup, to run with the user's permissions.
X * daemon_uid() switches back to the privileged uid for unlocking.
X * Finally, to avoid running a shell with the wrong real uid,
X * shell_uid() sets real and effective uid's to the user's real ID.
X */
Xstatic int uidswapped;
X
Xuser_uid()
X{
X	if(uidswapped == 0)
X	{
X		setregid(egid,gid);
X		setreuid(euid,uid);
X		uidswapped = 1;
X	}
X}
X
Xdaemon_uid()
X{
X	if(uidswapped)
X	{
X		setreuid(uid,euid);
X		setregid(gid,egid);
X		uidswapped = 0;
X	}
X}
X
Xshell_uid()
X{
X
X	setreuid(uid,uid);
X	setregid(gid,gid);
X}
X
X/*
X * put the controlling keyboard into raw mode
X */
Xraw()
X{
X
X	ioctl(0,TIOCSETP,&arg);
X	ioctl(0,TIOCSETC,&tchars);
X	ioctl(0,TIOCSLTC,&ltchars);
X	ioctl(0,TIOCSETD,(char *)&disc);
X}
X
X
X/*
X * return keyboard to normal mode
X */
Xunraw()
X{
X
X	ioctl(0,TIOCSETD,(char *)&odisc);
X	ioctl(0,TIOCSETP,(char *)&defarg);
X	ioctl(0,TIOCSETC,(char *)&defchars);
X	ioctl(0,TIOCSLTC,(char *)&deflchars);
X}
X
Xstatic jmp_buf promptbuf;
X
X/*
X * Print string ``s'', then read a string
X *  in from the terminal.  Handles signals & allows use of
X *  normal erase and kill characters.
X */
Xprompt(s,p)
Xchar *s;
Xregister char *p;
X{
X	register char *b = p;
X	sigfunc_t(*oint)(),(*oquit)();
X
X	stoprompt = 0;
X	oint = signal(SIGINT,intprompt);
X	oquit = signal(SIGQUIT,SIG_IGN);
X	unraw();
X	printf("%s",s);
X	if(setjmp(promptbuf) == 0)
X		while((*p = getchar()) != EOF && *p != '\n')
X			p++;
X	*p = '\0';
X
X	raw();
X	signal(SIGINT,oint);
X	signal(SIGQUIT,oint);
X	return(stoprompt || p == b);
X}
X
X/*
X * Interrupt service routine during prompting
X */
Xsigfunc_t
Xintprompt()
X{
X
X	signal(SIGINT,SIG_IGN);
X	stoprompt = 1;
X	printf("\r\n");
X	longjmp(promptbuf,1);
X}
X
X/*
X * ****TIPIN   TIPIN****
X */
Xtipin()
X{
X	char gch,bol = 1;
X
X	/*
X	 * Kinda klugey here...
X	 *   check for scripting being turned on from the .tiprc file,
X	 *   but be careful about just using setscript(), as we may
X	 *   send a SIGEMT before tipout has a chance to set up catching
X	 *   it; so wait a second, then setscript()
X	 */
X	if(boolean(value(SCRIPT)))
X	{
X		sleep(1);
X		setscript();
X	}
X
X#ifdef TIPX
X	if(!rawthru)
X		goto NORMAL_TIP2;
X
XRAWTHRU_TIP:
X	printf(rawthru_msg);
X	while(1)
X	{
X		long count;
X		char chbuf[4];
X		read(0,&gch,1);
X		if((gch == character(value(ESCAPE))))
X		{
X			sleep(1);
X			ioctl(0,FIONREAD,&count);
X			if(count == 2)
X			{	/* might have raw mode escape */
X				read(0,chbuf,2);
X				if((chbuf[0] == character(value(ESCAPE))) &&
X					(chbuf[1] == character(value(ESCAPE))))
X				{
X					printf("rawthru%s",ctrl(chbuf[0]));
X					if(!(gch = escape()))
X					{
X						if(!rawthru)
X						{
X							bol = 1;
X							goto NORMAL_TIP;
X						}
X						continue;
X					}
X				}
X				else
X				{
X					gch = character(value(ESCAPE));
X					write(FD,&gch,1);
X					write(FD,chbuf,2);
X					continue;
X				}
X			}
X		}
X		write(FD,&gch,1);
X	}
X
XNORMAL_TIP:
X	printf(no_rawthru_msg);
XNORMAL_TIP2:
X#endif /* TIPX */
X	while(1)
X	{
X		gch = getchar()&0177;
X		if((gch == character(value(ESCAPE))) && bol)
X		{
X			if(!(gch = escape()))
X#ifdef TIPX
X			{
X				if(rawthru)
X					goto RAWTHRU_TIP;
X				continue;
X			}
X#else /* TIPX */
X			continue;
X#endif /* TIPX */
X		}
X		else if(!cumode && gch == character(value(RAISECHAR)))
X		{
X			boolean(value(RAISE)) = !boolean(value(RAISE));
X			continue;
X		}
X		else if(gch == '\r')
X		{
X			bol = 1;
X			pwrite(FD,&gch,1);
X			if(boolean(value(HALFDUPLEX)))
X				printf("\r\n");
X			continue;
X		}
X		else if(!cumode && gch == character(value(FORCE)))
X			gch = getchar()&0177;
X		bol = any(gch,value(EOL));
X		if(boolean(value(RAISE)) && islower(gch))
X			gch = toupper(gch);
X		pwrite(FD,&gch,1);
X		if(boolean(value(HALFDUPLEX)))
X			printf("%c",gch);
X	}
X}
X
X/*
X * Escape handler --
X *  called on recognition of ``escapec'' at the beginning of a line
X */
Xescape()
X{
X	register char gch;
X	register esctable_t *p;
X	char c = character(value(ESCAPE));
X	extern esctable_t etable[];
X
X	gch = (getchar()&0177);
X	for(p = etable; p->e_char; p++)
X		if(p->e_char == gch)
X		{
X			if((p->e_flags&PRIV) && uid)
X				continue;
X#ifdef TIPX
X			if(!rawthru)
X#endif
X				printf("%s",ctrl(c));
X			(*p->e_func)(gch);
X			return(0);
X		}
X	/* ESCAPE ESCAPE forces ESCAPE */
X	if(c != gch)
X		pwrite(FD,&c,1);
X	return(gch);
X}
X
Xspeed(n)
Xint n;
X{
X	register int *p;
X
X	for(p = bauds; *p != -1;  p++)
X		if(*p == n)
X			return(p - bauds);
X	return(NULL);
X}
X
Xany(c,p)
Xregister char c,*p;
X{
X	while(p && *p)
X		if(*p++ == c)
X			return(1);
X	return(0);
X}
X
Xsize(s)
Xregister char *s;
X{
X	register int i = 0;
X
X	while(s && *s++)
X		i++;
X	return(i);
X}
X
Xchar *
Xinterp(s)
Xregister char *s;
X{
X	static char buf[256];
X	register char *p = buf,c,*q;
X
X	while(c = *s++)
X	{
X		for(q = "\nn\rr\tt\ff\033E\bb"; *q; q++)
X			if(*q++ == c)
X			{
X				*p++ = '\\';
X				*p++ = *q;
X				goto next;
X			}
X		if(c < 040)
X		{
X			*p++ = '^';
X			*p++ = c + 'A'-1;
X		}
X		else if(c == 0177)
X		{
X			*p++ = '^';
X			*p++ = '?';
X		}
X		else
X			*p++ = c;
Xnext:
X		;
X	}
X	*p = '\0';
X	return(buf);
X}
X
Xchar *
Xctrl(c)
Xchar c;
X{
X	static char s[3];
X
X	if(c < 040 || c == 0177)
X	{
X		s[0] = '^';
X		s[1] = c == 0177 ? '?' : c+'A'-1;
X		s[2] = '\0';
X	}
X	else 
X	{
X		s[0] = c;
X		s[1] = '\0';
X	}
X	return(s);
X}
X
X/*
X * Help command
X */
Xhelp(c)
Xchar c;
X{
X	register esctable_t *p;
X	extern esctable_t etable[];
X
X	printf("%c\r\n",c);
X	for(p = etable; p->e_char; p++)
X	{
X		if((p->e_flags&PRIV) && uid)
X			continue;
X		printf("%2s",ctrl(character(value(ESCAPE))));
X		printf("%-2s %c   %s\r\n",ctrl(p->e_char),
X		    p->e_flags&EXP ? '*': ' ',p->e_help);
X	}
X}
X
X/*
X * Set up the "remote" tty's state
X */
Xttysetup(speed)
Xint speed;
X{
X	unsigned bits = LDECCTQ;
X
X	ttyarg.sg_ispeed = ttyarg.sg_ospeed = speed;
X	ttyarg.sg_flags = RAW;
X	if(boolean(value(TAND)))
X		ttyarg.sg_flags |= TANDEM;
X	if(boolean(value(DTRHUP)))
X	{
X		ioctl(FD,TIOCSDTR,0);
X		ioctl(FD,TIOCHPCL,0);
X	}
X	ioctl(FD,TIOCSETP,(char *)&ttyarg);
X	ioctl(FD,TIOCLBIS,(char *)&bits);
X}
X
X/*
X * Return "simple" name from a file name,
X * strip leading directories.
X */
Xchar *
Xsname(s)
Xregister char *s;
X{
X	register char *p = s;
X
X	while(*s)
X		if(*s++ == '/')
X			p = s;
X	return(p);
X}
X
Xstatic char partab[0200];
X
X/*
X * Do a write to the remote machine with the correct parity.
X * We are doing 8 bit wide output, so we just generate a character
X * with the right parity and output it.
X */
Xpwrite(fd,buf,n)
Xint fd;
Xchar *buf;
Xregister int n;
X{
X	register int i;
X	register char *bp;
X	extern int errno;
X#ifdef TIPX
X	extern int rawthru;
X
X	if(rawthru)
X	{
X		write(fd,buf,n);
X		return;
X	}
X#endif /* TIPX */
X
X	bp = buf;
X	for(i = 0; i < n; i++)
X	{
X		*bp = partab[(*bp) & 0177];
X		bp++;
X	}
X	if(write(fd,buf,n) < 0)
X	{
X		if(errno == EIO)
X			abort("Lost carrier.");
X		/* this is questionable */
X		perror("write");
X	}
X}
X
X/*
X * Build a parity table with appropriate high-order bit.
X */
Xsetparity(defparity)
Xchar *defparity;
X{
X	register int i;
X	char *parity;
X	extern char evenpartab[];
X
X	if(value(PARITY) == NOSTR)
X		value(PARITY) = defparity;
X	parity = value(PARITY);
X	for(i = 0; i < 0200; i++)
X		partab[i] = evenpartab[i];
X	if(equal(parity,"even"))
X		return;
X	if(equal(parity,"odd"))
X	{
X		for(i = 0; i < 0200; i++)
X			partab[i] ^= 0200;	/* reverse bit 7 */
X		return;
X	}
X	if(equal(parity,"none") || equal(parity,"zero"))
X	{
X		for(i = 0; i < 0200; i++)
X			partab[i] &= ~0200;	/* turn off bit 7 */
X		return;
X	}
X	if(equal(parity,"one"))
X	{
X		for(i = 0; i < 0200; i++)
X			partab[i] |= 0200;	/* turn on bit 7 */
X		return;
X	}
X	fprintf(stderr,"%s: unknown parity value\n",PA);
X	fflush(stderr);
X}
X
X/* The uid could be determined by stat()-ing ACULOG */
Xgetuucpuid()
X{
X	struct passwd *pw;
X
X	if((pw = getpwnam("uucp")) == NULL)
X	{
X		fprintf(stderr,"tip: unable to get uucp uid\n");
X		exit(1);
X	}
X	return(pw->pw_uid);
X}
END_OF_FILE
if test 16153 -ne `wc -c <'pf-bootstrap-v1.1a/tipx-p1/tip.c'`; then
    echo shar: \"'pf-bootstrap-v1.1a/tipx-p1/tip.c'\" unpacked with wrong size!
fi
# end of 'pf-bootstrap-v1.1a/tipx-p1/tip.c'
fi
if test -f 'pf-bootstrap-v1.1a/xmodem-3.9/receive.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pf-bootstrap-v1.1a/xmodem-3.9/receive.c'\"
else
echo shar: Extracting \"'pf-bootstrap-v1.1a/xmodem-3.9/receive.c'\" \(17709 characters\)
sed "s/^X//" >'pf-bootstrap-v1.1a/xmodem-3.9/receive.c' <<'END_OF_FILE'
X#include "xmodem.h"
X
X/**  receive a file  **/
X
X/* returns TRUE if in the midst of a batch transfer */
X/* returns FALSE if no more files are coming */
X
X/* This routine is one HUGE do-while loop with far to many indented levels.
X * I chose this route to facilitate error processing and to avoid GOTOs.
X * Given the troubles I've had keeping the nested IF statements straight,
X * I was probably mistaken...
X */
X
Xrfile(name)
Xchar *name;
X{
X
Xchar *sectdisp();
Xchar *cpm_unix();
Xchar *strcpy();
Xchar *ctime();
Xtime_t time();
X
Xint fd,     /* file descriptor for created file */
Xchecksum,   /* packet checksum */
Xfirstchar,  /* first character of a packet */
Xsectnum,    /* number of last received packet (modulo 128) */
Xsectcurr,   /* second byte of packet--should be packet number (mod 128) */
Xsectcomp,   /* third byte of packet--should be complement of sectcurr */
Xtmode,      /* text mode if true */
Xamode,      /* apple mode if true */
Xerrors,     /* count of errors for each packet */
Xsterrors,   /* count of errors during startup handshake */
Xerrorflag,  /* set true when packet (or first char of putative packet) is invalid */
Xfatalerror, /* set within main "read-packet" Do-While when bad error found */
Xinchecksum, /* incoming checksum or CRC */
Xexpsect,    /* expected number of sectors (YMODEM batch) */
Xfirstwait,  /* seconds to wait for first character in a packet */
Xnocancanabort, /* if true, don't allow CAN-CAN abort */
Xbufsize;    /* packet size (128 or 1024) */
Xlong recvsectcnt;   /* running sector count (128 byte sectors) */
Xlong modtime;       /* Unix style file mod time from YMODEM header */
Xint filemode;       /* Unix style file mode from YMODEM header */
Xint serial;	/* serial # from YMODEM header */
Xint filesleft;		/* # of files left from YMODEM header */
Xlong totalleft;		/* # of bytes left from YMODEM header */
Xint yfiletype;		/* file type from YMODEM header */
Xlong readbackup;    /* "backup" value for characters read in file */
Xtime_t timep[2];    /* used in setting mod time of received file */
Xchar *p;    /* generic pointer */
Xint bufctr; /* number of real chars in read packet */
Xunsigned char *nameptr; /* ptr in filename for MODEM7 protocol */
Xtime_t start;       /* starting time of transfer */
Xint openflag = FALSE;   /* is file open for writing? */
X
Xlogit("----\nXMODEM File Receive Function\n");
Xtlogit("----\nXMODEM File Receive Function\n");
Xif (CRCMODE)
X	{
X	logit("CRC mode requested on command line\n");
X	tlogit("CRC mode requested on command line\n");
X	}
X
Xif (YMODEMG)
X	{
X	logit("YMODEM-G mode requested on command line\n");
X	tlogit("YMODEM-G mode requested on command line\n");
X	}
X
XBATCH = FALSE;          /* don't know if really are in batch mode ! */
Xfatalerror = FALSE;
Xfirstwait = WAITFIRST;  /* For first packet, wait short time */
Xsectnum = errors = recvsectcnt = 0;
Xbufsize = 128;
Xmodtime = 0l; filemode = 0;
Xserial = 0; filesleft = 0; totalleft = 0l; yfiletype = 0;
Xfilelength = 0l; fileread =0l; CHECKLENGTH = FALSE;
Xnocancanabort = FALSE;
X
Xtmode = (XMITTYPE == 't') ? TRUE : FALSE;
Xamode = (XMITTYPE == 'a') ? TRUE : FALSE;
X
X/* start up transfer */
X
Xsterrors = 0;
Xflushin();         /* flush input queue */
X
Xif (YMODEMG)
X	sendbyte(GCHR);
Xelse if (CRCMODE && !MDM7BAT)        
X{
X	sendbyte(CRCCHR);
X	if (LONGPACK && !MDM7BAT)
X		sendbyte(KCHR);
X}
Xelse
X	sendbyte(NAK);
X
X
Xdo                  /* start of MAIN Do-While loop to read packets */
X{   
X	errorflag = FALSE;
X	do              /* start by reading first byte in packet */
X	{
X		firstchar = readbyte(firstwait);
X	} 
X	while ((firstchar != SOH) 
X	    && (firstchar != STX) 
X	    && (firstchar != EOT) 
X	    && (firstchar != ACK || recvsectcnt > 0) 
X	    && (firstchar != TIMEOUT) 
X	    && (firstchar != CAN || nocancanabort));
X
X	if (firstchar == EOT && !NOEOT)           /* check for REAL EOT */
X	{
X		flushin();
X		sendbyte(NAK);              /* NAK the EOT */
X		if ((firstchar = readbyte(5)) != EOT)   /* check next character */
X		{
X			logit("Spurious EOT detected; ignored\n");
X			tlogit("Spurious EOT detected; ignored\n");
X			if ((firstchar == SOH) || (firstchar == STX) ||
X			    (firstchar == ACK && recvsectcnt == 0) ||
X			    (firstchar == CAN && !nocancanabort) ||
X			    (firstchar == TIMEOUT))
X				;
X			else
X			{
X				firstchar = 0;
X				errorflag = TRUE;
X			}
X		}
X	}
X
X	if (firstchar == TIMEOUT)       /* timeout? */
X	{  
X		if (recvsectcnt > 0)
X			{
X			logitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1));
X			tlogitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1));
X			}
X		errorflag = TRUE;
X	}
X
X	if (firstchar == CAN)           /* bailing out? (only at beginning or if CANCAN flag set) */
X	{
X		if ((readbyte(3) & 0x7f) == CAN)
X			{
X			if (openflag)
X				{
X				close(fd);
X				unlink(name);
X				error("Reception Canceled by CAN-CAN; partial file deleted",TRUE);
X				}
X			else
X				error("Reception Canceled by CAN-CAN",TRUE);
X			}
X		else
X		{
X			errorflag = TRUE;
X			logit("Received single CAN character\n");
X			tlogit("Received single CAN character\n");
X		}
X	}
X
X	if (firstchar == ACK)           /* MODEM7 batch? (only at beginning) */
X	{
X		int i,c; 
X
X		logit("MODEM7 Batch Protocol\n");
X		tlogit("MODEM7 Batch Protocol\n");
X		nameptr = buff;
X		checksum = 0;
X
X		for (i=0; i<NAMSIZ; i++)
X		{
X			c = readbyte(3);
X
X			if (c == CAN)
X			{
X				if (readbyte(3) == CAN)
X					error("Program Canceled by CAN-CAN", TRUE);
X				else
X				{
X					logit("Received single CAN character in MODEM7 filename\n");
X					tlogit("Received single CAN character in MODEM7 filename\n");
X					errorflag = TRUE;
X					break;
X				}
X			}
X
X			if (c == EOT && i == 0)
X			{
X				sendbyte(ACK);          /* acknowledge EOT */
X				logit("MODEM7 Batch Receive Complete\n");
X				tlogit("MODEM7 Batch Receive Complete\n");
X				return (FALSE);
X			}
X
X			if (c == TIMEOUT)
X			{
X				logit("Timeout waiting for MODEM7 filename character\n");
X				tlogit("Timeout waiting for MODEM7 filename character\n");
X				errorflag = TRUE;
X				break;
X			}
X
X			if (c == BAD_NAME)
X			{
X				logit("Error during MODEM7 filename transfer\n");
X				tlogit("Error during MODEM7 filename transfer\n");
X				errorflag = TRUE;
X				break;
X			}
X
X			*nameptr++ = c;
X			checksum += c;
X			sendbyte(ACK);
X		}
X
X		if (!errorflag)
X		{
X			c = readbyte(3);
X			if (c == CTRLZ)     /* OK; end of string found */
X			{
X				sendbyte(checksum + CTRLZ);
X				if (readbyte(15) == ACK)     /* file name found! */
X				{
X					xmdebug("MODEM7 file name OK");
X					*nameptr = '\000';  /* unixify the file name */
X					name = cpm_unix(buff);
X					BATCH = TRUE;
X					logitarg("MODEM7 file name: %s\n", name);
X					tlogitarg("MODEM7 file name: %s\n", name);
X					errors = 0;     /* restart crc handshake */
X					sleep(2);       /* give other side a chance */
X				}
X				else
X				{
X					logit("Checksum error in MODEM7 filename\n");
X					tlogit("Checksum error in MODEM7 filename\n");
X					errorflag = TRUE;
X				}
X			}
X			else
X			{
X				logit("Length error in MODEM7 filename\n");
X				tlogit("Length error in MODEM7 filename\n");
X				errorflag = TRUE;
X			}
X		}
X	}
X
X
X	if (firstchar == SOH || firstchar == STX)  /* start reading packet */
X	{
X		bufsize = (firstchar == SOH) ? 128 : 1024;
X
X		if (recvsectcnt == 0)           /* 1st data packet, initialize */
X		{
X			if (bufsize == 1024)
X				{
X				logit("1K packet mode chosen\n");
X				tlogit("1K packet mode chosen\n");
X				}
X			start = time((time_t *) 0);
X			errors = 0;
X			firstwait = 5;
X		}
X
X		sectcurr = readbyte(3);
X		sectcomp = readbyte(3);
X		if ((sectcurr + sectcomp) == 0xff)  /* is packet number checksum correct? */
X		{  
X			if (sectcurr == ((sectnum+1) & 0xff))   /* is packet number correct? */
X			{  
X				if (DEBUG)
X					fprintf(LOGFP,"DEBUG: packet with sector number %d started\n", sectnum);
X
X				/* Read, process and calculate checksum for a buffer of data */
X
X				readbackup = fileread;
X				if (readbuf(bufsize, 1, tmode, amode, recvsectcnt, &checksum, &bufctr) != TIMEOUT) 
X				{
X
X					/* verify checksum or CRC */
X
X					if (CRCMODE) 
X					{
X						checksum &= 0xffff;
X						inchecksum = readbyte(3);  /* get 16-bit CRC */
X						inchecksum = (inchecksum<<8) | readbyte(3);
X					}
X
X					else
X						inchecksum = readbyte(3);  /* get simple 8-bit checksum */
X
X					if (inchecksum == checksum) /* good checksum, hence good packet */
X					{  
X						xmdebug("checksum ok");
X						errors = 0;
X						recvsectcnt += (bufsize == 128) ? 1 : 8;
X						nocancanabort = CANCAN ? FALSE : TRUE;
X						sectnum = sectcurr; 
X
X						if (!openflag)      /* open output file if necessary */
X						{
X							openflag = TRUE;
X							if ((fd = creat(name, CREATMODE)) < 0)
X							{
X								sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X								error("Can't create file for receive", TRUE);
X							}
X							if (!BATCH)
X								{
X								logitarg("File Name: %s\n", name);
X								tlogitarg("File Name: %s\n", name);
X								}
X						}
X
X						if (write(fd, (char *) buff, bufctr) != bufctr)
X						{
X							close(fd);
X							unlink(name);
X							error("File Write Error", TRUE);
X						}
X						else
X						{
X							if (TIPFLAG && recvsectcnt % 32 == 0)
X								tlogitarg("Sector %s received\n", sectdisp(recvsectcnt,bufsize,0));
X							if (!YMODEMG)
X								{
X								flushin();          /* flush input */
X								sendbyte(ACK);      /* ACK the received packet */
X								}
X						}
X					}
X
X					/* Start handling various errors and special conditions */
X
X					else        /* bad checksum */
X					{  
X						logitarg("Checksum Error on Sector %s:  ", sectdisp(recvsectcnt,bufsize,1));
X						logitarg("sent=%x  ", inchecksum);
X						logitarg("recvd=%x\n", checksum);
X						tlogitarg("Checksum Error on Sector %s:  ", sectdisp(recvsectcnt,bufsize,1));
X						tlogitarg("sent=%x  ", inchecksum);
X						tlogitarg("recvd=%x\n", checksum);
X						fileread = readbackup;
X						errorflag = TRUE;
X						if (YMODEMG)
X							fatalerror = TRUE;
X					}
X				}
X
X				else    /* read timeout */
X				{
X					logitarg("Timeout while reading sector %s\n",sectdisp(recvsectcnt,bufsize,1));
X					tlogitarg("Timeout while reading sector %s\n",sectdisp(recvsectcnt,bufsize,1));
X					fileread = readbackup;
X					errorflag = TRUE;
X					if (YMODEMG)
X						fatalerror = TRUE;
X				}
X			}
X
X			else        /* sector number is wrong OR Ymodem filename */
X			{ 
X				if (sectcurr == 0 && recvsectcnt == 0)  /* Ymodem file-name packet */
X				{
X					logit("YMODEM Batch Protocol\n");
X					tlogit("YMODEM Batch Protocol\n");
X
X					/* Read and process a file-name packet */
X
X					if (readbuf(bufsize, 1, FALSE, FALSE, recvsectcnt, &checksum, &bufctr) != TIMEOUT) 
X					{
X
X						/* verify checksum or CRC */
X
X						if (CRCMODE) 
X						{
X							checksum &= 0xffff;
X							inchecksum = readbyte(3);  /* get 16-bit CRC */
X							inchecksum = (inchecksum<<8) | readbyte(3);
X						}
X
X						else
X							inchecksum = readbyte(3);  /* get simple 8-bit checksum */
X
X						if (inchecksum == checksum) /* good checksum, hence good filename */
X						{
X							xmdebug("checksum ok");
X							strcpy(name, (char *)buff);
X							expsect = ((buff[bufsize-1]<<8) | buff[bufsize-2]);
X							BATCH = TRUE;
X							YMDMBAT = TRUE;
X							if (strlen(name) == 0)  /* check for no more files */
X							{
X								flushin();          /* flush input */
X								sendbyte(ACK);      /* ACK the packet */
X								logit("YMODEM Batch Receive Complete\n");
X								tlogit("YMODEM Batch Receive Complete\n");
X								return (FALSE);
X							}
X							unixify(name);       /* make filename canonical */
X
X							/* read rest of YMODEM header */
X							p = (char *)buff + strlen((char *)buff) + 1;
X							if (DEBUG)
X								fprintf(LOGFP, "DEBUG: header info: %s\n", p);
X							sscanf(p, "%ld%lo%o%o%d%ld%d", 
X							  &filelength, &modtime, &filemode, 
X							  &serial, &filesleft, &totalleft,
X							  &yfiletype);
X							logitarg("YMODEM file name: %s\n", name);
X							tlogitarg("YMODEM file name: %s\n", name);
X							fileread = 0l;
X							if (filelength)
X							{
X								CHECKLENGTH = TRUE;
X								logitarg("YMODEM file size: %ld\n", filelength);
X								tlogitarg("YMODEM file size: %ld\n", filelength);
X							}
X							else if (expsect)
X								logitarg("YMODEM estimated file length %d sectors\n", expsect);
X							if (modtime)
X							{
X								logitarg("YMODEM file date: %s", ctime((time_t *)&modtime));
X							}
X							if (filemode)
X								logitarg("YMODEM file mode: %o\n", filemode);
X
X							if (filesleft)
X							{
X								logitarg("YMODEM %d file(s) left to receive ", filesleft);
X								logitarg("containing %ld bytes\n", totalleft);
X								tlogitarg("YMODEM %d file(s) left to receive ", filesleft);
X								tlogitarg("containing %ld bytes\n", totalleft);
X							}
X							if (serial)
X								logitarg("YMODEM sender's serial number: %d\n", serial);
X							if (yfiletype)
X								logitarg("YMODEM file type %d\n", yfiletype);
X
X							openflag = TRUE;	/* open the file for writing */
X							if ((fd = creat(name, CREATMODE)) < 0)
X							{
X								sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X								error("Can't create file for receive", TRUE);
X							}
X							if (!YMODEMG)
X								{
X								flushin();		/* flush the input stream */
X								sendbyte(ACK);		/* ACK the filename packet */
X								}
X							/* do initial handshake to start file transfer */
X							if (YMODEMG)
X								sendbyte(GCHR);
X							else if (CRCMODE) 
X							{
X								sendbyte(CRCCHR);
X								if (LONGPACK)
X									sendbyte(KCHR);
X							}
X							else
X								sendbyte(NAK);
X							firstwait = WAITFIRST;  /* reset waiting time */
X						}
X
X						else                /* bad filename checksum */
X						{
X							logit("checksum error on filename sector\n");
X							tlogit("checksum error on filename sector\n");
X							errorflag = TRUE;
X							if (YMODEMG)
X								fatalerror = TRUE;
X						}
X					}
X					else
X					{
X						logit("Timeout while reading filename packet\n");
X						tlogit("Timeout while reading filename packet\n");
X						errorflag = TRUE;
X						if (YMODEMG)
X							fatalerror = TRUE;
X					}
X				}
X
X				else if (sectcurr == sectnum)   /* duplicate sector? */
X				{  
X					logitarg("Duplicate sector %s flushed\n", sectdisp(recvsectcnt,bufsize,0));
X					tlogitarg("Duplicate sector %s flushed\n", sectdisp(recvsectcnt,bufsize,0));
X					if (YMODEMG)
X						{
X						errorflag = TRUE;
X						fatalerror = TRUE;
X						}
X					else
X						{
X						flushin();                  /* REALLY flush input */
X						while(readbyte(1) != TIMEOUT)
X							;
X						sendbyte(ACK);
X						}
X				}
X				else                /* no, real phase error */
X				{
X					logitarg("Phase Error - Expected packet is %s\n", sectdisp(recvsectcnt,bufsize,1));
X					tlogitarg("Phase Error - Expected packet is %s\n", sectdisp(recvsectcnt,bufsize,1));
X					errorflag = TRUE;
X					fatalerror = TRUE;
X				}
X			}
X		}
X
X		else        /* bad packet number checksum */
X		{  
X			logitarg("Header Sector Number Error on Sector %s\n", sectdisp(recvsectcnt, bufsize,1));
X			tlogitarg("Header Sector Number Error on Sector %s\n", sectdisp(recvsectcnt, bufsize,1));
X			errorflag = TRUE;
X			if (YMODEMG)
X				fatalerror = TRUE;
X		}
X
X	}           /* END reading packet loop */
X
X	if (errorflag && !fatalerror && recvsectcnt != 0)   /* Handle errors */
X	{  
X		errors++;
X
X		if (errors >= ERRORMAX)     /* over error limit? */
X			fatalerror = TRUE;
X		else                        /* flush input and NAK the packet */
X		{
X			flushin();
X			while (readbyte(2) != TIMEOUT)  /* wait for line to settle */
X				;
X			sendbyte(NAK);
X		}
X	}
X
X	if (recvsectcnt == 0 && errorflag && !fatalerror && firstchar != EOT) 	/* handle startup handshake */
X	{
X		sterrors++;
X
X		if (sterrors >= STERRORMAX)
X			fatalerror = TRUE;
X
X		else if (CRCMODE && MDM7BAT && !BATCH)
X			sendbyte(NAK);
X		
X		else if (CRCMODE && sterrors == CRCSWMAX && !YMDMBAT)
X		{
X			CRCMODE = FALSE;
X			logit("Sender not accepting CRC request, changing to checksum\n");
X			tlogit("Sender not accepting CRC request, changing to checksum\n");
X			sendbyte(NAK);
X		}
X
X		else if (!CRCMODE && sterrors == CRCSWMAX && !YMDMBAT)
X		{
X			CRCMODE = TRUE;
X			logit("Sender not accepting checksum request, changing to CRC\n");
X			tlogit("Sender not accepting checksum request, changing to CRC\n");
X			sendbyte(CRCCHR);
X			if (LONGPACK && !MDM7BAT)
X				sendbyte(KCHR);
X		}
X
X		else if (YMODEMG)
X			sendbyte(GCHR);
X
X		else if (CRCMODE)
X			{
X			sendbyte(CRCCHR);
X			if (LONGPACK && !MDM7BAT)
X				sendbyte(KCHR);
X			}
X
X		else
X			sendbyte(NAK);
X	}
X}
Xwhile ((firstchar != EOT) && !fatalerror);   /* end of MAIN Do-While */
X
Xif ((firstchar == EOT) && !fatalerror)  /* normal exit? */
X{
X	if (openflag)       /* close the file */
X		close(fd);
X	sendbyte(ACK);      /* ACK the EOT */
X	logit("Receive Complete\n");
X	tlogit("Receive Complete\n");
X	if (LOGFLAG)
X		prtime (recvsectcnt, time((time_t *) 0) - start, LOGFP);
X	if (TIPFLAG)
X		prtime (recvsectcnt, time((time_t *) 0) - start, stderr);
X
X	if (openflag && modtime)   /* set file modification time */
X	{
X		timep[0] = time((time_t *) 0);
X		timep[1] = modtime;
X		utime(name, timep);
X	}
X
X	if (BATCH)          /* send appropriate return code */
X		return(TRUE);
X	else
X		return(FALSE);
X}
Xelse                /* no, error exit */
X{ 
X	if (openflag)
X	{
X		sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X		close(fd);
X		unlink(name);
X		flushin();
X		while (readbyte(2) != TIMEOUT)  /* wait for line to settle */
X			;
X		error("ABORTED -- Too Many Errors -- Deleting File", TRUE);
X	}
X	else if (recvsectcnt != 0)
X		{
X		sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
X		flushin();
X		while (readbyte(2) != TIMEOUT)  /* wait for line to settle */
X			;
X		error("ABORTED -- Too Many Errors", TRUE);
X		}
X	else
X		{
X		flushin();
X		while (readbyte(2) != TIMEOUT)  /* wait for line to settle */
X			;
X		error("ABORTED -- Remote system is not responding", TRUE);
X		}
X
X}
X
Xreturn(FALSE);
X}
END_OF_FILE
if test 17709 -ne `wc -c <'pf-bootstrap-v1.1a/xmodem-3.9/receive.c'`; then
    echo shar: \"'pf-bootstrap-v1.1a/xmodem-3.9/receive.c'\" unpacked with wrong size!
fi
# end of 'pf-bootstrap-v1.1a/xmodem-3.9/receive.c'
fi
echo shar: End of archive 7 \(of 9\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0