📄 tar.c
字号:
case WILDCARDS_OPTION: args->wildcards = enable_wildcards; break; case WILDCARDS_MATCH_SLASH_OPTION: args->matching_flags &= ~ FNM_FILE_NAME; break; case NO_RECURSION_OPTION: recursion_option = 0; break; case NO_SAME_OWNER_OPTION: same_owner_option = -1; break; case NO_SAME_PERMISSIONS_OPTION: same_permissions_option = -1; break; case RECURSION_OPTION: recursion_option = FNM_LEADING_DIR; break; case SAME_OWNER_OPTION: same_owner_option = 1; break; case UNQUOTE_OPTION: unquote_option = true; break; case NO_UNQUOTE_OPTION: unquote_option = false; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':#ifdef DEVICE_PREFIX { int device = key - '0'; int density; static char buf[sizeof DEVICE_PREFIX + 10]; char *cursor; if (arg[1]) argp_error (state, _("Malformed density argument: %s"), quote (arg)); strcpy (buf, DEVICE_PREFIX); cursor = buf + strlen (buf);#ifdef DENSITY_LETTER sprintf (cursor, "%d%c", device, arg[0]);#else /* not DENSITY_LETTER */ switch (arg[0]) { case 'l': device += LOW_DENSITY_NUM; break; case 'm': device += MID_DENSITY_NUM; break; case 'h': device += HIGH_DENSITY_NUM; break; default: argp_error (state, _("Unknown density: `%c'"), arg[0]); } sprintf (cursor, "%d", device);#endif /* not DENSITY_LETTER */ if (archive_names == allocated_archive_names) archive_name_array = x2nrealloc (archive_name_array, &allocated_archive_names, sizeof (archive_name_array[0])); archive_name_array[archive_names++] = xstrdup (buf); } break;#else /* not DEVICE_PREFIX */ argp_error (state, _("Options `-[0-7][lmh]' not supported by *this* tar"));#endif /* not DEVICE_PREFIX */ case '?': tar_help (state); close_stdout (); exit (0); case USAGE_OPTION: argp_state_help (state, state->out_stream, ARGP_HELP_USAGE); close_stdout (); exit (0); case VERSION_OPTION: version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION, "John Gilmore", "Jay Fenlason", (char *) NULL); close_stdout (); exit (0); case HANG_OPTION: _argp_hang = atoi (arg ? arg : "3600"); while (_argp_hang-- > 0) sleep (1); break; default: return ARGP_ERR_UNKNOWN; } return 0;}static struct argp argp = { options, parse_opt, N_("[FILE]..."), doc, NULL, NULL, NULL};voidusage (int status){ argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name); close_stdout (); exit (status);}/* Parse the options for tar. */static struct argp_option *find_argp_option (struct argp_option *o, int letter){ for (; !(o->name == NULL && o->key == 0 && o->arg == 0 && o->flags == 0 && o->doc == NULL); o++) if (o->key == letter) return o; return NULL;}static voiddecode_options (int argc, char **argv){ int idx; struct tar_args args; /* Set some default option values. */ args.textual_date = NULL; args.wildcards = default_wildcards; args.matching_flags = 0; args.include_anchored = EXCLUDE_ANCHORED; args.o_option = false; args.pax_option = false; args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); args.version_control_string = 0; args.input_files = false; args.compress_autodetect = false; subcommand_option = UNKNOWN_SUBCOMMAND; archive_format = DEFAULT_FORMAT; blocking_factor = DEFAULT_BLOCKING; record_size = DEFAULT_BLOCKING * BLOCKSIZE; excluded = new_exclude (); newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t); newer_mtime_option.tv_nsec = -1; recursion_option = FNM_LEADING_DIR; unquote_option = true; tar_sparse_major = 1; tar_sparse_minor = 0; owner_option = -1; group_option = -1; check_device_option = true; /* Convert old-style tar call by exploding option element and rearranging options accordingly. */ if (argc > 1 && argv[1][0] != '-') { int new_argc; /* argc value for rearranged arguments */ char **new_argv; /* argv value for rearranged arguments */ char *const *in; /* cursor into original argv */ char **out; /* cursor into rearranged argv */ const char *letter; /* cursor into old option letters */ char buffer[3]; /* constructed option buffer */ /* Initialize a constructed option. */ buffer[0] = '-'; buffer[2] = '\0'; /* Allocate a new argument array, and copy program name in it. */ new_argc = argc - 1 + strlen (argv[1]); new_argv = xmalloc ((new_argc + 1) * sizeof (char *)); in = argv; out = new_argv; *out++ = *in++; /* Copy each old letter option as a separate option, and have the corresponding argument moved next to it. */ for (letter = *in++; *letter; letter++) { struct argp_option *opt; buffer[1] = *letter; *out++ = xstrdup (buffer); opt = find_argp_option (options, *letter); if (opt && opt->arg) { if (in < argv + argc) *out++ = *in++; else USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."), *letter)); } } /* Copy all remaining options. */ while (in < argv + argc) *out++ = *in++; *out = 0; /* Replace the old option list by the new one. */ argc = new_argc; argv = new_argv; } /* Parse all options and non-options as they appear. */ prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv); if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, &idx, &args)) exit (TAREXIT_FAILURE); /* Special handling for 'o' option: GNU tar used to say "output old format". UNIX98 tar says don't chown files after extracting (we use "--no-same-owner" for this). The old GNU tar semantics is retained when used with --create option, otherwise UNIX98 semantics is assumed */ if (args.o_option) { if (subcommand_option == CREATE_SUBCOMMAND) { /* GNU Tar <= 1.13 compatibility */ set_archive_format ("v7"); } else { /* UNIX98 compatibility */ same_owner_option = -1; } } /* Handle operands after any "--" argument. */ for (; idx < argc; idx++) { name_add_name (argv[idx], MAKE_INCL_OPTIONS (&args)); args.input_files = true; } /* Warn about implicit use of the wildcards in command line arguments. See TODO */ warn_regex_usage = args.wildcards == default_wildcards; /* Derive option values and check option consistency. */ if (archive_format == DEFAULT_FORMAT) { if (args.pax_option) archive_format = POSIX_FORMAT; else archive_format = DEFAULT_ARCHIVE_FORMAT; } if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND) || incremental_option || multi_volume_option || sparse_option) assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT) | FORMAT_MASK (POSIX_FORMAT)); if (occurrence_option) { if (!args.input_files) USAGE_ERROR ((0, 0, _("--occurrence is meaningless without a file list"))); if (subcommand_option != DELETE_SUBCOMMAND && subcommand_option != DIFF_SUBCOMMAND && subcommand_option != EXTRACT_SUBCOMMAND && subcommand_option != LIST_SUBCOMMAND) USAGE_ERROR ((0, 0, _("--occurrence cannot be used in the requested operation mode"))); } if (seekable_archive && subcommand_option == DELETE_SUBCOMMAND) { /* The current code in delete.c is based on the assumption that skip_member() reads all data from the archive. So, we should make sure it won't use seeks. On the other hand, the same code depends on the ability to backspace a record in the archive, so setting seekable_archive to false is technically incorrect. However, it is tested only in skip_member(), so it's not a problem. */ seekable_archive = false; } if (archive_names == 0) { /* If no archive file name given, try TAPE from the environment, or else, DEFAULT_ARCHIVE from the configuration process. */ archive_names = 1; archive_name_array[0] = getenv ("TAPE"); if (! archive_name_array[0]) archive_name_array[0] = DEFAULT_ARCHIVE; } /* Allow multiple archives only with `-M'. */ if (archive_names > 1 && !multi_volume_option) USAGE_ERROR ((0, 0, _("Multiple archive files require `-M' option"))); if (listed_incremental_option && NEWER_OPTION_INITIALIZED (newer_mtime_option)) USAGE_ERROR ((0, 0, _("Cannot combine --listed-incremental with --newer"))); if (volume_label_option) { if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT) { size_t volume_label_max_len = (sizeof current_header->header.name - 1 /* for trailing '\0' */ - (multi_volume_option ? (sizeof " Volume " - 1 /* for null at end of " Volume " */ + INT_STRLEN_BOUND (int) /* for volume number */ - 1 /* for sign, as 0 <= volno */) : 0)); if (volume_label_max_len < strlen (volume_label_option)) USAGE_ERROR ((0, 0, ngettext ("%s: Volume label is too long (limit is %lu byte)", "%s: Volume label is too long (limit is %lu bytes)", volume_label_max_len), quotearg_colon (volume_label_option), (unsigned long) volume_label_max_len)); } /* else FIXME Label length in PAX format is limited by the volume size. */ } if (verify_option) { if (multi_volume_option) USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives"))); if (use_compress_program_option) USAGE_ERROR ((0, 0, _("Cannot verify compressed archives"))); } if (use_compress_program_option) { if (multi_volume_option) USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives"))); if (subcommand_option == UPDATE_SUBCOMMAND || subcommand_option == APPEND_SUBCOMMAND || subcommand_option == DELETE_SUBCOMMAND) USAGE_ERROR ((0, 0, _("Cannot update compressed archives"))); if (subcommand_option == CAT_SUBCOMMAND) USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives"))); } /* It is no harm to use --pax-option on non-pax archives in archive reading mode. It may even be useful, since it allows to override file attributes from tar headers. Therefore I allow such usage. --gray */ if (args.pax_option && archive_format != POSIX_FORMAT && (subcommand_option != EXTRACT_SUBCOMMAND || subcommand_option != DIFF_SUBCOMMAND || subcommand_option != LIST_SUBCOMMAND)) USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives"))); /* If ready to unlink hierarchies, so we are for simpler files. */ if (recursive_unlink_option) old_files_option = UNLINK_FIRST_OLD_FILES; if (test_label_option) { /* --test-label is silent if the user has specified the label name to compare against. */ if (!args.input_files) verbose_option++; } else if (utc_option) verbose_option = 2; /* Forbid using -c with no input files whatsoever. Check that `-f -', explicit or implied, is used correctly. */ switch (subcommand_option) { case CREATE_SUBCOMMAND: if (!args.input_files && !files_from_option) USAGE_ERROR ((0, 0, _("Cowardly refusing to create an empty archive"))); if (args.compress_autodetect && archive_names && strcmp (archive_name_array[0], "-")) set_comression_program_by_suffix (archive_name_array[0], use_compress_program_option); break; case EXTRACT_SUBCOMMAND: case LIST_SUBCOMMAND: case DIFF_SUBCOMMAND: for (archive_name_cursor = archive_name_array; archive_name_cursor < archive_name_array + archive_names; archive_name_cursor++) if (!strcmp (*archive_name_cursor, "-")) request_stdin ("-f"); break; case CAT_SUBCOMMAND: case UPDATE_SUBCOMMAND: case APPEND_SUBCOMMAND: for (archive_name_cursor = archive_name_array; archive_name_cursor < archive_name_array + archive_names; archive_name_cursor++) if (!strcmp (*archive_name_cursor, "-")) USAGE_ERROR ((0, 0, _("Options `-Aru' are incompatible with `-f -'")))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -