Hi,

could you consider applying these patches?
I have used them for cpio-2.7-1.src.rpm.

--- cpio-2.7/src/copyin.c.chmodRaceC	2006-11-03 11:52:13.000000000 +0100
+++ cpio-2.7/src/copyin.c	2006-11-03 13:20:50.000000000 +0100
@@ -186,11 +186,12 @@
 
 static int
 try_existing_file(struct cpio_file_stat* file_hdr, int in_file_des,
-		  int *existing_dir)
+		  int *existing_dir, mode_t *existing_mode)
 {
   struct stat file_stat;
 
   *existing_dir = false;
+  *existing_mode = 0;
   if (lstat (file_hdr->c_name, &file_stat) == 0)
     {
       if (S_ISDIR (file_stat.st_mode)
@@ -200,6 +201,7 @@
 	     we are trying to create, don't complain about
 	     it.  */
 	  *existing_dir = true;
+          *existing_mode = file_stat.st_mode;
 	  return 0;
 	}
       else if (!unconditional_flag
@@ -387,10 +389,10 @@
 	  continue;
 	}
 
+      set_perms_fd (out_file_des, &d->header);
+
       if (close (out_file_des) < 0)
 	close_error (d->header.c_name);
-
-      set_perms (&d->header);
     }
 }
 
@@ -540,6 +542,9 @@
       write (out_file_des, "", 1);
       delayed_seek_count = 0;
     }
+
+  set_perms_fd (out_file_des, file_hdr);
+
   if (close (out_file_des) < 0)
     close_error (file_hdr->c_name);
 
@@ -550,8 +555,6 @@
 	       file_hdr->c_name, crc, file_hdr->c_chksum);
     }
 
-  set_perms (file_hdr);
-
   tape_skip_padding (in_file_des, file_hdr->c_filesize);
   if (file_hdr->c_nlink > 1
       && (archive_format == arf_newascii || archive_format == arf_crcascii) )
@@ -565,7 +568,7 @@
 }
 
 static void
-copyin_directory(struct cpio_file_stat* file_hdr, int existing_dir)
+copyin_directory(struct cpio_file_stat* file_hdr, int existing_dir, mode_t existing_mode)
 {
   int res;			/* Result of various function calls.  */
 #ifdef HPUX_CDF
@@ -608,14 +611,22 @@
 	  cdf_flag = 1;
 	}
 #endif
-      res = mkdir (file_hdr->c_name, file_hdr->c_mode);
+      res = mkdir (file_hdr->c_name, file_hdr->c_mode & ~077);
+    }
+   else
+    {
+      if (!no_chown_flag && (existing_mode & 077) != 0
+         && chmod (file_hdr->c_name, existing_mode & 07700) < 0)
+       {
+         error (0, errno, "%s: chmod", file_hdr->c_name);
+         return;
+       }
+      res = 0;
     }
-  else
-    res = 0;
   if (res < 0 && create_dir_flag)
     {
       create_all_directories (file_hdr->c_name);
-      res = mkdir (file_hdr->c_name, file_hdr->c_mode);
+      res = mkdir (file_hdr->c_name, file_hdr->c_mode & ~077);
     }
   if (res < 0)
     {
@@ -690,12 +701,12 @@
       return;
     }
   
-  res = mknod (file_hdr->c_name, file_hdr->c_mode,
+  res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077,
 	    makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
   if (res < 0 && create_dir_flag)
     {
       create_all_directories (file_hdr->c_name);
-      res = mknod (file_hdr->c_name, file_hdr->c_mode,
+      res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077,
 	    makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
     }
   if (res < 0)
@@ -769,9 +780,10 @@
 copyin_file (struct cpio_file_stat* file_hdr, int in_file_des)
 {
   int existing_dir;
+  mode_t existing_mode;
 
   if (!to_stdout_option
-      && try_existing_file (file_hdr, in_file_des, &existing_dir) < 0)
+      && try_existing_file (file_hdr, in_file_des, &existing_dir, &existing_mode) < 0)
     return;
 
   /* Do the real copy or link.  */
@@ -782,7 +794,7 @@
       break;
 
     case CP_IFDIR:
-      copyin_directory(file_hdr, existing_dir);
+      copyin_directory(file_hdr, existing_dir, existing_mode);
       break;
 
     case CP_IFCHR:
--- cpio-2.7/src/util.c.chmodRaceC	2006-11-03 12:22:40.000000000 +0100
+++ cpio-2.7/src/util.c	2006-11-03 12:28:54.000000000 +0100
@@ -1274,6 +1274,29 @@
 }
 
 void
+set_perms_fd (int fd, struct cpio_file_stat *header)
+{
+  if (!no_chown_flag)
+    {
+      uid_t uid = set_owner_flag ? set_owner : header->c_uid;
+      gid_t gid = set_group_flag ? set_group : header->c_gid; 
+      if ((fchown (fd, uid, gid) < 0) && errno != EPERM)
+	chown_error_details (header->c_name, uid, gid);
+    }
+  /* chown may have turned off some permissions we wanted. */
+  if (fchmod (fd, header->c_mode) < 0)
+    chmod_error_details (header->c_name, header->c_mode);
+#ifdef HPUX_CDF
+  if ((header->c_mode & CP_IFMT) && cdf_flag)
+    /* Once we "hide" the directory with the chmod(),
+       we have to refer to it using name+ instead of name.  */
+    file_hdr->c_name [cdf_char] = '+';
+#endif
+  if (retain_time_flag)
+    set_file_times (header->c_name, header->c_mtime, header->c_mtime);
+}
+
+void
 set_file_times (const char *name, unsigned long atime, unsigned long mtime)
 {
   struct timespec ts[2];
--- cpio-2.7/src/copypass.c.chmodRaceC	2006-11-03 13:21:05.000000000 +0100
+++ cpio-2.7/src/copypass.c	2006-11-03 13:49:44.000000000 +0100
@@ -42,6 +42,15 @@
   set_perms (&header);
 }
 
+static void
+set_copypass_perms_fd (int fd, const char *name, struct stat *st)
+{
+  struct cpio_file_stat header;
+  header.c_name = name;
+  stat_to_cpio (&header, st);
+  set_perms_fd (fd, &header);
+}
+
 /* Copy files listed on the standard input into directory `directory_name'.
    If `link_flag', link instead of copying.  */
 
@@ -194,10 +203,12 @@
 		}
 	      if (close (in_file_des) < 0)
 		close_error (input_name.ds_string);
+
+	      set_copypass_perms_fd (out_file_des, output_name.ds_string, &out_file_stat);
+
 	      if (close (out_file_des) < 0)
 		close_error (output_name.ds_string);
 
-	      set_copypass_perms (input_name.ds_string, &in_file_stat);
 
 	      if (reset_time_flag)
                 {
@@ -232,15 +243,23 @@
 		  cdf_flag = 1;
 		}
 #endif
-	      res = mkdir (output_name.ds_string, in_file_stat.st_mode);
+	      res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077);
 
 	    }
 	  else
-	    res = 0;
+            {
+              if (!no_chown_flag && (out_file_stat.st_mode & 077) != 0
+                  && chmod (output_name.ds_string, out_file_stat.st_mode & 07700) < 0)
+                {
+                  error (0, errno, "%s: chmod", output_name.ds_string);
+                  continue;
+                }
+              res = 0;
+            }
 	  if (res < 0 && create_dir_flag)
 	    {
 	      create_all_directories (output_name.ds_string);
-	      res = mkdir (output_name.ds_string, in_file_stat.st_mode);
+	      res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077);
 	    }
 	  if (res < 0)
 	    {
@@ -283,12 +302,12 @@
 
 	  if (link_res < 0)
 	    {
-	      res = mknod (output_name.ds_string, in_file_stat.st_mode,
+	      res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077,
 			   in_file_stat.st_rdev);
 	      if (res < 0 && create_dir_flag)
 		{
 		  create_all_directories (output_name.ds_string);
-		  res = mknod (output_name.ds_string, in_file_stat.st_mode,
+		  res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077,
 			       in_file_stat.st_rdev);
 		}
 	      if (res < 0)
--- cpio-2.7/src/util.c.lfs	2006-09-28 10:49:21.000000000 +0200
+++ cpio-2.7/src/util.c	2006-11-08 10:35:09.000000000 +0100
@@ -384,10 +384,10 @@
 /* Skip the next NUM_BYTES bytes of file descriptor IN_DES.  */
 
 void
-tape_toss_input (int in_des, long num_bytes)
+tape_toss_input (int in_des, off_t num_bytes)
 {
-  register long bytes_left = num_bytes;	/* Bytes needing to be copied.  */
-  register long space_left;	/* Bytes to copy from input buffer.  */
+  off_t bytes_left = num_bytes;	/* Bytes needing to be copied.  */
+  off_t space_left;	/* Bytes to copy from input buffer.  */
 
   while (bytes_left > 0)
     {
@@ -565,7 +565,7 @@
 /* Warn if file changed while it was being copied.  */
 
 void
-warn_if_file_changed (char *file_name, unsigned long old_file_size,
+warn_if_file_changed (char *file_name, off_t old_file_size,
 		      unsigned long old_file_mtime)
 {
   struct stat new_file_stat;
--- cpio-2.7/src/copyin.c.lfs	2006-09-27 10:19:44.000000000 +0200
+++ cpio-2.7/src/copyin.c	2006-11-08 10:35:09.000000000 +0100
@@ -854,7 +854,7 @@
     printf ("%3lu, %3lu ", file_hdr->c_rdev_maj,
 	    file_hdr->c_rdev_min);
   else
-    printf ("%8lu ", file_hdr->c_filesize);
+    printf ("%8llu ", file_hdr->c_filesize);
 
   printf ("%s ", tbuf + 4);
 
--- cpio-2.7/src/extern.h.lfs	2006-09-27 10:19:44.000000000 +0200
+++ cpio-2.7/src/extern.h	2006-11-08 10:35:09.000000000 +0100
@@ -162,11 +162,11 @@
 void tape_buffered_write (char *in_buf, int out_des, off_t num_bytes);
 void tape_buffered_read (char *in_buf, int in_des, off_t num_bytes);
 int tape_buffered_peek (char *peek_buf, int in_des, int num_bytes);
-void tape_toss_input (int in_des, long num_bytes);
+void tape_toss_input (int in_des, off_t num_bytes);
 void copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes);
 void copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes, char *filename);
 void copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes, char *filename);
-void warn_if_file_changed (char *file_name, unsigned long old_file_size,
+void warn_if_file_changed (char *file_name, off_t old_file_size,
                            unsigned long old_file_mtime);
 void create_all_directories (char *name);
 void prepare_append (int out_file_des);
--- cpio-2.7/src/copyout.c.lfs	2006-11-08 10:35:24.000000000 +0100
+++ cpio-2.7/src/copyout.c	2006-11-08 10:35:48.000000000 +0100
@@ -508,7 +508,7 @@
   short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
   short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
 
-  if ((short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1]
+  if (( (off_t) short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1]
        != file_hdr->c_filesize)
     {
       field_width_error (file_hdr->c_name, _("file size"));
--- cpio-2.7/src/util.c.warnings	2006-11-03 15:27:03.000000000 +0100
+++ cpio-2.7/src/util.c	2006-11-03 15:32:52.000000000 +0100
@@ -98,6 +98,8 @@
   output_size = 0;
 }
 
+int sparse_write (int fildes, char *buf, unsigned int nbyte);
+
 /* Write `output_size' bytes of `output_buffer' to file
    descriptor OUT_DES and reset `output_size' and `out_buff'.
    If `swapping_halfwords' or `swapping_bytes' is set,
@@ -1111,8 +1113,8 @@
   int complete_block_count;
   int leftover_bytes_count;
   int seek_count;
-  int write_count;
-  char *cur_write_start;
+  int write_count = 0;
+  char *cur_write_start = buf;
   int lseek_rc;
   int write_rc;
   int i;
--- cpio-2.7/src/copyout.c.exitCode	2006-11-03 15:47:47.000000000 +0100
+++ cpio-2.7/src/copyout.c	2006-11-03 15:48:33.000000000 +0100
@@ -296,7 +296,7 @@
 static void
 field_width_error (const char *filename, const char *fieldname)
 {
-  error (0, 0, _("%s: field width not sufficient for storing %s"),
+  error (1, 0, _("%s: field width not sufficient for storing %s"),
 	 filename, fieldname);
 }
 
_______________________________________________
Bug-cpio mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-cpio

Reply via email to