Annotation of 43BSDReno/usr.bin/cpio/cpio.c, revision 1.1

1.1     ! root        1: /*     Copyright (c) 1988 AT&T */
        !             2: /*       All Rights Reserved   */
        !             3: 
        !             4: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
        !             5: /*     The copyright notice above does not evidence any        */
        !             6: /*     actual or intended publication of such source code.     */
        !             7: 
        !             8: #ident "@(#)cpio:cpio.c        1.30.1.11"
        !             9: /*     /sccs/src/cmd/s.cpio.c
        !            10:        cpio.c  1.30.1.11       1/11/86 13:46:48
        !            11:        Reworked cpio which uses getopt(3) to interpret flag arguments and
        !            12:        changes reels to the save file name.
        !            13:        Performance and size improvements.
        !            14: */
        !            15: 
        !            16: /*     cpio    COMPILE:        cc -O cpio.c -s -i -o cpio -lgen -lerr
        !            17:        cpio -- copy file collections
        !            18: 
        !            19: */
        !            20: #include <errno.h>
        !            21: #include <fcntl.h>
        !            22: #include <memory.h>
        !            23: #include <stdio.h>
        !            24: #include <string.h>
        !            25: #include <signal.h>
        !            26: #include <varargs.h>
        !            27: #include <sys/param.h>
        !            28: #include <sys/types.h>
        !            29: #include <sys/stat.h>
        !            30: #include <paths.h>
        !            31: 
        !            32: struct utimbuf {
        !            33:        time_t  actime;
        !            34:        time_t  modtime;
        !            35: };
        !            36: #ifndef S_IFIFO
        !            37: #define        S_IFIFO 010000
        !            38: #endif
        !            39: 
        !            40: #define EQ(x,y)        (strcmp(x,y)==0)
        !            41: 
        !            42:                                /* MKSHORT:  for VAX, Interdata, ...    */
        !            43:                                /* Take a 4-byte long, lv, and turn it  */
        !            44:                                /* into an array of two 2-byte shorts, v*/
        !            45: #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];}
        !            46: 
        !            47: #define MAGIC  070707          /* cpio magic number */
        !            48: #define BSMAGIC        0143561         /* byte-swapped cpio magic number */
        !            49: #define IN     'i'             /* copy in */
        !            50: #define OUT    'o'             /* copy out */
        !            51: #define PASS   'p'             /* direct copy */
        !            52: #define HDRSIZE        (Hdr.h_name - (char *)&Hdr)     /* header size minus filename field */
        !            53: #define LINKS  500             /* no. of links allocated per bunch */
        !            54: #define CHARS  76              /* ASCII header size minus filename field */
        !            55: #define BUFSIZE 512            /* In u370, can't use BUFSIZ or BSIZE */
        !            56: #define CPIOBSZ 4096           /* file read/write */
        !            57: #define MK_USHORT(a)   (a & 00000177777)       /* Make unsigned shorts for portable  */
        !            58:                                                /* header.  Hardware may only know    */
        !            59:                                                /* integer operations and sign extend */
        !            60:                                                /* the large unsigned short resulting */
        !            61:                                                /* in 8 rather than 6 octal char in   */
        !            62:                                                /* the header.                        */
        !            63: 
        !            64: static struct  stat    Statb, Xstatb;
        !            65: 
        !            66:        /* Cpio header format */
        !            67: static struct header {
        !            68:        short   h_magic;
        !            69:        short   h_dev;
        !            70:        ushort  h_ino;
        !            71:        ushort  h_mode,
        !            72:                h_uid,
        !            73:                h_gid;
        !            74:        short   h_nlink;
        !            75:        short   h_rdev;
        !            76:        short   h_mtime[2],
        !            77:                h_namesize,
        !            78:                h_filesize[2];
        !            79:        char    h_name[256];
        !            80: } Hdr;
        !            81: 
        !            82: char   Symlbuf[MAXPATHLEN + 1];        /* target of symbolic link */
        !            83: static unsigned        Bufsize = BUFSIZE;              /* default record size */
        !            84: static char    Buf[CPIOBSZ], *Cbuf;
        !            85: static char    *Cp;
        !            86: 
        !            87: 
        !            88: static
        !            89: short  Option,
        !            90:        Dir,
        !            91:        Uncond,
        !            92:        PassLink,
        !            93:        Rename,
        !            94:        Toc,
        !            95:        Verbose,
        !            96:        Mod_time,
        !            97:        Acc_time,
        !            98:        Cflag,
        !            99:        fflag,
        !           100:        Swap,
        !           101:        byteswap,
        !           102:        halfswap;
        !           103: 
        !           104: static
        !           105: int    Ifile,
        !           106:        Ofile,
        !           107:        Input = 0,
        !           108:        Output = 1;
        !           109:                        /* sBlocks: short Blocks.  Cumulative character   */
        !           110:                        /* count for short reads in bread().  Encountered */
        !           111:                        /* with communication lines and pipes as in:      */
        !           112:                        /* split -100 cpio_archive; cat xa* | cpio -icd   */
        !           113: static
        !           114: long   sBlocks,
        !           115:        Blocks,
        !           116:        Longfile,
        !           117:        Longtime;
        !           118: 
        !           119: static
        !           120: char   Fullname[256],
        !           121:        Name[256];
        !           122: static
        !           123: int    Pathend;
        !           124: static
        !           125: char   *swfile;
        !           126: static
        !           127: char   *eommsg = "Change to part %d and press RETURN key. [q] ";
        !           128: 
        !           129: static
        !           130: FILE   *Rtty,
        !           131:        *Wtty;
        !           132: static
        !           133: char   ttyname[] = _PATH_TTY;
        !           134: 
        !           135: static
        !           136: char   **Pattern = 0;
        !           137: static
        !           138: char   Chdr[500];
        !           139: static
        !           140: short  Dev;
        !           141: ushort Uid,
        !           142:        A_directory,
        !           143:        A_special,
        !           144:        A_symlink,
        !           145:        Filetype = S_IFMT;
        !           146: 
        !           147: extern errno;
        !           148: extern void exit();
        !           149: char   *malloc();
        !           150: FILE   *popen();
        !           151: 
        !           152: static char *smemcpy();
        !           153: 
        !           154: static
        !           155: union {
        !           156:        long l;
        !           157:        short s[2];
        !           158:        char c[4];
        !           159: } U;
        !           160: 
        !           161: /* for VAX, Interdata, ... */
        !           162: static
        !           163: long mklong(v)
        !           164: short v[];
        !           165: {
        !           166:        U.l = 1;
        !           167:        if(U.c[0])
        !           168:                U.s[0] = v[1], U.s[1] = v[0];
        !           169:        else
        !           170:                U.s[0] = v[0], U.s[1] = v[1];
        !           171:        return U.l;
        !           172: }
        !           173: 
        !           174: main(argc, argv)
        !           175: char **argv;
        !           176: {
        !           177:        register ct;
        !           178:        long    filesz;
        !           179:        int     symlsz;
        !           180:        register char *fullp;
        !           181:        register i;
        !           182:        int ans;
        !           183:        register char *symlinkp;
        !           184:        short select;                   /* set when files are selected */
        !           185:        extern char     *optarg;
        !           186:        extern int      optind;
        !           187: 
        !           188:        signal(SIGSYS, SIG_IGN);
        !           189:        if(argc <= 1 || *argv[1] != '-')
        !           190:                usage();
        !           191:        Uid = getuid();
        !           192: 
        !           193:        while( (ans = getopt( argc, argv, "aBC:ifopcdlmrSsbtuvM:6eI:O:")) != EOF ) {
        !           194: 
        !           195:                switch( ans ) {
        !           196:                case 'a':               /* reset access time */
        !           197:                        Acc_time++;
        !           198:                        break;
        !           199:                case 'B':               /* change record size to 5120 bytes */
        !           200:                        Bufsize = 5120;
        !           201:                        break;
        !           202:                case 'C':               /* reset buffer size to arbitrary valu
        !           203:                                        */
        !           204:                        Bufsize = atoi( optarg );
        !           205:                        if( Bufsize == 0 ) {
        !           206:                                fperr("Illegal argument to -%c, '%s'",
        !           207:                                        ans, optarg );
        !           208:                                exit(2);
        !           209:                        }
        !           210:                        break;
        !           211:                case 'i':
        !           212:                        Option = IN;
        !           213:                        break;
        !           214:                case 'f':       /* copy files not matched by patterns */
        !           215:                        fflag++;
        !           216:                        break;
        !           217:                case 'o':
        !           218:                        Option = OUT;
        !           219:                        break;
        !           220:                case 'p':
        !           221:                        Option = PASS;
        !           222:                        break;
        !           223:                case 'c':               /* ASCII header */
        !           224:                        Cflag++;
        !           225:                        break;
        !           226:                case 'd':               /* create directories when needed */
        !           227:                        Dir++;
        !           228:                        break;
        !           229:                case 'l':               /* link files, when necessary */
        !           230:                        PassLink++;
        !           231:                        break;
        !           232:                case 'm':               /* retain mod time */
        !           233:                        Mod_time++;
        !           234:                        break;
        !           235:                case 'r':               /* rename files interactively */
        !           236:                        Rename++;
        !           237:                        Rtty = fopen(ttyname, "r");
        !           238:                        Wtty = fopen(ttyname, "w");
        !           239:                        if(Rtty==NULL || Wtty==NULL) {
        !           240:                                fperrno("Cannot rename (%s missing)",
        !           241:                                        ttyname );
        !           242:                                exit(2);
        !           243:                        }
        !           244:                        break;
        !           245:                case 'S':               /* swap halfwords */
        !           246:                        halfswap++;
        !           247:                        Swap++;
        !           248:                        break;
        !           249:                case 's':               /* swap bytes */
        !           250:                        byteswap++;
        !           251:                        Swap++;
        !           252:                        break;
        !           253:                case 'b':               /* swap both bytes and halfwords */
        !           254:                        halfswap++;
        !           255:                        byteswap++;
        !           256:                        Swap++;
        !           257:                        break;
        !           258:                case 't':               /* table of contents */
        !           259:                        Toc++;
        !           260:                        break;
        !           261:                case 'u':               /* copy unconditionally */
        !           262:                        Uncond++;
        !           263:                        break;
        !           264:                case 'v':               /* verbose - print out file names */
        !           265:                        Verbose++;
        !           266:                        break;
        !           267:                case 'M':               /* alternate message for end-of-media */
        !           268:                        eommsg = optarg;
        !           269:                        break;
        !           270:                case '6':               /* for old, sixth-edition files */
        !           271:                        Filetype = 060000;
        !           272:                        break;
        !           273:                case 'I':
        !           274:                        chkswfile( swfile, ans, Option );
        !           275:                        if( (i = open( optarg, O_RDONLY ) ) < 0) {
        !           276:                                fperrno("Cannot open <%s> for input", optarg);
        !           277:                                exit(2);
        !           278:                        }
        !           279:                        if( dup2(i, Input ) < 0 ) {
        !           280:                                fperrno("Cannot dup to standard input");
        !           281:                                exit(2);
        !           282:                        }
        !           283:                        swfile = optarg;
        !           284:                        break;
        !           285:                case 'O':
        !           286:                        chkswfile( swfile, ans, Option );
        !           287:                        if( (i = open( optarg, O_WRONLY | O_CREAT | O_TRUNC,
        !           288:                            0666 ) ) < 0) {
        !           289:                                fperrno("Cannot open <%s> for output", optarg);
        !           290:                                exit(2);
        !           291:                        }
        !           292:                        if( dup2(i, Output ) < 0 ) {
        !           293:                                fperrno("Cannot dup to standard output");
        !           294:                                exit(2);
        !           295:                        }
        !           296:                        swfile = optarg;
        !           297:                        break;
        !           298:                default:
        !           299:                        usage();
        !           300:                }
        !           301:        }
        !           302:        if(!Option) {
        !           303:                (void) fprintf(stderr,
        !           304:                    "Options must include one of -o, -i, or -p\n");
        !           305:                exit(2);
        !           306:        }
        !           307: 
        !           308:        if(Option == PASS) {
        !           309:                if(Rename) {
        !           310:                        (void) fprintf(stderr,
        !           311:                            "Pass and Rename cannot be used together\n");
        !           312:                        exit(2);
        !           313:                }
        !           314:                if( Bufsize != BUFSIZE ) {
        !           315:                        fprintf( stderr, "`B' or `C' option is irrelevant with the '-p' option\n");
        !           316:                        Bufsize = BUFSIZE;
        !           317:                }
        !           318: 
        !           319:        }else  {
        !           320:                Cp = Cbuf = (char *)malloc(Bufsize);
        !           321:                if(Cp == NULL) {
        !           322:                        perror("cpio");
        !           323:                        exit(2);
        !           324:                }
        !           325:        }
        !           326:        argc -= optind;
        !           327:        argv += optind;
        !           328: 
        !           329:        switch(Option) {
        !           330:        case OUT:
        !           331:                if(argc != 0)
        !           332:                        usage();
        !           333:                /* get filename, copy header and file out */
        !           334:                while(getname()) {
        !           335:                        if( mklong(Hdr.h_filesize) == 0L) {
        !           336:                                if( Cflag )
        !           337:                                        bwrite(Chdr,CHARS+Hdr.h_namesize);
        !           338:                                else
        !           339:                                        bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
        !           340:                                if(Verbose)
        !           341:                                        (void) fprintf(stderr, "%s\n",
        !           342:                                            Hdr.h_name);
        !           343:                                continue;
        !           344:                        } else if( A_symlink ) {
        !           345:                                symlsz = (int) mklong(Hdr.h_filesize);
        !           346:                                if (readlink(Hdr.h_name, Symlbuf, symlsz) < 0) {
        !           347:                                        fperrno("Cannot read symbolic link <%s>",
        !           348:                                            Hdr.h_name);
        !           349:                                        continue;
        !           350:                                }
        !           351:                                Symlbuf[symlsz] = '\0';
        !           352:                                bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
        !           353:                                bwrite(Symlbuf, symlsz);
        !           354:                                if(Verbose)
        !           355:                                        (void) fprintf(stderr, "%s\n",
        !           356:                                            Hdr.h_name);
        !           357:                                continue;
        !           358:                        }
        !           359:                        if((Ifile = open(Hdr.h_name, 0)) < 0) {
        !           360:                                fperrno("Cannot open <%s>", Hdr.h_name);
        !           361:                                continue;
        !           362:                        }
        !           363:                        if ( Cflag )
        !           364:                                bwrite(Chdr,CHARS+Hdr.h_namesize);
        !           365:                        else
        !           366:                                bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
        !           367:                        for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){
        !           368:                                ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
        !           369:                                if(read(Ifile, Buf, ct) < 0) {
        !           370:                                        fperrno("Cannot read %s", Hdr.h_name);
        !           371:                                        continue;
        !           372:                                }
        !           373:                                bwrite(Buf,ct);
        !           374:                        }
        !           375:                        close(Ifile);
        !           376:                        if(Acc_time) {
        !           377:                                struct utimbuf utb;
        !           378: 
        !           379:                                utb.actime = Statb.st_atime;
        !           380:                                utb.modtime = Statb.st_mtime;
        !           381:                                (void)utime(Hdr.h_name, &utb);
        !           382:                        }
        !           383:                        if(Verbose)
        !           384:                                (void) fprintf(stderr, "%s\n", Hdr.h_name);
        !           385:                }
        !           386: 
        !           387:        /* copy trailer, after all files have been copied */
        !           388:                strcpy(Hdr.h_name, "TRAILER!!!");
        !           389:                Hdr.h_magic = MAGIC;
        !           390:                MKSHORT(Hdr.h_filesize, 0L);
        !           391:                Hdr.h_namesize = strlen("TRAILER!!!") + 1;
        !           392:                if ( Cflag )  {
        !           393:                        bintochar(0L);
        !           394:                        bwrite(Chdr, CHARS+Hdr.h_namesize);
        !           395:                }
        !           396:                else
        !           397:                        bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);
        !           398:                bwrite(Cbuf, Bufsize);
        !           399:                break;
        !           400: 
        !           401:        case IN:
        !           402:                if(argc > 0 ) { /* save patterns, if any */
        !           403:                        Pattern = argv;
        !           404:                }
        !           405:                pwd();
        !           406:                chkhdr();
        !           407:                while(gethdr()) {
        !           408:                        if (A_symlink) {
        !           409:                                symlsz = (int) mklong(Hdr.h_filesize);
        !           410:                                bread(Symlbuf, symlsz);
        !           411:                                Symlbuf[symlsz] = '\0';
        !           412:                                if( ckname(Hdr.h_name)  &&  !Toc)
        !           413:                                        (void)openout(Hdr.h_name, Symlbuf);
        !           414:                        } else {
        !           415:                                if( (select = ckname(Hdr.h_name))  &&  !Toc )
        !           416:                                        Ofile = openout(Hdr.h_name, (char *)0);
        !           417:                                else
        !           418:                                        Ofile = 0;
        !           419:                                for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){
        !           420:                                        ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
        !           421:                                        bread(Buf, ct);
        !           422:                                        if(Ofile) {
        !           423:                                                if(Swap)
        !           424:                                                       swap(Buf,ct,byteswap,halfswap);
        !           425:                                                if(write(Ofile, Buf, ct) < 0) {
        !           426:                                                 fperrno("Cannot write %s", Hdr.h_name);
        !           427:                                                 continue;
        !           428:                                                }
        !           429:                                        }
        !           430:                                }
        !           431:                                if( Ofile ) {
        !           432:                                        (void) close(Ofile);
        !           433:                                        if(chmod(Hdr.h_name, Hdr.h_mode) < 0)
        !           434:                                                fperrno("Cannot change mode of <%s>",
        !           435:                                                    Hdr.h_name);
        !           436:                                        set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
        !           437:                                }
        !           438:                        }
        !           439:                        if(select) {
        !           440:                                if(Verbose)
        !           441:                                        if(Toc)
        !           442:                                                pentry(Hdr.h_name);
        !           443:                                        else
        !           444:                                                puts(Hdr.h_name);
        !           445:                                else if(Toc)
        !           446:                                        puts(Hdr.h_name);
        !           447:                        }
        !           448:                }
        !           449:                break;
        !           450: 
        !           451:        case PASS:              /* move files around */
        !           452:                if(argc != 1)
        !           453:                        usage();
        !           454:                if(access(argv[0], 2) == -1) {
        !           455:                        (void) fperrno("Cannot write in <%s>", argv[0]);
        !           456:                        exit(2);
        !           457:                }
        !           458:                strcpy(Fullname, argv[0]);      /* destination directory */
        !           459:                if(stat(Fullname, &Xstatb) < 0) {
        !           460:                        fperrno("Cannot stat <%s>", Fullname);
        !           461:                        exit(2);
        !           462:                }
        !           463:                if((Xstatb.st_mode&S_IFMT) != S_IFDIR) {
        !           464:                        (void) fprintf(stderr, "<%s> is not a directory",
        !           465:                            Fullname);
        !           466:                        exit(2);
        !           467:                }
        !           468:                Dev = Xstatb.st_dev;
        !           469:                if( Fullname[ strlen(Fullname) - 1 ] != '/' )
        !           470:                        strcat(Fullname, "/");
        !           471:                fullp = Fullname + strlen(Fullname);
        !           472: 
        !           473:                while(getname()) {
        !           474:                        if (A_directory && !Dir)
        !           475:                                fperr("Use `-d' option to copy <%s>",
        !           476:                                        Hdr.h_name);
        !           477:                        if(!ckname(Hdr.h_name))
        !           478:                                continue;
        !           479:                        i = 0;
        !           480:                        while(Hdr.h_name[i] == '/')
        !           481:                                i++;
        !           482:                        strcpy(fullp, &(Hdr.h_name[i]));
        !           483: 
        !           484:                        if( PassLink  &&  !A_directory  &&  Dev == Statb.st_dev ) {
        !           485:                                if(link(Hdr.h_name, Fullname) < 0) {
        !           486:                                        switch(errno) {
        !           487:                                                case ENOENT:
        !           488:                                                        if(missdir(Fullname) != 0) {
        !           489:                                                                fperrno("Cannot create directory for <%s>",
        !           490:                                                                        Fullname);
        !           491:                                                                continue;
        !           492:                                                        }
        !           493:                                                        break;
        !           494:                                                case EEXIST:
        !           495:                                                        if(unlink(Fullname) < 0) {
        !           496:                                                                fperrno("Cannot unlink <%s>",
        !           497:                                                                        Fullname);
        !           498:                                                                continue;
        !           499:                                                        }
        !           500:                                                        break;
        !           501:                                                default:
        !           502:                                                        fperrno("Cannot link <%s> to <%s>",
        !           503:                                                                Hdr.h_name, Fullname);
        !           504:                                                        continue;
        !           505:                                                }
        !           506:                                        if(link(Hdr.h_name, Fullname) < 0) {
        !           507:                                                fperrno("Cannot link <%s> to <%s>",
        !           508:                                                        Hdr.h_name, Fullname);
        !           509:                                                continue;
        !           510:                                        }
        !           511:                                }
        !           512: 
        !           513:                                goto ckverbose;
        !           514:                        }
        !           515:                        if( A_symlink ) {
        !           516:                           symlsz = (int) mklong(Hdr.h_filesize);
        !           517:                           if (readlink(Hdr.h_name, Symlbuf, symlsz) < 0) {
        !           518:                                fperrno("Cannot read symbolic link <%s>",
        !           519:                                    Hdr.h_name);
        !           520:                                continue;
        !           521:                           }
        !           522:                           Symlbuf[symlsz] = '\0';
        !           523:                           if(!openout(Fullname, Symlbuf))
        !           524:                                continue;
        !           525:                           Blocks += ((symlsz + (BUFSIZE - 1)) / BUFSIZE);
        !           526:                           if(Verbose)
        !           527:                                puts(Fullname);
        !           528:                           continue;
        !           529:                        }
        !           530:                        if(!(Ofile = openout(Fullname, (char *)0)))
        !           531:                                continue;
        !           532:                        if((Ifile = open(Hdr.h_name, 0)) < 0) {
        !           533:                                fperrno("Cannot open <%s>", Hdr.h_name);
        !           534:                                close(Ofile);
        !           535:                                continue;
        !           536:                        }
        !           537:                        filesz = Statb.st_size;
        !           538:                        for(; filesz > 0; filesz -= CPIOBSZ) {
        !           539:                                ct = filesz>CPIOBSZ? CPIOBSZ: filesz;
        !           540:                                if(read(Ifile, Buf, ct) < 0) {
        !           541:                                        fperrno("Cannot read %s", Hdr.h_name);
        !           542:                                        break;
        !           543:                                }
        !           544:                                if(write(Ofile, Buf, ct) < 0) {
        !           545:                                 fperrno("Cannot write %s", Hdr.h_name);
        !           546:                                 break;
        !           547:                                }
        !           548:                                /* Removed u370 ifdef which caused cpio */
        !           549:                                /* to report blocks in terms of 4096 bytes. */
        !           550: 
        !           551:                                Blocks += ((ct + (BUFSIZE - 1)) / BUFSIZE);
        !           552:                        }
        !           553:                        close(Ifile);
        !           554:                        if(Acc_time) {
        !           555:                                struct utimbuf utb;
        !           556: 
        !           557:                                utb.actime = Statb.st_atime;
        !           558:                                utb.modtime = Statb.st_mtime;
        !           559:                                (void)utime(Hdr.h_name, &utb);
        !           560:                        }
        !           561:                        if(Ofile) {
        !           562:                                close(Ofile);
        !           563:                                if(chmod(Fullname, Hdr.h_mode) < 0)
        !           564:                                        fperrno("Cannot change mode of <%s>",
        !           565:                                            Fullname);
        !           566:                                set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime));
        !           567: ckverbose:
        !           568:                                if(Verbose)
        !           569:                                        puts(Fullname);
        !           570:                        }
        !           571:                }
        !           572:        }
        !           573:        /* print number of blocks actually copied */
        !           574:        Blocks += ((sBlocks + (BUFSIZE - 1)) / BUFSIZE);
        !           575:        (void) fprintf(stderr, "%ld blocks\n", Blocks * (Bufsize>>9));
        !           576:        exit(0);
        !           577: }
        !           578: 
        !           579: static
        !           580: usage()
        !           581: {
        !           582:        (void) fprintf("Usage: %s\n     %s\n     %s\n     %s\n       %s\n",
        !           583:            "cpio -o[acvB] <name-list >collection",
        !           584:            "cpio -o[acvB] -Ocollection <name-list",
        !           585:            "cpio -i[cdmrstuvfB6] [ pattern ... ] <collection",
        !           586:            "cpio -i[cdmrstuvfB6] -Icollection [ pattern ... ]",
        !           587:            "cpio -p[adlmruv] directory <name-list");
        !           588: }
        !           589: 
        !           590: static
        !           591: chkswfile( sp, c, option )
        !           592: char   *sp;
        !           593: char   c;
        !           594: short  option;
        !           595: {
        !           596:        if( !option ) {
        !           597:                fperr( "-%c must be specified before -%c option",
        !           598:                        c == 'I' ? 'i' : 'o', c );
        !           599:                exit(2);
        !           600:        }
        !           601:        if( (c == 'I'  &&  option != IN)  ||  (c == 'O'  &&  option != OUT) ) {
        !           602:                fperr( "-%c option not permitted with -%c option", c,
        !           603:                        option );
        !           604:                exit(2);
        !           605:        }
        !           606:        if( !sp )
        !           607:                return;
        !           608:        fperr("No more than one -I or -O flag permitted");
        !           609:        exit(2);
        !           610: }
        !           611: 
        !           612: static
        !           613: getname()              /* get file name, get info for header */
        !           614: {
        !           615:        register char *namep = Name;
        !           616:        register ushort ftype;
        !           617:        struct stat Lstatb;
        !           618:        long tlong;
        !           619: 
        !           620:        for(;;) {
        !           621:                if(gets(namep) == NULL)
        !           622:                        return 0;
        !           623:                while(*namep == '.' && namep[1] == '/') {
        !           624:                        namep++;
        !           625:                        while(*namep == '/') namep++;
        !           626:                }
        !           627:                strcpy(Hdr.h_name, namep);
        !           628:                if(lstat(namep, &Statb) < 0) {
        !           629:                        fperrno("Cannot stat <%s>", Hdr.h_name);
        !           630:                        continue;
        !           631:                }
        !           632:                ftype = Statb.st_mode & Filetype;
        !           633:                A_directory = (ftype == S_IFDIR);
        !           634:                A_special = (ftype == S_IFBLK)
        !           635:                        || (ftype == S_IFCHR)
        !           636:                        || (ftype == S_IFIFO);
        !           637:                A_symlink = (ftype == S_IFLNK);
        !           638:                Hdr.h_magic = MAGIC;
        !           639:                Hdr.h_namesize = strlen(Hdr.h_name) + 1;
        !           640:                Hdr.h_uid = Statb.st_uid;
        !           641:                Hdr.h_gid = Statb.st_gid;
        !           642:                Hdr.h_dev = Statb.st_dev;
        !           643:                Hdr.h_ino = Statb.st_ino;
        !           644:                Hdr.h_mode = Statb.st_mode;
        !           645:                MKSHORT(Hdr.h_mtime, Statb.st_mtime);
        !           646:                Hdr.h_nlink = Statb.st_nlink;
        !           647:                tlong = ((Hdr.h_mode&S_IFMT) == S_IFREG ||
        !           648:                        (Hdr.h_mode&S_IFMT) == S_IFLNK)? Statb.st_size: 0L;
        !           649:                MKSHORT(Hdr.h_filesize, tlong);
        !           650:                Hdr.h_rdev = Statb.st_rdev;
        !           651:                if( Cflag )
        !           652:                        bintochar(tlong);
        !           653:                return 1;
        !           654:        }
        !           655: }
        !           656: 
        !           657: static
        !           658: bintochar(t)           /* ASCII header write */
        !           659: long t;
        !           660: {
        !           661:        sprintf(Chdr,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s",
        !           662:                MAGIC, MK_USHORT(Statb.st_dev), MK_USHORT(Statb.st_ino), Statb.st_mode, Statb.st_uid,
        !           663:                Statb.st_gid, Statb.st_nlink, MK_USHORT(Statb.st_rdev),
        !           664:                Statb.st_mtime, (short)strlen(Hdr.h_name)+1, t, Hdr.h_name);
        !           665: }
        !           666: 
        !           667: static
        !           668: chartobin()            /* ASCII header read */
        !           669: {
        !           670:        sscanf(Chdr, "%6ho%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo",
        !           671:                &Hdr.h_magic, &Hdr.h_dev, &Hdr.h_ino, &Hdr.h_mode, &Hdr.h_uid,
        !           672:                &Hdr.h_gid, &Hdr.h_nlink, &Hdr.h_rdev, &Longtime,
        !           673:                &Hdr.h_namesize, &Longfile);
        !           674:        MKSHORT(Hdr.h_filesize, Longfile);
        !           675:        MKSHORT(Hdr.h_mtime, Longtime);
        !           676: }
        !           677: 
        !           678: 
        !           679: /*     Check the header for the magic number.  Switch modes automatically to
        !           680:        match the type of header found.
        !           681: */
        !           682: static
        !           683: chkhdr()
        !           684: {
        !           685:        bread(Chdr, CHARS);
        !           686:        chartobin();
        !           687:        if( Hdr.h_magic == MAGIC )
        !           688:                Cflag = 1;
        !           689:        else {
        !           690:                breread(&Hdr.h_magic, sizeof Hdr.h_magic);
        !           691:                if( Hdr.h_magic == MAGIC || Hdr.h_magic == (short)BSMAGIC )
        !           692:                        Cflag = 0;
        !           693:                else {
        !           694:                        fperr("This is not a cpio file.  Bad magic number.");
        !           695:                        exit(2);
        !           696:                }
        !           697:        }
        !           698:        breread(Chdr, 0);
        !           699: }
        !           700: 
        !           701: 
        !           702: static
        !           703: gethdr()               /* get file headers */
        !           704: {
        !           705:        register ushort ftype;
        !           706: 
        !           707:        if (Cflag)  {
        !           708:                bread(Chdr, CHARS);
        !           709:                chartobin();
        !           710:        }
        !           711:        else
        !           712:                bread(&Hdr, HDRSIZE);
        !           713: 
        !           714:        if(Hdr.h_magic == (short)BSMAGIC)
        !           715:                swap((char *)&Hdr, HDRSIZE, 1, 0);
        !           716:        else if( Hdr.h_magic != MAGIC ) {
        !           717:                fperr("Out of phase--get help");
        !           718:                exit(2);
        !           719:        }
        !           720:        bread(Hdr.h_name, Hdr.h_namesize);
        !           721:        if(EQ(Hdr.h_name, "TRAILER!!!"))
        !           722:                return 0;
        !           723:        ftype = Hdr.h_mode & Filetype;
        !           724:        A_directory = (ftype == S_IFDIR);
        !           725:        A_special = (ftype == S_IFBLK)
        !           726:                ||  (ftype == S_IFCHR)
        !           727:                ||  (ftype == S_IFIFO);
        !           728:        A_symlink = (ftype == S_IFLNK);
        !           729:        return 1;
        !           730: }
        !           731: 
        !           732: static
        !           733: ckname(namep)  /* check filenames with patterns given on cmd line */
        !           734: register char *namep;
        !           735: {
        !           736:        char    buf[sizeof Hdr.h_name];
        !           737: 
        !           738:        if(fflag ^ !nmatch(namep, Pattern)) {
        !           739:                return 0;
        !           740:        }
        !           741:        if(Rename && !A_directory) {    /* rename interactively */
        !           742:                fprintf(Wtty, "Rename <%s>\n", namep);
        !           743:                fflush(Wtty);
        !           744:                fgets(buf, sizeof buf, Rtty);
        !           745:                if(feof(Rtty))
        !           746:                        exit(2);
        !           747:                buf[strlen(buf) - 1] = '\0';
        !           748:                if(EQ(buf, "")) {
        !           749:                        strcpy(namep,buf);
        !           750:                        printf("Skipped\n");
        !           751:                        return 0;
        !           752:                }
        !           753:                else if(EQ(buf, "."))
        !           754:                        printf("Same name\n");
        !           755:                else
        !           756:                        strcpy(namep,buf);
        !           757:        }
        !           758:        return  1;
        !           759: }
        !           760: 
        !           761: static
        !           762: openout(namep, symlname)       /* open files for writing, set all necessary info */
        !           763: register char *namep;
        !           764: char *symlname;
        !           765: {
        !           766:        register f;
        !           767:        register char *np;
        !           768:        int ans;
        !           769: 
        !           770:        if(!strncmp(namep, "./", 2))
        !           771:                namep += 2;
        !           772:        np = namep;
        !           773:        if(A_directory) {
        !           774:                if( !Dir  ||  Rename  ||  EQ(namep, ".")  ||  EQ(namep, "..") )
        !           775:                        /* do not consider . or .. files */
        !           776:                        return 0;
        !           777:                if(stat(namep, &Xstatb) == -1) {
        !           778: 
        !           779: /* try creating (only twice) */
        !           780:                        ans = 0;
        !           781:                        do {
        !           782:                                if(mkdir(namep, Hdr.h_mode) != 0) {
        !           783:                                        ans += 1;
        !           784:                                }else {
        !           785:                                        ans = 0;
        !           786:                                        break;
        !           787:                                }
        !           788:                        }while(ans < 2 && missdir(namep) == 0);
        !           789:                        if(ans == 1) {
        !           790:                                fperrno("Cannot create directory for <%s>",
        !           791:                                        namep);
        !           792:                                return(0);
        !           793:                        }else if(ans == 2) {
        !           794:                                fperrno("Cannot create directory <%s>", namep);
        !           795:                                return(0);
        !           796:                        }
        !           797:                }
        !           798: 
        !           799: ret:
        !           800:                if(chmod(namep, Hdr.h_mode) < 0)
        !           801:                        fperrno("Cannot change mode of <%s>", namep);
        !           802:                if(Uid == 0)
        !           803:                        if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0)
        !           804:                                fperrno("Cannot change ownership of <%s>",
        !           805:                                    namep);
        !           806:                set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
        !           807:                return 0;
        !           808:        }
        !           809:        if(Hdr.h_nlink > 1)
        !           810:                if(!postml(namep, np))
        !           811:                        return 0;
        !           812:        if(lstat(namep, &Xstatb) == 0) {
        !           813:                if(Uncond && !((!(Xstatb.st_mode & S_IWRITE) || A_special) && (Uid != 0))) {
        !           814:                        if(unlink(namep) < 0) {
        !           815:                                fperrno("cannot unlink current <%s>", namep);
        !           816:                        }
        !           817:                }
        !           818:                if(!Uncond && (mklong(Hdr.h_mtime) <= Xstatb.st_mtime)) {
        !           819:                /* There's a newer or same aged version of file on destination */
        !           820:                        fperr("current <%s> newer or same age", np);
        !           821:                        return 0;
        !           822:                }
        !           823:        }
        !           824:        if( Option == PASS
        !           825:                && Hdr.h_ino == Xstatb.st_ino
        !           826:                && Hdr.h_dev == Xstatb.st_dev) {
        !           827:                fperr("Attempt to pass file to self!");
        !           828:                exit(2);
        !           829:        }
        !           830:        if(A_symlink) {
        !           831: /* try symlinking (only twice) */
        !           832:                ans = 0;
        !           833:                do {
        !           834:                        if(symlink(
        !           835: symlname, namep) < 0) {
        !           836:                                ans += 1;
        !           837:                        }else {
        !           838:                                ans = 0;
        !           839:                                break;
        !           840:                        }
        !           841:                }while(ans < 2 && missdir(np) == 0);
        !           842:                if(ans == 1) {
        !           843:                        fperrno("Cannot create directory for <%s>", namep);
        !           844:                        return(0);
        !           845:                }else if(ans == 2) {
        !           846:                        fperrno("Cannot symlink <%s> and <%s>", namep, symlname);
        !           847:                        return(0);
        !           848:                }
        !           849: 
        !           850:                return 0;
        !           851:        }
        !           852:        if(A_special) {
        !           853:                if((Hdr.h_mode & Filetype) == S_IFIFO)
        !           854:                        Hdr.h_rdev = 0;
        !           855: 
        !           856: /* try creating (only twice) */
        !           857:                ans = 0;
        !           858:                do {
        !           859:                        if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) {
        !           860:                                ans += 1;
        !           861:                        }else {
        !           862:                                ans = 0;
        !           863:                                break;
        !           864:                        }
        !           865:                }while(ans < 2 && missdir(np) == 0);
        !           866:                if(ans == 1) {
        !           867:                        fperrno("Cannot create directory for <%s>", namep);
        !           868:                        return(0);
        !           869:                }else if(ans == 2) {
        !           870:                        fperrno("Cannot mknod <%s>", namep);
        !           871:                        return(0);
        !           872:                }
        !           873: 
        !           874:                goto ret;
        !           875:        }
        !           876: 
        !           877: /* try creating (only twice) */
        !           878:        ans = 0;
        !           879:        do {
        !           880:                if((f = creat(namep, Hdr.h_mode)) < 0) {
        !           881:                        ans += 1;
        !           882:                }else {
        !           883:                        ans = 0;
        !           884:                        break;
        !           885:                }
        !           886:        }while(ans < 2 && missdir(np) == 0);
        !           887:        if(ans == 1) {
        !           888:                fperrno("Cannot create directory for <%s>", namep);
        !           889:                return(0);
        !           890:        }else if(ans == 2) {
        !           891:                fperrno("Cannot create <%s>", namep);
        !           892:                return(0);
        !           893:        }
        !           894: 
        !           895:        if(Uid == 0)
        !           896:                if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0)
        !           897:                        fperrno("Cannot change ownership of <%s>", namep);
        !           898:        return f;
        !           899: }
        !           900: 
        !           901: 
        !           902: /*     Shared by bread() and breread()
        !           903: */
        !           904: static int     nleft = 0;      /* unread chars left in Cbuf */
        !           905: static char    *ip;            /* pointer to next char to be read from Cbuf */
        !           906: 
        !           907: /*     Reread the current buffer Cbuf.
        !           908:        A character count, c, of 0 simply resets the pointer so next bread gets
        !           909:        the same data again.
        !           910: */
        !           911: static
        !           912: breread(b, c)
        !           913: char   *b;
        !           914: int    c;
        !           915: {
        !           916:        ip = Cbuf;
        !           917:        if( nleft )
        !           918:                nleft = Bufsize;
        !           919:        if( !c )
        !           920:                return;
        !           921:        bread(b, c);
        !           922: }
        !           923: 
        !           924: static
        !           925: bread(b, c)
        !           926: register char  *b;
        !           927: register int   c;
        !           928: {
        !           929:        register int    rv;
        !           930:        register char   *p = ip;
        !           931: 
        !           932:        if( !Cflag ) {
        !           933:                /* round c up to an even number */
        !           934:                c = (c+1)/2;
        !           935:                c *= 2;
        !           936:        }
        !           937:        while( c )  {
        !           938:                if( nleft == 0 ) {
        !           939:                        while( (rv = read(Input, Cbuf, Bufsize)) == 0 ) {
        !           940:                                Input = chgreel(0, Input, rv);
        !           941:                        }
        !           942:                        if( rv == Bufsize ) {
        !           943:                                nleft = Bufsize;
        !           944:                                p = Cbuf;
        !           945:                                ++Blocks;
        !           946:                        }
        !           947:                        else if( rv == -1 ) {
        !           948:                                fperrno("Read error on archive");
        !           949:                                exit(2);
        !           950:                        }
        !           951:                        else if( rv < Bufsize ) {       /* short read */
        !           952:                                smemcpy( &Cbuf[ Bufsize - rv ], Cbuf, rv );
        !           953:                                nleft = rv;
        !           954:                                p = &Cbuf[ Bufsize - rv ];
        !           955:                                sBlocks += rv;
        !           956:                        }
        !           957:                }
        !           958:                if( nleft <= c ) {
        !           959:                        memcpy( b, p, nleft );
        !           960:                        c -= nleft;
        !           961:                        b += nleft;
        !           962:                        p += nleft;
        !           963:                        nleft = 0;
        !           964:                }
        !           965:                else {
        !           966:                        memcpy( b, p, c );
        !           967:                        nleft -= c;
        !           968:                        b += c;
        !           969:                        p += c;
        !           970:                        c = 0;
        !           971:                }
        !           972:        }
        !           973:        ip = p;
        !           974: }
        !           975: 
        !           976: 
        !           977: static
        !           978: bwrite(rp, c)
        !           979: register char *rp;
        !           980: register c;
        !           981: {
        !           982:        register char   *cp = Cp;
        !           983:        static unsigned Ccnt = 0;
        !           984:        register unsigned Cleft;
        !           985:        register int    rv;
        !           986: 
        !           987:        if( !Cflag ) {
        !           988:                /* round c up to an even number */
        !           989:                c = (c+1)/2;
        !           990:                c *= 2;
        !           991:        }
        !           992:        while( c )  {
        !           993:                if( (Cleft = Bufsize - Ccnt) <= c ) {
        !           994:                        memcpy( cp, rp, Cleft );
        !           995:                        rv = write(Output, Cbuf, Bufsize);
        !           996:                        if( rv == 0  ||  ( rv == -1  &&  errno == ENXIO ) ) {
        !           997:                                rv = eomchgreel();
        !           998:                        }
        !           999:                        if( rv == Bufsize ) {
        !          1000:                                Ccnt = 0;
        !          1001:                                cp = Cbuf;
        !          1002:                        }
        !          1003:                        else if( rv == -1 ) {
        !          1004:                                fperrno("Write error on archive");
        !          1005:                                exit(2);
        !          1006:                        }
        !          1007:                        else if( rv < Bufsize ) {
        !          1008:                                Output = chgreel(1, Output, 0);
        !          1009:                                smemcpy( Cbuf, &Cbuf[ Bufsize - rv ], rv );
        !          1010:                                Ccnt = Bufsize - rv;
        !          1011:                                cp = &Cbuf[ rv ];
        !          1012:                        }
        !          1013:                        ++Blocks;
        !          1014:                        rp += Cleft;
        !          1015:                        c -= Cleft;
        !          1016:                }
        !          1017:                else {
        !          1018:                        memcpy( cp, rp, c );
        !          1019:                        Ccnt += c;
        !          1020:                        cp += c;
        !          1021:                        rp += c;
        !          1022:                        c = 0;
        !          1023:                }
        !          1024:        }
        !          1025:        Cp = cp;
        !          1026: }
        !          1027: 
        !          1028: 
        !          1029: static int     reelcount = 1;  /* used below and in chgreel() */
        !          1030: 
        !          1031: /*     Change reel due to reaching end-of-media.
        !          1032:        Keep trying to get a successful write before considering the
        !          1033:        change-of-reel as successful.
        !          1034: */
        !          1035: static
        !          1036: int
        !          1037: eomchgreel()
        !          1038: {
        !          1039:        int     rv;
        !          1040: 
        !          1041:        while( 1 ) {
        !          1042:                Output = chgreel(1, Output, 0);
        !          1043:                rv = write(Output, Cbuf, Bufsize);
        !          1044:                if( rv == Bufsize )
        !          1045:                        return  rv;
        !          1046:                if( rv == -1 )
        !          1047:                        fperrno( "Unable to write this medium" );
        !          1048:                else
        !          1049:                        fperr( "Unable to write this medium: Premature EOF" );
        !          1050:                (void) fprintf(stderr, "Try again.\n");
        !          1051:                reelcount--;
        !          1052:        }
        !          1053:        /*NOTREACHED*/
        !          1054: }
        !          1055: 
        !          1056: 
        !          1057: static
        !          1058: postml(namep, np)              /* linking funtion:  Postml() is called after */
        !          1059: register char *namep, *np;     /* namep is created.  Postml() checks to see  */
        !          1060: {                              /* if namep should be linked to np.  If so,   */
        !          1061:                                /* postml() removes the independent instance  */
        !          1062:        register i;             /* of namep and links namep to np.            */
        !          1063:        static struct ml {
        !          1064:                short   m_dev;
        !          1065:                ushort  m_ino;
        !          1066:                char    m_name[2];
        !          1067:        } **ml = 0;
        !          1068:        register struct ml      *mlp;
        !          1069:        static unsigned mlsize = 0;
        !          1070:        static unsigned mlinks = 0;
        !          1071:        char            *lnamep;
        !          1072:        int             ans;
        !          1073: 
        !          1074:        if( !ml ) {
        !          1075:                mlsize = LINKS;
        !          1076:                ml = (struct ml **) malloc(mlsize * sizeof(struct ml));
        !          1077:        }
        !          1078:        else if( mlinks == mlsize ) {
        !          1079:                mlsize += LINKS;
        !          1080:                ml = (struct ml **) realloc((char *) ml,
        !          1081:                    mlsize * sizeof(struct ml));
        !          1082:        }
        !          1083:        if (ml == NULL) {
        !          1084:                fperr("Out of memory for links");
        !          1085:                exit(2);
        !          1086:        }
        !          1087:        for(i = 0; i < mlinks; ++i) {
        !          1088:                mlp = ml[i];
        !          1089:                if(mlp->m_ino==Hdr.h_ino  &&  mlp->m_dev==Hdr.h_dev) {
        !          1090:                        if(Verbose)
        !          1091:                          printf("%s linked to %s\n", ml[i]->m_name,
        !          1092:                                np);
        !          1093:                        unlink(namep);
        !          1094:                        if(Option == IN && *(mlp->m_name) != '/') {
        !          1095:                                Fullname[Pathend] = '\0';
        !          1096:                                strcat(Fullname, mlp->m_name);
        !          1097:                                lnamep = Fullname;
        !          1098:                        }
        !          1099:                        lnamep = mlp->m_name;
        !          1100: 
        !          1101: /* try linking (only twice) */
        !          1102:                        ans = 0;
        !          1103:                        do {
        !          1104:                                if(link(lnamep, namep) < 0) {
        !          1105:                                        ans += 1;
        !          1106:                                }else {
        !          1107:                                        ans = 0;
        !          1108:                                        break;
        !          1109:                                }
        !          1110:                        }while(ans < 2 && missdir(np) == 0);
        !          1111:                        if(ans == 1) {
        !          1112:                                fperrno("Cannot create directory for <%s>", np);
        !          1113:                                return(0);
        !          1114:                        }else if(ans == 2) {
        !          1115:                                fperrno("Cannot link <%s> & <%s>", lnamep, np);
        !          1116:                                return(0);
        !          1117:                        }
        !          1118: 
        !          1119:                        set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime));
        !          1120:                        return 0;
        !          1121:                }
        !          1122:        }
        !          1123:        if( !(ml[mlinks] = (struct ml *)malloc(strlen(np) + 2 + sizeof(struct ml)))) {
        !          1124:                static int first=1;
        !          1125: 
        !          1126:                if(first)
        !          1127:                        fperr("Out of memory for links");
        !          1128:                first = 0;
        !          1129:                return 1;
        !          1130:        }
        !          1131:        ml[mlinks]->m_dev = Hdr.h_dev;
        !          1132:        ml[mlinks]->m_ino = Hdr.h_ino;
        !          1133:        strcpy(ml[mlinks]->m_name, np);
        !          1134:        ++mlinks;
        !          1135:        return 1;
        !          1136: }
        !          1137: 
        !          1138: static
        !          1139: pentry(namep)          /* print verbose table of contents */
        !          1140: register char *namep;
        !          1141: {
        !          1142: 
        !          1143:        static short lastid = -1;
        !          1144: #include <pwd.h>
        !          1145:        static struct passwd *pw;
        !          1146:        struct passwd *getpwuid();
        !          1147:        static char tbuf[32];
        !          1148:        char *ctime();
        !          1149: 
        !          1150:        printf("%-7o", MK_USHORT(Hdr.h_mode));
        !          1151:        if(lastid == Hdr.h_uid)
        !          1152:                printf("%-6s", pw->pw_name);
        !          1153:        else {
        !          1154:                setpwent();
        !          1155:                if(pw = getpwuid((int)Hdr.h_uid)) {
        !          1156:                        printf("%-6s", pw->pw_name);
        !          1157:                        lastid = Hdr.h_uid;
        !          1158:                } else {
        !          1159:                        printf("%-6d", Hdr.h_uid);
        !          1160:                        lastid = -1;
        !          1161:                }
        !          1162:        }
        !          1163:        printf("%7ld ", mklong(Hdr.h_filesize));
        !          1164:        U.l = mklong(Hdr.h_mtime);
        !          1165:        strcpy(tbuf, ctime((long *)&U.l));
        !          1166:        tbuf[24] = '\0';
        !          1167:        printf(" %s  %s", &tbuf[4], namep);
        !          1168:        if (A_symlink)
        !          1169:                printf(" -> %s", Symlbuf);
        !          1170:        putchar('\n');
        !          1171: }
        !          1172: 
        !          1173:                /* pattern matching functions */
        !          1174: static
        !          1175: nmatch(s, pat)
        !          1176: char *s, **pat;
        !          1177: {
        !          1178:        if( !pat )
        !          1179:                return 1;
        !          1180:        while(*pat) {
        !          1181:                if((**pat == '!' && !gmatch(s, *pat+1))
        !          1182:                || gmatch(s, *pat))
        !          1183:                        return 1;
        !          1184:                ++pat;
        !          1185:        }
        !          1186:        return 0;
        !          1187: }
        !          1188: 
        !          1189: 
        !          1190: static
        !          1191: gmatch(s, p)
        !          1192: register char *s, *p;
        !          1193: {
        !          1194:        register int c;
        !          1195:        register cc, ok, lc, scc;
        !          1196: 
        !          1197:        scc = *s;
        !          1198:        lc = 077777;
        !          1199:        switch (c = *p) {
        !          1200: 
        !          1201:        case '[':
        !          1202:                ok = 0;
        !          1203:                while (cc = *++p) {
        !          1204:                        switch (cc) {
        !          1205: 
        !          1206:                        case ']':
        !          1207:                                if (ok)
        !          1208:                                        return(gmatch(++s, ++p));
        !          1209:                                else
        !          1210:                                        return(0);
        !          1211: 
        !          1212:                        case '-':
        !          1213:                                ok |= ((lc <= scc) && (scc <= (cc=p[1])));
        !          1214:                        }
        !          1215:                        if (scc==(lc=cc)) ok++;
        !          1216:                }
        !          1217:                return(0);
        !          1218: 
        !          1219:        case '?':
        !          1220:        caseq:
        !          1221:                if(scc) return(gmatch(++s, ++p));
        !          1222:                return(0);
        !          1223:        case '*':
        !          1224:                return(umatch(s, ++p));
        !          1225:        case 0:
        !          1226:                return(!scc);
        !          1227:        }
        !          1228:        if (c==scc) goto caseq;
        !          1229:        return(0);
        !          1230: }
        !          1231: 
        !          1232: 
        !          1233: 
        !          1234: static
        !          1235: umatch(s, p)
        !          1236: register char *s, *p;
        !          1237: {
        !          1238:        if(*p==0) return(1);
        !          1239:        while(*s)
        !          1240:                if (gmatch(s++,p)) return(1);
        !          1241:        return(0);
        !          1242: }
        !          1243: 
        !          1244: swap(buf, bytecount, bytes, halfwords) /* swap halfwords, bytes or both */
        !          1245: char *buf;
        !          1246: int bytecount;
        !          1247: int bytes, halfwords;
        !          1248: {
        !          1249:        register int count;
        !          1250:        int n, i;
        !          1251: 
        !          1252:        if(bytes) {
        !          1253:                register union swpbytes {
        !          1254:                        short   shortw;
        !          1255:                        char    charv[2];
        !          1256:                } *pbuf;
        !          1257:                register char c;
        !          1258: 
        !          1259:                count = bytecount;
        !          1260:                pbuf = (union swpbytes *)buf;
        !          1261:                if (count % sizeof(union swpbytes))
        !          1262:                        pbuf->charv[count] = 0;
        !          1263:                count = (count + (sizeof(union swpbytes) - 1)) / sizeof(union swpbytes);
        !          1264:                while (count--) {
        !          1265:                        c = pbuf->charv[0];
        !          1266:                        pbuf->charv[0] = pbuf->charv[1];
        !          1267:                        pbuf->charv[1] = c;
        !          1268:                        ++pbuf;
        !          1269:                }
        !          1270:        }
        !          1271:        if (halfwords) {
        !          1272:                register union swphalf {
        !          1273:                        long    longw;
        !          1274:                        short   shortv[2];
        !          1275:                        char    charv[4];
        !          1276:                } *pbuf;
        !          1277:                register short cc;
        !          1278: 
        !          1279:                count = bytecount;
        !          1280:                pbuf = (union swphalf *)buf;
        !          1281:                if (n = count % sizeof(union swphalf))
        !          1282:                        if(bytes && n % 2)
        !          1283:                                for(i = count + 1; i <= count + (sizeof(union swphalf) - n); i++)
        !          1284:                                        pbuf->charv[i] = 0;
        !          1285:                        else
        !          1286:                                for (i = count; i < count + (sizeof(union swphalf) - n); i++)
        !          1287:                                        pbuf->charv[i] = 0;
        !          1288:                count = (count + (sizeof(union swphalf) - 1)) / sizeof(union swphalf);
        !          1289:                while (count--) {
        !          1290:                        cc = pbuf->shortv[0];
        !          1291:                        pbuf->shortv[0] = pbuf->shortv[1];
        !          1292:                        pbuf->shortv[1] = cc;
        !          1293:                        ++pbuf;
        !          1294:                }
        !          1295:        }
        !          1296: }
        !          1297: 
        !          1298: 
        !          1299: static
        !          1300: set_time(namep, atime, mtime)  /* set access and modification times */
        !          1301: register char *namep;
        !          1302: time_t atime, mtime;
        !          1303: {
        !          1304:        static struct utimbuf timevec;
        !          1305: 
        !          1306:        if(!Mod_time)
        !          1307:                return;
        !          1308:        timevec.actime = atime;
        !          1309:        timevec.modtime = mtime;
        !          1310:        (void)utime(namep, &timevec);
        !          1311: }
        !          1312: 
        !          1313: 
        !          1314: 
        !          1315: static
        !          1316: chgreel(x, fl, rv)
        !          1317: {
        !          1318:        register f;
        !          1319:        char str[BUFSIZ];
        !          1320:        struct stat statb;
        !          1321: 
        !          1322:        fstat(fl, &statb);
        !          1323:        if((statb.st_mode&S_IFMT) != S_IFCHR) {
        !          1324:                fperrno("Can't %s: ", x? "write output": "read input");
        !          1325:                exit(2);
        !          1326:        }
        !          1327:        if( rv == 0  ||
        !          1328:                ( rv == -1  &&  ( errno == ENOSPC  ||  errno == ENXIO ) ) )
        !          1329:                fperr( "\007Reached end of medium on %s",
        !          1330:                        x? "output":"input" );
        !          1331:        else {
        !          1332:                fperrno( "\007Encountered an error on %s",
        !          1333:                        x? "output":"input" );
        !          1334:                exit(2);
        !          1335:        }
        !          1336:        if( Rtty == NULL ) {
        !          1337:                Rtty = fopen(ttyname, "r");
        !          1338:                if( Rtty == NULL ) {
        !          1339:                        fperrno("Cannot prompt (can't open %s)", ttyname);
        !          1340:                        exit(2);
        !          1341:                }
        !          1342:        }
        !          1343:        close(fl);
        !          1344:        reelcount++;
        !          1345: again:
        !          1346:        if( swfile ) {
        !          1347:            askagain:
        !          1348:                fperr( eommsg, reelcount );
        !          1349:                fgets(str, sizeof str, Rtty);
        !          1350:                switch( *str ) {
        !          1351:                case '\n':
        !          1352:                        strcpy( str, swfile );
        !          1353:                        break;
        !          1354:                case 'q':
        !          1355:                        exit(2);
        !          1356:                default:
        !          1357:                        goto askagain;
        !          1358:                }
        !          1359:        }
        !          1360:        else {
        !          1361:                fperr("If you want to go on, type device/file name when ready.");
        !          1362:                fgets(str, sizeof str, Rtty);
        !          1363:                str[strlen(str) - 1] = '\0';
        !          1364:                if(!*str)
        !          1365:                        exit(2);
        !          1366:        }
        !          1367:        if((f = open(str, x? 1: 0)) < 0) {
        !          1368:                fperrno("Can't open <%s>", str);
        !          1369:                goto again;
        !          1370:        }
        !          1371:        return f;
        !          1372: }
        !          1373: 
        !          1374: 
        !          1375: 
        !          1376: static
        !          1377: missdir(namep)
        !          1378: register char *namep;
        !          1379: {
        !          1380:        register char *np;
        !          1381:        register ct = 2;
        !          1382: 
        !          1383:        for(np = namep; *np; ++np)
        !          1384:                if(*np == '/') {
        !          1385:                        if(np == namep) continue;       /* skip over 'root slash' */
        !          1386:                        *np = '\0';
        !          1387:                        if(stat(namep, &Xstatb) == -1) {
        !          1388:                                if(Dir) {
        !          1389:                                        if((ct = mkdir(namep, 0777)) != 0) {
        !          1390:                                                *np = '/';
        !          1391:                                                return(ct);
        !          1392:                                        }
        !          1393:                                }else {
        !          1394:                                        fperr("missing 'd' option");
        !          1395:                                        return(-1);
        !          1396:                                }
        !          1397:                        }
        !          1398:                        *np = '/';
        !          1399:                }
        !          1400:        if (ct == 2) ct = 0;            /* the file already exists */
        !          1401:        return ct;
        !          1402: }
        !          1403: 
        !          1404: 
        !          1405: 
        !          1406: static
        !          1407: pwd()          /* get working directory */
        !          1408: {
        !          1409:        if (getwd(Fullname) == 0) {
        !          1410:                (void)fprintf(stderr, "cpio: %s\n",
        !          1411:                    Fullname);
        !          1412:                exit(2);
        !          1413:        }
        !          1414:        Pathend = strlen(Fullname);
        !          1415:        Fullname[Pathend++] = '/';
        !          1416:        Fullname[Pathend] = '\0';
        !          1417: }
        !          1418: 
        !          1419: 
        !          1420: /*
        !          1421:        print message on the stderr
        !          1422: */
        !          1423: static
        !          1424: fperr( va_alist )
        !          1425: va_dcl
        !          1426: {
        !          1427:        va_list args;
        !          1428:        char    *fmt;
        !          1429: 
        !          1430:        va_start( args );
        !          1431:        fprintf( stderr, "cpio: ");
        !          1432:        fmt = va_arg( args, char * );
        !          1433:        vfprintf( stderr, fmt, args );
        !          1434:        putc( '\n', stderr);
        !          1435:        fflush( stderr );
        !          1436: }
        !          1437: 
        !          1438: /*
        !          1439:        print message on the stderr followed by error number and meaning.
        !          1440: */
        !          1441: static
        !          1442: fperrno( va_alist )
        !          1443: va_dcl
        !          1444: {
        !          1445:        va_list args;
        !          1446:        char    *fmt;
        !          1447: 
        !          1448:        va_start( args );
        !          1449:        fprintf( stderr, "cpio: ");
        !          1450:        fmt = va_arg( args, char * );
        !          1451:        vfprintf( stderr, fmt, args );
        !          1452:        fprintf( stderr, ": " );
        !          1453:        fflush( stderr );
        !          1454:        perror("");
        !          1455: }
        !          1456: 
        !          1457: 
        !          1458: /*     Safe memory copy.
        !          1459:        Fast if the to and from strings do not overlap,
        !          1460:        slower but safe if they do.
        !          1461: */
        !          1462: 
        !          1463: static char *
        !          1464: smemcpy( to, from, count )
        !          1465: register char          *to, *from;
        !          1466: register unsigned      count;
        !          1467: {
        !          1468:        char    *savedto;
        !          1469: 
        !          1470:        if( &to[ count ] <= from  ||  &from[ count ] <= to )
        !          1471:                return  memcpy( to, from, count );
        !          1472: 
        !          1473:        if( to == from )
        !          1474:                return  to;
        !          1475: 
        !          1476:        savedto = to;
        !          1477:        if( to < from )
        !          1478:                while( count-- )
        !          1479:                        *(to++) = *(from++);
        !          1480:        else {
        !          1481:                to += count;
        !          1482:                from += count;
        !          1483:                while( count-- )
        !          1484:                        *(--to) = *(--from);
        !          1485:        }
        !          1486: 
        !          1487:        return  savedto;
        !          1488: }
        !          1489: 
        !          1490: extern int _doprnt();
        !          1491: 
        !          1492: /*VARARGS2*/
        !          1493: int
        !          1494: vfprintf(iop, format, ap)
        !          1495: FILE *iop;
        !          1496: char *format;
        !          1497: va_list ap;
        !          1498: {
        !          1499:        register int count;
        !          1500: 
        !          1501:        if (!(iop->_flag | _IOWRT)) {
        !          1502:                /* if no write flag */
        !          1503:                if (iop->_flag | _IORW) {
        !          1504:                        /* if ok, cause read-write */
        !          1505:                        iop->_flag |= _IOWRT;
        !          1506:                } else {
        !          1507:                        /* else error */
        !          1508:                        return EOF;
        !          1509:                }
        !          1510:        }
        !          1511:        count = _doprnt(format, ap, iop);
        !          1512:        return(ferror(iop)? EOF: count);
        !          1513: }

unix.superglobalmegacorp.com

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