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 is a modified server_file that hash file names. *
- *****************************************************************************/
-
- #define NBSIZE (2*sizeof(UBUF))
-
- extern *malloc();
-
- #define fexist(A) (!access(A,0))
- #define touch(A) close(open(A,O_CREAT,0777))
- #define LF_PFX '&'
- #define LP_PFX '\\'
-
- /*****************************************************************************
- * Routine to check a path string given by the client.
- * Will replace null string by ".".
- * In case of error, returns the error string.
- *****************************************************************************/
-
- /*****************************************************************************
- * The PPATH structure is filled in by the function check_path when given a
- * path string. The elements are filled in as such:
- *
- * fullp pointer to a string containing the full path name
- * f_ptr pointer to begining of the last component of the path
- * f_len length of the last component of the path
- * d_ptr pointer to begining of the directory part of path
- * d_len length of the directory part of the path
- *
- * fullp is a null-terminated full path string.
- * f_ptr is always a null-terminated sub-string of fullp.
- * p_ptr is generally not null-terminated.
- *****************************************************************************/
-
- char *check_path(fullp,len,pp)
- char *fullp;
- int len;
- PPATH *pp;
- {
- char *s;
- int state;
-
- if(len < 1) return("Path must have non-zero length");
- if(fullp[len-1]) return("Path not null terminated");
-
- pp->d_ptr = "."; pp->d_len = 1; /* initial dir part ---> root */
-
- if(len == 1 && fullp[0] == 0) /* null path --> root */
- {
- pp->fullp = pp->f_ptr = ".";
- pp->f_len = 1;
- return(NULLP);
- }
-
- for(s = pp->fullp = pp->f_ptr = fullp, state = 0; *s; s++)
- {
- if(*s <= ' ' || *s >= '~') return("Path contains illegal chars");
-
- switch(*s)
- {
- case LF_PFX:
- case LP_PFX:
- case '.': if(!state) return("Path can't begin with '.'");
- break;
-
- case '/': if(!state) return("Path can't contain '//'");
- pp->d_ptr = fullp;
- pp->d_len = s - fullp;
- pp->f_ptr = s+1;
- state = 0;
- break;
-
- default : state = 1;
- break;
- }
- }
-
- pp->f_len = s - pp->f_ptr;
- return(NULLP);
- }
-
- /*****************************************************************************
- * Put the directory part of the path pp into dbuf.
- * return pointer to the null character.
- *****************************************************************************/
-
- char *copy_dir(dbuf,pp)
- char *dbuf;
- PPATH *pp;
- {
- char *p1,*p2;
- int cnt;
-
- for(p1 = dbuf, p2 = pp->d_ptr, cnt = pp->d_len; cnt--; *p1++ = *p2++);
- *p1 = 0; return(p1);
- }
-
- /*****************************************************************************
- * Reads directory and write directory listing file.
- *****************************************************************************/
-
- static build_dir_file(fp)
- FILE *fp;
- {
- int nlen, skip, rem;
- DIR *dir_f;
- #ifdef DIRENT
- struct dirent *dp;
- #else
- struct direct *dp;
- #endif
- struct stat sb;
- register char *s;
- RDIRENT rdb;
- static char marker[] = "******************";
- char longname[UBUF_SPACE];
- FILE *lfp;
-
- 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;
-
- if(s[0] == LF_PFX)
- {
- s[0] = LP_PFX;
- if(!(lfp = fopen(s,"r"))) { unlink(s); *s = LF_PFX; unlink(s); }
- fgets(longname,UBUF_SPACE,lfp); fclose(lfp);
- s[0] = LF_PFX; s = longname; longname[UBUF_SPACE-1] = 0;
- }
-
- if(s[0] == LP_PFX) continue;
- /* 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((char *) &rdb,1,RDHSIZE,fp);
- fwrite(s,1,nlen,fp);
- rem -= (nlen + RDHSIZE);
-
- if((skip = (nlen + RDHSIZE) & 0x3))
- { fwrite((char *) &rdb,1,4-skip,fp); rem -= (4-skip); }
-
- if(!rem) rem = UBUF_SPACE;
- }
-
- rdb.type = RDTYPE_END;
- fwrite((char *) &rdb,1,RDHSIZE,fp);
-
- fflush(fp);
- closedir(dir_f);
- }
-
- /***************************************************************************/
-
- char *server_get_dir(pp,fp)
- PPATH *pp; /* returned file may not point at BOF */
- FILE **fp;
- {
- char *server_get_dir_2();
- struct stat sd, sf;
- char list_p[NBSIZE];
- int fsp_content_exists;
-
- if(stat(pp->fullp,&sd)) return("Can't find directory");
- if(!(S_IFDIR & sd.st_mode)) return("Not a directory");
-
- sprintf(list_p,"%s/.FSP_CONTENT",pp->fullp);
-
- if(fsp_content_exists = !stat(list_p,&sf))
- {
- if(sf.st_mtime >= sd.st_mtime)
- {
- *fp = fopen(list_p,"r");
- if(!*fp) return("Can't read directory listing");
- return((char *)0);
- }
- }
-
- if(!fsp_content_exists &&
- always_use_cache_dir) return(server_get_dir_2(pp,fp,&sd));
-
- if(!(*fp = fopen(list_p,"w+")))
- {
- if(!fsp_content_exists &&
- !always_use_cache_dir) return(server_get_dir_2(pp,fp,&sd));
- return("directory unreadable");
- }
- if(chdir(pp->fullp)) return("Can't cd to directory");
- build_dir_file(*fp);
- if(chdir(home_dir) == -1) { perror("chdir2"); exit(1); }
- return(NULLP);
- }
-
- char *server_get_dir_2(pp,fp,sd)
- PPATH *pp;
- FILE **fp;
- struct stat *sd;
- {
- struct stat sf;
- char name_p[NBSIZE], list_p[NBSIZE], tmp[UBUF_SPACE];
- unsigned int hash, i, mask, new_namefile;
- unsigned char *p;
- FILE *np;
-
- mask = dir_cache_limit << 8;
-
- for(hash = 0, p = (unsigned char *) pp->fullp; *p; p++)
- {
- hash = (hash << 1) ^ *p;
- if(hash & mask) hash ^= (mask+1);
- }
-
- for(i = 8; i--; )
- {
- hash <<= 1;
- if(hash & mask) hash ^= (mask+1);
- }
-
- hash = (hash >> 8) & (mask-1);
-
- sprintf(name_p,"%s/.N%x",dir_cache_dir,hash);
- sprintf(list_p,"%s/.L%x",dir_cache_dir,hash);
-
- if(!(np = fopen(name_p,"r"))) new_namefile = 1; else
- {
- fgets(tmp,UBUF_SPACE,np); fclose(np);
-
- if(strcmp(tmp,pp->fullp)) new_namefile = 1; else
- {
- 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);
- }
- new_namefile = 0;
- }
- }
-
- if(new_namefile)
- {
- if(!(np = fopen(name_p,"w")))
- return("Can't write directory listing name file");
- fputs(pp->fullp,np); fclose(np);
- }
-
- if(!(*fp = fopen(list_p,"w+"))) return("directory unreadable");
- if(chdir(pp->fullp)) 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(pp,inet_num) /* assume path is validated */
- PPATH *pp;
- unsigned long inet_num;
- {
- int is_long;
- struct stat sb;
- char ok_del_p[NBSIZE], owner_p[NBSIZE];
-
- if(is_long = (pp->f_len > max_nlen)) fold_path(pp);
-
- if(stat(pp->fullp,&sb)) return("unlink: file not accessible");
- if(!(S_IFREG & sb.st_mode)) return("unlink: not an ordinary file");
-
- sprintf(copy_dir( owner_p,pp),"/.OWN.%08X" ,inet_num);
- strcpy(copy_dir(ok_del_p,pp),"/.FSP_OK_DEL" );
-
- if(!fexist(owner_p) && !fexist(ok_del_p))
- return("no permission for removing this file");
-
- if(unlink(pp->fullp) == -1) return("unlink: cannot unlink");
-
- if(is_long) { *pp->f_ptr = LP_PFX; unlink(pp->fullp); }
-
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_del_dir(pp,inet_num)
- PPATH *pp;
- unsigned long inet_num;
- {
- struct stat sb;
- char list_p[NBSIZE], ok_del_p[NBSIZE], ok_add_p[NBSIZE], owner_p[NBSIZE];
- int has_ok_del_p, has_ok_add_p;
-
- if(stat(pp->fullp,&sb)) return("rmdir: directory not accessible");
- if(!(S_IFDIR & sb.st_mode)) return("rmdir: not an ordinary directory");
-
- sprintf( owner_p,"%s/.OWN.%08X" ,pp->fullp,inet_num);
- sprintf( list_p,"%s/.FSP_CONTENT",pp->fullp );
- sprintf(ok_del_p,"%s/.FSP_OK_DEL" ,pp->fullp );
- sprintf(ok_add_p,"%s/.FSP_OK_ADD" ,pp->fullp );
-
- if(!fexist(owner_p)) return("no permission for removing this directory");
-
- unlink(owner_p); unlink( list_p);
- has_ok_del_p = !unlink(ok_del_p);
- has_ok_add_p = !unlink(ok_add_p);
-
- if(rmdir(pp->fullp) != 0)
- {
- if(has_ok_del_p) touch(ok_del_p);
- if(has_ok_add_p) touch(ok_add_p);
- if( owner_p) touch( owner_p);
- return("rmdir: cannot unlink");
- }
-
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_make_dir(pp,inet_num)
- PPATH *pp;
- unsigned long inet_num;
- {
- char ok_add_p[NBSIZE], owner_p[NBSIZE];
-
- sprintf(copy_dir( owner_p,pp),"/.OWN.%08X" ,inet_num);
- strcpy(copy_dir(ok_add_p,pp),"/.FSP_OK_ADD" );
-
- if(!fexist(owner_p) && !fexist(ok_add_p))
- return("no permission for directory creation");
-
- sprintf(owner_p,"%s/.OWN.%08X",pp->fullp,inet_num);
-
- if(mkdir(pp->fullp,0777) != 0) return("Can't create directory");
-
- touch(owner_p);
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_get_file(pp,fp)
- PPATH *pp;
- FILE **fp;
- {
- struct stat sb;
-
- if(pp->f_len > max_nlen) fold_path(pp);
-
- if(stat(pp->fullp,&sb)) return("Can't find file");
- if(!(S_IFREG & sb.st_mode)) return("Not a file");
- if(!(*fp = fopen(pp->fullp,"r"))) return("Can't open file");
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_get_pro(pp,result,inet_num) /* result and pp->fullp may overlap */
- PPATH *pp;
- char *result;
- unsigned long inet_num;
- {
- struct stat sb;
- char buf[NBSIZE];
- char *owner_s, *del_s, *add_s;
-
- if(stat(pp->fullp,&sb)) return("getpro: directory not accessible");
- if(!(S_IFDIR & sb.st_mode)) return("getpro: not an ordinary directory");
-
- sprintf(buf,"%s/.OWN.%08X",pp->fullp,inet_num);
- owner_s = ( fexist(buf)) ? "your" : "some other";
- sprintf(buf,"%s/.FSP_OK_DEL" ,pp->fullp);
- del_s = (!fexist(buf)) ? "NO" : "YES";
- sprintf(buf,"%s/.FSP_OK_ADD" ,pp->fullp);
- add_s = (!fexist(buf)) ? "NO" : "YES";
-
- sprintf(result,"(owner: %s machine)(delete: %s)(create: %s)",
- owner_s, del_s, add_s);
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_set_pro(pp,key,inet_num)
- PPATH *pp;
- char *key;
- unsigned long inet_num;
- {
- struct stat sb;
- char buf[NBSIZE];
-
- if(stat(pp->fullp,&sb)) return("getpro: directory not accessible");
- if(!(S_IFDIR & sb.st_mode)) return("getpro: not an ordinary directory");
-
- sprintf(buf,"%s/.OWN.%08X",pp->fullp,inet_num);
- if(!fexist(buf)) return("no permission for changing the protection-mode");
-
- switch(key[1])
- {
- case 'c': sprintf(buf,"%s/.FSP_OK_ADD",pp->fullp); break;
- case 'd': sprintf(buf,"%s/.FSP_OK_DEL",pp->fullp); 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,port_num)
- char *data;
- int len;
- unsigned long pos, inet_num;
- unsigned short port_num;
- {
- FILE *fp;
- char tname[NBSIZE];
-
- sprintf(tname,"%s/.T%08X%04X",dir_cache_dir,inet_num,port_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(pp,inet_num,port_num)
- PPATH *pp;
- unsigned long inet_num;
- unsigned short port_num;
- {
- FILE *ft, *fp;
- char tname[NBSIZE], owner_p[NBSIZE], save_p[NBSIZE], buf[512];
- char ok_del_p[NBSIZE], ok_add_p[NBSIZE];
- int bytes, is_long;
-
- if(is_long = (pp->f_len > max_nlen))
- { strcpy(save_p,pp->f_ptr); fold_path(pp); }
-
- sprintf(copy_dir(owner_p,pp),"/.OWN.%08X",inet_num);
- sprintf(tname,"%s/.T%08X%04X",dir_cache_dir,inet_num,port_num);
-
- if(!fexist(owner_p))
- {
- strcpy(copy_dir(ok_add_p,pp),"/.FSP_OK_ADD");
- strcpy(copy_dir(ok_del_p,pp),"/.FSP_OK_DEL");
-
- if(!fexist(ok_add_p))
- {
- unlink(tname);
- return("no permission for creating that file");
- }
-
- if(!fexist(ok_del_p) && fexist(pp->fullp))
- {
- unlink(tname);
- return("no permission for replacing that file");
- }
- }
-
- unlink(pp->fullp);
- if(link(tname,pp->fullp) == 0) { unlink(tname); goto done; }
-
- if(!(ft = fopen(tname,"r"))) { unlink(tname);
- return("Can't open temporary file"); }
-
- if(!(fp = fopen(pp->fullp ,"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);
-
- done:
-
- if(is_long)
- {
- *pp->f_ptr = LP_PFX;
- if(!(fp = fopen(pp->fullp,"w")))
- {
- *pp->f_ptr = LF_PFX; unlink(tname);
- return("Can't create long named file for output");
- }
- fputs(save_p,fp); fclose(fp);
- }
-
- return(NULLP);
- }
-
- /**********************************************************************/
-
- char *server_secure_file(pp,inet_num,port_num) /* assume path is validated */
- PPATH *pp;
- unsigned long inet_num;
- unsigned short port_num;
- {
- int is_long;
- struct stat sb;
- char ok_del_p[NBSIZE], owner_p[NBSIZE], temp_p[NBSIZE];
-
- if(is_long = (pp->f_len > max_nlen)) fold_path(pp);
-
- if(stat(pp->fullp,&sb)) return("grab: file not accessible");
- if(!(S_IFREG & sb.st_mode)) return("grab: not an ordinary file");
-
- sprintf(copy_dir( owner_p,pp),"/.OWN.%08X" ,inet_num );
- strcpy(copy_dir(ok_del_p,pp),"/.FSP_OK_DEL" );
- sprintf(copy_dir( temp_p,pp),"/.G%08X%04X" ,inet_num,port_num);
-
- if(!fexist(owner_p) && !fexist(ok_del_p))
- return("grab: no permission for grabbing this file");
-
- unlink(temp_p);
- if(link(pp->fullp,temp_p) == -1) return("grab: cannot make link");
- if(unlink(pp->fullp) == -1) { unlink(temp_p);
- return("grab: cannot unlink"); }
-
- if(is_long) { *pp->f_ptr = LP_PFX; unlink(pp->fullp); }
-
- return(NULLP);
- }
-
- char *server_grab_file(pp,fp,inet_num,port_num)
- PPATH *pp;
- FILE **fp;
- unsigned long inet_num;
- unsigned short port_num;
- {
- struct stat sb;
- char temp_p[NBSIZE];
-
- sprintf(copy_dir(temp_p,pp),"/.G%08X%04X",inet_num,port_num);
-
- if(stat(temp_p,&sb)) return("grab: can't find file");
- if(!(S_IFREG & sb.st_mode)) return("grab: Not a file");
- if(!(*fp = fopen(temp_p,"r"))) return("grab: can't open file");
- return(NULLP);
- }
-
- char *server_grab_done(pp,inet_num,port_num)
- PPATH *pp;
- unsigned long inet_num;
- unsigned short port_num;
- {
- struct stat sb;
- char temp_p[NBSIZE];
-
- sprintf(copy_dir(temp_p,pp),"/.G%08X%04X",inet_num,port_num);
-
- if(stat(temp_p,&sb)) return("grab: can't find temporary file");
- if(unlink(temp_p) == -1) return("grab: can't delete temporary file");
- return(NULLP);
- }
-
- /**********************************************************************/
-
- fold_path(pp)
- PPATH *pp;
- {
- unsigned char *p;
- unsigned long v1, v2;
-
- p = (unsigned char *) pp->f_ptr;
-
- for(v1 = 0; v2 = *p++; )
- {
- if(v1 & 0x80000000) { v1 = (v1 << 1) ^ v2 ^ 1; }
- else { v1 = (v1 << 1) ^ v2 ; }
- }
-
- sprintf(pp->f_ptr,"%c%08X",LF_PFX,v1);
- pp->f_len = 9;
- }
-
- /**********************************************************************/
-
- 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); }
- }
-
- /***************************************************************************/
-