home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / fsp / part03 / server_file.c
Encoding:
C/C++ Source or Header  |  1991-12-12  |  11.3 KB  |  404 lines

  1.     /*********************************************************************\
  2.     *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  3.     *                                                                     *
  4.     *  You may copy or modify this file in any manner you wish, provided  *
  5.     *  that this notice is always included, and that you hold the author  *
  6.     *  harmless for any loss or damage resulting from the installation or *
  7.     *  use of this software.                                              *
  8.     \*********************************************************************/
  9.  
  10. #include "server_def.h"
  11.  
  12. /*****************************************************************************
  13. * This file handles all file io in request to client requests.
  14. *****************************************************************************/
  15.  
  16. #define NBSIZE (2*sizeof(UBUF))
  17.  
  18. extern *malloc();
  19.  
  20. #define fexist(A) (!access(A,0))
  21. #define touch(A) close(open(A,O_CREAT,0777))
  22.  
  23. /*****************************************************************************
  24. * Routine to check a path string given by the client.
  25. * Will replace null string by ".".
  26. * In case of error, returns the error string.
  27. *****************************************************************************/
  28.  
  29. char *check_path(path,len)
  30.     char *path;
  31.     int len;
  32. {
  33.     char *s;
  34.     int state;
  35.  
  36.     if(len < 1) return("Path must have non-zero lenght");
  37.     if(len == 1 && path[0] == 0) { *path++ = '.'; *path = 0; return(NULLP); }
  38.     if(path[len-1]) return("Path not null terminated");
  39.  
  40.     for(s = path, state = 0; *s; s++)
  41.     {
  42.     if(*s <= ' ' || *s >= '~') return("Path contains illegal chars");
  43.  
  44.     switch(*s)
  45.     {
  46.         case '.': if(!state) return("Path can't begin with '.'");
  47.               break;
  48.  
  49.         case '/': if(!state) return("Path can't contain '//'");
  50.               state = 0;
  51.               break;
  52.  
  53.         default : state = 1;
  54.               break;
  55.     }
  56.     }
  57.  
  58.     return(NULLP);
  59. }
  60.  
  61. /*****************************************************************************
  62. * Put the directory name of path into dbuf.
  63. *****************************************************************************/
  64.  
  65. char *get_dir_name(path,dbuf)
  66.     char *path, *dbuf;
  67. {
  68.     char *p1,*p2,*p3;
  69.  
  70.     for(p1 = path, p2 = p3 = dbuf; *p1; p1++, p3++)
  71.     {
  72.     if((*p3 = *p1) == '/') p2 = p3;
  73.     }
  74.  
  75.     if(dbuf == p2) { dbuf[0] = '.'; dbuf[1] = 0; }
  76.           else { *p2 = 0;             }
  77.  
  78.     return(dbuf);
  79. }
  80.  
  81. /*****************************************************************************
  82. * Reads directory and write directory listing file.
  83. *****************************************************************************/
  84.  
  85. static build_dir_file(fp)
  86.     FILE *fp;
  87. {
  88.     int nlen, skip, rem;
  89.     DIR *dir_f;
  90.     struct dirent *dp;
  91.     struct stat    sb;
  92.     register char  *s;
  93.     RDIRENT rdb;
  94.     static char marker[] = "******************";
  95.  
  96.     if(!(dir_f = opendir(".")))    /* assume I have cd to path already */
  97.     { fprintf(stderr,"Can't open dir during initialization\n"); exit(1); }
  98.  
  99.     for(rem = UBUF_SPACE; dp = readdir(dir_f); )
  100.     {
  101.     if (dp->d_ino == 0) continue;
  102.     s = dp->d_name;
  103.                         /* hide dot files */
  104.     if((s[0] == '.') && ((s[1] !=  0 ) &&
  105.                  (s[1] != '.' || s[2] != 0))) continue;
  106.  
  107.     if(stat(dp->d_name,&sb)) continue;
  108.  
  109.     nlen = strlen(s)+1;
  110.  
  111.     if(rem < RDHSIZE + nlen)
  112.     {
  113.         rdb.type = RDTYPE_SKIP;
  114.         if(rem <= RDHSIZE) { fwrite(marker,1,rem    ,fp); }
  115.               else { fwrite(marker,1,RDHSIZE,fp);
  116.                  fwrite(s, 1,rem-RDHSIZE,fp); }
  117.         rem = UBUF_SPACE;
  118.     }
  119.  
  120.     rdb.type = ((S_IFDIR & sb.st_mode)) ? RDTYPE_DIR : RDTYPE_FILE;
  121.     rdb.size = htonl(sb.st_size);
  122.     rdb.time = htonl(sb.st_mtime);
  123.  
  124.     fwrite(&rdb,1,RDHSIZE,fp);
  125.     fwrite(s,1,nlen,fp);
  126.     rem -= (nlen + RDHSIZE);
  127.  
  128.     if((skip = (nlen + RDHSIZE) & 0x3))
  129.         { fwrite(&rdb,1,4-skip,fp); rem -= (4-skip); }
  130.  
  131.     if(!rem) rem = UBUF_SPACE;
  132.     }
  133.  
  134.     rdb.type = RDTYPE_END;
  135.     fwrite(&rdb,1,RDHSIZE,fp);
  136.  
  137.     fflush(fp);
  138.     closedir(dir_f);
  139. }
  140.  
  141. /***************************************************************************/
  142.  
  143. char *server_get_dir(path,fp)    /* assume path is validated */
  144.     char *path;            /* returned file may not point at BOF */
  145.     FILE **fp;
  146. {
  147.     struct stat sd, sf;
  148.     char   list_p[NBSIZE];
  149.  
  150.     if(!*path) path = ".";
  151.     if(stat(path,&sd)) return("Can't find directory");
  152.     if(!(S_IFDIR & sd.st_mode)) return("Not a directory");
  153.  
  154.     sprintf(list_p,"%s/.FSP_CONTENT",path);
  155.  
  156.     if(!stat(list_p,&sf) && (sf.st_mtime >= sd.st_mtime))
  157.     {
  158.     *fp = fopen(list_p,"r");
  159.     if(!*fp) return("Can't read directory listing");
  160.     return((char *)0);
  161.     }
  162.  
  163.     if(!(*fp = fopen(list_p,"w+"))) return("Can't create directory listing");
  164.     if(chdir(path)) return("Can't cd to directory");
  165.     build_dir_file(*fp);
  166.     if(chdir(home_dir) == -1) { perror("chdir2"); exit(1); }
  167.     return(NULLP);
  168. }
  169.  
  170. /**********************************************************************/
  171.  
  172. char *server_del_file(path,inet_num)        /* assume path is validated */
  173.     char *path;
  174.     unsigned long inet_num;
  175. {
  176.     struct stat sb;
  177.     char   dir_p[NBSIZE], no_del_p[NBSIZE], owner_p[NBSIZE];
  178.  
  179.     if(stat(path,&sb)) return("unlink: file not accessible");
  180.     if(!(S_IFREG & sb.st_mode)) return("unlink: not an ordinary file");
  181.  
  182.     get_dir_name(path,dir_p);
  183.     sprintf(owner_p ,"%s/.OWN.%08X"  ,dir_p,inet_num);
  184.     sprintf(no_del_p,"%s/.FSP_NO_DEL",dir_p         );
  185.  
  186.     if(!fexist(owner_p) && fexist(no_del_p))
  187.             return("no permission for removing this file");
  188.  
  189.     if(unlink(path) == -1) return("unlink: cannot unlink");
  190.  
  191.     return(NULLP);
  192. }
  193.  
  194. /**********************************************************************/
  195.  
  196. char *server_del_dir(path,inet_num)        /* assume path is validated */
  197.     char *path;
  198.     unsigned long inet_num;
  199. {
  200.     struct stat sb;
  201.     char   dir_p[NBSIZE], no_del_p[NBSIZE], no_add_p[NBSIZE], owner_p[NBSIZE];
  202.     int    has_no_del_p, has_no_add_p;
  203.  
  204.     if(stat(path,&sb)) return("rmdir: directory not accessible");
  205.     if(!(S_IFDIR & sb.st_mode)) return("rmdir: not an ordinary directory");
  206.  
  207.     get_dir_name(path,dir_p);
  208.     sprintf( owner_p,"%s/.OWN.%08X"  ,dir_p,inet_num);
  209.     sprintf(no_del_p,"%s/.FSP_NO_DEL",dir_p         );
  210.  
  211.     if(!fexist(owner_p) && fexist(no_del_p))
  212.             return("no permission for removing this directory");
  213.  
  214.     sprintf( owner_p,"%s/.OWN.%08X"   ,path,inet_num);
  215.     sprintf(   dir_p,"%s/.FSP_CONTENT",path         );
  216.     sprintf(no_del_p,"%s/.FSP_NO_DEL" ,path                );
  217.     sprintf(no_add_p,"%s/.FSP_NO_ADD" ,path                );
  218.  
  219.     if(!fexist(owner_p)) return("no permission for removing this directory");
  220.  
  221.     unlink(owner_p); unlink(  dir_p);
  222.     has_no_del_p = !unlink(no_del_p);
  223.     has_no_add_p = !unlink(no_add_p);
  224.  
  225.     if(rmdir(path) != 0)
  226.     {
  227.     if(has_no_del_p) touch(no_del_p);
  228.     if(has_no_add_p) touch(no_add_p);
  229.     if(     owner_p) touch( owner_p);
  230.     return("rmdir: cannot unlink");
  231.     }
  232.  
  233.     return(NULLP);
  234. }
  235.  
  236. /**********************************************************************/
  237.  
  238. char *server_make_dir(path,inet_num)        /* assume path is validated */
  239.     char *path;
  240.     unsigned long inet_num;
  241. {
  242.     char   dir_p[NBSIZE], no_del_p[NBSIZE], no_add_p[NBSIZE], owner_p[NBSIZE];
  243.  
  244.     get_dir_name(path,dir_p);
  245.     sprintf( owner_p,"%s/.OWN.%08X"  ,dir_p,inet_num);
  246.     sprintf(no_add_p,"%s/.FSP_NO_ADD",dir_p         );
  247.  
  248.     if(!fexist(owner_p) && fexist(no_add_p))
  249.             return("no permission for directory creation");
  250.  
  251.     sprintf( owner_p,"%s/.OWN.%08X"   ,path,inet_num);
  252.     sprintf(   dir_p,"%s/.FSP_CONTENT",path         );
  253.     sprintf(no_del_p,"%s/.FSP_NO_DEL" ,path         );
  254.     sprintf(no_add_p,"%s/.FSP_NO_ADD" ,path         );
  255.  
  256.     if(mkdir(path,0777) != 0) return("Can't create directory");
  257.  
  258.     touch(no_del_p);
  259.     touch(no_add_p);
  260.     touch( owner_p);
  261.     return(NULLP);
  262. }
  263.  
  264. /**********************************************************************/
  265.  
  266. char *server_get_file(path,fp)        /* assume path is validated */
  267.     char *path;
  268.     FILE **fp;
  269. {
  270.     struct stat sb;
  271.  
  272.     if(stat(path,&sb)) return("Can't find file");
  273.     if(!(S_IFREG & sb.st_mode)) return("Not a file");
  274.     if(!(*fp = fopen(path,"r"))) return("Can't open file");
  275.     return(NULLP);
  276. }
  277.  
  278. /**********************************************************************/
  279.  
  280. char *server_get_pro(s,inet_num)    /* s is both I and O */
  281.     char *s;
  282.     unsigned long inet_num;
  283. {
  284.     struct stat sb;
  285.     char   buf[NBSIZE];
  286.     char  *owner_s, *del_s, *add_s;
  287.  
  288.     if(stat(s,&sb)) return("getpro: directory not accessible");
  289.     if(!(S_IFDIR & sb.st_mode)) return("getpro: not an ordinary directory");
  290.  
  291.     sprintf(buf,"%s/.OWN.%08X",s,inet_num);
  292.     owner_s = (fexist(buf)) ? "your" : "some other";
  293.     sprintf(buf,"%s/.FSP_NO_DEL" ,s); del_s = (fexist(buf)) ? "NO" : "YES";
  294.     sprintf(buf,"%s/.FSP_NO_ADD" ,s); add_s = (fexist(buf)) ? "NO" : "YES";
  295.  
  296.     sprintf(s,"(owner: %s machine)(delete: %s)(create: %s)",
  297.                         owner_s, del_s, add_s);
  298.     return(NULLP);
  299. }
  300.  
  301. /**********************************************************************/
  302.  
  303. char *server_set_pro(path,key,inet_num)
  304.     char *path, *key;
  305.     unsigned long inet_num;
  306. {
  307.     struct stat sb;
  308.     char   buf[NBSIZE];
  309.  
  310.     if(stat(path,&sb)) return("getpro: directory not accessible");
  311.     if(!(S_IFDIR & sb.st_mode)) return("getpro: not an ordinary directory");
  312.  
  313.     sprintf(buf,"%s/.OWN.%08X",path,inet_num);
  314.     if(!fexist(buf)) return("no permission for changing the protection-mode");
  315.  
  316.     switch(key[1])
  317.     {
  318.     case 'c': sprintf(buf,"%s/.FSP_NO_ADD",path); break;
  319.     case 'd': sprintf(buf,"%s/.FSP_NO_DEL",path); break;
  320.     default : return("bad flag");
  321.     }
  322.  
  323.     switch(key[0])
  324.     {
  325.     case '-': touch(buf);  break;
  326.     case '+': unlink(buf); break;
  327.     default : return("bad flag");
  328.     }
  329.  
  330.     return(NULLP);
  331. }
  332.  
  333. /**********************************************************************
  334. *  These two are used for file uploading.
  335. **********************************************************************/
  336.  
  337. char *server_up_load(data,len,pos,inet_num)
  338.     char *data;
  339.     unsigned len;
  340.     unsigned long pos, inet_num;
  341. {
  342.     FILE *fp;
  343.     char  tname[NBSIZE];
  344.  
  345.     sprintf(tname,".TMP.%08X",inet_num);
  346.  
  347.     if(pos) {             fp = fopen(tname,"a"); }
  348.        else { unlink(tname); fp = fopen(tname,"w"); }
  349.  
  350.     if(!fp) return("Cannot open temporary file");
  351.  
  352.     fwrite(data, 1, len, fp);
  353.     fclose(fp);
  354.  
  355.     return(NULLP);
  356. }
  357.  
  358. char *server_install(path,inet_num)
  359.     char *path;
  360.     unsigned long inet_num;
  361. {
  362.     FILE *ft, *fp;
  363.     char   tname[NBSIZE], no_add_p[NBSIZE], owner_p[NBSIZE], buf[512];
  364.     int bytes;
  365.  
  366.     get_dir_name(path,tname);
  367.     sprintf( owner_p,"%s/.OWN.%08X"  ,tname,inet_num);
  368.     sprintf(no_add_p,"%s/.FSP_NO_ADD",tname         );
  369.     sprintf(tname,".TMP.%08X"        ,      inet_num);
  370.  
  371.     if(!fexist(owner_p) && fexist(no_add_p))
  372.     {
  373.     unlink(tname);
  374.     return("no permission for writting to that file");
  375.     }
  376.  
  377.     unlink(path);
  378.     if(link(tname,path) == 0) { unlink(tname); return(NULLP); }
  379.  
  380.     if(!(ft = fopen(tname,"r"))) { unlink(tname);
  381.                    return("Can't open temporary file"); }
  382.  
  383.     if(!(fp = fopen(path ,"w"))) { unlink(tname); fclose(ft);
  384.                    return("Can't open file for output"); }
  385.  
  386.     while(bytes = fread(buf,1,sizeof(buf),ft)) fwrite(buf,1,bytes,fp);
  387.  
  388.     fclose(ft); fclose(fp); unlink(tname); return(NULLP);
  389. }
  390.  
  391. /**********************************************************************/
  392.  
  393. init_home_dir()
  394. {
  395.     if(*home_dir != '/') { fprintf(stderr,"[%s] does not start with a /\n");
  396.                exit(1); }
  397.  
  398.     if(chdir(home_dir) == -1) { perror("chdir"); exit(1); }
  399.  
  400.     if(dbug) { fprintf(stderr,"home on %s\n",home_dir); fflush(stderr); }
  401. }
  402.  
  403. /***************************************************************************/
  404.