Annotation of researchv10no/cmd/bcp/Path.c, revision 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.