home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************\
- * Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) *
- * *
- * You may copy or modify this file in any manner you wish, provided *
- * that this notice is always included, and that you hold the author *
- * harmless for any loss or damage resulting from the installation or *
- * use of this software. *
- \*********************************************************************/
-
- #include "server_def.h"
-
- /*****************************************************************************
- * This file handles all file io in request to client requests.
- *****************************************************************************/
-
- #define NBSIZE (2*sizeof(UBUF))
-
- extern *malloc();
-
- #define fexist(A) (!access(A,0))
- #define touch(A) close(open(A,O_CREAT,0777))
-
- /*****************************************************************************
- * Routine to check a path string given by the client.
- * Will replace null string by ".".
- * In case of error, returns the error string.
- *****************************************************************************/
-
- char *check_path(path,len)
- char *path;
- int len;
- {
- char *s;
- int state;
-
- if(len < 1) return("Path must have non-zero lenght");
- if(len == 1 && path[0] == 0) { *path++ = '.'; *path = 0; return(NULLP); }
- if(path[len-1]) return("Path not null terminated");
-
- for(s = path, state = 0; *s; s++)
- {
- if(*s <= ' ' || *s >= '~') return("Path contains illegal chars");
-
- switch(*s)
- {
- case '.': if(!state) return("Path can't begin with '.'");
- break;
-
- case '/': if(!state) return("Path can't contain '//'");
- state = 0;
- break;
-
- default : state = 1;
- break;
- }
- }
-
- return(NULLP);
- }
-
- /*****************************************************************************
- * Put the directory name of path into dbuf.
- *****************************************************************************/
-
- char *get_dir_name(path,dbuf)
- char *path, *dbuf;
- {
- char *p1,*p2,*p3;
-
- for(p1 = path, p2 = p3 = dbuf; *p1; p1++, p3++)
- {
- if((*p3 = *p1) == '/') p2 = p3;
- }
-
- if(dbuf == p2) { dbuf[0] = '.'; dbuf[1] = 0; }
- else { *p2 = 0; }
-
- return(dbuf);
- }
-
- /*****************************************************************************
- * Reads directory and write directory listing file.
- *****************************************************************************/
-
- static build_dir_file(fp)
- FILE *fp;
- {
- int nlen, skip, rem;
- DIR *dir_f;
- struct dirent *dp;
- struct stat sb;
- register char *s;
- RDIRENT rdb;
- static char marker[] = "******************";
-
- if(!(dir_f = opendir("."))) /* assume I have cd to path already */
- { fprintf(stderr,"Can't open dir during initialization\n"); exit(1); }
-
- for(rem = UBUF_SPACE; dp = readdir(dir_f); )
- {
- if (dp->d_ino == 0) continue;
- s = dp->d_name;
- /* hide dot files */
- if((s[0] == '.') && ((s[1] != 0 ) &&
- (s[1] != '.' || s[2] != 0))) continue;
-
- if(stat(dp->d_name,&sb)) continue;
-
- nlen = strlen(s)+1;
-
- if(rem < RDHSIZE + nlen)
- {
- rdb.type = RDTYPE_SKIP;
- if(rem <= RDHSIZE) { fwrite(marker,1,rem ,fp); }
- else { fwrite(marker,1,RDHSIZE,fp);
- fwrite(s, 1,rem-RDHSIZE,fp); }
- rem = UBUF_SPACE;
- }
-
- rdb.type = ((S_IFDIR & sb.st_mode)) ? RDTYPE_DIR : RDTYPE_FILE;
- rdb.size = htonl(sb.st_size);
- rdb.time = htonl(sb.st_mtime);
-
- fwrite(&rdb,1,RDHSIZE,fp);
- fwrite(s,1,nlen,fp);
- rem -= (nlen + RDHSIZE);
-
- if((skip = (nlen + RDHSIZE) & 0x3))
- { fwrite(&rdb,1,4-skip,fp); rem -= (4-skip); }
-
- if(!rem) rem = UBUF_SPACE;
- }
-
- rdb.type = RDTYPE_END;
- fwrite(&rdb,1,RDHSIZE,fp);
-
- fflush(fp);
- closedir(dir_f);
- }
-
- /***************************************************************************/
-
- char *server_get_dir(path,fp) /* assume path is validated */
- char *path; /* returned file may not point at BOF */
- FILE **fp;
- {
- struct stat sd, sf;
- char list_p[NBSIZE];
-
- if(!*path) path = ".";
- if(stat(path,&sd)) return("Can't find directory");
- if(!(S_IFDIR & sd.st_mode)) return("Not a directory");
-
- sprintf(list_p,"%s/.FSP_CONTENT",path);
-
- if(!stat(list_p,&sf) && (sf.st_mtime >= sd.st_mtime))
- {
- *fp = fopen(list_p,"r");
- if(!*fp) return("Can't read directory listing");
- return((char *)0);
- }
-
- if(!(*fp = fopen(list_p,"w+"))) return("Can't create directory listing");
- if(chdir(path)) return("Can't cd to directory");
- build_dir_file(*fp);
- if(chdir(home_dir) == -1) { perror("chdir2"); exit(1); }
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_del_file(path,inet_num) /* assume path is validated */
- char *path;
- unsigned long inet_num;
- {
- struct stat sb;
- char dir_p[NBSIZE], no_del_p[NBSIZE], owner_p[NBSIZE];
-
- if(stat(path,&sb)) return("unlink: file not accessible");
- if(!(S_IFREG & sb.st_mode)) return("unlink: not an ordinary file");
-
- get_dir_name(path,dir_p);
- sprintf(owner_p ,"%s/.OWN.%08X" ,dir_p,inet_num);
- sprintf(no_del_p,"%s/.FSP_NO_DEL",dir_p );
-
- if(!fexist(owner_p) && fexist(no_del_p))
- return("no permission for removing this file");
-
- if(unlink(path) == -1) return("unlink: cannot unlink");
-
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_del_dir(path,inet_num) /* assume path is validated */
- char *path;
- unsigned long inet_num;
- {
- struct stat sb;
- char dir_p[NBSIZE], no_del_p[NBSIZE], no_add_p[NBSIZE], owner_p[NBSIZE];
- int has_no_del_p, has_no_add_p;
-
- if(stat(path,&sb)) return("rmdir: directory not accessible");
- if(!(S_IFDIR & sb.st_mode)) return("rmdir: not an ordinary directory");
-
- get_dir_name(path,dir_p);
- sprintf( owner_p,"%s/.OWN.%08X" ,dir_p,inet_num);
- sprintf(no_del_p,"%s/.FSP_NO_DEL",dir_p );
-
- if(!fexist(owner_p) && fexist(no_del_p))
- return("no permission for removing this directory");
-
- sprintf( owner_p,"%s/.OWN.%08X" ,path,inet_num);
- sprintf( dir_p,"%s/.FSP_CONTENT",path );
- sprintf(no_del_p,"%s/.FSP_NO_DEL" ,path );
- sprintf(no_add_p,"%s/.FSP_NO_ADD" ,path );
-
- if(!fexist(owner_p)) return("no permission for removing this directory");
-
- unlink(owner_p); unlink( dir_p);
- has_no_del_p = !unlink(no_del_p);
- has_no_add_p = !unlink(no_add_p);
-
- if(rmdir(path) != 0)
- {
- if(has_no_del_p) touch(no_del_p);
- if(has_no_add_p) touch(no_add_p);
- if( owner_p) touch( owner_p);
- return("rmdir: cannot unlink");
- }
-
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_make_dir(path,inet_num) /* assume path is validated */
- char *path;
- unsigned long inet_num;
- {
- char dir_p[NBSIZE], no_del_p[NBSIZE], no_add_p[NBSIZE], owner_p[NBSIZE];
-
- get_dir_name(path,dir_p);
- sprintf( owner_p,"%s/.OWN.%08X" ,dir_p,inet_num);
- sprintf(no_add_p,"%s/.FSP_NO_ADD",dir_p );
-
- if(!fexist(owner_p) && fexist(no_add_p))
- return("no permission for directory creation");
-
- sprintf( owner_p,"%s/.OWN.%08X" ,path,inet_num);
- sprintf( dir_p,"%s/.FSP_CONTENT",path );
- sprintf(no_del_p,"%s/.FSP_NO_DEL" ,path );
- sprintf(no_add_p,"%s/.FSP_NO_ADD" ,path );
-
- if(mkdir(path,0777) != 0) return("Can't create directory");
-
- touch(no_del_p);
- touch(no_add_p);
- touch( owner_p);
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_get_file(path,fp) /* assume path is validated */
- char *path;
- FILE **fp;
- {
- struct stat sb;
-
- if(stat(path,&sb)) return("Can't find file");
- if(!(S_IFREG & sb.st_mode)) return("Not a file");
- if(!(*fp = fopen(path,"r"))) return("Can't open file");
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_get_pro(s,inet_num) /* s is both I and O */
- char *s;
- unsigned long inet_num;
- {
- struct stat sb;
- char buf[NBSIZE];
- char *owner_s, *del_s, *add_s;
-
- if(stat(s,&sb)) return("getpro: directory not accessible");
- if(!(S_IFDIR & sb.st_mode)) return("getpro: not an ordinary directory");
-
- sprintf(buf,"%s/.OWN.%08X",s,inet_num);
- owner_s = (fexist(buf)) ? "your" : "some other";
- sprintf(buf,"%s/.FSP_NO_DEL" ,s); del_s = (fexist(buf)) ? "NO" : "YES";
- sprintf(buf,"%s/.FSP_NO_ADD" ,s); add_s = (fexist(buf)) ? "NO" : "YES";
-
- sprintf(s,"(owner: %s machine)(delete: %s)(create: %s)",
- owner_s, del_s, add_s);
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_set_pro(path,key,inet_num)
- char *path, *key;
- unsigned long inet_num;
- {
- struct stat sb;
- char buf[NBSIZE];
-
- if(stat(path,&sb)) return("getpro: directory not accessible");
- if(!(S_IFDIR & sb.st_mode)) return("getpro: not an ordinary directory");
-
- sprintf(buf,"%s/.OWN.%08X",path,inet_num);
- if(!fexist(buf)) return("no permission for changing the protection-mode");
-
- switch(key[1])
- {
- case 'c': sprintf(buf,"%s/.FSP_NO_ADD",path); break;
- case 'd': sprintf(buf,"%s/.FSP_NO_DEL",path); break;
- default : return("bad flag");
- }
-
- switch(key[0])
- {
- case '-': touch(buf); break;
- case '+': unlink(buf); break;
- default : return("bad flag");
- }
-
- return(NULLP);
- }
-
- /**********************************************************************
- * These two are used for file uploading.
- **********************************************************************/
-
- char *server_up_load(data,len,pos,inet_num)
- char *data;
- unsigned len;
- unsigned long pos, inet_num;
- {
- FILE *fp;
- char tname[NBSIZE];
-
- sprintf(tname,".TMP.%08X",inet_num);
-
- if(pos) { fp = fopen(tname,"a"); }
- else { unlink(tname); fp = fopen(tname,"w"); }
-
- if(!fp) return("Cannot open temporary file");
-
- fwrite(data, 1, len, fp);
- fclose(fp);
-
- return(NULLP);
- }
-
- char *server_install(path,inet_num)
- char *path;
- unsigned long inet_num;
- {
- FILE *ft, *fp;
- char tname[NBSIZE], no_add_p[NBSIZE], owner_p[NBSIZE], buf[512];
- int bytes;
-
- get_dir_name(path,tname);
- sprintf( owner_p,"%s/.OWN.%08X" ,tname,inet_num);
- sprintf(no_add_p,"%s/.FSP_NO_ADD",tname );
- sprintf(tname,".TMP.%08X" , inet_num);
-
- if(!fexist(owner_p) && fexist(no_add_p))
- {
- unlink(tname);
- return("no permission for writting to that file");
- }
-
- unlink(path);
- if(link(tname,path) == 0) { unlink(tname); return(NULLP); }
-
- if(!(ft = fopen(tname,"r"))) { unlink(tname);
- return("Can't open temporary file"); }
-
- if(!(fp = fopen(path ,"w"))) { unlink(tname); fclose(ft);
- return("Can't open file for output"); }
-
- while(bytes = fread(buf,1,sizeof(buf),ft)) fwrite(buf,1,bytes,fp);
-
- fclose(ft); fclose(fp); unlink(tname); return(NULLP);
- }
-
- /**********************************************************************/
-
- init_home_dir()
- {
- if(*home_dir != '/') { fprintf(stderr,"[%s] does not start with a /\n");
- exit(1); }
-
- if(chdir(home_dir) == -1) { perror("chdir"); exit(1); }
-
- if(dbug) { fprintf(stderr,"home on %s\n",home_dir); fflush(stderr); }
- }
-
- /***************************************************************************/
-