1
0
Эх сурвалжийг харах

Add cpio -R, tweak help text.

Rob Landley 2 жил өмнө
parent
commit
d94bda4bab
1 өөрчлөгдсөн 23 нэмэгдсэн , 10 устгасан
  1. 23 10
      toys/posix/cpio.c

+ 23 - 10
toys/posix/cpio.c

@@ -16,33 +16,33 @@
  *
  * todo: export/import linux file list text format ala gen_initramfs_list.sh
 
-USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)R(owner):md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
 
 config CPIO
   bool "cpio"
   default y
   help
-    usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [--no-preserve-owner]
-           [ignored: -m -H newc]
+    usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [-R [USER][:GROUP] [--no-preserve-owner]
 
     Copy files into and out of a "newc" format cpio archive.
 
+    -d	Create directories if needed
     -F FILE	Use archive FILE instead of stdin/stdout
-    -p DEST	Copy-pass mode, copy stdin file list to directory DEST
     -i	Extract from archive into file system (stdin=archive)
     -o	Create archive (stdin=list of files, stdout=archive)
+    -p DEST	Copy-pass mode, copy stdin file list to directory DEST
+    -R USER	Replace owner with USER[:GROUP]
     -t	Test files (list only, stdin=archive, stdout=list of files)
-    -d	Create directories if needed
-    -u	unlink existing files when extracting
+    -u	Unlink existing files when extracting
     -v	Verbose
-    --no-preserve-owner (don't set ownership during extract)
+    --no-preserve-owner     Don't set ownership during extract
 */
 
 #define FOR_cpio
 #include "toys.h"
 
 GLOBALS(
-  char *F, *H;
+  char *F, *H, *R;
 )
 
 // Read strings, tail padded to 4 byte alignment. Argument "align" is amount
@@ -83,6 +83,17 @@ void cpio_main(void)
   // Subtle bit: FLAG_o is 1 so we can just use it to select stdin/stdout.
   int pipe, afd = FLAG(o), empty = 1;
   pid_t pid = 0;
+  long Ruid = -1, Rgid = -1;
+
+  if (TT.R) {
+    char *group = TT.R+strcspn(TT.R, ":.");
+
+    if (*group) {
+      Rgid = xgetgid(group+1);
+      *group = 0;
+    }
+    if (group != TT.R) Ruid = xgetuid(TT.R);
+  }
 
   // In passthrough mode, parent stays in original dir and generates archive
   // to pipe, child does chdir to new dir and reads archive from stdin (pipe).
@@ -145,8 +156,8 @@ void cpio_main(void)
 
     size = x8u(toybuf+54);
     mode = x8u(toybuf+14);
-    uid = x8u(toybuf+22);
-    gid = x8u(toybuf+30);
+    uid = (Ruid>=0) ? Ruid : x8u(toybuf+22);
+    gid = (Rgid>=0) ? Rgid : x8u(toybuf+30);
     timestamp = x8u(toybuf+46); // unsigned 32 bit, so year 2100 problem
 
     // (This output is unaffected by --quiet.)
@@ -266,6 +277,8 @@ void cpio_main(void)
       // encrypted filesystems can stat the wrong link size
       if (link) st.st_size = strlen(link);
 
+      if (Ruid>=0) st.st_uid = Ruid;
+      if (Rgid>=0) st.st_gid = Rgid;
       if (FLAG(no_preserve_owner)) st.st_uid = st.st_gid = 0;
       if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) st.st_size = 0;
       if (st.st_size >> 32) perror_msg("skipping >2G file '%s'", name);