[BACK]Return to options.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / bin / pax

Annotation of src/bin/pax/options.c, Revision 1.22

1.22    ! tron        1: /*     $NetBSD: options.c,v 1.21 1999/08/24 08:00:03 tron Exp $        */
1.5       cgd         2:
1.1       jtc         3: /*-
                      4:  * Copyright (c) 1992 Keith Muller.
                      5:  * Copyright (c) 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Keith Muller of the University of California, San Diego.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the University of
                     22:  *     California, Berkeley and its contributors.
                     23:  * 4. Neither the name of the University nor the names of its contributors
                     24:  *    may be used to endorse or promote products derived from this software
                     25:  *    without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     28:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     29:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     30:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     31:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     32:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     33:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     34:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     35:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     36:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     37:  * SUCH DAMAGE.
                     38:  */
                     39:
1.8       christos   40: #include <sys/cdefs.h>
1.1       jtc        41: #ifndef lint
1.5       cgd        42: #if 0
                     43: static char sccsid[] = "@(#)options.c  8.2 (Berkeley) 4/18/94";
                     44: #else
1.22    ! tron       45: __RCSID("$NetBSD: options.c,v 1.21 1999/08/24 08:00:03 tron Exp $");
1.5       cgd        46: #endif
1.1       jtc        47: #endif /* not lint */
                     48:
                     49: #include <sys/types.h>
                     50: #include <sys/time.h>
                     51: #include <sys/stat.h>
                     52: #include <sys/mtio.h>
                     53: #include <sys/param.h>
                     54: #include <stdio.h>
                     55: #include <ctype.h>
                     56: #include <string.h>
                     57: #include <unistd.h>
                     58: #include <stdlib.h>
                     59: #include <limits.h>
                     60: #include "pax.h"
                     61: #include "options.h"
                     62: #include "cpio.h"
                     63: #include "tar.h"
                     64: #include "extern.h"
                     65:
                     66: /*
                     67:  * Routines which handle command line options
                     68:  */
                     69:
1.10      mrg        70: int cpio_mode;                 /* set if we are in cpio mode */
                     71: char *chdir_dir;               /* directory to chdir to before operating */
                     72:
1.18      tv         73: static int nopids;             /* tar mode: suppress "pids" for -p option */
1.10      mrg        74: static char *flgch = FLGCH;    /* list of all possible flags (pax) */
1.1       jtc        75: static OPLIST *ophead = NULL;  /* head for format specific options -x */
                     76: static OPLIST *optail = NULL;  /* option tail */
                     77:
                     78: static int no_op __P((void));
                     79: static void printflg __P((unsigned int));
                     80: static int c_frmt __P((const void *, const void *));
                     81: static off_t str_offt __P((char *));
1.7       tls        82: static void pax_options __P((int, char **));
1.1       jtc        83: static void pax_usage __P((void));
1.7       tls        84: static void tar_options __P((int, char **));
1.1       jtc        85: static void tar_usage __P((void));
1.7       tls        86: static void cpio_options __P((int, char **));
1.1       jtc        87: static void cpio_usage __P((void));
                     88:
1.6       mrg        89: #define GZIP_CMD       "gzip"          /* command to run as gzip */
                     90: #define COMPRESS_CMD   "compress"      /* command to run as compress */
                     91:
1.1       jtc        92: /*
                     93:  *     Format specific routine table - MUST BE IN SORTED ORDER BY NAME
                     94:  *     (see pax.h for description of each function)
                     95:  *
                     96:  *     name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
                     97:  *     read, end_read, st_write, write, end_write, trail,
                     98:  *     rd_data, wr_data, options
                     99:  */
                    100:
                    101: FSUB fsub[] = {
                    102: /* 0: OLD BINARY CPIO */
1.8       christos  103:        { "bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,
                    104:        bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, NULL,
                    105:        cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
1.1       jtc       106:
                    107: /* 1: OLD OCTAL CHARACTER CPIO */
1.8       christos  108:        { "cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,
                    109:        cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, NULL,
                    110:        cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
1.1       jtc       111:
                    112: /* 2: SVR4 HEX CPIO */
1.8       christos  113:        { "sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,
                    114:        vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, NULL,
                    115:        cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
1.1       jtc       116:
                    117: /* 3: SVR4 HEX CPIO WITH CRC */
1.8       christos  118:        { "sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,
                    119:        vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, NULL,
                    120:        cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
1.1       jtc       121:
                    122: /* 4: OLD TAR */
1.8       christos  123:        { "tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op,
1.1       jtc       124:        tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
1.8       christos  125:        NULL, rd_wrfile, wr_rdfile, tar_opt },
1.1       jtc       126:
                    127: /* 5: POSIX USTAR */
1.8       christos  128:        { "ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,
1.1       jtc       129:        ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
1.8       christos  130:        NULL, rd_wrfile, wr_rdfile, bad_opt }
1.1       jtc       131: };
1.10      mrg       132: #define F_BCPIO                0       /* old binary cpio format */
                    133: #define F_CPIO         1       /* old octal character cpio format */
                    134: #define F_SV4CPIO      2       /* SVR4 hex cpio format */
                    135: #define F_SV4CRC       3       /* SVR4 hex with crc cpio format */
1.18      tv        136: #define F_TAR          4       /* old V7 UNIX tar format */
1.10      mrg       137: #define F_USTAR                5       /* ustar format */
                    138: #define DEFLT          F_USTAR /* default write format from list above */
1.1       jtc       139:
                    140: /*
                    141:  * ford is the archive search order used by get_arc() to determine what kind
                    142:  * of archive we are dealing with. This helps to properly id  archive formats
                    143:  * some formats may be subsets of others....
                    144:  */
1.10      mrg       145: int ford[] = {F_USTAR, F_TAR, F_SV4CRC, F_SV4CPIO, F_CPIO, F_BCPIO, -1};
1.1       jtc       146:
                    147: /*
                    148:  * options()
                    149:  *     figure out if we are pax, tar or cpio. Call the appropriate options
                    150:  *     parser
                    151:  */
                    152:
                    153: #if __STDC__
                    154: void
1.7       tls       155: options(int argc, char **argv)
1.1       jtc       156: #else
                    157: void
                    158: options(argc, argv)
1.7       tls       159:        int argc;
                    160:        char **argv;
1.1       jtc       161: #endif
                    162: {
                    163:
                    164:        /*
                    165:         * Are we acting like pax, tar or cpio (based on argv[0])
                    166:         */
                    167:        if ((argv0 = strrchr(argv[0], '/')) != NULL)
                    168:                argv0++;
                    169:        else
                    170:                argv0 = argv[0];
                    171:
                    172:        if (strcmp(NM_TAR, argv0) == 0)
1.13      mycroft   173:                tar_options(argc, argv);
1.1       jtc       174:        else if (strcmp(NM_CPIO, argv0) == 0)
1.13      mycroft   175:                cpio_options(argc, argv);
                    176:        else {
                    177:                argv0 = NM_PAX;
                    178:                pax_options(argc, argv);
                    179:        }
1.1       jtc       180: }
                    181:
                    182: /*
                    183:  * pax_options()
                    184:  *     look at the user specified flags. set globals as required and check if
                    185:  *     the user specified a legal set of flags. If not, complain and exit
                    186:  */
                    187:
                    188: #if __STDC__
                    189: static void
1.7       tls       190: pax_options(int argc, char **argv)
1.1       jtc       191: #else
                    192: static void
                    193: pax_options(argc, argv)
1.7       tls       194:        int argc;
                    195:        char **argv;
1.1       jtc       196: #endif
                    197: {
1.7       tls       198:        int c;
                    199:        int i;
1.1       jtc       200:        unsigned int flg = 0;
                    201:        unsigned int bflg = 0;
1.7       tls       202:        char *pt;
1.1       jtc       203:         FSUB tmp;
                    204:        extern char *optarg;
                    205:        extern int optind;
                    206:
                    207:        /*
                    208:         * process option flags
                    209:         */
1.20      tron      210:        while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zAB:DE:G:HLPT:U:XYZ"))
1.9       lukem     211:            != -1) {
1.1       jtc       212:                switch (c) {
                    213:                case 'a':
                    214:                        /*
                    215:                         * append
                    216:                         */
                    217:                        flg |= AF;
                    218:                        break;
                    219:                case 'b':
                    220:                        /*
                    221:                         * specify blocksize
                    222:                         */
                    223:                        flg |= BF;
                    224:                        if ((wrblksz = (int)str_offt(optarg)) <= 0) {
1.8       christos  225:                                tty_warn(1, "Invalid block size %s", optarg);
1.1       jtc       226:                                pax_usage();
                    227:                        }
                    228:                        break;
                    229:                case 'c':
                    230:                        /*
                    231:                         * inverse match on patterns
                    232:                         */
                    233:                        cflag = 1;
                    234:                        flg |= CF;
                    235:                        break;
                    236:                case 'd':
                    237:                        /*
                    238:                         * match only dir on extract, not the subtree at dir
                    239:                         */
                    240:                        dflag = 1;
                    241:                        flg |= DF;
                    242:                        break;
                    243:                case 'f':
                    244:                        /*
                    245:                         * filename where the archive is stored
                    246:                         */
                    247:                        arcname = optarg;
                    248:                        flg |= FF;
                    249:                        break;
                    250:                case 'i':
                    251:                        /*
                    252:                         * interactive file rename
                    253:                         */
                    254:                        iflag = 1;
                    255:                        flg |= IF;
                    256:                        break;
                    257:                case 'k':
                    258:                        /*
                    259:                         * do not clobber files that exist
                    260:                         */
                    261:                        kflag = 1;
                    262:                        flg |= KF;
                    263:                        break;
                    264:                case 'l':
                    265:                        /*
                    266:                         * try to link src to dest with copy (-rw)
                    267:                         */
                    268:                        lflag = 1;
                    269:                        flg |= LF;
                    270:                        break;
                    271:                case 'n':
                    272:                        /*
                    273:                         * select first match for a pattern only
                    274:                         */
                    275:                        nflag = 1;
                    276:                        flg |= NF;
                    277:                        break;
                    278:                case 'o':
                    279:                        /*
                    280:                         * pass format specific options
                    281:                         */
                    282:                        flg |= OF;
                    283:                        if (opt_add(optarg) < 0)
                    284:                                pax_usage();
                    285:                        break;
                    286:                case 'p':
                    287:                        /*
                    288:                         * specify file characteristic options
                    289:                         */
                    290:                        for (pt = optarg; *pt != '\0'; ++pt) {
                    291:                                switch(*pt) {
                    292:                                case 'a':
                    293:                                        /*
                    294:                                         * do not preserve access time
                    295:                                         */
                    296:                                        patime = 0;
                    297:                                        break;
                    298:                                case 'e':
                    299:                                        /*
                    300:                                         * preserve user id, group id, file
                    301:                                         * mode, access/modification times
                    302:                                         */
                    303:                                        pids = 1;
                    304:                                        pmode = 1;
                    305:                                        patime = 1;
                    306:                                        pmtime = 1;
                    307:                                        break;
                    308:                                case 'm':
                    309:                                        /*
                    310:                                         * do not preserve modification time
                    311:                                         */
                    312:                                        pmtime = 0;
                    313:                                        break;
                    314:                                case 'o':
                    315:                                        /*
                    316:                                         * preserve uid/gid
                    317:                                         */
                    318:                                        pids = 1;
                    319:                                        break;
                    320:                                case 'p':
                    321:                                        /*
                    322:                                         * preserver file mode bits
                    323:                                         */
                    324:                                        pmode = 1;
                    325:                                        break;
                    326:                                default:
1.8       christos  327:                                        tty_warn(1,
                    328:                                            "Invalid -p string: %c", *pt);
1.1       jtc       329:                                        pax_usage();
                    330:                                        break;
                    331:                                }
                    332:                        }
                    333:                        flg |= PF;
                    334:                        break;
                    335:                case 'r':
                    336:                        /*
                    337:                         * read the archive
                    338:                         */
                    339:                        flg |= RF;
                    340:                        break;
                    341:                case 's':
                    342:                        /*
                    343:                         * file name substitution name pattern
                    344:                         */
                    345:                        if (rep_add(optarg) < 0) {
                    346:                                pax_usage();
                    347:                                break;
                    348:                        }
                    349:                        flg |= SF;
                    350:                        break;
                    351:                case 't':
                    352:                        /*
                    353:                         * preserve access time on filesystem nodes we read
                    354:                         */
                    355:                        tflag = 1;
                    356:                        flg |= TF;
                    357:                        break;
                    358:                case 'u':
                    359:                        /*
                    360:                         * ignore those older files
                    361:                         */
                    362:                        uflag = 1;
                    363:                        flg |= UF;
                    364:                        break;
                    365:                case 'v':
                    366:                        /*
                    367:                         * verbose operation mode
                    368:                         */
                    369:                        vflag = 1;
                    370:                        flg |= VF;
                    371:                        break;
                    372:                case 'w':
                    373:                        /*
                    374:                         * write an archive
                    375:                         */
                    376:                        flg |= WF;
                    377:                        break;
                    378:                case 'x':
                    379:                        /*
                    380:                         * specify an archive format on write
                    381:                         */
                    382:                        tmp.name = optarg;
1.8       christos  383:                        frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
                    384:                            sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt);
                    385:                        if (frmt != NULL) {
1.1       jtc       386:                                flg |= XF;
                    387:                                break;
                    388:                        }
1.8       christos  389:                        tty_warn(1, "Unknown -x format: %s", optarg);
1.1       jtc       390:                        (void)fputs("pax: Known -x formats are:", stderr);
                    391:                        for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
                    392:                                (void)fprintf(stderr, " %s", fsub[i].name);
                    393:                        (void)fputs("\n\n", stderr);
                    394:                        pax_usage();
                    395:                        break;
1.6       mrg       396:                case 'z':
                    397:                        /*
                    398:                         * use gzip.  Non standard option.
                    399:                         */
                    400:                        zflag = 1;
                    401:                        gzip_program = GZIP_CMD;
1.20      tron      402:                        break;
                    403:                case 'A':
                    404:                        Aflag = 1;
                    405:                        flg |= CAF;
1.6       mrg       406:                        break;
1.1       jtc       407:                case 'B':
                    408:                        /*
                    409:                         * non-standard option on number of bytes written on a
                    410:                         * single archive volume.
                    411:                         */
                    412:                        if ((wrlimit = str_offt(optarg)) <= 0) {
1.8       christos  413:                                tty_warn(1, "Invalid write limit %s", optarg);
1.1       jtc       414:                                pax_usage();
                    415:                        }
                    416:                        if (wrlimit % BLKMULT) {
1.8       christos  417:                                tty_warn(1,
                    418:                                    "Write limit is not a %d byte multiple",
1.1       jtc       419:                                    BLKMULT);
                    420:                                pax_usage();
                    421:                        }
                    422:                        flg |= CBF;
                    423:                        break;
                    424:                case 'D':
                    425:                        /*
                    426:                         * On extraction check file inode change time before the
                    427:                         * modification of the file name. Non standard option.
                    428:                         */
                    429:                        Dflag = 1;
                    430:                        flg |= CDF;
                    431:                        break;
                    432:                case 'E':
                    433:                        /*
                    434:                         * non-standard limit on read faults
                    435:                         * 0 indicates stop after first error, values
                    436:                         * indicate a limit, "NONE" try forever
                    437:                         */
                    438:                        flg |= CEF;
                    439:                        if (strcmp(NONE, optarg) == 0)
                    440:                                maxflt = -1;
                    441:                        else if ((maxflt = atoi(optarg)) < 0) {
1.8       christos  442:                                tty_warn(1,
                    443:                                    "Error count value must be positive");
1.1       jtc       444:                                pax_usage();
                    445:                        }
                    446:                        break;
                    447:                case 'G':
                    448:                        /*
                    449:                         * non-standard option for selecting files within an
                    450:                         * archive by group (gid or name)
                    451:                         */
                    452:                        if (grp_add(optarg) < 0) {
                    453:                                pax_usage();
                    454:                                break;
                    455:                        }
                    456:                        flg |= CGF;
                    457:                        break;
                    458:                case 'H':
                    459:                        /*
                    460:                         * follow command line symlinks only
                    461:                         */
                    462:                        Hflag = 1;
                    463:                        flg |= CHF;
                    464:                        break;
                    465:                case 'L':
                    466:                        /*
                    467:                         * follow symlinks
                    468:                         */
                    469:                        Lflag = 1;
                    470:                        flg |= CLF;
                    471:                        break;
                    472:                case 'P':
                    473:                        /*
                    474:                         * do NOT follow symlinks (default)
                    475:                         */
                    476:                        Lflag = 0;
                    477:                        flg |= CPF;
                    478:                        break;
                    479:                case 'T':
                    480:                        /*
                    481:                         * non-standard option for selecting files within an
                    482:                         * archive by modification time range (lower,upper)
                    483:                         */
                    484:                        if (trng_add(optarg) < 0) {
                    485:                                pax_usage();
                    486:                                break;
                    487:                        }
                    488:                        flg |= CTF;
                    489:                        break;
                    490:                case 'U':
                    491:                        /*
                    492:                         * non-standard option for selecting files within an
                    493:                         * archive by user (uid or name)
                    494:                         */
                    495:                        if (usr_add(optarg) < 0) {
                    496:                                pax_usage();
                    497:                                break;
                    498:                        }
                    499:                        flg |= CUF;
                    500:                        break;
                    501:                case 'X':
                    502:                        /*
                    503:                         * do not pass over mount points in the file system
                    504:                         */
                    505:                        Xflag = 1;
                    506:                        flg |= CXF;
                    507:                        break;
                    508:                case 'Y':
                    509:                        /*
                    510:                         * On extraction check file inode change time after the
                    511:                         * modification of the file name. Non standard option.
                    512:                         */
                    513:                        Yflag = 1;
                    514:                        flg |= CYF;
                    515:                        break;
                    516:                case 'Z':
                    517:                        /*
                    518:                         * On extraction check modification time after the
                    519:                         * modification of the file name. Non standard option.
                    520:                         */
                    521:                        Zflag = 1;
                    522:                        flg |= CZF;
                    523:                        break;
                    524:                case '?':
                    525:                default:
                    526:                        pax_usage();
                    527:                        break;
                    528:                }
                    529:        }
                    530:
                    531:        /*
                    532:         * figure out the operation mode of pax read,write,extract,copy,append
                    533:         * or list. check that we have not been given a bogus set of flags
                    534:         * for the operation mode.
                    535:         */
                    536:        if (ISLIST(flg)) {
                    537:                act = LIST;
                    538:                bflg = flg & BDLIST;
                    539:        } else if (ISEXTRACT(flg)) {
                    540:                act = EXTRACT;
                    541:                bflg = flg & BDEXTR;
                    542:        } else if (ISARCHIVE(flg)) {
                    543:                act = ARCHIVE;
                    544:                bflg = flg & BDARCH;
                    545:        } else if (ISAPPND(flg)) {
                    546:                act = APPND;
                    547:                bflg = flg & BDARCH;
                    548:        } else if (ISCOPY(flg)) {
                    549:                act = COPY;
                    550:                bflg = flg & BDCOPY;
                    551:        } else
                    552:                pax_usage();
                    553:        if (bflg) {
                    554:                printflg(flg);
                    555:                pax_usage();
                    556:        }
                    557:
                    558:        /*
                    559:         * if we are writing (ARCHIVE) we use the default format if the user
                    560:         * did not specify a format. when we write during an APPEND, we will
                    561:         * adopt the format of the existing archive if none was supplied.
                    562:         */
                    563:        if (!(flg & XF) && (act == ARCHIVE))
                    564:                frmt = &(fsub[DEFLT]);
                    565:
                    566:        /*
                    567:         * process the args as they are interpreted by the operation mode
                    568:         */
                    569:        switch (act) {
                    570:        case LIST:
                    571:        case EXTRACT:
                    572:                for (; optind < argc; optind++)
                    573:                        if (pat_add(argv[optind]) < 0)
                    574:                                pax_usage();
                    575:                break;
                    576:        case COPY:
                    577:                if (optind >= argc) {
1.8       christos  578:                        tty_warn(0, "Destination directory was not supplied");
1.1       jtc       579:                        pax_usage();
                    580:                }
                    581:                --argc;
                    582:                dirptr = argv[argc];
1.14      mycroft   583:                /* FALLTHROUGH */
1.1       jtc       584:        case ARCHIVE:
                    585:        case APPND:
                    586:                for (; optind < argc; optind++)
                    587:                        if (ftree_add(argv[optind]) < 0)
                    588:                                pax_usage();
                    589:                /*
                    590:                 * no read errors allowed on updates/append operation!
                    591:                 */
                    592:                maxflt = 0;
                    593:                break;
                    594:        }
                    595: }
                    596:
                    597:
                    598: /*
                    599:  * tar_options()
                    600:  *     look at the user specified flags. set globals as required and check if
                    601:  *     the user specified a legal set of flags. If not, complain and exit
                    602:  */
                    603:
                    604: #if __STDC__
                    605: static void
1.7       tls       606: tar_options(int argc, char **argv)
1.1       jtc       607: #else
                    608: static void
                    609: tar_options(argc, argv)
1.7       tls       610:        int argc;
                    611:        char **argv;
1.1       jtc       612: #endif
                    613: {
1.7       tls       614:        int c;
1.1       jtc       615:        int fstdin = 0;
                    616:
                    617:        /*
                    618:         * process option flags
                    619:         */
1.22    ! tron      620:        while ((c = getoldopt(argc, argv, "b:cef:hlmoprutvwxzBC:LPX:Z014578"))
1.9       lukem     621:            != -1)  {
1.4       jtc       622:                switch(c) {
1.1       jtc       623:                case 'b':
                    624:                        /*
                    625:                         * specify blocksize
                    626:                         */
1.4       jtc       627:                        if ((wrblksz = (int)str_offt(optarg)) <= 0) {
1.8       christos  628:                                tty_warn(1, "Invalid block size %s", optarg);
1.1       jtc       629:                                tar_usage();
                    630:                        }
                    631:                        break;
                    632:                case 'c':
                    633:                        /*
                    634:                         * create an archive
                    635:                         */
                    636:                        act = ARCHIVE;
                    637:                        break;
1.10      mrg       638:                case 'C':
                    639:                        /*
                    640:                         * chdir here before extracting.
                    641:                         */
                    642:                        chdir_dir = optarg;
                    643:                        break;
1.1       jtc       644:                case 'e':
                    645:                        /*
                    646:                         * stop after first error
                    647:                         */
                    648:                        maxflt = 0;
                    649:                        break;
                    650:                case 'f':
                    651:                        /*
                    652:                         * filename where the archive is stored
                    653:                         */
1.4       jtc       654:                        if ((optarg[0] == '-') && (optarg[1]== '\0')) {
1.1       jtc       655:                                /*
                    656:                                 * treat a - as stdin
                    657:                                 */
1.4       jtc       658:                                fstdin = 1;
1.1       jtc       659:                                arcname = (char *)0;
                    660:                                break;
                    661:                        }
                    662:                        fstdin = 0;
1.4       jtc       663:                        arcname = optarg;
1.1       jtc       664:                        break;
1.21      tron      665:                case 'h':
                    666:                        /*
                    667:                         * follow command line symlinks only
                    668:                         */
                    669:                        Hflag = 1;
                    670:                        break;
1.10      mrg       671:                case 'l':
                    672:                        /*
                    673:                         * do not pass over mount points in the file system
                    674:                         */
                    675:                        Xflag = 1;
                    676:                        break;
1.1       jtc       677:                case 'm':
                    678:                        /*
                    679:                         * do not preserve modification time
                    680:                         */
                    681:                        pmtime = 0;
                    682:                        break;
                    683:                case 'o':
1.18      tv        684:                        /*
                    685:                         * This option does several things based on whether
                    686:                         * this is a create or extract operation.
                    687:                         */
                    688:                        if (act == ARCHIVE) {
                    689:                                /* 4.2BSD: don't add directory entries. */
                    690:                                if (opt_add("write_opt=nodir") < 0)
                    691:                                        tar_usage();
                    692:
                    693:                                /* GNU tar: write V7 format archives. */
1.16      tv        694:                                frmt = &(fsub[F_TAR]);
1.18      tv        695:                        } else {
                    696:                                /* SUS: don't preserve owner/group. */
                    697:                                pids = 0;
                    698:                                nopids = 1;
                    699:                        }
1.1       jtc       700:                        break;
                    701:                case 'p':
                    702:                        /*
                    703:                         * preserve user id, group id, file
                    704:                         * mode, access/modification times
                    705:                         */
1.18      tv        706:                        if (!nopids)
                    707:                                pids = 1;
1.1       jtc       708:                        pmode = 1;
                    709:                        patime = 1;
                    710:                        pmtime = 1;
                    711:                        break;
                    712:                case 'r':
                    713:                case 'u':
                    714:                        /*
                    715:                         * append to the archive
                    716:                         */
                    717:                        act = APPND;
                    718:                        break;
                    719:                case 't':
                    720:                        /*
                    721:                         * list contents of the tape
                    722:                         */
                    723:                        act = LIST;
                    724:                        break;
                    725:                case 'v':
                    726:                        /*
                    727:                         * verbose operation mode
                    728:                         */
                    729:                        vflag = 1;
                    730:                        break;
                    731:                case 'w':
                    732:                        /*
                    733:                         * interactive file rename
                    734:                         */
                    735:                        iflag = 1;
                    736:                        break;
                    737:                case 'x':
                    738:                        /*
                    739:                         * write an archive
                    740:                         */
                    741:                        act = EXTRACT;
                    742:                        break;
1.6       mrg       743:                case 'z':
                    744:                        /*
                    745:                         * use gzip.  Non standard option.
                    746:                         */
                    747:                        zflag = 1;
                    748:                        gzip_program = GZIP_CMD;
                    749:                        break;
1.1       jtc       750:                case 'B':
                    751:                        /*
                    752:                         * Nothing to do here, this is pax default
                    753:                         */
                    754:                        break;
                    755:                case 'L':
                    756:                        /*
                    757:                         * follow symlinks
                    758:                         */
                    759:                        Lflag = 1;
                    760:                        break;
                    761:                case 'P':
1.21      tron      762:                        Aflag = 1;
1.1       jtc       763:                        break;
                    764:                case 'X':
                    765:                        /*
1.15      mrg       766:                         * GNU tar compat: exclude the files listed in optarg
1.1       jtc       767:                         */
1.15      mrg       768:                        if (tar_gnutar_X_compat(optarg) != 0)
                    769:                                tar_usage();
1.6       mrg       770:                        break;
                    771:                case 'Z':
                    772:                        /*
                    773:                         * use compress.
                    774:                         */
                    775:                        zflag = 1;
                    776:                        gzip_program = COMPRESS_CMD;
1.1       jtc       777:                        break;
                    778:                case '0':
                    779:                        arcname = DEV_0;
                    780:                        break;
                    781:                case '1':
                    782:                        arcname = DEV_1;
                    783:                        break;
                    784:                case '4':
                    785:                        arcname = DEV_4;
                    786:                        break;
                    787:                case '5':
                    788:                        arcname = DEV_5;
                    789:                        break;
                    790:                case '7':
                    791:                        arcname = DEV_7;
                    792:                        break;
                    793:                case '8':
                    794:                        arcname = DEV_8;
                    795:                        break;
                    796:                default:
                    797:                        tar_usage();
                    798:                        break;
                    799:                }
                    800:        }
1.4       jtc       801:        argc -= optind;
                    802:        argv += optind;
1.17      tv        803:
                    804:        /*
                    805:         * if we are writing (ARCHIVE) specify tar, otherwise run like pax
                    806:         */
                    807:        if (act == ARCHIVE && frmt == NULL)
                    808:                frmt = &(fsub[F_USTAR]);
1.1       jtc       809:
                    810:        /*
                    811:         * process the args as they are interpreted by the operation mode
                    812:         */
                    813:        switch (act) {
                    814:        case LIST:
                    815:        case EXTRACT:
                    816:        default:
                    817:                while (*argv != (char *)NULL)
                    818:                        if (pat_add(*argv++) < 0)
                    819:                                tar_usage();
                    820:                break;
                    821:        case ARCHIVE:
                    822:        case APPND:
                    823:                while (*argv != (char *)NULL)
                    824:                        if (ftree_add(*argv++) < 0)
                    825:                                tar_usage();
                    826:                /*
                    827:                 * no read errors allowed on updates/append operation!
                    828:                 */
                    829:                maxflt = 0;
                    830:                break;
                    831:        }
                    832:        if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) {
                    833:                arcname = getenv("TAPE");
                    834:                if ((arcname == (char *)NULL) || (*arcname == '\0'))
                    835:                        arcname = DEV_8;
                    836:        }
                    837: }
                    838:
                    839: /*
                    840:  * cpio_options()
                    841:  *     look at the user specified flags. set globals as required and check if
                    842:  *     the user specified a legal set of flags. If not, complain and exit
                    843:  */
                    844:
                    845: #if __STDC__
                    846: static void
1.7       tls       847: cpio_options(int argc, char **argv)
1.1       jtc       848: #else
                    849: static void
                    850: cpio_options(argc, argv)
1.7       tls       851:        int argc;
                    852:        char **argv;
1.1       jtc       853: #endif
                    854: {
1.10      mrg       855:         FSUB tmp;
                    856:        unsigned int flg = 0;
                    857:        unsigned int bflg = 0;
                    858:        int c, i;
                    859:
                    860:        cpio_mode = uflag = 1;
                    861:        /*
                    862:         * process option flags
                    863:         */
                    864:        while ((c = getoldopt(argc, argv, "ABC:E:H:I:LM:O:R:SVabcdfiklmoprstuv"))
                    865:            != -1)  {
                    866:                switch(c) {
                    867:                case 'A':
                    868:                        /*
                    869:                         * append to an archive
                    870:                         */
                    871:                        act = APPND;
                    872:                        flg |= AF;
                    873:                        break;
                    874:                case 'B':
                    875:                        /*
                    876:                         * set blocksize to 5120
                    877:                         */
                    878:                        blksz = 5120;
                    879:                        break;
                    880:                case 'C':
                    881:                        /*
                    882:                         * specify blocksize
                    883:                         */
                    884:                        if ((blksz = (int)str_offt(optarg)) <= 0) {
                    885:                                tty_warn(1, "Invalid block size %s", optarg);
                    886:                                tar_usage();
                    887:                        }
                    888:                        break;
                    889: #ifdef notyet
                    890:                case 'E':
                    891:                        arg = optarg;
                    892:                        break;
                    893: #endif
                    894:                case 'H':
                    895:                        /*
                    896:                         * specify an archive format on write
                    897:                         */
                    898:                        tmp.name = optarg;
                    899:                        frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,
                    900:                            sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt);
                    901:                        if (frmt != NULL) {
                    902:                                flg |= XF;
                    903:                                break;
                    904:                        }
                    905:                        tty_warn(1, "Unknown -H format: %s", optarg);
                    906:                        (void)fputs("cpio: Known -H formats are:", stderr);
                    907:                        for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
                    908:                                (void)fprintf(stderr, " %s", fsub[i].name);
                    909:                        (void)fputs("\n\n", stderr);
                    910:                        tar_usage();
                    911:                        break;
                    912:                case 'I':
                    913:                case 'O':
                    914:                        /*
                    915:                         * filename where the archive is stored
                    916:                         */
                    917:                        if ((optarg[0] == '-') && (optarg[1]== '\0')) {
                    918:                                /*
                    919:                                 * treat a - as stdin
                    920:                                 */
                    921:                                arcname = (char *)0;
                    922:                                break;
                    923:                        }
                    924:                        arcname = optarg;
                    925:                        break;
                    926:                case 'L':
                    927:                        /*
                    928:                         * follow symlinks
                    929:                         */
                    930:                        Lflag = 1;
                    931:                        flg |= CLF;
                    932:                        break;
                    933: #ifdef notyet
                    934:                case 'M':
                    935:                        arg = optarg;
                    936:                        break;
                    937:                case 'R':
                    938:                        arg = optarg;
                    939:                        break;
                    940: #endif
                    941:                case 'S':
                    942:                        cpio_swp_head = 1;
                    943:                        break;
                    944: #ifdef notyet
                    945:                case 'V':
                    946:                        break;
                    947: #endif
                    948:                case 'a':
                    949:                        /*
                    950:                         * preserve access time on filesystem nodes we read
                    951:                         */
                    952:                        tflag = 1;
                    953:                        flg |= TF;
                    954:                        break;
                    955: #ifdef notyet
                    956:                case 'b':
                    957:                        break;
                    958: #endif
                    959:                case 'c':
                    960:                        frmt = &fsub[F_SV4CPIO];
                    961:                        break;
                    962:                case 'd':
                    963:                        /*
                    964:                         * pax does this by default ..
                    965:                         */
                    966:                        flg |= RF;
                    967:                        break;
                    968:                case 'f':
                    969:                        /*
                    970:                         * inverse match on patterns
                    971:                         */
                    972:                        cflag = 1;
                    973:                        flg |= CF;
                    974:                        break;
                    975:                case 'i':
                    976:                        /*
                    977:                         * read the archive
                    978:                         */
                    979:                        flg |= RF;
                    980:                        break;
                    981: #ifdef notyet
                    982:                case 'k':
                    983:                        break;
                    984: #endif
                    985:                case 'l':
                    986:                        /*
                    987:                         * try to link src to dest with copy (-rw)
                    988:                         */
                    989:                        lflag = 1;
                    990:                        flg |= LF;
                    991:                        break;
                    992:                case 'm':
                    993:                        /*
                    994:                         * preserve mtime
                    995:                         */
                    996:                        flg |= PF;
                    997:                        pmtime = 1;
                    998:                        break;
                    999:                case 'o':
                   1000:                        /*
                   1001:                         * write an archive
                   1002:                         */
                   1003:                        flg |= WF;
                   1004:                        break;
                   1005:                case 'p':
                   1006:                        /*
                   1007:                         * cpio -p is like pax -rw
                   1008:                         */
                   1009:                        flg |= RF | WF;
                   1010:                        break;
                   1011:                case 'r':
                   1012:                        /*
                   1013:                         * interactive file rename
                   1014:                         */
                   1015:                        iflag = 1;
                   1016:                        flg |= IF;
                   1017:                        break;
                   1018: #ifdef notyet
                   1019:                case 's':
                   1020:                        break;
                   1021: #endif
                   1022:                case 't':
                   1023:                        act = LIST;
                   1024:                        break;
                   1025:                case 'u':
                   1026:                        /*
                   1027:                         * don't ignore those older files
                   1028:                         */
                   1029:                        uflag = 0;
                   1030:                        flg |= UF;
                   1031:                        break;
                   1032:                case 'v':
                   1033:                        /*
                   1034:                         * verbose operation mode
                   1035:                         */
                   1036:                        vflag = 1;
                   1037:                        flg |= VF;
                   1038:                        break;
                   1039:                default:
                   1040:                        cpio_usage();
                   1041:                        break;
                   1042:                }
                   1043:        }
                   1044:
                   1045:        /*
                   1046:         * figure out the operation mode of cpio. check that we have not been
                   1047:         * given a bogus set of flags for the operation mode.
                   1048:         */
                   1049:        if (ISLIST(flg)) {
                   1050:                act = LIST;
                   1051:                bflg = flg & BDLIST;
                   1052:        } else if (ISEXTRACT(flg)) {
                   1053:                act = EXTRACT;
                   1054:                bflg = flg & BDEXTR;
                   1055:        } else if (ISARCHIVE(flg)) {
                   1056:                act = ARCHIVE;
                   1057:                bflg = flg & BDARCH;
                   1058:        } else if (ISAPPND(flg)) {
                   1059:                act = APPND;
                   1060:                bflg = flg & BDARCH;
                   1061:        } else if (ISCOPY(flg)) {
                   1062:                act = COPY;
                   1063:                bflg = flg & BDCOPY;
                   1064:        } else
                   1065:                cpio_usage();
                   1066:        if (bflg) {
                   1067:                cpio_usage();
                   1068:        }
                   1069:
                   1070:        /*
                   1071:         * if we are writing (ARCHIVE) we use the default format if the user
                   1072:         * did not specify a format. when we write during an APPEND, we will
                   1073:         * adopt the format of the existing archive if none was supplied.
                   1074:         */
                   1075:        if (!(flg & XF) && (act == ARCHIVE))
                   1076:                frmt = &(fsub[F_BCPIO]);
                   1077:
                   1078:        /*
                   1079:         * process the args as they are interpreted by the operation mode
                   1080:         */
                   1081:        switch (act) {
                   1082:        case LIST:
                   1083:        case EXTRACT:
                   1084:                for (; optind < argc; optind++)
                   1085:                        if (pat_add(argv[optind]) < 0)
                   1086:                                cpio_usage();
                   1087:                break;
                   1088:        case COPY:
                   1089:                if (optind >= argc) {
                   1090:                        tty_warn(0, "Destination directory was not supplied");
                   1091:                        cpio_usage();
                   1092:                }
                   1093:                --argc;
                   1094:                dirptr = argv[argc];
1.14      mycroft  1095:                /* FALLTHROUGH */
1.10      mrg      1096:        case ARCHIVE:
                   1097:        case APPND:
                   1098:                for (; optind < argc; optind++)
                   1099:                        if (ftree_add(argv[optind]) < 0)
                   1100:                                cpio_usage();
                   1101:                /*
                   1102:                 * no read errors allowed on updates/append operation!
                   1103:                 */
                   1104:                maxflt = 0;
                   1105:                break;
                   1106:        }
1.1       jtc      1107: }
                   1108:
                   1109: /*
                   1110:  * printflg()
                   1111:  *     print out those invalid flag sets found to the user
                   1112:  */
                   1113:
                   1114: #if __STDC__
                   1115: static void
                   1116: printflg(unsigned int flg)
                   1117: #else
                   1118: static void
                   1119: printflg(flg)
                   1120:        unsigned int flg;
                   1121: #endif
                   1122: {
                   1123:        int nxt;
                   1124:        int pos = 0;
                   1125:
                   1126:        (void)fprintf(stderr,"%s: Invalid combination of options:", argv0);
1.8       christos 1127:        while ((nxt = ffs(flg)) != 0) {
1.1       jtc      1128:                flg = flg >> nxt;
                   1129:                pos += nxt;
                   1130:                (void)fprintf(stderr, " -%c", flgch[pos-1]);
                   1131:        }
                   1132:        (void)putc('\n', stderr);
                   1133: }
                   1134:
                   1135: /*
                   1136:  * c_frmt()
                   1137:  *     comparison routine used by bsearch to find the format specified
                   1138:  *     by the user
                   1139:  */
                   1140:
                   1141: #if __STDC__
                   1142: static int
                   1143: c_frmt(const void *a, const void *b)
                   1144: #else
                   1145: static int
                   1146: c_frmt(a, b)
                   1147:         void *a;
                   1148:         void *b;
                   1149: #endif
                   1150: {
                   1151:         return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name));
                   1152: }
                   1153:
                   1154: /*
                   1155:  * opt_next()
                   1156:  *     called by format specific options routines to get each format specific
                   1157:  *     flag and value specified with -o
                   1158:  * Return:
                   1159:  *     pointer to next OPLIST entry or NULL (end of list).
                   1160:  */
                   1161:
                   1162: #if __STDC__
                   1163: OPLIST *
                   1164: opt_next(void)
                   1165: #else
                   1166: OPLIST *
                   1167: opt_next()
                   1168: #endif
                   1169: {
                   1170:        OPLIST *opt;
                   1171:
                   1172:        if ((opt = ophead) != NULL)
                   1173:                ophead = ophead->fow;
                   1174:        return(opt);
                   1175: }
                   1176:
                   1177: /*
                   1178:  * bad_opt()
                   1179:  *     generic routine used to complain about a format specific options
                   1180:  *     when the format does not support options.
                   1181:  */
                   1182:
                   1183: #if __STDC__
                   1184: int
                   1185: bad_opt(void)
                   1186: #else
                   1187: int
                   1188: bad_opt()
                   1189: #endif
                   1190: {
1.7       tls      1191:        OPLIST *opt;
1.1       jtc      1192:
                   1193:        if (ophead == NULL)
                   1194:                return(0);
                   1195:        /*
                   1196:         * print all we were given
                   1197:         */
1.8       christos 1198:        tty_warn(1,"These format options are not supported");
1.1       jtc      1199:        while ((opt = opt_next()) != NULL)
                   1200:                (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
                   1201:        pax_usage();
                   1202:        return(0);
                   1203: }
                   1204:
                   1205: /*
                   1206:  * opt_add()
                   1207:  *     breaks the value supplied to -o into a option name and value. options
                   1208:  *     are given to -o in the form -o name-value,name=value
                   1209:  *     mulltiple -o may be specified.
                   1210:  * Return:
                   1211:  *     0 if format in name=value format, -1 if -o is passed junk
                   1212:  */
                   1213:
                   1214: #if __STDC__
                   1215: int
1.18      tv       1216: opt_add(const char *str)
1.1       jtc      1217: #else
                   1218: int
                   1219: opt_add(str)
1.18      tv       1220:        const char *str;
1.1       jtc      1221: #endif
                   1222: {
1.7       tls      1223:        OPLIST *opt;
                   1224:        char *frpt;
                   1225:        char *pt;
                   1226:        char *endpt;
1.1       jtc      1227:
                   1228:        if ((str == NULL) || (*str == '\0')) {
1.8       christos 1229:                tty_warn(0, "Invalid option name");
1.1       jtc      1230:                return(-1);
                   1231:        }
1.18      tv       1232:        frpt = endpt = strdup(str);
1.1       jtc      1233:
                   1234:        /*
                   1235:         * break into name and values pieces and stuff each one into a
                   1236:         * OPLIST structure. When we know the format, the format specific
                   1237:         * option function will go through this list
                   1238:         */
                   1239:        while ((frpt != NULL) && (*frpt != '\0')) {
                   1240:                if ((endpt = strchr(frpt, ',')) != NULL)
                   1241:                        *endpt = '\0';
                   1242:                if ((pt = strchr(frpt, '=')) == NULL) {
1.8       christos 1243:                        tty_warn(0, "Invalid options format");
1.1       jtc      1244:                        return(-1);
                   1245:                }
                   1246:                if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {
1.8       christos 1247:                        tty_warn(0, "Unable to allocate space for option list");
1.1       jtc      1248:                        return(-1);
                   1249:                }
                   1250:                *pt++ = '\0';
                   1251:                opt->name = frpt;
                   1252:                opt->value = pt;
                   1253:                opt->fow = NULL;
                   1254:                if (endpt != NULL)
                   1255:                        frpt = endpt + 1;
                   1256:                else
                   1257:                        frpt = NULL;
                   1258:                if (ophead == NULL) {
                   1259:                        optail = ophead = opt;
                   1260:                        continue;
                   1261:                }
                   1262:                optail->fow = opt;
                   1263:                optail = opt;
                   1264:        }
                   1265:        return(0);
                   1266: }
                   1267:
                   1268: /*
                   1269:  * str_offt()
                   1270:  *     Convert an expression of the following forms to an off_t > 0.
                   1271:  *     1) A positive decimal number.
                   1272:  *     2) A positive decimal number followed by a b (mult by 512).
                   1273:  *     3) A positive decimal number followed by a k (mult by 1024).
                   1274:  *     4) A positive decimal number followed by a m (mult by 512).
                   1275:  *     5) A positive decimal number followed by a w (mult by sizeof int)
                   1276:  *     6) Two or more positive decimal numbers (with/without k,b or w).
                   1277:  *        seperated by x (also * for backwards compatibility), specifying
                   1278:  *        the product of the indicated values.
                   1279:  * Return:
                   1280:  *     0 for an error, a positive value o.w.
                   1281:  */
                   1282:
                   1283: #if __STDC__
                   1284: static off_t
                   1285: str_offt(char *val)
                   1286: #else
                   1287: static off_t
                   1288: str_offt(val)
                   1289:        char *val;
                   1290: #endif
                   1291: {
                   1292:        char *expr;
                   1293:        off_t num, t;
                   1294:
                   1295: #      ifdef NET2_STAT
                   1296:        num = strtol(val, &expr, 0);
                   1297:        if ((num == LONG_MAX) || (num <= 0) || (expr == val))
                   1298: #      else
                   1299:        num = strtoq(val, &expr, 0);
                   1300:        if ((num == QUAD_MAX) || (num <= 0) || (expr == val))
                   1301: #      endif
                   1302:                return(0);
                   1303:
                   1304:        switch(*expr) {
                   1305:        case 'b':
                   1306:                t = num;
                   1307:                num *= 512;
                   1308:                if (t > num)
                   1309:                        return(0);
                   1310:                ++expr;
                   1311:                break;
                   1312:        case 'k':
                   1313:                t = num;
                   1314:                num *= 1024;
                   1315:                if (t > num)
                   1316:                        return(0);
                   1317:                ++expr;
                   1318:                break;
                   1319:        case 'm':
                   1320:                t = num;
                   1321:                num *= 1048576;
                   1322:                if (t > num)
                   1323:                        return(0);
                   1324:                ++expr;
                   1325:                break;
                   1326:        case 'w':
                   1327:                t = num;
                   1328:                num *= sizeof(int);
                   1329:                if (t > num)
                   1330:                        return(0);
                   1331:                ++expr;
                   1332:                break;
                   1333:        }
                   1334:
                   1335:        switch(*expr) {
                   1336:                case '\0':
                   1337:                        break;
                   1338:                case '*':
                   1339:                case 'x':
                   1340:                        t = num;
                   1341:                        num *= str_offt(expr + 1);
                   1342:                        if (t > num)
                   1343:                                return(0);
                   1344:                        break;
                   1345:                default:
                   1346:                        return(0);
                   1347:        }
                   1348:        return(num);
                   1349: }
                   1350:
                   1351: /*
                   1352:  * no_op()
                   1353:  *     for those option functions where the archive format has nothing to do.
                   1354:  * Return:
                   1355:  *     0
                   1356:  */
                   1357:
                   1358: #if __STDC__
                   1359: static int
                   1360: no_op(void)
                   1361: #else
                   1362: static int
                   1363: no_op()
                   1364: #endif
                   1365: {
                   1366:        return(0);
                   1367: }
                   1368:
                   1369: /*
                   1370:  * pax_usage()
                   1371:  *     print the usage summary to the user
                   1372:  */
                   1373:
                   1374: #if __STDC__
                   1375: void
                   1376: pax_usage(void)
                   1377: #else
                   1378: void
                   1379: pax_usage()
                   1380: #endif
                   1381: {
1.19      mycroft  1382:        (void)fputs("usage: pax [-cdnvz] [-E limit] [-f archive] ", stderr);
1.1       jtc      1383:        (void)fputs("[-s replstr] ... [-U user] ...", stderr);
                   1384:        (void)fputs("\n           [-G group] ... ", stderr);
                   1385:        (void)fputs("[-T [from_date][,to_date]] ... ", stderr);
                   1386:        (void)fputs("[pattern ...]\n", stderr);
1.19      mycroft  1387:        (void)fputs("       pax -r [-cdiknuvzDYZ] [-E limit] ", stderr);
1.1       jtc      1388:        (void)fputs("[-f archive] [-o options] ... \n", stderr);
                   1389:        (void)fputs("           [-p string] ... [-s replstr] ... ", stderr);
                   1390:        (void)fputs("[-U user] ... [-G group] ...\n           ", stderr);
                   1391:        (void)fputs("[-T [from_date][,to_date]] ... ", stderr);
                   1392:        (void)fputs(" [pattern ...]\n", stderr);
1.19      mycroft  1393:        (void)fputs("       pax -w [-dituvzHLPX] [-b blocksize] ", stderr);
                   1394:        (void)fputs("[[-a] [-f archive]] [-x format] \n", stderr);
                   1395:        (void)fputs("           [-B bytes] [-o options] ... ", stderr);
                   1396:        (void)fputs("[-s replstr] ... [-U user] ...", stderr);
1.1       jtc      1397:        (void)fputs("\n           [-G group] ... ", stderr);
                   1398:        (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr);
                   1399:        (void)fputs("[file ...]\n", stderr);
1.19      mycroft  1400:        (void)fputs("       pax -r -w [-diklntuvzDHLPXYZ] ", stderr);
1.1       jtc      1401:        (void)fputs("[-p string] ... [-s replstr] ...", stderr);
                   1402:        (void)fputs("\n           [-U user] ... [-G group] ... ", stderr);
                   1403:        (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr);
                   1404:        (void)fputs("\n           [file ...] directory\n", stderr);
                   1405:        exit(1);
1.12      mycroft  1406:        /* NOTREACHED */
1.1       jtc      1407: }
                   1408:
                   1409: /*
                   1410:  * tar_usage()
                   1411:  *     print the usage summary to the user
                   1412:  */
                   1413:
                   1414: #if __STDC__
                   1415: void
                   1416: tar_usage(void)
                   1417: #else
                   1418: void
                   1419: tar_usage()
                   1420: #endif
                   1421: {
1.22    ! tron     1422:        (void)fputs("usage: tar -{txru}[cevfbhlmopwBLPX014578] [tapefile] ",
1.1       jtc      1423:                 stderr);
1.15      mrg      1424:        (void)fputs("[blocksize] [exclude-file] file1 file2...\n", stderr);
1.1       jtc      1425:        exit(1);
1.12      mycroft  1426:        /* NOTREACHED */
1.1       jtc      1427: }
                   1428:
                   1429: /*
                   1430:  * cpio_usage()
                   1431:  *     print the usage summary to the user
                   1432:  */
                   1433:
                   1434: #if __STDC__
                   1435: void
                   1436: cpio_usage(void)
                   1437: #else
                   1438: void
                   1439: cpio_usage()
                   1440: #endif
                   1441: {
1.10      mrg      1442:
                   1443: #if 1
                   1444:        (void)fputs(
                   1445:            "usage: cpio -i [-BcdfmrStuv] [ -C blksize ] [ -H header ]\n",
                   1446:            stderr);
                   1447:        (void)fputs("  [ -I file ] [ pattern ... ]\n", stderr);
                   1448:        (void)fputs("usage: cpio -o [-aABcLv] [ -C bufsize ] [ -H header ]\n",
                   1449:            stderr);
                   1450:        (void)fputs("  [ -O file ]\n", stderr);
                   1451:        (void)fputs("usage: cpio -p [ adlLmuv ] directory\n", stderr);
                   1452: #else
                   1453:        /* no E, M, R, V, b, k or s */
                   1454:        (void)fputs("usage: cpio -i [-bBcdfkmrsStuvV] [ -C bufsize ]\n", stderr);
                   1455:        (void)fputs("  [ -E file ] [ -H header ] [ -I file [ -M message ] ]\n",
                   1456:            stderr);
                   1457:        (void)fputs("  [ -R id ] [ pattern ... ]\n", stderr);
                   1458:        (void)fputs("usage: cpio -o [-aABcLvV] [ -C bufsize ] [ -H header ]\n",
                   1459:            stderr);
                   1460:        (void)fputs("  [ -O file [ -M message ] ]\n", stderr);
                   1461:        (void)fputs("usage: cpio -p [ adlLmuvV ] [ -R id ] directory\n", stderr);
                   1462: #endif
1.1       jtc      1463:        exit(1);
1.12      mycroft  1464:        /* NOTREACHED */
1.1       jtc      1465: }

CVSweb <webmaster@jp.NetBSD.org>