1 /*- 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992 The Regents of the University of California. 4 * 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 1.1 (Berkeley) 12/17/92"; 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:E:G:HLT:U:XZ")) 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 'E': 323 /* 324 * non-standard limit on read faults 325 * 0 indicates stop after first error, values 326 * indicate a limit, "NONE" try forever 327 */ 328 flg |= CEF; 329 if (strcmp(NONE, optarg) == 0) 330 maxflt = -1; 331 else if ((maxflt = atoi(optarg)) < 0) { 332 warn(1, "Error count value must be positive"); 333 usage(); 334 } 335 break; 336 case 'G': 337 /* 338 * non-standard option for selecting files within an 339 * archive by group (gid or name) 340 */ 341 if (grp_add(optarg) < 0) { 342 usage(); 343 break; 344 } 345 flg |= CGF; 346 break; 347 case 'H': 348 /* 349 * follow command line symlinks only 350 */ 351 Hflag = 1; 352 flg |= CHF; 353 break; 354 case 'L': 355 /* 356 * follow symlinks 357 */ 358 Lflag = 1; 359 flg |= CLF; 360 break; 361 case 'T': 362 /* 363 * non-standard option for selecting files within an 364 * archive by modification time range (lower,upper) 365 */ 366 if (trng_add(optarg) < 0) { 367 usage(); 368 break; 369 } 370 flg |= CTF; 371 break; 372 case 'U': 373 /* 374 * non-standard option for selecting files within an 375 * archive by user (uid or name) 376 */ 377 if (usr_add(optarg) < 0) { 378 usage(); 379 break; 380 } 381 flg |= CUF; 382 break; 383 case 'X': 384 /* 385 * do not pass over mount points in the file system 386 */ 387 Xflag = 1; 388 flg |= CXF; 389 break; 390 case 'Z': 391 /* 392 * On extraction check file time after the modification 393 * of the file name. Non standard option. 394 */ 395 Zflag = 1; 396 flg |= CZF; 397 break; 398 case '?': 399 default: 400 usage(); 401 break; 402 } 403 } 404 405 /* 406 * figure out the operation mode of pax read,write,extract,copy,append 407 * or list. check that we have not been given a bogus set of flags 408 * for the operation mode. 409 */ 410 if (ISLIST(flg)) { 411 act = LIST; 412 bflg = flg & BDLIST; 413 } else if (ISEXTRACT(flg)) { 414 act = EXTRACT; 415 bflg = flg & BDEXTR; 416 } else if (ISARCHIVE(flg)) { 417 act = ARCHIVE; 418 bflg = flg & BDARCH; 419 } else if (ISAPPND(flg)) { 420 act = APPND; 421 bflg = flg & BDARCH; 422 } else if (ISCOPY(flg)) { 423 act = COPY; 424 bflg = flg & BDCOPY; 425 } else 426 usage(); 427 if (bflg) { 428 printflg(flg); 429 usage(); 430 } 431 432 /* 433 * if we are writing (ARCHIVE) we use the default format if the user 434 * did not specify a format. when we write during an APPEND, we will 435 * adopt the format of the existing archive if none was supplied. 436 */ 437 if (!(flg & XF) && (act == ARCHIVE)) 438 frmt = &(fsub[DEFLT]); 439 440 /* 441 * process the args as they are interpreted by the operation mode 442 */ 443 switch (act) { 444 case LIST: 445 case EXTRACT: 446 for (; optind < argc; optind++) 447 if (pat_add(argv[optind]) < 0) 448 usage(); 449 break; 450 case COPY: 451 if (optind >= argc) { 452 warn(0, "Destination directory was not supplied"); 453 usage(); 454 } 455 --argc; 456 dirptr = argv[argc]; 457 /* FALL THROUGH */ 458 case ARCHIVE: 459 case APPND: 460 for (; optind < argc; optind++) 461 if (ftree_add(argv[optind]) < 0) 462 usage(); 463 /* 464 * no read errors allowed on updates/append operation! 465 */ 466 maxflt = 0; 467 break; 468 } 469 } 470 471 /* 472 * printflg() 473 * print out those invalid flag sets found to the user 474 */ 475 476 #if __STDC__ 477 static void 478 printflg(unsigned int flg) 479 #else 480 static void 481 printflg(flg) 482 unsigned int flg; 483 #endif 484 { 485 int nxt; 486 int pos = 0; 487 488 (void)fputs("pax: Invalid combination of options:", stderr); 489 while (nxt = ffs(flg)) { 490 flg = flg >> nxt; 491 pos += nxt; 492 (void)fprintf(stderr, " -%c", flgch[pos-1]); 493 } 494 (void)putc('\n', stderr); 495 } 496 497 /* 498 * c_frmt() 499 * comparison routine used by bsearch to find the format specified 500 * by the user 501 */ 502 503 #if __STDC__ 504 static int 505 c_frmt(const void *a, const void *b) 506 #else 507 static int 508 c_frmt(a, b) 509 void *a; 510 void *b; 511 #endif 512 { 513 return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); 514 } 515 516 /* 517 * opt_next() 518 * called by format specific options routines to get each format specific 519 * flag and value specified with -o 520 * Return: 521 * pointer to next OPLIST entry or NULL (end of list). 522 */ 523 524 #if __STDC__ 525 OPLIST * 526 opt_next(void) 527 #else 528 OPLIST * 529 opt_next() 530 #endif 531 { 532 OPLIST *opt; 533 534 if ((opt = ophead) != NULL) 535 ophead = ophead->fow; 536 return(opt); 537 } 538 539 /* 540 * bad_opt() 541 * generic routine used to complain about a format specific options 542 * when the format does not support options. 543 */ 544 545 #if __STDC__ 546 int 547 bad_opt(void) 548 #else 549 int 550 bad_opt() 551 #endif 552 { 553 register OPLIST *opt; 554 555 if (ophead == NULL) 556 return(0); 557 /* 558 * print all we were given 559 */ 560 warn(1,"These format options are not supported"); 561 while ((opt = opt_next()) != NULL) 562 (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value); 563 usage(); 564 return(0); 565 } 566 567 /* 568 * opt_add() 569 * breaks the value supplied to -o into a option name and value. options 570 * are given to -o in the form -o name-value,name=value 571 * mulltiple -o may be specified. 572 * Return: 573 * 0 if format in name=value format, -1 if -o is passed junk 574 */ 575 576 #if __STDC__ 577 int 578 opt_add(register char *str) 579 #else 580 int 581 opt_add(str) 582 register char *str; 583 #endif 584 { 585 register OPLIST *opt; 586 register char *frpt; 587 register char *pt; 588 register char *endpt; 589 590 if ((str == NULL) || (*str == '\0')) { 591 warn(0, "Invalid option name"); 592 return(-1); 593 } 594 frpt = endpt = str; 595 596 /* 597 * break into name and values pieces and stuff each one into a 598 * OPLIST structure. When we know the format, the format specific 599 * option function will go through this list 600 */ 601 while ((frpt != NULL) && (*frpt != '\0')) { 602 if ((endpt = strchr(frpt, ',')) != NULL) 603 *endpt = '\0'; 604 if ((pt = strchr(frpt, '=')) == NULL) { 605 warn(0, "Invalid options format"); 606 return(-1); 607 } 608 if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) { 609 warn(0, "Unable to allocate space for option list"); 610 return(-1); 611 } 612 *pt++ = '\0'; 613 opt->name = frpt; 614 opt->value = pt; 615 opt->fow = NULL; 616 if (endpt != NULL) 617 frpt = endpt + 1; 618 else 619 frpt = NULL; 620 if (ophead == NULL) { 621 optail = ophead = opt; 622 continue; 623 } 624 optail->fow = opt; 625 optail = opt; 626 } 627 return(0); 628 } 629 630 /* 631 * str_offt() 632 * Convert an expression of the following forms to an off_t > 0. 633 * 1) A positive decimal number. 634 * 2) A positive decimal number followed by a b (mult by 512). 635 * 3) A positive decimal number followed by a k (mult by 1024). 636 * 4) A positive decimal number followed by a m (mult by 512). 637 * 5) A positive decimal number followed by a w (mult by sizeof int) 638 * 6) Two or more positive decimal numbers (with/without k,b or w). 639 * seperated by x (also * for backwards compatibility), specifying 640 * the product of the indicated values. 641 * Return: 642 * 0 for an error, a positive value o.w. 643 */ 644 645 #if __STDC__ 646 static off_t 647 str_offt(char *val) 648 #else 649 static off_t 650 str_offt(val) 651 char *val; 652 #endif 653 { 654 char *expr; 655 off_t num, t; 656 657 # ifdef NET2_STAT 658 num = strtol(val, &expr, 0); 659 if ((num == LONG_MAX) || (num <= 0) || (expr == val)) 660 # else 661 num = strtoq(val, &expr, 0); 662 if ((num == QUAD_MAX) || (num <= 0) || (expr == val)) 663 # endif 664 return(0); 665 666 switch(*expr) { 667 case 'b': 668 t = num; 669 num *= 512; 670 if (t > num) 671 return(0); 672 ++expr; 673 break; 674 case 'k': 675 t = num; 676 num *= 1024; 677 if (t > num) 678 return(0); 679 ++expr; 680 break; 681 case 'm': 682 t = num; 683 num *= 1048576; 684 if (t > num) 685 return(0); 686 ++expr; 687 break; 688 case 'w': 689 t = num; 690 num *= sizeof(int); 691 if (t > num) 692 return(0); 693 ++expr; 694 break; 695 } 696 697 switch(*expr) { 698 case '\0': 699 break; 700 case '*': 701 case 'x': 702 t = num; 703 num *= str_offt(expr + 1); 704 if (t > num) 705 return(0); 706 break; 707 default: 708 return(0); 709 } 710 return(num); 711 } 712 713 /* 714 * no_op() 715 * for those option functions where the archive format has nothing to do. 716 * Return: 717 * 0 718 */ 719 720 #if __STDC__ 721 static int 722 no_op(void) 723 #else 724 static int 725 no_op() 726 #endif 727 { 728 return(0); 729 } 730