home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 239.lha / Unix2src.shar / server / sgcopy.c < prev    next >
C/C++ Source or Header  |  1989-05-02  |  5KB  |  330 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.  
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <sys/wait.h>
  18. #include <sys/time.h>
  19. #include <sys/dir.h>
  20. #include <sys/file.h>
  21. #include <sys/resource.h>
  22. #include <stdio.h>
  23. #include <errno.h>
  24. #include <signal.h>
  25.  
  26. #include "servers.h"
  27.  
  28. typedef struct {
  29.     char    Cmd;
  30.     char    Str[64];
  31.     long    Val;
  32. } HDR;
  33.  
  34. typedef unsigned char ubyte;
  35. char *getnamepart();
  36. char *getdirpart();
  37.  
  38. char Buf[4096];
  39. int Chan;
  40.  
  41. chandler()
  42. {
  43.     union wait stat;
  44.     struct rusage rus;
  45.     while (wait3(&stat, WNOHANG, &rus) > 0);
  46. }
  47.  
  48. main(ac,av)
  49. char *av[];
  50. {
  51.     long chann = DListen(PORT_GFILECOPY);
  52.     int fd;
  53.     int n;
  54.     char buf[256];
  55.     extern int errno;
  56.  
  57.     if (av[1])
  58.     chdir(av[1]);
  59.     signal(SIGCHLD, chandler);
  60.     signal(SIGPIPE, SIG_IGN);
  61.     for (;;) {
  62.     fd = DAccept(chann);
  63.     if (fd < 0) {
  64.         if (errno == EINTR)
  65.         continue;
  66.         break;
  67.     }
  68.     if (fork() == NULL) {
  69.         SGCopy(fd);
  70.         _exit(1);
  71.     }
  72.     close(fd);
  73.     }
  74.     perror("SCOPY");
  75. }
  76.  
  77. SGCopy(fd)
  78. int fd;
  79. {
  80.     short error = 0;
  81.     static HDR Hdr;
  82.  
  83.     Chan = fd;
  84.     error = WriteHeader('H', "Hello, GCopy server V1.30", 0);
  85.     if (error)
  86.     return(error);
  87.     switch(ReadHeader(&Hdr)) {
  88.     default:
  89.     case -1:
  90.     error = 1;
  91.     return(error);
  92.     case 'H':
  93.     break;
  94.     }
  95.     while (!error) {
  96.     switch(ReadHeader(&Hdr)) {
  97.     case 'G':
  98.         {
  99.         char svdir[1024];
  100.         getwd(svdir);
  101.         if (chdir(getdirpart(Hdr.Str)) < 0) {
  102.             error = WriteHeader('N', "Unable to cd to dir", 0);
  103.         } else {
  104.                 error = PutObject(getnamepart(Hdr.Str));
  105.         }
  106.         chdir(svdir);
  107.         }
  108.         break;
  109.     case 'E':
  110.         goto done;
  111.     case 'P':   /*  put-files, not implemented  */
  112.     default:
  113.         error = 1;
  114.         break;
  115.     }
  116.     }
  117. done:
  118.     ;
  119. }
  120.  
  121. PutObject(str)
  122. char *str;
  123. {
  124.     struct stat stat;
  125.     short error = 0;
  126.  
  127.     if (lstat(str, &stat) < 0) {
  128.     error = WriteHeader('N', "Unable to find object", 0);
  129.     return(0);
  130.     }
  131.     if (stat.st_mode & S_IFDIR) {
  132.     error = PutDir(str);
  133.     } else {
  134.     error = PutFile(str);
  135.     }
  136.     return(0);
  137. }
  138.  
  139. PutDir(name)
  140. char *name;
  141. {
  142.     struct stat stat;
  143.     char svdir[1024];
  144.     static HDR Hdr;
  145.     short error = 0;
  146.     char *fn = getnamepart(name);
  147.     DIR *dir;
  148.     struct direct *de;
  149.  
  150.     if (lstat(name, &stat) < 0 || !(dir = opendir(name))) {
  151.     WriteHeader('N', "Possible Disk Error", 0);
  152.     error = 1;
  153.     goto done;
  154.     }
  155.     if (error = WriteHeader('D', fn, 0)) 
  156.     goto done;
  157.     switch(ReadHeader(&Hdr)) {
  158.     case 'Y':
  159.     break;
  160.     case 'S':
  161.     goto done;
  162.     case 'N':
  163.     error = 1;
  164.     break;
  165.     default:
  166.     error = 1;
  167.     break;
  168.     }
  169.     if (error)
  170.     goto done;
  171.  
  172.     getwd(svdir);
  173.     if (chdir(name) < 0) {
  174.     error = 1;
  175.     WriteHeader('N', "unable to chdir", 0);
  176.     }
  177.     if (error)
  178.     goto done;
  179.  
  180.     while (de = readdir(dir)) {
  181.     if (strcmp(de->d_name, ".") == 0)
  182.         continue;
  183.     if (strcmp(de->d_name, "..") == 0)
  184.         continue;
  185.     if (lstat(de->d_name, &stat) < 0) {
  186.         continue;
  187.     }
  188.     if (stat.st_mode & S_IFDIR) {
  189.         error = PutDir(de->d_name);
  190.     } else {
  191.         error = PutFile(de->d_name);
  192.     }
  193.     if (error)
  194.         break;
  195.     }
  196.     WriteHeader('E', NULL, 0);
  197.     chdir(svdir);
  198. done:
  199.     return(error);
  200. }
  201.  
  202. PutFile(name)
  203. char *name;
  204. {
  205.     int fd = -1;
  206.     static HDR Hdr;
  207.     long len;
  208.     short error = 0;
  209.     char *fn = getnamepart(name);
  210.  
  211.     fd = open(fn, O_RDONLY, 0);
  212.     if (fd < 0) {       /*  don't do anything if unable to open it */
  213.     WriteHeader('N', "file not readable", 0);
  214.     goto done;
  215.     }
  216.     len = lseek(fd, 0L, 2);
  217.     if (error = WriteHeader('F', fn, len))
  218.     goto done;
  219.     switch(ReadHeader(&Hdr)) {
  220.     case 'Y':
  221.     lseek(fd, Hdr.Val, 0);  /*  start pos.  */
  222.     len -= Hdr.Val;
  223.     if (len < 0)
  224.         len = 0;
  225.     break;
  226.     case 'S':
  227.     goto done;
  228.     case 'N':
  229.     error = 1;
  230.     break;
  231.     default:
  232.     error = 1;
  233.     break;
  234.     }
  235.     if (error)
  236.     goto done;
  237.     while (len) {
  238.     register long n = (len > sizeof(Buf)) ? sizeof(Buf) : len;
  239.  
  240.     if (read(fd, Buf, n) != n) {    /*  read failed! */
  241.         error = 10;
  242.         goto done;
  243.     }
  244.     if (gwrite(Chan, Buf, n) != n) {
  245.         error = 10;
  246.         goto done;
  247.     }
  248.     len -= n;
  249.     }
  250. done:
  251.     if (fd >= 0)
  252.     close(fd);
  253.     return(error);
  254. }
  255.  
  256.  
  257. WriteHeader(c, str, len)
  258. char c;
  259. char *str;
  260. long len;
  261. {
  262.     ubyte sl;
  263.  
  264.     if (str == NULL)
  265.     str = "";
  266.     sl = strlen(str);
  267.  
  268.     if (gwrite(Chan, &c, 1) < 0)
  269.     return(1);
  270.     if (gwrite(Chan, &sl,1) < 0)
  271.     return(1);
  272.     if (gwrite(Chan, str, sl) != sl)
  273.     return(1);
  274.     len = htonl68(len);
  275.     if (gwrite(Chan, &len, 4) != 4)
  276.     return(1);
  277.     return(0);
  278. }
  279.  
  280. ReadHeader(hdr)
  281. HDR *hdr;
  282. {
  283.     ubyte sl;
  284.     ubyte cmd;
  285.  
  286.     hdr->Cmd = -1;
  287.     if (ggread(Chan, &cmd, 1) != 1)
  288.     return(-1);
  289.     if (ggread(Chan, &sl, 1) != 1)
  290.     return(-1);
  291.     if (sl >= sizeof(hdr->Str)) {
  292.     return(-1);
  293.     }
  294.     if (ggread(Chan, hdr->Str, sl) != sl)
  295.     return(-1);
  296.     hdr->Str[sl] = 0;
  297.     if (ggread(Chan, &hdr->Val, 4) != 4)
  298.     return(-1);
  299.     hdr->Val = ntohl68(hdr->Val);
  300.     hdr->Cmd = cmd;
  301.     return(hdr->Cmd);
  302. }
  303.  
  304. char *
  305. getnamepart(str)
  306. char *str;
  307. {
  308.     register char *ptr = str + strlen(str);
  309.  
  310.     while (ptr >= str) {
  311.     if (*ptr == '/')
  312.         break;
  313.     --ptr;
  314.     }
  315.     return(ptr+1);
  316. }
  317.  
  318. char *
  319. getdirpart(str)
  320. char *str;
  321. {
  322.     static char buf[1024];
  323.  
  324.     strcpy(buf, str);
  325.     getnamepart(buf)[0] = 0;
  326.     if (buf[0] == 0)
  327.     return(".");
  328.     return(buf);
  329. }
  330.