X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Ftar.c;h=dcf6a3e3fb2a67bea96fcb6f8d0f282188fce7f9;hb=6de64217875d12467ed9c87284e5e20981a4ff0a;hp=004a13d30108f9f1ba9b482e8cc1db2c6c8377f4;hpb=879ae47aa16752580616c6c52d6b4757a2705dd3;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index 004a13d..dcf6a3e 100644 --- a/src/tar.c +++ b/src/tar.c @@ -44,6 +44,10 @@ /* Local declarations. */ +#ifndef DEFAULT_ARCHIVE_FORMAT +# define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT +#endif + #ifndef DEFAULT_ARCHIVE # define DEFAULT_ARCHIVE "tar.out" #endif @@ -113,39 +117,47 @@ confirm (const char *message_action, const char *message_name) } } -void -set_archive_format (char *name) -{ - static struct fmttab { - char *name; - enum archive_format fmt; - } fmttab[] = { - { "v7", V7_FORMAT }, - { "oldgnu", OLDGNU_FORMAT }, - { "posix", POSIX_FORMAT }, +static struct fmttab { + char const *name; + enum archive_format fmt; +} const fmttab[] = { + { "v7", V7_FORMAT }, + { "oldgnu", OLDGNU_FORMAT }, + { "posix", POSIX_FORMAT }, #if 0 /* not fully supported yet */ - { "star", STAR_FORMAT }, + { "star", STAR_FORMAT }, #endif - { "gnu", GNU_FORMAT }, - NULL - }; - struct fmttab *p; - enum archive_format fmt; - - for (p = fmttab; p->name; p++) - { - if (strcmp (p->name, name) == 0) - { - fmt = p->fmt; - break; - } - } + { "gnu", GNU_FORMAT }, + { NULL, 0 } +}; + +static void +set_archive_format (char const *name) +{ + struct fmttab const *p; + + for (p = fmttab; strcmp (p->name, name) != 0; ) + if (! (++p)->name) + USAGE_ERROR ((0, 0, _("%s: Invalid archive format"), + quotearg_colon (name))); - if (archive_format != DEFAULT_FORMAT && archive_format != fmt) + if (archive_format != DEFAULT_FORMAT && archive_format != p->fmt) USAGE_ERROR ((0, 0, _("Conflicting archive format options"))); - archive_format = fmt; + archive_format = p->fmt; } + +static const char * +archive_format_string (enum archive_format fmt) +{ + struct fmttab const *p; + + for (p = fmttab; p->name; p++) + if (p->fmt == fmt) + return p->name; + return "unknown?"; +} + /* Options. */ @@ -188,6 +200,7 @@ enum REMOVE_FILES_OPTION, RSH_COMMAND_OPTION, SHOW_OMITTED_DIRS_OPTION, + STRIP_PATH_OPTION, SUFFIX_OPTION, TOTALS_OPTION, USE_COMPRESS_PROGRAM_OPTION, @@ -287,6 +300,7 @@ static struct option long_options[] = {"show-omitted-dirs", no_argument, 0, SHOW_OMITTED_DIRS_OPTION}, {"sparse", no_argument, 0, 'S'}, {"starting-file", required_argument, 0, 'K'}, + {"strip-path", required_argument, 0, STRIP_PATH_OPTION }, {"suffix", required_argument, 0, SUFFIX_OPTION}, {"tape-length", required_argument, 0, 'L'}, {"to-stdout", no_argument, 0, 'O'}, @@ -439,7 +453,9 @@ Local file selection:\n\ -h, --dereference dump instead the files symlinks point to\n\ --no-recursion avoid descending automatically in directories\n\ -l, --one-file-system stay in local file system when creating archive\n\ - -K, --starting-file=NAME begin at file NAME in the archive\n"), + -K, --starting-file=NAME begin at file NAME in the archive\n\ + --strip-path=NUM strip NUM leading components from file names\n\ + before extraction\n"), stdout); #if !MSDOS fputs (_("\ @@ -484,12 +500,10 @@ The version control may be set with --backup or VERSION_CONTROL, values are:\n\ stdout); printf (_("\ \n\ -GNU tar cannot read nor produce `--posix' archives. If POSIXLY_CORRECT\n\ -is set in the environment, GNU extensions are disallowed with `--posix'.\n\ -Support for POSIX is only partially implemented, don't count on it yet.\n\ ARCHIVE may be FILE, HOST:FILE or USER@HOST:FILE; DATE may be a textual date\n\ or a file name starting with `/' or `.', in which case the file's date is used.\n\ -*This* `tar' defaults to `-f%s -b%d'.\n"), +*This* `tar' defaults to `--format=%s -f%s -b%d'.\n"), + archive_format_string (DEFAULT_ARCHIVE_FORMAT), DEFAULT_ARCHIVE, DEFAULT_BLOCKING); printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); } @@ -540,7 +554,7 @@ decode_options (int argc, char **argv) char const *backup_suffix_string; char const *version_control_string = 0; int exclude_options = EXCLUDE_WILDCARDS; - int o_option = 0; + bool o_option = 0; /* Set some default option values. */ @@ -661,7 +675,7 @@ decode_options (int argc, char **argv) BSD-derived systems. This is a consequence of the block/record terminology confusion. */ - read_full_records_option = 1; + read_full_records_option = true; break; case 'c': @@ -693,12 +707,12 @@ decode_options (int argc, char **argv) script at the end of each tape. */ info_script_option = optarg; - multi_volume_option = 1; + multi_volume_option = true; break; case 'g': listed_incremental_option = optarg; - after_date_option = 1; + after_date_option = true; /* Fall through. */ case 'G': @@ -706,13 +720,12 @@ decode_options (int argc, char **argv) directories at the beginning of the archive, and include in each directory its contents. */ - incremental_option = 1; + incremental_option = true; break; case 'h': /* Follow symbolic links. */ - - dereference_option = 1; + dereference_option = true; break; case 'i': @@ -720,7 +733,7 @@ decode_options (int argc, char **argv) because Unix tar writes two blocks of zeros, then pads out the record with garbage. */ - ignore_zeros_option = 1; + ignore_zeros_option = true; break; case 'I': @@ -739,7 +752,7 @@ decode_options (int argc, char **argv) break; case 'K': - starting_file_option = 1; + starting_file_option = true; addname (optarg, 0); break; @@ -747,7 +760,7 @@ decode_options (int argc, char **argv) /* When dumping directories, don't dump files/subdirectories that are on other filesystems. */ - one_file_system_option = 1; + one_file_system_option = true; break; case 'L': @@ -757,24 +770,24 @@ decode_options (int argc, char **argv) USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), _("Invalid tape length"))); tape_length_option = 1024 * (tarlong) u; - multi_volume_option = 1; + multi_volume_option = true; } break; case 'm': - touch_option = 1; + touch_option = true; break; case 'M': /* Make multivolume archive: when we can't write any more into the archive, re-open it, and continue writing. */ - multi_volume_option = 1; + multi_volume_option = true; break; #if !MSDOS case 'N': - after_date_option = 1; + after_date_option = true; /* Fall through. */ case NEWER_MTIME_OPTION: @@ -807,19 +820,19 @@ decode_options (int argc, char **argv) #endif /* not MSDOS */ case 'o': - o_option = 1; + o_option = true; break; case 'O': - to_stdout_option = 1; + to_stdout_option = true; break; case 'p': - same_permissions_option = 1; + same_permissions_option = true; break; case 'P': - absolute_names_option = 1; + absolute_names_option = true; break; case 'r': @@ -834,17 +847,17 @@ decode_options (int argc, char **argv) BSD-derived systems. This is a consequence of the block/record terminology confusion. */ - block_number_option = 1; + block_number_option = true; break; case 's': /* Names to extr are sorted. */ - same_order_option = 1; + same_order_option = true; break; case 'S': - sparse_option = 1; + sparse_option = true; break; case 't': @@ -873,11 +886,11 @@ decode_options (int argc, char **argv) break; case 'w': - interactive_option = 1; + interactive_option = true; break; case 'W': - verify_option = 1; + verify_option = true; break; case 'x': @@ -913,15 +926,15 @@ decode_options (int argc, char **argv) break; case ATIME_PRESERVE_OPTION: - atime_preserve_option = 1; + atime_preserve_option = true; break; case CHECKPOINT_OPTION: - checkpoint_option = 1; + checkpoint_option = true; break; case BACKUP_OPTION: - backup_option = 1; + backup_option = true; if (optarg) version_control_string = optarg; break; @@ -935,7 +948,7 @@ decode_options (int argc, char **argv) break; case FORCE_LOCAL_OPTION: - force_local_option = 1; + force_local_option = true; break; case FORMAT_OPTION: @@ -951,7 +964,7 @@ decode_options (int argc, char **argv) break; case IGNORE_FAILED_READ_OPTION: - ignore_failed_read_option = 1; + ignore_failed_read_option = true; break; case GROUP_OPTION: @@ -1003,7 +1016,7 @@ decode_options (int argc, char **argv) break; case NUMERIC_OWNER_OPTION: - numeric_owner_option = 1; + numeric_owner_option = true; break; case OVERWRITE_OPTION: @@ -1029,8 +1042,8 @@ decode_options (int argc, char **argv) break; case PRESERVE_OPTION: - same_permissions_option = 1; - same_order_option = 1; + same_permissions_option = true; + same_order_option = true; break; case RECORD_SIZE_OPTION: @@ -1049,22 +1062,37 @@ decode_options (int argc, char **argv) break; case RECURSIVE_UNLINK_OPTION: - recursive_unlink_option = 1; + recursive_unlink_option = true; break; case REMOVE_FILES_OPTION: - remove_files_option = 1; + remove_files_option = true; break; case RSH_COMMAND_OPTION: rsh_command_option = optarg; break; + case STRIP_PATH_OPTION: + { + uintmax_t u; + if (! (xstrtoumax (optarg, 0, 10, &u, "") == LONGINT_OK + && u == (size_t) u)) + USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg), + _("Invalid number of elements"))); + strip_path_elements = u; + } + break; + case SUFFIX_OPTION: - backup_option = 1; + backup_option = true; backup_suffix_string = optarg; break; + case TOTALS_OPTION: + totals_option = true; + break; + case USE_COMPRESS_PROGRAM_OPTION: set_use_compress_program_option (optarg); break; @@ -1209,12 +1237,12 @@ see the file named COPYING for details.")); /* Derive option values and check option consistency. */ if (archive_format == DEFAULT_FORMAT) - archive_format = GNU_FORMAT; + archive_format = DEFAULT_ARCHIVE_FORMAT; if (archive_format == GNU_FORMAT && getenv ("POSIXLY_CORRECT")) archive_format = POSIX_FORMAT; - if ((volume_label_option + if (((volume_label_option && subcommand_option == CREATE_SUBCOMMAND) || incremental_option || multi_volume_option || sparse_option) && archive_format != OLDGNU_FORMAT && archive_format != GNU_FORMAT) USAGE_ERROR ((0, 0, @@ -1255,7 +1283,9 @@ see the file named COPYING for details.")); : 0)); if (volume_label_max_len < strlen (volume_label_option)) USAGE_ERROR ((0, 0, - _("%s: Volume label is too long (limit is %lu bytes)"), + 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)); }