It appears I've forgotten to send the attachment. Here it goes.
Regards,
Sergey
diff --git a/src/common.h b/src/common.h
index b9d2ae48..eede95f4 100644
--- a/src/common.h
+++ b/src/common.h
@@ -521,6 +521,8 @@ bool cachedir_file_p (int fd);
char *get_directory_entries (struct tar_stat_info *st)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
+void dump_incremental (void);
+
void create_archive (void);
void pad_archive (off_t size_left);
void dump_file (struct tar_stat_info *parent, char const *name,
diff --git a/src/create.c b/src/create.c
index 078c77e1..dd26736b 100644
--- a/src/create.c
+++ b/src/create.c
@@ -1295,78 +1295,81 @@ static nlink_t trivial_link_count;
/* Main functions of this module. */
void
-create_archive (void)
+dump_incremental (void)
{
+ idx_t buffer_size = 0;
+ char *buffer = NULL;
+ const char *q;
struct name const *p;
- trivial_link_count = filename_args != FILES_MANY && ! dereference_option;
-
- open_archive (ACCESS_WRITE);
- buffer_write_global_xheader ();
-
- if (incremental_option)
- {
- idx_t buffer_size = 0;
- char *buffer = NULL;
- const char *q;
+ collect_and_sort_names ();
- collect_and_sort_names ();
+ while ((p = name_from_list ()) != NULL)
+ if (!excluded_name (p->name, NULL))
+ dump_file (0, p->name, p->name);
- while ((p = name_from_list ()) != NULL)
- if (!excluded_name (p->name, NULL))
- dump_file (0, p->name, p->name);
-
- blank_name_list ();
- while ((p = name_from_list ()) != NULL)
- if (!excluded_name (p->name, NULL))
- {
- struct tar_stat_info st;
- idx_t plen = strlen (p->name);
- if (buffer_size <= plen)
- buffer = xpalloc (buffer, &buffer_size,
- plen - buffer_size + 1, -1, 1);
- memcpy (buffer, p->name, plen);
- if (! ISSLASH (buffer[plen - 1]))
- buffer[plen++] = DIRECTORY_SEPARATOR;
- tar_stat_init (&st);
- q = directory_contents (p->directory);
- if (q)
- while (*q)
+ blank_name_list ();
+ while ((p = name_from_list ()) != NULL)
+ if (!excluded_name (p->name, NULL))
+ {
+ struct tar_stat_info st;
+ idx_t plen = strlen (p->name);
+ if (buffer_size <= plen)
+ buffer = xpalloc (buffer, &buffer_size,
+ plen - buffer_size + 1, -1, 1);
+ memcpy (buffer, p->name, plen);
+ if (! ISSLASH (buffer[plen - 1]))
+ buffer[plen++] = DIRECTORY_SEPARATOR;
+ tar_stat_init (&st);
+ q = directory_contents (p->directory);
+ if (q)
+ while (*q)
+ {
+ idx_t qlen = strlen (q);
+ if (*q == 'Y')
{
- idx_t qlen = strlen (q);
- if (*q == 'Y')
+ if (! st.orig_file_name)
{
- if (! st.orig_file_name)
+ int fd = openat (chdir_fd, p->name,
+ open_searchdir_flags);
+ if (fd < 0)
{
- int fd = openat (chdir_fd, p->name,
- open_searchdir_flags);
- if (fd < 0)
- {
- file_removed_diag (p->name, !p->parent,
- open_diag);
- break;
- }
- st.fd = fd;
- if (fstat (fd, &st.stat) < 0)
- {
- file_removed_diag (p->name, !p->parent,
- stat_diag);
- break;
- }
- st.orig_file_name = xstrdup (p->name);
+ file_removed_diag (p->name, !p->parent,
+ open_diag);
+ break;
}
- if (buffer_size < plen + qlen)
- buffer = xpalloc (buffer, &buffer_size,
- plen + qlen - buffer_size, -1, 1);
- strcpy (buffer + plen, q + 1);
- dump_file (&st, q + 1, buffer);
+ st.fd = fd;
+ if (fstat (fd, &st.stat) < 0)
+ {
+ file_removed_diag (p->name, !p->parent,
+ stat_diag);
+ break;
+ }
+ st.orig_file_name = xstrdup (p->name);
}
- q += qlen + 1;
+ if (buffer_size < plen + qlen)
+ buffer = xpalloc (buffer, &buffer_size,
+ plen + qlen - buffer_size, -1, 1);
+ strcpy (buffer + plen, q + 1);
+ dump_file (&st, q + 1, buffer);
}
- tar_stat_destroy (&st);
- }
- free (buffer);
- }
+ q += qlen + 1;
+ }
+ tar_stat_destroy (&st);
+ }
+ free (buffer);
+}
+
+void
+create_archive (void)
+{
+ trivial_link_count = filename_args != FILES_MANY && ! dereference_option;
+
+ open_archive (ACCESS_WRITE);
+ buffer_write_global_xheader ();
+
+ if (incremental_option)
+ dump_incremental ();
else
{
const char *name;
diff --git a/src/update.c b/src/update.c
index c74d3baa..0b13f913 100644
--- a/src/update.c
+++ b/src/update.c
@@ -208,7 +208,10 @@ update_archive (void)
time_to_start_writing = true;
output_start = charptr (current_block);
- {
+ if (subcommand_option == APPEND_SUBCOMMAND && incremental_option)
+ dump_incremental ();
+ else
+ {
struct name const *p;
while ((p = name_from_list ()) != NULL)
{
@@ -228,4 +231,6 @@ update_archive (void)
close_archive ();
finish_deferred_unlinks ();
names_notfound ();
+ if (subcommand_option == APPEND_SUBCOMMAND && listed_incremental_option)
+ write_directory_file ();
}