home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / gopher / gopher1.01 / gopherd / ftp.c < prev    next >
C/C++ Source or Header  |  1992-06-22  |  8KB  |  308 lines

  1. /* -------------------------------------------------
  2. *    g2fd.c          Gopher to FTP gateway daemon.
  3. *    Version 0.3 Hacked up: April 1992.  Farhad Anklesaria.
  4. *    Based on a Perl story by John Ladwig.
  5. *    Based on a Perl story by Farhad Anklesaria.
  6. *
  7. *    To be run by inetd.
  8. *    For installation, read the companion README.... or
  9. *    if you don't feel like doing that, the brief instructions
  10. *    are below:
  11. *    
  12. *    First edit the local parameters in defines below.
  13. *    Then do a "make g2fd"
  14. *    Then place the binary (g2fd) in some reasonable place,
  15. *        eg in /usr/local/bin
  16. *    Finally, edit /etc/services and /etc/servers or
  17. *         /etc/inetd.conf as the case may be.  Kill
  18. *        and restart inetd.
  19. *
  20. *    This file looks best with tabstops set to 4 rather than 8.
  21. ---------------------------------------------------- */
  22.  
  23. #include "gopherd.h"
  24. #include <signal.h>
  25.  
  26. #include <stdio.h>
  27.  
  28.  
  29. #define GFILE    0        /* Gopher item types */
  30. #define GDIR    1
  31. #define GBINHEX    4
  32. #define GDOSB    5
  33. #define GUNIXB    9
  34.  
  35. #define SLEN    255    /* Generic small buffer length */
  36. #define    TMOUT    1200    /* 20 minutes is plenty long enough */
  37.  
  38. char    *appname;
  39. char    ftp[SLEN] = FTP;
  40. char    tmpList[SLEN] = LIST;
  41. char    tmpData[SLEN] = DATA;
  42. char    query[BUFSIZ];                /* input redirected by inetd */
  43. char     *host, *thing;                /* pointers into query */
  44. int        gettingFile = 1;
  45. int        gettingBinary = 0;
  46. int        childpid;
  47.  
  48.  
  49. SendFtpQuery(query)
  50.   char *query;
  51. {
  52.      int   sLen, termCh;
  53.      char  *at;
  54.      FILE  *fd, *popen();
  55.      
  56.      if (DEBUG)
  57.       printf("The full query was %s\n", query);
  58.      
  59.      if ((sLen = strlen(query)) <= 2) Abort("No host name specified.");
  60.      host = query;
  61.      at = strchr(query, '@');
  62.  
  63.      if (at == NULL) 
  64.       Abort("Not a valid ftp query.");
  65.  
  66.      thing = at + 1;
  67.      *at = '\0';             /*Sneakily chop it into two strings*/
  68.      sprintf(ftp + strlen(ftp), " -n %s > %s", host, tmpList);
  69.  
  70.      if ((fd = popen(ftp, "w")) == NULL) 
  71.       Abort("Can't run ftp.");
  72.  
  73.      FailErr(fprintf(fd, "user anonymous gopher@%s\n", Zehostname));
  74.     
  75.      sLen = strlen(thing);
  76.      termCh = thing[sLen - 1];            /* Grab possible end char: / etc */
  77.  
  78.      if ((termCh == '*') || (termCh == '@'))  /*  || (termCh == '/')  */
  79.       thing[sLen - 1] = '\0';
  80.  
  81.      if (DEBUG)
  82.       printf("At this point host: %s   thing: %s\n", host, thing);
  83.  
  84.      if (termCh == '/') {    /* We have a directory */
  85.       gettingFile = 0;
  86.       if (strlen(thing) > 0) 
  87.            FailErr(fprintf(fd, "cd \"%s\"\n", thing));
  88.       FailErr(fprintf(fd, "ls -F\n"));
  89.      } 
  90.      else {                    /* We have a file */
  91.       gettingFile = 1;
  92.       if (gettingBinary = IsBinaryType(thing))  
  93.            FailErr(fprintf(fd, "binary\n"));
  94.       FailErr(fprintf(fd, "get \"%s\" \"%s\"\n", thing, tmpData));
  95.      }
  96.      FailErr(fprintf(fd, "quit\n"));
  97.      pclose(fd);
  98. }
  99.  
  100. /*--------------------------------*/
  101.  
  102. TranslateResults(sockfd)
  103. {
  104.      FILE  *fp, *OpenOrDie();
  105.      char  buf[BUFSIZ], theName[SLEN];
  106.      int   fd, nRead, checkIt;
  107.      char  outputline[512];
  108.      
  109.      checkIt = 1;
  110.  
  111.      if (gettingFile) {
  112.       if (gettingBinary) {                /* icky binary file */
  113.            if (DEBUG)
  114.             printf("Whoa!  That's a binary file\n");
  115.            fd = uopen(tmpData, "r");
  116.            while ((nRead = read(fd, buf, sizeof buf)) > 0) {
  117.             writen(sockfd, buf, nRead);
  118.            }
  119.            close(fd);
  120.       } else {            /* must be a nice texty file */
  121.            fp = OpenOrDie(tmpData, "r");
  122.            while (fgets(buf, sizeof buf, fp) != NULL) {
  123.             if (checkIt) { /* Just peek at it once */
  124.              checkIt = 0;
  125.              if (NotText(buf)) {
  126.                   fclose(fp);
  127.                   Abort("Sorry.  File does not appear to contain text.");
  128.              }
  129.             }
  130.             ZapCRLF(buf);
  131.             writestring(sockfd, buf);
  132.             writestring(sockfd, "\r\n");
  133.             /*FailErr(printf("%s\r\n", buf));*/
  134.            }
  135.            fclose(fp);
  136.            FailErr(writestring(sockfd,".\r\n"));
  137.       }
  138.      } else {                       /* Must be a directory */
  139.       fp = OpenOrDie(tmpList, "r");
  140.       while (fgets(buf, sizeof buf, fp) != NULL) {
  141.            GopherType(buf, theName);
  142.            sprintf(outputline, "%s\tftp:%s@%s%s\t%s\t%d\r\n", theName, 
  143.                host, thing, buf, Zehostname, GopherPort);
  144.            writestring(sockfd, outputline);
  145.       }
  146.       fclose(fp);
  147.       FailErr(writestring(sockfd, ".\r\n"));
  148.      }
  149. }
  150.  
  151. /*--------------------------------*/
  152.  
  153. FILE *OpenOrDie(file, mode)
  154.   char *file, *mode;
  155. {
  156.      FILE *fp, *fopen();
  157.      if ((fp = ufopen(file, mode)) != NULL) {
  158.       return(fp);
  159.      } else {
  160.       Abort("Could not complete the transfer.");
  161.      }
  162. }
  163.  
  164.  
  165. /*--------------------------------*/
  166. NotText(buf)
  167.   char * buf;
  168. {
  169.      int max;   char *c;
  170.      
  171.      if ((max = strlen(buf)) >= (BUFSIZ - 50)) max = BUFSIZ - 50;
  172.      for (c = buf; c < (buf + max); c++) {
  173.       if (*c > '~') return(1);
  174.      }
  175.      return(0);
  176. }
  177.  
  178. /*--------------------------------*/
  179.  
  180. Abort(complaint)
  181.   char *complaint;
  182.   
  183. {
  184.      printf("3 Error: %s\r\n.\r\n", complaint); 
  185.      Cleanup();
  186.      exit(1);
  187. }
  188.  
  189. /*--------------------------------*/
  190.  
  191. IsBinaryType(thing)
  192.   char *thing;
  193. {
  194.      static char *binExt[] = {
  195.       ".zip", ".zoo", ".arj", ".arc", ".lzh", ".hyp", ".pak", ".exe", ".com",
  196.       ".ps", ".gif", ".pict", ".pct", ".tiff", ".tif", ".tar", ".Z"
  197.       };
  198.      
  199.      int extType, i;
  200.      
  201.      for (extType = 0; extType < 17; extType++) { 
  202.       i = strcasecmp(thing + strlen(thing) - strlen(binExt[extType]),
  203.              binExt[extType]);
  204.       if (i == 0) return(1);
  205.      }
  206.      return(0);
  207.      
  208. }
  209.  
  210. /*--------------------------------*/
  211.  
  212. GenerateUniqueFiles(tmpList, tmpData)
  213.   char *tmpList, *tmpData;
  214. {
  215.      char *s;
  216.      int pid;
  217.      
  218.      pid = getpid();
  219.      s = strchr(tmpList, '+');
  220.      sprintf(s, "%d", pid);
  221.      s = strchr(tmpData, '+');
  222.      sprintf(s, "%d", pid);
  223. }
  224.  
  225. /*--------------------------------*/
  226.  
  227. GopherType(buf, theName)
  228.   char *buf, *theName;
  229.   
  230. {
  231.      static char ext4[] = ".hqx";
  232.      static char *ext5[] = {".zip", ".zoo", ".arj", ".arc", ".lzh", ".hyp", 
  233.                  ".pak", ".exe", ".com", ".ps", ".gif", ".pict", 
  234.                  ".pct", ".tiff", ".tif"};
  235.      static char *ext9[] = {".tar", ".Z"};
  236.      int extType, i, last;
  237.      char    tmpName[SLEN];    
  238.      
  239.      last = strlen(buf) - 1;     buf[last--] = '\0';  /* Munge the LF */
  240.      strcpy(tmpName, buf);
  241.      if (buf[last] == '/') {
  242.       tmpName[last] = '\0';
  243.       sprintf(theName, "%d%s", GDIR, tmpName);
  244.       return;
  245.      }
  246.      if ((buf[last] == '*') || (buf[last] == '@')) {        /* Hack out * and @ */
  247.       buf[last] = '\0';
  248.       tmpName[last] = '\0';
  249.      }
  250.      
  251.      /* At this point we're looking at a file */
  252.      if (strcasecmp(buf + strlen(buf) - strlen(ext4), ext4) == 0) { /* BinHex? */
  253.       sprintf(theName, "%d%s", GBINHEX, tmpName);
  254.       return;
  255.      }
  256.      
  257.      for (extType = 0; extType < 15; extType++) {            /* PC garbage? */ 
  258.       i = strcasecmp(buf + strlen(buf) - strlen(ext5[extType]), 
  259.              ext5[extType]);
  260.       if (i == 0) {
  261.            sprintf(theName, "%d%s", GDOSB, tmpName);
  262.            return;
  263.       }
  264.      }
  265.      
  266.      for (extType = 0; extType < 2; extType++) {                /* unix binary? */ 
  267.       i = strcasecmp(buf + strlen(buf) - strlen(ext9[extType]), 
  268.              ext9[extType]);
  269.       if (i == 0) {
  270.            sprintf(theName, "%d%s", GUNIXB, tmpName);
  271.            return;
  272.       }
  273.      }
  274.      
  275.      sprintf(theName, "%d%s", GFILE, tmpName);
  276.      return;        /* Some other and hopefully text file */
  277. }
  278.  
  279. /*--------------------------------*/
  280.  
  281. Cleanup()
  282. {
  283.      unlink(tmpList);
  284.      unlink(tmpData);
  285.      exit(1);
  286. }
  287.  
  288. /*--------------------------------*/
  289.  
  290. RoundEmUp()
  291. {
  292.      
  293.      kill(childpid, SIGKILL);
  294.      Cleanup();
  295. }
  296.  
  297. /*--------------------------------*/
  298.  
  299. FailErr(result)
  300.   int result;
  301. {
  302.      if (result < 0) {
  303.       Cleanup();
  304.      }
  305. }
  306.  
  307. /*--------------------------------*/
  308.