home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / fsp / part02 / client_util.c next >
Encoding:
C/C++ Source or Header  |  1991-12-12  |  9.3 KB  |  427 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 "client_def.h"
  11.  
  12. extern char *realloc(), *malloc(), *getenv();
  13. extern int errno;
  14.  
  15. static int env_dir_malloced = 0;
  16. char *env_dir = "/";
  17. char *env_myport;
  18. char *env_host;
  19. char *env_port;
  20.  
  21. char *util_abs_path(s2)
  22.     char *s2;
  23. {
  24.     char *path, *s, *d, *t;
  25.  
  26.     if(!env_dir) env_dir = "";
  27.     if(!s2) s2 = "";
  28.  
  29.     if(*s2 == '/')
  30.     {
  31.     path = malloc(strlen(s2)+2);
  32.     sprintf(path,"/%s",s2);
  33.     } else
  34.     {
  35.     path = malloc(strlen(env_dir)+strlen(s2)+3);
  36.     sprintf(path,"/%s/%s",env_dir,s2);
  37.     }
  38.  
  39.     for(t = path; *t; )
  40.     {
  41.     if(t[0] == '/')
  42.     {
  43.         while(t[1] == '/') for(d = t, s = t+1; *d++ = *s++; );
  44.         if(t != path && t[1] == 0) { t[0] = 0; return(path); }
  45.     }
  46.     if(t[0] == '.' && t[1] == '.')
  47.     {
  48.         if(t-1 == path && t[2] ==  0 ) { *t = 0; return(path); }
  49.         if(t-1 == path && t[2] == '/')
  50.         {
  51.         for(d = t, s = t + 3; *d++ = *s++; );
  52.         continue;
  53.         }
  54.         if(t[-1] == '/' && (t[2] == '/' || t[2] ==  0))
  55.         {
  56.         s = t + 2;    /* point to either slash or nul */
  57.         t -= 2;        /* guaranteed that t >= path here */
  58.         while(t > path && t[0] != '/') t--;
  59.         if(t != path || *s == '/') { for(d = t; *d++ = *s++; ); }
  60.                       else { t[1] = 0; return(path);    }
  61.         continue;
  62.         }
  63.     }
  64.     if(t[0] == '.')
  65.     {
  66.         if(t-1 == path && t[1] ==  0 ) { *t = 0; return(path); }
  67.         if(t-1 == path && t[1] == '/')
  68.         {
  69.         for(d = t, s = t + 2; *d++ = *s++; );
  70.         continue;
  71.         }
  72.         if(t[-1] == '/' && (t[1] == '/' || t[1] ==  0))
  73.         {
  74.         s = t + 1;    /* point to either slash or nul */
  75.         for(d = t-1; *d++ = *s++; ); 
  76.         t--;
  77.         continue;
  78.         }
  79.     }
  80.     t++;
  81.     }
  82.     return(path);
  83. }
  84.  
  85. char *util_getwd(p)
  86.     char *p;
  87. {
  88.     if(p) strcpy(p,env_dir);
  89.     return(p);
  90. }
  91.  
  92. RDIRENT **get_dir_blk(path)
  93.     char *path;
  94. {
  95.     RDIRENT **dp;
  96.     char *p1, *p2;
  97.     unsigned long pos;
  98.     int cnt, k, rem;
  99.     UBUF *ub;
  100.     char *fpath;
  101.  
  102.     fpath = util_abs_path(path);
  103.  
  104.     for(pos = 0, cnt = 0; ; )
  105.     {
  106.     ub = client_interact(CC_GET_DIR,pos, strlen(fpath),fpath+1, 0,NULLP);
  107.  
  108.     if(ub->cmd == CC_ERR)
  109.     {
  110.         fprintf(stderr,"directory reading error: %s\n",ub->buf);
  111.         free(fpath); return((RDIRENT **) 0);
  112.     }
  113.  
  114.     for(p2 = ub->buf, rem = ub->len, k = 0; ; k++)
  115.     {
  116.         if(rem < RDHSIZE) break;
  117.         if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
  118.         if(((RDIRENT *) p2)->type == RDTYPE_END ) { k++; break; }
  119.         p2 += RDHSIZE; rem -= (RDHSIZE+1);
  120.         while(*p2++             ) {       rem--; }
  121.         while((p2 - ub->buf) & 3) { p2++; rem--; }
  122.     }
  123.  
  124.     p1 = malloc(p2-ub->buf);
  125.     if(cnt) dp = (RDIRENT **) realloc(dp,(cnt+k+1)*sizeof(RDIRENT *));
  126.        else dp = (RDIRENT **)  malloc(   (cnt+k+1)*sizeof(RDIRENT *));
  127.  
  128.     if(!p1 || !dp) { free(fpath);
  129.               fputs("directory reading out of memory\n",stderr);
  130.               return((RDIRENT **) 0); }
  131.  
  132.     for(p2 = ub->buf, rem = ub->len; ; cnt++)
  133.     {
  134.         if(rem < RDHSIZE) break;
  135.         if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
  136.         if(((RDIRENT *) p2)->type == RDTYPE_END )
  137.                         { dp[cnt] = 0; return(dp); }
  138.         dp[cnt] = (RDIRENT *) p1;
  139.         ((RDIRENT *) p1)->time = ntohl(((RDIRENT *) p2)->time);
  140.         ((RDIRENT *) p1)->size = ntohl(((RDIRENT *) p2)->size);
  141.         ((RDIRENT *) p1)->type =       ((RDIRENT *) p2)->type ;
  142.  
  143.         p2 += RDHSIZE; p1 += RDHSIZE; rem -= (RDHSIZE+1);
  144.         while(*p1++ = *p2++     ) {            rem--; }
  145.         while((p2 - ub->buf) & 3) { p2++; p1++; rem--; }
  146.     }
  147.  
  148.     if(ub->len != UBUF_SPACE) { dp[cnt] = 0; return(dp); }
  149.     pos += ub->len;
  150.     }
  151. }
  152.  
  153. util_download(path,fp)
  154.     char *path;
  155.     FILE *fp;
  156. {   
  157.     unsigned long pos;
  158.     unsigned tmax, tcnt, wrote;
  159.     UBUF *ub;
  160.     char *fpath;
  161.  
  162.     fpath = util_abs_path(path);
  163.  
  164.     for(tmax = 1, tcnt = 0, pos = 0; ; )
  165.     {   
  166.         ub = client_interact(CC_GET_FILE,pos, strlen(fpath),fpath+1, 0,NULLP);
  167.  
  168.     if(client_trace && (++tcnt >= tmax))
  169.     {
  170.         if(tmax < 16) tmax <<= 1; else tcnt = 0;
  171.         fprintf(stderr,"\r%luk  ",pos>>10);
  172.         fflush(stderr);
  173.     }
  174.  
  175.         if(ub->cmd == CC_ERR)
  176.         {    
  177.             fprintf(stderr,"downloading %s: %s\n",path,ub->buf);
  178.         free(fpath); return(-1); 
  179.         }   
  180.  
  181.         wrote = fwrite(ub->buf,1,ub->len,fp);
  182.         pos  += wrote;
  183.  
  184.         if(ub->len < UBUF_SPACE || ub->len != wrote) break;
  185.     }
  186.  
  187.     if(client_trace) { fprintf(stderr,"\r%luk : %s \n",pos>>10,path);
  188.                fflush(stderr); }
  189.  
  190.     free(fpath); return(0);
  191. }
  192.  
  193. util_upload(path,fp)
  194.     char *path;
  195.     FILE *fp;
  196. {   
  197.     unsigned long pos;
  198.     unsigned bytes, first, tmax, tcnt;
  199.     char *fpath, buf[UBUF_SPACE];
  200.     UBUF *ub;
  201.  
  202.     fpath = util_abs_path(path);
  203.  
  204.     for(tmax = 1, tcnt = 0, pos = 0, first = 1; ; first = 0)
  205.     {   
  206.     if((bytes = fread(buf,1,sizeof(buf),fp)) || first)
  207.     {
  208.         ub = client_interact(CC_UP_LOAD,pos, bytes,buf, 0,NULLP);
  209.         if(client_trace && (++tcnt >= tmax))
  210.         {
  211.         if(tmax < 16) tmax <<= 1; else tcnt = 0;
  212.         fprintf(stderr,"\r%luk ",pos>>10);
  213.         fflush(stderr);
  214.         }
  215.  
  216.     } else
  217.     {
  218.         ub = client_interact(CC_INSTALL,pos,strlen(fpath),fpath+1,0,NULLP);
  219.     }
  220.  
  221.         if(ub->cmd == CC_ERR)
  222.         {    
  223.             fprintf(stderr,"uploading %s: %s\n",path,ub->buf);
  224.         free(fpath); return(1); 
  225.         }   
  226.  
  227.     if(!bytes && !first) break;
  228.         pos += bytes;
  229.     }
  230.  
  231.     if(client_trace) { fprintf(stderr,"\r%luk : %s \n",pos>>10,path);
  232.                fflush(stderr); }
  233.  
  234.     free(fpath); return(0);
  235. }
  236.  
  237. util_get_env()
  238. {
  239.     if(!(env_host = getenv("FSP_HOST")))
  240.         { fputs("Env var FSP_HOST not defined\n",stderr); exit(1); }
  241.     if(!(env_port = getenv("FSP_PORT")))
  242.         { fputs("Env var FSP_PORT not defined\n",stderr); exit(1); }
  243.     if(!(env_dir  = getenv("FSP_DIR")))
  244.         { fputs("Env var FSP_DIR not defined\n",stderr); exit(1); }
  245.     if(!(env_myport  = getenv("FSP_LOCALPORT")))
  246.         { fputs("Env var FSP_LOCALPORT not defined\n",stderr); exit(1); }
  247.  
  248.     client_trace  = !!getenv("FSP_TRACE");
  249. }
  250.  
  251. client_intr()
  252. {
  253.     switch(client_intr_state)
  254.     {
  255.     case 0: exit(2);
  256.     case 1: client_intr_state = 2; break;
  257.     case 2: exit(3);
  258.     }
  259. }
  260.  
  261. env_client()
  262. {
  263.     util_get_env();
  264.     init_client(env_host,atoi(env_port),atoi(env_myport));
  265.     signal(SIGINT,client_intr);
  266. }
  267.  
  268. /*****************************************************************************/
  269.  
  270. static DDLIST *ddroot = 0;
  271.  
  272. RDIR *util_opendir(path)
  273.     char *path;
  274. {
  275.     char *fpath;
  276.     RDIRENT **dep;
  277.     DDLIST   *ddp;
  278.     RDIR   *rdirp;
  279.  
  280.     fpath = util_abs_path(path);
  281.  
  282.     for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
  283.  
  284.     if(!ddp)
  285.     {
  286.     if(!(dep = get_dir_blk(fpath))) return((RDIR *) 0);
  287.     ddp = (DDLIST *) malloc(sizeof(DDLIST));
  288.     ddp->dep_root = dep;
  289.     ddp->path     = fpath;
  290.     ddp->ref_cnt  = 0;
  291.     ddp->next     = ddroot;
  292.     ddroot        = ddp;
  293.  
  294.     } else free(fpath);
  295.  
  296.     ddp->ref_cnt++;
  297.  
  298.     rdirp = (RDIR *) malloc(sizeof(RDIR));
  299.     rdirp->ddp = ddp;
  300.     rdirp->dep = ddp->dep_root;
  301.     return(rdirp);
  302. }
  303.  
  304. util_closedir(rdirp)
  305.     RDIR *rdirp;
  306. {
  307.     rdirp->ddp->ref_cnt--;
  308.     free(rdirp);
  309. }
  310.  
  311. rdirent *util_readdir(rdirp)
  312.     RDIR *rdirp;
  313. {
  314.     static rdirent rde;
  315.     RDIRENT **dep;
  316.  
  317.     dep = rdirp->dep;
  318.  
  319.     if(!*dep) return((rdirent *) 0);
  320.  
  321.     rde.d_fileno = 10;
  322.     rde.d_reclen = 10;
  323.     rde.d_namlen = strlen((*dep)->name);
  324.     rde.d_name   = (*dep)->name;
  325.     rdirp->dep   = dep+1;
  326.  
  327.     return(&rde);
  328. }
  329.  
  330. util_split_path(path,p1,p2,p3)
  331.     char *path, **p1, **p2, **p3;
  332. {
  333.     char *s;
  334.     static char junk;
  335.  
  336.     *p1 = "/";
  337.     if(*path == '/') { *p2 =  path; *p3 = path+1; }
  338.         else { *p2 = &junk; *p3 = path  ; }
  339.  
  340.     for(s = *p3; *s; s++)
  341.     {
  342.     if(*s == '/')
  343.     {
  344.         *p1 = path;
  345.         *p2 = s;
  346.         *p3 = s+1;
  347.     }
  348.     }
  349.  
  350.     return(1);
  351. }
  352.  
  353. util_stat(path,sbuf)
  354.     char *path;
  355.     struct stat *sbuf;
  356. {
  357.     RDIR *drp;
  358.     RDIRENT **dep;
  359.     char *fpath, *ppath, *p1, *pfile;
  360.  
  361.     fpath = util_abs_path(path);
  362.  
  363.     if(!strcmp(fpath,env_dir))
  364.     {
  365.     ppath = fpath;
  366.     pfile = ".";
  367.  
  368.     } else
  369.     {
  370.     util_split_path(fpath,&ppath,&p1,&pfile); *p1 = 0;
  371.     }
  372.  
  373.     if(drp = util_opendir(ppath))
  374.     {
  375.     for(dep = drp->dep; *dep; dep++)
  376.     {
  377.         if(!strcmp((*dep)->name,pfile))
  378.         {
  379.         if((*dep)->type & RDTYPE_DIR) sbuf->st_mode = 0777 | S_IFDIR;
  380.                      else sbuf->st_mode = 0666 | S_IFREG;
  381.  
  382.         if((*dep)->type & RDTYPE_DIR) sbuf->st_nlink  = 2;
  383.                      else sbuf->st_nlink  = 1;
  384.         sbuf->st_uid    = 0;
  385.         sbuf->st_gid    = 0;
  386.         sbuf->st_size   = (*dep)->size;
  387.         sbuf->st_atime  = (*dep)->time;
  388.         sbuf->st_mtime  = (*dep)->time;
  389.         sbuf->st_ctime  = (*dep)->time;
  390.         util_closedir(drp); free(fpath); return(0);
  391.         }
  392.     }
  393.     util_closedir(drp);
  394.     }
  395.  
  396.     free(fpath); errno = ENOENT; return(-1);
  397. }
  398.  
  399. util_cd(p)
  400.     char *p;
  401. {
  402.     char *fpath;
  403.     UBUF *ub;
  404.     DDLIST   *ddp;
  405.  
  406.     fpath = util_abs_path(p);
  407.     for(ddp = ddroot; ddp; ddp = ddp->next) if(!strcmp(ddp->path,fpath)) break;
  408.  
  409.     if(!ddp)
  410.     {
  411.     ub = client_interact(CC_GET_DIR,0L, strlen(fpath),fpath+1, 0,NULLP);
  412.  
  413.     if(ub->cmd == CC_ERR)
  414.     {
  415.         free(fpath);
  416.         fprintf(stderr,"cd error: %s\n",ub->buf);
  417.         errno = EACCES;
  418.         return(-1);
  419.     }
  420.     }
  421.  
  422.     if(env_dir_malloced) free(env_dir);
  423.     env_dir_malloced = 1;
  424.     env_dir = fpath;
  425.     return(0);
  426. }
  427.