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