aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/cpio.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2021-03-01 19:03:49 -0600
committerRob Landley <rob@landley.net>2021-03-01 19:03:49 -0600
commitf1be076b52adcad7b2419315cc148009a1bc2fec (patch)
treebd4ea668dfe3006102a826617647c2edbfa79838 /toys/posix/cpio.c
parent50f604f415d77b3679df1f8d9d3856f9840998be (diff)
downloadtoybox-f1be076b52adcad7b2419315cc148009a1bc2fec.tar.gz
Yi-yo Chiang wants cpio -u implemented, and sent some tests.
Diffstat (limited to 'toys/posix/cpio.c')
-rw-r--r--toys/posix/cpio.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c
index 04700ddb..b60e19b4 100644
--- a/toys/posix/cpio.c
+++ b/toys/posix/cpio.c
@@ -22,7 +22,7 @@ config CPIO
default y
help
usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [--no-preserve-owner]
- [ignored: -mdu -H newc]
+ [ignored: -m -H newc]
Copy files into and out of a "newc" format cpio archive.
@@ -32,6 +32,7 @@ config CPIO
-o Create archive (stdin=list of files, stdout=archive)
-t Test files (list only, stdin=archive, stdout=list of files)
-d Create directories if needed
+ -u unlink existing files when extracting
-v Verbose
--no-preserve-owner (don't set ownership during extract)
*/
@@ -137,6 +138,8 @@ void cpio_main(void)
// (This output is unaffected by --quiet.)
if (FLAG(t) || FLAG(v)) puts(name);
+ if (FLAG(u) && !test) if (unlink(name) && errno == EISDIR) rmdir(name);
+
if (!test && FLAG(d) && strrchr(name, '/') && mkpath(name)) {
perror_msg("mkpath '%s'", name);
test++;
@@ -146,7 +149,7 @@ void cpio_main(void)
// properly aligned with next file.
if (S_ISDIR(mode)) {
- if (!test) err = mkdir(name, mode);
+ if (!test) err = mkdir(name, mode) && !FLAG(u);
} else if (S_ISLNK(mode)) {
data = strpad(afd, size, 0);
if (!test) err = symlink(data, name);
@@ -155,7 +158,7 @@ void cpio_main(void)
if (!err && !geteuid() && !FLAG(no_preserve_owner))
err = lchown(name, uid, gid);
} else if (S_ISREG(mode)) {
- int fd = test ? 0 : open(name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, mode);
+ int fd = test ? 0 : open(name, O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, mode);
// If write fails, we still need to read/discard data to continue with
// archive. Since doing so overwrites errno, report error now