1 /*- 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Keith Muller of the University of California, San Diego. 8 * 9 * %sccs.include.redist.c% 10 */ 11 12 #ifndef lint 13 static char sccsid[] = "@(#)options.c 8.1 (Berkeley) 05/31/93"; 14 #endif /* not lint */ 15 16 #include <sys/types.h> 17 #include <sys/time.h> 18 #include <sys/stat.h> 19 #include <sys/mtio.h> 20 #include <sys/param.h> 21 #include <stdio.h> 22 #include <ctype.h> 23 #include <string.h> 24 #include <unistd.h> 25 #include <stdlib.h> 26 #include <limits.h> 27 #include "pax.h" 28 #include "options.h" 29 #include "cpio.h" 30 #include "extern.h" 31 32 /* 33 * Routines which handle command line options 34 */ 35 36 static char flgch[] = FLGCH; /* list of all possible flags */ 37 static OPLIST *ophead = NULL; /* head for format specific options -x */ 38 static OPLIST *optail = NULL; /* option tail */ 39 40 static int no_op __P((void)); 41 static void printflg __P((unsigned int)); 42 static int c_frmt __P((const void *, const void *)); 43 static off_t str_offt __P((char *)); 44 45 /* 46 * Format specific routine table - MUST BE IN SORTED ORDER BY NAME 47 * (see pax.h for description of each function) 48 * 49 * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read, 50 * read, end_read, st_write, write, end_write, trail, 51 * rd_data, wr_data, options 52 */ 53 54 FSUB fsub[] = { 55 /* 0: OLD BINARY CPIO */ 56 "bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd, 57 bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail, 58 rd_wrfile, wr_rdfile, bad_opt, 59 60 /* 1: OLD OCTAL CHARACTER CPIO */ 61 "cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd, 62 cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail, 63 rd_wrfile, wr_rdfile, bad_opt, 64 65 /* 2: SVR4 HEX CPIO */ 66 "sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd, 67 vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail, 68 rd_wrfile, wr_rdfile, bad_opt, 69 70 /* 3: SVR4 HEX CPIO WITH CRC */ 71 "sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd, 72 vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail, 73 rd_wrfile, wr_rdfile, bad_opt, 74 75 /* 4: OLD TAR */ 76 "tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op, 77 tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail, 78 rd_wrfile, wr_rdfile, tar_opt, 79 80 /* 5: POSIX USTAR */ 81 "ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd, 82 ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail, 83 rd_wrfile, wr_rdfile, bad_opt, 84 }; 85 #define DEFLT 5 /* default write format from list above */ 86 87 /* 88 * ford is the archive search order used by get_arc() to determine what kind 89 * of archive we are dealing with. This helps to properly id archive formats 90 * some formats may be subsets of others.... 91 */ 92 int ford[] = {5, 4, 3, 2, 1, 0, -1 }; 93 94 /* 95 * options() 96 * look at the user specified flags. set globals as required and check if 97 * the user specified a legal set of flags. If not, complain and exit 98 */ 99 100 #if __STDC__ 101 void 102 options(register int argc, register char **argv) 103 #else 104 void 105 options(argc, argv) 106 register int argc; 107 register char **argv; 108 #endif 109 { 110 register int c; 111 register int i; 112 unsigned int flg = 0; 113 unsigned int bflg = 0; 114 register char *pt; 115 FSUB tmp; 116 extern char *optarg; 117 extern int optind; 118 119 /* 120 * process option flags 121 */ 122 while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLT:U:XYZ")) 123 != EOF) { 124 switch (c) { 125 case 'a': 126 /* 127 * append 128 */ 129 flg |= AF; 130 break; 131 case 'b': 132 /* 133 * specify blocksize on write 134 */ 135 flg |= BF; 136 if ((wrblksz = (int)str_offt(optarg)) <= 0) { 137 warn(1, "Invalid block size %s", optarg); 138 usage(); 139 } 140 break; 141 case 'c': 142 /* 143 * inverse match on patterns 144 */ 145 cflag = 1; 146 flg |= CF; 147 break; 148 case 'd': 149 /* 150 * match only dir on extract, not the subtree at dir 151 */ 152 dflag = 1; 153 flg |= DF; 154 break; 155 case 'f': 156 /* 157 * filename where the archive is stored 158 */ 159 arcname = optarg; 160 flg |= FF; 161 break; 162 case 'i': 163 /* 164 * interactive file rename 165 */ 166 iflag = 1; 167 flg |= IF; 168 break; 169 case 'k': 170 /* 171 * do not clobber files that exist 172 */ 173 kflag = 1; 174 flg |= KF; 175 break; 176 case 'l': 177 /* 178 * try to link src to dest with copy (-rw) 179 */ 180 lflag = 1; 181 flg |= LF; 182 break; 183 case 'n': 184 /* 185 * select first match for a pattern only 186 */ 187 nflag = 1; 188 flg |= NF; 189 break; 190 case 'o': 191 /* 192 * pass format specific options 193 */ 194 flg |= OF; 195 if (opt_add(optarg) < 0) 196 usage(); 197 break; 198 case 'p': 199 /* 200 * specify file characteristic options 201 */ 202 for (pt = optarg; *pt != '\0'; ++pt) { 203 switch(*pt) { 204 case 'a': 205 /* 206 * do not preserve access time 207 */ 208 patime = 0; 209 break; 210 case 'e': 211 /* 212 * preserve user id, group id, file 213 * mode, access/modification times 214 */ 215 pids = 1; 216 pmode = 1; 217 patime = 1; 218 pmtime = 1; 219 break; 220 case 'm': 221 /* 222 * do not preserve modification time 223 */ 224 pmtime = 0; 225 break; 226 case 'o': 227 /* 228 * preserve uid/gid 229 */ 230 pids = 1; 231 break; 232 case 'p': 233 /* 234 * preserver file mode bits 235 */ 236 pmode = 1; 237 break; 238 default: 239 warn(1, "Invalid -p string: %c", *pt); 240 usage(); 241 break; 242 } 243 } 244 flg |= PF; 245 break; 246 case 'r': 247 /* 248 * read the archive 249 */ 250 flg |= RF; 251 break; 252 case 's': 253 /* 254 * file name substitution name pattern 255 */ 256 if (rep_add(optarg) < 0) { 257 usage(); 258 break; 259 } 260 flg |= SF; 261 break; 262 case 't': 263 /* 264 * preserve access time on filesystem nodes we read 265 */ 266 tflag = 1; 267 flg |= TF; 268 break; 269 case 'u': 270 /* 271 * ignore those older files 272 */ 273 uflag = 1; 274 flg |= UF; 275 break; 276 case 'v': 277 /* 278 * verbose operation mode 279 */ 280 vflag = 1; 281 flg |= VF; 282 break; 283 case 'w': 284 /* 285 * write an archive 286 */ 287 flg |= WF; 288 break; 289 case 'x': 290 /* 291 * specify an archive format on write 292 */ 293 tmp.name = optarg; 294 if (frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 295 sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) { 296 flg |= XF; 297 break; 298 } 299 warn(1, "Unknown -x format: %s", optarg); 300 (void)fputs("pax: Known -x formats are:", stderr); 301 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 302 (void)fprintf(stderr, " %s", fsub[i].name); 303 (void)fputs("\n\n", stderr); 304 usage(); 305 break; 306 case 'B': 307 /* 308 * non-standard option on number of bytes written on a 309 * single archive volume. 310 */ 311 if ((wrlimit = str_offt(optarg)) <= 0) { 312 warn(1, "Invalid write limit %s", optarg); 313 usage(); 314 } 315 if (wrlimit % BLKMULT) { 316 warn(1, "Write limit is not a %d byte multiple", 317 BLKMULT); 318 usage(); 319 } 320 flg |= CBF; 321 break; 322 case 'D': 323 /* 324 * On extraction check file inode change time before the 325 * modification of the file name. Non standard option. 326 */ 327 Dflag = 1; 328 flg |= CDF; 329 break; 330 case 'E': 331 /* 332 * non-standard limit on read faults 333 * 0 indicates stop after first error, values 334 * indicate a limit, "NONE" try forever 335 */ 336 flg |= CEF; 337 if (strcmp(NONE, optarg) == 0) 338 maxflt = -1; 339 else if ((maxflt = atoi(optarg)) < 0) { 340 warn(1, "Error count value must be positive"); 341 usage(); 342 } 343 break; 344 case 'G': 345 /* 346 * non-standard option for selecting files within an 347 * archive by group (gid or name) 348 */ 349 if (grp_add(optarg) < 0) { 350 usage(); 351 break; 352 } 353 flg |= CGF; 354 break; 355 case 'H': 356 /* 357 * follow command line symlinks only 358 */ 359 Hflag = 1; 360 flg |= CHF; 361 break; 362 case 'L': 363 /* 364 * follow symlinks 365 */ 366 Lflag = 1; 367 flg |= CLF; 368 break; 369 case 'T': 370 /* 371 * non-standard option for selecting files within an 372 * archive by modification time range (lower,upper) 373 */ 374 if (trng_add(optarg) < 0) { 375 usage(); 376 break; 377 } 378 flg |= CTF; 379 break; 380 case 'U': 381 /* 382 * non-standard option for selecting files within an 383 * archive by user (uid or name) 384 */ 385 if (usr_add(optarg) < 0) { 386 usage(); 387 break; 388 } 389 flg |= CUF; 390 break; 391 case 'X': 392 /* 393 * do not pass over mount points in the file system 394 */ 395 Xflag = 1; 396 flg |= CXF; 397 break; 398 case 'Y': 399 /* 400 * On extraction check file inode change time after the 401 * modification of the file name. Non standard option. 402 */ 403 Yflag = 1; 404 flg |= CYF; 405 break; 406 case 'Z': 407 /* 408 * On extraction check modification time after the 409 * modification of the file name. Non standard option. 410 */ 411 Zflag = 1; 412 flg |= CZF; 413 break; 414 case '?': 415 default: 416 usage(); 417 break; 418 } 419 } 420 421 /* 422 * figure out the operation mode of pax read,write,extract,copy,append 423 * or list. check that we have not been given a bogus set of flags 424 * for the operation mode. 425 */ 426 if (ISLIST(flg)) { 427 act = LIST; 428 bflg = flg & BDLIST; 429 } else if (ISEXTRACT(flg)) { 430 act = EXTRACT; 431 bflg = flg & BDEXTR; 432 } else if (ISARCHIVE(flg)) { 433 act = ARCHIVE; 434 bflg = flg & BDARCH; 435 } else if (ISAPPND(flg)) { 436 act = APPND; 437 bflg = flg & BDARCH; 438 } else if (ISCOPY(flg)) { 439 act = COPY; 440 bflg = flg & BDCOPY; 441 } else 442 usage(); 443 if (bflg) { 444 printflg(flg); 445 usage(); 446 } 447 448 /* 449 * if we are writing (ARCHIVE) we use the default format if the user 450 * did not specify a format. when we write during an APPEND, we will 451 * adopt the format of the existing archive if none was supplied. 452 */ 453 if (!(flg & XF) && (act == ARCHIVE)) 454 frmt = &(fsub[DEFLT]); 455 456 /* 457 * process the args as they are interpreted by the operation mode 458 */ 459 switch (act) { 460 case LIST: 461 case EXTRACT: 462 for (; optind < argc; optind++) 463 if (pat_add(argv[optind]) < 0) 464 usage(); 465 break; 466 case COPY: 467 if (optind >= argc) { 468 warn(0, "Destination directory was not supplied"); 469 usage(); 470 } 471 --argc; 472 dirptr = argv[argc]; 473 /* FALL THROUGH */ 474 case ARCHIVE: 475 case APPND: 476 for (; optind < argc; optind++) 477 if (ftree_add(argv[optind]) < 0) 478 usage(); 479 /* 480 * no read errors allowed on updates/append operation! 481 */ 482 maxflt = 0; 483 break; 484 } 485 } 486 487 /* 488 * printflg() 489 * print out those invalid flag sets found to the user 490 */ 491 492 #if __STDC__ 493 static void 494 printflg(unsigned int flg) 495 #else 496 static void 497 printflg(flg) 498 unsigned int flg; 499 #endif 500 { 501 int nxt; 502 int pos = 0; 503 504 (void)fputs("pax: Invalid combination of options:", stderr); 505 while (nxt = ffs(flg)) { 506 flg = flg >> nxt; 507 pos += nxt; 508 (void)fprintf(stderr, " -%c", flgch[pos-1]); 509 } 510 (void)putc('\n', stderr); 511 } 512 513 /* 514 * c_frmt() 515 * comparison routine used by bsearch to find the format specified 516 * by the user 517 */ 518 519 #if __STDC__ 520 static int 521 c_frmt(const void *a, const void *b) 522 #else 523 static int 524 c_frmt(a, b) 525 void *a; 526 void *b; 527 #endif 528 { 529 return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); 530 } 531 532 /* 533 * opt_next() 534 * called by format specific options routines to get each format specific 535 * flag and value specified with -o 536 * Return: 537 * pointer to next OPLIST entry or NULL (end of list). 538 */ 539 540 #if __STDC__ 541 OPLIST * 542 opt_next(void) 543 #else 544 OPLIST * 545 opt_next() 546 #endif 547 { 548 OPLIST *opt; 549 550 if ((opt = ophead) != NULL) 551 ophead = ophead->fow; 552 return(opt); 553 } 554 555 /* 556 * bad_opt() 557 * generic routine used to complain about a format specific options 558 * when the format does not support options. 559 */ 560 561 #if __STDC__ 562 int 563 bad_opt(void) 564 #else 565 int 566 bad_opt() 567 #endif 568 { 569 register OPLIST *opt; 570 571 if (ophead == NULL) 572 return(0); 573 /* 574 * print all we were given 575 */ 576 warn(1,"These format options are not supported"); 577 while ((opt = opt_next()) != NULL) 578 (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value); 579 usage(); 580 return(0); 581 } 582 583 /* 584 * opt_add() 585 * breaks the value supplied to -o into a option name and value. options 586 * are given to -o in the form -o name-value,name=value 587 * mulltiple -o may be specified. 588 * Return: 589 * 0 if format in name=value format, -1 if -o is passed junk 590 */ 591 592 #if __STDC__ 593 int 594 opt_add(register char *str) 595 #else 596 int 597 opt_add(str) 598 register char *str; 599 #endif 600 { 601 register OPLIST *opt; 602 register char *frpt; 603 register char *pt; 604 register char *endpt; 605 606 if ((str == NULL) || (*str == '\0')) { 607 warn(0, "Invalid option name"); 608 return(-1); 609 } 610 frpt = endpt = str; 611 612 /* 613 * break into name and values pieces and stuff each one into a 614 * OPLIST structure. When we know the format, the format specific 615 * option function will go through this list 616 */ 617 while ((frpt != NULL) && (*frpt != '\0')) { 618 if ((endpt = strchr(frpt, ',')) != NULL) 619 *endpt = '\0'; 620 if ((pt = strchr(frpt, '=')) == NULL) { 621 warn(0, "Invalid options format"); 622 return(-1); 623 } 624 if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) { 625 warn(0, "Unable to allocate space for option list"); 626 return(-1); 627 } 628 *pt++ = '\0'; 629 opt->name = frpt; 630 opt->value = pt; 631 opt->fow = NULL; 632 if (endpt != NULL) 633 frpt = endpt + 1; 634 else 635 frpt = NULL; 636 if (ophead == NULL) { 637 optail = ophead = opt; 638 continue; 639 } 640 optail->fow = opt; 641 optail = opt; 642 } 643 return(0); 644 } 645 646 /* 647 * str_offt() 648 * Convert an expression of the following forms to an off_t > 0. 649 * 1) A positive decimal number. 650 * 2) A positive decimal number followed by a b (mult by 512). 651 * 3) A positive decimal number followed by a k (mult by 1024). 652 * 4) A positive decimal number followed by a m (mult by 512). 653 * 5) A positive decimal number followed by a w (mult by sizeof int) 654 * 6) Two or more positive decimal numbers (with/without k,b or w). 655 * seperated by x (also * for backwards compatibility), specifying 656 * the product of the indicated values. 657 * Return: 658 * 0 for an error, a positive value o.w. 659 */ 660 661 #if __STDC__ 662 static off_t 663 str_offt(char *val) 664 #else 665 static off_t 666 str_offt(val) 667 char *val; 668 #endif 669 { 670 char *expr; 671 off_t num, t; 672 673 # ifdef NET2_STAT 674 num = strtol(val, &expr, 0); 675 if ((num == LONG_MAX) || (num <= 0) || (expr == val)) 676 # else 677 num = strtoq(val, &expr, 0); 678 if ((num == QUAD_MAX) || (num <= 0) || (expr == val)) 679 # endif 680 return(0); 681 682 switch(*expr) { 683 case 'b': 684 t = num; 685 num *= 512; 686 if (t > num) 687 return(0); 688 ++expr; 689 break; 690 case 'k': 691 t = num; 692 num *= 1024; 693 if (t > num) 694 return(0); 695 ++expr; 696 break; 697 case 'm': 698 t = num; 699 num *= 1048576; 700 if (t > num) 701 return(0); 702 ++expr; 703 break; 704 case 'w': 705 t = num; 706 num *= sizeof(int); 707 if (t > num) 708 return(0); 709 ++expr; 710 break; 711 } 712 713 switch(*expr) { 714 case '\0': 715 break; 716 case '*': 717 case 'x': 718 t = num; 719 num *= str_offt(expr + 1); 720 if (t > num) 721 return(0); 722 break; 723 default: 724 return(0); 725 } 726 return(num); 727 } 728 729 /* 730 * no_op() 731 * for those option functions where the archive format has nothing to do. 732 * Return: 733 * 0 734 */ 735 736 #if __STDC__ 737 static int 738 no_op(void) 739 #else 740 static int 741 no_op() 742 #endif 743 { 744 return(0); 745 } 746