home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / networking / dnet / dnet2.3.2 / amiga / client / getfiles.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-29  |  11.0 KB  |  521 lines

  1. /*
  2.  *  GETFILES.C        V1.30
  3.  *
  4.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  5.  *
  6.  *
  7.  *  GETFILES [-Nnetid] [-dlocaldir] [-c] file/dir file/dir file/dir
  8.  *
  9.  *  -Nnetid    network identifier
  10.  *
  11.  *  -dlocaldir    local directory to place files
  12.  *
  13.  *  -c        Continue from where you left off before.  Files that already
  14.  *        exist on the local machine will not be re-transfered.  This
  15.  *        will also re-start in the middle of a file that was
  16.  *        partially transfered previously.
  17.  *
  18.  *        This command assumes the file(s) on both machines have not
  19.  *        been modified since the first attempt.    No other checking
  20.  *        is done at the moment.
  21.  */
  22.  
  23. #include "defs.h"
  24.  
  25.  
  26. typedef struct {
  27.     char    Cmd;
  28.     char    Str[128];
  29.     long    Val;
  30. } HDR;
  31.  
  32. #ifdef DEBUG
  33. #define IFDEBUG(foo) foo
  34. #else
  35. #define IFDEBUG(foo) 
  36. #endif
  37.  
  38.  
  39. #ifndef __GNUC__
  40. extern int Enable_Abort;
  41. #endif
  42.  
  43. char Buf[4096];
  44.  
  45. short ContMode;
  46. char  *NetId;
  47. long  LocalDirLock;
  48. void *Chan;
  49.  
  50. void fail ARGS((int));
  51. int CheckNoPath ARGS((char *));
  52. int LostChannel ARGS((int));
  53. void UnknownCmd ARGS((HDR *));
  54. int GetFile ARGS((HDR *, int));
  55. int GetDir ARGS((HDR *, int));
  56. int WriteHeader ARGS((char, char *, long));
  57. int ReadHeader ARGS((HDR *));
  58. char *NSpaces ARGS((int));
  59. int CheckBreak ARGS((void));
  60. void ResetBreak ARGS((void));
  61.  
  62. #ifdef MEM_DEBUG
  63. void AllFree();
  64. #endif
  65. int brk()
  66. {
  67.     return(0);
  68. }
  69.  
  70.  
  71. main(ac,av)
  72. int ac;
  73. char *av[];
  74. {
  75.     HDR Hdr;
  76.     short error;
  77.  
  78.     onbreak(brk);
  79. #if !defined( LATTICE) && !defined(__GNUC__)
  80.     Enable_Abort = 0;
  81. #endif
  82. #ifdef MEM_DEBUG
  83.     atexit(AllFree);
  84. #endif
  85.     printf("GetFiles V%s%s\n", VERSION, GETFILES_VERSION);
  86.     ResetBreak();
  87.     IFDEBUG(printf("Doing args, locking dir\n");sleep(1);)
  88.     {
  89.     char *ldir = "";
  90.     FIB *fib = malloc(sizeof(FIB));
  91.     if(fib == NULL){
  92.         fprintf(stderr, "Out of memory\n");
  93.         exit(0);
  94.     }
  95.     ac = DoOption(ac, av, "N%sd%sc", &NetId, &ldir, &ContMode);
  96.     IFDEBUG(printf("Options done\n");)
  97.     if (ac <= 1) {
  98.         puts("GETFILES [-Nnetid -dlocaldir -c] remotefile/dir ...");
  99.         fail(22);
  100.     }
  101.     LocalDirLock = Lock(ldir, SHARED_LOCK);
  102.     if (!LocalDirLock && ldir[0]) {     /*  couldn't find it, try to make it */
  103.         if (LocalDirLock = (long)CreateDir(ldir)) {
  104.         UnLock(LocalDirLock);
  105.         LocalDirLock = Lock(ldir, SHARED_LOCK);
  106.         }
  107.     }
  108.     if (!LocalDirLock || !Examine(LocalDirLock, fib) || fib->fib_DirEntryType < 0) {
  109.         printf("Unable to CD or create local directory: \"%s\"\n", ldir);
  110.         fail(21);
  111.     }
  112.     if(fib != NULL) free(fib);
  113.     }
  114.     IFDEBUG(printf("DOpen(%d)ing \n", PORT_GFILECOPY);sleep(1);)
  115.     Chan = DOpen(NetId, PORT_GFILECOPY, 126, -80);
  116.     if (!Chan) {
  117.     puts("Unable to connect");
  118.     fail(20);
  119.     }
  120.     IFDEBUG(printf("Net opened, saying hello\n");sleep(1);)
  121.     error = WriteHeader('H', "Hello, getfiles client V1.30", 0);
  122.     if (error)
  123.     fail(LostChannel(1));
  124.     IFDEBUG(printf("WroteHeader, Reading reply...\n");sleep(1);)
  125.     switch(ReadHeader(&Hdr)) {
  126.     case -1:
  127.     fail(LostChannel(2));
  128.     case 'H':
  129.     printf("%s\n", Hdr.Str);
  130.     break;
  131.     }
  132.     IFDEBUG(printf("ReadHeader, got Hello...\n");sleep(1);)
  133.     {
  134.     short i;
  135.  
  136.     for (i = 1; i < ac; ++i) {
  137.         short error;
  138.  
  139.             IFDEBUG(printf("WritingHdr(G, %s)\n", av[i]);sleep(1);)
  140.  
  141.         error = WriteHeader('G', av[i], 0);
  142.         if (error)
  143.         fail(LostChannel(3));
  144.         switch(ReadHeader(&Hdr)) {
  145.         case -1:
  146.         fail(LostChannel(4));
  147.         case 'N':
  148.         printf("Remote error on %s: %s\n", av[i], Hdr.Str);
  149.         break;
  150.         case 'F':
  151.         error = CheckNoPath(Hdr.Str);
  152.         if (!error) {
  153.             long olddir = (long)CurrentDir(LocalDirLock);
  154.             IFDEBUG(printf("Getting file...\n");)
  155.             error = GetFile(&Hdr, 0);
  156.             IFDEBUG(printf("Going back to old dir...\n");sleep(1);)
  157.             CurrentDir(olddir);
  158.         }
  159.         break;
  160.         case 'D':
  161.         error = CheckNoPath(Hdr.Str);
  162.         if (!error) {
  163.             long olddir = (long)CurrentDir(LocalDirLock);
  164.             error = GetDir(&Hdr, 0);
  165.             CurrentDir(olddir);
  166.         }
  167.         break;
  168.         case 'S':
  169.         printf("Access Violation: %s\n", Hdr.Str);
  170.         break;
  171.         default:
  172.         UnknownCmd(&Hdr);
  173.         error = 1;
  174.         break;
  175.         }
  176.             IFDEBUG(printf("Done with that, err: %d\n", error);)
  177.         if (error)
  178.         fail(error);
  179.     }
  180.     IFDEBUG(printf("Done with args, saying bye..\n");)
  181.     if (!error) {
  182.         error = WriteHeader('E', "bye", 0);
  183.         if (error)
  184.         fail(LostChannel(5));
  185.     }
  186.     IFDEBUG(printf("Done with everything, closing..\n");)
  187.     }
  188.  
  189.     IFDEBUG(printf("Done closing, bye!\n");)
  190.     fail(0);
  191. }
  192.  
  193. void
  194. fail(int code)
  195. {
  196.     IFDEBUG(printf("failing, code %d\n", code);sleep(1);)
  197.     IFDEBUG(if(code == 0) code++;)
  198.  
  199.     if (Chan){
  200.     if(code){printf("Attempting to close DNet channel...\n"); sleep(1);}
  201.     DClose(Chan);
  202.     if(code){printf("Whew, that worked...\n");sleep(1);}
  203.     }
  204.     if (LocalDirLock){
  205.     if(code){printf("UnLock()ing LocalDir...\n");sleep(1);}
  206.     UnLock(LocalDirLock);
  207.     if(code){printf("Whew, that worked too.\n");sleep(1);}
  208.     }
  209.  
  210.     if(code)printf("OK, bye\n");
  211.  
  212.     exit(code);   /* AllFree gets called via atexit */
  213. }
  214.  
  215. int
  216. CheckNoPath(str)
  217. char *str;
  218. {
  219.     while (*str) {
  220.     if (*str == '/' || *str == ':') {
  221.         puts("SECURITY ALERT: Illegal path spec received");
  222.         return(40);
  223.     }
  224.     ++str;
  225.     }
  226.     return(0);
  227. }
  228.  
  229. int
  230. LostChannel(int point)
  231. {
  232.     printf("DATA CHANNEL LOST: %d\n", point);
  233.     return(10);
  234. }
  235.  
  236. void
  237. UnknownCmd(hdr)
  238. HDR *hdr;
  239. {
  240.     printf("UnRecognized command code: %02x\n", hdr->Cmd);
  241. }
  242.  
  243. /*
  244.  *  retrieve a file.  If ContMode set and file exists, try to append to
  245.  *  it.
  246.  */
  247.  
  248. int
  249. GetFile(hdr, stab)
  250. HDR *hdr;
  251. int stab;
  252. {
  253.     BPTR Fh = 0;
  254.     long pos = 0;
  255.     short error = 0;
  256.  
  257.     IFDEBUG(printf("GetFile( %s, %d)\n", hdr->Str, stab);)
  258.  
  259.     printf("%s%-20s ", NSpaces(stab), hdr->Str);
  260.     fflush(stdout);
  261.     if (ContMode) {
  262.     IFDEBUG(printf("ContMode\n");)
  263.     SetProtection(hdr->Str, 0);         /*  make sure it's r/w  */
  264.     if ((Fh = Open(hdr->Str, MODE_OLDFILE)) != 0) { /*  already exists  */
  265.         long len;
  266.         Seek(Fh, 0L, 1);
  267.         len = Seek(Fh, 0L, 0);          /*  get length      */
  268.         if (len > hdr->Val) {
  269.         Close(Fh);
  270.         printf("Cont Error, local file is larger than remote!: %s\n", hdr->Str);
  271.         puts("(not downloaded)");
  272.         return(0);
  273.         }
  274.         if (len == hdr->Val) {
  275.         Close(Fh);
  276.         if (error = WriteHeader('S', NULL, 0))
  277.             return(LostChannel(6));
  278.         puts("HAVE IT, SKIP");
  279.         return(0);
  280.         }
  281.         printf("(Append %ld/%ld) ", len, hdr->Val);
  282.         hdr->Val -= len;        /*  that much less  */
  283.         pos = len;            /*  start at offset */
  284.     }
  285.     }
  286.     IFDEBUG(printf("Getting\n");)
  287.     if (Fh == 0) {
  288.     Fh = Open(hdr->Str, MODE_NEWFILE);
  289.         IFDEBUG(printf("output file opened, handle %lx\n", Fh);)
  290.     if (Fh == 0) {
  291.         error = WriteHeader('N', "open error", 0);
  292.         printf("Unable to open %s for output\n", hdr->Str);
  293.         if (error)
  294.         return(LostChannel(7));
  295.         return(1);
  296.     }
  297.     }
  298.     IFDEBUG(printf("WriteHeader(Y)\n");)
  299.     error = WriteHeader('Y', NULL, pos);    /*  yes, gimme gimme    */
  300.  
  301.     /*
  302.      *    Retrieve the data
  303.      */
  304.  
  305.     IFDEBUG(printf("WriteHeader(y) result: %d\n", error);)
  306.     if (error == 0) {
  307.     long left = hdr->Val;
  308.     long cnt = pos;
  309.     long total = pos + left;
  310.     IFDEBUG(printf("Receiving file\n");)
  311.  
  312.     while (left) {
  313.         long n = (left > sizeof(Buf)) ? sizeof(Buf) : left;
  314.         printf("%8ld/%-8ld\23317D", cnt, total);
  315.         fflush(stdout);
  316.         IFDEBUG(printf("Starting DRead \n");sleep(1);)
  317.         if (DRead(Chan, Buf, n) != n) {
  318.         error = 5;
  319.         break;
  320.         }
  321.         IFDEBUG(printf("Done DRead \n");)
  322.         if (CheckBreak()) {
  323.         error = 1;
  324.         break;
  325.         }
  326.         IFDEBUG(printf("Writing data\n");)
  327.         if (Write(Fh, Buf, n) != n) {
  328.         puts("Local Write failed!");
  329.         error = 6;
  330.         break;
  331.         }
  332.         left -= n;
  333.         cnt += n;
  334.         if (CheckBreak()) {
  335.         error = 1;
  336.         break;
  337.         }
  338.         IFDEBUG(printf("Continuing receiving data\n");)
  339.     }
  340.     printf("%8ld/%-8ld  %s", cnt, total, ((cnt == total) ? "OK" : "INCOMPLETE"));
  341.     }
  342.     IFDEBUG(printf("Closing file (handle %lx)\n", Fh);sleep(1);)
  343.     Close(Fh);
  344.     IFDEBUG(printf("Closed\n");sleep(1);)
  345.     puts("");
  346.     if (error != 0) {
  347.     SetProtection(hdr->Str, 016);    /*  disallow reads/write/exec! */
  348.     IFDEBUG(printf("returning error\n");sleep(1);)
  349.     return(LostChannel(8));
  350.     }
  351.     IFDEBUG(printf("Done getting \n");)
  352.     return((int)error);
  353. }
  354.  
  355. /*
  356.  *  Retrieve a directory.  Create it if necessary.
  357.  */
  358.  
  359. int
  360. GetDir(hdr, stab)
  361. HDR *hdr;
  362. int stab;
  363. {
  364.     short error = 0;
  365.     long dirlock;
  366.     static HDR Hdr;        /*    note: static */
  367.  
  368.     if (CheckBreak())
  369.     return(1);
  370.     printf("%s%-20s(DIR)\n", NSpaces(stab), hdr->Str);
  371.     dirlock = Lock(hdr->Str, SHARED_LOCK);  /*  try to lock directory */
  372.     if (!dirlock) {
  373.     if (dirlock = (long)CreateDir(hdr->Str)) {
  374.         UnLock(dirlock);
  375.         dirlock = Lock(hdr->Str, SHARED_LOCK);
  376.     }
  377.     }
  378.     if (!dirlock) {
  379.     error = WriteHeader('N', "couldn't create", 0);
  380.     printf("Unable to create local directory: %s\n", hdr->Str);
  381.     if (error)
  382.         return(LostChannel(9));
  383.     return(1);
  384.     }
  385.     error = WriteHeader('Y', NULL, 0);  /*  yes, gimme gimme    */
  386.     while (!error) {
  387.     switch(ReadHeader(&Hdr)) {
  388.     case -1:
  389.         error = 1;
  390.         break;
  391.     case 'E':                   /*  end of directory    */
  392.         UnLock(dirlock);
  393.         return(0);
  394.         break;
  395.     case 'F':
  396.         error = CheckNoPath(Hdr.Str);
  397.         if (!error) {
  398.         long olddir = (long)CurrentDir(dirlock);
  399.         error = GetFile(&Hdr, stab + 4);
  400.         CurrentDir(olddir);
  401.         }
  402.         break;
  403.     case 'D':
  404.         error = CheckNoPath(Hdr.Str);
  405.         if (!error) {
  406.         long olddir = (long)CurrentDir(dirlock);
  407.         error = GetDir(&Hdr, stab + 4);
  408.         CurrentDir(olddir);
  409.         }
  410.         break;
  411.     case 'S':
  412.         printf("Access Violation: %s\n", Hdr.Str);
  413.         break;
  414.     case 'N':
  415.         printf("REMOTE ERROR: %s\n", Hdr.Str);
  416.         error = 10;
  417.         break;
  418.     default:
  419.         UnknownCmd(&Hdr);
  420.         error = 1;
  421.         break;
  422.     }
  423.     }
  424.     UnLock(dirlock);
  425.     return(LostChannel(10));
  426. }
  427.  
  428. int
  429. WriteHeader(c, str, len)
  430. char c;
  431. char *str;
  432. long len;
  433. {
  434.     ubyte sl;
  435.     char cmd = c;
  436.  
  437.     IFDEBUG(printf("Writing header %s \n", str);)
  438.  
  439.     if (str == NULL)
  440.     str = "";
  441.     sl = strlen(str);
  442.  
  443.     if (DWrite(Chan, &cmd, 1) < 0){
  444.     return(1);
  445.     }
  446.     if (DWrite(Chan, &sl,1) < 0){
  447.     return(2);
  448.     }
  449.     if (DWrite(Chan, str, sl) != sl){
  450.     return(3);
  451.     }
  452.     if (DWrite(Chan, &len, sizeof(long) ) != 4){
  453.     return(4);
  454.     }
  455.     return(0);
  456. }
  457.  
  458. int
  459. ReadHeader(hdr)
  460. HDR *hdr;
  461. {
  462.     ubyte sl;
  463.     ubyte cmd;
  464.  
  465.     hdr->Cmd = -1;
  466.     if (DRead(Chan, &cmd, 1) != 1)
  467.     return(-2);
  468.     if (DRead(Chan, &sl, 1) != 1)
  469.     return(-3);
  470.     if (sl >= sizeof(hdr->Str)) {
  471.     puts("Software error: received file name length too long");
  472.     return(-4);
  473.     }
  474.     if (DRead(Chan, hdr->Str, sl) != sl)
  475.     return(-5);
  476.     hdr->Str[sl] = 0;
  477.     if (DRead(Chan, &hdr->Val, sizeof(long) ) != 4)
  478.     return(-6);
  479.     hdr->Cmd = cmd;
  480.     return((int)hdr->Cmd);
  481. }
  482.  
  483. char *
  484. NSpaces(n)
  485. int n;
  486. {
  487.     static char Buf[128];
  488.     static short in = 0;
  489.     static short last;
  490.  
  491.     if (in == 0) {
  492.     in = 1;
  493.     BSet(Buf, sizeof(Buf)-1, ' ');
  494.     }
  495.     Buf[last] = ' ';
  496.     if (n < 127)
  497.     Buf[n] = 0;
  498.     last = n;
  499.     return(Buf);
  500. }
  501.  
  502. int
  503. CheckBreak()
  504. {
  505.     IFDEBUG(printf("SettingSignal\n");)
  506.     if (SetSignal(0,0) & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) {
  507.     puts("^C");
  508.     IFDEBUG(printf("SettingSignal done 1\n");)
  509.     return(1);
  510.     }
  511.     IFDEBUG(printf("SettingSignal done 0\n");)
  512.     return(0);
  513. }
  514.  
  515. void
  516. ResetBreak()
  517. {
  518.     SetSignal(0, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D);
  519. }
  520.  
  521.