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