Annotation of researchv9/cmd/cpio.c, revision 1.1.1.1

1.1       root        1: /*     @(#)cpio.c      1.17    */
                      2: /*     cpio    COMPILE:        cc -O cpio.c -s -i -o cpio 
                      3:        cpio -- copy file collections
                      4: 
                      5: */
                      6: #include <stdio.h>
                      7: #include <signal.h>
                      8: #ifdef RT
                      9: #include <rt/macro.h>
                     10: #include <rt/types.h>
                     11: #include <rt/stat.h>
                     12: #else
                     13: #include <sys/types.h>
                     14: #include <sys/stat.h>
                     15: #include <errno.h>
                     16: #endif
                     17: #define EQ(x,y)        (strcmp(x,y)==0)
                     18: /* for VAX, Interdata, ... */
                     19: #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}
                     20: #define MAGIC  070707          /* cpio magic number */
                     21: #define IN     1               /* copy in */
                     22: #define OUT    2               /* copy out */
                     23: #define PASS   3               /* direct copy */
                     24: #define HDRSIZE        (Hdr.h_name - (char *)&Hdr)     /* header size minus filename field */
                     25: #define LINKS  1000            /* max no. of links allowed */
                     26: #define CHARS  76              /* ASCII header size minus filename field */
                     27: #undef BUFSIZE
                     28: #define BUFSIZE 512            /* In u370, can't use BUFSIZ nor BSIZE */
                     29: #define CPIOBSZ 4096           /* file read/write */
                     30: #define MAXFILENAME 14
                     31: #ifdef RT
                     32: extern long filespace;
                     33: #endif
                     34: 
                     35: struct stat    Statb, Xstatb;
                     36: 
                     37:        /* Cpio header format */
                     38: struct header {
                     39:        short   h_magic,
                     40:                h_dev;
                     41:        unsigned
                     42:        short   h_ino,
                     43:                h_mode,
                     44:                h_uid,
                     45:                h_gid;
                     46:        short   h_nlink,
                     47:                h_rdev,
                     48:                h_mtime[2],
                     49:                h_namesize,
                     50:                h_filesize[2];
                     51:        char    h_name[256];
                     52: } Hdr;
                     53: 
                     54: unsigned       Bufsize = BUFSIZE;              /* default record size */
                     55: short  Buf[CPIOBSZ/2], *Dbuf;
                     56: char   BBuf[CPIOBSZ], *Cbuf;
                     57: int    Wct, Wc;
                     58: short  *Wp;
                     59: char   *Cp;
                     60: 
                     61: #ifdef RT
                     62: short  Actual_size[2];
                     63: #endif
                     64: 
                     65: short  Option,
                     66:        Dir,
                     67:        Uncond,
                     68:        Link,
                     69:        Rename,
                     70:        Toc,
                     71:        Verbose,
                     72:        Select,
                     73:        Mod_time,
                     74:        Acc_time,
                     75:        Cflag,
                     76:        fflag,
                     77: #ifdef RT
                     78:        Extent,
                     79: #endif
                     80:        Swap,
                     81:        byteswap,
                     82:        bothswap,
                     83:        halfswap;
                     84: 
                     85: int    Ifile,
                     86:        Ofile,
                     87:        Input = 0,
                     88:        Output = 1;
                     89: long   Blocks,
                     90:        Longfile,
                     91:        Longtime;
                     92: 
                     93: char   Fullname[256],
                     94:        Name[256];
                     95: int    Pathend;
                     96: int    usrmask;
                     97: 
                     98: FILE   *Rtty,
                     99:        *Wtty;
                    100: 
                    101: char   *Pattern[100];
                    102: char   Strhdr[500];
                    103: char   *Chdr = Strhdr;
                    104: short  Dev,
                    105:        Uid,
                    106:        A_directory,
                    107:        A_special,
                    108: #ifdef RT
                    109:        One_extent,
                    110:        Multi_extent,
                    111: #endif
                    112:        Filetype = S_IFMT;
                    113: 
                    114: extern errno;
                    115: char   *malloc();
                    116: char   *cd();
                    117: /*     char    *Cd_name;       */
                    118: FILE   *popen();
                    119: 
                    120: union { long l; short s[2]; char c[4]; } U;
                    121: 
                    122: /* for VAX, Interdata, ... */
                    123: long mklong(v)
                    124: short v[];
                    125: {
                    126:        U.l = 1;
                    127:        if(U.c[0])
                    128:                U.s[0] = v[1], U.s[1] = v[0];
                    129:        else
                    130:                U.s[0] = v[0], U.s[1] = v[1];
                    131:        return U.l;
                    132: }
                    133: 
                    134: main(argc, argv)
                    135: char **argv;
                    136: {
                    137:        register ct;
                    138:        long    filesz;
                    139:        register char *fullp;
                    140:        register i;
                    141:        int ans;
                    142: 
                    143:        signal(SIGSYS, 1);
                    144:        if(*argv[1] != '-')
                    145:                usage();
                    146:        Uid = geteuid();
                    147:        usrmask = umask(0);
                    148:        umask(usrmask);
                    149:        Pattern[0] = "*";
                    150: 
                    151:        while(*++argv[1]) {
                    152:                switch(*argv[1]) {
                    153:                case 'a':               /* reset access time */
                    154:                        Acc_time++;
                    155:                        break;
                    156:                case 'B':               /* change record size to 5120 bytes */
                    157:                        Bufsize = 5120;
                    158:                        break;
                    159:                case 'i':
                    160:                        Option = IN;
                    161:                        if(argc > 2 ) { /* save patterns, if any */
                    162:                                for(i = 0; (i+2) < argc; ++i)
                    163:                                        Pattern[i] = argv[i+2];
                    164:                        }
                    165:                        break;
                    166:                case 'f':       /* do not consider patterns in cmd line */
                    167:                        fflag++;
                    168:                        break;
                    169:                case 'o':
                    170:                        if(argc != 2)
                    171:                                usage();
                    172:                        Option = OUT;
                    173:                        break;
                    174:                case 'p':
                    175:                        if(argc != 3)
                    176:                                usage();
                    177:                        if(access(argv[2], 2) == -1) {
                    178: accerr:
                    179:                                fprintf(stderr,"cannot write in <%s>\n", argv[2]);
                    180:                                exit(2);
                    181:                        }
                    182:                        strcpy(Fullname, argv[2]);      /* destination directory */
                    183:                        strcat(Fullname, "/");
                    184:                        stat(Fullname, &Xstatb);
                    185:                        if((Xstatb.st_mode&S_IFMT) != S_IFDIR)
                    186:                                goto accerr;
                    187:                        Option = PASS;
                    188:                        Dev = Xstatb.st_dev;
                    189:                        break;
                    190:                case 'c':               /* ASCII header */
                    191:                        Cflag++;
                    192:                        break;
                    193:                case 'd':               /* create directories when needed */
                    194:                        Dir++;
                    195:                        break;
                    196:                case 'l':               /* link files, when necessary */
                    197:                        Link++;
                    198:                        break;
                    199:                case 'm':               /* retain mod time */
                    200:                        Mod_time++;
                    201:                        break;
                    202:                case 'r':               /* rename files interactively */
                    203:                        Rename++;
                    204:                        Rtty = fopen("/dev/tty", "r");
                    205:                        Wtty = fopen("/dev/tty", "w");
                    206:                        if(Rtty==NULL || Wtty==NULL) {
                    207:                                fprintf(stderr,
                    208:                                  "Cannot rename (/dev/tty missing)\n");
                    209:                                exit(2);
                    210:                        }
                    211:                        break;
                    212:                case 'S':               /* swap halfwords */
                    213:                        halfswap++;
                    214:                        Swap++;
                    215:                        break;
                    216:                case 's':               /* swap bytes */
                    217:                        byteswap++;
                    218:                        Swap++;
                    219:                        break;
                    220:                case 'b':
                    221:                        bothswap++;
                    222:                        Swap++;
                    223:                        break;
                    224:                case 't':               /* table of contents */
                    225:                        Toc++;
                    226:                        break;
                    227:                case 'u':               /* copy unconditionally */
                    228:                        Uncond++;
                    229:                        break;
                    230:                case 'v':               /* verbose table of contents */
                    231:                        Verbose++;
                    232:                        break;
                    233:                case '6':               /* for old, sixth-edition files */
                    234:                        Filetype = 060000;
                    235:                        break;
                    236: #ifdef RT
                    237:                case 'e':
                    238:                        Extent++;
                    239:                        break;
                    240: #endif
                    241:                default:
                    242:                        usage();
                    243:                }
                    244:        }
                    245:        if(!Option) {
                    246:                fprintf(stderr,"Options must include o|i|p\n");
                    247:                exit(2);
                    248:        }
                    249: #ifdef RT
                    250:                setio(-1,1);    /* turn on physio */
                    251: #endif
                    252: 
                    253:        if(Option == PASS) {
                    254:                if(Rename) {
                    255:                        fprintf(stderr,"Pass and Rename cannot be used together\n");
                    256:                        exit(2);
                    257:                }
                    258:                if(Bufsize == 5120) {
                    259:                        printf("`B' option is irrelevant with the '-p' option\n");
                    260:                        Bufsize = BUFSIZE;
                    261:                }
                    262: 
                    263:        }else  {
                    264:                if(Cflag)
                    265:                    Cp = Cbuf = (char *)malloc(Bufsize);
                    266:                else
                    267:                    Wp = Dbuf = (short *)malloc(Bufsize);
                    268:        }
                    269:        Wct = Bufsize >> 1;
                    270:        Wc = Bufsize;
                    271: 
                    272:        switch(Option) {
                    273: 
                    274:        case OUT:               /* get filename, copy header and file out */
                    275:                while(getname()) {
                    276:                        if( mklong(Hdr.h_filesize) == 0L) {
                    277:                           if( Cflag )
                    278:                                writehdr(Chdr,CHARS+Hdr.h_namesize);
                    279:                           else
                    280:                                bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
                    281: #ifdef RT
                    282:                        if (One_extent || Multi_extent) {
                    283:                           actsize(0);
                    284:                           if( Cflag )
                    285:                                writehdr(Chdr,CHARS+Hdr.h_namesize);
                    286:                           else
                    287:                                bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
                    288:                        }
                    289: #endif
                    290:                                continue;
                    291:                        }
                    292:                        if((Ifile = open(Hdr.h_name, 0)) < 0) {
                    293:                                fprintf(stderr,"<%s> ?\n", Hdr.h_name);
                    294:                                continue;
                    295:                        }
                    296:                        if ( Cflag )
                    297:                                writehdr(Chdr,CHARS+Hdr.h_namesize);
                    298:                        else
                    299:                                bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
                    300: #ifdef RT
                    301:                        if (One_extent || Multi_extent) {
                    302:                           actsize(Ifile);
                    303:                           if(Cflag)
                    304:                                writehdr(Chdr,CHARS+Hdr.h_namesize);
                    305:                           else
                    306:                                bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
                    307:                           Hdr.h_filesize[0] = Actual_size[0];
                    308:                           Hdr.h_filesize[1] = Actual_size[1];
                    309:                        }
                    310: #endif
                    311:                        for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){
                    312:                                ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
                    313:                                if(read(Ifile, Cflag? BBuf: (char *)Buf, ct) < 0) {
                    314:                                        fprintf(stderr,"Cannot read %s\n", Hdr.h_name);
                    315:                                        continue;
                    316:                                }
                    317:                                Cflag? writehdr(BBuf,ct): bwrite(Buf,ct);
                    318:                        }
                    319:                        close(Ifile);
                    320:                        if(Acc_time)
                    321:                                utime(Hdr.h_name, &Statb.st_atime);
                    322:                        if(Verbose)
                    323:                                fprintf(stderr,"%s\n", Hdr.h_name);
                    324:                }
                    325: 
                    326:        /* copy trailer, after all files have been copied */
                    327:                strcpy(Hdr.h_name, "TRAILER!!!");
                    328:                Hdr.h_magic = MAGIC;
                    329:                MKSHORT(Hdr.h_filesize, 0L);
                    330:                Hdr.h_namesize = strlen("TRAILER!!!") + 1;
                    331:                if ( Cflag )  {
                    332:                        bintochar(0L);
                    333:                        writehdr(Chdr,CHARS+Hdr.h_namesize);
                    334:                }
                    335:                else
                    336:                        bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
                    337:                Cflag? writehdr(Cbuf, Bufsize): bwrite(Dbuf, Bufsize);
                    338:                break;
                    339: 
                    340:        case IN:
                    341:                pwd();
                    342:                while(gethdr()) {
                    343:                        Ofile = ckname(Hdr.h_name)? openout(Hdr.h_name): 0;
                    344:                        for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){
                    345:                                ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
                    346:                                Cflag? readhdr(BBuf,ct): bread(Buf, ct);
                    347:                                if(Ofile) {
                    348:                                        if(Swap)
                    349:                                           Cflag? swap(BBuf,ct): swap(Buf,ct);
                    350:                                        if(write(Ofile, Cflag? BBuf: (char *)Buf, ct) < 0) {
                    351:                                         fprintf(stderr,"Cannot write %s\n", Hdr.h_name);
                    352:                                         continue;
                    353:                                        }
                    354:                                }
                    355:                        }
                    356:                        if(Ofile) {
                    357:                                close(Ofile);
                    358:                                if(chmod(Hdr.h_name, Hdr.h_mode) < 0) {
                    359:                                        fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno);
                    360:                                }
                    361:                                set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
                    362:                        }
                    363:                        if(!Select)
                    364:                                continue;
                    365:                        if(Verbose)
                    366:                                if(Toc)
                    367:                                        pentry(Hdr.h_name);
                    368:                                else
                    369:                                        puts(Hdr.h_name);
                    370:                        else if(Toc)
                    371:                                puts(Hdr.h_name);
                    372:                }
                    373:                break;
                    374: 
                    375:        case PASS:              /* move files around */
                    376:                fullp = Fullname + strlen(Fullname);
                    377: 
                    378:                while(getname()) {
                    379:                        if (A_directory && !Dir)
                    380:                                fprintf(stderr,"Use `-d' option to copy <%s>\n",Hdr.h_name);
                    381:                        if(!ckname(Hdr.h_name))
                    382:                                continue;
                    383:                        i = 0;
                    384:                        while(Hdr.h_name[i] == '/')
                    385:                                i++;
                    386:                        strcpy(fullp, &(Hdr.h_name[i]));
                    387: 
                    388:                        if(Link
                    389:                        && !A_directory
                    390:                        && Dev == Statb.st_dev)  {
                    391: /* ???                 && (Uid == Statb.st_uid || !Uid)) {*/
                    392:                                if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */
                    393:                                        if(errno == EEXIST)
                    394:                                                fprintf(stderr, "Cannot link <%s> & <%s> (errno:%d)\n",
                    395:                                                 Hdr.h_name, Fullname, errno);
                    396:                                        else {
                    397:                                                unlink(Fullname);
                    398:                                                missdir(Fullname);
                    399:                                                if(link(Hdr.h_name, Fullname) < 0) {
                    400:                                                        fprintf(stderr, "Cannot link <%s> & <%s> (errno:%d)\n", Hdr.h_name, Fullname, errno);
                    401:                                                        continue;
                    402:                                                }
                    403:                                        }
                    404:                                }
                    405: 
                    406: /* try creating (only twice) */
                    407:                                ans = 0;
                    408:                                do {
                    409:                                        if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */
                    410:                                                if(errno == EEXIST) {
                    411:                                                        ans = 3;
                    412:                                                        break;
                    413:                                                        }
                    414:                                                else
                    415:                                                        unlink(Fullname);
                    416:                                                ans += 1;
                    417:                                        }else {
                    418:                                                ans = 0;
                    419:                                                break;
                    420:                                        }
                    421:                                }while(ans < 2 && missdir(Fullname) == 0);
                    422:                                if(ans == 1) {
                    423:                                        fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", Fullname, errno);
                    424:                                        exit(0);
                    425:                                }else if(ans == 2) {
                    426:                                        fprintf(stderr,"Cannot link <%s> & <%s> (errno:%d)\n", Hdr.h_name, Fullname, errno);
                    427:                                        exit(0);
                    428:                                }
                    429: 
                    430:                                if(!Link)
                    431:                                        if(chmod(Hdr.h_name, Hdr.h_mode) < 0) {
                    432:                                                fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno);
                    433:                                        }
                    434:                                set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
                    435:                                goto ckverbose;
                    436:                        }
                    437: #ifdef RT
                    438:                        if (One_extent || Multi_extent)
                    439:                                actsize(0);
                    440: #endif
                    441:                        if(!(Ofile = openout(Fullname)))
                    442:                                continue;
                    443:                        if((Ifile = open(Hdr.h_name, 0)) < 0) {
                    444:                                fprintf(stderr,"<%s> ?\n", Hdr.h_name);
                    445:                                close(Ofile);
                    446:                                continue;
                    447:                        }
                    448:                        filesz = Statb.st_size;
                    449:                        for(; filesz > 0; filesz -= CPIOBSZ) {
                    450:                                ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
                    451:                                if(read(Ifile, Buf, ct) < 0) {
                    452:                                        fprintf(stderr,"Cannot read %s\n", Hdr.h_name);
                    453:                                        break;
                    454:                                }
                    455:                                if(Ofile)
                    456:                                        if(write(Ofile, Buf, ct) < 0) {
                    457:                                         fprintf(stderr,"Cannot write %s\n", Hdr.h_name);
                    458:                                         break;
                    459:                                        }
                    460: #ifndef u370
                    461:                                Blocks += ((ct + (BUFSIZE - 1)) / BUFSIZE);
                    462: #else
                    463:                                ++Blocks;
                    464: #endif
                    465:                        }
                    466:                        close(Ifile);
                    467:                        if(Acc_time)
                    468:                                utime(Hdr.h_name, &Statb.st_atime);
                    469:                        if(Ofile) {
                    470:                                close(Ofile);
                    471:                                if(chmod(Fullname, Hdr.h_mode) < 0) {
                    472:                                        fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Fullname, errno);
                    473:                                }
                    474:                                set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime));
                    475: ckverbose:
                    476:                                if(Verbose)
                    477:                                        puts(Fullname);
                    478:                        }
                    479:                }
                    480:        }
                    481:        /* print number of blocks actually copied */
                    482:           fprintf(stderr,"%ld blocks\n", Blocks * (Bufsize>>9));
                    483:        exit(0);
                    484: }
                    485: usage()
                    486: {
                    487:        fprintf(stderr,"Usage: cpio -o[acvB] <name-list >collection\n%s\n%s\n",
                    488:        "       cpio -i[cdmrstuvfB6] [pattern ...] <collection",
                    489:        "       cpio -p[adlmruv] directory <name-list");
                    490:        exit(2);
                    491: }
                    492: 
                    493: getname()              /* get file name, get info for header */
                    494: {
                    495:        register char *namep = Name;
                    496:        register unsigned short ftype;
                    497:        long tlong;
                    498: 
                    499:        for(;;) {
                    500:                if(gets(namep) == NULL)
                    501:                        return 0;
                    502:                if(*namep == '.' && namep[1] == '/') {
                    503:                        namep++;
                    504:                        while(*namep == '/') namep++;
                    505:                }
                    506:                strcpy(Hdr.h_name, namep);
                    507:                if(stat(namep, &Statb) < 0) {
                    508:                        fprintf(stderr,"< %s > ?\n", Hdr.h_name);
                    509:                        continue;
                    510:                }
                    511:                ftype = Statb.st_mode & Filetype;
                    512:                A_directory = (ftype == S_IFDIR);
                    513:                A_special = (ftype == S_IFBLK)
                    514:                        || (ftype == S_IFCHR)
                    515: #ifdef UX3
                    516:                        || (ftype == S_IFIFO)
                    517: #endif
                    518:                        ;
                    519: #ifdef RT
                    520:                A_special |= (ftype == S_IFREC);
                    521:                One_extent = (ftype == S_IF1EXT);
                    522:                Multi_extent = (ftype == S_IFEXT);
                    523: #endif
                    524:                Hdr.h_magic = MAGIC;
                    525:                Hdr.h_namesize = strlen(Hdr.h_name) + 1;
                    526:                Hdr.h_uid = Statb.st_uid;
                    527:                Hdr.h_gid = Statb.st_gid;
                    528:                Hdr.h_dev = Statb.st_dev;
                    529:                Hdr.h_ino = Statb.st_ino;
                    530:                Hdr.h_mode = Statb.st_mode;
                    531:                MKSHORT(Hdr.h_mtime, Statb.st_mtime);
                    532:                Hdr.h_nlink = Statb.st_nlink;
                    533:                tlong = (Hdr.h_mode&S_IFMT) == S_IFREG? Statb.st_size: 0L;
                    534: #ifdef RT
                    535:                if (One_extent || Multi_extent) tlong = Statb.st_size;
                    536: #endif
                    537:                MKSHORT(Hdr.h_filesize, tlong);
                    538:                Hdr.h_rdev = Statb.st_rdev;
                    539:                if( Cflag )
                    540:                   bintochar(tlong);
                    541:                return 1;
                    542:        }
                    543: }
                    544: 
                    545: bintochar(t)           /* ASCII header write */
                    546: long t;
                    547: {
                    548:        sprintf(Chdr,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s",
                    549:                MAGIC,Statb.st_dev,Statb.st_ino,Statb.st_mode,
                    550:                Statb.st_uid & 00000177777, Statb.st_gid & 00000177777,
                    551:                Statb.st_nlink,Statb.st_rdev & 00000177777,
                    552:                Statb.st_mtime,(short)strlen(Hdr.h_name)+1,t,Hdr.h_name);
                    553: }
                    554: 
                    555: chartobin()            /* ASCII header read */
                    556: {
                    557:        sscanf(Chdr,"%6ho%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo",
                    558:                &Hdr.h_magic,&Hdr.h_dev,&Hdr.h_ino,&Hdr.h_mode,&Hdr.h_uid,
                    559:                &Hdr.h_gid,&Hdr.h_nlink,&Hdr.h_rdev,&Longtime,&Hdr.h_namesize,
                    560:                &Longfile);
                    561:        MKSHORT(Hdr.h_filesize, Longfile);
                    562:        MKSHORT(Hdr.h_mtime, Longtime);
                    563: }
                    564: 
                    565: gethdr()               /* get file headers */
                    566: {
                    567:        register unsigned short ftype;
                    568: 
                    569:        if (Cflag)  {
                    570:                readhdr(Chdr,CHARS);
                    571:                chartobin();
                    572:        }
                    573:        else
                    574:                bread(&Hdr, HDRSIZE);
                    575: 
                    576:        if(Hdr.h_magic != MAGIC) {
                    577:                fprintf(stderr,"Out of phase--get help\n");
                    578:                fprintf(stderr,"Perhaps the \"-c\" option should be used\n");
                    579:                exit(2);
                    580:        }
                    581:        if(Cflag)
                    582:                readhdr(Hdr.h_name, Hdr.h_namesize);
                    583:        else
                    584:                bread(Hdr.h_name, Hdr.h_namesize);
                    585:        if(EQ(Hdr.h_name, "TRAILER!!!"))
                    586:                return 0;
                    587:        ftype = Hdr.h_mode & Filetype;
                    588:        A_directory = (ftype == S_IFDIR);
                    589:        A_special =(ftype == S_IFBLK)
                    590:                || (ftype == S_IFCHR)
                    591: #ifdef UX3
                    592:                || (ftype == S_IFIFO)
                    593: #endif
                    594:                ;
                    595: #ifdef RT
                    596:        A_special |= (ftype == S_IFREC);
                    597:        One_extent = (ftype == S_IF1EXT);
                    598:        Multi_extent = (ftype == S_IFEXT);
                    599:        if (One_extent || Multi_extent) {
                    600:                Actual_size[0] = Hdr.h_filesize[0];
                    601:                Actual_size[1] = Hdr.h_filesize[1];
                    602:                if (Cflag)  {
                    603:                        readhdr(Chdr,CHARS);
                    604:                        chartobin();
                    605:                }
                    606:                else
                    607:                        bread(&Hdr, HDRSIZE);
                    608:        
                    609:                if(Hdr.h_magic != MAGIC) {
                    610:                        fprintf(stderr,"Out of phase--get RT help\n");
                    611:                        fprintf(stderr,"Perhaps the \"-c\" option should be used\n");
                    612:                        exit(2);
                    613:                }
                    614:                if(Cflag)
                    615:                        readhdr(Hdr.h_name, Hdr.h_namesize);
                    616:                else
                    617:                        bread(Hdr.h_name, Hdr.h_namesize);
                    618:        }
                    619: #endif
                    620:        return 1;
                    621: }
                    622: 
                    623: ckname(namep)  /* check filenames with patterns given on cmd line */
                    624: register char *namep;
                    625: {
                    626:        ++Select;
                    627:        if(fflag ^ !nmatch(namep, Pattern)) {
                    628:                Select = 0;
                    629:                return 0;
                    630:        }
                    631:        if(Rename && !A_directory) {    /* rename interactively */
                    632:                fprintf(Wtty, "Rename <%s>\n", namep);
                    633:                fflush(Wtty);
                    634:                fgets(namep, 128, Rtty);
                    635:                if(feof(Rtty))
                    636:                        exit(2);
                    637:                namep[strlen(namep) - 1] = '\0';
                    638:                if(EQ(namep, "")) {
                    639:                        printf("Skipped\n");
                    640:                        return 0;
                    641:                }
                    642:        }
                    643:        return !Toc;
                    644: }
                    645: 
                    646: openout(namep) /* open files for writing, set all necessary info */
                    647: register char *namep;
                    648: {
                    649:        register f;
                    650:        register char *np;
                    651:        int ans;
                    652: 
                    653:        if(!strncmp(namep, "./", 2))
                    654:                namep += 2;
                    655:        fixname(namep);
                    656:        np = namep;
                    657: /*
                    658:        if(Option == IN)
                    659:                Cd_name = namep = cd(namep);
                    660: */
                    661:        if(A_directory) {
                    662:                if(!Dir
                    663:                || Rename
                    664:                || EQ(namep, ".")
                    665:                || EQ(namep, ".."))     /* do not consider . or .. files */
                    666:                        return 0;
                    667:                if(stat(namep, &Xstatb) == -1) {
                    668: 
                    669: /* try creating (only twice) */
                    670:                        ans = 0;
                    671:                        do {
                    672:                                if(makdir(namep) != 0) {
                    673:                                        ans += 1;
                    674:                                }else {
                    675:                                        ans = 0;
                    676:                                        break;
                    677:                                }
                    678:                        }while(ans < 2 && missdir(namep) == 0);
                    679:                        if(ans == 1) {
                    680:                                fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
                    681:                                return(0);
                    682:                        }else if(ans == 2) {
                    683:                                fprintf(stderr,"Cannot create directory <%s> (errno:%d)\n", namep, errno);
                    684:                                return(0);
                    685:                        }
                    686:                }
                    687: 
                    688: ret:
                    689:                if(chmod(namep, Hdr.h_mode) < 0) {
                    690:                        fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", namep, errno);
                    691:                }
                    692:                if(Uid == 0)
                    693:                        if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) {
                    694:                                fprintf(stderr,"Cannot chown <%s> (errno:%d)\n", namep, errno);
                    695:                        }
                    696:                set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
                    697:                return 0;
                    698:        }
                    699:        if(Hdr.h_nlink > 1)
                    700:                if(!postml(namep, np))
                    701:                        return 0;
                    702:        if(stat(namep, &Xstatb) == 0) {
                    703:                if(Uncond && !((!(Xstatb.st_mode & S_IWRITE) || A_special) && (Uid != 0))) {
                    704:                        if(unlink(namep) < 0) {
                    705:                                fprintf(stderr,"cannot unlink current <%s> (errno:%d)\n", namep, errno);
                    706:                        }
                    707:                }
                    708:                if(!Uncond && (mklong(Hdr.h_mtime) <= Xstatb.st_mtime)) {
                    709:                /* There's a newer version of file on destination */
                    710:                        if(mklong(Hdr.h_mtime) < Xstatb.st_mtime)
                    711:                                fprintf(stderr,"current <%s> newer\n", np);
                    712:                        return 0;
                    713:                }
                    714:        }
                    715:        if(Option == PASS
                    716:        && Hdr.h_ino == Xstatb.st_ino
                    717:        && Hdr.h_dev == Xstatb.st_dev) {
                    718:                fprintf(stderr,"Attempt to pass file to self!\n");
                    719:                exit(2);
                    720:        }
                    721:        if(A_special) {
                    722: #ifdef UX3
                    723:                if((Hdr.h_mode & Filetype) == S_IFIFO)
                    724:                        Hdr.h_rdev = 0;
                    725: #endif
                    726: 
                    727: /* try creating (only twice) */
                    728:                ans = 0;
                    729:                do {
                    730:                        if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) {
                    731:                                ans += 1;
                    732:                        }else {
                    733:                                ans = 0;
                    734:                                break;
                    735:                        }
                    736:                }while(ans < 2 && missdir(np) == 0);
                    737:                if(ans == 1) {
                    738:                        fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
                    739:                        return(0);
                    740:                }else if(ans == 2) {
                    741:                        fprintf(stderr,"Cannot mknod <%s> (errno:%d)\n", namep, errno);
                    742:                        return(0);
                    743:                }
                    744: 
                    745:                goto ret;
                    746:        }
                    747: #ifdef RT
                    748:        if(One_extent || Multi_extent) {
                    749: 
                    750: /* try creating (only twice) */
                    751:                ans = 0;
                    752:                do {
                    753:                        if((f = falloc(namep, Hdr.h_mode, longword(Hdr.h_filesize[0]))) < 0) {
                    754:                                ans += 1;
                    755:                        }else {
                    756:                                ans = 0;
                    757:                                break;
                    758:                        }
                    759:                }while(ans < 2 && missdir(np) == 0);
                    760:                if(ans == 1) {
                    761:                        fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
                    762:                        return(0);
                    763:                }else if(ans == 2) {
                    764:                        fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno);
                    765:                        return(0);
                    766:                }
                    767: 
                    768:                if(filespace < longword(Hdr.h_filesize[0])){
                    769:                        fprintf(stderr,"Cannot create contiguous file <%s> proper size\n", namep);
                    770:                        fprintf(stderr,"    <%s> will be created as a regular file\n", namep);
                    771:                        if(unlink(Fullname) != 0)
                    772:                                fprintf(stderr,"<%s> not removed\n", namep);
                    773:                        Hdr.h_mode = (Hdr.h_mode & !S_IFMT) | S_IFREG;
                    774:                        One_extent = Multi_extent = 0;
                    775:                }
                    776:        Hdr.h_filesize[0] = Actual_size[0];
                    777:        Hdr.h_filesize[1] = Actual_size[1];
                    778:        }
                    779:        if (!(One_extent || Multi_extent)) {
                    780: #endif
                    781: 
                    782: /* try creating (only twice) */
                    783:        ans = 0;
                    784:        do {
                    785:                if((f = creat(namep, ~usrmask)) < 0) {
                    786:                        ans += 1;
                    787:                }else {
                    788:                        ans = 0;
                    789:                        break;
                    790:                }
                    791:        }while(ans < 2 && missdir(np) == 0);
                    792:        if(ans == 1) {
                    793:                fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno);
                    794:                return(0);
                    795:        }else if(ans == 2) {
                    796:                fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno);
                    797:                return(0);
                    798:        }
                    799: 
                    800: #ifdef RT
                    801:        }
                    802: #endif
                    803:        if(Uid == 0)
                    804:                chown(namep, Hdr.h_uid, Hdr.h_gid);
                    805:        return f;
                    806: }
                    807: 
                    808: bread(b, c)
                    809: register c;
                    810: register short *b;
                    811: {
                    812:        static nleft = 0;
                    813:        static short *ip;
                    814:        register int rv;
                    815:        register short *p = ip;
                    816:        register int in;
                    817: 
                    818:        c = (c+1)>>1;
                    819:        while(c--) {
                    820:                if(nleft == 0) {
                    821:                        in = 0;
                    822:                        while((rv=read(Input, &(((char *)Dbuf)[in]), Bufsize - in)) != Bufsize - in) {
                    823:                                if(rv <= 0) {
                    824:                                        Input = chgreel(0, Input);
                    825:                                        continue;
                    826:                                }
                    827:                                in += rv;
                    828:                                nleft += (rv >> 1);
                    829:                        }
                    830:                        nleft += (rv >> 1);
                    831:                        p = Dbuf;
                    832:                        ++Blocks;
                    833:                }
                    834:                *b++ = *p++;
                    835:                --nleft;
                    836:        }
                    837:        ip = p;
                    838: }
                    839: 
                    840: readhdr(b, c)
                    841: register c;
                    842: register char *b;
                    843: {
                    844:        static nleft = 0;
                    845:        static char *ip;
                    846:        register int rv;
                    847:        register char *p = ip;
                    848:        register int in;
                    849: 
                    850:        while(c--)  {
                    851:                if(nleft == 0) {
                    852:                        in = 0;
                    853:                        while((rv=read(Input, &(((char *)Cbuf)[in]), Bufsize - in)) != Bufsize - in) {
                    854:                                if(rv <= 0) {
                    855:                                        Input = chgreel(0, Input);
                    856:                                        continue;
                    857:                                }
                    858:                                in += rv;
                    859:                                nleft += rv;
                    860:                        }
                    861:                        nleft += rv;
                    862:                        p = Cbuf;
                    863:                        ++Blocks;
                    864:                }
                    865:                *b++ = *p++;
                    866:                --nleft;
                    867:        }
                    868:        ip = p;
                    869: }
                    870: 
                    871: bwrite(rp, c)
                    872: register short *rp;
                    873: register c;
                    874: {
                    875:        register short *wp = Wp;
                    876: 
                    877:        c = (c+1) >> 1;
                    878:        while(c--) {
                    879:                if(!Wct) {
                    880: again:
                    881:                        if(write(Output, Dbuf, Bufsize)<0) {
                    882:                                Output = chgreel(1, Output);
                    883:                                goto again;
                    884:                        }
                    885:                        Wct = Bufsize >> 1;
                    886:                        wp = Dbuf;
                    887:                        ++Blocks;
                    888:                }
                    889:                *wp++ = *rp++;
                    890:                --Wct;
                    891:        }
                    892:        Wp = wp;
                    893: }
                    894: 
                    895: writehdr(rp, c)
                    896: register char *rp;
                    897: register c;
                    898: {
                    899:        register char *cp = Cp;
                    900: 
                    901:        while(c--)  {
                    902:                if(!Wc)  {
                    903: again:
                    904:                        if(write(Output,Cbuf,Bufsize)<0)  {
                    905:                                Output = chgreel(1,Output);
                    906:                                goto again;
                    907:                        }
                    908:                        Wc = Bufsize;
                    909:                        cp = Cbuf;
                    910:                        ++Blocks;
                    911:                }
                    912:                *cp++ = *rp++;
                    913:                --Wc;
                    914:        }
                    915:        Cp = cp;
                    916: }
                    917: 
                    918: postml(namep, np)              /* linking funtion */
                    919: register char *namep, *np;
                    920: {
                    921:        register i;
                    922:        static struct ml {
                    923:                short   m_dev,
                    924:                        m_ino;
                    925:                char    m_name[2];
                    926:        } *ml[LINKS];
                    927:        static  mlinks = 0;
                    928:        char *mlp;
                    929:        int ans;
                    930: 
                    931:        for(i = 0; i < mlinks; ++i) {
                    932:                if(mlinks == LINKS) break;
                    933:                if(ml[i]->m_ino==Hdr.h_ino &&
                    934:                        ml[i]->m_dev==Hdr.h_dev) {
                    935:                        if(Verbose)
                    936:                          printf("%s linked to %s\n", ml[i]->m_name,
                    937:                                np);
                    938:                        unlink(namep);
                    939:                        if(Option == IN && *ml[i]->m_name != '/') {
                    940:                                Fullname[Pathend] = '\0';
                    941:                                strcat(Fullname, ml[i]->m_name);
                    942:                                mlp = Fullname;
                    943:                        }
                    944:                        mlp = ml[i]->m_name;
                    945: 
                    946: /* try linking (only twice) */
                    947:                        ans = 0;
                    948:                        do {
                    949:                                if(link(mlp, namep) < 0) {
                    950:                                        ans += 1;
                    951:                                }else {
                    952:                                        ans = 0;
                    953:                                        break;
                    954:                                }
                    955:                        }while(ans < 2 && missdir(np) == 0);
                    956:                        if(ans == 1) {
                    957:                                fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", np, errno);
                    958:                                return(0);
                    959:                        }else if(ans == 2) {
                    960:                                fprintf(stderr,"Cannot link <%s> & <%s> (errno:%d)\n", ml[i]->m_name, np, errno);
                    961:                                return(0);
                    962:                        }
                    963: 
                    964:                        set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
                    965:                        return 0;
                    966:                }
                    967:        }
                    968:        if(mlinks == LINKS
                    969:        || !(ml[mlinks] = (struct ml *)malloc(strlen(np) + 2 + sizeof(struct ml)))) {
                    970:                static int first=1;
                    971: 
                    972:                if(first)
                    973:                        if(mlinks == LINKS)
                    974:                                fprintf(stderr,"Too many links\n");
                    975:                        else
                    976:                                fprintf(stderr,"No memory for links\n");
                    977:                mlinks = LINKS;
                    978:                first = 0;
                    979:                return 1;
                    980:        }
                    981:        ml[mlinks]->m_dev = Hdr.h_dev;
                    982:        ml[mlinks]->m_ino = Hdr.h_ino;
                    983:        strcpy(ml[mlinks]->m_name, np);
                    984:        ++mlinks;
                    985:        return 1;
                    986: }
                    987: 
                    988: pentry(namep)          /* print verbose table of contents */
                    989: register char *namep;
                    990: {
                    991: 
                    992:        static short lastid = -1;
                    993: #include <pwd.h>
                    994:        static struct passwd *pw;
                    995:        struct passwd *getpwuid();
                    996:        static char tbuf[32];
                    997:        char *ctime();
                    998: 
                    999:        printf("%-7o", Hdr.h_mode & 0177777);
                   1000:        if(lastid == Hdr.h_uid)
                   1001:                printf("%-6s", pw->pw_name);
                   1002:        else {
                   1003:                setpwent();
                   1004:                if(pw = getpwuid((int)Hdr.h_uid)) {
                   1005:                        printf("%-6s", pw->pw_name);
                   1006:                        lastid = Hdr.h_uid;
                   1007:                } else {
                   1008:                        printf("%-6d", Hdr.h_uid);
                   1009:                        lastid = -1;
                   1010:                }
                   1011:        }
                   1012:        printf("%7ld ", mklong(Hdr.h_filesize));
                   1013:        U.l = mklong(Hdr.h_mtime);
                   1014:        strcpy(tbuf, ctime((long *)&U.l));
                   1015:        tbuf[24] = '\0';
                   1016:        printf(" %s  %s\n", &tbuf[4], namep);
                   1017: }
                   1018: 
                   1019:                /* pattern matching functions */
                   1020: nmatch(s, pat)
                   1021: char *s, **pat;
                   1022: {
                   1023:        if(EQ(*pat, "*"))
                   1024:                return 1;
                   1025:        while(*pat) {
                   1026:                if((**pat == '!' && !gmatch(s, *pat+1))
                   1027:                || gmatch(s, *pat))
                   1028:                        return 1;
                   1029:                ++pat;
                   1030:        }
                   1031:        return 0;
                   1032: }
                   1033: gmatch(s, p)
                   1034: register char *s, *p;
                   1035: {
                   1036:        register int c;
                   1037:        register cc, ok, lc, scc;
                   1038: 
                   1039:        scc = *s;
                   1040:        lc = 077777;
                   1041:        switch (c = *p) {
                   1042: 
                   1043:        case '[':
                   1044:                ok = 0;
                   1045:                while (cc = *++p) {
                   1046:                        switch (cc) {
                   1047: 
                   1048:                        case ']':
                   1049:                                if (ok)
                   1050:                                        return(gmatch(++s, ++p));
                   1051:                                else
                   1052:                                        return(0);
                   1053: 
                   1054:                        case '-':
                   1055:                                ok |= ((lc <= scc) && (scc <= (cc=p[1])));
                   1056:                        }
                   1057:                        if (scc==(lc=cc)) ok++;
                   1058:                }
                   1059:                return(0);
                   1060: 
                   1061:        case '?':
                   1062:        caseq:
                   1063:                if(scc) return(gmatch(++s, ++p));
                   1064:                return(0);
                   1065:        case '*':
                   1066:                return(umatch(s, ++p));
                   1067:        case 0:
                   1068:                return(!scc);
                   1069:        }
                   1070:        if (c==scc) goto caseq;
                   1071:        return(0);
                   1072: }
                   1073: 
                   1074: umatch(s, p)
                   1075: register char *s, *p;
                   1076: {
                   1077:        if(*p==0) return(1);
                   1078:        while(*s)
                   1079:                if (gmatch(s++,p)) return(1);
                   1080:        return(0);
                   1081: }
                   1082: 
                   1083: makdir(namep)          /* make needed directories */
                   1084: register char *namep;
                   1085: {
                   1086:        static status;
                   1087:        register pid;
                   1088: 
                   1089:        if(pid = fork())
                   1090:                while(wait(&status) != pid);
                   1091:        else if(pid == -1) {
                   1092:                fprintf(stderr,"Cannot fork, try again\n");
                   1093:                exit(2);
                   1094:        }
                   1095:        else {
                   1096:                close(2);
                   1097:                execl("/bin/mkdir", "mkdir", namep, 0);
                   1098:                exit(2);
                   1099:        }
                   1100:        return ((status>>8) & 0377)? 1: 0;
                   1101: }
                   1102: 
                   1103: swap(buf, ct)          /* swap halfwords, bytes or both */
                   1104: register ct;
                   1105: register char *buf;
                   1106: {
                   1107:        register char c;
                   1108:        register union swp { long       longw; short    shortv[2]; char charv[4]; } *pbuf;
                   1109:        int savect, n, i;
                   1110:        char *savebuf;
                   1111:        short cc;
                   1112: 
                   1113:        savect = ct;    savebuf = buf;
                   1114:        if(byteswap || bothswap) {
                   1115:                if (ct % 2) buf[ct] = 0;
                   1116:                ct = (ct + 1) / 2;
                   1117:                while (ct--) {
                   1118:                        c = *buf;
                   1119:                        *buf = *(buf + 1);
                   1120:                        *(buf + 1) = c;
                   1121:                        buf += 2;
                   1122:                }
                   1123:                if (bothswap) {
                   1124:                        ct = savect;
                   1125:                        pbuf = (union swp *)savebuf;
                   1126:                        if (n = ct % sizeof(union swp)) {
                   1127:                                if(n % 2)
                   1128:                                        for(i = ct + 1; i <= ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0;
                   1129:                                else
                   1130:                                        for (i = ct; i < ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0;
                   1131:                        }
                   1132:                        ct = (ct + (sizeof(union swp) -1)) / sizeof(union swp);
                   1133:                        while(ct--) {
                   1134:                                cc = pbuf->shortv[0];
                   1135:                                pbuf->shortv[0] = pbuf->shortv[1];
                   1136:                                pbuf->shortv[1] = cc;
                   1137:                                ++pbuf;
                   1138:                        }
                   1139:                }
                   1140:        }
                   1141:        else if (halfswap) {
                   1142:                pbuf = (union swp *)buf;
                   1143:                if (n = ct % sizeof(union swp))
                   1144:                        for (i = ct; i < ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0;
                   1145:                ct = (ct + (sizeof(union swp) -1)) / sizeof(union swp);
                   1146:                while (ct--) {
                   1147:                        cc = pbuf->shortv[0];
                   1148:                        pbuf->shortv[0] = pbuf->shortv[1];
                   1149:                        pbuf->shortv[1] = cc;
                   1150:                        ++pbuf;
                   1151:                }
                   1152:        }
                   1153: }
                   1154: set_time(namep, atime, mtime)  /* set access and modification times */
                   1155: register *namep;
                   1156: long atime, mtime;
                   1157: {
                   1158:        static long timevec[2];
                   1159: 
                   1160:        if(!Mod_time)
                   1161:                return;
                   1162:        timevec[0] = atime;
                   1163:        timevec[1] = mtime;
                   1164:        utime(namep, timevec);
                   1165: }
                   1166: chgreel(x, fl)
                   1167: {
                   1168:        register f;
                   1169:        char str[22];
                   1170:        FILE *devtty;
                   1171:        struct stat statb;
                   1172: 
                   1173:        fprintf(stderr,"errno: %d, ", errno);
                   1174:        fprintf(stderr,"Can't %s\n", x? "write output": "read input");
                   1175:        fstat(fl, &statb);
                   1176: #ifndef RT
                   1177:        if((statb.st_mode&S_IFMT) != S_IFCHR)
                   1178:                exit(2);
                   1179: #else
                   1180:        if((statb.st_mode & (S_IFBLK|S_IFREC))==0)
                   1181:                exit(2);
                   1182: #endif
                   1183: again:
                   1184:        fprintf(stderr,"If you want to go on, type device/file name when ready\n");
                   1185:        devtty = fopen("/dev/tty", "r");
                   1186:        fgets(str, 20, devtty);
                   1187:        str[strlen(str) - 1] = '\0';
                   1188:        if(!*str)
                   1189:                exit(2);
                   1190:        close(fl);
                   1191:        if((f = open(str, x? 1: 0)) < 0) {
                   1192:                fprintf(stderr,"That didn't work");
                   1193:                fclose(devtty);
                   1194:                goto again;
                   1195:        }
                   1196:        fclose(devtty);
                   1197:        return f;
                   1198: }
                   1199: missdir(namep)
                   1200: register char *namep;
                   1201: {
                   1202:        register char *np;
                   1203:        register ct = 2;
                   1204: 
                   1205:        for(np = namep; *np; ++np)
                   1206:                if(*np == '/') {
                   1207:                        if(np == namep) continue;       /* skip over 'root slash' */
                   1208:                        *np = '\0';
                   1209:                        if(stat(namep, &Xstatb) == -1) {
                   1210:                                if(Dir) {
                   1211:                                        if((ct = makdir(namep)) != 0) {
                   1212:                                                *np = '/';
                   1213:                                                return(ct);
                   1214:                                        }
                   1215:                                }else {
                   1216:                                        fprintf(stderr,"missing 'd' option\n");
                   1217:                                        return(-1);
                   1218:                                }
                   1219:                        }
                   1220:                        *np = '/';
                   1221:                }
                   1222:        if (ct == 2) ct = 0;            /* the file already exists */
                   1223:        return ct;
                   1224: }
                   1225: 
                   1226: pwd()          /* get working directory */
                   1227: {
                   1228:        FILE *dir;
                   1229: 
                   1230:        dir = popen("pwd", "r");
                   1231:        fgets(Fullname, 256, dir);
                   1232:        if(pclose(dir))
                   1233:                exit(2);
                   1234:        Pathend = strlen(Fullname);
                   1235:        Fullname[Pathend - 1] = '/';
                   1236: }
                   1237: char * cd(n)           /* change directories */
                   1238: register char *n;
                   1239: {
                   1240:        char *p_save = Name, *n_save = n, *p_end = 0;
                   1241:        register char *p = Name;
                   1242:        static char dotdot[]="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../";
                   1243:        int slashes, ans;
                   1244: 
                   1245:        if(*n == '/') /* don't try to chdir on full pathnames */
                   1246:                return n;
                   1247:        for(; *p && *n == *p; ++p, ++n) { /* whatever part of strings == */
                   1248:                if(*p == '/')
                   1249:                        p_save = p+1, n_save = n+1;
                   1250:        }
                   1251: 
                   1252:        p = p_save;
                   1253:        *p++ = '\0';
                   1254:        for(slashes = 0; *p; ++p) { /* if prev is longer, chdir("..") */
                   1255:                if(*p == '/')
                   1256:                        ++slashes;
                   1257:        }
                   1258:        p = p_save;
                   1259:        if(slashes) {
                   1260:                slashes = slashes * 3 - 1;
                   1261:                dotdot[slashes] = '\0';
                   1262:                chdir(dotdot);
                   1263:                dotdot[slashes] = '/';
                   1264:        }
                   1265: 
                   1266:        n = n_save;
                   1267:        for(; *n; ++n, ++p) {
                   1268:                *p = *n;
                   1269:                if(*n == '/')
                   1270:                        p_end = p+1, n_save = n+1;
                   1271:        }
                   1272:        *p = '\0';
                   1273: 
                   1274:        if(p_end) {
                   1275:                *p_end = '\0';
                   1276:                if(chdir(p_save) == -1) {
                   1277:                        if((ans = missdir(p_save)) == -1) {
                   1278:                                fprintf(stderr,"Cannot chdir (no `d' option)\n");
                   1279:                                exit(2);
                   1280:                        } else if (ans > 0)  {
                   1281:                                fprintf(stderr,"Cannot chdir - no write permission\n");
                   1282:                                exit(2);
                   1283:                        } else if(chdir(p_save) == -1)  {
                   1284:                                fprintf(stderr,"Cannot chdir\n");
                   1285:                                exit(2);
                   1286:                        }
                   1287:                }
                   1288:        } else
                   1289:                *p_save = '\0';
                   1290:        return n_save;
                   1291: }
                   1292: #ifdef RT
                   1293: actsize(file)
                   1294: register int file;
                   1295: {
                   1296:        long tlong;
                   1297:        long fsize();
                   1298:        register int tfile;
                   1299: 
                   1300:        Actual_size[0] = Hdr.h_filesize[0];
                   1301:        Actual_size[1] = Hdr.h_filesize[1];
                   1302:        if (!Extent)
                   1303:                return;
                   1304:        if (file)
                   1305:                tfile = file;
                   1306:        else if ((tfile = open(Hdr.h_name,0)) < 0)
                   1307:                return;
                   1308:        tlong = fsize(tfile);
                   1309:        MKSHORT(Hdr.h_filesize,tlong);
                   1310:        if (Cflag)
                   1311:                bintochar(tlong);
                   1312:        if (!file)
                   1313:                close(tfile);
                   1314: }
                   1315: #endif
                   1316: 
                   1317: #ifdef MAXFILENAME
                   1318: FILE *longnamefd;
                   1319: 
                   1320: affix(n,ptr)
                   1321:   int n;
                   1322:   char *ptr;
                   1323: {
                   1324:        int i=0,m;
                   1325:        char ext[5];
                   1326: 
                   1327:        while(1) {
                   1328:                if((m=n%52)<26) ext[i++] = m + 'a';
                   1329:                else ext[i++] = m + 'A' - 26;
                   1330:                if(n < 52)break;
                   1331:                n = n/52 - 1;  /* so we have Z,aa not Z,ba */
                   1332:        }
                   1333: 
                   1334:        while(--i >= 0)*ptr++ = ext[i];
                   1335:        *ptr = '\0';
                   1336: }
                   1337: 
                   1338: #define MAXOVER        1000
                   1339: struct {
                   1340:        char *longname,
                   1341:                *shortname;
                   1342:        } pairs[MAXOVER];
                   1343: int npairs = 0;        /* no. of tabulated pairs */
                   1344: 
                   1345: int ntoolong = 0;      /* no. of overlong pathnames */
                   1346: 
                   1347: char *
                   1348: findname(key)
                   1349: char *key;
                   1350: {
                   1351: int i, nprevious = 0, nprefix;
                   1352: char *longptr, *shortptr, *malloc(), *endbit, *strrchr();
                   1353: 
                   1354:        endbit = strrchr(key,'/');
                   1355:        if(endbit == 0)endbit = key;
                   1356:        else endbit++;
                   1357:        nprefix = endbit - key;
                   1358: 
                   1359:        for(i=0;i<npairs;i++){
                   1360:                if(strcmp(key,pairs[i].longname) == 0)
                   1361:                        return(pairs[i].shortname);
                   1362:                if(strncmp(key,pairs[i].longname,nprefix+MAXFILENAME-4) == 0)
                   1363:                        nprevious++;
                   1364:        }
                   1365:        longptr = pairs[npairs].longname = malloc(strlen(key)+1);
                   1366:        shortptr = pairs[npairs].shortname = malloc(MAXFILENAME+1);
                   1367:        strcpy(longptr,key);
                   1368:        strncpy(shortptr,endbit,MAXFILENAME-4);
                   1369:        sprintf(shortptr+MAXFILENAME-4,"..");
                   1370:        affix(nprevious,shortptr+MAXFILENAME-2);
                   1371:        npairs++;
                   1372:        return(shortptr);
                   1373: }
                   1374: 
                   1375: fixname(original)
                   1376: char *original;
                   1377: {
                   1378:   int length;
                   1379:   char newname[100];
                   1380:   register char *inend, *outptr=newname, *instart=original,
                   1381:                *outstart;
                   1382:  int changed = 0;
                   1383: 
                   1384:   while(1){
                   1385:        if(*instart == '\0')break;
                   1386:        if(*instart == '/')*outptr++ = *instart++;
                   1387:        outstart = outptr;
                   1388:        for(inend=instart;*inend != '\0' && *inend != '/';)
                   1389:                *outptr++ = *inend++;
                   1390:        *outptr = '\0';
                   1391:        length = strlen(outstart);
                   1392:        if(length > MAXFILENAME){
                   1393:                changed++;
                   1394:                strcpy(outstart,findname(newname));
                   1395:        }
                   1396:        outptr = outstart + strlen(outstart);
                   1397:        instart = inend;
                   1398:        }
                   1399: 
                   1400:   if(changed){
                   1401:        if(ntoolong == 0) {
                   1402:                longnamefd = fopen("longnamelist","w");
                   1403:                if(longnamefd == NULL){
                   1404:                        fprintf(stderr,
                   1405:                                "can't create longnamelist file\n");
                   1406:                        exit(1);
                   1407:                }
                   1408:                fprintf(stderr,"check out file 'longnamelist'\n");
                   1409:        }
                   1410:        printf("%s changed to %s\n",original,newname);
                   1411:        fprintf(longnamefd,"%s\t%s\n",original, newname);
                   1412:        fflush(longnamefd);
                   1413:        strcpy(original,newname);
                   1414:        ntoolong++;
                   1415:   }
                   1416: }
                   1417: #else /* MAXFILESIZE */
                   1418: fixname(){}
                   1419: #else /* MAXFILESIZE */

unix.superglobalmegacorp.com

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