|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U
Length: 46810 (0xb6da) Types: TextFile Notes: Uncompressed file
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦8811b075b⟧ »EurOpenD3/network/uupc/uupc.dcp.8.3.Z« └─⟦this⟧
From uucp Wed Aug 12 02:36 PDT 1987 >From slynne Wed Aug 12 02:35:56 1987 remote from slmac Received: by van-bc.uucp (smail2.3) id AA17550; 12 Aug 87 02:35:56 PDT (Wed) Received: by slmac.vnet.van-bc.uucp (pcmail) Wed Aug 12 02:36:17 1987 Date: Wed Aug 12 02:36:17 1987 From: Stuart Lynne - test a mac <slynne@slmac.vnet.van-bc.uucp> Message-ID: <147@slmac.vnet.van-bc.uucp> To: sl@van-bc Subject: shar/uupc.dcp.8.3 #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # dcp.c # dcp.h # dcpgpkt.c # dcpsys.c # dcpxfer.c # This archive created: Wed Aug 12 02:01:59 1987 # By: Stuart Lynne - test a mac () export PATH; PATH=/bin:$PATH if test -f 'dcp.c' then echo shar: will not over-write existing file "'dcp.c'" else 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 */ /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ /* This program implements a uucico type file transfer and remote execution type protocol. */ #include "dcp.h" /**/ 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; int debuglevel; /* debugging flag */ 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 ); exit( NULL ); } dcpmain( argc, argv ) int argc; char*argv[]; { FILE *ftmp; char line[132]; if ( name == NULL || *name == '\0' ) { complain( NAME ); exit( -1 ); } if ( nodename == NULL || *nodename == '\0' ) { complain( NODENAME ); exit( -1 ); } mkfilename( s_logfile, spooldir, LOGFILE ); mkfilename( s_syslog, spooldir, 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 ); remote = MASTER; debuglevel = 1; fp = -1; fw = (char *)NULL; remote = MASTER; strcpy( Rmtname, "any" ); 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; } } } if ( remote == MASTER ) { printmsg( 0, "Calling %s, debuglevel=%d", Rmtname, debuglevel ); if (( fsys = FOPEN( s_systems, "r", 't' )) == (char *)NULL ) exit( FAILED ); 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(); break; case 'Y': state = sysend(); 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 ); return 0; } /**/ /* ** ** **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 '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 'A': return('Y');/* "Abort" state */ default: return('Y'); } } } /**/ /* * s e n d * * Sendsw is the state table switcher for sending files. It loops until * either it finishes, or an error is encountered. The routines called * by sendsw 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 'A': return ('Y'); /* "Abort" */ 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\n", command ); shell( command, input, output, (char *)NULL ); unlink(cfile); importpath( hostfile, input ); unlink(hostfile); 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 ); fputs( msg, logfile ); } } SHAR_EOF chmod +x 'dcp.c' fi # end of overwriting check if test -f 'dcp.h' then echo shar: will not over-write existing file "'dcp.h'" else cat << \SHAR_EOF > 'dcp.h' /* DCP a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ #include <stdio.h> /* 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 #ifndef TRUE #define TRUE (-1) #define FALSE 0 #endif #define SAME 0 #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 chmod +x 'dcp.h' fi # end of overwriting check if test -f 'dcpgpkt.c' then echo shar: will not over-write existing file "'dcpgpkt.c'" else 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 */ #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 TIMEOUT 4 /* could be longer */ #define KPKT 1024/PKTSIZE #define POK -1 #define SWINDOW 3 /* fixed now, U make it variable */ #define RWINDOW 3 #define NBUF 8 /* always SAME as MAXSEQ ? */ #define MAXSEQ 8 #define between(a,b,c) ((a<=b && b<c) || (c<a && a<=b) || (b<c && c<a)) /* packet defin */ static int rwl, swl, swu, rwu, nerr, nbuffers, npkt, irec, timeout, GOT_SYNC, GOT_HDR; static int fseq[NBUF], outlen[NBUF], inlen[NBUF], arr[NBUF]; static char outbuf[NBUF][PKTSIZE+1], inbuf[NBUF][PKTSIZE+1]; static unsigned char grpkt[HDRSIZE+1]; static long ftimer[NBUF], acktmr, naktmr; /**/ /******************SUB SUB SUB PACKET HANDLER************/ gopenpk() { int i, j, n1, n2, len; char tmp[PKTSIZE+1]; pktsize = PKTSIZE; /* change it later after the init */ msgtime = MSGTIME; /* not sure I need this for "g" proto */ /* initialize proto parameters */ swl = nerr = nbuffers = npkt = 0; swl = swu = 1; rwl = 0; rwu = RWINDOW - 1; for (i = 0; i < NBUF; i++) { ftimer[i] = 0; arr[i] = FALSE; } GOT_SYNC = GOT_HDR = FALSE; /* 3-way handshake */ timeout = 1; /* want some timeout capability here */ gspack(7, 0, 0, 0, tmp); rsrt: if (nerr >= MAXERR) return(-1); /* INIT sequence. Easy fix for variable pktsize and windows. */ /* I didnt since all the machines I talk to use W=3 PKTSZ=64 */ /* If you do this make sure to reflect the changes in "grpack" */ /* and "gspack" */ switch (grpack(&n1, &n2, &len, tmp)) { case 7: gspack(6, 0, 0, 0, tmp); goto rsrt; case 6: gspack(5, 0, 0, 0, tmp); goto rsrt; case 5: break; default: nerr++; gspack(7, 0, 0, 0, tmp); goto rsrt; } nerr = 0; return(0); /* channel open */ } gclosepk() { int i; char tmp[PKTSIZE+1]; timeout = 1; for (i = 0; i < MAXTRY; 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 = 0; /* 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]; strncpy(cdata, inbuf[i2], *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 = 0; /* non-blocking reads */ /* WAIT FOR INPUT i.e. if weve sent SWINDOW pkts and none have been */ /* acked, wait for acks */ while (nbuffers >= SWINDOW) 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) { strcpy(outbuf[i1], cdata); len = PKTSIZE; for (i = strlen(cdata); i < len; i++) outbuf[i1][i] = '\0'; } else { strncpy(outbuf[i1], cdata, 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<W<%d, rec %d<W<%d, err %d", swl, swu, rwl, rwu, nerr ); /* waiting for ACKs for swl to swu-1. Next pkt to send=swu */ /* rwl=expected pkt */ printmsg( 7, "Kbytes transfered %d errors %d\r", npkt / KPKT, nerr ); if (nerr >= MAXERR) goto close; dflg = 0; switch (grpack(&rack, &rseq, &rlen, rdata)) { case CLOSE: printmsg( 5, "**got CLOSE"); goto close; case NAK: nerr++; acktmr = naktmr = 0; /* stop ack/nak timer */ printmsg( 5, "**got NAK %d", rack ); nloop: if (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 nloop; } if (dflg) return(POK); goto reply; /* any other stuff ? */ case EMPTY: printmsg( 5, "**got EMPTY" ); 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++; dflg = 1; /* same hack */ rack = i2; goto nloop; } } return(POK); case ACK: printmsg( 5, "**got ACK %d", rack ); acktmr = naktmr = 0; /* disable ack/nak's */ aloop: if (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 */ goto aloop; } 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 ); 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; strncpy(inbuf[i1], rdata, 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 ); } goto aloop; case ERROR: 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: printmsg( 5, "**got SCREW UP" ); goto reply; /* ignore it */ } close: gspack(CLOSE, 0, 0, 0, rdata); return(CLOSE); } /**/ /*************** FRAMMING *****************************/ /* * * * 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] += SWINDOW; break; /* 3 windows */ case 6: pkt[4] += 1; break; /* pktsiz = 64 (1) */ case 7: pkt[4] += SWINDOW; break; /* 3 windows */ 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; if (GOT_SYNC) goto get_hdr; if (GOT_HDR) goto get_data; c = '\0'; while ((c & 0x7f) != '\020') if (sread(&c, 1, timeout) == 0) return(EMPTY); GOT_SYNC = TRUE; get_hdr: if (sread(&grpkt[1], HDRSIZE - 1, timeout) < (HDRSIZE - 1)) return(EMPTY); GOT_SYNC = FALSE; /*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 */ } GOT_HDR = TRUE; 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'; GOT_HDR = FALSE; } else { /* data packet */ if (grpkt[1] != PKTSIZ2) return(-5); /* cant handle other than 64*/ get_data: if (sread(cnt1, PKTSIZE, timeout) < PKTSIZE) return(EMPTY); GOT_HDR = FALSE; 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 chmod +x 'dcpgpkt.c' fi # end of overwriting check if test -f 'dcpsys.c' then echo shar: will not over-write existing file "'dcpsys.c'" else 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" 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() { char msg[80]; msg[1] = '\0'; msgtime = 2 * MSGTIME; /* while (msg[1] != 'O') { */ wmsg("OOOOOO", 2); if (rmsg(msg, 2) == -1) goto hang; /*}*/ hang: wmsg("OOOOOO", 2); 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; { int i; 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; register char * m; 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; { int nw, ns; int nulls; printmsg( 2, "sending %s", str ); #ifdef BREAK if (prefix("BREAK", str)) { sscanf(&str[5], "%1d", &nulls); if (nulls <= 0 || nulls > 10) nulls = 3; /* send break */ ssendbrk(nulls); return; } #endif 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() { int flg, kk, jj, ll, firstflg; char buf[4], *prsend; char *exp; char *alternate; int ok; int i; 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() { int flg, kk, jj, ll, firstflg; char *prsend; 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, 30 ); printmsg( 1, "got %s", ok != TRUE ? "?" : "that" ); if ( ok == TRUE ) { printmsg( 0, "got that" ); break; } if ( alternate == (char *)NULL ) { printmsg( 0, "LOGIN FAILED" ); return( 'Y' ); } 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); /* (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 fn, len, i; char cname[40], tmp[132]; 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 fn, len, i; char cname[40], tmp[132]; 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: file = %s cname = %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 chmod +x 'dcpsys.c' fi # end of overwriting check if test -f 'dcpxfer.c' then echo shar: will not over-write existing file "'dcpxfer.c'" else 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" #include <ctype.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, i; sprintf(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, i; 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 ); unlink(hostfile); printmsg( 0, "Transfer of %s (%s) completed. fp=%d", fromfile, hostfile, fp ); /* 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 i, len; char * cp; if (fp == -1) {/* If not already open, */ printmsg( 3, "looking for next file..." ); if (getfile()) { /* get next file from current work*/ fclose( fw ); unlink( cfile );/* close and delete completed workfile */ fw = (char *)NULL; return('B'); /* end sending session */ } importpath( hostfile, fromfile ); printmsg( 3, "Opening %s (%s) for sending.", fromfile, 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 (%s).", fromfile, hostfile ); return('A'); } } else return('A'); /* If somethings already open. were in trouble*/ printmsg( 0, "Sending %s (%s) as %s", fromfile, hostfile, tofile ); strcpy(spacket, tofile); if ((*sendpkt)(spacket, 0, 1)) return(0); /* send S fromfile tofile */ if ((*getpkt)(spacket, &len)) return(0); /* user - tofile 0666. */ if (spacket[1] != 'Y') return('A'); /* If otherside says no-quit*/ size = bufill(spacket); return('D'); } /**/ /* * 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 * (file). If there are no more TRUE is returned. * --A fix for "R from to 0666" should be done here to recieve files * --in addition to sending them. The appropriate "state letter" * --i.e. "R" should be returned to the send "master" or "slave" * --state switching table in "dcp.c" * --I did not implement this since the majority of uucp transactions * --appear to be "S from to 0666" type. RHLamb 1/87 * */ getfile() { int i; char line[132]; register char * cp; if ( fgets( line, BUFSIZ, fw ) == (char *)NULL ) return(TRUE); sscanf(&line[2], "%s ", fromfile); for ( i = 0, cp = line; *cp!='\0'; i++, cp++ ) { if ( strncmp( cp, "0666", 4 ) == 0) break; } cp+=4; *cp = '\0'; strcpy(tofile, line); printmsg(3, " getfile: fromfile=%s, tofile=%s.", fromfile, tofile); return(FALSE); } /**/ /*********************** MISC SUB SUB PROTOCOL *************************/ /* ** **schkdir ** scan the dir */ schkdir() { char c; c = scandir(); if (c == 'Q') { return('Y'); } if (c == 'S') { sprintf(rpacket, "HN"); if ((*sendpkt)(rpacket, 0, 1)) return(0); } return('B'); } /**/ /* * * endp() end protocol * */ endp() { sprintf(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); sprintf(rpacket, "CY"); if ((*sendpkt)(rpacket, 0, 1)) return(0); printmsg( 0, "transfer complete" ); return('F'); } write(fp, rpacket, len);/* Write the data to the file */ 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, i; char tmpfilename[256]; /*Holds the converted file name */ char *cp; 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)) tolower(*cp); numflds = getargs( buf, flds ); cp = flds[2]; 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 ); 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", flds[1] ); cp = rindex( flds[1], '/' ); if ( cp == (char *) NULL ) cp = flds[1]; else cp++; fprintf( stderr, "rfile: dironly add %s\n", cp ); strcat( tmpfilename, cp ); } 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) { /* Try to open a new file */ printmsg( 0, "cannot create %s", tofile ); /* Give up if can't */ return('A'); } printmsg( 0, "Receiving %s as %s", flds[1], tofile ); sprintf(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 chmod +x 'dcpxfer.c' fi # end of overwriting check # End of shell archive exit 0 -- {ubc-vision,uunet}!van-bc!sl Stuart.Lynne@van-bc.uucp