Path: utzoo!mnetor!uunet!husc6!tut.cis.ohio-state.edu!rutgers!iuvax!pur-ee!j.cc.purdue.edu!ain From: ain@j.cc.purdue.edu (Patrick White) Newsgroups: comp.sources.amiga Subject: uupc version 1.1 (part 1 of 3) Message-ID: <6732@j.cc.purdue.edu> Date: 21 Mar 88 05:02:47 GMT Organization: PUCC Land, USA Lines: 2590 Keywords: part 1 of 3, version 1.1, uupc, uncompiled Approved: ain@j.cc.purdue.edu (Pat White) Program Name: uupc version 1.1 (part 1 of 3) Submitted By: Johan Widen Summary: Implements uucp for the Amiga -- allows your Amiga to become a uupc site for mail (and news?). Poster Boy: Pat White (ain@j.cc.purdue.edu) Uncompiled. NOTES: Haven't tried to compile it. Converted the origional zoo to shars so docs, binaries & sources could be separated. I'm pretty sure this would allow one to receive news, but I remember something in the docs about it not having been tested from when I was quickly scanning them... so I'm not too sure on this. Rob has been playing with it for a while and says it works. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # dcp.c # dcp.h # dcpgpkt.c # dcpsys.c # dcpxfer.c # This archive created: Sat Mar 19 01:40:46 1988 # By: Patrick White (PUCC Land, USA) echo shar: extracting Makefile '(701 characters)' cat << \SHAR_EOF > Makefile CFLAGS=-b -r all: uupc mail pccp uupc: uuhost.o dcp.o dcpsys.o dcpxfer.o dcpgpkt.o rmail.o lib.o ulib.o ndir.o \ genv.o sio.o timer.o serial.o sleep.o df0:c/blink with link.uupc.cmd mail: mailhost.o mail.o lmail.o mlib.o lib.o ndir.o genv.o raw.o sendpacket.o df0:c/blink with link.mail.cmd pccp: pccp.o genv.o cc -o pccp pccp.o genv.o dcp.o: dcp.h host.h genv.h dcpgpkt.o: dcp.h host.h genv.h dcpsys.o: dcp.h host.h genv.h ndir.h dcpxfer.o: dcp.h host.h genv.h genv.o: genv.h lib.o: host.h genv.h lmail.o: host.h genv.h mail.o: host.h genv.h mailhost.o: host.h genv.h mlib.o: host.h genv.h ndir.o: ndir.h pccp.o: host.h rmail.o: host.h genv.h ulib.o: host.h genv.h uuhost.o: host.h genv.h SHAR_EOF if test 701 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 701 characters)' fi echo shar: extracting dcp.c '(9330 characters)' cat << \SHAR_EOF > dcp.c /* dcp.c Revised edition of dcp Stuart Lynne May/87 Copyright (c) Richard H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart Lynne 1987 Maintenance Notes: 25Aug87 - Added a version number - Jal 25Aug87 - Return 0 if contact made with host, or 5 otherwise. 04Sep87 - Bug causing premature sysend() fixed. - Randall Jessup. */ /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 * This program implements a uucico type file transfer and remote * execution type protocol. */ #define VERSION "1.8 Camelot" #include "dcp.h" #include /**/ int pktsize; /* packet size for pro */ FILE *logfile; /* system log file */ FILE *syslog; /* system log file */ FILE *fw; /* cfile pointer */ char state; /* system state*/ char cfile[80]; /* work file pointer */ int remote; /* -1 means we're remote ..7*/ int msgtime; /* timout setting */ char fromfile[132]; char hostfile[132]; /* host version of fromfile */ char tofile[132]; int fp; /* current disk file ptr */ int size; /* nbytes in buff */ FILE *fsys; char Rmtname[20]; char rmtname[20]; char * cctime; char proto[5]; /* char loginseq[256]; */ char sysline[BUFSIZ]; char s_systems[64]; char s_logfile[64]; char s_syslog[64]; char *flds[60]; int kflds; unsigned int checksum(); /**/ /* new usage dcp [-xn] -r0 slave mode dcp [-xn] -shost call host dcp [-xn] -sall call all hosts dcp [-xn] call any hosts as required by C. files */ complain( s ) char *s; { fprintf( stderr, "Please set your %s environment variable.", s ); } static void cant( file ) char *file; { fprintf( stderr, "Can't open: \"%s\"\n", file ); onBreak(); } onBreak() { extern char *orgDir; sysAbortEnd(); chdir( orgDir ); exit(100); } dcpmain( argc, argv ) int argc; char*argv[]; { FILE *ftmp; char line[132]; int Contact = FALSE; if ( name == NULL || *name == '\0' ) { complain( NAME ); onBreak(); } if ( nodename == NULL || *nodename == '\0' ) { complain( NODENAME ); onBreak(); } mkfilename( s_logfile, logdir, LOGFILE ); mkfilename( s_syslog, logdir, SYSLOG ); mkfilename( s_systems, confdir, SYSTEMS ); if ( (logfile = FOPEN( s_logfile, "a", 't' )) == NULL ) cant( s_logfile ); if ( (syslog = FOPEN( s_syslog, "a", 't' )) == NULL ) cant( s_syslog ); fp = -1; fw = (FILE *)NULL; remote = MASTER; strcpy( Rmtname, "any" ); remote = MASTER; while ( --argc ) { if ( **(++argv) == '-') { switch(argv[0][1]) { case 'x': debuglevel = atoi( &argv[0][2] ); break; case 's': sprintf( Rmtname, "%.7s", &argv[0][2] ); break; case 'r': remote = atoi( &argv[0][2] ); break; default: break; } } } signal(SIGINT, onBreak); printmsg(0, "UUPC Version %s", VERSION ); if ( remote == MASTER ) { printmsg( 0, "Calling %s %d", Rmtname, debuglevel ); if (( fsys = FOPEN( s_systems, "r", 't' )) == (char *)NULL ) onBreak(); state = 'I'; while (TRUE) { printmsg( 4, "Mstate = %c", state ); switch (state) { case 'I': state = getsystem(); break; case 'S': state = callup(); break; case 'P': state = startup(); break; case 'D': state = master(); Contact = TRUE; break; case 'Y': state = sysend(); break; case 'Z': state = sysAbortEnd(); break; case 'G': if ( strcmp( Rmtname, "any" ) == SAME ) state = 'Y'; else state = 'I'; break; } if (state == 'A') break; } fclose( fsys ); } else { if (openline( device, speed ) == -1) return(FALSE); state = 'L'; while (TRUE) { printmsg( 4, "Sstate = %c", state ); switch (state) { case 'L': state = login(); break; case 'I': state = startup(); break; case 'R': state = slave(); break; case 'Y': state = sysend(); break; } if (state == 'A') break; } closeline(); } /* fprintf( stderr, "calling dcxqt\n" ); */ if (dcxqt()) printmsg( 0, "ERROR in DCXQT" ); /* scan and process any recieved files */ fclose( syslog ); fclose( logfile ); if (Contact ) return 0; else return 5; } /**/ /* ** ** **master ** ** */ master() { state = 'I'; while (TRUE) { printmsg( 4, "Top level state (master mode) %c", state ); switch (state) { case 'I': state = sinit(); break; case 'B': state = scandir(); break; case 'R': state = mreceive(); break; case 'S': state = send(); break; case 'Q': state = sbreak(); break; case 'G': state = receive(); break; case 'C': state = 'Y'; break; case 'Y': state = endp(); break; case 'P': return('Y'); case 'A': return('A'); default: return('A'); } } } /**/ /* ** ** **slave ** ** */ slave() { state = 'I'; while (TRUE) { printmsg( 4, "Top level state (slave mode) %c", state ); switch (state) { case 'I': state = rinit(); break; case 'F': state = receive(); break; case 'C': state = schkdir(); break; case 'T': state = 'B'; break; case 'B': state = scandir(); break; case 'S': state = send(); break; case 'Q': state = sbreak(); break; case 'G': return('Y'); case 'Y': state = endp(); break; case 'P': return('Y'); case 'A': return('A'); default: return('A'); } } } /**/ /* * r e c e i v e * * This is the state table switcher for receiving files. */ receive() { state = 'F';/* Receive-Init is the start state */ while (TRUE) { printmsg( 4, " receive state: %c", state ); switch (state)/* Do until done */ { case 'F': state = rfile(); break; /* Receive-File */ case 'D': state = rdata(); break; /* Receive-Data */ case 'C': return('C');/* Complete state */ case 'd': /* send file in slave mode */ while ((state = sdata()) == 'D'); break; case 'Z': state = reof(); break; case 'A': return('Y'); /* "Abort" state */ default: return('Y'); } } } /**/ /* * s e n d * * This is the state table switcher for sending files in master mode. It * loops until either it finishes, or an error is encountered. The routines * called by send() are responsible for changing the state. * */ send() { fp = -1; /* reset file getter/opener */ state = 'F';/* Send initiate is the start state */ while (TRUE)/* Do this as long as necessary */ { printmsg( 4, "send state: %c", state ); switch (state) { case 'F': state = sfile(); break; /* Send-File */ case 'D': state = sdata(); break; /* Send-Data */ case 'Z': state = seof(); break; /* Send-End-of-File */ case 'B': return ('B'); /* Complete */ case 'R': return ('R'); /* Receive a file */ case 'A': return ('Y'); /* "Abort" */ default: return ('Y'); /* Unknown, fail */ } } } /**/ /* * m r e c e i v e * * This is the state table switcher for receiving files in master mode. It * loops until either it finishes, or an error is encountered. The routines * called by sendsw are responsible for changing the state. * */ mreceive() { fp = -1; /* reset file getter/opener */ state = 'F';/* Receive initiate is the start state */ while (TRUE)/* Do this as long as necessary */ { printmsg( 4, "send state: %c", state ); switch (state) { case 'F': state = mrfile(); break; /* Recive-File */ case 'D': if((state = rdata()) == 'F') return('S'); break; /* Receive-Data */ case 'B': return ('S'); /* Complete */ case 'A': state = mrabort(); /* "Abort" */ break; default: return ('Y'); /* Unknown, fail */ } } } /**/ /* A command formatter for DCP. RH Lamb */ /* sets up stdin and stdout on various machines */ /* There is NO command checking so watch what you send and who you */ /* let accsess your machine. "C rm /usr/*.*" could be executed. */ dcxqt() { int i; char command[60], input[60], output[60], line[BUFSIZ]; char *cp; while (dscandir()) { strcpy( line, cfile ); fw = FOPEN( line, "r", 'b' );/* imported X file */ strcpy(cfile, line); printmsg( 2, "dcxqt:%s %ld", cfile, fw ); input[0] = '\0'; output[0] = '\0'; command[0] = '\0'; while ( fgets( line, BUFSIZ, fw ) != (char *)NULL ) { cp = index( line, '\n' ); if ( cp != (char *)NULL ) *cp = '\0'; printmsg( 8, "dcxqt: %s", line ); switch (line[0]) { case 'U': break; case 'I': strcpy( input, &line[2] ); break; case 'O': strcpy( output, &line[2] ); break; case 'C': strcpy( command, &line[2] ); break; case 'R': break; default : break; } } fclose( fw ); printmsg( 0, "xqt: %s", command ); shell( command, input, output, (char *)NULL ); unlink(cfile); if (input[0]) { importpath( hostfile, input ); unlink(hostfile); } if (output[0]) { importpath( hostfile, output ); unlink(hostfile); } } return(0); } /**/ /* * p r i n t m s g * * Print error message on standard output if not remote. */ /*VARARGS1*/ printmsg(level, fmt, a1, a2, a3, a4, a5) int level; char *fmt; char *a1, *a2, *a3, *a4, *a5; { char msg[256]; if ( debuglevel > level ) { sprintf( msg, fmt, a1, a2, a3, a4, a5 ); strcat( msg, "\n" ); if ( remote == MASTER ) { fputs( msg, stdout ); fflush( stdout ); } fputs( msg, logfile ); } } SHAR_EOF if test 9330 -ne "`wc -c dcp.c`" then echo shar: error transmitting dcp.c '(should have been 9330 characters)' fi echo shar: extracting dcp.h '(2347 characters)' cat << \SHAR_EOF > dcp.h /* DCP a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ #include /* Standard UNIX definitions */ #include "host.h" /* Host specific definitions */ FILE * FOPEN(); int CREAT(); #define SYSTEMS "systems" #define LOGFILE "LOGFILE" #define SYSLOG "SYSLOG" #define MSGTIME 20 #define MAXPACK 256 #define ACK 4 /* general definitions */ #define NAK 2 #define DATA 0 #define CLOSE 1 #define ERROR 10 #define EMPTY 11 #define SLAVE 0 #define MASTER 1 #define FAILED -1 #define OK 0 /* L.sys field defines */ #define FLD_REMOTE 0 #define FLD_CCTIME 1 #define FLD_DEVICE 2 #define FLD_TYPE 3 #define FLD_SPEED 4 #define FLD_PROTO 5 #define FLD_EXPECT 6 #define FLD_SEND 7 /**/ typedef int (*procref)(); typedef struct { char type; procref a; procref b; procref c; procref d; } Proto; /* the various protocols available. Add here for others */ extern procref getpkt, sendpkt, openpk, closepk; extern int ggetpkt(), gsendpkt(), gopenpk(), gclosepk(); /* extern int kgetpkt(), ksendpkt(), kopenpk(), kclosepk(); extern int rgetpkt(), rsendpkt(), ropenpk(), rclosepk(); extern int tgetpkt(), tsendpkt(), topenpk(), tclosepk(); */ /**/ extern int pktsize; /* packet size for this pro*/ extern FILE *logfile; /* system log file */ extern FILE *syslog; /* system log file */ extern FILE *fw; /* cfile pointer */ extern char cfile[80]; /* work file pointer */ extern int remote; /* -1 means we're remote*/ extern int findwork; extern int msgtime; /* timout setting */ extern char fromfile[132]; extern char hostfile[132]; /* host version of fromfile */ extern char tofile[132]; extern char state; /* present state */ extern int fp; /* current disk file ptr */ extern int size; /* nbytes in buff */ extern FILE *fsys; extern char Rmtname[20]; extern char rmtname[20]; extern char *cctime; extern char proto[5]; extern char sysline[BUFSIZ]; extern char s_systems[64]; extern char s_logfile[64]; extern char s_syslog[64]; extern char *flds[60]; extern int kflds; extern int debuglevel; /* debugging flag */ extern unsigned int checksum(); extern char *index(); extern char *rindex(); extern char *curdir; SHAR_EOF if test 2347 -ne "`wc -c dcp.h`" then echo shar: error transmitting dcp.h '(should have been 2347 characters)' fi echo shar: extracting dcpgpkt.c '(15366 characters)' cat << \SHAR_EOF > dcpgpkt.c /* dcpgpkt.c Revised edition of dcp Stuart Lynne May/87 Copyright (c) Richard H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart Lynne 1987 */ /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ /* 3-window "g" ptotocol */ /* Thanks got to John Gilmore for sending me a copy of Greg Chesson's UUCP protocol description-- Obviously invaluable Thanks also go to Andrew Tannenbaum for the section on Siding window protocols with a program example in his "Computer Networks" book MAINTENANCE NOTES: 25Aug87 - Allow for up to 7 windows - Jal */ #include "dcp.h" #define PKTSIZE 64 #define PKTSIZ2 2 #define HDRSIZE 6 #define MAXTRY 4 #define MAXERR 200 /* Dont want to quit in a middle of a long file*/ #define MAXBADINAROW 5 /* Max bad reads in a row */ #define TIMEOUT 4 /* could be longer */ #define KPKT 1024/PKTSIZE #define POK -1 #define MAXWINDOW 7 #define NBUF 8 /* always SAME as MAXSEQ ? */ #define MAXSEQ 8 #define between(a,b,c) ((a<=b && b= MAXBADINAROW || nerr >= MAXERR) return(-1); switch (grpack(&n1, &n2, &len, tmp)) { case 7: badInARow = 0; gspack(6, 0, 0, 0, tmp); nwindows = n1; if ( nwindows > MAXWINDOW ) nwindows = MAXWINDOW; rwu = nwindows - 1; goto rsrt; case 6: badInARow = 0; gspack(5, 0, 0, 0, tmp); goto rsrt; case 5: badInARow = 0; break; default: badInARow++; nerr++; gspack(7, 0, 0, 0, tmp); goto rsrt; } nerr = 0; return(0); /* channel open */ } gclosepk() { int i; char tmp[PKTSIZE+1]; timeout = 10; for (i = 0; i < MAXTRY && badInARow < MAXBADINAROW; i++) { gspack(CLOSE, 0, 0, 0, tmp); if (gmachine() == CLOSE) break; } printmsg( 0, "number of errors %d and pkts xfered %d", nerr, npkt ); return(0); } /* * * ggetpkt ***** description: Gets no more than a packet's worth of data from **** the "packet i/o state machine". May have to **** periodically run the pkt machine to get some **** packets. * on input: dont care getpkt(data,&len) char *data int len * on return: data+\0 and length in len. ret(0) if alls well * ret(-1) if problems.(fail) */ ggetpkt(cdata, len) int *len; char cdata[]; { int i2; irec = 1; timeout = 10; /* WAIT FOR THE DESIRED PACKET */ while ((arr[rwl]) == FALSE) if (gmachine() != POK) return(-1); /* GOT A PKT ! */ i2 = rwl; /*<-- mod(,rwindow) for larger than 8 seq no.s */ *len = inlen[i2]; movmem(inbuf[i2], cdata, *len); arr[i2] = FALSE; rwu = (1 + rwu) % MAXSEQ; /* bump rec window */ npkt++; return(0); } /* * * sendpkt * ***** description: Put at most a packet's worth of data in the pkt state **** machine for xmission. ***** May have to run the pkt machine a few times to get ***** an available output slot. * * on input: char *data int len,flg; len=length of data in data. * flg=2 just send the packet with no wait for ack. * flg>0 zero out the unused part of the buffer. (for UUCP "msg" * pkts) * flg=0 normal data * return: ret(0) if alls well ret(-1) if problems (fail) * */ gsendpkt(cdata, len, flg) int len, flg; char *cdata; { int i, i1; long ttmp; irec = 0; timeout = 10; /* non-blocking reads */ /* WAIT FOR INPUT i.e. if weve sent nwindows pkts and none have been */ /* acked, wait for acks */ while (nbuffers >= nwindows) if (gmachine() != POK) return(-1); i1 = swu; /* <--If we ever have more than 8 seq no.s, must mod() here*/ /* PLACE PACKET IN TABLE AND MARK UNACKED */ /* fill with zeros or not */ if (flg) { strncpy(outbuf[i1], cdata, PKTSIZE); len = PKTSIZE; for (i = strlen(cdata); i < len; i++) outbuf[i1][i] = '\0'; } else { movmem(cdata, outbuf[i1], len); outbuf[i1][len] = '\0'; } /* mark packet */ outlen[i1] = len; ftimer[i1] = time(&ttmp); fseq[i1] = swu; swu = (1 + swu) % MAXSEQ; /* bump send window */ nbuffers++; npkt++; /* send it */ gspack(DATA, rwl, fseq[i1], outlen[i1], outbuf[i1]); /* send it once then let the pkt machine take it. wouldnt need this for */ /* mtasking systems */ /* sl gmachine(); */ return(0); } /************ packet machine ****** RH Lamb 3/87 */ /* Idealy we would like to fork this process off in an infinite loop */ /* and send and rec pkts thru "inbuf" and "outbuf". Cant do this in MS-DOS*/ /* so we setup "getpkt" and "sendpkt" to call this routine often and return */ /* only when the input buffer is empty thus "blocking" the pkt-machine task. */ gmachine() { int rack, rseq, rlen, i1, i2, dflg; char rdata[PKTSIZE+1]; long ttmp, itmp; reply: printmsg( 6, "*send %d= MAXERR) goto close; dflg = 0; switch (grpack(&rack, &rseq, &rlen, rdata)) { case CLOSE: printmsg( 5, "**got CLOSE"); badInARow = 0; goto close; case NAK: nerr++; badInARow = 0; acktmr = naktmr = 0; /* stop ack/nak timer */ printmsg( 5, "**got NAK %d", rack ); rack = (rack + 1) % MAXSEQ; while (between(swl, rack, swu)) { /* resend rack->(swu-1) */ i1 = rack; gspack(DATA, rwl, rack, outlen[i1], outbuf[i1]); printmsg( 5, "***resent %d", rack ); ftimer[i1] = time(&ttmp); rack = (1 + rack) % MAXSEQ; } goto reply; /* any other stuff ? */ case EMPTY: printmsg( 5, "**got EMPTY" ); if(badInARow++ >= MAXBADINAROW) return(0); itmp = time(&ttmp); if (acktmr) if ((itmp - acktmr) >= TIMEOUT) { /* ack timed out*/ gspack(ACK, rwl, 0, 0, rdata); acktmr = itmp; } if (naktmr) if ((itmp - naktmr) >= TIMEOUT) { /*nak timed out*/ gspack(NAK, rwl, 0, 0, rdata); naktmr = itmp; } /* resend any timed out un-acked pkts */ for (i2 = swl; between(swl, i2, swu); i2 = (1 + i2) % MAXSEQ) { acktmr = naktmr = 0; /* reset ack/nak */ i1 = i2; printmsg( 5, "--->seq,elapst %d %ld", i2, (itmp - ftimer[i1]) ); if ((itmp - ftimer[i1]) >= TIMEOUT) { printmsg( 5, "***timeout %d", i2 ); /* since "g" is "go-back-N", when we time out we */ /* must send the last N pkts in order. The generalized*/ /* sliding window scheme relaxes this reqirment */ nerr++; rack = i2; while (between(swl, rack, swu)) { /* resend rack->(swu-1) */ i1 = rack; gspack(DATA, rwl, rack, outlen[i1], outbuf[i1]); printmsg( 5, "***resent %d", rack ); ftimer[i1] = time(&ttmp); rack = (1 + rack) % MAXSEQ; } return(POK); } } return(POK); case ACK: printmsg( 5, "**got ACK %d", rack ); badInARow = 0; acktmr = naktmr = 0; /* disable ack/nak's */ while (between(swl, rack, swu)) { /* S<-- -->(S+W-1)%8 */ printmsg( 5, "***ACK %d", swl ); ftimer[swl] = 0; nbuffers--; swl = (1 + swl) % MAXSEQ; dflg = 1; /* same hack */ /* sl */ } if (dflg) return(POK); /* hack for non-mtask sys's */ /* to empty "inbuf[]" */ goto reply; case DATA: printmsg( 5, "**got DATA %d %d", rack, rseq ); badInARow = 0; i1 = (1 + rwl) % MAXSEQ; /* (R+1)%8 <-- -->(R+W)%8 */ i2 = (1 + rwu) % MAXSEQ; if (between(i1, rseq, i2)) { if (i1 == rseq) { i1 = rseq; arr[i1] = TRUE; inlen[i1] = rlen; movmem(rdata, inbuf[i1], rlen); rwl = (rwl + 1) % MAXSEQ; printmsg( 5, "***ACK d %d", rwl ); gspack(ACK, rwl, 0, 0, rdata); acktmr = time(&ttmp); /* enable ack/nak tmout*/ dflg = 1; /*return to call when finished*/ /* in a mtask system, unneccesary */ } else { nerr++; printmsg( 5, "***unexpect %d ne %d", rseq, rwl ); } } else { nerr++; printmsg( 5, "***wrong seq %d", rseq ); } while (between(swl, rack, swu)) { /* S<-- -->(S+W-1)%8 */ printmsg( 5, "***ACK %d", swl ); ftimer[swl] = 0; nbuffers--; swl = (1 + swl) % MAXSEQ; dflg = 1; /* same hack */ /* sl */ } if (dflg) return(POK); /* hack for non-mtask sys's */ case ERROR: if(badInARow++ >= MAXBADINAROW) return(0); nerr++; printmsg( 5, "**got BAD CHK" ); gspack(NAK, rwl, 0, 0, rdata); naktmr = time(&ttmp); /* set nak timer */ printmsg( 5, "***NAK d %d", rwl ); goto reply; default: if(badInARow++ >= MAXBADINAROW) return(0); printmsg( 5, "**got SCREW UP" ); goto reply; /* ignore it */ } close: gspack(CLOSE, 0, 0, 0, rdata); return(CLOSE); } /**/ /*************** FRAMING *****************************/ /* * * * send a packet * nt2=type nt3=pkrec nt4=pksent len=length<=PKTSIZE cnt1= data * ret(0) always */ gspack(nt2, nt3, nt4, len, cnt1) int nt2, nt3, nt4, len; char cnt1[]; { unsigned int check, i; unsigned char c2, pkt[HDRSIZE+1], dpkerr[10]; if (len > 64) len = 64; if (len == 0) cnt1[0] = '\0'; /**Link testing mods- create artificial errors ***/ /* printf("**n:normal,e:error,l:lost,p:partial,h:bad header,s:new seq--> "); gets(dpkerr); if(dpkerr[0] == 's') { sscanf(&dpkerr[1],"%d",&nt4); } /**/ /** End Link testing mods ***/ printmsg( 5, "send packet type %d, num=%d, n=%d, len=%d", nt2, nt3, nt4, len ); printmsg( 5, "data =\n|%s|", cnt1 ); c2 = '\0'; pkt[0] = '\020'; pkt[4] = nt2 << 3; nt2 &= 7; switch (nt2) { case 1: break; /* stop protocol */ case 2: pkt[4] += nt3; break; /* reject */ case 3: break; case 4: pkt[4] += nt3; break; /* ack */ case 5: pkt[4] += nwindows; break; case 6: pkt[4] += 1; break; /* pktsiz = 64 (1) */ case 7: pkt[4] += MAXWINDOW; break; case 0: pkt[4] += 0x80 + nt3 + (nt4 << 3); c2 = (PKTSIZE - len) & 0xff; /* havnt set it up for VERY LONG pkts with a few */ /* bytes yet (-128) */ if (c2) { /* short packet handling */ pkt[4] += 0x40; /* if len < PKTSIZE */ for (i = PKTSIZE - 1; i > 0; i--) cnt1[i] = cnt1[i-1]; cnt1[0] = c2; } break; } pkt[4] &= 0xff; if (nt2) { pkt[1] = 9; /* control packet size = 0 (9) */ check = (0xaaaa - pkt[4]) & 0xffff; } else { pkt[1] = PKTSIZ2; /* data packet size = 64 (2) */ check = checksum(cnt1, PKTSIZE); i = pkt[4];/* got to do this on PC for ex-or high bits */ i &= 0xff; check = (check ^ i) & 0xffff; check = (0xaaaa - check) & 0xffff; } pkt[2] = check & 0xff; pkt[3] = (check >> 8) & 0xff; pkt[5] = (pkt[1] ^ pkt[2] ^ pkt[3] ^ pkt[4]) & 0xff; /***More Link testing MODS ******/ /* switch(dpkerr[0]) { case 'e': cnt1[10] = -cnt1[10]; break; case 'h': pkt[5] = -pkt[5]; break; case 'l': return; case 'p': swrite(pkt,HDRSIZE); if(pkt[1] != 9) swrite(cnt1,PKTSIZE-3); return; default: break; } /**/ /******End Link Testing Mods **********/ swrite(pkt, HDRSIZE); /* header is 6-bytes long */ /* write(flog,pkt,HDRSIZE); */ if (pkt[1] != 9) { swrite(cnt1, PKTSIZE); /* data is always 64 bytes long */ /* write(flog,cnt1,PKTSIZE); */ } } /**/ /* * * read packet * on return: nt3=pkrec nt4=pksent len=length <=PKTSIZE cnt1=data * * ret(type) ok; ret(EMPTY) input buf empty; ret(ERROR) bad header; * ret(EMPTY) lost pkt timeout; ret(ERROR) checksum error;ret(-5) ? ****NOTE : ***sread(buf,n,timeout) while(TRUE) { if(# of chars available >= n) (without dec internal counter) read n chars into buf (decrenent internal char counter) break else if(time>timeout) break } return(# of chars available) ****END NOTE */ grpack(nt3, nt4, len, cnt1) int *nt3, *nt4, *len; char cnt1[]; { unsigned int nt1, check, checkchk, i; unsigned char c, c2; int ii; chkabort(); c = '\0'; while ((c & 0x7f) != '\020') { if (sread(&c, 1, timeout) <= 0) return(EMPTY); } if (sread(&grpkt[1], HDRSIZE - 1, timeout) < (HDRSIZE - 1)) return(EMPTY); /*i = grpkt[1] ^ grpkt[2] ^ grpkt[3] ^ grpkt[4] ^ grpkt[5];*/ i = (unsigned)grpkt[1] ^ (unsigned)grpkt[2] ^ (unsigned)grpkt[3] ^ (unsigned)grpkt[4] ^ (unsigned)grpkt[5]; i &= 0xff; printmsg( 10, "prpkt %02x %02x %02x %02x %02x .. %02x ", grpkt[1], grpkt[2], grpkt[3], grpkt[4], grpkt[5], i ); if (i) { /* bad header */ printmsg( 0, "****bad header****" ); return(ERROR); /* Im not sure whether "g" considers it an empty or error */ } if ((grpkt[1] &= 0x7f) == 9) { /* control packet */ *len = 0; c = grpkt[4] & 0xff; nt1 = c >> 3; *nt3 = c & 7; *nt4 = 0; check = 0; checkchk = 0; cnt1[*len] = '\0'; } else { /* data packet */ if (grpkt[1] != PKTSIZ2) return(-5); /* cant handle other than 64*/ if (sread(cnt1, PKTSIZE, timeout) < PKTSIZE) return(EMPTY); nt1 = 0; c2 = grpkt[4] & 0xff; c = c2 & 0x3f; *nt4 = c >> 3; *nt3 = c & 7; i = grpkt[3]; i = (i << 8) & 0xff00; check = grpkt[2]; check = i | (check & 0xff); checkchk = checksum(cnt1, PKTSIZE); i = grpkt[4] | 0x80; i &= 0xff; checkchk = 0xaaaa - (checkchk ^ i); checkchk &= 0xffff; if (checkchk != check) { printmsg( 4, "***checksum error***" ); return(ERROR); } *len = PKTSIZE; /* havnt set it up for very long pkts yet (>128) RH Lamb */ if (c2 & 0x40) { ii = (cnt1[0] & 0xff); *len = (*len - ii) & 0xff; for (ii = 0; ii < *len; ii++) cnt1[ii] = cnt1[ii+1]; } cnt1[*len] = '\0'; } printmsg( 5, "rec packet type %d, num=%d, n=%d, len=%d", nt1, *nt3, *nt4, *len ); printmsg( 6, " checksum rec = %x comp = %x, data=\n|%s|", check, checkchk, cnt1 ); ii = nt1; return(ii); } unsigned checksum(data, len) int len; char data[]; { unsigned int i, j, tmp, chk1, chk2; chk1 = 0xffff; chk2 = 0; j = len; for (i = 0; i < len; i++) { if (chk1 & 0x8000) { chk1 <<= 1; chk1++; } else { chk1 <<= 1; } tmp = chk1; chk1 += (data[i] & 0xff); chk2 += chk1 ^ j; if ((chk1 & 0xffff) <= (tmp & 0xffff)) chk1 ^= chk2; j--; } return(chk1 & 0xffff); } /* */ /* gwrmsg send a null terminated string out */ gwrmsg( typ, buf ) char typ; char *buf; /* null terminated */ { } /* grdmsg read a null terminated string */ grdmsg( buf ) char * buf; { } /* gwrdata read a file and send it out */ gwrdata( f ) { } /* grrdata read in data and send to file */ grrdata( f ) { } /* grdblk read a block of data in */ grdblk( blk, len ) { } /* gwrblk write out a block of data */ gwrblk( blk, len ) { } SHAR_EOF if test 15366 -ne "`wc -c dcpgpkt.c`" then echo shar: error transmitting dcpgpkt.c '(should have been 15366 characters)' fi echo shar: extracting dcpsys.c '(13004 characters)' cat << \SHAR_EOF > dcpsys.c /* dcpsys.c Revised edition of dcp Stuart Lynne May/87 Copyright (c) Richard H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart Lynne 1987 */ /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ /* Get the next system, and other support routines */ #include "dcp.h" /*#define PROTOS "trkg"*/ #define PROTOS "g" #define MAXLOGTRY 3 Proto Protolst[] = { 'g', ggetpkt, gsendpkt, gopenpk, gclosepk, /* 'k', kgetpkt, ksendpkt, kopenpk, kclosepk, 'r', rgetpkt, rsendpkt, ropenpk, rclosepk, 't', tgetpkt, tsendpkt, topenpk, tclosepk, */ '0'}; #define EOTMSG "\004\r\004\r" static int timeOut = 30;/* default timeout when processing callup script */ /* You can specify the timeout in the systems file */ /* DELAY10 */ /* sets the timeout to 10. */ procref getpkt, sendpkt, openpk, closepk; /**/ /***************************************************************/ /*** Sub Systems */ /* ** **getsystem ** Process an "systems" file entry (like L.sys) */ getsystem() { int i; if ( fgets( sysline, BUFSIZ, fsys ) == (char *)NULL ) return( 'A' ); printmsg( 2, "%s", sysline ); kflds = getargs( sysline, flds ); strcpy( rmtname, flds[FLD_REMOTE] ); cctime = flds[FLD_CCTIME]; strcpy( device, flds[FLD_DEVICE] ); /* strcpy( type, flds[FLD_TYPE] ); */ strcpy( speed, flds[FLD_SPEED] ); strcpy( proto, flds[FLD_PROTO] ); if (debuglevel > 3) for (i = FLD_EXPECT; i < kflds; i += 2) fprintf( stderr, "expect[%02d]:\t%s\nsend [%02d]:\t%s\n", i, flds[i], i+1, flds[i+1] ); printmsg( 2, "rmt= %s ctm= %s", rmtname, flds[FLD_CCTIME] ); printmsg( 2, "dev= %s ", device ); printmsg( 2, "spd= %s pro= %s", speed, proto ); fw = (FILE *)NULL; if ( /* (checktime( cctime )) || */ ( strcmp( Rmtname, "all" ) == SAME ) || ( strcmp( Rmtname, rmtname ) == SAME ) || ( (strcmp( Rmtname, "any" ) == SAME) && scandir() == 'S' ) ) { if ( fw != (FILE *)NULL ) fclose( fw ); /* in case we matched with scandir */ return( 'S' ); /* startup this system */ } else return('G'); } /**/ /* ** **checkname ** Do we know the guy ? */ checkname(name) char name[]; { FILE *ff; char line[BUFSIZ], tmp[20]; /* can change to 8 if %8s works */ if ( ( ff = FOPEN( s_systems, "r", 't' )) == (char *)NULL ) return( FAILED ); while ( fgets( line, BUFSIZ, ff ) != (char *)NULL ){ sscanf( line, "%8s ", tmp ); printmsg( 3, "rmt= %s sys= %s", name, tmp ); if ( strncmp( tmp, line, 7 ) == 0 ) { fclose( ff ); return ( OK ); /*OK I like you */ } } fclose( ff ); return( FAILED ); /* Who are you ? */ } /**/ /* ** **checktime ** check if we may make a call at this time **------------>to be implemented. Again. Didnt think it crucial */ checktime(xtime) char xtime[]; { return(0); /* OK go to it */ } /**/ /* ** **sysend ** end UUCP session negotiation */ sysend() { extern int lineIsOpen; char msg[80]; if(lineIsOpen) { msg[1] = '\0'; msgtime = 2 * MSGTIME; wmsg("OOOOOO", 2); rmsg(msg, 2); } closeline(); if ( remote == MASTER ) return('I'); return('A'); } /* ** **sysAbortEnd ** break connection without any message */ sysAbortEnd() { msgtime = 2 * MSGTIME; closeline(); if ( remote == MASTER ) return('I'); return('A'); } /**/ /* ** ** delay ** */ /*ddelay(dtime) int dtime; { int i, j; for (i = 0; i < dtime; i++) { } } */ /**/ /* ** **wmsg ** write a ^P type msg to the remote uucp */ wmsg(msg, syn) int syn; char msg[]; { int len; len = strlen(msg); if (syn == 2) swrite("\0\020", 2); swrite(msg, len); if (syn == 2) swrite("\0", 1); } /* ** **rmsg ** read a ^P msg from UUCP */ rmsg(msg, syn) int syn; char msg[]; { int ii; char c, cc[5]; /* *msg0;*/ /*msg0 = msg;*/ c = 'a'; if (syn == 2) { while ((c & 0x7f) != '\020') { if (sread(cc, 1, msgtime) < 1) return(-1); c = cc[0]; /* Dont ask. MSC needs more than a byte to breathe */ /* printf("Hello im in rmsg c=%x\n",c); */ } } for (ii = 0; ii < 132 && c ; ii++) { if (sread(cc, 1, msgtime) < 1) return(-1); c = cc[0] & 0x7f; if (c == '\r' || c == '\n') c = '\0'; msg[ii] = c; /*if(c == '\020') msg = msg0; */ } return(strlen(msg)); } /**/ /* ** ** **startup ** ** */ startup() { char msg[80], tmp1[20], tmp2[20]; if ( remote == MASTER ) { msgtime = 2 * MSGTIME; if (rmsg(msg, 2) == -1) return('Y'); printmsg( 2, "1st msg = %s", msg ); if (msg[5] == '=' && strncmp(&msg[6], rmtname, 7)) return('Y'); /*sprintf(msg, "S%.7s -Q0 -x%d", nodename, debuglevel);*/ /* -Q0 -x16 remote debuglevel set */ sprintf(msg, "S%.7s", nodename); wmsg(msg, 2); if (rmsg(msg, 2) == -1) return('Y'); printmsg( 2, "2nd msg = %s", msg ); if (strncmp(&msg[1], "OK", 2)) return('Y'); if (rmsg(msg, 2) == -1) return('Y'); printmsg( 2, "3rd msg = %s", msg ); if (msg[0] != 'P' || index(&msg[1], proto[0]) == (char *)NULL) { wmsg("UN", 2); return('Y'); } sprintf(msg, "U%c", proto[0]); wmsg(msg, 2); setproto(proto[0]); return('D'); } else { msgtime = 2 * MSGTIME; sprintf(msg, "Shere=%s", nodename); wmsg(msg, 2); if (rmsg(msg, 2) == -1) return('Y'); sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2); sscanf(tmp2, "-x%d", &debuglevel); printmsg( 1, "debuglevel level = %d", debuglevel ); printmsg( 2, "1st msg from remote = %s", msg ); if (checkname(rmtname)) return('Y'); wmsg("ROK", 2); sprintf(msg, "P%s", PROTOS); wmsg(msg, 2); if (rmsg(msg, 2) == -1) return('Y'); if (msg[0] != 'U' || index(PROTOS, msg[1]) == (char *)NULL ) return('Y'); proto[0] = msg[1]; setproto(proto[0]); return('R'); } } /******* set the protocol **********/ setproto(pr) char pr; { Proto * tproto; for (tproto = Protolst; tproto->type != '\0' && pr != tproto->type; tproto++) { printmsg( 3, "setproto: %c %c", pr, tproto->type ); } if (tproto->type == '\0') { printmsg( 0, "setproto:You said I had it but I cant find it" ); exit(1); } getpkt = tproto->a; sendpkt = tproto->b; openpk = tproto->c; closepk = tproto->d; } /**/ int prefix(sh,lg) char *sh,*lg; { return( strncmp(sh,lg,strlen(sh)) == SAME); } int notin(sh,lg) char *sh,*lg; { while (*lg) { if (prefix(sh,lg++)) return( FALSE ); } return( TRUE ); } #define MAXR 300 int expectstr( str, timeout ) char *str; { static char rdvec[MAXR]; char *rp = rdvec; int kr; char nextch; printmsg( 0, "wanted %s", str ); if ( strcmp(str, "\"\"") == SAME ) { return( TRUE ); } *rp = 0; while ( notin( str,rdvec ) ) { /* fprintf(stderr, "---------->%s<------\n", rdvec);/**/ kr = sread( &nextch, 1, timeout /* 40 */ ); /* nextch &= 0177; fprintf(stderr, "kr - %2d '%c'\n", kr, nextch); */ if (kr <= 0) { return( FALSE ); } if ((*rp = nextch & 0177) != '\0') { rp++; } *rp = '\0'; if (rp >= rdvec + MAXR) { return( FALSE ); } } return( TRUE ); } int writestr(s) register char *s; { register char last; int nocr; last = '\0'; nocr = FALSE; while (*s) { if (last == '\\') { switch (*s) { case 'd': case 'D': /* delay */ sleep(2); break; case 'c': case 'C': /* end string don't output CR */ nocr = TRUE; break; case 'r': case 'R': /* carriage return */ case 'm': case 'M': swrite( "\r", 1 ); break; case 'n': case 'N': swrite( "\n", 1 ); break; case 'b': case 'B': swrite( "\b", 1 ); break; case 't': case 'T': swrite( "\t", 1 ); break; case 's': case 'S': swrite( " ", 1 ); break; case 'z': case 'Z': SIOSpeed( ++s ); while ( *s != '\0' && *s != '\\' ) s++; if ( *s == '\\' ) s++; break; default: swrite( s, 1 ); } last = '\0'; } else if (*s != '\\') { swrite( s, 1 ); /* fputc(*s,stderr); */ } else { last = *s; } s++; } return( nocr ); } /*** * void sendthem(str) send line of login sequence * char *str; * * return codes: none */ void sendstr(str) char *str; { printmsg( 2, "sending %s", str ); #ifdef BREAK if (prefix("BREAK", str)) { /* send break */ ssendbrk(); return; } #endif if (prefix("DELAY", str)) { str += 5; timeOut = atoi(str); str += strspn(str, "0123456789"); } if ( strcmp(str, "EOT") == SAME ) { swrite(EOTMSG, strlen(EOTMSG)); return; } if ( strcmp(str,"\"\"") == SAME ) *str = '\0'; /*fprintf(stderr,"'%s'\n",str);*/ if ( strcmp(str,"") != SAME ) { if (!writestr(str)) { swrite ("\r", 1); } } else { swrite("\r", 1); } return; } int sendexpect( s, e, timeout ) char * s; char * e; { sendstr( s ); return( expectstr( e, timeout ) ); } dial() { char buf[4]; if ( strcmp( flds[FLD_TYPE], "HAYES" ) != SAME ) { printmsg( 0, "dial: unsupported dialer %s", flds[FLD_TYPE] ); return( FALSE ); } printmsg( 3, "calling host %s", rmtname ); if (openline(device, "2400" )) return( FALSE ); printmsg( 0, "hayes: trying 2400" ); if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) { sendexpect( "\\d+++\\d", "OK", 2 ); if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) { printmsg( 0, "hayes: trying 1200" ); SIOSpeed( "1200" ); if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) { sendexpect( "\\d+++\\d", "OK", 2 ); if ( sendexpect( "ATZ", "OK", 2 ) != TRUE ) return( FALSE); } } } printmsg( 0, "hayes: got modem response" ); /*(sendstr( "\\d\\dATS7=30" ); expectstr( "OK", 40 );*/ sendstr( "\\d\\dATX4\\c" ); if ( sendexpect( speed, "CONNECT ", 40 ) == TRUE ) { printmsg( 3, "hayes: got CONNECT" ); if ( sread( buf, 4, 4 ) == 4 ) { printmsg( 3, "hayes: speed select %s", buf ); /* set speed appropriately */ SIOSpeed( buf ); } return( TRUE ); } else return( FALSE ); } /* ** **callup ** script processor - nothing fancy! */ callup() { char *exp; char *alternate; int ok; int i; printmsg( 0, "calling host %s", rmtname ); if ( strcmp( flds[FLD_TYPE], "DIR" ) != SAME ) { if ( dial() == FALSE ) return( 'G' ); } else if (openline(device, speed)) return( 'G' ); for (i = 6; i < kflds; i+=2) { exp = flds[i]; printmsg( 2, "callup: expect %d of %d \"%s\"", i, kflds, exp ); ok = FALSE; while (ok != TRUE) { alternate = index( exp, '-' ); if (alternate != (char *)NULL) *alternate++ = '\0'; ok = expectstr( exp, timeOut ); printmsg( 1, "got %s", ok != TRUE ? "?" : "that" ); if ( ok == TRUE ) { printmsg( 0, "got that" ); break; } if ( alternate == (char *)NULL ) { printmsg( 0, "LOGIN FAILED" ); return( 'Z' ); } exp = index( alternate, '-' ); if ( exp != (char *)NULL ) *exp++ = '\0'; printmsg( 0, "send alternate" ); sendstr( alternate ); } printmsg(2, "callup: send %d of %d \"%s\"", i+1, kflds, flds[i+1] ); sleep(1); sendstr(flds[i+1]); } return('P'); } /**/ /* ** ** slowrite ** comunication slow write. needed for auto-baud modems */ /*slowrite(st) register char *st; { int len, j; char c; len = strlen(st); printmsg( 2, "sent %s", st ); for (j = 0; j < len; j++) { swrite(&st[j], 1); ddelay(80000); } } */ /**/ /* ** **scandir ** */ #include "ndir.h" /* scandir scan work dir for C. files matching current remote host (rmtname) return A - abort Y - can't open file S - ok Q - no files */ scandir() { int len; char cname[40]; DIR *dirp; struct direct *dp; if ((dirp = opendir( spooldir )) == (DIR *)NULL ) { fprintf( stderr, "couldn't open dir %s\n", spooldir ); return( 'A' ); } sprintf(cname, CALLFILE, rmtname); len = strlen(cname); while ((dp = readdir(dirp)) != (struct direct *)NULL) { printmsg( 4, "scandir: %s", dp->d_name ); if ( strncmp( cname, dp->d_name, len ) == SAME ) { printmsg( 4, "scandir: match!!" ); strcpy(cfile, dp->d_name); closedir( dirp ); if ((fw = FOPEN( cfile, "r", 't' )) == (char *)NULL ) return('Y'); return('S'); } } closedir( dirp ); return('Q'); } /**/ /* ** **dscandir ** scan the directory */ dscandir() { int len; char cname[40]; DIR *dirp; struct direct *dp; if ((dirp = opendir( spooldir )) == (DIR *)NULL ) { fprintf( stderr, "couldn't open dir %s\n", spooldir ); return(0); } sprintf(cname, XQTFILE, rmtname); /* sprintf(cname,"c%.4s",rmtname); */ len = strlen(cname); while ((dp = readdir(dirp)) != (struct direct *)NULL) { printmsg( 4, "dscandir:dir file = %s cfile = %s", dp->d_name, cname ); if ( strncmp( cname, dp->d_name, len ) == SAME ) { printmsg( 4, "dscandir: match!!" ); strcpy(cfile, dp->d_name); closedir( dirp ); return( -1 ); } } closedir( dirp ); return( 0 ); } SHAR_EOF if test 13004 -ne "`wc -c dcpsys.c`" then echo shar: error transmitting dcpsys.c '(should have been 13004 characters)' fi echo shar: extracting dcpxfer.c '(10190 characters)' cat << \SHAR_EOF > dcpxfer.c /* dcpxfer.c Revised edition of dcp Stuart Lynne May/87 Copyright (c) Richard H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart Lynne 1987 */ /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ /* file send routines */ #include "dcp.h" static unsigned char rpacket[MAXPACK]; static unsigned char spacket[MAXPACK]; /**/ /***************SEND PROTOCOL***************************/ /* * s d a t a * * Send File Data */ sdata() { while( TRUE ) { if (( *sendpkt) ( spacket, size, 0 )) return (0 ); /* send data */ if (( size = bufill( spacket )) == 0 ) /* Get data from file */ return( 'Z' ); /* If EOF set state to that */ } return('D');/* Got data, stay in state D */ } /* * b u f i l l * * Get a bufferful of data from the file that's being sent. * Only control-quoting is done; 8-bit & repeat count prefixes are * not handled. */ bufill(buffer) char *buffer;/* Buffer */ { return( read(fp, buffer, pktsize) );/* Handle partial buffer */ } /* * s b r e a k * * Send Break (EOT) */ sbreak() { int len; strcpy(spacket, "H"); if ((*sendpkt)(spacket, 0, 1)) return(0); if ((*getpkt)(spacket, &len)) return(0); printmsg( 2, "Switch modes" ); if (spacket[1] == 'N') return('G'); return('Y'); } /**/ /* * s e o f * * Send End-Of-File. */ seof() { int len; if ((*sendpkt)(spacket, 0, 0)) return(0); if ((*getpkt)(spacket, &len)) return(0); /* rec CY or CN */ if (strncmp(spacket, "CY", 2)) return(0); /* cant send file */ close(fp); fp = (-1); importpath( hostfile, fromfile ); if(!strchr(fromfile,':') && !strchr(fromfile,'/')) unlink(fromfile); printmsg( 0, "transfer %s complete", fromfile ); /* fprintf( syslog, "%s!%s (%d/%d-%d:%d:%d) -> %ld / %ld secs", host, id, size, secs ); */ return('F'); /* go get the next file to send */ } /**/ /* * r e o f * * Send End-Of-File and receive Ack in slave mode. */ reof() { int len; if ((*sendpkt)(spacket, 0, 0)) return(0); if ((*getpkt)(spacket, &len)) return(0); /* rec CY or CN */ if (strncmp(spacket, "CY", 2)) return(0); /* send failed */ close(fp); fp = (-1); importpath( hostfile, fromfile ); printmsg( 0, "transfer %s complete", fromfile ); /* fprintf( syslog, "%s!%s (%d/%d-%d:%d:%d) -> %ld / %ld secs", host, id, size, secs ); */ return('F'); /* go get the next file to send */ } /**/ /* * s f i l e * * Send File Header. */ sfile() { int len; int toLength; char *cp; int nextState; if (fp == -1) {/* If not already open, */ printmsg( 3, "looking for next file..." ); if ((nextState = getfile()) == 'B') { fclose( fw ); unlink( cfile ); fw = (char *)NULL; return(nextState); /* end sending session */ } if(nextState == 'R') return(nextState); /* check for ~/ path -> /usr/spool/uucppublic */ if ( strncmp( fromfile, "~/", 2 ) == SAME ) sprintf( hostfile, "%s%s", pubdir, fromfile + 1); else importpath( hostfile, fromfile ); printmsg( 3, " Opening %s for sending.", hostfile ); fp = open(hostfile, 0);/* open the file to be sent */ if (fp == -1) {/* If bad file pointer, give up */ printmsg( 0, "Cannot open file %s", hostfile ); return('A'); } } else return('A'); /* If somethings already open. were in trouble*/ printmsg( 0, "Sending %s to %s", hostfile, tofile ); /* S fromfile tofile user - tofile 0666 */ toLength = strlen(tofile); cp = tofile; while(toLength >= pktsize) { strncpy(spacket, cp, pktsize); cp += pktsize; if ((*sendpkt)(spacket, 0, 1)) return(0); toLength -= pktsize; } strcpy(spacket, cp); if ((*sendpkt)(spacket, 0, 1)) return(0); if ((*getpkt)(spacket, &len)) return(0); if (spacket[1] != 'Y') return('A'); /* If otherside says no-quit */ size = bufill(spacket); return('D'); } /**/ /* * m r f i l e * * Receive File Header. */ mrfile() { int len; int fromLength; char *cp; if (fp == -1) {/* If not already open, */ /* check for ~/ path -> /usr/spool/uucppublic */ if ( strncmp( tofile, "~/", 2 ) == SAME ) sprintf( hostfile, "%s%s", pubdir, tofile + 1); else importpath( hostfile, tofile ); printmsg( 3, " Opening %s for receiving.", hostfile ); if ((fp = CREAT( hostfile, 0775, 'b' )) == -1) { printmsg( 0, "Cannot create %s", hostfile ); return('A'); } } else return('A'); /* If somethings already open. were in trouble*/ printmsg( 0, "Receiving %s from %s", hostfile, fromfile ); /* R fromfile tofile user - tofile 0666 */ fromLength = strlen(fromfile); cp = fromfile; while(fromLength >= pktsize) { strncpy(spacket, cp, pktsize); cp += pktsize; if ((*sendpkt)(spacket, 0, 1)) return(0); fromLength -= pktsize; } strcpy(spacket, cp); if ((*sendpkt)(spacket, 0, 1)) return(0); if ((*getpkt)(spacket, &len)) return(0); if (spacket[1] != 'Y') return('A'); /* If otherside says no-quit*/ size = bufill(spacket); return('D'); } mrabort() { if(fp != -1) close(fp); strcpy(rpacket, "CN5"); if ((*sendpkt)(rpacket, 0, 1)) return(0); printmsg( 0, "transfer failed" ); return('Y'); } /**/ /* * s i n i t * * Send Initiate: send this host's parameters and get other side's back. */ sinit() { if ((*openpk)()) return('A'); return('B'); } /**/ /* * * * getfile * * getfile reads the next line from the presently open workfile * (cfile) and determines from this the next file to be sent or received. * If there are no more then 'B' is returned. Otherwise 'S' or 'R' will * be returned. * We handle the following formats: * R from to [other stuff] * S from to [other stuff] */ getfile() { char line[132]; char from1[132]; char to1[132]; char user[64]; char mode[64]; register char * cp; if ( !fgets( line, BUFSIZ, fw ) || (line[0] != 'R' && line[0] != 'S') ) return('B'); if(line[0] == 'R') { sscanf(&line[2], "%s %s ", from1, tofile); if(tofile[strlen(tofile) - 1] == '/') { if((cp = strrchr(from1,'/')) || (cp = strchr(from1,':'))) cp++; else cp = from1; strcat(tofile, cp); } strcpy(fromfile, line); } else { sscanf(&line[2], "%s %s %s - %s %s", from1, to1, user, fromfile, mode); if((to1[strlen(to1) - 1] == '/') && (cp = strchr(from1,':'))) { *cp = '/'; } else { cp = from1; } sprintf(tofile,"S %s %s %s - %s %s\n", cp, to1, user, fromfile, mode); } printmsg(3, " getfile: fromfile=%s, tofile=%s.", fromfile, tofile); return(line[0]); } /**/ /*********************** MISC SUB SUB PROTOCOL *************************/ /* ** **schkdir ** scan the dir */ schkdir() { char c; c = scandir(); if (c == 'Q') { return('Y'); } if (c == 'S') { strcpy(rpacket, "HN"); if ((*sendpkt)(rpacket, 0, 1)) return(0); } return('B'); } /**/ /* * * endp() end protocol * */ endp() { strcpy(rpacket, "HY"); (*sendpkt)(rpacket, 0, 2); /* dont wait for ACK */ (*closepk)(); return('P'); } /**/ /***********************RECIEVE PROTOCOL**********************/ /* * r d a t a * * Receive Data */ rdata() { int len; if ((*getpkt)(rpacket, &len)) return(0); if (len == 0) { close(fp); strcpy(rpacket, "CY"); if ((*sendpkt)(rpacket, 0, 1)) return(0); printmsg( 0, "transfer complete" ); return('F'); } if ( write(fp, rpacket, len) != len ) /* Write the data to the file */ { printmsg( 0, "Error Writing File" ); return 'A'; } return('D');/* Remain in data state */ } /**/ /* * r f i l e * * Receive File Header */ rfile() { char buf[256]; char * flds[10]; int numflds; int len; char tmpfilename[256]; /*Holds the converted file name */ char *cp, *cp2; printmsg( 3, "rfile entered" ); cp = buf; while ( TRUE ) { if ((*getpkt)( rpacket, &len )) return( 0 ); strncpy( cp, rpacket, len ); cp += len; if ( *(cp - 1) == '\0' ) break; } if (( buf[0] & 0x7f ) == 'H' ) return( 'C' ); printmsg( 3, "rfile: buf %d \"%s\"", len, buf ); /* Convert upper case to lower */ /* for (cp = buf; *cp != '\0';cp++) if (isupper(*cp)) *cp = tolower(*cp); */ numflds = getargs( buf, flds ); if(buf[0] == 'R') { cp = flds[1]; cp2 = flds[2]; printmsg( 3, "rfile: send file \"%s\"", cp ); } else { cp = flds[2]; cp2 = flds[1]; printmsg( 3, "rfile: receive file \"%s\"", cp ); } /* check for ~/ destination -> /usr/spool/uucppublic */ if ( strncmp( cp, "~/", 2 ) == SAME ) sprintf( tmpfilename, "%s%s", pubdir, cp+1); else strcpy( tmpfilename, cp ); if(buf[0] == 'R') printmsg( 3, "rfile: send file \"%s\"", tmpfilename ); else printmsg( 3, "rfile: receive file \"%s\"", tmpfilename ); /* check for dirname only */ cp = tmpfilename + strlen( tmpfilename ) - 1; if ( *cp == '\n' ) *cp-- = '\0'; if ( *cp == '/' ) { fprintf( stderr, "rfile: fromfile %s\n", cp2 ); cp = rindex( cp2, '/' ); if ( cp == (char *) NULL ) cp = cp2; else cp++; fprintf( stderr, "rfile: dironly add %s\n", cp ); strcat( tmpfilename, cp ); } if(buf[0] == 'R') { printmsg( 3, "rfile: send file \"%s\"", tmpfilename ); /* let host munge filename as appropriate */ importpath( fromfile, tmpfilename ); printmsg( 3, "rfile: send file \"%s\"", tofile ); if ((fp = open( fromfile, 0)) == -1) { printmsg( 0, "cannot open %s", fromfile ); return('A'); } printmsg( 0, "Sending %s to %s", fromfile, flds[2] ); strcpy(spacket, "RY"); if ((*sendpkt)(spacket, 0, 1)) return(0); size = bufill(spacket); return('d'); /* Switch to data state */ } else { printmsg( 3, "rfile: receive file \"%s\"", tmpfilename ); /* let host munge filename as appropriate */ importpath( tofile, tmpfilename ); printmsg( 3, "rfile: receive file \"%s\"", tofile ); if ((fp = CREAT( tofile, 0775, 'b' )) == -1) { printmsg( 0, "cannot create %s", tofile ); return('A'); } printmsg( 0, "Receiving %s to %s", flds[1], tofile ); strcpy(rpacket, "SY"); if ((*sendpkt)(rpacket, 0, 1)) return(0); return('D'); /* Switch to data state */ } } /**/ /* * r i n i t * * Receive Initialization */ rinit() { if ((*openpk)()) return(0); return('F'); } SHAR_EOF if test 10190 -ne "`wc -c dcpxfer.c`" then echo shar: error transmitting dcpxfer.c '(should have been 10190 characters)' fi # End of shell archive exit 0