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

  1.  
  2. /*
  3.  *  SGCOPY.C     V1.1
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  GET-COPY SERVER    (NEW COPY SERVER)
  8.  *
  9.  *  The current version only accepts one connection at a time.    This server
  10.  *  will send requested files to the remote machine.
  11.  *
  12.  *  length in 68000 longword format.
  13.  *
  14.  *  ACCESS RESTRICTIONS:
  15.  *
  16.  *    Remote access restrictions are according to DNET_GROUP or DNET_READ
  17.  *
  18.  *    DNET_READ >= 9        Full Access
  19.  *    DNET_READ <  9        According to comment field (AC=n) or group acc.
  20.  *                (GR=n) matches DNET_GROUP)
  21.  *
  22.  *    When searching for access rights, the comment field of the file/dir
  23.  *    requested is checked first.  If empty, the parent dir is checked.
  24.  *    This continues (parent diring) until root is found or a comment
  25.  *    field with access info in it.
  26.  */
  27.  
  28. #include <local/typedefs.h>
  29. #include <stdio.h>
  30. #include <fcntl.h>
  31. #include "servers.h"
  32.  
  33.  
  34. typedef struct {
  35.     char    Cmd;
  36.     char    Str[64];
  37.     long    Val;
  38. } HDR;
  39.  
  40.  
  41. int Enable_Abort;
  42. char Buf[8192];
  43. long Chan;
  44.  
  45. extern struct MsgPort *DListen();
  46.  
  47. _main()
  48. {
  49.     struct MsgPort *port;
  50.     PROC    *myproc = (PROC *)FindTask(NULL);
  51.     long    savedir;
  52.     long    mask, rmask;
  53.  
  54.     Enable_Abort = 0;
  55.     if (myproc->pr_CLI) {
  56.     Version("SGCopy", VERSION, SGCOPY_VERSION);
  57.     _exit(0);
  58.     }
  59.  
  60.     port = DListen(PORT_GFILECOPY);
  61.     WaitPort(&myproc->pr_MsgPort);
  62.     ReplyMsg(GetMsg(&myproc->pr_MsgPort));
  63.     savedir = Lock("", SHARED_LOCK);   /* duplicate current dir    */
  64.     if (!savedir) {
  65.     DUnListen(port);
  66.     _exit(1);
  67.     }
  68.     savedir = CurrentDir(savedir);              /* CD dup, returns original */
  69.     mask = SIGBREAKF_CTRL_C|(1 << port->mp_SigBit);
  70.     for (;;) {
  71.     long dupdir = DupLock(myproc->pr_CurrentDir);
  72.     rmask = Wait(mask);
  73.     if (rmask & SIGBREAKF_CTRL_C) {
  74.         UnLock(CurrentDir(dupdir));
  75.         break;
  76.     }
  77.     while (Chan = DAccept(port)) {
  78.         SGCopy();
  79.         DClose(Chan);
  80.     }
  81.     UnLock(CurrentDir(dupdir));
  82.     }
  83.     UnLock(CurrentDir(savedir));                /* restore original         */
  84.     DUnListen(port);
  85. }
  86.  
  87. SGCopy()
  88. {
  89.     short error;
  90.     static HDR Hdr;
  91.  
  92.     error = WriteHeader('H', "Hello, GCopy server V1.30", 0);
  93.     if (error)
  94.     return(error);
  95.     switch(ReadHeader(&Hdr)) {
  96.     case -1:
  97.     return(error);
  98.     case 'H':
  99.     break;
  100.     }
  101.     while (!error) {
  102.     switch(ReadHeader(&Hdr)) {
  103.     case 'G':
  104.         error = PutObject(Hdr.Str);
  105.         break;
  106.     case 'E':
  107.         goto done;
  108.     case 'P':   /*  put-files, not implemented  */
  109.     default:
  110.         error = 1;
  111.         break;
  112.     }
  113.     }
  114. done:
  115.     ;
  116. }
  117.  
  118. PutObject(str)
  119. char *str;
  120. {
  121.     long lock;
  122.     FIB *fib = malloc(sizeof(FIB));
  123.     short error = 0;
  124.     short access = GetEnvVal(DNET_READ);
  125.     short group  = GetEnvVal(DNET_GROUP);
  126.  
  127.     mountrequest(0);
  128.     lock = Lock(str, SHARED_LOCK);
  129.     mountrequest(1);
  130.     if (lock == NULL || !Examine(lock, fib)) {     /*  unable to find it!  */
  131.     error = WriteHeader('N', "Unable to find object", 0);
  132.     goto done;
  133.     }
  134.  
  135.     /*
  136.      *    Determine Access rights
  137.      *
  138.      *    If the file/dir or any parent dir has AC > your_ac, access is
  139.      *    denied.  If the file/dir and all parent dirs have neither an ACcess
  140.      *    or GRoup entry, access is denied.  If a group entry is found that
  141.      *    matches your group, access is allowed (unless an AC is found > your_ac)
  142.      *
  143.      *    If your_ac is >= 9, no access checking of parent directories is
  144.      *    done at all.  However, access checking of downloaded files will
  145.      *    be done, and any AC values > your_ac will be disalloweds.
  146.      */
  147.  
  148.     if (access < 9) {           /*  must check comment/access   */
  149.     short ok = 0;
  150.     long lock2 = DupLock(lock);
  151.     long tmp;
  152.     for (;;) {
  153.         short ac = 0;
  154.  
  155.         while (ac >= 0) {       /*  check groups    */
  156.         short idx = 0;
  157.         ac = ExtractFieldVal(fib->fib_Comment, FS_GROUP, &idx);
  158.         if (ac >= 0 && ac == group) {
  159.             ok = 1;
  160.             break;
  161.         }
  162.         }
  163.         ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
  164.         if (ac >= 0) {                  /*  valid access field      */
  165.         if (ac <= access) {         /*  access ok               */
  166.             ok = 1;
  167.         } else {            /*    access not ok        */
  168.             ok = 0;
  169.             break;
  170.         }
  171.         }
  172.         if (tmp = ParentDir(lock2)) {   /*  check the par.dir */
  173.         UnLock(lock2);
  174.         lock2 = tmp;
  175.         fib->fib_Comment[0] = 0;
  176.         Examine(lock2, fib);
  177.         continue;
  178.         }
  179.         break;
  180.     }
  181.     UnLock(lock2);
  182.     if (!ok) {
  183.         error = WriteHeader('N', "Access Violation", 0);
  184.         goto done;
  185.     }
  186.     }
  187.     Examine(lock, fib);
  188.     UnLock(lock);
  189.     lock = NULL;
  190.     if (fib->fib_DirEntryType > 0) {
  191.     error = PutDir(str, access);
  192.     } else {
  193.     error = PutFile(str, access);
  194.     }
  195. done:
  196.     if (lock)
  197.     UnLock(lock);
  198.     free(fib);
  199.     return(error);
  200. }
  201.  
  202. PutDir(name, access)
  203. char *name;
  204. {
  205.     long lock = Lock(name, SHARED_LOCK);
  206.     FIB *fib = malloc(sizeof(FIB));
  207.     static HDR Hdr;
  208.     short error = 0;
  209.     short ac;
  210.  
  211.     if (!lock || !Examine(lock, fib)) {
  212.     WriteHeader('N', "Possible Disk Error", 0);
  213.     error = 1;
  214.     goto done;
  215.     }
  216.  
  217.     ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
  218.     if (ac >= 0 && ac > access) {
  219.     error = WriteHeader('S', fib->fib_FileName, 0);
  220.     goto done;
  221.     }
  222.  
  223.     if (error = WriteHeader('D', fib->fib_FileName, 0))
  224.     goto done;
  225.     switch(ReadHeader(&Hdr)) {
  226.     case 'Y':
  227.     break;
  228.     case 'S':
  229.     goto done;
  230.     case 'N':
  231.     error = 1;
  232.     break;
  233.     default:
  234.     error = 1;
  235.     break;
  236.     }
  237.     if (error)
  238.     goto done;
  239.     while (ExNext(lock, fib)) {     /*  try to give him the files   */
  240.     if (fib->fib_DirEntryType > 0) {
  241.         long oldlock = CurrentDir(lock);
  242.         error = PutDir(fib->fib_FileName, access);
  243.         CurrentDir(oldlock);
  244.         if (error)
  245.         break;
  246.     } else {
  247.         long oldlock = CurrentDir(lock);
  248.         error = PutFile(fib->fib_FileName, access);
  249.         CurrentDir(oldlock);
  250.         if (error)
  251.         break;
  252.     }
  253.     }
  254.     if (!error)
  255.     WriteHeader('E', "Possible Disk Error", 0);
  256. done:
  257.     free(fib);
  258.     if (lock)
  259.     UnLock(lock);
  260.     return(error);
  261. }
  262.  
  263. PutFile(name, access)
  264. char *name;
  265. {
  266.     long lock = Lock(name, SHARED_LOCK);
  267.     long fh = NULL;
  268.     FIB *fib = malloc(sizeof(FIB));
  269.     static HDR Hdr;
  270.     long len;
  271.     short error = 0;
  272.     short ac;
  273.  
  274.     if (!lock || !Examine(lock, fib)) {
  275.     WriteHeader('N', "Possible Disk Error", 0);
  276.     error = 1;
  277.     goto done;
  278.     }
  279.  
  280.     ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
  281.     if (ac >= 0 && ac > access) {
  282.     error = WriteHeader('S', fib->fib_FileName, 0);
  283.     goto done;
  284.     }
  285.  
  286.     fh = Open(name, 1005);
  287.     if (fh == NULL)         /*  don't do anything if unable to open it */
  288.     goto done;
  289.     Seek(fh, 0L, 1);
  290.     len = Seek(fh, 0L, 0);
  291.     if (error = WriteHeader('F', fib->fib_FileName, len))
  292.     goto done;
  293.     switch(ReadHeader(&Hdr)) {
  294.     case 'Y':
  295.     Seek(fh, Hdr.Val, -1);  /*  start pos.  */
  296.     len -= Hdr.Val;
  297.     if (len < 0)
  298.         len = 0;
  299.     break;
  300.     case 'S':
  301.     goto done;
  302.     case 'N':
  303.     error = 1;
  304.     break;
  305.     default:
  306.     error = 1;
  307.     break;
  308.     }
  309.     if (error)
  310.     goto done;
  311.     while (len) {
  312.     register long n = (len > sizeof(Buf)) ? sizeof(Buf) : len;
  313.  
  314.     if (Read(fh, Buf, n) != n) {    /*  read failed! */
  315.         error = 10;
  316.         goto done;
  317.     }
  318.     if (DWrite(Chan, Buf, n) != n) {
  319.         error = 10;
  320.         goto done;
  321.     }
  322.     len -= n;
  323.     }
  324. done:
  325.     free(fib);
  326.     if (fh)
  327.     Close(fh);
  328.     if (lock)
  329.     UnLock(lock);
  330.     return(error);
  331. }
  332.  
  333.  
  334. WriteHeader(c, str, len)
  335. char c;
  336. char *str;
  337. long len;
  338. {
  339.     ubyte sl;
  340.  
  341.     if (str == NULL)
  342.     str = "";
  343.     sl = strlen(str);
  344.  
  345.     if (DWrite(Chan, &c, 1) < 0)
  346.     return(1);
  347.     if (DWrite(Chan, &sl,1) < 0)
  348.     return(1);
  349.     if (DWrite(Chan, str, sl) != sl)
  350.     return(1);
  351.     if (DWrite(Chan, &len, 4) != 4)
  352.     return(1);
  353.     return(0);
  354. }
  355.  
  356. ReadHeader(hdr)
  357. HDR *hdr;
  358. {
  359.     ubyte sl;
  360.     ubyte cmd;
  361.  
  362.     hdr->Cmd = -1;
  363.     if (DRead(Chan, &cmd, 1) != 1)
  364.     return(-1);
  365.     if (DRead(Chan, &sl, 1) != 1)
  366.     return(-1);
  367.     if (sl >= sizeof(hdr->Str)) {
  368.     return(-1);
  369.     }
  370.     if (DRead(Chan, hdr->Str, sl) != sl)
  371.     return(-1);
  372.     hdr->Str[sl] = 0;
  373.     if (DRead(Chan, &hdr->Val, 4) != 4)
  374.     return(-1);
  375.     hdr->Cmd = cmd;
  376.     return(hdr->Cmd);
  377. }
  378.  
  379.  
  380.