/*			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(fromfile);
	printmsg( 0, "transfer %s complete,%d", fromfile, 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 for sending.", fromfile );
		fp = open(fromfile, 0);/* open the file to be sent */
		if (fp == -1) {/* If bad file pointer, give up */
			printmsg( 0, "Cannot open file %s", fromfile );
			return('A');
		}
	} else 
		return('A'); /* If somethings already open. were in trouble*/
	printmsg( 0, "Sending %s as %s", fromfile, 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');
	}
	if ( write(fp, rpacket, len) == -1 ) /* Write the data to the file */
	   {
		printmsg( 0, "Error Writing File" );
		return 'A';
	   }
	return('D');/* Remain in data state */
}


/**/
/*
 *  r f i l e
 *
 *  Receive File Header
 */
rfile()
{

	char 	buf[256];
	char *	flds[10];
	int		numflds;
	
	int		len, 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');
}



