X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=245b6c3a88254d7c265b4e26d8f77b922623b4ce;hb=f74cab3a936190a65d57c82fea5b1a05affee60a;hp=35022364ae436eae4cee5af94ba0ef21eadb885b;hpb=a0eb52da3fe6b9279591b4aeffff0672369b72a5;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index 3502236..245b6c3 100644 --- a/src/create.c +++ b/src/create.c @@ -58,7 +58,7 @@ add_exclusion_tag (const char *name, enum exclusion_tag_type type, exclusion_tags = tag; } -static void +void exclusion_tag_warning (const char *dirname, const char *tagname, const char *message) { @@ -70,18 +70,19 @@ exclusion_tag_warning (const char *dirname, const char *tagname, message)); } -static enum exclusion_tag_type +enum exclusion_tag_type check_exclusion_tags (char *dirname, const char **tag_file_name) { static char *tagname; static size_t tagsize; struct exclusion_tag *tag; size_t dlen = strlen (dirname); + int addslash = dirname[dlen-1] != '/'; char *nptr = NULL; for (tag = exclusion_tags; tag; tag = tag->next) { - size_t size = dlen + tag->length + 1; + size_t size = dlen + addslash + tag->length + 1; if (size > tagsize) { tagsize = size; @@ -92,6 +93,8 @@ check_exclusion_tags (char *dirname, const char **tag_file_name) { strcpy (tagname, dirname); nptr = tagname + dlen; + if (addslash) + *nptr++ = '/'; } strcpy (nptr, tag->name); if (access (tagname, F_OK) == 0 @@ -1038,7 +1041,7 @@ dump_regular_file (int fd, struct tar_stat_info *st) while (size_left > 0) { size_t bufsize, count; - + mv_size_left (size_left); blk = find_next_block (); @@ -1063,8 +1066,7 @@ dump_regular_file (int fd, struct tar_stat_info *st) return dump_status_short; } size_left -= count; - if (count) - set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); + set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); if (count != bufsize) { @@ -1078,7 +1080,7 @@ dump_regular_file (int fd, struct tar_stat_info *st) STRINGIFY_BIGINT (size_left, buf))); if (! ignore_failed_read_option) exit_status = TAREXIT_DIFFERS; - pad_archive (size_left - (bufsize-count)); + pad_archive (size_left - (bufsize - count)); return dump_status_short; } } @@ -1182,8 +1184,11 @@ dump_dir0 (char *directory, switch (check_exclusion_tags (st->orig_file_name, &tag_file_name)) { - case exclusion_tag_none: case exclusion_tag_all: + /* Handled in dump_file0 */ + break; + + case exclusion_tag_none: { char const *entry; size_t entry_len; @@ -1417,22 +1422,31 @@ dump_hard_link (struct tar_stat_info *st) static void file_count_links (struct tar_stat_info *st) { + if (hard_dereference_option) + return; if (st->stat.st_nlink > 1) { struct link *duplicate; - struct link *lp = xmalloc (offsetof (struct link, name) - + strlen (st->orig_file_name) + 1); + char *linkname = NULL; + struct link *lp; + + assign_string (&linkname, st->orig_file_name); + transform_name (&linkname, XFORM_LINK); + + lp = xmalloc (offsetof (struct link, name) + + strlen (linkname) + 1); lp->ino = st->stat.st_ino; lp->dev = st->stat.st_dev; lp->nlink = st->stat.st_nlink; - strcpy (lp->name, st->orig_file_name); - + strcpy (lp->name, linkname); + free (linkname); + if (! ((link_table || (link_table = hash_initialize (0, 0, hash_link, compare_links, 0))) && (duplicate = hash_insert (link_table, lp)))) xalloc_die (); - + if (duplicate != lp) abort (); lp->nlink--; @@ -1488,7 +1502,7 @@ dump_file0 (struct tar_stat_info *st, const char *p, assign_string (&st->file_name, safer_name_suffix (p, false, absolute_names_option)); - transform_name (&st->file_name); + transform_name (&st->file_name, XFORM_REGFILE); if (deref_stat (dereference_option, p, &st->stat) != 0) { @@ -1609,6 +1623,7 @@ dump_file0 (struct tar_stat_info *st, const char *p, case dump_status_ok: case dump_status_short: mv_end (); + file_count_links (st); break; case dump_status_fail: @@ -1618,8 +1633,6 @@ dump_file0 (struct tar_stat_info *st, const char *p, abort (); } - file_count_links (st); - ok = status == dump_status_ok; } @@ -1699,6 +1712,7 @@ dump_file0 (struct tar_stat_info *st, const char *p, } buffer[size] = '\0'; assign_string (&st->link_name, buffer); + transform_name (&st->link_name, XFORM_SYMLINK); if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size) write_long_link (st); @@ -1707,7 +1721,7 @@ dump_file0 (struct tar_stat_info *st, const char *p, header = start_header (st); if (!header) return; - tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE); + tar_copy_str (header->header.linkname, st->link_name, NAME_FIELD_SIZE); header->header.typeflag = SYMTYPE; finish_header (st, header, block_ordinal); /* nothing more to do to it */