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