| 1 | /* Common declarations for the tar program.
|
|---|
| 2 |
|
|---|
| 3 | Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
|---|
| 4 | 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
|---|
| 5 |
|
|---|
| 6 | This program is free software; you can redistribute it and/or modify it
|
|---|
| 7 | under the terms of the GNU General Public License as published by the
|
|---|
| 8 | Free Software Foundation; either version 2, or (at your option) any later
|
|---|
| 9 | version.
|
|---|
| 10 |
|
|---|
| 11 | This program is distributed in the hope that it will be useful, but
|
|---|
| 12 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|---|
| 14 | Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License along
|
|---|
| 17 | with this program; if not, write to the Free Software Foundation, Inc.,
|
|---|
| 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|---|
| 19 |
|
|---|
| 20 | /* Declare the GNU tar archive format. */
|
|---|
| 21 | #include "tar.h"
|
|---|
| 22 |
|
|---|
| 23 | /* The checksum field is filled with this while the checksum is computed. */
|
|---|
| 24 | #define CHKBLANKS " " /* 8 blanks, no null */
|
|---|
| 25 |
|
|---|
| 26 | /* Some constants from POSIX are given names. */
|
|---|
| 27 | #define NAME_FIELD_SIZE 100
|
|---|
| 28 | #define PREFIX_FIELD_SIZE 155
|
|---|
| 29 | #define UNAME_FIELD_SIZE 32
|
|---|
| 30 | #define GNAME_FIELD_SIZE 32
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 | |
|---|
| 34 |
|
|---|
| 35 | /* Some various global definitions. */
|
|---|
| 36 |
|
|---|
| 37 | /* Name of file to use for interacting with user. */
|
|---|
| 38 |
|
|---|
| 39 | /* GLOBAL is defined to empty in tar.c only, and left alone in other *.c
|
|---|
| 40 | modules. Here, we merely set it to "extern" if it is not already set.
|
|---|
| 41 | GNU tar does depend on the system loader to preset all GLOBAL variables to
|
|---|
| 42 | neutral (or zero) values, explicit initialization is usually not done. */
|
|---|
| 43 | #ifndef GLOBAL
|
|---|
| 44 | # define GLOBAL extern
|
|---|
| 45 | #endif
|
|---|
| 46 |
|
|---|
| 47 | #define TAREXIT_SUCCESS PAXEXIT_SUCCESS
|
|---|
| 48 | #define TAREXIT_DIFFERS PAXEXIT_DIFFERS
|
|---|
| 49 | #define TAREXIT_FAILURE PAXEXIT_FAILURE
|
|---|
| 50 |
|
|---|
| 51 | |
|---|
| 52 |
|
|---|
| 53 | #include "arith.h"
|
|---|
| 54 | #include <backupfile.h>
|
|---|
| 55 | #include <exclude.h>
|
|---|
| 56 | #include <full-write.h>
|
|---|
| 57 | #include <modechange.h>
|
|---|
| 58 | #include <quote.h>
|
|---|
| 59 | #include <safe-read.h>
|
|---|
| 60 | #include <stat-time.h>
|
|---|
| 61 | #include <timespec.h>
|
|---|
| 62 | #define obstack_chunk_alloc xmalloc
|
|---|
| 63 | #define obstack_chunk_free free
|
|---|
| 64 | #include <obstack.h>
|
|---|
| 65 |
|
|---|
| 66 | #include <paxlib.h>
|
|---|
| 67 |
|
|---|
| 68 | /* Log base 2 of common values. */
|
|---|
| 69 | #define LG_8 3
|
|---|
| 70 | #define LG_64 6
|
|---|
| 71 | #define LG_256 8
|
|---|
| 72 | |
|---|
| 73 |
|
|---|
| 74 | /* Information gleaned from the command line. */
|
|---|
| 75 |
|
|---|
| 76 | /* Name of this program. */
|
|---|
| 77 | GLOBAL const char *program_name;
|
|---|
| 78 |
|
|---|
| 79 | /* Main command option. */
|
|---|
| 80 |
|
|---|
| 81 | enum subcommand
|
|---|
| 82 | {
|
|---|
| 83 | UNKNOWN_SUBCOMMAND, /* none of the following */
|
|---|
| 84 | APPEND_SUBCOMMAND, /* -r */
|
|---|
| 85 | CAT_SUBCOMMAND, /* -A */
|
|---|
| 86 | CREATE_SUBCOMMAND, /* -c */
|
|---|
| 87 | DELETE_SUBCOMMAND, /* -D */
|
|---|
| 88 | DIFF_SUBCOMMAND, /* -d */
|
|---|
| 89 | EXTRACT_SUBCOMMAND, /* -x */
|
|---|
| 90 | LIST_SUBCOMMAND, /* -t */
|
|---|
| 91 | UPDATE_SUBCOMMAND /* -u */
|
|---|
| 92 | };
|
|---|
| 93 |
|
|---|
| 94 | GLOBAL enum subcommand subcommand_option;
|
|---|
| 95 |
|
|---|
| 96 | /* Selected format for output archive. */
|
|---|
| 97 | GLOBAL enum archive_format archive_format;
|
|---|
| 98 |
|
|---|
| 99 | /* Either NL or NUL, as decided by the --null option. */
|
|---|
| 100 | GLOBAL char filename_terminator;
|
|---|
| 101 |
|
|---|
| 102 | /* Size of each record, once in blocks, once in bytes. Those two variables
|
|---|
| 103 | are always related, the second being BLOCKSIZE times the first. They do
|
|---|
| 104 | not have _option in their name, even if their values is derived from
|
|---|
| 105 | option decoding, as these are especially important in tar. */
|
|---|
| 106 | GLOBAL int blocking_factor;
|
|---|
| 107 | GLOBAL size_t record_size;
|
|---|
| 108 |
|
|---|
| 109 | GLOBAL bool absolute_names_option;
|
|---|
| 110 |
|
|---|
| 111 | /* Display file times in UTC */
|
|---|
| 112 | GLOBAL bool utc_option;
|
|---|
| 113 |
|
|---|
| 114 | /* This variable tells how to interpret newer_mtime_option, below. If zero,
|
|---|
| 115 | files get archived if their mtime is not less than newer_mtime_option.
|
|---|
| 116 | If nonzero, files get archived if *either* their ctime or mtime is not less
|
|---|
| 117 | than newer_mtime_option. */
|
|---|
| 118 | GLOBAL int after_date_option;
|
|---|
| 119 |
|
|---|
| 120 | enum atime_preserve
|
|---|
| 121 | {
|
|---|
| 122 | no_atime_preserve,
|
|---|
| 123 | replace_atime_preserve,
|
|---|
| 124 | system_atime_preserve
|
|---|
| 125 | };
|
|---|
| 126 | GLOBAL enum atime_preserve atime_preserve_option;
|
|---|
| 127 |
|
|---|
| 128 | GLOBAL bool backup_option;
|
|---|
| 129 |
|
|---|
| 130 | /* Type of backups being made. */
|
|---|
| 131 | GLOBAL enum backup_type backup_type;
|
|---|
| 132 |
|
|---|
| 133 | GLOBAL bool block_number_option;
|
|---|
| 134 |
|
|---|
| 135 | GLOBAL unsigned checkpoint_option;
|
|---|
| 136 |
|
|---|
| 137 | enum checkpoint_style
|
|---|
| 138 | {
|
|---|
| 139 | checkpoint_text,
|
|---|
| 140 | checkpoint_dot
|
|---|
| 141 | };
|
|---|
| 142 |
|
|---|
| 143 | GLOBAL enum checkpoint_style checkpoint_style;
|
|---|
| 144 |
|
|---|
| 145 | /* Specified name of compression program, or "gzip" as implied by -z. */
|
|---|
| 146 | GLOBAL const char *use_compress_program_option;
|
|---|
| 147 |
|
|---|
| 148 | GLOBAL bool dereference_option;
|
|---|
| 149 |
|
|---|
| 150 | /* Print a message if not all links are dumped */
|
|---|
| 151 | GLOBAL int check_links_option;
|
|---|
| 152 |
|
|---|
| 153 | /* Patterns that match file names to be excluded. */
|
|---|
| 154 | GLOBAL struct exclude *excluded;
|
|---|
| 155 |
|
|---|
| 156 | /* Exclude directories containing a cache directory tag. */
|
|---|
| 157 | GLOBAL bool exclude_caches_option;
|
|---|
| 158 |
|
|---|
| 159 | /* Specified value to be put into tar file in place of stat () results, or
|
|---|
| 160 | just -1 if such an override should not take place. */
|
|---|
| 161 | GLOBAL gid_t group_option;
|
|---|
| 162 |
|
|---|
| 163 | GLOBAL bool ignore_failed_read_option;
|
|---|
| 164 |
|
|---|
| 165 | GLOBAL bool ignore_zeros_option;
|
|---|
| 166 |
|
|---|
| 167 | GLOBAL bool incremental_option;
|
|---|
| 168 |
|
|---|
| 169 | /* Specified name of script to run at end of each tape change. */
|
|---|
| 170 | GLOBAL const char *info_script_option;
|
|---|
| 171 |
|
|---|
| 172 | GLOBAL bool interactive_option;
|
|---|
| 173 |
|
|---|
| 174 | /* If nonzero, extract only Nth occurrence of each named file */
|
|---|
| 175 | GLOBAL uintmax_t occurrence_option;
|
|---|
| 176 |
|
|---|
| 177 | enum old_files
|
|---|
| 178 | {
|
|---|
| 179 | DEFAULT_OLD_FILES, /* default */
|
|---|
| 180 | NO_OVERWRITE_DIR_OLD_FILES, /* --no-overwrite-dir */
|
|---|
| 181 | OVERWRITE_OLD_FILES, /* --overwrite */
|
|---|
| 182 | UNLINK_FIRST_OLD_FILES, /* --unlink-first */
|
|---|
| 183 | KEEP_OLD_FILES, /* --keep-old-files */
|
|---|
| 184 | KEEP_NEWER_FILES /* --keep-newer-files */
|
|---|
| 185 | };
|
|---|
| 186 | GLOBAL enum old_files old_files_option;
|
|---|
| 187 |
|
|---|
| 188 | /* Specified file name for incremental list. */
|
|---|
| 189 | GLOBAL const char *listed_incremental_option;
|
|---|
| 190 |
|
|---|
| 191 | /* Specified mode change string. */
|
|---|
| 192 | GLOBAL struct mode_change *mode_option;
|
|---|
| 193 |
|
|---|
| 194 | /* Initial umask, if needed for mode change string. */
|
|---|
| 195 | GLOBAL mode_t initial_umask;
|
|---|
| 196 |
|
|---|
| 197 | GLOBAL bool multi_volume_option;
|
|---|
| 198 |
|
|---|
| 199 | /* Specified threshold date and time. Files having an older time stamp
|
|---|
| 200 | do not get archived (also see after_date_option above). */
|
|---|
| 201 | GLOBAL struct timespec newer_mtime_option;
|
|---|
| 202 |
|
|---|
| 203 | /* If true, override actual mtime (see below) */
|
|---|
| 204 | GLOBAL bool set_mtime_option;
|
|---|
| 205 | /* Value to be put in mtime header field instead of the actual mtime */
|
|---|
| 206 | GLOBAL struct timespec mtime_option;
|
|---|
| 207 |
|
|---|
| 208 | /* Return true if newer_mtime_option is initialized. */
|
|---|
| 209 | #define NEWER_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec)
|
|---|
| 210 |
|
|---|
| 211 | /* Return true if the struct stat ST's M time is less than
|
|---|
| 212 | newer_mtime_option. */
|
|---|
| 213 | #define OLDER_STAT_TIME(st, m) \
|
|---|
| 214 | (timespec_cmp (get_stat_##m##time (&(st)), newer_mtime_option) < 0)
|
|---|
| 215 |
|
|---|
| 216 | /* Likewise, for struct tar_stat_info ST. */
|
|---|
| 217 | #define OLDER_TAR_STAT_TIME(st, m) \
|
|---|
| 218 | (timespec_cmp ((st).m##time, newer_mtime_option) < 0)
|
|---|
| 219 |
|
|---|
| 220 | /* Zero if there is no recursion, otherwise FNM_LEADING_DIR. */
|
|---|
| 221 | GLOBAL int recursion_option;
|
|---|
| 222 |
|
|---|
| 223 | GLOBAL bool numeric_owner_option;
|
|---|
| 224 |
|
|---|
| 225 | GLOBAL bool one_file_system_option;
|
|---|
| 226 |
|
|---|
| 227 | /* Specified value to be put into tar file in place of stat () results, or
|
|---|
| 228 | just -1 if such an override should not take place. */
|
|---|
| 229 | GLOBAL uid_t owner_option;
|
|---|
| 230 |
|
|---|
| 231 | GLOBAL bool recursive_unlink_option;
|
|---|
| 232 |
|
|---|
| 233 | GLOBAL bool read_full_records_option;
|
|---|
| 234 |
|
|---|
| 235 | GLOBAL bool remove_files_option;
|
|---|
| 236 |
|
|---|
| 237 | /* Specified rmt command. */
|
|---|
| 238 | GLOBAL const char *rmt_command_option;
|
|---|
| 239 |
|
|---|
| 240 | /* Specified remote shell command. */
|
|---|
| 241 | GLOBAL const char *rsh_command_option;
|
|---|
| 242 |
|
|---|
| 243 | GLOBAL bool same_order_option;
|
|---|
| 244 |
|
|---|
| 245 | /* If positive, preserve ownership when extracting. */
|
|---|
| 246 | GLOBAL int same_owner_option;
|
|---|
| 247 |
|
|---|
| 248 | /* If positive, preserve permissions when extracting. */
|
|---|
| 249 | GLOBAL int same_permissions_option;
|
|---|
| 250 |
|
|---|
| 251 | /* When set, strip the given number of file name components from the file name
|
|---|
| 252 | before extracting */
|
|---|
| 253 | GLOBAL size_t strip_name_components;
|
|---|
| 254 |
|
|---|
| 255 | GLOBAL bool show_omitted_dirs_option;
|
|---|
| 256 |
|
|---|
| 257 | GLOBAL bool sparse_option;
|
|---|
| 258 | GLOBAL unsigned tar_sparse_major;
|
|---|
| 259 | GLOBAL unsigned tar_sparse_minor;
|
|---|
| 260 |
|
|---|
| 261 | GLOBAL bool starting_file_option;
|
|---|
| 262 |
|
|---|
| 263 | /* Specified maximum byte length of each tape volume (multiple of 1024). */
|
|---|
| 264 | GLOBAL tarlong tape_length_option;
|
|---|
| 265 |
|
|---|
| 266 | GLOBAL bool to_stdout_option;
|
|---|
| 267 |
|
|---|
| 268 | GLOBAL bool totals_option;
|
|---|
| 269 |
|
|---|
| 270 | GLOBAL bool touch_option;
|
|---|
| 271 |
|
|---|
| 272 | GLOBAL char *to_command_option;
|
|---|
| 273 | GLOBAL bool ignore_command_error_option;
|
|---|
| 274 |
|
|---|
| 275 | /* Restrict some potentially harmful tar options */
|
|---|
| 276 | GLOBAL bool restrict_option;
|
|---|
| 277 |
|
|---|
| 278 | /* Return true if the extracted files are not being written to disk */
|
|---|
| 279 | #define EXTRACT_OVER_PIPE (to_stdout_option || to_command_option)
|
|---|
| 280 |
|
|---|
| 281 | /* Count how many times the option has been set, multiple setting yields
|
|---|
| 282 | more verbose behavior. Value 0 means no verbosity, 1 means file name
|
|---|
| 283 | only, 2 means file name and all attributes. More than 2 is just like 2. */
|
|---|
| 284 | GLOBAL int verbose_option;
|
|---|
| 285 |
|
|---|
| 286 | GLOBAL bool verify_option;
|
|---|
| 287 |
|
|---|
| 288 | /* Specified name of file containing the volume number. */
|
|---|
| 289 | GLOBAL const char *volno_file_option;
|
|---|
| 290 |
|
|---|
| 291 | /* Specified value or pattern. */
|
|---|
| 292 | GLOBAL const char *volume_label_option;
|
|---|
| 293 | |
|---|
| 294 |
|
|---|
| 295 | /* Other global variables. */
|
|---|
| 296 |
|
|---|
| 297 | /* File descriptor for archive file. */
|
|---|
| 298 | GLOBAL int archive;
|
|---|
| 299 |
|
|---|
| 300 | /* Nonzero when outputting to /dev/null. */
|
|---|
| 301 | GLOBAL bool dev_null_output;
|
|---|
| 302 |
|
|---|
| 303 | /* Timestamps: */
|
|---|
| 304 | GLOBAL struct timespec start_time; /* when we started execution */
|
|---|
| 305 | GLOBAL struct timespec volume_start_time; /* when the current volume was
|
|---|
| 306 | opened*/
|
|---|
| 307 | GLOBAL struct timespec last_stat_time; /* when the statistics was last
|
|---|
| 308 | computed */
|
|---|
| 309 |
|
|---|
| 310 | GLOBAL struct tar_stat_info current_stat_info;
|
|---|
| 311 |
|
|---|
| 312 | /* List of tape drive names, number of such tape drives, allocated number,
|
|---|
| 313 | and current cursor in list. */
|
|---|
| 314 | GLOBAL const char **archive_name_array;
|
|---|
| 315 | GLOBAL size_t archive_names;
|
|---|
| 316 | GLOBAL size_t allocated_archive_names;
|
|---|
| 317 | GLOBAL const char **archive_name_cursor;
|
|---|
| 318 |
|
|---|
| 319 | /* Output index file name. */
|
|---|
| 320 | GLOBAL char const *index_file_name;
|
|---|
| 321 |
|
|---|
| 322 | /* Structure for keeping track of filenames and lists thereof. */
|
|---|
| 323 | struct name
|
|---|
| 324 | {
|
|---|
| 325 | struct name *next; /* Link to the next element */
|
|---|
| 326 | int change_dir; /* Number of the directory to change to.
|
|---|
| 327 | Set with the -C option. */
|
|---|
| 328 | uintmax_t found_count; /* number of times a matching file has
|
|---|
| 329 | been found */
|
|---|
| 330 | int matching_flags; /* this name is a regexp, not literal */
|
|---|
| 331 | char const *dir_contents; /* for incremental_option */
|
|---|
| 332 |
|
|---|
| 333 | size_t length; /* cached strlen(name) */
|
|---|
| 334 | char name[1];
|
|---|
| 335 | };
|
|---|
| 336 |
|
|---|
| 337 | /* Obnoxious test to see if dimwit is trying to dump the archive. */
|
|---|
| 338 | GLOBAL dev_t ar_dev;
|
|---|
| 339 | GLOBAL ino_t ar_ino;
|
|---|
| 340 |
|
|---|
| 341 | GLOBAL bool seekable_archive;
|
|---|
| 342 |
|
|---|
| 343 | GLOBAL dev_t root_device;
|
|---|
| 344 |
|
|---|
| 345 | /* Unquote filenames */
|
|---|
| 346 | GLOBAL bool unquote_option;
|
|---|
| 347 |
|
|---|
| 348 | GLOBAL bool test_label_option; /* Test archive volume label and exit */
|
|---|
| 349 |
|
|---|
| 350 | /* Show file or archive names after transformation.
|
|---|
| 351 | In particular, when creating archive in verbose mode, list member names
|
|---|
| 352 | as stored in the archive */
|
|---|
| 353 | GLOBAL bool show_transformed_names_option;
|
|---|
| 354 |
|
|---|
| 355 | /* Delay setting modification times and permissions of extracted directories
|
|---|
| 356 | until the end of extraction. This variable helps correctly restore directory
|
|---|
| 357 | timestamps from archives with an unusual member order. It is automatically
|
|---|
| 358 | set for incremental archives. */
|
|---|
| 359 | GLOBAL bool delay_directory_restore_option;
|
|---|
| 360 |
|
|---|
| 361 | /* Warn about implicit use of the wildcards in command line arguments.
|
|---|
| 362 | (Default for tar prior to 1.15.91, but changed afterwards */
|
|---|
| 363 | GLOBAL bool warn_regex_usage;
|
|---|
| 364 | |
|---|
| 365 |
|
|---|
| 366 | /* Declarations for each module. */
|
|---|
| 367 |
|
|---|
| 368 | /* FIXME: compare.c should not directly handle the following variable,
|
|---|
| 369 | instead, this should be done in buffer.c only. */
|
|---|
| 370 |
|
|---|
| 371 | enum access_mode
|
|---|
| 372 | {
|
|---|
| 373 | ACCESS_READ,
|
|---|
| 374 | ACCESS_WRITE,
|
|---|
| 375 | ACCESS_UPDATE
|
|---|
| 376 | };
|
|---|
| 377 | extern enum access_mode access_mode;
|
|---|
| 378 |
|
|---|
| 379 | /* Module buffer.c. */
|
|---|
| 380 |
|
|---|
| 381 | extern FILE *stdlis;
|
|---|
| 382 | extern bool write_archive_to_stdout;
|
|---|
| 383 | extern char *volume_label;
|
|---|
| 384 | extern char *continued_file_name;
|
|---|
| 385 | extern uintmax_t continued_file_size;
|
|---|
| 386 | extern uintmax_t continued_file_offset;
|
|---|
| 387 |
|
|---|
| 388 | size_t available_space_after (union block *pointer);
|
|---|
| 389 | off_t current_block_ordinal (void);
|
|---|
| 390 | void close_archive (void);
|
|---|
| 391 | void closeout_volume_number (void);
|
|---|
| 392 | void compute_duration (void);
|
|---|
| 393 | union block *find_next_block (void);
|
|---|
| 394 | void flush_read (void);
|
|---|
| 395 | void flush_write (void);
|
|---|
| 396 | void flush_archive (void);
|
|---|
| 397 | void init_volume_number (void);
|
|---|
| 398 | void open_archive (enum access_mode mode);
|
|---|
| 399 | void print_total_stats (void);
|
|---|
| 400 | void reset_eof (void);
|
|---|
| 401 | void set_next_block_after (union block *block);
|
|---|
| 402 | void clear_read_error_count (void);
|
|---|
| 403 | void xclose (int fd);
|
|---|
| 404 | void archive_write_error (ssize_t status) __attribute__ ((noreturn));
|
|---|
| 405 | void archive_read_error (void);
|
|---|
| 406 | off_t seek_archive (off_t size);
|
|---|
| 407 | void set_start_time (void);
|
|---|
| 408 |
|
|---|
| 409 | void mv_begin (struct tar_stat_info *st);
|
|---|
| 410 | void mv_end (void);
|
|---|
| 411 | void mv_total_size (off_t size);
|
|---|
| 412 | void mv_size_left (off_t size);
|
|---|
| 413 |
|
|---|
| 414 |
|
|---|
| 415 | /* Module create.c. */
|
|---|
| 416 |
|
|---|
| 417 | enum dump_status
|
|---|
| 418 | {
|
|---|
| 419 | dump_status_ok,
|
|---|
| 420 | dump_status_short,
|
|---|
| 421 | dump_status_fail,
|
|---|
| 422 | dump_status_not_implemented
|
|---|
| 423 | };
|
|---|
| 424 |
|
|---|
| 425 | bool file_dumpable_p (struct tar_stat_info *st);
|
|---|
| 426 | void create_archive (void);
|
|---|
| 427 | void pad_archive (off_t size_left);
|
|---|
| 428 | void dump_file (const char *st, int top_level, dev_t parent_device);
|
|---|
| 429 | union block *start_header (struct tar_stat_info *st);
|
|---|
| 430 | void finish_header (struct tar_stat_info *st, union block *header,
|
|---|
| 431 | off_t block_ordinal);
|
|---|
| 432 | void simple_finish_header (union block *header);
|
|---|
| 433 | union block * write_extended (bool global, struct tar_stat_info *st,
|
|---|
| 434 | union block *old_header);
|
|---|
| 435 | union block *start_private_header (const char *name, size_t size);
|
|---|
| 436 | void write_eot (void);
|
|---|
| 437 | void check_links (void);
|
|---|
| 438 |
|
|---|
| 439 | #define GID_TO_CHARS(val, where) gid_to_chars (val, where, sizeof (where))
|
|---|
| 440 | #define MAJOR_TO_CHARS(val, where) major_to_chars (val, where, sizeof (where))
|
|---|
| 441 | #define MINOR_TO_CHARS(val, where) minor_to_chars (val, where, sizeof (where))
|
|---|
| 442 | #define MODE_TO_CHARS(val, where) mode_to_chars (val, where, sizeof (where))
|
|---|
| 443 | #define OFF_TO_CHARS(val, where) off_to_chars (val, where, sizeof (where))
|
|---|
| 444 | #define SIZE_TO_CHARS(val, where) size_to_chars (val, where, sizeof (where))
|
|---|
| 445 | #define TIME_TO_CHARS(val, where) time_to_chars (val, where, sizeof (where))
|
|---|
| 446 | #define UID_TO_CHARS(val, where) uid_to_chars (val, where, sizeof (where))
|
|---|
| 447 | #define UINTMAX_TO_CHARS(val, where) uintmax_to_chars (val, where, sizeof (where))
|
|---|
| 448 | #define UNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf))
|
|---|
| 449 | #define GNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf))
|
|---|
| 450 |
|
|---|
| 451 | bool gid_to_chars (gid_t gid, char *buf, size_t size);
|
|---|
| 452 | bool major_to_chars (major_t m, char *buf, size_t size);
|
|---|
| 453 | bool minor_to_chars (minor_t m, char *buf, size_t size);
|
|---|
| 454 | bool mode_to_chars (mode_t m, char *buf, size_t size);
|
|---|
| 455 | bool off_to_chars (off_t off, char *buf, size_t size);
|
|---|
| 456 | bool size_to_chars (size_t v, char *buf, size_t size);
|
|---|
| 457 | bool time_to_chars (time_t t, char *buf, size_t size);
|
|---|
| 458 | bool uid_to_chars (uid_t uid, char *buf, size_t size);
|
|---|
| 459 | bool uintmax_to_chars (uintmax_t v, char *buf, size_t size);
|
|---|
| 460 | void string_to_chars (char const *s, char *buf, size_t size);
|
|---|
| 461 |
|
|---|
| 462 | /* Module diffarch.c. */
|
|---|
| 463 |
|
|---|
| 464 | extern bool now_verifying;
|
|---|
| 465 |
|
|---|
| 466 | void diff_archive (void);
|
|---|
| 467 | void diff_init (void);
|
|---|
| 468 | void verify_volume (void);
|
|---|
| 469 |
|
|---|
| 470 | /* Module extract.c. */
|
|---|
| 471 |
|
|---|
| 472 | void extr_init (void);
|
|---|
| 473 | void extract_archive (void);
|
|---|
| 474 | void extract_finish (void);
|
|---|
| 475 | bool rename_directory (char *src, char *dst);
|
|---|
| 476 |
|
|---|
| 477 | /* Module delete.c. */
|
|---|
| 478 |
|
|---|
| 479 | void delete_archive_members (void);
|
|---|
| 480 |
|
|---|
| 481 | /* Module incremen.c. */
|
|---|
| 482 |
|
|---|
| 483 | char *get_directory_contents (char *dir_name, dev_t device);
|
|---|
| 484 | const char *append_incremental_renames (const char *dump);
|
|---|
| 485 | void read_directory_file (void);
|
|---|
| 486 | void write_directory_file (void);
|
|---|
| 487 | void purge_directory (char const *directory_name);
|
|---|
| 488 | void list_dumpdir (char *buffer, size_t size);
|
|---|
| 489 | void update_parent_directory (const char *name);
|
|---|
| 490 |
|
|---|
| 491 | size_t dumpdir_size (const char *p);
|
|---|
| 492 | bool is_dumpdir (struct tar_stat_info *stat_info);
|
|---|
| 493 |
|
|---|
| 494 | /* Module list.c. */
|
|---|
| 495 |
|
|---|
| 496 | enum read_header
|
|---|
| 497 | {
|
|---|
| 498 | HEADER_STILL_UNREAD, /* for when read_header has not been called */
|
|---|
| 499 | HEADER_SUCCESS, /* header successfully read and checksummed */
|
|---|
| 500 | HEADER_SUCCESS_EXTENDED, /* likewise, but we got an extended header */
|
|---|
| 501 | HEADER_ZERO_BLOCK, /* zero block where header expected */
|
|---|
| 502 | HEADER_END_OF_FILE, /* true end of file while header expected */
|
|---|
| 503 | HEADER_FAILURE /* ill-formed header, or bad checksum */
|
|---|
| 504 | };
|
|---|
| 505 |
|
|---|
| 506 | struct xheader
|
|---|
| 507 | {
|
|---|
| 508 | struct obstack *stk;
|
|---|
| 509 | size_t size;
|
|---|
| 510 | char *buffer;
|
|---|
| 511 | };
|
|---|
| 512 |
|
|---|
| 513 | GLOBAL struct xheader extended_header;
|
|---|
| 514 | extern union block *current_header;
|
|---|
| 515 | extern enum archive_format current_format;
|
|---|
| 516 | extern size_t recent_long_name_blocks;
|
|---|
| 517 | extern size_t recent_long_link_blocks;
|
|---|
| 518 |
|
|---|
| 519 | void decode_header (union block *header, struct tar_stat_info *stat_info,
|
|---|
| 520 | enum archive_format *format_pointer, int do_user_group);
|
|---|
| 521 | char const *tartime (struct timespec t, bool full_time);
|
|---|
| 522 |
|
|---|
| 523 | #define GID_FROM_HEADER(where) gid_from_header (where, sizeof (where))
|
|---|
| 524 | #define MAJOR_FROM_HEADER(where) major_from_header (where, sizeof (where))
|
|---|
| 525 | #define MINOR_FROM_HEADER(where) minor_from_header (where, sizeof (where))
|
|---|
| 526 | #define MODE_FROM_HEADER(where) mode_from_header (where, sizeof (where))
|
|---|
| 527 | #define OFF_FROM_HEADER(where) off_from_header (where, sizeof (where))
|
|---|
| 528 | #define SIZE_FROM_HEADER(where) size_from_header (where, sizeof (where))
|
|---|
| 529 | #define TIME_FROM_HEADER(where) time_from_header (where, sizeof (where))
|
|---|
| 530 | #define UID_FROM_HEADER(where) uid_from_header (where, sizeof (where))
|
|---|
| 531 | #define UINTMAX_FROM_HEADER(where) uintmax_from_header (where, sizeof (where))
|
|---|
| 532 |
|
|---|
| 533 | gid_t gid_from_header (const char *buf, size_t size);
|
|---|
| 534 | major_t major_from_header (const char *buf, size_t size);
|
|---|
| 535 | minor_t minor_from_header (const char *buf, size_t size);
|
|---|
| 536 | mode_t mode_from_header (const char *buf, size_t size);
|
|---|
| 537 | off_t off_from_header (const char *buf, size_t size);
|
|---|
| 538 | size_t size_from_header (const char *buf, size_t size);
|
|---|
| 539 | time_t time_from_header (const char *buf, size_t size);
|
|---|
| 540 | uid_t uid_from_header (const char *buf, size_t size);
|
|---|
| 541 | uintmax_t uintmax_from_header (const char * buf, size_t size);
|
|---|
| 542 |
|
|---|
| 543 | void list_archive (void);
|
|---|
| 544 | void print_for_mkdir (char *dirname, int length, mode_t mode);
|
|---|
| 545 | void print_header (struct tar_stat_info *st, off_t block_ordinal);
|
|---|
| 546 | void read_and (void (*do_something) (void));
|
|---|
| 547 | enum read_header read_header_primitive (bool raw_extended_headers,
|
|---|
| 548 | struct tar_stat_info *info);
|
|---|
| 549 | enum read_header read_header (bool raw_extended_headers);
|
|---|
| 550 | enum read_header tar_checksum (union block *header, bool silent);
|
|---|
| 551 | void skip_file (off_t size);
|
|---|
| 552 | void skip_member (void);
|
|---|
| 553 |
|
|---|
| 554 | /* Module misc.c. */
|
|---|
| 555 |
|
|---|
| 556 | void assign_string (char **dest, const char *src);
|
|---|
| 557 | char *quote_copy_string (const char *str);
|
|---|
| 558 | int unquote_string (char *str);
|
|---|
| 559 |
|
|---|
| 560 | void code_ns_fraction (int ns, char *p);
|
|---|
| 561 | char const *code_timespec (struct timespec ts, char *sbuf);
|
|---|
| 562 | enum { BILLION = 1000000000, LOG10_BILLION = 9 };
|
|---|
| 563 | enum { TIMESPEC_STRSIZE_BOUND =
|
|---|
| 564 | UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 };
|
|---|
| 565 |
|
|---|
| 566 | enum remove_option
|
|---|
| 567 | {
|
|---|
| 568 | ORDINARY_REMOVE_OPTION,
|
|---|
| 569 | RECURSIVE_REMOVE_OPTION,
|
|---|
| 570 |
|
|---|
| 571 | /* FIXME: The following value is never used. It seems to be intended
|
|---|
| 572 | as a placeholder for a hypothetical option that should instruct tar
|
|---|
| 573 | to recursively remove subdirectories in purge_directory(),
|
|---|
| 574 | as opposed to the functionality of --recursive-unlink
|
|---|
| 575 | (RECURSIVE_REMOVE_OPTION value), which removes them in
|
|---|
| 576 | prepare_to_extract() phase. However, with the addition of more
|
|---|
| 577 | meta-info to the incremental dumps, this should become unnecessary */
|
|---|
| 578 | WANT_DIRECTORY_REMOVE_OPTION
|
|---|
| 579 | };
|
|---|
| 580 | int remove_any_file (const char *file_name, enum remove_option option);
|
|---|
| 581 | bool maybe_backup_file (const char *file_name, bool this_is_the_archive);
|
|---|
| 582 | void undo_last_backup (void);
|
|---|
| 583 |
|
|---|
| 584 | int deref_stat (bool deref, char const *name, struct stat *buf);
|
|---|
| 585 |
|
|---|
| 586 | void closeopen (void);
|
|---|
| 587 | int chdir_arg (char const *dir);
|
|---|
| 588 | void chdir_do (int dir);
|
|---|
| 589 |
|
|---|
| 590 | void close_diag (char const *name);
|
|---|
| 591 | void open_diag (char const *name);
|
|---|
| 592 | void read_diag_details (char const *name, off_t offset, size_t size);
|
|---|
| 593 | void readlink_diag (char const *name);
|
|---|
| 594 | void savedir_diag (char const *name);
|
|---|
| 595 | void seek_diag_details (char const *name, off_t offset);
|
|---|
| 596 | void stat_diag (char const *name);
|
|---|
| 597 | void write_error_details (char const *name, size_t status, size_t size);
|
|---|
| 598 | void write_fatal (char const *name) __attribute__ ((noreturn));
|
|---|
| 599 | void write_fatal_details (char const *name, ssize_t status, size_t size)
|
|---|
| 600 | __attribute__ ((noreturn));
|
|---|
| 601 |
|
|---|
| 602 | pid_t xfork (void);
|
|---|
| 603 | void xpipe (int fd[2]);
|
|---|
| 604 |
|
|---|
| 605 | void *page_aligned_alloc (void **ptr, size_t size);
|
|---|
| 606 | int set_file_atime (int fd, char const *file,
|
|---|
| 607 | struct timespec const timespec[2]);
|
|---|
| 608 |
|
|---|
| 609 | /* Module names.c. */
|
|---|
| 610 |
|
|---|
| 611 | extern struct name *gnu_list_name;
|
|---|
| 612 |
|
|---|
| 613 | void gid_to_gname (gid_t gid, char **gname);
|
|---|
| 614 | int gname_to_gid (char const *gname, gid_t *pgid);
|
|---|
| 615 | void uid_to_uname (uid_t uid, char **uname);
|
|---|
| 616 | int uname_to_uid (char const *uname, uid_t *puid);
|
|---|
| 617 |
|
|---|
| 618 | void name_init (void);
|
|---|
| 619 | void name_add_name (const char *name, int matching_flags);
|
|---|
| 620 | void name_add_dir (const char *name);
|
|---|
| 621 | void name_term (void);
|
|---|
| 622 | const char *name_next (int change_dirs);
|
|---|
| 623 | void name_gather (void);
|
|---|
| 624 | struct name *addname (char const *string, int change_dir);
|
|---|
| 625 | bool name_match (const char *name);
|
|---|
| 626 | void names_notfound (void);
|
|---|
| 627 | void collect_and_sort_names (void);
|
|---|
| 628 | struct name *name_scan (const char *name);
|
|---|
| 629 | char *name_from_list (void);
|
|---|
| 630 | void blank_name_list (void);
|
|---|
| 631 | char *new_name (const char *dir_name, const char *name);
|
|---|
| 632 | size_t stripped_prefix_len (char const *file_name, size_t num);
|
|---|
| 633 | bool all_names_found (struct tar_stat_info *st);
|
|---|
| 634 |
|
|---|
| 635 | bool excluded_name (char const *name);
|
|---|
| 636 |
|
|---|
| 637 | void add_avoided_name (char const *name);
|
|---|
| 638 | bool is_avoided_name (char const *name);
|
|---|
| 639 | bool is_individual_file (char const *name);
|
|---|
| 640 |
|
|---|
| 641 | bool contains_dot_dot (char const *name);
|
|---|
| 642 |
|
|---|
| 643 | #define ISFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \
|
|---|
| 644 | (c)->found_count == occurrence_option)
|
|---|
| 645 | #define WASFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \
|
|---|
| 646 | (c)->found_count >= occurrence_option)
|
|---|
| 647 |
|
|---|
| 648 | /* Module tar.c. */
|
|---|
| 649 |
|
|---|
| 650 | void usage (int);
|
|---|
| 651 |
|
|---|
| 652 | int confirm (const char *message_action, const char *name);
|
|---|
| 653 | void request_stdin (const char *option);
|
|---|
| 654 |
|
|---|
| 655 | void tar_stat_init (struct tar_stat_info *st);
|
|---|
| 656 | void tar_stat_destroy (struct tar_stat_info *st);
|
|---|
| 657 | void usage (int) __attribute__ ((noreturn));
|
|---|
| 658 | int tar_timespec_cmp (struct timespec a, struct timespec b);
|
|---|
| 659 | const char *archive_format_string (enum archive_format fmt);
|
|---|
| 660 | const char *subcommand_string (enum subcommand c);
|
|---|
| 661 |
|
|---|
| 662 | /* Module update.c. */
|
|---|
| 663 |
|
|---|
| 664 | extern char *output_start;
|
|---|
| 665 |
|
|---|
| 666 | void update_archive (void);
|
|---|
| 667 |
|
|---|
| 668 | /* Module xheader.c. */
|
|---|
| 669 |
|
|---|
| 670 | void xheader_decode (struct tar_stat_info *stat);
|
|---|
| 671 | void xheader_decode_global (void);
|
|---|
| 672 | void xheader_store (char const *keyword, struct tar_stat_info const *st,
|
|---|
| 673 | void const *data);
|
|---|
| 674 | void xheader_read (union block *header, size_t size);
|
|---|
| 675 | void xheader_write (char type, char *name, struct xheader *xhdr);
|
|---|
| 676 | void xheader_write_global (void);
|
|---|
| 677 | void xheader_finish (struct xheader *hdr);
|
|---|
| 678 | void xheader_destroy (struct xheader *hdr);
|
|---|
| 679 | char *xheader_xhdr_name (struct tar_stat_info *st);
|
|---|
| 680 | char *xheader_ghdr_name (void);
|
|---|
| 681 | void xheader_write (char type, char *name, struct xheader *xhdr);
|
|---|
| 682 | void xheader_write_global (void);
|
|---|
| 683 | void xheader_set_option (char *string);
|
|---|
| 684 | void xheader_string_begin (void);
|
|---|
| 685 | void xheader_string_add (char const *s);
|
|---|
| 686 | bool xheader_string_end (char const *keyword);
|
|---|
| 687 | bool xheader_keyword_deleted_p (const char *kw);
|
|---|
| 688 | char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
|
|---|
| 689 | size_t n);
|
|---|
| 690 |
|
|---|
| 691 | /* Module system.c */
|
|---|
| 692 |
|
|---|
| 693 | void sys_detect_dev_null_output (void);
|
|---|
| 694 | void sys_save_archive_dev_ino (void);
|
|---|
| 695 | void sys_drain_input_pipe (void);
|
|---|
| 696 | void sys_wait_for_child (pid_t);
|
|---|
| 697 | void sys_spawn_shell (void);
|
|---|
| 698 | bool sys_compare_uid (struct stat *a, struct stat *b);
|
|---|
| 699 | bool sys_compare_gid (struct stat *a, struct stat *b);
|
|---|
| 700 | bool sys_file_is_archive (struct tar_stat_info *p);
|
|---|
| 701 | bool sys_compare_links (struct stat *link_data, struct stat *stat_data);
|
|---|
| 702 | int sys_truncate (int fd);
|
|---|
| 703 | pid_t sys_child_open_for_compress (void);
|
|---|
| 704 | pid_t sys_child_open_for_uncompress (void);
|
|---|
| 705 | size_t sys_write_archive_buffer (void);
|
|---|
| 706 | bool sys_get_archive_stat (void);
|
|---|
| 707 | int sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st);
|
|---|
| 708 | void sys_wait_command (void);
|
|---|
| 709 | int sys_exec_info_script (const char **archive_name, int volume_number);
|
|---|
| 710 |
|
|---|
| 711 | /* Module compare.c */
|
|---|
| 712 | void report_difference (struct tar_stat_info *st, const char *message, ...);
|
|---|
| 713 |
|
|---|
| 714 | /* Module sparse.c */
|
|---|
| 715 | bool sparse_member_p (struct tar_stat_info *st);
|
|---|
| 716 | bool sparse_fixup_header (struct tar_stat_info *st);
|
|---|
| 717 | enum dump_status sparse_dump_file (int, struct tar_stat_info *st);
|
|---|
| 718 | enum dump_status sparse_extract_file (int fd, struct tar_stat_info *st,
|
|---|
| 719 | off_t *size);
|
|---|
| 720 | enum dump_status sparse_skip_file (struct tar_stat_info *st);
|
|---|
| 721 | bool sparse_diff_file (int, struct tar_stat_info *st);
|
|---|
| 722 |
|
|---|
| 723 | /* Module utf8.c */
|
|---|
| 724 | bool string_ascii_p (const char *str);
|
|---|
| 725 | bool utf8_convert (bool to_utf, char const *input, char **output);
|
|---|
| 726 |
|
|---|
| 727 | /* Module transform.c */
|
|---|
| 728 | void set_transform_expr (const char *expr);
|
|---|
| 729 | bool transform_name (char **pinput);
|
|---|
| 730 | bool transform_name_fp (char **pinput, char *(*fun)(char *));
|
|---|