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