home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff319.lzh
/
CNewsSrc
/
uupc.lzh
/
uupc
/
dcpxfer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-16
|
10KB
|
447 lines
/*
* dcpxfer.c
*
* Revised edition of DCP
*
* Stuart Lynne May/87
* Copyright (c) Richard H. Lamb 1985, 1986, 1987
* Changes Copyright (c) Stuart Lynne 1987
*
* $Id: dcpxfer.c,v 1.2 90/01/16 10:25:25 crash Exp Locker: crash $
*/
#ifndef lint
static char RCSid[] = "$Id: dcpxfer.c,v 1.2 90/01/16 10:25:25 crash Exp Locker: crash $";
#endif /* lint */
/*
* "DCP" is a uucp clone. Copyright Richard H. Lamb 1985, 1986, 1987
*
* file send/receive routines
*/
#include "dcp.h"
#ifndef _U
# include <ctype.h>
#endif
#ifdef AMIGA
void *IntuitionBase = 0, *OpenLibrary();
void CloseLibrary();
static unsigned long fileSecs, fileMicro; /* For xmit logging purposes */
#endif /* AMIGA */
int filecount;
static long filetime, filesize;
static char file_buf[256]; /* buffer used by rfile() & sfile() */
static char *file_flds[10]; /* (ditto) */
static unsigned char rpacket[MAXPACK];
static unsigned char spacket[MAXPACK];
int closelibs(x)
int x;
{
if (IntuitionBase) CloseLibrary(IntuitionBase), IntuitionBase = 0;
return( x );
}
void logtime(dir)
char *dir;
{
register struct tm *tim; /* Start time in fields for display */
#ifdef AMIGA
unsigned long Secs, Micro; /* Current time (for calculating duration) */
register unsigned long thousandths;
register int msd;
#else
long Secs, Micro; /* Current time (for calculating duration) */
register unsigned long thousandths;
register int msd;
#endif /* AMIGA */
tim = localtime( &filetime );
#ifdef AMIGA
if (!IntuitionBase)
IntuitionBase = OpenLibrary("intuition.library", 0L);
if (IntuitionBase) {
CurrentTime( &Secs, &Micro );
if (Micro < fileMicro)
Secs -= fileSecs+1, Micro += 1000000L - fileMicro;
else
Secs -= fileSecs, Micro -= fileMicro;
Micro /= 100000L;
thousandths = (100 * filesize) / (10 * Secs + Micro);
} else {
Secs = time( 0L ) - filetime;
Micro = 0;
thousandths = (10 * filesize) / Secs;
}
#else /* !AMIGA */
Secs = time( 0L ) - filetime;
Micro = 0;
thousandths = (10 * filesize) / Secs;
#endif /* AMIGA */
msd = (int) (thousandths / 10L);
fprintf(syslog, /* 68 characters (usually) */
"%s!%-6s %c (%02d/%02d-%02d:%02d:%02d) (C,PID,%02d) [SER:] %s %6ld bytes / %4ld.%01d secs, %3d.%01d baud\n",
rmtname, file_flds[3], remote == MASTER ? 'M' : 'S',
(int) tim->tm_mon+1, (int) tim->tm_mday,
(int) tim->tm_hour, (int) tim->tm_min, (int) tim->tm_sec,
++filecount,
dir,
filesize, Secs, (int) Micro, /* Faster than modulus?? */
msd, (int) (thousandths - msd * 10L)
);
closelibs(0);
}
/***************SEND PROTOCOL***************************/
/*
* sdata
* send file data
*/
sdata()
{
while( TRUE ) {
filesize += (long) size;
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 */
}
/*
* bufill
* Get a bufferful of data from the file that's being sent.
* 8-bit & repeat count prefixes are not handled.
*/
bufill(buffer)
char *buffer;
{
return( read(fp, buffer, pktsize) ); /* Handle partial buffer */
}
/*
* sbreak
* send hangup request
*/
sbreak()
{
int len, i;
strcpy(spacket, "H");
if ((*sendpkt)(spacket, 0, 1))
return(0);
if ((*getpkt)(spacket, &len))
return(0);
printmsg( 1, "\n********************************\nSwitch modes" );
if (spacket[1] == 'N')
return('G');
return('Y');
}
/*
* seof
* send end-of-file.
*/
seof()
{
int len;
if ((*sendpkt)(spacket, 0, 0))
return(0);
if ((*getpkt)(spacket, &len))
return(0); /* receive CY or CN */
if (strncmp(spacket, "CY", 2) != SAME)
return(0); /* couldn't copy file */
close(fp);
fp = (-1);
importpath( hostfile, fromfile );
unlink(hostfile);
logtime("->");
printmsg( 0, "Transfer of %s (%s) completed.", fromfile, hostfile );
return('F'); /* go get the next file to send */
}
/*
* sfile
* 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 = (FILE *) 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 something's already open, we're in trouble */
printmsg( 1, "Sending %s (%s)\n\t%s", fromfile, hostfile, tofile );
strcpy(spacket, tofile);
if ((*sendpkt)(spacket, 0, 1))
return(0); /* S fromfile tofile user - tofile 0666 */
if ((*getpkt)(spacket, &len))
return(0);
if (spacket[1] != 'Y')
return('A'); /* If otherside says NO, quit */
filetime = time( (long *) 0 );
filesize = 0L;
#ifdef AMIGA
if (!IntuitionBase)
IntuitionBase = OpenLibrary("intuition.library", 0L);
if (IntuitionBase)
CurrentTime( &fileSecs, &fileMicro );
#endif /* AMIGA */
file_flds[3] = mailbox;
size = bufill(spacket);
return('D');
}
/*
* sinit
* send init: 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 receive files
* in addition to sending them. The appropriate "state letter",
* i.e. "R", should be returned to the "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
*
* [FJE]
* Except when attempting to download from an anonymous uucp site!!
*/
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, "\tgetfile: fromfile=%s;\n\t\ttofile=%s.", fromfile, tofile);
return(FALSE);
}
/*********************** MISC SUB SUB PROTOCOL *************************/
/*
* schkdir
* scan the dir
*/
schkdir()
{
char c;
c = scandir();
if (c == 'Q') return('Y'); /* No files available */
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); /* don't wait for ACK */
(*closepk)();
return('P');
}
/********************* RECEIVE PROTOCOL ********************/
/*
* rdata
* 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);
logtime("<-");
printmsg( 2, "Transfer complete\n" );
return('F');
}
filesize += write(fp, rpacket, len); /* Write the data to the file */
return('D'); /* Remain in data state */
}
/*
* rfile
* receive file header
*/
rfile()
{
int numflds;
int len, i;
char tmpfilename[256]; /* Holds the converted file name */
char *cp, *index();
printmsg( 3, "rfile entered" );
cp = file_buf;
while ( TRUE ) {
if ((*getpkt)( rpacket, &len )) {
printmsg( 5, "end connection" );
return( 0 );
}
strncpy( cp, rpacket, len );
cp += len;
if ( *(cp - 1) == '\0' ) break;
}
if (( file_buf[0] & 0x7f ) == 'H' ) /* FJE: Hangup mean all done?! */
return( 'C' );
/* Convert upper case to lower [FJE: Why? Does it matter?] */
for (cp = file_buf; *cp != '\0';cp++)
if (isupper(*cp)) *cp = tolower(*cp);
/*
* Fields:
* 0 1 2 3 4 5 6
*
* x D.ckctpab0008 D.boake20008 uucp - D.ckctpab0008 0666
*
* | | | | | | |
* | | | who | | |
* What src file dest file que'd| | file
* to (his name) (my name) it | ??? modes
* do ??? (rw-rw-rw-)
*/
numflds = getargs( file_buf, file_flds );
cp = file_flds[2];
/*
* Check for the funky stuff in the destination filename...
*
* ~ -> $PUBDIR
* ~uucp -> $PUBDIR
*
* ~/pathname -> $PUBDIR/pathname "pathname" may be empty
* ~uucp/pathname -> $PUBDIR/pathname
*/
if (strcmp( cp, "~" ) == SAME || strcmp( cp, "~uucp" ) == SAME ) {
sprintf( tmpfilename, "%s/", pubdir );
} else if (!strncmp( cp, "~/", 2 ) || !strncmp( cp, "~uucp/", 6 )) {
sprintf( tmpfilename, "%s%s", pubdir, index(cp, '/'));
} else {
strcpy( tmpfilename, cp );
}
/* check for dirname only */
cp = tmpfilename + strlen( tmpfilename ) - 1;
if ( *cp == '\n' )
*cp-- = '\0';
if ( *cp == '/' ) {
cp = rindex( file_flds[1], '/' );
if ( cp == (char *) NULL )
cp = file_flds[1];
else
cp++;
strcat( tmpfilename, cp );
} else
cp = file_flds[1];
/* let host munge filename as appropriate */
importpath( tofile, tmpfilename );
if ((fp = CREAT(tofile, 0775, 'b')) == -1) { /* open a new file */
printmsg( 0, "cannot create %s", tofile ); /* Give up if can't */
return('A');
}
printmsg( 1, "Receiving %s as %s", file_flds[1], tofile );
strcpy(rpacket, "SY");
if ((*sendpkt)(rpacket, 0, 1))
return(0);
filetime = time( (long *) 0 );
filesize = 0L;
#ifdef AMIGA
if (!IntuitionBase)
IntuitionBase = OpenLibrary("intuition.library", 0L);
if (IntuitionBase)
CurrentTime( &fileSecs, &fileMicro );
#endif /* AMIGA */
return('D'); /* Switch to data state */
}
/*
* rinit
* receive init
*/
rinit()
{
if ((*openpk)())
return(0);
return('F');
}