aboutsummaryrefslogtreecommitdiffstats
path: root/cpio/cpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpio/cpio.c')
-rw-r--r--cpio/cpio.c96
1 files changed, 67 insertions, 29 deletions
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 29f405c091ee..025c50cfafd2 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -50,9 +50,15 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
@@ -69,9 +75,6 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
@@ -136,6 +139,16 @@ main(int argc, char *argv[])
cpio->buff = buff;
cpio->buff_size = sizeof(buff);
+#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
+ { /* Ignore SIGPIPE signals. */
+ struct sigaction sa;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+ }
+#endif
+
/* Need lafe_progname before calling lafe_warnc. */
if (*argv == NULL)
lafe_progname = "bsdcpio";
@@ -150,6 +163,10 @@ main(int argc, char *argv[])
else
lafe_progname = *argv;
}
+#if HAVE_SETLOCALE
+ if (setlocale(LC_ALL, "") == NULL)
+ lafe_warnc(0, "Failed to set default locale");
+#endif
cpio->uid_override = -1;
cpio->gid_override = -1;
@@ -187,9 +204,9 @@ main(int argc, char *argv[])
cpio->bytes_per_block = 5120;
break;
case 'C': /* NetBSD/OpenBSD */
- cpio->bytes_per_block = atoi(cpio->optarg);
+ cpio->bytes_per_block = atoi(cpio->argument);
if (cpio->bytes_per_block <= 0)
- lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
+ lafe_errc(1, 0, "Invalid blocksize %s", cpio->argument);
break;
case 'c': /* POSIX 1997 */
cpio->format = "odc";
@@ -199,22 +216,22 @@ main(int argc, char *argv[])
break;
case 'E': /* NetBSD/OpenBSD */
lafe_include_from_file(&cpio->matching,
- cpio->optarg, cpio->option_null);
+ cpio->argument, cpio->option_null);
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
- cpio->filename = cpio->optarg;
+ cpio->filename = cpio->argument;
break;
case 'f': /* POSIX 1997 */
- lafe_exclude(&cpio->matching, cpio->optarg);
+ lafe_exclude(&cpio->matching, cpio->argument);
break;
case 'H': /* GNU cpio (also --format) */
- cpio->format = cpio->optarg;
+ cpio->format = cpio->argument;
break;
case 'h':
long_help();
break;
case 'I': /* NetBSD/OpenBSD */
- cpio->filename = cpio->optarg;
+ cpio->filename = cpio->argument;
break;
case 'i': /* POSIX 1997 */
if (cpio->mode != '\0')
@@ -251,7 +268,7 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
case 'O': /* GNU cpio */
- cpio->filename = cpio->optarg;
+ cpio->filename = cpio->argument;
break;
case 'o': /* POSIX 1997 */
if (cpio->mode != '\0')
@@ -275,7 +292,7 @@ main(int argc, char *argv[])
case 'R': /* GNU cpio, also --owner */
/* TODO: owner_parse should return uname/gname
* also; use that to set [ug]name_override. */
- errmsg = owner_parse(cpio->optarg, &uid, &gid);
+ errmsg = owner_parse(cpio->argument, &uid, &gid);
if (errmsg) {
lafe_warnc(-1, "%s", errmsg);
usage();
@@ -302,6 +319,9 @@ main(int argc, char *argv[])
case 'v': /* POSIX 1997 */
cpio->verbose++;
break;
+ case 'V': /* GNU cpio */
+ cpio->dot++;
+ break;
case OPTION_VERSION: /* GNU convention */
version();
break;
@@ -345,6 +365,12 @@ main(int argc, char *argv[])
/* -l requires -p */
if (cpio->option_link && cpio->mode != 'p')
lafe_errc(1, 0, "Option -l requires -p");
+ /* -v overrides -V */
+ if (cpio->dot && cpio->verbose)
+ cpio->dot = 0;
+ /* -v overrides -V */
+ if (cpio->dot && cpio->verbose)
+ cpio->dot = 0;
/* TODO: Flag other nonsensical combinations. */
switch (cpio->mode) {
@@ -402,7 +428,7 @@ static const char *long_help_msg =
"First option must be a mode specifier:\n"
" -i Input -o Output -p Pass\n"
"Common Options:\n"
- " -v Verbose\n"
+ " -v Verbose filenames -V one dot per file\n"
"Create: %p -o [options] < [list of files] > [archive]\n"
" -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n"
" --format {odc|newc|ustar} Select archive format\n"
@@ -451,7 +477,7 @@ version(void)
{
fprintf(stdout,"bsdcpio %s -- %s\n",
BSDCPIO_VERSION_STRING,
- archive_version());
+ archive_version_string());
exit(0);
}
@@ -533,6 +559,8 @@ mode_out(struct cpio *cpio)
}
r = archive_write_close(cpio->archive);
+ if (cpio->dot)
+ fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
@@ -543,7 +571,7 @@ mode_out(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
- archive_write_finish(cpio->archive);
+ archive_write_free(cpio->archive);
}
/*
@@ -656,6 +684,8 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
/* Print out the destination name to the user. */
if (cpio->verbose)
fprintf(stderr,"%s", destpath);
+ if (cpio->dot)
+ fprintf(stderr, ".");
/*
* Option_link only makes sense in pass mode and for
@@ -725,7 +755,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
if (r == ARCHIVE_FATAL)
exit(1);
- if (r >= ARCHIVE_WARN && fd >= 0) {
+ if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) {
bytes_read = read(fd, cpio->buff, cpio->buff_size);
while (bytes_read > 0) {
r = archive_write_data(cpio->archive,
@@ -825,7 +855,7 @@ mode_in(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
lafe_errc(1, 0, "Couldn't allocate archive object");
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
@@ -849,7 +879,9 @@ mode_in(struct cpio *cpio)
if (destpath == NULL)
continue;
if (cpio->verbose)
- fprintf(stdout, "%s\n", destpath);
+ fprintf(stderr, "%s\n", destpath);
+ if (cpio->dot)
+ fprintf(stderr, ".");
if (cpio->uid_override >= 0)
archive_entry_set_uid(entry, cpio->uid_override);
if (cpio->gid_override >= 0)
@@ -859,13 +891,16 @@ mode_in(struct cpio *cpio)
fprintf(stderr, "%s: %s\n",
archive_entry_pathname(entry),
archive_error_string(ext));
- } else if (archive_entry_size(entry) > 0) {
+ } else if (!archive_entry_size_is_set(entry)
+ || archive_entry_size(entry) > 0) {
r = extract_data(a, ext);
if (r != ARCHIVE_OK)
cpio->return_value = 1;
}
}
r = archive_read_close(a);
+ if (cpio->dot)
+ fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(a));
r = archive_write_close(ext);
@@ -877,8 +912,8 @@ mode_in(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
- archive_read_finish(a);
- archive_write_finish(ext);
+ archive_read_free(a);
+ archive_write_free(ext);
exit(cpio->return_value);
}
@@ -892,7 +927,7 @@ extract_data(struct archive *ar, struct archive *aw)
int r;
size_t size;
const void *block;
- off_t offset;
+ int64_t offset;
for (;;) {
r = archive_read_data_block(ar, &block, &size, &offset);
@@ -922,7 +957,7 @@ mode_list(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
lafe_errc(1, 0, "Couldn't allocate archive object");
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
@@ -952,7 +987,7 @@ mode_list(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
- archive_read_finish(a);
+ archive_read_free(a);
exit(0);
}
@@ -989,11 +1024,11 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
/* Use uname if it's present, else lookup name from uid. */
uname = archive_entry_uname(entry);
if (uname == NULL)
- uname = lookup_uname(cpio, archive_entry_uid(entry));
+ uname = lookup_uname(cpio, (uid_t)archive_entry_uid(entry));
/* Use gname if it's present, else lookup name from gid. */
gname = archive_entry_gname(entry);
if (gname == NULL)
- gname = lookup_gname(cpio, archive_entry_gid(entry));
+ gname = lookup_gname(cpio, (uid_t)archive_entry_gid(entry));
}
/* Print device number or file size. */
@@ -1075,6 +1110,8 @@ mode_pass(struct cpio *cpio, const char *destdir)
archive_entry_linkresolver_free(cpio->linkresolver);
r = archive_write_close(cpio->archive);
+ if (cpio->dot)
+ fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
@@ -1086,7 +1123,7 @@ mode_pass(struct cpio *cpio, const char *destdir)
blocks == 1 ? "block" : "blocks");
}
- archive_write_finish(cpio->archive);
+ archive_write_free(cpio->archive);
}
/*
@@ -1260,8 +1297,9 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
const char *
cpio_i64toa(int64_t n0)
{
- // 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
- // We also need 1 byte for '-' and 1 for '\0'.
+ /* 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
+ * We also need 1 byte for '-' and 1 for '\0'.
+ */
static char buff[22];
int64_t n = n0 < 0 ? -n0 : n0;
char *p = buff + sizeof(buff);