Bug Summary

File:src/bin/pax/options.c
Warning:line 1522, column 9
Although the value stored to 'endpt' is used in the enclosing expression, the value is never actually read from 'endpt'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name options.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/bin/pax/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/bin/pax/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/bin/pax/options.c
1/* $OpenBSD: options.c,v 1.103 2019/11/15 20:34:17 naddy Exp $ */
2/* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */
3
4/*-
5 * Copyright (c) 1992 Keith Muller.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * Keith Muller of the University of California, San Diego.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <errno(*__errno()).h>
40#include <limits.h>
41#include <paths.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47#include "pax.h"
48#include "cpio.h"
49#include "tar.h"
50#include "extern.h"
51
52/*
53 * argv[0] names. Used for tar and cpio emulation
54 */
55
56#define NM_TAR"tar" "tar"
57#define NM_CPIO"cpio" "cpio"
58#define NM_PAX"pax" "pax"
59
60/*
61 * Constants used to specify the legal sets of flags in pax. For each major
62 * operation mode of pax, a set of illegal flags is defined. If any one of
63 * those illegal flags are found set, we scream and exit
64 */
65
66/*
67 * flags (one for each option).
68 */
69#define AF0x00000001 0x00000001
70#define BF0x00000002 0x00000002
71#define CF0x00000004 0x00000004
72#define DF0x00000008 0x00000008
73#define FF0x00000010 0x00000010
74#define IF0x00000020 0x00000020
75#define KF0x00000040 0x00000040
76#define LF0x00000080 0x00000080
77#define NF0x00000100 0x00000100
78#define OF0x00000200 0x00000200
79#define PF0x00000400 0x00000400
80#define RF0x00000800 0x00000800
81#define SF0x00001000 0x00001000
82#define TF0x00002000 0x00002000
83#define UF0x00004000 0x00004000
84#define VF0x00008000 0x00008000
85#define WF0x00010000 0x00010000
86#define XF0x00020000 0x00020000
87#define CBF0x00040000 0x00040000 /* nonstandard extension */
88#define CDF0x00080000 0x00080000 /* nonstandard extension */
89#define CEF0x00100000 0x00100000 /* nonstandard extension */
90#define CGF0x00200000 0x00200000 /* nonstandard extension */
91#define CHF0x00400000 0x00400000 /* nonstandard extension */
92#define CLF0x00800000 0x00800000 /* nonstandard extension */
93#define CPF0x01000000 0x01000000 /* nonstandard extension */
94#define CTF0x02000000 0x02000000 /* nonstandard extension */
95#define CUF0x04000000 0x04000000 /* nonstandard extension */
96#define CXF0x08000000 0x08000000
97#define CYF0x10000000 0x10000000 /* nonstandard extension */
98#define CZF0x20000000 0x20000000 /* nonstandard extension */
99#define C0F0x40000000 0x40000000 /* nonstandard extension */
100
101/*
102 * ascii string indexed by bit position above (alter the above and you must
103 * alter this string) used to tell the user what flags caused us to complain
104 */
105#define FLGCH"abcdfiklnoprstuvwxBDEGHLPTUXYZ0" "abcdfiklnoprstuvwxBDEGHLPTUXYZ0"
106
107/*
108 * legal pax operation bit patterns
109 */
110
111#define ISLIST(x)(((x) & (0x00000800|0x00010000)) == 0) (((x) & (RF0x00000800|WF0x00010000)) == 0)
112#define ISEXTRACT(x)(((x) & (0x00000800|0x00010000)) == 0x00000800) (((x) & (RF0x00000800|WF0x00010000)) == RF0x00000800)
113#define ISARCHIVE(x)(((x) & (0x00000001|0x00000800|0x00010000)) == 0x00010000
)
(((x) & (AF0x00000001|RF0x00000800|WF0x00010000)) == WF0x00010000)
114#define ISAPPND(x)(((x) & (0x00000001|0x00000800|0x00010000)) == (0x00000001
|0x00010000))
(((x) & (AF0x00000001|RF0x00000800|WF0x00010000)) == (AF0x00000001|WF0x00010000))
115#define ISCOPY(x)(((x) & (0x00000800|0x00010000)) == (0x00000800|0x00010000
))
(((x) & (RF0x00000800|WF0x00010000)) == (RF0x00000800|WF0x00010000))
116#define ISWRITE(x)(((x) & (0x00000800|0x00010000)) == 0x00010000) (((x) & (RF0x00000800|WF0x00010000)) == WF0x00010000)
117
118/*
119 * Illegal option flag subsets based on pax operation
120 */
121
122#define BDEXTR(0x00000001|0x00000002|0x00000080|0x00002000|0x00010000|0x00020000
|0x00040000|0x00400000|0x00800000|0x01000000|0x08000000)
(AF0x00000001|BF0x00000002|LF0x00000080|TF0x00002000|WF0x00010000|XF0x00020000|CBF0x00040000|CHF0x00400000|CLF0x00800000|CPF0x01000000|CXF0x08000000)
123#define BDARCH(0x00000004|0x00000040|0x00000080|0x00000100|0x00000400|0x00000800
|0x00080000|0x00100000|0x10000000|0x20000000)
(CF0x00000004|KF0x00000040|LF0x00000080|NF0x00000100|PF0x00000400|RF0x00000800|CDF0x00080000|CEF0x00100000|CYF0x10000000|CZF0x20000000)
124#define BDCOPY(0x00000001|0x00000002|0x00000010|0x00000200|0x00020000|0x00040000
|0x00100000)
(AF0x00000001|BF0x00000002|FF0x00000010|OF0x00000200|XF0x00020000|CBF0x00040000|CEF0x00100000)
125#define BDLIST(0x00000001|0x00000002|0x00000020|0x00000040|0x00000080|0x00000200
|0x00000400|0x00000800|0x00002000|0x00004000|0x00010000|0x00020000
|0x00040000|0x00080000|0x00400000|0x00800000|0x01000000|0x08000000
|0x10000000|0x20000000)
(AF0x00000001|BF0x00000002|IF0x00000020|KF0x00000040|LF0x00000080|OF0x00000200|PF0x00000400|RF0x00000800|TF0x00002000|UF0x00004000|WF0x00010000|XF0x00020000|CBF0x00040000|CDF0x00080000|CHF0x00400000|CLF0x00800000|CPF0x01000000|CXF0x08000000|CYF0x10000000|CZF0x20000000)
126
127
128/*
129 * Routines which handle command line options
130 */
131
132static char flgch[] = FLGCH"abcdfiklnoprstuvwxBDEGHLPTUXYZ0"; /* list of all possible flags */
133static OPLIST *ophead = NULL((void *)0); /* head for format specific options -x */
134static OPLIST *optail = NULL((void *)0); /* option tail */
135
136static int no_op(void);
137static void printflg(unsigned int);
138static off_t str_offt(char *);
139static char *get_line(FILE *fp);
140static void pax_options(int, char **);
141static void pax_usage(void);
142static void tar_options(int, char **);
143static void tar_usage(void);
144#ifndef NOCPIO
145static void cpio_options(int, char **);
146static void cpio_usage(void);
147#endif
148
149static int compress_id(char *_blk, int _size);
150static int gzip_id(char *_blk, int _size);
151static int bzip2_id(char *_blk, int _size);
152static int xz_id(char *_blk, int _size);
153
154#define GZIP_CMD"gzip" "gzip" /* command to run as gzip */
155#define COMPRESS_CMD"compress" "compress" /* command to run as compress */
156#define BZIP2_CMD"bzip2" "bzip2" /* command to run as bzip2 */
157
158/*
159 * Format specific routine table
160 * (see pax.h for description of each function)
161 *
162 * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read,
163 * read, end_read, st_write, write, end_write, trail,
164 * rd_data, wr_data, options
165 */
166
167FSUB fsub[] = {
168#ifdef NOCPIO
169/* 0: OLD BINARY CPIO */
170 { },
171/* 1: OLD OCTAL CHARACTER CPIO */
172 { },
173/* 2: SVR4 HEX CPIO */
174 { },
175/* 3: SVR4 HEX CPIO WITH CRC */
176 { },
177#else
178/* 0: OLD BINARY CPIO */
179 {"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,
180 bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail,
181 bad_opt},
182
183/* 1: OLD OCTAL CHARACTER CPIO */
184 {"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,
185 cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail,
186 bad_opt},
187
188/* 2: SVR4 HEX CPIO */
189 {"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,
190 vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail,
191 bad_opt},
192
193/* 3: SVR4 HEX CPIO WITH CRC */
194 {"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,
195 vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail,
196 bad_opt},
197#endif
198/* 4: OLD TAR */
199 {"tar", 10240, BLKMULT512, 0, 1, BLKMULT512, 0, tar_id, no_op,
200 tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
201 tar_opt},
202
203/* 5: POSIX USTAR */
204 {"ustar", 10240, BLKMULT512, 0, 1, BLKMULT512, 0, ustar_id, no_op,
205 ustar_rd, tar_endrd, no_op, ustar_wr, tar_endwr, tar_trail,
206 tar_opt},
207
208#ifdef SMALL
209/* 6: compress, to detect failure to use -Z */
210 { },
211/* 7: xz, to detect failure to decompress it */
212 { },
213/* 8: bzip2, to detect failure to use -j */
214 { },
215/* 9: gzip, to detect failure to use -z */
216 { },
217#else
218/* 6: compress, to detect failure to use -Z */
219 {NULL((void *)0), 0, 4, 0, 0, 0, 0, compress_id},
220/* 7: xz, to detect failure to decompress it */
221 {NULL((void *)0), 0, 4, 0, 0, 0, 0, xz_id},
222/* 8: bzip2, to detect failure to use -j */
223 {NULL((void *)0), 0, 4, 0, 0, 0, 0, bzip2_id},
224/* 9: gzip, to detect failure to use -z */
225 {NULL((void *)0), 0, 4, 0, 0, 0, 0, gzip_id},
226#endif
227};
228#define F_OCPIO0 0 /* format when called as cpio -6 */
229#define F_ACPIO1 1 /* format when called as cpio -c */
230#define F_CPIO3 3 /* format when called as cpio */
231#define F_OTAR4 4 /* format when called as tar -o */
232#define F_TAR5 5 /* format when called as tar */
233#define DEFLT5 5 /* default write format from list above */
234
235/*
236 * ford is the archive search order used by get_arc() to determine what kind
237 * of archive we are dealing with. This helps to properly id archive formats
238 * some formats may be subsets of others....
239 */
240int ford[] = {5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1};
241
242/*
243 * Do we have -C anywhere and what is it?
244 */
245int havechd = 0;
246char *chdname = NULL((void *)0);
247
248/*
249 * options()
250 * figure out if we are pax, tar or cpio. Call the appropriate options
251 * parser
252 */
253
254void
255options(int argc, char **argv)
256{
257 extern char *__progname;
258
259 /*
260 * Are we acting like pax, tar or cpio (based on argv[0])
261 */
262 argv0 = __progname;
263
264 if (strcmp(NM_TAR"tar", argv0) == 0) {
265 op_mode = OP_TAR;
266 tar_options(argc, argv);
267 return;
268 }
269#ifndef NOCPIO
270 else if (strcmp(NM_CPIO"cpio", argv0) == 0) {
271 op_mode = OP_CPIO;
272 cpio_options(argc, argv);
273 return;
274 }
275#endif /* !NOCPIO */
276 /*
277 * assume pax as the default
278 */
279 argv0 = NM_PAX"pax";
280 op_mode = OP_PAX;
281 pax_options(argc, argv);
282}
283
284/*
285 * pax_options()
286 * look at the user specified flags. set globals as required and check if
287 * the user specified a legal set of flags. If not, complain and exit
288 */
289
290static void
291pax_options(int argc, char **argv)
292{
293 int c;
294 unsigned i;
295 unsigned int flg = 0;
296 unsigned int bflg = 0;
297 const char *errstr;
298 char *pt;
299
300 /*
301 * process option flags
302 */
303 while ((c=getopt(argc,argv,"ab:cdf:ijklno:p:rs:tuvwx:zB:DE:G:HLOPT:U:XYZ0"))
304 != -1) {
305 switch (c) {
306 case 'a':
307 /*
308 * append
309 */
310 flg |= AF0x00000001;
311 break;
312 case 'b':
313 /*
314 * specify blocksize
315 */
316 flg |= BF0x00000002;
317 if ((wrblksz = (int)str_offt(optarg)) <= 0) {
318 paxwarn(1, "Invalid block size %s", optarg);
319 pax_usage();
320 }
321 break;
322 case 'c':
323 /*
324 * inverse match on patterns
325 */
326 cflag = 1;
327 flg |= CF0x00000004;
328 break;
329 case 'd':
330 /*
331 * match only dir on extract, not the subtree at dir
332 */
333 dflag = 1;
334 flg |= DF0x00000008;
335 break;
336 case 'f':
337 /*
338 * filename where the archive is stored
339 */
340 arcname = optarg;
341 flg |= FF0x00000010;
342 break;
343 case 'i':
344 /*
345 * interactive file rename
346 */
347 iflag = 1;
348 flg |= IF0x00000020;
349 break;
350 case 'j':
351 /*
352 * use bzip2. Non standard option.
353 */
354 gzip_program = BZIP2_CMD"bzip2";
355 break;
356 case 'k':
357 /*
358 * do not clobber files that exist
359 */
360 kflag = 1;
361 flg |= KF0x00000040;
362 break;
363 case 'l':
364 /*
365 * try to link src to dest with copy (-rw)
366 */
367 lflag = 1;
368 flg |= LF0x00000080;
369 break;
370 case 'n':
371 /*
372 * select first match for a pattern only
373 */
374 nflag = 1;
375 flg |= NF0x00000100;
376 break;
377 case 'o':
378 /*
379 * pass format specific options
380 */
381 flg |= OF0x00000200;
382 if (opt_add(optarg) < 0)
383 pax_usage();
384 break;
385 case 'p':
386 /*
387 * specify file characteristic options
388 */
389 for (pt = optarg; *pt != '\0'; ++pt) {
390 switch (*pt) {
391 case 'a':
392 /*
393 * do not preserve access time
394 */
395 patime = 0;
396 break;
397 case 'e':
398 /*
399 * preserve user id, group id, file
400 * mode, access/modification times
401 */
402 pids = 1;
403 pmode = 1;
404 patime = 1;
405 pmtime = 1;
406 break;
407 case 'm':
408 /*
409 * do not preserve modification time
410 */
411 pmtime = 0;
412 break;
413 case 'o':
414 /*
415 * preserve uid/gid
416 */
417 pids = 1;
418 break;
419 case 'p':
420 /*
421 * preserve file mode bits
422 */
423 pmode = 1;
424 break;
425 default:
426 paxwarn(1, "Invalid -p string: %c", *pt);
427 pax_usage();
428 break;
429 }
430 }
431 flg |= PF0x00000400;
432 break;
433 case 'r':
434 /*
435 * read the archive
436 */
437 flg |= RF0x00000800;
438 break;
439 case 's':
440 /*
441 * file name substitution name pattern
442 */
443 if (rep_add(optarg) < 0) {
444 pax_usage();
445 break;
446 }
447 flg |= SF0x00001000;
448 break;
449 case 't':
450 /*
451 * preserve access time on filesystem nodes we read
452 */
453 tflag = 1;
454 flg |= TF0x00002000;
455 break;
456 case 'u':
457 /*
458 * ignore those older files
459 */
460 uflag = 1;
461 flg |= UF0x00004000;
462 break;
463 case 'v':
464 /*
465 * verbose operation mode
466 */
467 vflag = 1;
468 flg |= VF0x00008000;
469 break;
470 case 'w':
471 /*
472 * write an archive
473 */
474 flg |= WF0x00010000;
475 break;
476 case 'x':
477 /*
478 * specify an archive format on write
479 */
480 for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i)
481 if (fsub[i].name != NULL((void *)0) &&
482 strcmp(fsub[i].name, optarg) == 0)
483 break;
484 if (i < sizeof(fsub)/sizeof(FSUB)) {
485 frmt = &fsub[i];
486 flg |= XF0x00020000;
487 break;
488 }
489 paxwarn(1, "Unknown -x format: %s", optarg);
490 (void)fputs("pax: Known -x formats are:", stderr(&__sF[2]));
491 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
492 if (fsub[i].name != NULL((void *)0))
493 (void)fprintf(stderr(&__sF[2]), " %s",
494 fsub[i].name);
495 (void)fputs("\n\n", stderr(&__sF[2]));
496 pax_usage();
497 break;
498 case 'z':
499 /*
500 * use gzip. Non standard option.
501 */
502 gzip_program = GZIP_CMD"gzip";
503 break;
504 case 'B':
505 /*
506 * non-standard option on number of bytes written on a
507 * single archive volume.
508 */
509 if ((wrlimit = str_offt(optarg)) <= 0) {
510 paxwarn(1, "Invalid write limit %s", optarg);
511 pax_usage();
512 }
513 if (wrlimit % BLKMULT512) {
514 paxwarn(1, "Write limit is not a %d byte multiple",
515 BLKMULT512);
516 pax_usage();
517 }
518 flg |= CBF0x00040000;
519 break;
520 case 'D':
521 /*
522 * On extraction check file inode change time before the
523 * modification of the file name. Non standard option.
524 */
525 Dflag = 1;
526 flg |= CDF0x00080000;
527 break;
528 case 'E':
529 /*
530 * non-standard limit on read faults
531 * 0 indicates stop after first error, values
532 * indicate a limit
533 */
534 flg |= CEF0x00100000;
535 maxflt = strtonum(optarg, 0, INT_MAX2147483647, &errstr);
536 if (errstr) {
537 paxwarn(1, "Error count value: %s", errstr);
538 pax_usage();
539 }
540 break;
541 case 'G':
542 /*
543 * non-standard option for selecting files within an
544 * archive by group (gid or name)
545 */
546 if (grp_add(optarg) < 0) {
547 pax_usage();
548 break;
549 }
550 flg |= CGF0x00200000;
551 break;
552 case 'H':
553 /*
554 * follow command line symlinks only
555 */
556 Hflag = 1;
557 flg |= CHF0x00400000;
558 break;
559 case 'L':
560 /*
561 * follow symlinks
562 */
563 Lflag = 1;
564 flg |= CLF0x00800000;
565 break;
566 case 'O':
567 /*
568 * Force one volume. Non standard option.
569 */
570 force_one_volume = 1;
571 break;
572 case 'P':
573 /*
574 * do NOT follow symlinks (default)
575 */
576 Lflag = 0;
577 flg |= CPF0x01000000;
578 break;
579 case 'T':
580 /*
581 * non-standard option for selecting files within an
582 * archive by modification time range (lower,upper)
583 */
584 if (trng_add(optarg) < 0) {
585 pax_usage();
586 break;
587 }
588 flg |= CTF0x02000000;
589 break;
590 case 'U':
591 /*
592 * non-standard option for selecting files within an
593 * archive by user (uid or name)
594 */
595 if (usr_add(optarg) < 0) {
596 pax_usage();
597 break;
598 }
599 flg |= CUF0x04000000;
600 break;
601 case 'X':
602 /*
603 * do not pass over mount points in the file system
604 */
605 Xflag = 1;
606 flg |= CXF0x08000000;
607 break;
608 case 'Y':
609 /*
610 * On extraction check file inode change time after the
611 * modification of the file name. Non standard option.
612 */
613 Yflag = 1;
614 flg |= CYF0x10000000;
615 break;
616 case 'Z':
617 /*
618 * On extraction check modification time after the
619 * modification of the file name. Non standard option.
620 */
621 Zflag = 1;
622 flg |= CZF0x20000000;
623 break;
624 case '0':
625 /*
626 * Use \0 as pathname terminator.
627 * (For use with the -print0 option of find(1).)
628 */
629 zeroflag = 1;
630 flg |= C0F0x40000000;
631 break;
632 default:
633 pax_usage();
634 break;
635 }
636 }
637
638 /*
639 * figure out the operation mode of pax read,write,extract,copy,append
640 * or list. check that we have not been given a bogus set of flags
641 * for the operation mode.
642 */
643 if (ISLIST(flg)(((flg) & (0x00000800|0x00010000)) == 0)) {
644 act = LIST0;
645 listf = stdout(&__sF[1]);
646 bflg = flg & BDLIST(0x00000001|0x00000002|0x00000020|0x00000040|0x00000080|0x00000200
|0x00000400|0x00000800|0x00002000|0x00004000|0x00010000|0x00020000
|0x00040000|0x00080000|0x00400000|0x00800000|0x01000000|0x08000000
|0x10000000|0x20000000)
;
647 } else if (ISEXTRACT(flg)(((flg) & (0x00000800|0x00010000)) == 0x00000800)) {
648 act = EXTRACT1;
649 bflg = flg & BDEXTR(0x00000001|0x00000002|0x00000080|0x00002000|0x00010000|0x00020000
|0x00040000|0x00400000|0x00800000|0x01000000|0x08000000)
;
650 } else if (ISARCHIVE(flg)(((flg) & (0x00000001|0x00000800|0x00010000)) == 0x00010000
)
) {
651 act = ARCHIVE2;
652 bflg = flg & BDARCH(0x00000004|0x00000040|0x00000080|0x00000100|0x00000400|0x00000800
|0x00080000|0x00100000|0x10000000|0x20000000)
;
653 } else if (ISAPPND(flg)(((flg) & (0x00000001|0x00000800|0x00010000)) == (0x00000001
|0x00010000))
) {
654 act = APPND3;
655 bflg = flg & BDARCH(0x00000004|0x00000040|0x00000080|0x00000100|0x00000400|0x00000800
|0x00080000|0x00100000|0x10000000|0x20000000)
;
656 } else if (ISCOPY(flg)(((flg) & (0x00000800|0x00010000)) == (0x00000800|0x00010000
))
) {
657 act = COPY4;
658 bflg = flg & BDCOPY(0x00000001|0x00000002|0x00000010|0x00000200|0x00020000|0x00040000
|0x00100000)
;
659 } else
660 pax_usage();
661 if (bflg) {
662 printflg(flg);
663 pax_usage();
664 }
665
666 /*
667 * if we are writing (ARCHIVE) we use the default format if the user
668 * did not specify a format. when we write during an APPEND, we will
669 * adopt the format of the existing archive if none was supplied.
670 */
671 if (!(flg & XF0x00020000) && (act == ARCHIVE2))
672 frmt = &(fsub[DEFLT5]);
673
674 /*
675 * process the args as they are interpreted by the operation mode
676 */
677 switch (act) {
678 case LIST0:
679 case EXTRACT1:
680 for (; optind < argc; optind++)
681 if (pat_add(argv[optind], NULL((void *)0)) < 0)
682 pax_usage();
683 break;
684 case COPY4:
685 if (optind >= argc) {
686 paxwarn(0, "Destination directory was not supplied");
687 pax_usage();
688 }
689 --argc;
690 dirptr = argv[argc];
691 /* FALL THROUGH */
692 case ARCHIVE2:
693 case APPND3:
694 for (; optind < argc; optind++)
695 if (ftree_add(argv[optind], 0) < 0)
696 pax_usage();
697 /*
698 * no read errors allowed on updates/append operation!
699 */
700 maxflt = 0;
701 break;
702 }
703}
704
705
706/*
707 * tar_options()
708 * look at the user specified flags. set globals as required and check if
709 * the user specified a legal set of flags. If not, complain and exit
710 */
711
712static void
713tar_options(int argc, char **argv)
714{
715 int c;
716 int Oflag = 0;
717 int nincfiles = 0;
718 int incfiles_max = 0;
719 struct incfile {
720 char *file;
721 char *dir;
722 };
723 struct incfile *incfiles = NULL((void *)0);
724
725 /*
726 * Set default values.
727 */
728 rmleadslash = 1;
729
730 /*
731 * process option flags
732 */
733 while ((c = getoldopt(argc, argv,
734 "b:cef:hjmopqruts:vwxzBC:HI:LNOPXZ014578")) != -1) {
735 switch (c) {
736 case 'b':
737 /*
738 * specify blocksize in 512-byte blocks
739 */
740 if ((wrblksz = (int)str_offt(optarg)) <= 0) {
741 paxwarn(1, "Invalid block size %s", optarg);
742 tar_usage();
743 }
744 wrblksz *= 512; /* XXX - check for int oflow */
745 break;
746 case 'c':
747 /*
748 * create an archive
749 */
750 act = ARCHIVE2;
751 break;
752 case 'e':
753 /*
754 * stop after first error
755 */
756 maxflt = 0;
757 break;
758 case 'f':
759 /*
760 * filename where the archive is stored
761 */
762 arcname = optarg;
763 break;
764 case 'h':
765 /*
766 * follow symlinks
767 */
768 Lflag = 1;
769 break;
770 case 'j':
771 /*
772 * use bzip2. Non standard option.
773 */
774 gzip_program = BZIP2_CMD"bzip2";
775 break;
776 case 'm':
777 /*
778 * do not preserve modification time
779 */
780 pmtime = 0;
781 break;
782 case 'O':
783 Oflag = 1;
784 break;
785 case 'o':
786 Oflag = 2;
787 tar_nodir = 1;
788 break;
789 case 'p':
790 /*
791 * preserve uid/gid and file mode, regardless of umask
792 */
793 pmode = 1;
794 pids = 1;
795 break;
796 case 'q':
797 /*
798 * select first match for a pattern only
799 */
800 nflag = 1;
801 break;
802 case 'r':
803 case 'u':
804 /*
805 * append to the archive
806 */
807 act = APPND3;
808 break;
809 case 's':
810 /*
811 * file name substitution name pattern
812 */
813 if (rep_add(optarg) < 0) {
814 tar_usage();
815 break;
816 }
817 break;
818 case 't':
819 /*
820 * list contents of the tape
821 */
822 act = LIST0;
823 break;
824 case 'v':
825 /*
826 * verbose operation mode
827 */
828 vflag++;
829 break;
830 case 'w':
831 /*
832 * interactive file rename
833 */
834 iflag = 1;
835 break;
836 case 'x':
837 /*
838 * extract an archive, preserving mode,
839 * and mtime if possible.
840 */
841 act = EXTRACT1;
842 pmtime = 1;
843 break;
844 case 'z':
845 /*
846 * use gzip. Non standard option.
847 */
848 gzip_program = GZIP_CMD"gzip";
849 break;
850 case 'B':
851 /*
852 * Nothing to do here, this is pax default
853 */
854 break;
855 case 'C':
856 havechd++;
857 chdname = optarg;
858 break;
859 case 'H':
860 /*
861 * follow command line symlinks only
862 */
863 Hflag = 1;
864 break;
865 case 'I':
866 if (++nincfiles > incfiles_max) {
867 size_t n = nincfiles + 3;
868 struct incfile *p;
869
870 p = reallocarray(incfiles, n,
871 sizeof(*incfiles));
872 if (p == NULL((void *)0)) {
873 paxwarn(0, "Unable to allocate space "
874 "for option list");
875 exit(1);
876 }
877 incfiles = p;
878 incfiles_max = n;
879 }
880 incfiles[nincfiles - 1].file = optarg;
881 incfiles[nincfiles - 1].dir = chdname;
882 break;
883 case 'L':
884 /*
885 * follow symlinks
886 */
887 Lflag = 1;
888 break;
889 case 'N':
890 /* numeric uid and gid only */
891 Nflag = 1;
892 break;
893 case 'P':
894 /*
895 * do not remove leading '/' from pathnames
896 */
897 rmleadslash = 0;
898 break;
899 case 'X':
900 /*
901 * do not pass over mount points in the file system
902 */
903 Xflag = 1;
904 break;
905 case 'Z':
906 /*
907 * use compress.
908 */
909 gzip_program = COMPRESS_CMD"compress";
910 break;
911 case '0':
912 arcname = DEV_0"/dev/rst0";
913 break;
914 case '1':
915 arcname = DEV_1"/dev/rst1";
916 break;
917 case '4':
918 arcname = DEV_4"/dev/rst4";
919 break;
920 case '5':
921 arcname = DEV_5"/dev/rst5";
922 break;
923 case '7':
924 arcname = DEV_7"/dev/rst7";
925 break;
926 case '8':
927 arcname = DEV_8"/dev/rst8";
928 break;
929 default:
930 tar_usage();
931 break;
932 }
933 }
934 argc -= optind;
935 argv += optind;
936
937 if ((arcname == NULL((void *)0)) || (*arcname == '\0')) {
938 arcname = getenv("TAPE");
939 if ((arcname == NULL((void *)0)) || (*arcname == '\0'))
940 arcname = _PATH_DEFTAPE"/dev/rst0";
941 }
942 if ((arcname[0] == '-') && (arcname[1]== '\0'))
943 arcname = NULL((void *)0);
944
945 /*
946 * Traditional tar behaviour: list-like output goes to stdout unless
947 * writing the archive there. (pax uses stderr unless in list mode)
948 */
949 if (act == LIST0 || act == EXTRACT1 || arcname != NULL((void *)0))
950 listf = stdout(&__sF[1]);
951
952 /* Traditional tar behaviour (pax wants to read file list from stdin) */
953 if ((act == ARCHIVE2 || act == APPND3) && argc == 0 && nincfiles == 0)
954 exit(0);
955
956 /*
957 * process the args as they are interpreted by the operation mode
958 */
959 switch (act) {
960 case LIST0:
961 case EXTRACT1:
962 default:
963 {
964 int sawpat = 0;
965 char *file, *dir;
966
967 while (nincfiles || *argv != NULL((void *)0)) {
968 /*
969 * If we queued up any include files,
970 * pull them in now. Otherwise, check
971 * for -I and -C positional flags.
972 * Anything else must be a file to
973 * extract.
974 */
975 if (nincfiles) {
976 file = incfiles->file;
977 dir = incfiles->dir;
978 incfiles++;
979 nincfiles--;
980 } else if (strcmp(*argv, "-I") == 0) {
981 if (*++argv == NULL((void *)0))
982 break;
983 file = *argv++;
984 dir = chdname;
985 } else
986 file = NULL((void *)0);
987 if (file != NULL((void *)0)) {
988 FILE *fp;
989 char *str;
990
991 if (strcmp(file, "-") == 0)
992 fp = stdin(&__sF[0]);
993 else if ((fp = fopen(file, "r")) == NULL((void *)0)) {
994 syswarn(1, errno(*__errno()),
995 "Unable to open %s", file);
996 tar_usage();
997 }
998 while ((str = get_line(fp)) != NULL((void *)0)) {
999 if (pat_add(str, dir) < 0)
1000 tar_usage();
1001 sawpat = 1;
1002 }
1003 if (ferror(fp)(!__isthreaded ? (((fp)->_flags & 0x0040) != 0) : (ferror
)(fp))
) {
1004 syswarn(1, errno(*__errno()),
1005 "Unable to read from %s",
1006 strcmp(file, "-") ? file :
1007 "stdin");
1008 tar_usage();
1009 }
1010 if (strcmp(file, "-") != 0)
1011 fclose(fp);
1012 } else if (strcmp(*argv, "-C") == 0) {
1013 if (*++argv == NULL((void *)0))
1014 break;
1015 chdname = *argv++;
1016 havechd++;
1017 } else if (pat_add(*argv++, chdname) < 0)
1018 tar_usage();
1019 else
1020 sawpat = 1;
1021 }
1022 /*
1023 * if patterns were added, we are doing chdir()
1024 * on a file-by-file basis, else, just one
1025 * global chdir (if any) after opening input.
1026 */
1027 if (sawpat > 0)
1028 chdname = NULL((void *)0);
1029 }
1030 break;
1031 case ARCHIVE2:
1032 case APPND3:
1033 frmt = &(fsub[Oflag ? F_OTAR4 : F_TAR5]);
1034
1035 if (chdname != NULL((void *)0)) { /* initial chdir() */
1036 if (ftree_add(chdname, 1) < 0)
1037 tar_usage();
1038 }
1039
1040 while (nincfiles || *argv != NULL((void *)0)) {
1041 char *file, *dir;
1042
1043 /*
1044 * If we queued up any include files, pull them in
1045 * now. Otherwise, check for -I and -C positional
1046 * flags. Anything else must be a file to include
1047 * in the archive.
1048 */
1049 if (nincfiles) {
1050 file = incfiles->file;
1051 dir = incfiles->dir;
1052 incfiles++;
1053 nincfiles--;
1054 } else if (strcmp(*argv, "-I") == 0) {
1055 if (*++argv == NULL((void *)0))
1056 break;
1057 file = *argv++;
1058 dir = NULL((void *)0);
1059 } else
1060 file = NULL((void *)0);
1061 if (file != NULL((void *)0)) {
1062 FILE *fp;
1063 char *str;
1064
1065 /* Set directory if needed */
1066 if (dir) {
1067 if (ftree_add(dir, 1) < 0)
1068 tar_usage();
1069 }
1070
1071 if (strcmp(file, "-") == 0)
1072 fp = stdin(&__sF[0]);
1073 else if ((fp = fopen(file, "r")) == NULL((void *)0)) {
1074 syswarn(1, errno(*__errno()), "Unable to open %s",
1075 file);
1076 tar_usage();
1077 }
1078 while ((str = get_line(fp)) != NULL((void *)0)) {
1079 if (ftree_add(str, 0) < 0)
1080 tar_usage();
1081 }
1082 if (ferror(fp)(!__isthreaded ? (((fp)->_flags & 0x0040) != 0) : (ferror
)(fp))
) {
1083 syswarn(1, errno(*__errno()),
1084 "Unable to read from %s",
1085 strcmp(file, "-") ? file : "stdin");
1086 tar_usage();
1087 }
1088 if (strcmp(file, "-") != 0)
1089 fclose(fp);
1090 } else if (strcmp(*argv, "-C") == 0) {
1091 if (*++argv == NULL((void *)0))
1092 break;
1093 if (ftree_add(*argv++, 1) < 0)
1094 tar_usage();
1095 havechd++;
1096 } else if (ftree_add(*argv++, 0) < 0)
1097 tar_usage();
1098 }
1099 /*
1100 * no read errors allowed on updates/append operation!
1101 */
1102 maxflt = 0;
1103 break;
1104 }
1105}
1106
1107int mkpath(char *);
1108
1109int
1110mkpath(path)
1111 char *path;
1112{
1113 struct stat sb;
1114 char *slash;
1115 int done = 0;
1116
1117 slash = path;
1118
1119 while (!done) {
1120 slash += strspn(slash, "/");
1121 slash += strcspn(slash, "/");
1122
1123 done = (*slash == '\0');
1124 *slash = '\0';
1125
1126 if (stat(path, &sb)) {
1127 if (errno(*__errno()) != ENOENT2 || mkdir(path, 0777)) {
1128 paxwarn(1, "%s", path);
1129 return (-1);
1130 }
1131 } else if (!S_ISDIR(sb.st_mode)((sb.st_mode & 0170000) == 0040000)) {
1132 syswarn(1, ENOTDIR20, "%s", path);
1133 return (-1);
1134 }
1135
1136 if (!done)
1137 *slash = '/';
1138 }
1139
1140 return (0);
1141}
1142
1143#ifndef NOCPIO
1144/*
1145 * cpio_options()
1146 * look at the user specified flags. set globals as required and check if
1147 * the user specified a legal set of flags. If not, complain and exit
1148 */
1149
1150static void
1151cpio_options(int argc, char **argv)
1152{
1153 const char *errstr;
1154 int c, list_only = 0;
1155 unsigned i;
1156 char *str;
1157 FILE *fp;
1158
1159 kflag = 1;
1160 pids = 1;
1161 pmode = 1;
1162 pmtime = 0;
1163 arcname = NULL((void *)0);
1164 dflag = 1;
1165 act = -1;
1166 nodirs = 1;
1167 while ((c=getopt(argc,argv,"abcdfijklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1)
1168 switch (c) {
1169 case 'a':
1170 /*
1171 * preserve access time on files read
1172 */
1173 tflag = 1;
1174 break;
1175 case 'b':
1176 /*
1177 * swap bytes and half-words when reading data
1178 */
1179 break;
1180 case 'c':
1181 /*
1182 * ASCII cpio header
1183 */
1184 frmt = &(fsub[F_ACPIO1]);
1185 break;
1186 case 'd':
1187 /*
1188 * create directories as needed
1189 */
1190 nodirs = 0;
1191 break;
1192 case 'f':
1193 /*
1194 * invert meaning of pattern list
1195 */
1196 cflag = 1;
1197 break;
1198 case 'i':
1199 /*
1200 * restore an archive
1201 */
1202 act = EXTRACT1;
1203 break;
1204 case 'j':
1205 /*
1206 * use bzip2. Non standard option.
1207 */
1208 gzip_program = BZIP2_CMD"bzip2";
1209 break;
1210 case 'k':
1211 break;
1212 case 'l':
1213 /*
1214 * use links instead of copies when possible
1215 */
1216 lflag = 1;
1217 break;
1218 case 'm':
1219 /*
1220 * preserve modification time
1221 */
1222 pmtime = 1;
1223 break;
1224 case 'o':
1225 /*
1226 * create an archive
1227 */
1228 act = ARCHIVE2;
1229 if (frmt == NULL((void *)0))
1230 frmt = &(fsub[F_CPIO3]);
1231 break;
1232 case 'p':
1233 /*
1234 * copy-pass mode
1235 */
1236 act = COPY4;
1237 break;
1238 case 'r':
1239 /*
1240 * interactively rename files
1241 */
1242 iflag = 1;
1243 break;
1244 case 's':
1245 /*
1246 * swap bytes after reading data
1247 */
1248 break;
1249 case 't':
1250 /*
1251 * list contents of archive
1252 */
1253 list_only = 1;
1254 break;
1255 case 'u':
1256 /*
1257 * replace newer files
1258 */
1259 kflag = 0;
1260 break;
1261 case 'v':
1262 /*
1263 * verbose operation mode
1264 */
1265 vflag = 1;
1266 break;
1267 case 'z':
1268 /*
1269 * use gzip. Non standard option.
1270 */
1271 gzip_program = GZIP_CMD"gzip";
1272 break;
1273 case 'A':
1274 /*
1275 * append mode
1276 */
1277 act = APPND3;
1278 break;
1279 case 'B':
1280 /*
1281 * Use 5120 byte block size
1282 */
1283 wrblksz = 5120;
1284 break;
1285 case 'C':
1286 /*
1287 * set block size in bytes
1288 */
1289 wrblksz = strtonum(optarg, 0, INT_MAX2147483647, &errstr);
1290 if (errstr) {
1291 paxwarn(1, "Invalid block size %s: %s",
1292 optarg, errstr);
1293 pax_usage();
1294 }
1295 break;
1296 case 'E':
1297 /*
1298 * file with patterns to extract or list
1299 */
1300 if ((fp = fopen(optarg, "r")) == NULL((void *)0)) {
1301 syswarn(1, errno(*__errno()), "Unable to open %s",
1302 optarg);
1303 cpio_usage();
1304 }
1305 while ((str = get_line(fp)) != NULL((void *)0)) {
1306 pat_add(str, NULL((void *)0));
1307 }
1308 if (ferror(fp)(!__isthreaded ? (((fp)->_flags & 0x0040) != 0) : (ferror
)(fp))
) {
1309 syswarn(1, errno(*__errno()),
1310 "Unable to read from %s", optarg);
1311 cpio_usage();
1312 }
1313 fclose(fp);
1314 break;
1315 case 'F':
1316 case 'I':
1317 case 'O':
1318 /*
1319 * filename where the archive is stored
1320 */
1321 if ((optarg[0] == '-') && (optarg[1]== '\0')) {
1322 /*
1323 * treat a - as stdin
1324 */
1325 arcname = NULL((void *)0);
1326 break;
1327 }
1328 arcname = optarg;
1329 break;
1330 case 'H':
1331 /*
1332 * specify an archive format on write
1333 */
1334 for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i)
1335 if (fsub[i].name != NULL((void *)0) &&
1336 strcmp(fsub[i].name, optarg) == 0)
1337 break;
1338 if (i < sizeof(fsub)/sizeof(FSUB)) {
1339 frmt = &fsub[i];
1340 break;
1341 }
1342 paxwarn(1, "Unknown -H format: %s", optarg);
1343 (void)fputs("cpio: Known -H formats are:", stderr(&__sF[2]));
1344 for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
1345 if (fsub[i].name != NULL((void *)0))
1346 (void)fprintf(stderr(&__sF[2]), " %s",
1347 fsub[i].name);
1348 (void)fputs("\n\n", stderr(&__sF[2]));
1349 cpio_usage();
1350 break;
1351 case 'L':
1352 /*
1353 * follow symbolic links
1354 */
1355 Lflag = 1;
1356 break;
1357 case 'S':
1358 /*
1359 * swap halfwords after reading data
1360 */
1361 break;
1362 case 'Z':
1363 /*
1364 * use compress. Non standard option.
1365 */
1366 gzip_program = COMPRESS_CMD"compress";
1367 break;
1368 case '6':
1369 /*
1370 * process Version 6 cpio format
1371 */
1372 frmt = &(fsub[F_OCPIO0]);
1373 break;
1374 case '?':
1375 default:
1376 cpio_usage();
1377 break;
1378 }
1379 argc -= optind;
1380 argv += optind;
1381
1382 /*
1383 * process the args as they are interpreted by the operation mode
1384 */
1385 switch (act) {
1386 case EXTRACT1:
1387 if (list_only) {
1388 act = LIST0;
1389
1390 /*
1391 * cpio is like pax: list to stderr
1392 * unless in list mode
1393 */
1394 listf = stdout(&__sF[1]);
1395 }
1396 while (*argv != NULL((void *)0))
1397 if (pat_add(*argv++, NULL((void *)0)) < 0)
1398 cpio_usage();
1399 break;
1400 case COPY4:
1401 if (*argv == NULL((void *)0)) {
1402 paxwarn(0, "Destination directory was not supplied");
1403 cpio_usage();
1404 }
1405 dirptr = *argv;
1406 if (mkpath(dirptr) < 0)
1407 cpio_usage();
1408 --argc;
1409 ++argv;
1410 /* FALL THROUGH */
1411 case ARCHIVE2:
1412 case APPND3:
1413 if (*argv != NULL((void *)0))
1414 cpio_usage();
1415 /*
1416 * no read errors allowed on updates/append operation!
1417 */
1418 maxflt = 0;
1419 while ((str = get_line(stdin(&__sF[0]))) != NULL((void *)0)) {
1420 ftree_add(str, 0);
1421 }
1422 if (ferror(stdin)(!__isthreaded ? ((((&__sF[0]))->_flags & 0x0040) !=
0) : (ferror)((&__sF[0])))
) {
1423 syswarn(1, errno(*__errno()), "Unable to read from %s",
1424 "stdin");
1425 cpio_usage();
1426 }
1427 break;
1428 default:
1429 cpio_usage();
1430 break;
1431 }
1432}
1433#endif /* !NOCPIO */
1434
1435/*
1436 * printflg()
1437 * print out those invalid flag sets found to the user
1438 */
1439
1440static void
1441printflg(unsigned int flg)
1442{
1443 int nxt;
1444 int pos = 0;
1445
1446 (void)fprintf(stderr(&__sF[2]),"%s: Invalid combination of options:", argv0);
1447 while ((nxt = ffs(flg)) != 0) {
1448 flg >>= nxt;
1449 pos += nxt;
1450 (void)fprintf(stderr(&__sF[2]), " -%c", flgch[pos-1]);
1451 }
1452 (void)putc('\n', stderr)(!__isthreaded ? __sputc('\n', (&__sF[2])) : (putc)('\n',
(&__sF[2])))
;
1453}
1454
1455/*
1456 * opt_next()
1457 * called by format specific options routines to get each format specific
1458 * flag and value specified with -o
1459 * Return:
1460 * pointer to next OPLIST entry or NULL (end of list).
1461 */
1462
1463OPLIST *
1464opt_next(void)
1465{
1466 OPLIST *opt;
1467
1468 if ((opt = ophead) != NULL((void *)0))
1469 ophead = ophead->fow;
1470 return(opt);
1471}
1472
1473/*
1474 * bad_opt()
1475 * generic routine used to complain about a format specific options
1476 * when the format does not support options.
1477 */
1478
1479int
1480bad_opt(void)
1481{
1482 OPLIST *opt;
1483
1484 if (ophead == NULL((void *)0))
1485 return(0);
1486 /*
1487 * print all we were given
1488 */
1489 paxwarn(1,"These format options are not supported");
1490 while ((opt = opt_next()) != NULL((void *)0))
1491 (void)fprintf(stderr(&__sF[2]), "\t%s = %s\n", opt->name, opt->value);
1492 pax_usage();
1493 return(0);
1494}
1495
1496/*
1497 * opt_add()
1498 * breaks the value supplied to -o into a option name and value. options
1499 * are given to -o in the form -o name-value,name=value
1500 * multiple -o may be specified.
1501 * Return:
1502 * 0 if format in name=value format, -1 if -o is passed junk
1503 */
1504
1505int
1506opt_add(const char *str)
1507{
1508 OPLIST *opt;
1509 char *frpt;
1510 char *pt;
1511 char *endpt;
1512 char *dstr;
1513
1514 if ((str == NULL((void *)0)) || (*str == '\0')) {
1515 paxwarn(0, "Invalid option name");
1516 return(-1);
1517 }
1518 if ((dstr = strdup(str)) == NULL((void *)0)) {
1519 paxwarn(0, "Unable to allocate space for option list");
1520 return(-1);
1521 }
1522 frpt = endpt = dstr;
Although the value stored to 'endpt' is used in the enclosing expression, the value is never actually read from 'endpt'
1523
1524 /*
1525 * break into name and values pieces and stuff each one into a
1526 * OPLIST structure. When we know the format, the format specific
1527 * option function will go through this list
1528 */
1529 while ((frpt != NULL((void *)0)) && (*frpt != '\0')) {
1530 if ((endpt = strchr(frpt, ',')) != NULL((void *)0))
1531 *endpt = '\0';
1532 if ((pt = strchr(frpt, '=')) == NULL((void *)0)) {
1533 paxwarn(0, "Invalid options format");
1534 free(dstr);
1535 return(-1);
1536 }
1537 if ((opt = malloc(sizeof(OPLIST))) == NULL((void *)0)) {
1538 paxwarn(0, "Unable to allocate space for option list");
1539 free(dstr);
1540 return(-1);
1541 }
1542 dstr = NULL((void *)0); /* parts of string going onto the OPLIST */
1543 *pt++ = '\0';
1544 opt->name = frpt;
1545 opt->value = pt;
1546 opt->fow = NULL((void *)0);
1547 if (endpt != NULL((void *)0))
1548 frpt = endpt + 1;
1549 else
1550 frpt = NULL((void *)0);
1551 if (ophead == NULL((void *)0)) {
1552 optail = ophead = opt;
1553 continue;
1554 }
1555 optail->fow = opt;
1556 optail = opt;
1557 }
1558 free(dstr);
1559 return(0);
1560}
1561
1562/*
1563 * str_offt()
1564 * Convert an expression of the following forms to an off_t > 0.
1565 * 1) A positive decimal number.
1566 * 2) A positive decimal number followed by a b (mult by 512).
1567 * 3) A positive decimal number followed by a k (mult by 1024).
1568 * 4) A positive decimal number followed by a m (mult by 512).
1569 * 5) A positive decimal number followed by a w (mult by sizeof int)
1570 * 6) Two or more positive decimal numbers (with/without k,b or w).
1571 * separated by x (also * for backwards compatibility), specifying
1572 * the product of the indicated values.
1573 * Return:
1574 * 0 for an error, a positive value o.w.
1575 */
1576
1577static off_t
1578str_offt(char *val)
1579{
1580 char *expr;
1581 off_t num, t;
1582
1583 num = strtoll(val, &expr, 0);
1584 if ((num == LLONG_MAX9223372036854775807LL) || (num <= 0) || (expr == val))
1585 return(0);
1586
1587 switch (*expr) {
1588 case 'b':
1589 t = num;
1590 num *= 512;
1591 if (t > num)
1592 return(0);
1593 ++expr;
1594 break;
1595 case 'k':
1596 t = num;
1597 num *= 1024;
1598 if (t > num)
1599 return(0);
1600 ++expr;
1601 break;
1602 case 'm':
1603 t = num;
1604 num *= 1048576;
1605 if (t > num)
1606 return(0);
1607 ++expr;
1608 break;
1609 case 'w':
1610 t = num;
1611 num *= sizeof(int);
1612 if (t > num)
1613 return(0);
1614 ++expr;
1615 break;
1616 }
1617
1618 switch (*expr) {
1619 case '\0':
1620 break;
1621 case '*':
1622 case 'x':
1623 t = num;
1624 num *= str_offt(expr + 1);
1625 if (t > num)
1626 return(0);
1627 break;
1628 default:
1629 return(0);
1630 }
1631 return(num);
1632}
1633
1634char *
1635get_line(FILE *f)
1636{
1637 char *str = NULL((void *)0);
1638 size_t size = 0;
1639 ssize_t len;
1640
1641 do {
1642 len = getline(&str, &size, f);
1643 if (len == -1) {
1644 free(str);
1645 return NULL((void *)0);
1646 }
1647 if (str[len - 1] == '\n')
1648 str[len - 1] = '\0';
1649 } while (str[0] == '\0');
1650 return str;
1651}
1652
1653/*
1654 * no_op()
1655 * for those option functions where the archive format has nothing to do.
1656 * Return:
1657 * 0
1658 */
1659
1660static int
1661no_op(void)
1662{
1663 return(0);
1664}
1665
1666/*
1667 * pax_usage()
1668 * print the usage summary to the user
1669 */
1670
1671void
1672pax_usage(void)
1673{
1674 (void)fputs(
1675 "usage: pax [-0cdjnOvz] [-E limit] [-f archive] [-G group] [-s replstr]\n"
1676 " [-T range] [-U user] [pattern ...]\n"
1677 " pax -r [-0cDdijknOuvYZz] [-E limit] [-f archive] [-G group] [-o options]\n"
1678 " [-p string] [-s replstr] [-T range] [-U user] [pattern ...]\n"
1679 " pax -w [-0adHijLOPtuvXz] [-B bytes] [-b blocksize] [-f archive]\n"
1680 " [-G group] [-o options] [-s replstr] [-T range] [-U user]\n"
1681 " [-x format] [file ...]\n"
1682 " pax -rw [-0DdHikLlnOPtuvXYZ] [-G group] [-p string] [-s replstr]\n"
1683 " [-T range] [-U user] [file ...] directory\n",
1684 stderr(&__sF[2]));
1685 exit(1);
1686}
1687
1688/*
1689 * tar_usage()
1690 * print the usage summary to the user
1691 */
1692
1693void
1694tar_usage(void)
1695{
1696 (void)fputs(
1697 "usage: tar {crtux}[014578befHhjLmNOoPpqsvwXZz]\n"
1698 " [blocking-factor | archive | replstr] [-C directory] [-I file]\n"
1699 " [file ...]\n"
1700 " tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n"
1701 " [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n",
1702 stderr(&__sF[2]));
1703 exit(1);
1704}
1705
1706#ifndef NOCPIO
1707/*
1708 * cpio_usage()
1709 * print the usage summary to the user
1710 */
1711
1712void
1713cpio_usage(void)
1714{
1715 (void)fputs(
1716 "usage: cpio -o [-AaBcjLvZz] [-C bytes] [-F archive] [-H format]\n"
1717 " [-O archive] < name-list [> archive]\n"
1718 " cpio -i [-6BbcdfjmrSstuvZz] [-C bytes] [-E file] [-F archive] [-H format]\n"
1719 " [-I archive] [pattern ...] [< archive]\n"
1720 " cpio -p [-adLlmuv] destination-directory < name-list\n",
1721 stderr(&__sF[2]));
1722 exit(1);
1723}
1724#endif /* !NOCPIO */
1725
1726#ifndef SMALL
1727static int
1728compress_id(char *blk, int size)
1729{
1730 if (size >= 2 && blk[0] == '\037' && blk[1] == '\235') {
1731 paxwarn(0, "input compressed with %s; use the -%c option"
1732 " to decompress it", "compress", 'Z');
1733 exit(1);
1734 }
1735 return (-1);
1736}
1737
1738static int
1739gzip_id(char *blk, int size)
1740{
1741 if (size >= 2 && blk[0] == '\037' && blk[1] == '\213') {
1742 paxwarn(0, "input compressed with %s; use the -%c option"
1743 " to decompress it", "gzip", 'z');
1744 exit(1);
1745 }
1746 return (-1);
1747}
1748
1749static int
1750bzip2_id(char *blk, int size)
1751{
1752 if (size >= 3 && blk[0] == 'B' && blk[1] == 'Z' && blk[2] == 'h') {
1753 paxwarn(0, "input compressed with %s; use the -%c option"
1754 " to decompress it", "bzip2", 'j');
1755 exit(1);
1756 }
1757 return (-1);
1758}
1759
1760static int
1761xz_id(char *blk, int size)
1762{
1763 if (size >= 6 && memcmp(blk, "\xFD\x37\x7A\x58\x5A", 6) == 0) {
1764 paxwarn(0, "input compressed with xz");
1765 exit(1);
1766 }
1767 return (-1);
1768}
1769#endif /* !SMALL */