|
|
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