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 "client_def.h"
-
- extern char *realloc(), *malloc(), *getenv();
- extern long atol();
- extern int errno;
-
- static int env_dir_malloced = 0;
- char *env_dir = "/";
- char *env_myport;
- char *env_host;
- char *env_port;
- unsigned short client_buf_len;
- unsigned short client_net_len;
-
- char *util_abs_path(s2)
- char *s2;
- {
- char *path, *s, *d, *t;
-
- if(!env_dir) env_dir = "";
- if(!s2) s2 = "";
-
- if(*s2 == '/')
- {
- path = malloc(strlen(s2)+2);
- sprintf(path,"/%s",s2);
- } else
- {
- path = malloc(strlen(env_dir)+strlen(s2)+3);
- sprintf(path,"/%s/%s",env_dir,s2);
- }
-
- for(t = path; *t; )
- {
- if(t[0] == '/')
- {
- while(t[1] == '/') for(d = t, s = t+1; *d++ = *s++; );
- if(t != path && t[1] == 0) { t[0] = 0; return(path); }
- }
- if(t[0] == '.' && t[1] == '.')
- {
- if(t-1 == path && t[2] == 0 ) { *t = 0; return(path); }
- if(t-1 == path && t[2] == '/')
- {
- for(d = t, s = t + 3; *d++ = *s++; );
- continue;
- }
- if(t[-1] == '/' && (t[2] == '/' || t[2] == 0))
- {
- s = t + 2; /* point to either slash or nul */
- t -= 2; /* guaranteed that t >= path here */
- while(t > path && t[0] != '/') t--;
- if(t != path || *s == '/') { for(d = t; *d++ = *s++; ); }
- else { t[1] = 0; return(path); }
- continue;
- }
- }
- if(t[0] == '.')
- {
- if(t-1 == path && t[1] == 0 ) { *t = 0; return(path); }
- if(t-1 == path && t[1] == '/')
- {
- for(d = t, s = t + 2; *d++ = *s++; );
- continue;
- }
- if(t[-1] == '/' && (t[1] == '/' || t[1] == 0))
- {
- s = t + 1; /* point to either slash or nul */
- for(d = t-1; *d++ = *s++; );
- t--;
- continue;
- }
- }
- t++;
- }
- return(path);
- }
-
- char *util_getwd(p)
- char *p;
- {
- if(p) strcpy(p,env_dir);
- return(p);
- }
-
- RDIRENT **get_dir_blk(path)
- char *path;
- {
- RDIRENT **dp;
- char *p1, *p2, *fpath, buf[2*UBUF_SPACE];
- unsigned long pos;
- int cnt, k, len, rem, acc, at_eof;
- UBUF *ub;
-
- fpath = util_abs_path(path);
-
- for(pos = 0, at_eof = acc = cnt = 0; ; )
- {
- while((acc < UBUF_SPACE) && !at_eof)
- {
- ub = client_interact(CC_GET_DIR,pos,
- strlen(fpath),fpath+1, 2,&client_net_len);
-
- if(ub->cmd == CC_ERR)
- {
- fprintf(stderr,"directory reading error: %s\n",ub->buf);
- free(fpath);
- errno = EACCES;
- return((RDIRENT **) 0);
- }
-
- if(ub->len < client_buf_len) at_eof = 1;
- for(p1 = ub->buf, p2 = buf + acc, k = ub->len; k--; ) *p2++ = *p1++;
- acc += ub->len;
- pos += ub->len;
- }
-
- if(acc >= UBUF_SPACE) len = UBUF_SPACE;
- else len = acc;
-
- for(p2 = buf, rem = len, k = 0; ; k++)
- {
- if(rem < RDHSIZE) break;
- if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
- if(((RDIRENT *) p2)->type == RDTYPE_END ) { k++; break; }
- p2 += RDHSIZE; rem -= (RDHSIZE+1);
- while(*p2++ ) { rem--; }
- while((p2 - buf) & 3) { p2++; rem--; }
- }
-
- p1 = malloc(p2-buf);
- if(cnt) dp = (RDIRENT **) realloc(dp,(cnt+k+1)*sizeof(RDIRENT *));
- else dp = (RDIRENT **) malloc( (cnt+k+1)*sizeof(RDIRENT *));
-
- if(!p1 || !dp) { free(fpath);
- fputs("directory reading out of memory\n",stderr);
- return((RDIRENT **) 0); }
-
- for(p2 = buf, rem = len; ; cnt++)
- {
- if(rem < RDHSIZE) break;
- if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
- if(((RDIRENT *) p2)->type == RDTYPE_END )
- { dp[cnt] = 0; return(dp); }
- dp[cnt] = (RDIRENT *) p1;
- ((RDIRENT *) p1)->time = ntohl(((RDIRENT *) p2)->time);
- ((RDIRENT *) p1)->size = ntohl(((RDIRENT *) p2)->size);
- ((RDIRENT *) p1)->type = ((RDIRENT *) p2)->type ;
-
- p2 += RDHSIZE; p1 += RDHSIZE; rem -= (RDHSIZE+1);
- while(*p1++ = *p2++ ) { rem--; }
- while((p2 - buf) & 3) { p2++; p1++; rem--; }
- }
-
- if(acc < UBUF_SPACE) { dp[cnt] = 0; return(dp); }
- for(p1 = buf + UBUF_SPACE, p2 = buf, k = (acc -= UBUF_SPACE); k--; )
- *p2++ = *p1++;
- }
- }
-
- util_download_main(path,fpath,fp,cmd)
- char *path, *fpath;
- FILE *fp;
- int cmd;
- {
- unsigned long pos;
- unsigned tmax, wrote, sent_time;
- UBUF *ub;
-
- for(tmax = 1, pos = 0, sent_time = 0; ; )
- {
- ub = client_interact(cmd,pos, strlen(fpath),fpath+1, 2,&client_net_len);
-
- if(client_trace && (udp_sent_time != sent_time))
- {
- sent_time = udp_sent_time;
- if(client_buf_len == UBUF_SPACE)
- fprintf(stderr,"\r%luk ",1+(pos>>10));
- else fprintf(stderr,"\r%lu ", pos );
- fflush(stderr);
- }
-
- if(ub->cmd == CC_ERR)
- {
- fprintf(stderr,"downloading %s: %s\n",path,ub->buf);
- return(-1);
- }
-
- wrote = fwrite(ub->buf,1,ub->len,fp);
- pos += wrote;
-
- if(ub->len < client_buf_len || ub->len != wrote) break;
- }
-
- if(client_trace) { fprintf(stderr,"\r%luk : %s \n",1+(pos>>10),path);
- fflush(stderr); }
-
- return(0);
- }
-
- util_download(path,fp)
- char *path;
- FILE *fp;
- {
- int code;
- char *fpath;
-
- fpath = util_abs_path(path);
- code = util_download_main(path,fpath,fp,CC_GET_FILE);
- free(fpath);
- return(code);
- }
-
- util_grab_file(path,fp)
- char *path;
- FILE *fp;
- {
- int code;
- char *fpath;
- UBUF *ub;
-
- fpath = util_abs_path(path);
- code = util_download_main(path,fpath,fp,CC_GRAB_FILE);
- if(code) { free(fpath); return(code); }
-
- ub = client_interact(CC_GRAB_DONE,0L, strlen(fpath),fpath+1, 0,NULLP);
-
- if(ub->cmd == CC_ERR)
- {
- fprintf(stderr,"Warning, unexpected grab error: %s\n",ub->buf);
- }
-
- free(fpath);
- return(code);
- }
-
- util_upload(path,fp)
- char *path;
- FILE *fp;
- {
- unsigned long pos;
- unsigned bytes, first, tmax, sent_time;
- char *fpath, buf[UBUF_SPACE];
- UBUF *ub;
-
- fpath = util_abs_path(path);
-
- for(tmax = 1, sent_time = 0, pos = 0, first = 1; ; first = 0)
- {
- if((bytes = fread(buf,1,client_buf_len,fp)) || first)
- {
- ub = client_interact(CC_UP_LOAD,pos, bytes,buf, 0,NULLP);
-
- if(client_trace && (udp_sent_time != sent_time))
- {
- sent_time = udp_sent_time;
- if(client_buf_len == UBUF_SPACE)
- fprintf(stderr,"\r%luk ",1+(pos>>10));
- else fprintf(stderr,"\r%lu ", pos );
- fflush(stderr);
- }
-
- } else
- {
- ub = client_interact(CC_INSTALL,pos,strlen(fpath),fpath+1,0,NULLP);
- }
-
- if(ub->cmd == CC_ERR)
- {
- fprintf(stderr,"uploading %s: %s\n",path,ub->buf);
- free(fpath); return(1);
- }
-
- if(!bytes && !first) break;
- pos += bytes;
- }
-
- if(client_trace) { fprintf(stderr,"\r%luk : %s \n",1+(pos>>10),path);
- fflush(stderr); }
-
- free(fpath); return(0);
- }
-
- util_get_env()
- {
- char *p;
-
- if(!(env_host = getenv("FSP_HOST")))
- { fputs("Env var FSP_HOST not defined\n",stderr); exit(1); }
- if(!(env_port = getenv("FSP_PORT")))
- { fputs("Env var FSP_PORT not defined\n",stderr); exit(1); }
- if(!(env_dir = getenv("FSP_DIR")))
- { fputs("Env var FSP_DIR not defined\n",stderr); exit(1); }
-
- if(!(env_myport = getenv("FSP_LOCALPORT"))) env_myport = "0";
-
- client_trace = !!getenv("FSP_TRACE");
-
- if(p = getenv("FSP_BUF_SIZE")) client_buf_len = atoi(p);
- else client_buf_len = UBUF_SPACE;
-
- if(client_buf_len > UBUF_SPACE) client_buf_len = UBUF_SPACE;
- client_net_len = htons(client_buf_len);
-
- if(p = getenv("FSP_DELAY")) target_delay = atol(p);
- }
-
- void client_intr()
- {
- switch(client_intr_state)
- {
- case 0: exit(2);
- case 1: client_intr_state = 2; break;
- case 2: exit(3);
- }
- }
-
- env_client()
- {
- util_get_env();
- init_client(env_host,atoi(env_port),atoi(env_myport));
- signal(SIGINT,client_intr);
- }
-
- /*****************************************************************************/
-
- static DDLIST *ddroot = 0;
-
- RDIR *util_opendir(path)
- char *path;
- {
- char *fpath;
- RDIRENT **dep;
- DDLIST *ddp;
- RDIR *rdirp;
-
- fpath = util_abs_path(path);
-
- for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
-
- if(!ddp)
- {
- if(!(dep = get_dir_blk(fpath))) return((RDIR *) 0);
- ddp = (DDLIST *) malloc(sizeof(DDLIST));
- ddp->dep_root = dep;
- ddp->path = fpath;
- ddp->ref_cnt = 0;
- ddp->next = ddroot;
- ddroot = ddp;
-
- } else free(fpath);
-
- ddp->ref_cnt++;
-
- rdirp = (RDIR *) malloc(sizeof(RDIR));
- rdirp->ddp = ddp;
- rdirp->dep = ddp->dep_root;
- return(rdirp);
- }
-
- util_closedir(rdirp)
- RDIR *rdirp;
- {
- rdirp->ddp->ref_cnt--;
- free(rdirp);
- }
-
- rdirent *util_readdir(rdirp)
- RDIR *rdirp;
- {
- static rdirent rde;
- RDIRENT **dep;
-
- dep = rdirp->dep;
-
- if(!*dep) return((rdirent *) 0);
-
- rde.d_fileno = 10;
- rde.d_reclen = 10;
- rde.d_namlen = strlen((*dep)->name);
- rde.d_name = (*dep)->name;
- rdirp->dep = dep+1;
-
- return(&rde);
- }
-
- util_split_path(path,p1,p2,p3)
- char *path, **p1, **p2, **p3;
- {
- char *s;
- static char junk;
-
- *p1 = "/";
- if(*path == '/') { *p2 = path; *p3 = path+1; }
- else { *p2 = &junk; *p3 = path ; }
-
- for(s = *p3; *s; s++)
- {
- if(*s == '/')
- {
- *p1 = path;
- *p2 = s;
- *p3 = s+1;
- }
- }
-
- if (**p3 == '\0') *p3 = ".";
- return(1);
- }
-
- util_stat(path,sbuf)
- char *path;
- struct stat *sbuf;
- {
- RDIR *drp;
- RDIRENT **dep;
- char *fpath, *ppath, *p1, *pfile;
-
- fpath = util_abs_path(path);
-
- if(!strcmp(fpath,env_dir))
- {
- ppath = fpath;
- pfile = ".";
-
- } else
- {
- util_split_path(fpath,&ppath,&p1,&pfile); *p1 = 0;
- }
-
- if(drp = util_opendir(ppath))
- {
- for(dep = drp->dep; *dep; dep++)
- {
- if(!strcmp((*dep)->name,pfile))
- {
- if((*dep)->type & RDTYPE_DIR) sbuf->st_mode = 0777 | S_IFDIR;
- else sbuf->st_mode = 0666 | S_IFREG;
-
- if((*dep)->type & RDTYPE_DIR) sbuf->st_nlink = 2;
- else sbuf->st_nlink = 1;
- sbuf->st_uid = 0;
- sbuf->st_gid = 0;
- sbuf->st_size = (*dep)->size;
- sbuf->st_atime = (*dep)->time;
- sbuf->st_mtime = (*dep)->time;
- sbuf->st_ctime = (*dep)->time;
- util_closedir(drp); free(fpath); return(0);
- }
- }
- util_closedir(drp);
- }
-
- free(fpath); errno = ENOENT; return(-1);
- }
-
- util_cd(p)
- char *p;
- {
- char *fpath;
- UBUF *ub;
- DDLIST *ddp;
-
- fpath = util_abs_path(p);
- for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
-
- if(!ddp && strcmp(p,".") && strcmp(p,".."))
- {
- ub = client_interact(CC_GET_DIR,0L, strlen(fpath),fpath+1,
- 2,&client_net_len);
- if(ub->cmd == CC_ERR)
- {
- free(fpath);
- fprintf(stderr,"cd error: %s\n",ub->buf);
- errno = EACCES;
- return(-1);
- }
- }
-
- if(env_dir_malloced) free(env_dir);
- env_dir_malloced = 1;
- env_dir = fpath;
- return(0);
- }
-
- util_cd2(p) /* Perform a cd, but don't verify path. Assume the path */
- char *p; /* has been verified by another mechanism. */
- {
- char *fpath;
-
- fpath = util_abs_path(p);
-
- if(env_dir_malloced) free(env_dir);
- env_dir_malloced = 1;
- env_dir = fpath;
- return(0);
- }
-