X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Ftar.c;h=d4fda6fad53c8df89902e23b95fc2ef339eb21b9;hb=dccb3806a6e9fcf50952b9d3cc96c6591acbd076;hp=943de847457a558e9d80e927f8a224f6dcea4ad1;hpb=51aee274e892923a3f8fdb774e4f6b90bce47437;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index 943de84..d4fda6f 100644 --- a/src/tar.c +++ b/src/tar.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #if ! defined SIGCHLD && defined SIGCLD @@ -256,6 +257,7 @@ enum DELAY_DIRECTORY_RESTORE_OPTION, HARD_DEREFERENCE_OPTION, DELETE_OPTION, + EXCLUDE_BACKUPS_OPTION, EXCLUDE_CACHES_OPTION, EXCLUDE_CACHES_UNDER_OPTION, EXCLUDE_CACHES_ALL_OPTION, @@ -266,7 +268,6 @@ enum EXCLUDE_VCS_OPTION, FORCE_LOCAL_OPTION, GROUP_OPTION, - HANG_OPTION, IGNORE_CASE_OPTION, IGNORE_COMMAND_ERROR_OPTION, IGNORE_FAILED_READ_OPTION, @@ -290,6 +291,7 @@ enum NO_RECURSION_OPTION, NO_SAME_OWNER_OPTION, NO_SAME_PERMISSIONS_OPTION, + NO_SEEK_OPTION, NO_UNQUOTE_OPTION, NO_WILDCARDS_MATCH_SLASH_OPTION, NO_WILDCARDS_OPTION, @@ -325,9 +327,7 @@ enum TO_COMMAND_OPTION, TRANSFORM_OPTION, UNQUOTE_OPTION, - USAGE_OPTION, UTC_OPTION, - VERSION_OPTION, VOLNO_FILE_OPTION, WARNING_OPTION, WILDCARDS_MATCH_SLASH_OPTION, @@ -365,7 +365,12 @@ The version control may be set with --backup or VERSION_CONTROL, values are:\n\n [q alias for --occurrence=1 =/= this would better be used for quiet?] y per-file gzip compression - Y per-block gzip compression */ + Y per-block gzip compression. + + Additionally, the 'n' letter is assigned for option --seek, which + is probably not needed and should be marked as deprecated, so that + -n may become available in the future. +*/ static struct argp_option options[] = { #define GRID 10 @@ -419,6 +424,8 @@ static struct argp_option options[] = { " NUMBER defaults to 1"), GRID+1 }, {"seek", 'n', NULL, 0, N_("archive is seekable"), GRID+1 }, + {"no-seek", NO_SEEK_OPTION, NULL, 0, + N_("archive is not seekable"), GRID+1 }, {"no-check-device", NO_CHECK_DEVICE_OPTION, NULL, 0, N_("do not check device numbers when creating incremental archives"), GRID+1 }, @@ -659,6 +666,8 @@ static struct argp_option options[] = { N_("exclude directories containing FILE"), GRID+1 }, {"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0, N_("exclude version control system directories"), GRID+1 }, + {"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0, + N_("exclude backup and lock files"), GRID+1 }, {"no-recursion", NO_RECURSION_OPTION, 0, 0, N_("avoid descending automatically in directories"), GRID+1 }, {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0, @@ -777,14 +786,6 @@ static struct argp_option options[] = { {"restrict", RESTRICT_OPTION, 0, 0, N_("disable use of some potentially harmful options"), -1 }, - - {"help", '?', 0, 0, N_("give this help list"), -1}, - {"usage", USAGE_OPTION, 0, 0, N_("give a short usage message"), -1}, - {"version", VERSION_OPTION, 0, 0, N_("print program version"), -1}, - /* FIXME -V (--label) conflicts with the default short option for - --version */ - {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("hang for SECS seconds (default 3600)"), 0}, #undef GRID {0, 0, 0, 0, 0, 0} @@ -844,44 +845,52 @@ struct tar_args /* Variables used during option parsing */ | (args)->matching_flags \ | recursion_option) +static char const * const vcs_file_table[] = { + /* CVS: */ + "CVS", + ".cvsignore", + /* RCS: */ + "RCS", + /* SCCS: */ + "SCCS", + /* SVN: */ + ".svn", + /* git: */ + ".git", + ".gitignore", + /* Arch: */ + ".arch-ids", + "{arch}", + "=RELEASE-ID", + "=meta-update", + "=update", + /* Bazaar */ + ".bzr", + ".bzrignore", + ".bzrtags", + /* Mercurial */ + ".hg", + ".hgignore", + ".hgtags", + /* darcs */ + "_darcs", + NULL +}; + +static char const * const backup_file_table[] = { + ".#*", + "*~", + "#*#", + NULL +}; + void -exclude_vcs_files () +add_exclude_array (char const * const * fv) { int i; - static char *vcs_file[] = { - /* CVS: */ - "CVS", - ".cvsignore", - /* RCS: */ - "RCS", - /* SCCS: */ - "SCCS", - /* SVN: */ - ".svn", - /* git: */ - ".git", - ".gitignore", - /* Arch: */ - ".arch-ids", - "{arch}", - "=RELEASE-ID", - "=meta-update", - "=update", - /* Bazaar */ - ".bzr", - ".bzrignore", - ".bzrtags", - /* Mercurial */ - ".hg", - ".hgignore", - ".hgtags", - /* darcs */ - "_darcs", - NULL - }; - for (i = 0; vcs_file[i]; i++) - add_exclude (excluded, vcs_file[i], 0); + for (i = 0; fv[i]; i++) + add_exclude (excluded, fv[i], 0); } @@ -1055,7 +1064,6 @@ report_textual_dates (struct tar_args *args) } -static volatile int _argp_hang; /* Either NL or NUL, as decided by the --null option. */ static char filename_terminator; @@ -1446,9 +1454,13 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case 'n': - seekable_archive = true; + seek_option = 1; break; + case NO_SEEK_OPTION: + seek_option = 0; + break; + case 'N': after_date_option = true; /* Fall through. */ @@ -1652,6 +1664,10 @@ parse_opt (int key, char *arg, struct argp_state *state) set_subcommand_option (DELETE_SUBCOMMAND); break; + case EXCLUDE_BACKUPS_OPTION: + add_exclude_array (backup_file_table); + break; + case EXCLUDE_OPTION: add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args)); break; @@ -1684,7 +1700,7 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case EXCLUDE_VCS_OPTION: - exclude_vcs_files (); + add_exclude_array (vcs_file_table); break; case FORCE_LOCAL_OPTION: @@ -2034,28 +2050,6 @@ parse_opt (int key, char *arg, struct argp_state *state) #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; } @@ -2096,12 +2090,20 @@ find_argp_option (struct argp_option *o, int letter) return NULL; } +static const char *tar_authors[] = { + "John Gilmore", + "Jay Fenlason", + NULL +}; + static void decode_options (int argc, char **argv) { int idx; struct tar_args args; + argp_version_setup ("tar", tar_authors); + /* Set some default option values. */ args.textual_date = NULL; args.wildcards = default_wildcards; @@ -2132,6 +2134,8 @@ decode_options (int argc, char **argv) check_device_option = true; incremental_level = -1; + + seek_option = -1; /* Convert old-style tar call by exploding option element and rearranging options accordingly. */ @@ -2194,8 +2198,7 @@ decode_options (int argc, char **argv) prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv); - if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, - &idx, &args)) + if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args)) exit (TAREXIT_FAILURE); @@ -2264,18 +2267,6 @@ decode_options (int argc, char **argv) _("--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 @@ -2560,7 +2551,7 @@ main (int argc, char **argv) if (stdlis == stdout) close_stdout (); else if (ferror (stderr) || fclose (stderr) != 0) - exit_status = TAREXIT_FAILURE; + set_exit_status (TAREXIT_FAILURE); return exit_status; } @@ -2598,3 +2589,13 @@ tar_timespec_cmp (struct timespec a, struct timespec b) a.tv_nsec = b.tv_nsec = 0; return timespec_cmp (a, b); } + +/* Set tar exit status to VAL, unless it is already indicating + a more serious condition. This relies on the fact that the + values of TAREXIT_ constants are ranged by severity. */ +void +set_exit_status (int val) +{ + if (val > exit_status) + exit_status = val; +}