options.c revision 76286
1226031Sstas/*- 2226031Sstas * Copyright (c) 1992 Keith Muller. 3226031Sstas * Copyright (c) 1992, 1993 4226031Sstas * The Regents of the University of California. All rights reserved. 5226031Sstas * 6226031Sstas * This code is derived from software contributed to Berkeley by 7226031Sstas * Keith Muller of the University of California, San Diego. 8226031Sstas * 9226031Sstas * Redistribution and use in source and binary forms, with or without 10226031Sstas * modification, are permitted provided that the following conditions 11226031Sstas * are met: 12226031Sstas * 1. Redistributions of source code must retain the above copyright 13226031Sstas * notice, this list of conditions and the following disclaimer. 14226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 15226031Sstas * notice, this list of conditions and the following disclaimer in the 16226031Sstas * documentation and/or other materials provided with the distribution. 17226031Sstas * 3. All advertising materials mentioning features or use of this software 18226031Sstas * must display the following acknowledgement: 19226031Sstas * This product includes software developed by the University of 20226031Sstas * California, Berkeley and its contributors. 21226031Sstas * 4. Neither the name of the University nor the names of its contributors 22226031Sstas * may be used to endorse or promote products derived from this software 23226031Sstas * without specific prior written permission. 24226031Sstas * 25226031Sstas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35226031Sstas * SUCH DAMAGE. 36226031Sstas */ 37226031Sstas 38226031Sstas#ifndef lint 39226031Sstas#if 0 40226031Sstasstatic char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; 41226031Sstas#endif 42226031Sstasstatic const char rcsid[] = 43226031Sstas "$FreeBSD: head/bin/pax/options.c 76286 2001-05-05 01:10:13Z kris $"; 44226031Sstas#endif /* not lint */ 45226031Sstas 46226031Sstas#include <sys/types.h> 47226031Sstas#include <sys/stat.h> 48226031Sstas#include <sys/mtio.h> 49226031Sstas#include <stdio.h> 50226031Sstas#include <string.h> 51226031Sstas#include <unistd.h> 52226031Sstas#include <stdlib.h> 53226031Sstas#include <limits.h> 54226031Sstas#include "pax.h" 55226031Sstas#include "options.h" 56226031Sstas#include "cpio.h" 57226031Sstas#include "tar.h" 58226031Sstas#include "extern.h" 59226031Sstas 60226031Sstas/* 61226031Sstas * Routines which handle command line options 62226031Sstas */ 63226031Sstas 64226031Sstasstatic char flgch[] = FLGCH; /* list of all possible flags */ 65226031Sstasstatic OPLIST *ophead = NULL; /* head for format specific options -x */ 66226031Sstasstatic OPLIST *optail = NULL; /* option tail */ 67226031Sstas 68226031Sstasstatic int no_op __P((void)); 69226031Sstasstatic void printflg __P((unsigned int)); 70226031Sstasstatic int c_frmt __P((const void *, const void *)); 71226031Sstasstatic off_t str_offt __P((char *)); 72226031Sstasstatic void pax_options __P((register int, register char **)); 73226031Sstasstatic void pax_usage __P((void)); 74226031Sstasstatic void tar_options __P((register int, register char **)); 75226031Sstasstatic void tar_usage __P((void)); 76226031Sstas#ifdef notdef 77226031Sstasstatic void cpio_options __P((register int, register char **)); 78226031Sstasstatic void cpio_usage __P((void)); 79226031Sstas#endif 80226031Sstas 81226031Sstas#define GZIP_CMD "gzip" /* command to run as gzip */ 82226031Sstas#define COMPRESS_CMD "compress" /* command to run as compress */ 83226031Sstas 84226031Sstas/* 85226031Sstas * Format specific routine table - MUST BE IN SORTED ORDER BY NAME 86226031Sstas * (see pax.h for description of each function) 87226031Sstas * 88226031Sstas * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read, 89226031Sstas * read, end_read, st_write, write, end_write, trail, 90226031Sstas * rd_data, wr_data, options 91226031Sstas */ 92226031Sstas 93226031SstasFSUB fsub[] = { 94226031Sstas/* 0: OLD BINARY CPIO */ 95226031Sstas {"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd, 96226031Sstas bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail, 97226031Sstas rd_wrfile, wr_rdfile, bad_opt}, 98226031Sstas 99226031Sstas/* 1: OLD OCTAL CHARACTER CPIO */ 100226031Sstas {"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd, 101226031Sstas cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail, 102226031Sstas rd_wrfile, wr_rdfile, bad_opt}, 103226031Sstas 104226031Sstas/* 2: SVR4 HEX CPIO */ 105226031Sstas {"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd, 106226031Sstas vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail, 107226031Sstas rd_wrfile, wr_rdfile, bad_opt}, 108226031Sstas 109226031Sstas/* 3: SVR4 HEX CPIO WITH CRC */ 110226031Sstas {"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd, 111226031Sstas vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail, 112226031Sstas rd_wrfile, wr_rdfile, bad_opt}, 113226031Sstas 114226031Sstas/* 4: OLD TAR */ 115226031Sstas {"tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op, 116226031Sstas tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail, 117226031Sstas rd_wrfile, wr_rdfile, tar_opt}, 118226031Sstas 119226031Sstas/* 5: POSIX USTAR */ 120226031Sstas {"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd, 121226031Sstas ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail, 122226031Sstas rd_wrfile, wr_rdfile, bad_opt}, 123226031Sstas}; 124226031Sstas#define F_TAR 4 /* format when called as tar */ 125226031Sstas#define DEFLT 5 /* default write format from list above */ 126226031Sstas 127226031Sstas/* 128226031Sstas * ford is the archive search order used by get_arc() to determine what kind 129226031Sstas * of archive we are dealing with. This helps to properly id archive formats 130226031Sstas * some formats may be subsets of others.... 131226031Sstas */ 132226031Sstasint ford[] = {5, 4, 3, 2, 1, 0, -1 }; 133226031Sstas 134226031Sstas/* 135226031Sstas * options() 136226031Sstas * figure out if we are pax, tar or cpio. Call the appropriate options 137226031Sstas * parser 138226031Sstas */ 139226031Sstas 140226031Sstas#ifdef __STDC__ 141226031Sstasvoid 142226031Sstasoptions(register int argc, register char **argv) 143226031Sstas#else 144226031Sstasvoid 145226031Sstasoptions(argc, argv) 146226031Sstas register int argc; 147226031Sstas register char **argv; 148226031Sstas#endif 149226031Sstas{ 150226031Sstas 151226031Sstas /* 152226031Sstas * Are we acting like pax, tar or cpio (based on argv[0]) 153226031Sstas */ 154226031Sstas if ((argv0 = strrchr(argv[0], '/')) != NULL) 155226031Sstas argv0++; 156226031Sstas else 157226031Sstas argv0 = argv[0]; 158226031Sstas 159226031Sstas if (strcmp(NM_TAR, argv0) == 0) 160226031Sstas return(tar_options(argc, argv)); 161226031Sstas# ifdef notdef 162226031Sstas else if (strcmp(NM_CPIO, argv0) == 0) 163226031Sstas return(cpio_options(argc, argv)); 164226031Sstas# endif 165226031Sstas /* 166226031Sstas * assume pax as the default 167226031Sstas */ 168226031Sstas argv0 = NM_PAX; 169226031Sstas return(pax_options(argc, argv)); 170226031Sstas} 171226031Sstas 172226031Sstas/* 173226031Sstas * pax_options() 174226031Sstas * look at the user specified flags. set globals as required and check if 175226031Sstas * the user specified a legal set of flags. If not, complain and exit 176226031Sstas */ 177 178#ifdef __STDC__ 179static void 180pax_options(register int argc, register char **argv) 181#else 182static void 183pax_options(argc, argv) 184 register int argc; 185 register char **argv; 186#endif 187{ 188 register int c; 189 register int i; 190 unsigned int flg = 0; 191 unsigned int bflg = 0; 192 register char *pt; 193 FSUB tmp; 194 195 /* 196 * process option flags 197 */ 198 while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ")) 199 != -1) { 200 switch (c) { 201 case 'a': 202 /* 203 * append 204 */ 205 flg |= AF; 206 break; 207 case 'b': 208 /* 209 * specify blocksize 210 */ 211 flg |= BF; 212 if ((wrblksz = (int)str_offt(optarg)) <= 0) { 213 paxwarn(1, "Invalid block size %s", optarg); 214 pax_usage(); 215 } 216 break; 217 case 'c': 218 /* 219 * inverse match on patterns 220 */ 221 cflag = 1; 222 flg |= CF; 223 break; 224 case 'd': 225 /* 226 * match only dir on extract, not the subtree at dir 227 */ 228 dflag = 1; 229 flg |= DF; 230 break; 231 case 'f': 232 /* 233 * filename where the archive is stored 234 */ 235 arcname = optarg; 236 flg |= FF; 237 break; 238 case 'i': 239 /* 240 * interactive file rename 241 */ 242 iflag = 1; 243 flg |= IF; 244 break; 245 case 'k': 246 /* 247 * do not clobber files that exist 248 */ 249 kflag = 1; 250 flg |= KF; 251 break; 252 case 'l': 253 /* 254 * try to link src to dest with copy (-rw) 255 */ 256 lflag = 1; 257 flg |= LF; 258 break; 259 case 'n': 260 /* 261 * select first match for a pattern only 262 */ 263 nflag = 1; 264 flg |= NF; 265 break; 266 case 'o': 267 /* 268 * pass format specific options 269 */ 270 flg |= OF; 271 if (opt_add(optarg) < 0) 272 pax_usage(); 273 break; 274 case 'p': 275 /* 276 * specify file characteristic options 277 */ 278 for (pt = optarg; *pt != '\0'; ++pt) { 279 switch(*pt) { 280 case 'a': 281 /* 282 * do not preserve access time 283 */ 284 patime = 0; 285 break; 286 case 'e': 287 /* 288 * preserve user id, group id, file 289 * mode, access/modification times 290 */ 291 pids = 1; 292 pmode = 1; 293 patime = 1; 294 pmtime = 1; 295 break; 296 case 'm': 297 /* 298 * do not preserve modification time 299 */ 300 pmtime = 0; 301 break; 302 case 'o': 303 /* 304 * preserve uid/gid 305 */ 306 pids = 1; 307 break; 308 case 'p': 309 /* 310 * preserver file mode bits 311 */ 312 pmode = 1; 313 break; 314 default: 315 paxwarn(1, "Invalid -p string: %c", *pt); 316 pax_usage(); 317 break; 318 } 319 } 320 flg |= PF; 321 break; 322 case 'r': 323 /* 324 * read the archive 325 */ 326 flg |= RF; 327 break; 328 case 's': 329 /* 330 * file name substitution name pattern 331 */ 332 if (rep_add(optarg) < 0) { 333 pax_usage(); 334 break; 335 } 336 flg |= SF; 337 break; 338 case 't': 339 /* 340 * preserve access time on filesystem nodes we read 341 */ 342 tflag = 1; 343 flg |= TF; 344 break; 345 case 'u': 346 /* 347 * ignore those older files 348 */ 349 uflag = 1; 350 flg |= UF; 351 break; 352 case 'v': 353 /* 354 * verbose operation mode 355 */ 356 vflag = 1; 357 flg |= VF; 358 break; 359 case 'w': 360 /* 361 * write an archive 362 */ 363 flg |= WF; 364 break; 365 case 'x': 366 /* 367 * specify an archive format on write 368 */ 369 tmp.name = optarg; 370 if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 371 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt))) { 372 flg |= XF; 373 break; 374 } 375 paxwarn(1, "Unknown -x format: %s", optarg); 376 (void)fputs("pax: Known -x formats are:", stderr); 377 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 378 (void)fprintf(stderr, " %s", fsub[i].name); 379 (void)fputs("\n\n", stderr); 380 pax_usage(); 381 break; 382 case 'z': 383 /* 384 * use gzip. Non standard option. 385 */ 386 gzip_program = GZIP_CMD; 387 break; 388 case 'B': 389 /* 390 * non-standard option on number of bytes written on a 391 * single archive volume. 392 */ 393 if ((wrlimit = str_offt(optarg)) <= 0) { 394 paxwarn(1, "Invalid write limit %s", optarg); 395 pax_usage(); 396 } 397 if (wrlimit % BLKMULT) { 398 paxwarn(1, "Write limit is not a %d byte multiple", 399 BLKMULT); 400 pax_usage(); 401 } 402 flg |= CBF; 403 break; 404 case 'D': 405 /* 406 * On extraction check file inode change time before the 407 * modification of the file name. Non standard option. 408 */ 409 Dflag = 1; 410 flg |= CDF; 411 break; 412 case 'E': 413 /* 414 * non-standard limit on read faults 415 * 0 indicates stop after first error, values 416 * indicate a limit, "NONE" try forever 417 */ 418 flg |= CEF; 419 if (strcmp(NONE, optarg) == 0) 420 maxflt = -1; 421 else if ((maxflt = atoi(optarg)) < 0) { 422 paxwarn(1, "Error count value must be positive"); 423 pax_usage(); 424 } 425 break; 426 case 'G': 427 /* 428 * non-standard option for selecting files within an 429 * archive by group (gid or name) 430 */ 431 if (grp_add(optarg) < 0) { 432 pax_usage(); 433 break; 434 } 435 flg |= CGF; 436 break; 437 case 'H': 438 /* 439 * follow command line symlinks only 440 */ 441 Hflag = 1; 442 flg |= CHF; 443 break; 444 case 'L': 445 /* 446 * follow symlinks 447 */ 448 Lflag = 1; 449 flg |= CLF; 450 break; 451 case 'P': 452 /* 453 * do NOT follow symlinks (default) 454 */ 455 Lflag = 0; 456 flg |= CPF; 457 break; 458 case 'T': 459 /* 460 * non-standard option for selecting files within an 461 * archive by modification time range (lower,upper) 462 */ 463 if (trng_add(optarg) < 0) { 464 pax_usage(); 465 break; 466 } 467 flg |= CTF; 468 break; 469 case 'U': 470 /* 471 * non-standard option for selecting files within an 472 * archive by user (uid or name) 473 */ 474 if (usr_add(optarg) < 0) { 475 pax_usage(); 476 break; 477 } 478 flg |= CUF; 479 break; 480 case 'X': 481 /* 482 * do not pass over mount points in the file system 483 */ 484 Xflag = 1; 485 flg |= CXF; 486 break; 487 case 'Y': 488 /* 489 * On extraction check file inode change time after the 490 * modification of the file name. Non standard option. 491 */ 492 Yflag = 1; 493 flg |= CYF; 494 break; 495 case 'Z': 496 /* 497 * On extraction check modification time after the 498 * modification of the file name. Non standard option. 499 */ 500 Zflag = 1; 501 flg |= CZF; 502 break; 503 case '?': 504 default: 505 pax_usage(); 506 break; 507 } 508 } 509 510 /* 511 * figure out the operation mode of pax read,write,extract,copy,append 512 * or list. check that we have not been given a bogus set of flags 513 * for the operation mode. 514 */ 515 if (ISLIST(flg)) { 516 act = LIST; 517 bflg = flg & BDLIST; 518 } else if (ISEXTRACT(flg)) { 519 act = EXTRACT; 520 bflg = flg & BDEXTR; 521 } else if (ISARCHIVE(flg)) { 522 act = ARCHIVE; 523 bflg = flg & BDARCH; 524 } else if (ISAPPND(flg)) { 525 act = APPND; 526 bflg = flg & BDARCH; 527 } else if (ISCOPY(flg)) { 528 act = COPY; 529 bflg = flg & BDCOPY; 530 } else 531 pax_usage(); 532 if (bflg) { 533 printflg(flg); 534 pax_usage(); 535 } 536 537 /* 538 * if we are writing (ARCHIVE) we use the default format if the user 539 * did not specify a format. when we write during an APPEND, we will 540 * adopt the format of the existing archive if none was supplied. 541 */ 542 if (!(flg & XF) && (act == ARCHIVE)) 543 frmt = &(fsub[DEFLT]); 544 545 /* 546 * process the args as they are interpreted by the operation mode 547 */ 548 switch (act) { 549 case LIST: 550 case EXTRACT: 551 for (; optind < argc; optind++) 552 if (pat_add(argv[optind]) < 0) 553 pax_usage(); 554 break; 555 case COPY: 556 if (optind >= argc) { 557 paxwarn(0, "Destination directory was not supplied"); 558 pax_usage(); 559 } 560 --argc; 561 dirptr = argv[argc]; 562 /* FALL THROUGH */ 563 case ARCHIVE: 564 case APPND: 565 for (; optind < argc; optind++) 566 if (ftree_add(argv[optind]) < 0) 567 pax_usage(); 568 /* 569 * no read errors allowed on updates/append operation! 570 */ 571 maxflt = 0; 572 break; 573 } 574} 575 576 577/* 578 * tar_options() 579 * look at the user specified flags. set globals as required and check if 580 * the user specified a legal set of flags. If not, complain and exit 581 */ 582 583#ifdef __STDC__ 584static void 585tar_options(register int argc, register char **argv) 586#else 587static void 588tar_options(argc, argv) 589 register int argc; 590 register char **argv; 591#endif 592{ 593 register char *cp; 594 int fstdin = 0; 595 596 if (argc < 2) 597 tar_usage(); 598 /* 599 * process option flags 600 */ 601 ++argv; 602 for (cp = *argv++; *cp != '\0'; ++cp) { 603 switch (*cp) { 604 case '-': 605 /* 606 * skip over - 607 */ 608 break; 609 case 'b': 610 /* 611 * specify blocksize 612 */ 613 if (*argv == NULL) { 614 paxwarn(1,"blocksize must be specified with 'b'"); 615 tar_usage(); 616 } 617 if ((wrblksz = (int)str_offt(*argv)) <= 0) { 618 paxwarn(1, "Invalid block size %s", *argv); 619 tar_usage(); 620 } 621 ++argv; 622 break; 623 case 'c': 624 /* 625 * create an archive 626 */ 627 act = ARCHIVE; 628 break; 629 case 'e': 630 /* 631 * stop after first error 632 */ 633 maxflt = 0; 634 break; 635 case 'f': 636 /* 637 * filename where the archive is stored 638 */ 639 if (*argv == NULL) { 640 paxwarn(1, "filename must be specified with 'f'"); 641 tar_usage(); 642 } 643 if ((argv[0][0] == '-') && (argv[0][1]== '\0')) { 644 /* 645 * treat a - as stdin 646 */ 647 ++argv; 648 ++fstdin; 649 arcname = (char *)0; 650 break; 651 } 652 fstdin = 0; 653 arcname = *argv++; 654 break; 655 case 'm': 656 /* 657 * do not preserve modification time 658 */ 659 pmtime = 0; 660 break; 661 case 'o': 662 if (opt_add("write_opt=nodir") < 0) 663 tar_usage(); 664 break; 665 case 'p': 666 /* 667 * preserve user id, group id, file 668 * mode, access/modification times 669 */ 670 pids = 1; 671 pmode = 1; 672 patime = 1; 673 pmtime = 1; 674 break; 675 case 'r': 676 case 'u': 677 /* 678 * append to the archive 679 */ 680 act = APPND; 681 break; 682 case 't': 683 /* 684 * list contents of the tape 685 */ 686 act = LIST; 687 break; 688 case 'v': 689 /* 690 * verbose operation mode 691 */ 692 vflag = 1; 693 break; 694 case 'w': 695 /* 696 * interactive file rename 697 */ 698 iflag = 1; 699 break; 700 case 'x': 701 /* 702 * write an archive 703 */ 704 act = EXTRACT; 705 break; 706 case 'z': 707 /* 708 * use gzip. Non standard option. 709 */ 710 gzip_program = GZIP_CMD; 711 break; 712 case 'B': 713 /* 714 * Nothing to do here, this is pax default 715 */ 716 break; 717 case 'H': 718 /* 719 * follow command line symlinks only 720 */ 721 Hflag = 1; 722 break; 723 case 'L': 724 /* 725 * follow symlinks 726 */ 727 Lflag = 1; 728 break; 729 case 'P': 730 /* 731 * do not follow symlinks 732 */ 733 Lflag = 0; 734 break; 735 case 'X': 736 /* 737 * do not pass over mount points in the file system 738 */ 739 Xflag = 1; 740 break; 741 case 'Z': 742 /* 743 * use compress. 744 */ 745 gzip_program = COMPRESS_CMD; 746 break; 747 case '0': 748 arcname = DEV_0; 749 break; 750 case '1': 751 arcname = DEV_1; 752 break; 753 case '4': 754 arcname = DEV_4; 755 break; 756 case '5': 757 arcname = DEV_5; 758 break; 759 case '7': 760 arcname = DEV_7; 761 break; 762 case '8': 763 arcname = DEV_8; 764 break; 765 default: 766 tar_usage(); 767 break; 768 } 769 } 770 771 /* 772 * if we are writing (ARCHIVE) specify tar, otherwise run like pax 773 */ 774 if (act == ARCHIVE) 775 frmt = &(fsub[F_TAR]); 776 777 /* 778 * process the args as they are interpreted by the operation mode 779 */ 780 switch (act) { 781 case LIST: 782 case EXTRACT: 783 default: 784 while (*argv != NULL) 785 if (pat_add(*argv++) < 0) 786 tar_usage(); 787 break; 788 case ARCHIVE: 789 case APPND: 790 while (*argv != NULL) 791 if (ftree_add(*argv++) < 0) 792 tar_usage(); 793 /* 794 * no read errors allowed on updates/append operation! 795 */ 796 maxflt = 0; 797 break; 798 } 799 if (!fstdin && ((arcname == NULL) || (*arcname == '\0'))) { 800 arcname = getenv("TAPE"); 801 if ((arcname == NULL) || (*arcname == '\0')) 802 arcname = DEV_8; 803 } 804} 805 806#ifdef notdef 807/* 808 * cpio_options() 809 * look at the user specified flags. set globals as required and check if 810 * the user specified a legal set of flags. If not, complain and exit 811 */ 812 813#ifdef __STDC__ 814static void 815cpio_options(register int argc, register char **argv) 816#else 817static void 818cpio_options(argc, argv) 819 register int argc; 820 register char **argv; 821#endif 822{ 823} 824#endif 825 826/* 827 * printflg() 828 * print out those invalid flag sets found to the user 829 */ 830 831#ifdef __STDC__ 832static void 833printflg(unsigned int flg) 834#else 835static void 836printflg(flg) 837 unsigned int flg; 838#endif 839{ 840 int nxt; 841 int pos = 0; 842 843 (void)fprintf(stderr,"%s: Invalid combination of options:", argv0); 844 while ((nxt = ffs(flg))) { 845 flg = flg >> nxt; 846 pos += nxt; 847 (void)fprintf(stderr, " -%c", flgch[pos-1]); 848 } 849 (void)putc('\n', stderr); 850} 851 852/* 853 * c_frmt() 854 * comparison routine used by bsearch to find the format specified 855 * by the user 856 */ 857 858#ifdef __STDC__ 859static int 860c_frmt(const void *a, const void *b) 861#else 862static int 863c_frmt(a, b) 864 void *a; 865 void *b; 866#endif 867{ 868 return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); 869} 870 871/* 872 * opt_next() 873 * called by format specific options routines to get each format specific 874 * flag and value specified with -o 875 * Return: 876 * pointer to next OPLIST entry or NULL (end of list). 877 */ 878 879#ifdef __STDC__ 880OPLIST * 881opt_next(void) 882#else 883OPLIST * 884opt_next() 885#endif 886{ 887 OPLIST *opt; 888 889 if ((opt = ophead) != NULL) 890 ophead = ophead->fow; 891 return(opt); 892} 893 894/* 895 * bad_opt() 896 * generic routine used to complain about a format specific options 897 * when the format does not support options. 898 */ 899 900#ifdef __STDC__ 901int 902bad_opt(void) 903#else 904int 905bad_opt() 906#endif 907{ 908 register OPLIST *opt; 909 910 if (ophead == NULL) 911 return(0); 912 /* 913 * print all we were given 914 */ 915 paxwarn(1,"These format options are not supported"); 916 while ((opt = opt_next()) != NULL) 917 (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value); 918 pax_usage(); 919 return(0); 920} 921 922/* 923 * opt_add() 924 * breaks the value supplied to -o into a option name and value. options 925 * are given to -o in the form -o name-value,name=value 926 * multiple -o may be specified. 927 * Return: 928 * 0 if format in name=value format, -1 if -o is passed junk 929 */ 930 931#ifdef __STDC__ 932int 933opt_add(register char *str) 934#else 935int 936opt_add(str) 937 register char *str; 938#endif 939{ 940 register OPLIST *opt; 941 register char *frpt; 942 register char *pt; 943 register char *endpt; 944 945 if ((str == NULL) || (*str == '\0')) { 946 paxwarn(0, "Invalid option name"); 947 return(-1); 948 } 949 frpt = endpt = str; 950 951 /* 952 * break into name and values pieces and stuff each one into a 953 * OPLIST structure. When we know the format, the format specific 954 * option function will go through this list 955 */ 956 while ((frpt != NULL) && (*frpt != '\0')) { 957 if ((endpt = strchr(frpt, ',')) != NULL) 958 *endpt = '\0'; 959 if ((pt = strchr(frpt, '=')) == NULL) { 960 paxwarn(0, "Invalid options format"); 961 return(-1); 962 } 963 if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) { 964 paxwarn(0, "Unable to allocate space for option list"); 965 return(-1); 966 } 967 *pt++ = '\0'; 968 opt->name = frpt; 969 opt->value = pt; 970 opt->fow = NULL; 971 if (endpt != NULL) 972 frpt = endpt + 1; 973 else 974 frpt = NULL; 975 if (ophead == NULL) { 976 optail = ophead = opt; 977 continue; 978 } 979 optail->fow = opt; 980 optail = opt; 981 } 982 return(0); 983} 984 985/* 986 * str_offt() 987 * Convert an expression of the following forms to an off_t > 0. 988 * 1) A positive decimal number. 989 * 2) A positive decimal number followed by a b (mult by 512). 990 * 3) A positive decimal number followed by a k (mult by 1024). 991 * 4) A positive decimal number followed by a m (mult by 512). 992 * 5) A positive decimal number followed by a w (mult by sizeof int) 993 * 6) Two or more positive decimal numbers (with/without k,b or w). 994 * separated by x (also * for backwards compatibility), specifying 995 * the product of the indicated values. 996 * Return: 997 * 0 for an error, a positive value o.w. 998 */ 999 1000#ifdef __STDC__ 1001static off_t 1002str_offt(char *val) 1003#else 1004static off_t 1005str_offt(val) 1006 char *val; 1007#endif 1008{ 1009 char *expr; 1010 off_t num, t; 1011 1012# ifdef NET2_STAT 1013 num = strtol(val, &expr, 0); 1014 if ((num == LONG_MAX) || (num <= 0) || (expr == val)) 1015# else 1016 num = strtoq(val, &expr, 0); 1017 if ((num == QUAD_MAX) || (num <= 0) || (expr == val)) 1018# endif 1019 return(0); 1020 1021 switch(*expr) { 1022 case 'b': 1023 t = num; 1024 num *= 512; 1025 if (t > num) 1026 return(0); 1027 ++expr; 1028 break; 1029 case 'k': 1030 t = num; 1031 num *= 1024; 1032 if (t > num) 1033 return(0); 1034 ++expr; 1035 break; 1036 case 'm': 1037 t = num; 1038 num *= 1048576; 1039 if (t > num) 1040 return(0); 1041 ++expr; 1042 break; 1043 case 'w': 1044 t = num; 1045 num *= sizeof(int); 1046 if (t > num) 1047 return(0); 1048 ++expr; 1049 break; 1050 } 1051 1052 switch(*expr) { 1053 case '\0': 1054 break; 1055 case '*': 1056 case 'x': 1057 t = num; 1058 num *= str_offt(expr + 1); 1059 if (t > num) 1060 return(0); 1061 break; 1062 default: 1063 return(0); 1064 } 1065 return(num); 1066} 1067 1068/* 1069 * no_op() 1070 * for those option functions where the archive format has nothing to do. 1071 * Return: 1072 * 0 1073 */ 1074 1075#ifdef __STDC__ 1076static int 1077no_op(void) 1078#else 1079static int 1080no_op() 1081#endif 1082{ 1083 return(0); 1084} 1085 1086/* 1087 * pax_usage() 1088 * print the usage summary to the user 1089 */ 1090 1091#ifdef __STDC__ 1092void 1093pax_usage(void) 1094#else 1095void 1096pax_usage() 1097#endif 1098{ 1099 (void)fputs("usage: pax [-cdnvz] [-E limit] [-f archive] ", stderr); 1100 (void)fputs("[-s replstr] ... [-U user] ...", stderr); 1101 (void)fputs("\n [-G group] ... ", stderr); 1102 (void)fputs("[-T [from_date][,to_date]] ... ", stderr); 1103 (void)fputs("[pattern ...]\n", stderr); 1104 (void)fputs(" pax -r [-cdiknuvzDYZ] [-E limit] ", stderr); 1105 (void)fputs("[-f archive] [-o options] ... \n", stderr); 1106 (void)fputs(" [-p string] ... [-s replstr] ... ", stderr); 1107 (void)fputs("[-U user] ... [-G group] ...\n ", stderr); 1108 (void)fputs("[-T [from_date][,to_date]] ... ", stderr); 1109 (void)fputs(" [pattern ...]\n", stderr); 1110 (void)fputs(" pax -w [-dituvzHLPX] [-b blocksize] ", stderr); 1111 (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); 1112 (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); 1113 (void)fputs("[-o options] ... [-U user] ...", stderr); 1114 (void)fputs("\n [-G group] ... ", stderr); 1115 (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); 1116 (void)fputs("[file ...]\n", stderr); 1117 (void)fputs(" pax -r -w [-diklntuvDHLPXYZ] ", stderr); 1118 (void)fputs("[-p string] ... [-s replstr] ...", stderr); 1119 (void)fputs("\n [-U user] ... [-G group] ... ", stderr); 1120 (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); 1121 (void)fputs("\n [file ...] directory\n", stderr); 1122 exit(1); 1123} 1124 1125/* 1126 * tar_usage() 1127 * print the usage summary to the user 1128 */ 1129 1130#ifdef __STDC__ 1131void 1132tar_usage(void) 1133#else 1134void 1135tar_usage() 1136#endif 1137{ 1138 (void)fputs("usage: tar -{txru}[cevfbmopwzBHLPXZ014578] [tapefile] ", 1139 stderr); 1140 (void)fputs("[blocksize] file1 file2...\n", stderr); 1141 exit(1); 1142} 1143 1144#ifdef notdef 1145/* 1146 * cpio_usage() 1147 * print the usage summary to the user 1148 */ 1149 1150#ifdef __STDC__ 1151void 1152cpio_usage(void) 1153#else 1154void 1155cpio_usage() 1156#endif 1157{ 1158 exit(1); 1159} 1160#endif 1161