source: trunk/essentials/app-arch/cpio/src/main.c

Last change on this file was 3332, checked in by bird, 18 years ago

cpio 2.7

File size: 24.1 KB
Line 
1/* main.c - main program and argument processing for cpio.
2 Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with this program; if not, write to the Free
17 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 USA. */
19
20/* Written by Phil Nelson <phil@cs.wwu.edu>,
21 David MacKenzie <djm@gnu.ai.mit.edu>,
22 John Oleynick <juo@klinzhai.rutgers.edu>,
23 and Sergey Poznyakoff <gray@mirddin.farlep.net> */
24
25#include <system.h>
26#include <paxlib.h>
27
28#include <stdio.h>
29#include <getopt.h>
30#include <argp.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33
34#ifdef HAVE_LOCALE_H
35# include <locale.h>
36#endif
37
38#include "filetypes.h"
39#include "cpiohdr.h"
40#include "dstring.h"
41#include "extern.h"
42#include <rmt.h>
43#include <localedir.h>
44
45enum cpio_options {
46 NO_ABSOLUTE_FILENAMES_OPTION=256,
47 ABSOLUTE_FILENAMES_OPTION,
48 NO_PRESERVE_OWNER_OPTION,
49 ONLY_VERIFY_CRC_OPTION,
50 RENAME_BATCH_FILE_OPTION,
51 RSH_COMMAND_OPTION,
52 QUIET_OPTION,
53 SPARSE_OPTION,
54 FORCE_LOCAL_OPTION,
55 DEBUG_OPTION,
56 BLOCK_SIZE_OPTION,
57 TO_STDOUT_OPTION,
58
59 HANG_OPTION,
60 USAGE_OPTION,
61 LICENSE_OPTION,
62 VERSION_OPTION
63};
64
65const char *argp_program_version = "cpio (" PACKAGE_NAME ") " VERSION;
66const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
67static char doc[] = N_("GNU `cpio' copies files to and from archives\n\
68\n\
69Examples:\n\
70 # Copy files named in name-list to the archive\n\
71 cpio -o < name-list [> archive]\n\
72 # Extract files from the archive\n\
73 cpio -i [< archive]\n\
74 # Copy files named in name-list to destination-directory\n\
75 cpio -p destination-directory < name-list\n");
76
77/* Print usage error message and exit with error. */
78
79#define CHECK_USAGE(cond, opt, mode_opt) \
80 if (cond) \
81 ERROR((PAXEXIT_FAILURE, 0, _("%s is meaningless with %s"), opt, mode_opt));
82
83static struct argp_option options[] = {
84 /* ********** */
85#define GRID 10
86 {NULL, 0, NULL, 0,
87 N_("Main operation mode:"), GRID },
88 {"create", 'o', 0, 0,
89 N_("Create the archive (run in copy-out mode)"), GRID },
90 {"extract", 'i', 0, 0,
91 N_("Extract files from an archive (run in copy-in mode)"), GRID },
92 {"pass-through", 'p', 0, 0,
93 N_("Run in copy-pass mode"), GRID },
94 {"list", 't', 0, 0,
95 N_("Print a table of contents of the input"), GRID },
96#undef GRID
97
98 /* ********** */
99#define GRID 100
100 {NULL, 0, NULL, 0,
101 N_("Operation modifiers valid in any mode:"), GRID },
102
103 {"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0,
104 N_("Use this FILE-NAME instead of standard input or output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
105 {"force-local", FORCE_LOCAL_OPTION, 0, 0,
106 N_("Archive file is local, even if its name contains colons"), GRID+1 },
107 {"format", 'H', N_("FORMAT"), 0,
108 N_("Use given archive FORMAT"), GRID+1 },
109 {NULL, 'B', NULL, 0,
110 N_("Set the I/O block size to 5120 bytes"), GRID+1 },
111 {"block-size", BLOCK_SIZE_OPTION, N_("BLOCK-SIZE"), 0,
112 N_("Set the I/O block size to BLOCK-SIZE * 512 bytes"), GRID+1 },
113 {NULL, 'c', NULL, 0,
114 N_("Use the old portable (ASCII) archive format"), GRID+1 },
115 {"dot", 'V', NULL, 0,
116 N_("Print a \".\" for each file processed"), GRID+1 },
117 {"io-size", 'C', N_("NUMBER"), 0,
118 N_("Set the I/O block size to the given NUMBER of bytes"), GRID+1 },
119 {"message", 'M', N_("STRING"), 0,
120 N_("Print STRING when the end of a volume of the backup media is reached"),
121 GRID+1 },
122 {"nonmatching", 'f', 0, 0,
123 N_("Only copy files that do not match any of the given patterns"), GRID+1 },
124 {"numeric-uid-gid", 'n', 0, 0,
125 N_("In the verbose table of contents listing, show numeric UID and GID"),
126 GRID+1 },
127 {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
128 N_("Use remote COMMAND instead of rsh"), GRID+1 },
129 {"quiet", QUIET_OPTION, NULL, 0,
130 N_("Do not print the number of blocks copied"), GRID+1 },
131 {"verbose", 'v', NULL, 0,
132 N_("Verbosely list the files processed"), GRID+1 },
133#ifdef DEBUG_CPIO
134 {"debug", DEBUG_OPTION, NULL, 0,
135 N_("Enable debugging info"), GRID+1 },
136#endif
137 {"warning", 'W', N_("FLAG"), 0,
138 N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 'all'. Multiple options accumulate."), GRID+1 },
139#undef GRID
140
141 /* ********** */
142#define GRID 200
143 {NULL, 0, NULL, 0,
144 N_("Operation modifiers valid only in copy-in mode:"), GRID },
145 {"pattern-file", 'E', N_("FILE"), 0,
146 N_("Read additional patterns specifying filenames to extract or list from FILE"), 210},
147 {"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0,
148 N_("When reading a CRC format archive, only verify the CRC's of each file in the archive, don't actually extract the files"), 210},
149 {"rename", 'r', 0, 0,
150 N_("Interactively rename files"), GRID+1 },
151 {"rename-batch-file", RENAME_BATCH_FILE_OPTION, N_("FILE"), OPTION_HIDDEN,
152 "", GRID+1 },
153 {"swap", 'b', NULL, 0,
154 N_("Swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS"), GRID+1 },
155 {"swap-bytes", 's', NULL, 0,
156 N_("Swap the bytes of each halfword in the files"), GRID+1 },
157 {"swap-halfwords", 'S', NULL, 0,
158 N_("Swap the halfwords of each word (4 bytes) in the files"),
159 GRID+1 },
160 {"to-stdout", TO_STDOUT_OPTION, NULL, 0,
161 N_("Extract files to standard output"), GRID+1 },
162#undef GRID
163
164 /* ********** */
165#define GRID 300
166 {NULL, 0, NULL, 0,
167 N_("Operation modifiers valid only in copy-out mode:"), GRID },
168 {"append", 'A', 0, 0,
169 N_("Append to an existing archive."), GRID+1 },
170 {NULL, 'O', N_("[[USER@]HOST:]FILE-NAME"), 0,
171 N_("Archive filename to use instead of standard output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
172#undef GRID
173
174 /* ********** */
175#define GRID 400
176 {NULL, 0, NULL, 0,
177 N_("Operation modifiers valid only in copy-pass mode:"), GRID},
178 {"link", 'l', 0, 0,
179 N_("Link files instead of copying them, when possible"), GRID+1 },
180
181#undef GRID
182
183 /* ********** */
184#define GRID 500
185 {NULL, 0, NULL, 0,
186 N_("Operation modifiers valid in copy-in and copy-out modes:"), GRID },
187 {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0,
188 N_("Do not strip file system prefix components from the file names"),
189 GRID+1 },
190 {"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0,
191 N_("Create all files relative to the current directory"), GRID+1 },
192#undef GRID
193 /* ********** */
194#define GRID 600
195 {NULL, 0, NULL, 0,
196 N_("Operation modifiers valid in copy-out and copy-pass modes:"), GRID },
197 {"null", '0', 0, 0,
198 N_("A list of filenames is terminated by a null character instead of a newline"), GRID+1 },
199 {NULL, 'I', N_("[[USER@]HOST:]FILE-NAME"), 0,
200 N_("Archive filename to use instead of standard input. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
201 {"dereference", 'L', 0, 0,
202 N_("Dereference symbolic links (copy the files that they point to instead of copying the links)."), GRID+1 },
203 {"owner", 'R', N_("[USER][:.][GROUP]"), 0,
204 N_("Set the ownership of all files created to the specified USER and/or GROUP"), GRID+1 },
205 {"reset-access-time", 'a', NULL, 0,
206 N_("Reset the access times of files after reading them"), GRID+1 },
207
208#undef GRID
209 /* ********** */
210#define GRID 700
211 {NULL, 0, NULL, 0,
212 N_("Operation modifiers valid in copy-in and copy-pass modes:"), GRID },
213 {"preserve-modification-time", 'm', 0, 0,
214 N_("Retain previous file modification times when creating files"), GRID+1 },
215 {"make-directories", 'd', 0, 0,
216 N_("Create leading directories where needed"), GRID+1 },
217 {"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
218 N_("Do not change the ownership of the files"), GRID+1 },
219 {"unconditional", 'u', NULL, 0,
220 N_("Replace all files unconditionally"), GRID+1 },
221 {"sparse", SPARSE_OPTION, NULL, 0,
222 N_("Write files with large blocks of zeros as sparse files"), GRID+1 },
223#undef GRID
224
225 /* ********** */
226#define GRID 800
227 {NULL, 0, NULL, 0,
228 N_("Informative options:"), GRID },
229
230 {"help", '?', 0, 0, N_("Give this help list"), -1},
231 {"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1},
232 {"license", LICENSE_OPTION, 0, 0, N_("Print license and exit"), -1},
233 {"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1},
234 /* FIXME -V (--dot) conflicts with the default short option for
235 --version */
236 {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
237 N_("hang for SECS seconds (default 3600)"), 0},
238#undef GRID
239 {0, 0, 0, 0}
240};
241
242static char *input_archive_name = 0;
243static char *output_archive_name = 0;
244
245static void
246license ()
247{
248 printf ("%s (%s) %s\n%s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION,
249 "Copyright (C) 2004 Free Software Foundation, Inc.\n");
250 printf (_(" GNU cpio is free software; you can redistribute it and/or modify\n"
251 " it under the terms of the GNU General Public License as published by\n"
252 " the Free Software Foundation; either version 2 of the License, or\n"
253 " (at your option) any later version.\n"
254 "\n"
255 " GNU cpio is distributed in the hope that it will be useful,\n"
256 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
257 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
258 " GNU General Public License for more details.\n"
259 "\n"
260 " You should have received a copy of the GNU General Public License\n"
261 " along with GNU cpio; if not, write to the Free Software Foundation,\n"
262 " Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n"));
263 exit (0);
264}
265
266static int
267warn_control (char *arg)
268{
269 static struct warn_tab {
270 char *name;
271 int flag;
272 } warn_tab[] = {
273 { "none", CPIO_WARN_ALL },
274 { "truncate", CPIO_WARN_TRUNCATE },
275 { "all", CPIO_WARN_ALL },
276 { NULL }
277 };
278 struct warn_tab *wt;
279 int offset = 0;
280
281 if (strcmp (arg, "none") == 0)
282 {
283 warn_option = 0;
284 return 0;
285 }
286
287 if (strlen (arg) > 2 && memcmp (arg, "no-", 3) == 0)
288 offset = 3;
289
290 for (wt = warn_tab; wt->name; wt++)
291 if (strcmp (arg + offset, wt->name) == 0)
292 {
293 if (offset)
294 warn_option &= ~wt->flag;
295 else
296 warn_option |= wt->flag;
297 return 0;
298 }
299
300 return 1;
301}
302
303static error_t
304parse_opt (int key, char *arg, struct argp_state *state)
305{
306 static volatile int _argp_hang;
307 switch (key)
308 {
309 case '0': /* Read null-terminated filenames. */
310 name_end = '\0';
311 break;
312
313 case 'a': /* Reset access times. */
314 reset_time_flag = true;
315 break;
316
317 case 'A': /* Append to the archive. */
318 append_flag = true;
319 break;
320
321 case 'b': /* Swap bytes and halfwords. */
322 swap_bytes_flag = true;
323 swap_halfwords_flag = true;
324 break;
325
326 case 'B': /* Set block size to 5120. */
327 io_block_size = 5120;
328 break;
329
330 case BLOCK_SIZE_OPTION: /* --block-size */
331 io_block_size = atoi (arg);
332 if (io_block_size < 1)
333 error (2, 0, _("invalid block size"));
334 io_block_size *= 512;
335 break;
336
337 case 'c': /* Use the old portable ASCII format. */
338 if (archive_format != arf_unknown)
339 error (0, EXIT_FAILURE, _("Archive format multiply defined"));
340#ifdef SVR4_COMPAT
341 archive_format = arf_newascii; /* -H newc. */
342#else
343 archive_format = arf_oldascii; /* -H odc. */
344#endif
345 break;
346
347 case 'C': /* Block size. */
348 io_block_size = atoi (arg);
349 if (io_block_size < 1)
350 error (2, 0, _("invalid block size"));
351 break;
352
353 case 'd': /* Create directories where needed. */
354 create_dir_flag = true;
355 break;
356
357 case 'f': /* Only copy files not matching patterns. */
358 copy_matching_files = false;
359 break;
360
361 case 'E': /* Pattern file name. */
362 pattern_file_name = arg;
363 break;
364
365 case 'F': /* Archive file name. */
366 archive_name = arg;
367 break;
368
369 case 'H': /* Header format name. */
370 if (archive_format != arf_unknown)
371 error (PAXEXIT_FAILURE, 0, _("Archive format multiply defined"));
372 if (!strcasecmp (arg, "crc"))
373 archive_format = arf_crcascii;
374 else if (!strcasecmp (arg, "newc"))
375 archive_format = arf_newascii;
376 else if (!strcasecmp (arg, "odc"))
377 archive_format = arf_oldascii;
378 else if (!strcasecmp (arg, "bin"))
379 archive_format = arf_binary;
380 else if (!strcasecmp (arg, "ustar"))
381 archive_format = arf_ustar;
382 else if (!strcasecmp (arg, "tar"))
383 archive_format = arf_tar;
384 else if (!strcasecmp (arg, "hpodc"))
385 archive_format = arf_hpoldascii;
386 else if (!strcasecmp (arg, "hpbin"))
387 archive_format = arf_hpbinary;
388 else
389 error (2, 0, _("\
390invalid archive format `%s'; valid formats are:\n\
391crc newc odc bin ustar tar (all-caps also recognized)"), arg);
392 break;
393
394 case 'i': /* Copy-in mode. */
395 if (copy_function != 0)
396 error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
397 copy_function = process_copy_in;
398 break;
399
400 case 'I': /* Input archive file name. */
401 input_archive_name = arg;
402 break;
403
404 case 'k': /* Handle corrupted archives. We always handle
405 corrupted archives, but recognize this
406 option for compatability. */
407 break;
408
409 case 'l': /* Link files when possible. */
410 link_flag = true;
411 break;
412
413 case 'L': /* Dereference symbolic links. */
414 xstat = stat;
415 break;
416
417 case 'm': /* Retain previous file modify times. */
418 retain_time_flag = true;
419 break;
420
421 case 'M': /* New media message. */
422 set_new_media_message (arg);
423 break;
424
425 case 'n': /* Long list owner and group as numbers. */
426 numeric_uid = true;
427 break;
428
429 case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
430 no_abs_paths_flag = true;
431 break;
432
433 case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */
434 no_abs_paths_flag = false;
435 break;
436
437 case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
438 if (set_owner_flag || set_group_flag)
439 error (PAXEXIT_FAILURE, 0,
440 _("--no-preserve-owner cannot be used with --owner"));
441 no_chown_flag = true;
442 break;
443
444 case 'o': /* Copy-out mode. */
445 if (copy_function != 0)
446 error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
447 copy_function = process_copy_out;
448 break;
449
450 case 'O': /* Output archive file name. */
451 output_archive_name = arg;
452 break;
453
454 case ONLY_VERIFY_CRC_OPTION:
455 only_verify_crc_flag = true;
456 break;
457
458 case 'p': /* Copy-pass mode. */
459 if (copy_function != 0)
460 error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
461 copy_function = process_copy_pass;
462 break;
463
464 case RSH_COMMAND_OPTION:
465 rsh_command_option = arg;
466 break;
467
468 case 'r': /* Interactively rename. */
469 rename_flag = true;
470 break;
471
472 case RENAME_BATCH_FILE_OPTION:
473 rename_batch_file = arg;
474 break;
475
476 case QUIET_OPTION:
477 quiet_flag = true;
478 break;
479
480 case 'R': /* Set the owner. */
481 if (no_chown_flag)
482 error (PAXEXIT_FAILURE, 0,
483 _("--owner cannot be used with --no-preserve-owner"));
484 else
485 {
486 char *e, *u, *g;
487
488 e = parse_user_spec (arg, &set_owner, &set_group, &u, &g);
489 if (e)
490 error (PAXEXIT_FAILURE, 0, "%s: %s", arg, e);
491 if (u)
492 {
493 free (u);
494 set_owner_flag = true;
495 }
496 if (g)
497 {
498 free (g);
499 set_group_flag = true;
500 }
501 }
502 break;
503
504 case 's': /* Swap bytes. */
505 swap_bytes_flag = true;
506 break;
507
508 case 'S': /* Swap halfwords. */
509 swap_halfwords_flag = true;
510 break;
511
512 case 't': /* Only print a list. */
513 table_flag = true;
514 break;
515
516 case 'u': /* Replace all! Unconditionally! */
517 unconditional_flag = true;
518 break;
519
520 case 'v': /* Verbose! */
521 verbose_flag = true;
522 break;
523
524 case 'V': /* Print `.' for each file. */
525 dot_flag = true;
526 break;
527
528 case 'W':
529 if (warn_control (arg))
530 argp_error (state, _("Invalid value for --warning option: %s"), arg);
531 break;
532
533 case SPARSE_OPTION:
534 sparse_flag = true;
535 break;
536
537 case FORCE_LOCAL_OPTION:
538 force_local_option = 1;
539 break;
540
541#ifdef DEBUG_CPIO
542 case DEBUG_OPTION:
543 debug_flag = true;
544 break;
545#endif
546
547 case TO_STDOUT_OPTION:
548 to_stdout_option = true;
549 break;
550
551 case HANG_OPTION:
552 _argp_hang = atoi (arg ? arg : "3600");
553 while (_argp_hang-- > 0)
554 sleep (1);
555 break;
556
557 case '?':
558 argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
559 break;
560
561 case USAGE_OPTION:
562 argp_state_help (state, state->out_stream,
563 ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
564 break;
565
566 case VERSION_OPTION:
567 fprintf (state->out_stream, "%s\n", argp_program_version);
568 exit (0);
569
570 case LICENSE_OPTION:
571 license ();
572 break;
573
574 default:
575 return ARGP_ERR_UNKNOWN;
576 }
577 return 0;
578}
579
580static struct argp argp = {
581 options,
582 parse_opt,
583 N_("[destination-directory]"),
584 doc,
585 NULL,
586 NULL,
587 NULL
588};
589
590/* Process the arguments. Set all options and set up the copy pass
591 directory or the copy in patterns. */
592
593void
594process_args (int argc, char *argv[])
595{
596 void (*copy_in) (); /* Work around for pcc bug. */
597 void (*copy_out) ();
598 int index;
599
600 if (argc < 2)
601 error (PAXEXIT_FAILURE, 0,
602 _("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
603 program_name, program_name);
604
605 xstat = lstat;
606
607 if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, &index, NULL))
608 exit (1);
609
610 /* Do error checking and look at other args. */
611
612 if (copy_function == 0)
613 {
614 if (table_flag)
615 copy_function = process_copy_in;
616 else
617 error (PAXEXIT_FAILURE, 0,
618 _("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
619 program_name, program_name);
620 }
621
622 /* Work around for pcc bug. */
623 copy_in = process_copy_in;
624 copy_out = process_copy_out;
625
626 if (copy_function == copy_in)
627 {
628 archive_des = 0;
629 CHECK_USAGE(link_flag, "--link", "--extract");
630 CHECK_USAGE(reset_time_flag, "--reset", "--extract");
631 CHECK_USAGE(xstat != lstat, "--dereference", "--extract");
632 CHECK_USAGE(append_flag, "--append", "--extract");
633 CHECK_USAGE(output_archive_name, "-O", "--extract");
634 if (to_stdout_option)
635 {
636 CHECK_USAGE(create_dir_flag, "--make-directories", "--to-stdout");
637 CHECK_USAGE(rename_flag, "--rename", "--to-stdout");
638 CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--to-stdout");
639 CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--to-stdout");
640 CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
641 "--to-stdout");
642 }
643
644 if (archive_name && input_archive_name)
645 error (PAXEXIT_FAILURE, 0,
646 _("Both -I and -F are used in copy-in mode"));
647
648 if (archive_format == arf_crcascii)
649 crc_i_flag = true;
650 num_patterns = argc - index;
651 save_patterns = &argv[index];
652 if (input_archive_name)
653 archive_name = input_archive_name;
654 }
655 else if (copy_function == copy_out)
656 {
657 if (index != argc)
658 error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
659
660 archive_des = 1;
661 CHECK_USAGE(create_dir_flag, "--make-directories", "--create");
662 CHECK_USAGE(rename_flag, "--rename", "--create");
663 CHECK_USAGE(table_flag, "--list", "--create");
664 CHECK_USAGE(unconditional_flag, "--unconditional", "--create");
665 CHECK_USAGE(link_flag, "--link", "--create");
666 CHECK_USAGE(sparse_flag, "--sparse", "--create");
667 CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
668 "--create");
669 CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create");
670 CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--create");
671 CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create");
672 CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
673 "--create");
674 CHECK_USAGE(to_stdout_option, "--to-stdout", "--create");
675
676 if (append_flag && !(archive_name || output_archive_name))
677 error (PAXEXIT_FAILURE, 0,
678 _("--append is used but no archive file name is given (use -F or -O options)"));
679
680 CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
681 CHECK_USAGE(input_archive_name, "-I", "--create");
682 if (archive_name && output_archive_name)
683 error (PAXEXIT_FAILURE, 0,
684 _("Both -O and -F are used in copy-out mode"));
685
686 if (archive_format == arf_unknown)
687 archive_format = arf_binary;
688 if (output_archive_name)
689 archive_name = output_archive_name;
690 }
691 else
692 {
693 /* Copy pass. */
694 if (index != argc - 1)
695 error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
696
697 if (archive_format != arf_unknown)
698 error (PAXEXIT_FAILURE, 0,
699 _("Archive format is not specified in copy-pass mode (use --format option)"));
700
701 CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
702 CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
703 "--pass-through");
704 CHECK_USAGE(table_flag, "--list", "--pass-through");
705 CHECK_USAGE(rename_flag, "--rename", "--pass-through");
706 CHECK_USAGE(append_flag, "--append", "--pass-through");
707 CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
708 CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames",
709 "--pass-through");
710 CHECK_USAGE(no_abs_paths_flag, "--absolute-pathnames",
711 "--pass-through");
712 CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
713
714 directory_name = argv[index];
715 }
716
717 if (archive_name)
718 {
719 if (copy_function != copy_in && copy_function != copy_out)
720 error (PAXEXIT_FAILURE, 0,
721 _("-F can be used only with --create or --extract"));
722 archive_des = open_archive (archive_name);
723 if (archive_des < 0)
724 error (PAXEXIT_FAILURE, errno, _("Cannot open %s"),
725 quotearg_colon (archive_name));
726 }
727
728 /* Prevent SysV non-root users from giving away files inadvertantly.
729 This happens automatically on BSD, where only root can give
730 away files. */
731 if (set_owner_flag == false && set_group_flag == false && geteuid ())
732 no_chown_flag = true;
733}
734
735/* Initialize the input and output buffers to their proper size and
736 initialize all variables associated with the input and output
737 buffers. */
738
739void
740initialize_buffers ()
741{
742 int in_buf_size, out_buf_size;
743
744 if (copy_function == process_copy_in)
745 {
746 /* Make sure the input buffer can always hold 2 blocks and that it
747 is big enough to hold 1 tar record (512 bytes) even if it
748 is not aligned on a block boundary. The extra buffer space
749 is needed by process_copyin and peek_in_buf to automatically
750 figure out what kind of archive it is reading. */
751 if (io_block_size >= 512)
752 in_buf_size = 2 * io_block_size;
753 else
754 in_buf_size = 1024;
755 out_buf_size = DISK_IO_BLOCK_SIZE;
756 }
757 else if (copy_function == process_copy_out)
758 {
759 in_buf_size = DISK_IO_BLOCK_SIZE;
760 out_buf_size = io_block_size;
761 }
762 else
763 {
764 in_buf_size = DISK_IO_BLOCK_SIZE;
765 out_buf_size = DISK_IO_BLOCK_SIZE;
766 }
767
768 input_buffer = (char *) xmalloc (in_buf_size);
769 in_buff = input_buffer;
770 input_buffer_size = in_buf_size;
771 input_size = 0;
772 input_bytes = 0;
773
774 output_buffer = (char *) xmalloc (out_buf_size);
775 out_buff = output_buffer;
776 output_size = 0;
777 output_bytes = 0;
778}
779
780int
781main (int argc, char *argv[])
782{
783 setlocale (LC_ALL, "");
784 bindtextdomain (PACKAGE, LOCALEDIR);
785 textdomain (PACKAGE);
786
787 program_name = argv[0];
788
789 process_args (argc, argv);
790
791 initialize_buffers ();
792
793 (*copy_function) ();
794
795 if (archive_des >= 0 && rmtclose (archive_des) == -1)
796 error (1, errno, _("error closing archive"));
797
798 exit (0);
799}
Note: See TracBrowser for help on using the repository browser.