X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=0a6bacf183aac19b32ccb8acff57dd5696b39d30;hb=37ddfb0b7eb41cc3f58bce686d389b1e965e9ccf;hp=6777f9cc078eac7b4c544a03d7a8b072d6d642ca;hpb=0ab5e64ac07d5b0162bf863f4da485d26760a8eb;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index 6777f9c..0a6bacf 100644 --- a/src/create.c +++ b/src/create.c @@ -30,7 +30,7 @@ struct link { dev_t dev; ino_t ino; - size_t nlink; + nlink_t nlink; char name[1]; }; @@ -214,6 +214,14 @@ to_base256 (int negative, uintmax_t value, char *where, size_t size) while (i); } +#define GID_TO_CHARS(val, where) gid_to_chars (val, where, sizeof (where)) +#define MAJOR_TO_CHARS(val, where) major_to_chars (val, where, sizeof (where)) +#define MINOR_TO_CHARS(val, where) minor_to_chars (val, where, sizeof (where)) +#define MODE_TO_CHARS(val, where) mode_to_chars (val, where, sizeof (where)) +#define UID_TO_CHARS(val, where) uid_to_chars (val, where, sizeof (where)) +#define UINTMAX_TO_CHARS(val, where) uintmax_to_chars (val, where, sizeof (where)) +#define UNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf)) +#define GNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf)) static bool to_chars (int negative, uintmax_t value, size_t valsize, @@ -368,25 +376,25 @@ gid_substitute (int *negative) return r; } -bool +static bool gid_to_chars (gid_t v, char *p, size_t s) { return to_chars (v < 0, (uintmax_t) v, sizeof v, gid_substitute, p, s, "gid_t"); } -bool +static bool major_to_chars (major_t v, char *p, size_t s) { return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t"); } -bool +static bool minor_to_chars (minor_t v, char *p, size_t s) { return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t"); } -bool +static bool mode_to_chars (mode_t v, char *p, size_t s) { /* In the common case where the internal and external mode bits are the same, @@ -460,19 +468,19 @@ uid_substitute (int *negative) return r; } -bool +static bool uid_to_chars (uid_t v, char *p, size_t s) { return to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t"); } -bool +static bool uintmax_to_chars (uintmax_t v, char *p, size_t s) { return to_chars (0, v, sizeof v, 0, p, s, "uintmax_t"); } -void +static void string_to_chars (char const *str, char *p, size_t s) { tar_copy_str (p, str, s); @@ -487,7 +495,7 @@ string_to_chars (char const *str, char *p, size_t s) a) it is empty *and* world-readable, or b) current archive is /dev/null */ -bool +static bool file_dumpable_p (struct tar_stat_info *st) { if (dev_null_output) @@ -1257,6 +1265,12 @@ dump_dir (int fd, struct tar_stat_info *st, bool top_level, return true; } + +/* Number of links a file can have without having to be entered into + the link table. Typically this is 1, but in trickier circumstances + it is 0. */ +static nlink_t trivial_link_count; + /* Main functions of this module. */ @@ -1265,6 +1279,8 @@ create_archive (void) { struct name const *p; + trivial_link_count = name_count <= 1 && ! dereference_option; + open_archive (ACCESS_WRITE); buffer_write_global_xheader (); @@ -1372,7 +1388,8 @@ static Hash_table *link_table; static bool dump_hard_link (struct tar_stat_info *st) { - if (link_table && (st->stat.st_nlink > 1 || remove_files_option)) + if (link_table + && (trivial_link_count < st->stat.st_nlink || remove_files_option)) { struct link lp; struct link *duplicate; @@ -1419,7 +1436,7 @@ file_count_links (struct tar_stat_info *st) { if (hard_dereference_option) return; - if (st->stat.st_nlink > 1) + if (trivial_link_count < st->stat.st_nlink) { struct link *duplicate; char *linkname = NULL;