home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / FTPSUBR.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  7KB  |  260 lines

  1. /* Routines common to both the FTP client and server
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by G1EMM */
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "socket.h"
  8. #include "proc.h"
  9. #include "mailbox.h"
  10. #include "bm.h"
  11. #include "ftp.h"
  12. #include "ftpcli.h"
  13.   
  14. /* Send a file (opened by caller) on a network socket.
  15.  * Normal return: count of bytes sent
  16.  * Error return: -1
  17.  */
  18. long
  19. sendfile(fp,s,mode,hash,m)
  20. FILE *fp;   /* File to be sent */
  21. int s;      /* Socket to be sent on */
  22. int mode;   /* Transfer mode */
  23. int hash;   /* Print hash marks every BLKSIZE bytes */
  24. struct mbx *m;
  25. {
  26.     struct mbuf *bp;
  27.     int c,oldf;
  28.     long total = 0;
  29.     long hmark = 0;
  30. #ifdef MAILBOX
  31.     int lin;
  32.     int usemore = 0;
  33. #endif
  34.   
  35.     switch(mode){
  36.         default:
  37.         case LOGICAL_TYPE:
  38.         case IMAGE_TYPE:
  39.             sockmode(s,SOCK_BINARY);
  40.             for(;;){
  41.                 bp = ambufw(BLKSIZE);
  42.                 if((bp->cnt = fread(bp->data,1,BLKSIZE,fp)) == 0){
  43.                     free_p(bp);
  44.                     break;
  45.                 }
  46.                 total += bp->cnt;
  47.                 if(send_mbuf(s,bp,0,NULLCHAR,0) == -1){
  48.                     total = -1;
  49.                     break;
  50.                 }
  51.                 while(hash == V_HASH && total >= hmark+1000){
  52.                     tputc('#');
  53.                     hmark += 1000;
  54.                 }
  55.                 while(hash == V_BYTE && total >= hmark+1000){
  56.                     tprintf("Bytes sent : %ld\r", total);
  57.                     hmark += 1000;
  58.                 }
  59.             }
  60.             break;
  61.         case ASCII_TYPE:
  62. #ifdef MAILBOX
  63.             if(m && ((lin=m->morerows) != 0))
  64.                 usemore = 1;    /* Display More prompt */
  65. #endif
  66.             oldf = setflush(s,-1);
  67.         /* Let the newline mapping code in usputc() do the work */
  68.             sockmode(s,SOCK_ASCII);
  69.             while((c = getc(fp)) != EOF){
  70. #if !defined(UNIX) && !defined(__TURBOC__)
  71.                 if(c == '\r'){
  72.                 /* Needed only if the OS uses a CR/LF
  73.                  * convention and getc doesn't do
  74.                  * an automatic translation
  75.                  */
  76.                     continue;
  77.                 }
  78. #endif
  79.                 if(usputc(s,(char)c) == -1){
  80.                     total = -1;
  81.                     break;
  82.                 }
  83.                 total++;
  84. #ifdef MAILBOX
  85.             /* More prompting added - WG7J */
  86.                 if(c == '\n'){
  87.                     lin--;
  88.                     if(usemore && lin <= 0){
  89.                         if(charmode_ok(m))
  90.                             c = tkeywait(TelnetMorePrompt,0);
  91.                         else  /* For AX.25 and NET/ROM connects - WG7J */
  92.                             c = mykeywait(BbsMorePrompt,m);
  93.                         if(c == -1 || c == 'q' || c == 'Q')
  94.                             break;
  95.                         if(c == '\n' || c == '\r')
  96.                             lin = 1;
  97.                         else
  98.                             lin = m->morerows;
  99.                     }
  100.   
  101.                 }
  102. #endif
  103.                 while(hash == V_HASH && total >= hmark+1000){
  104.                     tputc('#');
  105.                     hmark += 1000;
  106.                 }
  107.                 while(hash == V_BYTE && total >= hmark+1000){
  108.                     tprintf("Bytes sent : %ld\r", total);
  109.                     hmark += 1000;
  110.                 }
  111.             }
  112.             usflush(s);
  113.             setflush(s,oldf);
  114.             break;
  115.     }
  116.     if(hash)
  117.         tputc('\n');
  118.     return total;
  119. }
  120. /* Receive a file (opened by caller) from a network socket.
  121.  * Normal return: count of bytes received
  122.  * Error return: -1
  123.  */
  124. long
  125. recvfile(fp,s,mode,hash)
  126. FILE *fp;
  127. int s;
  128. int mode;
  129. int hash;
  130. {
  131.     int cnt,c;
  132.     struct mbuf *bp;
  133.     long total = 0;
  134.     long hmark = 0;
  135.   
  136.     switch(mode){
  137.         default:
  138.         case LOGICAL_TYPE:
  139.         case IMAGE_TYPE:
  140.             sockmode(s,SOCK_BINARY);
  141.             while((cnt = recv_mbuf(s,&bp,0,NULLCHAR,0)) != 0){
  142.                 if(cnt == -1){
  143.                     total = -1;
  144.                     break;
  145.                 }
  146.                 total += cnt;
  147.                 while(hash == V_HASH && total >= hmark+1000){
  148.                     tputc('#');
  149.                     hmark += 1000;
  150.                 }
  151.                 while(hash == V_BYTE && total >= hmark+1000){
  152.                     tprintf("Bytes recv : %ld\r", total);
  153.                     hmark += 1000;
  154.                 }
  155.                 if(fp != NULLFILE){
  156.                     if(write_p(fp,bp) == -1){
  157.                         free_p(bp);
  158.                         total = -1;
  159.                         break;
  160.                     }
  161.                     free_p(bp);
  162.                 } else {
  163.                     send_mbuf(Curproc->output, bp, 0, NULLCHAR, 0);
  164.                 }
  165.             }
  166.             break;
  167.         case ASCII_TYPE:
  168.             sockmode(s,SOCK_ASCII);
  169.             while((c = recvchar(s)) != EOF){
  170.                 if(fp != NULLFILE){
  171. #if !defined(UNIX) && !defined(__TURBOC__) && !defined(AMIGA)
  172.                     if(c == '\n'){
  173.                     /* Needed only if the OS uses a CR/LF
  174.                      * convention and putc doesn't do
  175.                      * an automatic translation
  176.                      */
  177.                         putc('\r',fp);
  178.                     }
  179. #endif
  180.                     if(putc(c,fp) == EOF){
  181.                         total = -1;
  182.                         break;
  183.                     }
  184.                 } else {
  185.                     tputc((char)c);
  186.                 }
  187.                 total++;
  188.                 while(hash == V_HASH && total >= hmark+1000){
  189.                     tputc('#');
  190.                     hmark += 1000;
  191.                 }
  192.                 while(hash == V_BYTE && total >= hmark+1000){
  193.                     tprintf("Bytes recv : %ld\r", total);
  194.                     hmark += 1000;
  195.                 }
  196.             }
  197.         /* Detect an abnormal close */
  198.             if(socklen(s,0) == -1)
  199.                 total = -1;
  200.             break;
  201.     }
  202.     if(hash)
  203.         tputc('\n');
  204.     return total;
  205. }
  206. /* Determine if a file appears to be binary (i.e., non-text).
  207.  * Return 1 if binary, 0 if ascii text after rewinding the file pointer.
  208.  *
  209.  * Used by FTP to warn users when transferring a binary file in text mode.
  210.  */
  211. int
  212. isbinary(fp)
  213. FILE *fp;
  214. {
  215.     int c,i;
  216.     int rval;
  217.   
  218.     rval = 0;
  219.     for(i=0;i<512;i++){
  220.         if((c = getc(fp)) == EOF)
  221.             break;
  222.         if(c & 0x80){
  223.             /* High bit is set, probably not text */
  224.             rval = 1;
  225.             break;
  226.         }
  227.     }
  228.     /* Assume it was at beginning */
  229.     fseek(fp,0L,SEEK_SET);
  230.     return rval;
  231. }
  232.   
  233. long
  234. getsize(fp)
  235. FILE *fp;
  236. {
  237.     fseek(fp,0L,SEEK_END);  /* Go to end of file */
  238.     return ftell(fp);   /* Return file pointer position */
  239. }
  240.   
  241. /* Compute checksum of the first n bytes */
  242. unsigned long
  243. checksum(fp,n)
  244. FILE *fp;
  245. long n;
  246. {
  247.     unsigned long sum;
  248.     long i;
  249.     int c;
  250.   
  251.     rewind(fp);
  252.     sum = 0;
  253.     for(i=1;i<=n;i++){
  254.         if((c = fgetc(fp)) == EOF)
  255.             break;
  256.         sum += (unsigned long)c;
  257.     }
  258.     return sum;
  259. }
  260.