home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / ftpsubr.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  4KB  |  183 lines

  1. /* Routines common to both the FTP client and server
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "socket.h"
  8. #include "proc.h"
  9. #include "ftp.h"
  10.  
  11. /* Send a file (opened by caller) on a network socket.
  12.  * Normal return: count of bytes sent
  13.  * Error return: -1
  14.  */
  15. long
  16. sendfile(fp,s,mode,hash)
  17. FILE *fp;    /* File to be sent */
  18. int s;        /* Socket to be sent on */
  19. int mode;    /* Transfer mode */
  20. int hash;    /* Print hash marks every BLKSIZE bytes */
  21. {
  22.     register struct mbuf *bp;
  23.     int c,oldf;
  24.     long total = 0;
  25.     long hmark = 0;
  26.  
  27.     switch(mode){
  28.     default:
  29.     case LOGICAL_TYPE:
  30.     case IMAGE_TYPE:
  31.         sockmode(s,SOCK_BINARY);
  32.         for(;;){
  33.             bp = ambufw(BLKSIZE);
  34.             if((bp->cnt = fread(bp->data,1,BLKSIZE,fp)) == 0){
  35.                 free_p(bp);
  36.                 break;
  37.             }
  38.             total += bp->cnt;
  39.             if(send_mbuf(s,bp,0,NULLCHAR,0) == -1){
  40.                 return -1;
  41.             }
  42.             while(hash && total >= hmark+1000){
  43.                 tputc('#');
  44.                 hmark += 1000;
  45.             }
  46.         }
  47.         break;
  48.     case ASCII_TYPE:
  49.         oldf = setflush(s,-1);
  50.         /* Let the newline mapping code in usputc() do the work */
  51.         sockmode(s,SOCK_ASCII);
  52.         while((c = getc(fp)) != EOF){
  53. #if !defined(UNIX) && !defined(__TURBOC__)
  54.             if(c == '\r'){
  55.                 /* Needed only if the OS uses a CR/LF
  56.                  * convention and getc doesn't do
  57.                  * an automatic translation
  58.                  */
  59.                 continue;
  60.             }
  61. #endif
  62.             if(usputc(s,(char)c) == -1){
  63.                 total = -1;
  64.                 break;
  65.             }
  66.             total++;
  67.             while(hash && total >= hmark+1000){
  68.                 tputc('#');
  69.                 hmark += 1000;
  70.             }
  71.         }
  72.         usflush(s);
  73.         setflush(s,oldf);        
  74.         break;
  75.     }
  76.     if(hash)
  77.         tputc('\n');
  78.     return total;
  79. }
  80. /* Receive a file (opened by caller) from a network socket.
  81.  * Normal return: count of bytes received
  82.  * Error return: -1
  83.  */
  84. long
  85. recvfile(fp,s,mode,hash)
  86. FILE *fp;
  87. int s;
  88. int mode;
  89. int hash;
  90. {
  91.     int cnt,c;
  92.     struct mbuf *bp;
  93.     long total = 0;
  94.     long hmark = 0;
  95.  
  96.     switch(mode){
  97.     default:
  98.     case LOGICAL_TYPE:
  99.     case IMAGE_TYPE:
  100.         sockmode(s,SOCK_BINARY);
  101.         while((cnt = recv_mbuf(s,&bp,0,NULLCHAR,0)) != 0){
  102.             if(cnt == -1)
  103.                 return -1;
  104.  
  105.             total += cnt;
  106.             while(hash && total >= hmark+1000){
  107.                 tputc('#');
  108.                 hmark += 1000;
  109.             }
  110.             if(fp != NULLFILE){
  111.                 if(write_p(fp,bp) == -1){
  112.                     free_p(bp);
  113.                     return -1;
  114.                 }
  115.                 free_p(bp);
  116.             } else {
  117.                 send_mbuf(Curproc->output, bp, 0, NULLCHAR, 0);
  118.             }
  119.         }
  120.         break;
  121.     case ASCII_TYPE:
  122.         sockmode(s,SOCK_ASCII);
  123.         while((c = recvchar(s)) != EOF){
  124.             if(fp != NULLFILE){
  125. #if !defined(UNIX) && !defined(__TURBOC__) && !defined(AMIGA)
  126.                 if(c == '\n'){
  127.                     /* Needed only if the OS uses a CR/LF
  128.                      * convention and putc doesn't do
  129.                      * an automatic translation
  130.                      */
  131.                     putc('\r',fp);
  132.                 }
  133. #endif
  134.                 if(putc(c,fp) == EOF){
  135.                     total = -1;
  136.                     break;
  137.                 }
  138.             } else {
  139.                 tputc((char)c);
  140.             }
  141.             total++;
  142.             while(hash && total >= hmark+1000){
  143.                 tputc('#');
  144.                 hmark += 1000;
  145.             }
  146.         }
  147.         /* Detect an abnormal close */
  148.         if(socklen(s,0) == -1)
  149.             total = -1;
  150.         break;
  151.     }
  152.     if(hash)
  153.         tputc('\n');
  154.     return total;
  155. }
  156. /* Determine if a file appears to be binary (i.e., non-text).
  157.  * Return 1 if binary, 0 if ascii text after rewinding the file pointer.
  158.  *
  159.  * Used by FTP to warn users when transferring a binary file in text mode.
  160.  */
  161. int
  162. isbinary(fp)
  163. FILE *fp;
  164. {
  165.     int c,i;
  166.     int rval;
  167.  
  168.     rval = 0;
  169.     for(i=0;i<512;i++){
  170.         if((c = getc(fp)) == EOF)
  171.             break;
  172.         if(c & 0x80){
  173.             /* High bit is set, probably not text */
  174.             rval = 1;
  175.             break;
  176.         }
  177.     }
  178.     /* Assume it was at beginning */
  179.     fseek(fp,0L,SEEK_SET);
  180.     return rval;
  181. }
  182.  
  183.