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 ();
 }

Reply via email to