Bug Summary

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