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,<chars); 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