Annotation of researchv10no/cmd/bcp/Path.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                      2: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                      3: /* The copyright notice does not imply actual or intended publication. */
                      4: /* AUTHORS:                                            */
                      5: /*     H. S. Baird - ATT-BL MH - first versions        */
                      6: /* Path.c - Path functions */
                      7: 
                      8: #include <errno.h>
                      9: #include <stdio.h>
                     10: #include <string.h>
                     11: #define FILE_TREE_INCL 1
                     12: #include "CPU.h"
                     13: #include "Path.h"
                     14: 
                     15: #define dbg_FTW (0)
                     16: 
                     17: /* Return full path string in Path *pp, starting at level `sl';
                     18:    if the level is too deep or the name at level `sl' is null, return null string.
                     19:    */
                     20: char *path_toa(pp,sl)
                     21:     Path *pp;
                     22:     int sl;    /* starting level: 0 is first */
                     23: {   int len,lvl;
                     24:     static char s[MAX_PATH_DEPTH*(32)];
                     25:        s[0] = '\0';
                     26:        if( sl<=pp->level && pp->name[sl]!=NULL && pp->name[sl][0]!='\0' ) {
                     27:                for(lvl=sl; lvl<=pp->level; lvl++) {
                     28:                        strcat(s,pp->name[lvl]);
                     29:                        strcat(s,"/");
                     30:                        };
                     31:                };
                     32:        if((len=strlen(s))>0) s[len-1] = '\0';
                     33:        return(s);
                     34:        }
                     35: 
                     36: /* no. slashes in a name */
                     37: int slashes(n)
                     38:     char *n;
                     39: {   register int res;
                     40:     register char *c;
                     41:        res=0;
                     42:        c=n;
                     43:        while(*c!='\0') {
                     44:                if(*c=='/') res++;
                     45:                c++;
                     46:                };
                     47:        return(res);
                     48:        }
                     49: 
                     50: /* basename */
                     51: char *bname(n)
                     52:     char *n;
                     53: {   register char *res,*c;
                     54:        res=n-1;
                     55:        c=n;
                     56:        while(*c!='\0') {
                     57:                if(*c=='/') res=c;
                     58:                c++;
                     59:                };
                     60:        return(res+1);
                     61:        }
                     62: 
                     63: #if CPU==VAX || CPU==CRAY
                     64: 
                     65: int process_file_tree_node(n,s,code,S)
                     66:     char *n;
                     67:     struct stat *s;
                     68:     int code;
                     69:     struct FTW *S;
                     70: /* Uses global `path_process' structure */
                     71: {   char *out_n;
                     72:     int persist;
                     73:     struct stat sbuf;
                     74:        switch(code) {
                     75:           case FTW_F:  if(dbg_FTW)err("visit file %s %s %d",n,n+(S->base),S->level);
                     76:                        if(S->level>0) {
                     77:                                if(path_process.path.name[S->level]!=NULL)
                     78:                                        free(path_process.path.name[S->level]);
                     79:                                path_process.path.name[S->level]=strdup(n+(S->base));
                     80:                                };
                     81:                        path_process.path.level = S->level;
                     82:                        out_n = strdup(path_toa(&path_process.path,0));
                     83:                        if(dbg_FTW)err("file: %s ==> %s",n,out_n);
                     84:                        (*path_process.process)(n,out_n,path_process.arg);
                     85:                        if(out_n!=NULL) free(out_n);
                     86:                        break;
                     87:           case FTW_SL: if(dbg_FTW)err("visit link %s %s %d",n,n+(S->base),S->level);
                     88:                        S->quit = FTW_FOLLOW;    /* follow symbolic link */
                     89:                        break;
                     90:           case FTW_D:  /* pre-visit of directory */
                     91:                        if(dbg_FTW)err("visit dir %s %s %d",n,n+(S->base),S->level);
                     92:                        if(S->level>0) {
                     93:                                if(path_process.path.name[S->level]!=NULL)
                     94:                                        free(path_process.path.name[S->level]);
                     95:                                path_process.path.name[S->level]=strdup(n+(S->base));
                     96:                                };
                     97:                        path_process.path.level = S->level;
                     98:                        out_n = path_toa(&path_process.path,0);
                     99:                        if(dbg_FTW)err("dir:   %s --> %s",n,out_n);
                    100:                        if(out_n[0]=='\0') /* no output name */ break;
                    101:                        /* ensure directory named out_n exists */
                    102:                        if(stat(out_n,&sbuf)==0) {
                    103:                                /* file exists */
                    104:                                if(!(sbuf.st_mode&S_IFDIR)) {
                    105:                                        /* not a directory - try to remove */
                    106:                                        if(unlink(out_n)==0) {
                    107:                                                if(mkdir(out_n,0777)!=0) {
                    108:                                                        /* irrecoverable mkdir */
                    109:                                                        abort("can't mkdir %s",
                    110:                                                                out_n);
                    111:                                                        };
                    112:                                                }
                    113:                                        else {  /* irrecoverable unlink */
                    114:                                                abort("can't unlink %s",out_n);
                    115:                                                };
                    116:                                        };
                    117:                                }
                    118:                        else if(errno==ENOENT) {
                    119:                                /* file doesn't exist */
                    120:                                if(mkdir(out_n,0777)!=0) {
                    121:                                        /* irrecoverable mkdir */
                    122:                                        abort("can't mkdir %s",out_n);
                    123:                                        };
                    124:                                }
                    125:                        else {  /* irrecoverable stat */
                    126:                                abort("can't stat %s",out_n);
                    127:                                };
                    128:                        break;
                    129:           case FTW_DP: /* post-visit of directory: ignore it*/
                    130:                        break;
                    131:           case FTW_DNR:
                    132:                        err("can't read dir %s (FTW_DNR) - ignore it",n);
                    133:                        break;
                    134:           case FTW_NS:
                    135:                        err("can't stat %s (FTW_NS) - ignore it",n);
                    136:                        break;
                    137:           case FTW_NSL:
                    138:                        if(0)   /* happens if file is missing */
                    139:                        err("can't stat symbolic link %s (FTW_NSL) - ignore it",n);
                    140:                        break;
                    141:           default:
                    142:                        err("unexpected FTW code %d - ignore it",code);
                    143:                        break;
                    144:           };
                    145:        return(0);
                    146:        }
                    147: 
                    148: #else
                    149: #if CPU==MIPS
                    150: int process_file_tree_node(n,s,code)
                    151:     char *n;           /* name of the object */
                    152:     struct stat *s;    /* info. about object */
                    153:     int code;
                    154: /* Uses global `path_process' structure */
                    155: #define lvl path_process.path.level
                    156: {   char *out_n;
                    157:     int persist;
                    158:     struct stat sbuf;
                    159:     char *bn;
                    160:        lvl = slashes(n) - path_process.sl0;
                    161:        bn = bname(n);  
                    162:        switch(code) {
                    163:           case FTW_F:  if(dbg_FTW) err("visit file %s, bn %s, lvl %d",n,bn,lvl);
                    164:                        if(lvl>0) {
                    165:                                if(path_process.path.name[lvl]!=NULL)
                    166:                                        free(path_process.path.name[lvl]);
                    167:                                path_process.path.name[lvl]=strdup(bn);
                    168:                                };
                    169:                        out_n = strdup(path_toa(&path_process.path,0));
                    170:                        if(dbg_FTW)err("file: %s ==> %s",n,out_n);
                    171:                        (*path_process.process)(n,out_n,path_process.arg);
                    172:                        if(out_n!=NULL) free(out_n);
                    173:                        break;
                    174:           case FTW_D:  /* pre-visit of directory */
                    175:                        if(dbg_FTW) err("visit dir %s, bn %s, lvl %d",n,bn,lvl);
                    176:                        if(lvl>0) {
                    177:                                if(path_process.path.name[lvl]!=NULL)
                    178:                                        free(path_process.path.name[lvl]);
                    179:                                path_process.path.name[lvl]=strdup(bn);
                    180:                                };
                    181:                        out_n = path_toa(&path_process.path,0);
                    182:                        if(dbg_FTW)err("dir:  %s --> %s",n,out_n);
                    183:                        if(out_n[0]=='\0') /* no output name */ break;
                    184:                        /* ensure directory named out_n exists */
                    185:                        if(stat(out_n,&sbuf)==0) {
                    186:                                /* file exists */
                    187:                                if(!(sbuf.st_mode&S_IFDIR)) {
                    188:                                        /* not a directory - try to remove */
                    189:                                        if(unlink(out_n)==0) {
                    190:                                                if(mkdir(out_n,0777)!=0) {
                    191:                                                        /* irrecoverable mkdir */
                    192:                                                        abort("can't mkdir %s",
                    193:                                                                out_n);
                    194:                                                        };
                    195:                                                }
                    196:                                        else {  /* irrecoverable unlink */
                    197:                                                abort("can't unlink %s",out_n);
                    198:                                                };
                    199:                                        };
                    200:                                }
                    201:                        else if(errno==ENOENT) {
                    202:                                /* file doesn't exist */
                    203:                                if(mkdir(out_n,0777)!=0) {
                    204:                                        /* irrecoverable mkdir */
                    205:                                        abort("can't mkdir %s",out_n);
                    206:                                        };
                    207:                                }
                    208:                        else {  /* irrecoverable stat */
                    209:                                abort("can't stat %s",out_n);
                    210:                                };
                    211:                        break;
                    212:           case FTW_DNR:
                    213:                        err("can't read dir %s (FTW_DNR) - ignore it",n);
                    214:                        break;
                    215:           case FTW_NS:
                    216:                        err("can't stat %s (FTW_NS) - ignore it",n);
                    217:                        break;
                    218:           default:
                    219:                        err("unexpected FTW code %d - ignore it",code);
                    220:                        break;
                    221:           };
                    222:        return(0);
                    223:        }
                    224: 
                    225: #endif
                    226: #endif
                    227: 
                    228: /* Process every leaf file (non-directory) in the file-tree rooted at `in_ftn'.
                    229:    If `in_ftn' is itself a leaf, then only it is processed.  If it is a directory,
                    230:    then a corresponding file-tree is built, rooted at `out_ftn', and paths
                    231:    to its leaves created by `mkdir's as required;  for each pair of corresponding
                    232:    leaf filenames, `process' is called.  The filenames have not yet been opened.
                    233:    If `out_ftn' is the empty string, then no output file-tree will be generated
                    234:    and the corresponding output filenames will all be null.  If `in_ftn' is the
                    235:    empty string, then `process' is called only once, with the input filename
                    236:    empty.  Pass 'arg' to 'process' as third argument. */
                    237: process_file_trees(process,in_ftn,out_ftn,arg)
                    238:     VOID (*process)();
                    239:     char *in_ftn;      /* may be empty */
                    240:     char *out_ftn;     /* may be empty */
                    241:     VOID *arg;         /* passed to '(*process)()' as 3rd argument */
                    242: /* Uses global `path_process' structure */
                    243: {   int level;
                    244:        if(in_ftn[0]=='\0') (*process)(in_ftn,out_ftn,arg);
                    245:        else {  if(dbg_FTW) err("process_file_trees(%s,%s)",in_ftn,out_ftn);
                    246:                path_process.path.level = 0;
                    247:                path_process.path.name[0] = out_ftn;
                    248:                path_process.sl0 = slashes(in_ftn);
                    249:                for(level=1; level<MAX_PATH_DEPTH; level++)
                    250:                        path_process.path.name[level] = NULL;
                    251:                path_process.process = process;
                    252:                path_process.arg = arg;
                    253:                if(ftw(in_ftn,process_file_tree_node,MAX_PATH_DEPTH)<0)
                    254:                        err("ftw error: errno %d",errno);
                    255:                };
                    256:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.