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

unix.superglobalmegacorp.com

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