/*         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');
}
