home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / packet / n17jsrc / ftpsubr.c < prev    next >
C/C++ Source or Header  |  1991-04-28  |  4KB  |  201 lines

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