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