home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 239.lha / amiga / src / client / getfiles.c < prev    next >
C/C++ Source or Header  |  1989-05-02  |  8KB  |  417 lines

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