home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff220.lzh / DNet / client / getfiles.c < prev    next >
C/C++ Source or Header  |  1989-06-04  |  8KB  |  396 lines

  1.  
  2. /*
  3.  *  GETFILES.C        V1.30
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  GETFILES [-dlocaldir] [-c] file/dir file/dir file/dir
  8.  *
  9.  *  -dlocaldir    local directory to place files
  10.  *
  11.  *  -c        Continue from where you left off before.  Files that already
  12.  *        exist on the local machine will not be re-transfered.  This
  13.  *        will also re-start in the middle of a file that was
  14.  *        partially transfered previously.
  15.  *
  16.  *        This command assumes the file(s) on both machines have not
  17.  *        been modified since the first attempt.    No other checking
  18.  *        is done at the moment.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <sys/types.h>
  23. #include <sys/file.h>
  24. #include <sys/stat.h>
  25. #include "../server/servers.h"
  26.  
  27. typedef unsigned char ubyte;
  28.  
  29. typedef struct {
  30.     char    Cmd;
  31.     char    Str[64];
  32.     long    Val;
  33. } HDR;
  34.  
  35. char *NSpaces();
  36.  
  37. char Buf[1024];
  38.  
  39. short ContMode;
  40. char  *NetId;
  41. long  Chan = -1;
  42.  
  43. main(ac,av)
  44. char *av[];
  45. {
  46.     HDR Hdr;
  47.     short error;
  48.  
  49.     {
  50.     char *ldir = ".";
  51.     struct stat stat;
  52.     ac = DoOption(ac, av, "N%sd%sc", &NetId, &ldir, &ContMode);
  53.     if (ac <= 1) {
  54.         puts("GETFILES [-Nnetid -dlocaldir -c] remotefile/dir ...");
  55.         fail(22);
  56.     }
  57.     if (chdir(ldir) < 0) {
  58.         mkdir(ldir, 0777);
  59.         if (chdir(ldir) < 0) {
  60.         printf("Unable to CD or make local directory: \"%s\"\n",ldir);
  61.         fail(21);
  62.         }
  63.     }
  64.     }
  65.     Chan = DOpen(NetId, PORT_GFILECOPY, 126, -80);
  66.     if (Chan < 0) {
  67.     puts("Unable to connect");
  68.     fail(20);
  69.     }
  70.     error = WriteHeader('H', "Hello, getfiles client V1.30", 0);
  71.     if (error)
  72.     fail(LostChannel());
  73.     switch(ReadHeader(&Hdr)) {
  74.     case -1:
  75.     fail(LostChannel());
  76.     case 'H':
  77.     printf("%s\n", Hdr.Str);
  78.     break;
  79.     }
  80.     {
  81.     register short i;
  82.     long val;
  83.  
  84.     for (i = 1; i < ac; ++i) {
  85.         short error;
  86.  
  87.         error = WriteHeader('G', av[i], 0);
  88.         if (error)
  89.         fail(LostChannel());
  90.         switch(ReadHeader(&Hdr)) {
  91.         case -1:
  92.         fail(LostChannel());
  93.         case 'N':
  94.         printf("Remote error on %s: %s\n", av[i], Hdr.Str);
  95.         break;
  96.         case 'F':
  97.         error = CheckNoPath(Hdr.Str);
  98.         if (!error) {
  99.             char svpath[1024];
  100.             getwd(svpath);
  101.             error = GetFile(&Hdr, 0);
  102.             chdir(svpath);
  103.         }
  104.         break;
  105.         case 'D':
  106.         error = CheckNoPath(Hdr.Str);
  107.         if (!error) {
  108.             char svpath[1024];
  109.             getwd(svpath);
  110.             error = GetDir(&Hdr, 0);
  111.             chdir(svpath);
  112.         }
  113.         break;
  114.         case 'S':
  115.         printf("Access Violation: %s\n", Hdr.Str);
  116.         break;
  117.         default:
  118.         error = UnknownCmd(&Hdr);
  119.         break;
  120.         }
  121.         if (error)
  122.         fail(error);
  123.     }
  124.     if (!error) {
  125.         error = WriteHeader('E', "bye", 0);
  126.         if (error)
  127.         fail(LostChannel());
  128.     }
  129.     }
  130.     fail(0);
  131. }
  132.  
  133. fail(code)
  134. {
  135.     if (Chan >= 0)
  136.     close(Chan);
  137.     exit(code);
  138. }
  139.  
  140. CheckNoPath(str)
  141. register char *str;
  142. {
  143.     while (*str) {
  144.     if (*str == '/' || *str == ':') {
  145.         puts("SECURITY ALERT: Illegal path spec received");
  146.         return(40);
  147.     }
  148.     ++str;
  149.     }
  150.     return(0);
  151. }
  152.  
  153. LostChannel()
  154. {
  155.     puts("DATA CHANNEL LOST");
  156.     return(10);
  157. }
  158.  
  159. UnknownCmd(hdr)
  160. HDR *hdr;
  161. {
  162.     printf("Unrecognized command code: %02x\n", hdr->Cmd);
  163. }
  164.  
  165. /*
  166.  *  retrieve a file.  If ContMode set and file exists, try to append to
  167.  *  it.
  168.  */
  169.  
  170.  
  171. #define BSSTR "\010\010\010\010\010\010\010\010\010\010\010\010\010"
  172.  
  173. GetFile(hdr, stab)
  174. HDR *hdr;
  175. {
  176.     int fd = -1;
  177.     long pos = 0;
  178.     short error = 0;
  179.  
  180.     printf("%s%-20s ", NSpaces(stab), hdr->Str);
  181.     fflush(stdout);
  182.     if (ContMode) {
  183.     if ((fd = open(hdr->Str, O_WRONLY)) >= 0) {    /*  already exists  */
  184.         long len;
  185.  
  186.         len = lseek(fd, 0L, 2);
  187.         if (len > hdr->Val) {
  188.         close(fd);
  189.         printf("Cont Error, local file is larger than remote!: %s\n",
  190.            hdr->Str
  191.         );
  192.         puts("(not downloaded)");
  193.         return(0);
  194.         }
  195.         if (len == hdr->Val) {
  196.         close(fd);
  197.         if (error = WriteHeader('S', NULL, 0))
  198.             return(LostChannel());
  199.         puts("HAVE IT, SKIP");
  200.         return(0);
  201.         }
  202.         printf("(HAVE %ld/%ld) ", len, hdr->Val);
  203.         hdr->Val -= len;        /*  that much less  */
  204.         pos = len;            /*  start at offset */
  205.     }
  206.     }
  207.     if (fd < 0) {
  208.     fd = open(hdr->Str, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  209.     if (fd < 0) {
  210.         error = WriteHeader('N', "open error", 0);
  211.         printf("Unable to open %s for output\n", hdr->Str);
  212.         if (error)
  213.         return(LostChannel());
  214.         return(1);
  215.     }
  216.     }
  217.     error = WriteHeader('Y', NULL, pos);    /*  yes, gimme gimme    */
  218.  
  219.     /*
  220.      *    Retrieve the data
  221.      */
  222.  
  223.     if (!error) {
  224.     register long left = hdr->Val;
  225.     register long cnt = pos;
  226.     long total = pos + left;
  227.  
  228.     printf("             ");
  229.     while (left) {
  230.         register long n = (left > sizeof(Buf)) ? sizeof(Buf) : left;
  231.         printf("%s%6ld/%6ld", BSSTR, cnt, total);
  232.         fflush(stdout);
  233.         if (ggread(Chan, Buf, n) != n) {
  234.         error = 5;
  235.         break;
  236.         }
  237.         if (write(fd, Buf, n) != n) {
  238.         puts("Local Write failed!");
  239.         error = 6;
  240.         break;
  241.         }
  242.         left -= n;
  243.         cnt += n;
  244.     }
  245.     printf("%s%6ld/%6ld  %s", BSSTR, cnt, total, 
  246.         ((cnt == total) ? "OK" : "INCOMPLETE")
  247.     );
  248.     }
  249.     puts("");
  250.     if (error) {
  251.     fchmod(fd, 0222);
  252.     close(fd);
  253.     return(LostChannel());
  254.     }
  255.     close(fd);
  256.     return(error);
  257. }
  258.  
  259. /*
  260.  *  Retrieve a directory.  Create it if necessary.
  261.  */
  262.  
  263. GetDir(hdr, stab)
  264. HDR *hdr;
  265. {
  266.     short error = 0;
  267.     long dirlock;
  268.     static HDR Hdr;        /*    note: static */
  269.     char svpath[1024];
  270.  
  271.     printf("%s%-20s(DIR)\n", NSpaces(stab), hdr->Str);
  272.     getwd(svpath);
  273.     if (chdir(hdr->Str) < 0) {
  274.     mkdir(hdr->Str, 0777);
  275.     if (chdir(hdr->Str) < 0) {
  276.         error = WriteHeader('N', "couldn't create", 0);
  277.         printf("Unable to create local directory: %s\n", hdr->Str);
  278.         if (error)
  279.             return(LostChannel());
  280.         return(1);
  281.     }
  282.     }
  283.     error = WriteHeader('Y', NULL, 0);  /*  yes, gimme gimme    */
  284.     while (!error) {
  285.     switch(ReadHeader(&Hdr)) {
  286.     case -1:
  287.         error = 1;
  288.         break;
  289.     case 'E':                   /*  end of directory    */
  290.         chdir(svpath);
  291.         return(0);
  292.         break;
  293.     case 'F':
  294.         error = CheckNoPath(Hdr.Str);
  295.         if (!error) {
  296.         char svpath2[1024];
  297.         getwd(svpath2);
  298.         error = GetFile(&Hdr, stab + 4);
  299.         chdir(svpath2);
  300.         }
  301.         break;
  302.     case 'D':
  303.         error = CheckNoPath(Hdr.Str);
  304.         if (!error) {
  305.         char svpath2[1024];
  306.         getwd(svpath2);
  307.         error = GetDir(&Hdr, stab + 4);
  308.         chdir(svpath2);
  309.         }
  310.         break;
  311.     case 'S':
  312.         printf("Access Violation: %s\n", Hdr.Str);
  313.         break;
  314.     case 'N':
  315.         printf("REMOTE ERROR: %s\n", Hdr.Str);
  316.         error = 10;
  317.         break;
  318.     default:
  319.         error = UnknownCmd(&Hdr);
  320.         break;
  321.     }
  322.     }
  323.     chdir(svpath);
  324.     return(LostChannel());
  325. }
  326.  
  327. WriteHeader(c, str, len)
  328. char c;
  329. char *str;
  330. long len;
  331. {
  332.     ubyte sl;
  333.  
  334.     if (str == NULL)
  335.     str = "";
  336.     sl = strlen(str);
  337.  
  338.     if (gwrite(Chan, &c, 1) < 0)
  339.     return(1);
  340.     if (gwrite(Chan, &sl,1) < 0)
  341.     return(1);
  342.     if (gwrite(Chan, str, sl) != sl)
  343.     return(1);
  344.     len = htonl68(len);
  345.     if (gwrite(Chan, &len, 4) != 4)
  346.     return(1);
  347.     return(0);
  348. }
  349.  
  350. ReadHeader(hdr)
  351. HDR *hdr;
  352. {
  353.     ubyte sl;
  354.     ubyte cmd;
  355.  
  356.     hdr->Cmd = -1;
  357.     if (ggread(Chan, &cmd, 1) != 1)
  358.     return(-1);
  359.     if (ggread(Chan, &sl, 1) != 1)
  360.     return(-1);
  361.     if (sl >= sizeof(hdr->Str)) {
  362.     puts("Software error: received file name length too long");
  363.     return(-1);
  364.     }
  365.     if (ggread(Chan, hdr->Str, sl) != sl)
  366.     return(-1);
  367.     hdr->Str[sl] = 0;
  368.     if (ggread(Chan, &hdr->Val, 4) != 4)
  369.     return(-1);
  370.     hdr->Val = ntohl68(hdr->Val);
  371.     hdr->Cmd = cmd;
  372.     return(hdr->Cmd);
  373. }
  374.  
  375. char *
  376. NSpaces(n)
  377. short n;
  378. {
  379.     static char Buf[128];
  380.     static short in = 0;
  381.     static short last;
  382.  
  383.     if (in == 0) {
  384.     register short i;
  385.     in = 1;
  386.     for (i = 0; i < sizeof(Buf); ++i)
  387.         Buf[i] = ' ';
  388.     }
  389.     Buf[last] = ' ';
  390.     if (n < 127)
  391.     Buf[n] = 0;
  392.     last = n;
  393.     return(Buf);
  394. }
  395.  
  396.