home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / FTP / c / ftp next >
Text File  |  1995-02-22  |  7KB  |  337 lines

  1. /* Stuff common to both the FTP server and client */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "netuser.h"
  8. #include "timer.h"
  9. #include "tcp.h"
  10. #include "ftp.h"
  11. #include "session.h"
  12. #include "misc.h"
  13. #include "alarm.h"
  14.  
  15. /* FTP Data channel Receive upcall handler */
  16. void ftpdr(struct tcb *tcb, int16 cnt)
  17. {
  18.   struct session *current;
  19.   register struct ftp *ftp;
  20.   struct mbuf *bp;
  21.   register char *s;
  22.   register char *t;
  23.   register int i;
  24.   char *line;
  25.  
  26.   ftp = (struct ftp *)tcb->user;
  27.   if (ftp->state != RECEIVING_STATE)
  28.   {
  29.     close_tcp(tcb);
  30.     return;
  31.   }
  32.   for (i = 0; i < nsessions; i++)
  33.   {
  34.     if(sessions[i].type == FTP && sessions[i].cb.ftp == ftp)
  35.     {
  36.       current = sessions + i;
  37.       break;
  38.     }
  39.   }
  40.  
  41.   /* This will likely also generate an ACK with window rotation */
  42.   if (recv_tcp(tcb, &bp, cnt) > 0)
  43.   {
  44. /*
  45.     if ((line = s = malloc(len_mbuf(bp) + 1)) == NULL)
  46.     {
  47.       cwprintf(ftp->window, "Out of memory in FTP\r\n");
  48.       free_p(bp);
  49.       return;
  50.     }
  51.  
  52.     while (bp != NULLBUF)
  53.     {
  54.       t = bp->data;
  55.       while (bp->cnt-- > 0)
  56.       {
  57.         if (ftp->type == ASCII_TYPE)
  58.         {
  59.           if (*t != '\r')
  60.             *s++ = *t;
  61.         }
  62.         else
  63.         {
  64.           *s++ = *t;
  65.         }
  66.         t++;
  67.       }
  68.       bp = free_mbuf(bp);
  69.     }
  70.     *s = '\0';
  71.  
  72.     if (ftp->fp == stdout)
  73.     {
  74.       cwputs(ftp->window, line);
  75.     }
  76.     else
  77. */
  78.     if (ftp->type == IMAGE_TYPE && ftp->fp != stdout)
  79.     {
  80.       while (bp != NULLBUF)
  81.       {
  82.         fwrite(bp->data, 1, bp->cnt, ftp->fp);
  83.         bp = free_mbuf(bp);
  84.       }
  85.     }
  86.     else
  87.     {
  88.       if ((line = s = malloc(len_mbuf(bp) + 1)) == NULL)
  89.       {
  90.         cwprintf(ftp->window, "Out of memory in FTP\r\n");
  91.         free_p(bp);
  92.         return;
  93.       }
  94.       while (bp != NULLBUF)
  95.       {
  96.         t = bp->data;
  97.         while (bp->cnt-- > 0)
  98.         {
  99.           if (*t != '\r' || ftp->type==IMAGE_TYPE)
  100.             *s++ = *t;
  101.           t++;
  102.         }
  103.         bp = free_mbuf(bp);
  104.       }
  105.       *s = '\0';
  106.       if (ftp->fp == stdout)
  107.         cwputs(ftp->window, line);
  108.       else
  109.         fwrite(line, 1, s - line, ftp->fp);
  110.       free(line);
  111.     }
  112.  
  113.     if (ftp->fp != stdout)
  114.     {
  115.       if (ftp->hash == 1)
  116.       {
  117.         int a = alarm_timedifference(ftp->start_time, alarm_timenow()) / 100 ;
  118.         long b = ftell(ftp->fp);
  119.  
  120.         cwprintf(ftp->window, "ftp receive: %lu " , b ) ;
  121.         if ( ftp->expected_size > 0 )
  122.           cwprintf(ftp->window, "%.1f%% ", (b * 100.0) / ftp->expected_size ) ;
  123.         if (a > 0)
  124.           cwprintf(ftp->window, "(%lu cps)" , (b-ftp->restart)/a );
  125.         cwputchar(ftp->window, '\r');
  126.       }
  127.       else
  128.       {
  129.         while (ftp->hash && (ftell(ftp->fp) - ftp->last > ftp->hash))
  130.         {
  131.           ftp->last += ftp->hash;
  132.           cwputchar(ftp->window, '#');
  133.         }
  134.       }
  135.     }
  136.   }
  137. }
  138.  
  139. /* FTP Data channel Transmit upcall handler */
  140. void ftpdt(struct tcb *tcb, int16 cnt)
  141. {
  142.   struct ftp *ftp;
  143.   struct mbuf *bp;
  144.   register char *cp;
  145.   register int c;
  146.   int eof_flag;
  147.  
  148.   ftp = (struct ftp *)tcb->user;
  149.   if(ftp->state != SENDING_FILE_STATE && ftp->state != SENDING_DATA_STATE)
  150.   {
  151.     close_tcp(tcb);
  152.     return;
  153.   }
  154.   if((bp = alloc_mbuf(cnt)) == NULLBUF)
  155.   {
  156.     /* Hard to know what to do here */
  157.     return;
  158.   }
  159.   eof_flag = 0;
  160.   if (ftp->state == SENDING_FILE_STATE)
  161.   {
  162.     if(ftp->type == IMAGE_TYPE)
  163.     {
  164.       bp->cnt = fread(bp->data,1,cnt,ftp->fp);
  165.       if(bp->cnt != cnt)
  166.         eof_flag = 1;
  167.       if ( ftp->hash == 1 )
  168.       {
  169.         int a = alarm_timedifference(ftp->start_time, alarm_timenow()) / 100;
  170.         long b = ftell(ftp->fp) ;
  171.  
  172.         cwprintf(ftp->window, "ftp send: %lu " , b);
  173.         if (ftp->expected_size > 0)
  174.           cwprintf(ftp->window, "%.1f%% ", b * 100.0 / ftp->expected_size);
  175.         if ( a > 0 )
  176.           cwprintf(ftp->window, "(%lu cps)" , b/a);
  177.         cwputchar(ftp->window, '\r');
  178.       }
  179.       else
  180.       {
  181.         while (ftp->hash && (ftell(ftp->fp) - ftp->last > ftp->hash))
  182.         {
  183.           ftp->last += ftp->hash;
  184.           cwputchar(ftp->window, '#');
  185.         }
  186.       }
  187.     }
  188.     else
  189.     {
  190.       cp = bp->data;
  191.       while(cnt > 1)
  192.       {
  193.         if((c = getc(ftp->fp)) == EOF)
  194.         {
  195.           eof_flag=1;
  196.           break;
  197.         }
  198.         if(c == '\n')
  199.         {
  200.           *cp++ = '\r';
  201.           bp->cnt++;
  202.           cnt--;
  203.         }
  204.         *cp++ = c;
  205.         bp->cnt++;
  206.         cnt--;
  207.       }
  208.       if ( ftp->hash == 1 )
  209.       {
  210.         int a = alarm_timedifference(ftp->start_time, alarm_timenow()) / 100;
  211.         long b = ftell(ftp->fp) ;
  212.  
  213.         cwprintf(ftp->window, "ftp send: %lu " , b );
  214.         if (ftp->expected_size > 0)
  215.           cwprintf(ftp->window, "%.1f%% ", b * 100.0 / ftp->expected_size );
  216.         if ( a > 0 )
  217.           cwprintf(ftp->window, "(%lu cps)", b/a);
  218.         cwputchar(ftp->window, '\r');
  219.       }
  220.       else
  221.       {
  222.         while (ftp->hash && (ftell(ftp->fp) - ftp->last > ftp->hash))
  223.         {
  224.           ftp->last += ftp->hash;
  225.           cwputchar(ftp->window, '#');
  226.         }
  227.       }
  228.     }
  229.     if(bp->cnt != 0)
  230.       send_tcp(tcb,bp);
  231.     else
  232.       free_p(bp);
  233.     if(eof_flag)
  234.     {   /* EOF seen */
  235.       fclose(ftp->fp);
  236.       ftp->fp = NULLFILE;
  237.       close_tcp(tcb);
  238.     }
  239.   }
  240.   else
  241.   {        /* SENDING_DATA_STATE */
  242.     if (ftp->type == IMAGE_TYPE)
  243.     {
  244.       if ((bp->cnt = strlen(ftp->cp)) < cnt)
  245.         eof_flag = 1;
  246.       else
  247.         bp->cnt = cnt;
  248.       strncpy(bp->data, ftp->cp, bp->cnt);
  249.       bp->data[bp->cnt] = '\0';
  250.       ftp->cp += bp->cnt;
  251.     }
  252.     else
  253.     {
  254.       cp = bp->data;
  255.       while(cnt > 1)
  256.       {
  257.         if((c = *ftp->cp++) == '\0')
  258.         {
  259.           c = EOF;
  260.           eof_flag=1;
  261.           break;
  262.         }
  263.         if(c == '\n')
  264.         {
  265.           *cp++ = '\r';
  266.           bp->cnt++;
  267.           cnt--;
  268.         }
  269.         *cp++ = c;
  270.         bp->cnt++;
  271.         cnt--;
  272.       }
  273.     }
  274.     if(bp->cnt != 0)
  275.       send_tcp(tcb,bp);
  276.     else
  277.       free_p(bp);
  278.     if(eof_flag)
  279.     {   /* EOF seen */
  280.       free(ftp->p);
  281.       ftp->p = ftp->cp = NULLCHAR;
  282.       close_tcp(tcb);
  283.     }
  284.   }
  285. }
  286. /* Allocate an FTP control block */
  287. struct ftp *ftp_create(unsigned int bufsize)
  288. {
  289.   register struct ftp *ftp;
  290.  
  291.   if((ftp = (struct ftp *)calloc(1,sizeof (struct ftp))) == NULLFTP)
  292.     return NULLFTP;
  293.   if(bufsize != 0 && (ftp->buf = malloc(bufsize)) == NULLCHAR)
  294.   {
  295.     ftp_delete(ftp);
  296.     return NULLFTP;
  297.   }
  298.   ftp->state = COMMAND_STATE;
  299.   ftp->type = ASCII_TYPE; /* Default transfer type */
  300.   ftp->batch = NULL;
  301.   ftp->mfp = NULL;
  302.   ftp->margv = NULL;
  303.   ftp->mtemp = NULL;
  304.   ftp->mpstate = FTPM_IDLE;
  305.   ftp->pathopts = PATH_OFF;
  306.   return ftp;
  307. }
  308. /* Free resources, delete control block */
  309. void ftp_delete(register struct ftp *ftp)
  310. {
  311.   int i;
  312.   extern void ftp_mpcleanup(struct ftp *ftp);
  313.  
  314.   delpathent(ftp->pathopts);
  315.   ftp_mpcleanup(ftp);
  316.   if(ftp->batch != NULLFILE)
  317.     fclose(ftp->batch);
  318.   if(ftp->fp != NULLFILE && ftp->fp != stdout)
  319.     fclose(ftp->fp);
  320.   if(ftp->p != NULLCHAR)
  321.     free(ftp->p);
  322.   if(ftp->data != NULLTCB)
  323.     del_tcp(ftp->data);
  324.   if(ftp->username != NULLCHAR)
  325.     free(ftp->username);
  326.   for (i = 0; i < MAXPATH; i++)
  327.     if(ftp->path[i] != NULLCHAR)
  328.       free(ftp->path[i]);
  329.   if(ftp->buf != NULLCHAR)
  330.     free(ftp->buf);
  331.   if(ftp->cd != NULLCHAR)
  332.     free(ftp->cd);
  333.   if(ftp->session != NULLSESSION)
  334.     freesession(ftp->session);
  335.   free((char *)ftp);
  336. }
  337.