X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=42c82fffe71d2a7b9716cf42ca6e31f7506f965f;hb=2eaf29f3fb63f1214b260f2e72d22447a5ae419b;hp=c6d78b280e9399f45881a8ac93e4230c62670b93;hpb=36682e50ccd859bb82bff444c4c68ff587966dc8;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index c6d78b2..42c82ff 100644 --- a/src/create.c +++ b/src/create.c @@ -114,25 +114,38 @@ to_chars (int negative, uintmax_t value, size_t valsize, { uintmax_t v = negative ? -value : value; + /* Generate the POSIX octal representation if the number fits. */ if (! negative && v <= MAX_VAL_WITH_DIGITS (size - 1, LG_8)) { where[size - 1] = '\0'; to_base (v, LG_8, base_8_digits, where, size - 1); } + + /* Otherwise, generate the GNU base-64 representation if we are + generating an old or new GNU format and if the number fits. */ else if (v <= MAX_VAL_WITH_DIGITS (size - 1, LG_64) - && archive_format == GNU_FORMAT) + && (archive_format == GNU_FORMAT + || archive_format == OLDGNU_FORMAT)) { where[0] = negative ? '-' : '+'; to_base (v, LG_64, base_64_digits, where + 1, size - 1); } - else if (negative - && archive_format != GNU_FORMAT - && valsize * CHAR_BIT <= (size - 1) * LG_8) + + /* Otherwise, if the number is negative, and if it would not cause + ambiguity on this host by confusing positive with negative + values, then generate the POSIX octal representation of the value + modulo 2**(field bits). The resulting tar file is + machine-dependent, since it depends on the host word size. Yuck! + But this is the traditional behavior. */ + else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8) { where[size - 1] = '\0'; to_base (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1), LG_8, base_8_digits, where, size - 1); } + + /* Otherwise, output a substitute value if possible (with a + warning), and an error message if not. */ else { uintmax_t maxval = (archive_format == GNU_FORMAT @@ -298,7 +311,7 @@ clear_buffer (char *buffer) } /*-------------------------------------------------------------------------. -| Write the EOT block(s). We actually zero at least one block, through | +| Write the EOT block(s). We zero at least two blocks, through | | the end of the record. Old tar, as previous versions of GNU tar, writes | | garbage after two zeroed blocks. | `-------------------------------------------------------------------------*/ @@ -307,14 +320,11 @@ void write_eot (void) { union block *pointer = find_next_block (); - - if (pointer) - { - size_t space = available_space_after (pointer); - - memset (pointer->buffer, 0, space); - set_next_block_after (pointer); - } + memset (pointer->buffer, 0, BLOCKSIZE); + set_next_block_after (pointer); + pointer = find_next_block (); + memset (pointer->buffer, 0, available_space_after (pointer)); + set_next_block_after (pointer); } /*-----------------------------------------------------. @@ -372,28 +382,29 @@ start_header (const char *name, struct stat *st) if (!absolute_names_option) { - static int warned_once = 0; size_t prefix_len = FILESYSTEM_PREFIX_LEN (name); if (prefix_len) { - name += prefix_len; + static int warned_once; if (!warned_once) { warned_once = 1; - WARN ((0, 0, _("Removing filesystem prefix from names in the archive"))); + WARN ((0, 0, _("Removing `%.*s' prefix from archive names"), + (int) prefix_len, name)); } + name += prefix_len; } while (*name == '/') { - name++; /* force relative path */ + static int warned_once; if (!warned_once) { warned_once = 1; - WARN ((0, 0, _("\ -Removing leading `/' from absolute path names in the archive"))); + WARN ((0, 0, _("Removing leading `/' from archive names"))); } + name++; } } @@ -765,8 +776,8 @@ finish_sparse_file (int file, off_t *sizeleft, off_t fullsize, char *name) if (count < 0) { char buf[UINTMAX_STRSIZE_BOUND]; - ERROR ((0, errno, _("\ -Read error at byte %s, reading %lu bytes, in file %s"), + ERROR ((0, errno, + _("Read error at byte %s, reading %lu bytes, in file %s"), STRINGIFY_BIGINT (fullsize - *sizeleft, buf), (unsigned long) bufsize, name)); return 1; @@ -851,22 +862,21 @@ create_archive (void) blank_name_list (); while (p = name_from_list (), p) - { - strcpy (buffer, p); - if (p[strlen (p) - 1] != '/') - strcat (buffer, "/"); - bufp = buffer + strlen (buffer); - for (q = gnu_list_name->dir_contents; - q && *q; - q += strlen (q) + 1) - { - if (*q == 'Y') - { - strcpy (bufp, q + 1); - dump_file (buffer, (dev_t) -1, 1); - } - } - } + if (!excluded_name (p)) + { + strcpy (buffer, p); + if (p[strlen (p) - 1] != '/') + strcat (buffer, "/"); + bufp = buffer + strlen (buffer); + q = gnu_list_name->dir_contents; + if (q) + for (; *q; q += strlen (q) + 1) + if (*q == 'Y') + { + strcpy (bufp, q + 1); + dump_file (buffer, (dev_t) -1, 1); + } + } free (buffer); } else @@ -945,14 +955,15 @@ dump_file (char *p, dev_t parent_device, int top_level) } #endif - /* See if we only want new files, and check if this one is too old to + /* See if we want only new files, and check if this one is too old to put in the archive. */ - if (!incremental_option && !S_ISDIR (current_stat.st_mode) + if ((!incremental_option || listed_incremental_option) + && !S_ISDIR (current_stat.st_mode) && current_stat.st_mtime < newer_mtime_option && (!after_date_option || current_stat.st_ctime < newer_ctime_option)) { - if (parent_device == (dev_t) -1) + if (!listed_incremental_option && parent_device == (dev_t) -1) WARN ((0, 0, _("%s: is unchanged; not dumped"), p)); /* FIXME: recheck this return. */ return; @@ -994,13 +1005,11 @@ dump_file (char *p, dev_t parent_device, int top_level) while (!absolute_names_option && *link_name == '/') { - static int warned_once = 0; - + static int warned_once; if (!warned_once) { warned_once = 1; - WARN ((0, 0, _("\ -Removing leading `/' from absolute links"))); + WARN ((0, 0, _("Removing leading `/' from link names"))); } link_name++; } @@ -1282,8 +1291,8 @@ Removing leading `/' from absolute links"))); if (count < 0) { char buf[UINTMAX_STRSIZE_BOUND]; - ERROR ((0, errno, _("\ -Read error at byte %s, reading %lu bytes, in file %s"), + ERROR ((0, errno, + _("Read error at byte %s, reading %lu bytes, in file %s"), STRINGIFY_BIGINT (current_stat.st_size - sizeleft, buf), (unsigned long) bufsize, p)); @@ -1550,11 +1559,6 @@ Read error at byte %s, reading %lu bytes, in file %s"), return; } - /* Hack to remove "./" from the front of all the file names. */ - - if (len == 2 && namebuf[0] == '.' && namebuf[1] == '/') - len = 0; - /* FIXME: Should speed this up by cd-ing into the dir. */ while (entry = readdir (directory), entry)