Date: Mon, 1 Aug 2011 07:59:54 +0000 (UTC) From: Martin Matuska <mm@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r224562 - in stable/8/usr.bin/cpio: . test Message-ID: <201108010759.p717xssi083695@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mm Date: Mon Aug 1 07:59:54 2011 New Revision: 224562 URL: http://svn.freebsd.org/changeset/base/224562 Log: Sync bsdcpio with 9-CURRENT: MFC on usr.bin/cpio: 203183,204329,207792,211054,211397,212263,224154-224155 MFC 203183 (kientzle): Support -V option to print a dot for each file processed. Also, change the existing -vi behavior to send the filenames to stderr rather than stdout, as GNU cpio does. PR: bin/141175 Submitted by: Philip Kizer MFC 204329 (ru): Fixed dependencies (make checkdpadd). MFC 207792 (kientzle): bsdcpio 2.8.3 MFC 211054 (kientzle): Fix -R when used with -p. Previously, the uname and gname weren't overwritten, so the disk restore would use those to lookup the original uid/gid again. Clearing the uname and gname prevents this. Reported by: swell.k MFC 211397 (joel): Fix typos, spelling, formatting and mdoc mistakes found by Nobuyuki while translating these manual pages. Minor corrections by me. Submitted by: Nobuyuki Koganemaru <n-kogane@syd.odn.ne.jp> MFC 212263 (gjb): Fix typo in bsdcpio manual: s/libarchive_formats/libarchive-formats MFC 224154 (mm): Update bsdcpio to 2.8.4 Use common code from lib/libarchive/libarchive_fe MFC 224155 (mm): Append to CPIO_SRCS instead of using TAR_SRCS, the variable name is misleading Added: stable/8/usr.bin/cpio/test/test_cmdline.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_cmdline.c stable/8/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu - copied unchanged from r224154, head/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu stable/8/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu - copied unchanged from r224154, head/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu stable/8/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu - copied unchanged from r224154, head/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu stable/8/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu - copied unchanged from r224154, head/usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu stable/8/usr.bin/cpio/test/test_option_B_upper.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_B_upper.c stable/8/usr.bin/cpio/test/test_option_C_upper.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_C_upper.c stable/8/usr.bin/cpio/test/test_option_J_upper.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_J_upper.c stable/8/usr.bin/cpio/test/test_option_L_upper.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_L_upper.c stable/8/usr.bin/cpio/test/test_option_Z_upper.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_Z_upper.c stable/8/usr.bin/cpio/test/test_option_l.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_l.c stable/8/usr.bin/cpio/test/test_option_lzma.c - copied unchanged from r224154, head/usr.bin/cpio/test/test_option_lzma.c Deleted: stable/8/usr.bin/cpio/err.c stable/8/usr.bin/cpio/matching.c stable/8/usr.bin/cpio/matching.h stable/8/usr.bin/cpio/pathmatch.c stable/8/usr.bin/cpio/pathmatch.h stable/8/usr.bin/cpio/test/test_option_B.c stable/8/usr.bin/cpio/test/test_option_L.c stable/8/usr.bin/cpio/test/test_option_ell.c Modified: stable/8/usr.bin/cpio/Makefile stable/8/usr.bin/cpio/bsdcpio.1 stable/8/usr.bin/cpio/cmdline.c stable/8/usr.bin/cpio/config_freebsd.h stable/8/usr.bin/cpio/cpio.c stable/8/usr.bin/cpio/cpio.h stable/8/usr.bin/cpio/cpio_platform.h stable/8/usr.bin/cpio/test/Makefile stable/8/usr.bin/cpio/test/main.c stable/8/usr.bin/cpio/test/test.h stable/8/usr.bin/cpio/test/test_0.c stable/8/usr.bin/cpio/test/test_basic.c stable/8/usr.bin/cpio/test/test_format_newc.c stable/8/usr.bin/cpio/test/test_gcpio_compat.c stable/8/usr.bin/cpio/test/test_option_a.c stable/8/usr.bin/cpio/test/test_option_c.c stable/8/usr.bin/cpio/test/test_option_d.c stable/8/usr.bin/cpio/test/test_option_f.c stable/8/usr.bin/cpio/test/test_option_help.c stable/8/usr.bin/cpio/test/test_option_m.c stable/8/usr.bin/cpio/test/test_option_t.c stable/8/usr.bin/cpio/test/test_option_u.c stable/8/usr.bin/cpio/test/test_option_version.c stable/8/usr.bin/cpio/test/test_option_y.c stable/8/usr.bin/cpio/test/test_option_z.c stable/8/usr.bin/cpio/test/test_owner_parse.c stable/8/usr.bin/cpio/test/test_passthrough_dotdot.c stable/8/usr.bin/cpio/test/test_passthrough_reverse.c stable/8/usr.bin/cpio/test/test_pathmatch.c Directory Properties: stable/8/usr.bin/cpio/ (props changed) Modified: stable/8/usr.bin/cpio/Makefile ============================================================================== --- stable/8/usr.bin/cpio/Makefile Mon Aug 1 07:59:02 2011 (r224561) +++ stable/8/usr.bin/cpio/Makefile Mon Aug 1 07:59:54 2011 (r224562) @@ -3,19 +3,28 @@ .include <bsd.own.mk> PROG= bsdcpio -BSDCPIO_VERSION_STRING=2.7.0 -SRCS= cpio.c cmdline.c err.c matching.c pathmatch.c +BSDCPIO_VERSION_STRING=2.8.4 + +SRCS= cpio.c cmdline.c + +.PATH: ${.CURDIR}/../../lib/libarchive/libarchive_fe +SRCS+= err.c line_reader.c matching.c pathmatch.c + WARNS?= 6 DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2} CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\" CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\" +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../lib/libarchive/libarchive_fe + .ifdef RELEASE_CRUNCH # FreeBSD's installer uses cpio in crunched binaries that are # statically linked, cannot use -lcrypto, and are size sensitive. CFLAGS+= -DSMALLER .endif -LDADD+= -larchive -lz -lbz2 -lmd +DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2} ${LIBMD} ${LIBLZMA} ${LIBBSDXML} +LDADD= -larchive -lz -lbz2 -lmd -llzma -lbsdxml .if ${MK_OPENSSL} != "no" +DPADD+= ${LIBCRYPTO} LDADD+= -lcrypto .endif Modified: stable/8/usr.bin/cpio/bsdcpio.1 ============================================================================== --- stable/8/usr.bin/cpio/bsdcpio.1 Mon Aug 1 07:59:02 2011 (r224561) +++ stable/8/usr.bin/cpio/bsdcpio.1 Mon Aug 1 07:59:54 2011 (r224562) @@ -80,6 +80,9 @@ specified directory. Unless specifically stated otherwise, options are applicable in all operating modes. .Bl -tag -width indent +.It Fl 0 +Read filenames separated by NUL characters instead of newlines. +This is necessary if any of the filenames being read might contain newlines. .It Fl A (o mode only) Append to the specified archive. @@ -142,6 +145,11 @@ for more complete information about the formats currently supported by the underlying .Xr libarchive 3 library. +.It Fl H Ar format +Synonym for +.Fl -format . +.It Fl h , Fl -help +Print usage information. .It Fl I Ar file Read archive from .Ar file . @@ -154,6 +162,14 @@ Disable security checks during extractio This allows extraction via symbolic links and path names containing .Sq .. in the name. +.It Fl J +(o mode only) +Compress the file with xz-compatible compression before writing it. +In input mode, this option is ignored; xz compression is recognized +automatically on input. +.It Fl j +Synonym for +.Fl y . .It Fl L (o and p modes) All symbolic links will be followed. @@ -163,6 +179,11 @@ With this option, the target of the link (p mode only) Create links from the target directory to the original files, instead of copying. +.It Fl lzma +(o mode only) +Compress the file with lzma-compatible compression before writing it. +In input mode, this option is ignored; lzma compression is recognized +automatically on input. .It Fl m (i and p modes) Set file modification time on created files to match @@ -176,6 +197,10 @@ By default, displays the user and group names when they are provided in the archive, or looks up the user and group names in the system password database. +.It Fl no-preserve-owner +(i mode only) +Do not attempt to restore file ownership. +This is the default when run by non-root users. .It Fl O Ar file Write archive to .Ar file . @@ -185,6 +210,10 @@ See above for description. .It Fl p Pass-through mode. See above for description. +.It Fl preserve-owner +(i mode only) +Restore file ownership. +This is the default when run by the root user. .It Fl -quiet Suppress unnecessary messages. .It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc Modified: stable/8/usr.bin/cpio/cmdline.c ============================================================================== --- stable/8/usr.bin/cpio/cmdline.c Mon Aug 1 07:59:02 2011 (r224561) +++ stable/8/usr.bin/cpio/cmdline.c Mon Aug 1 07:59:54 2011 (r224562) @@ -46,11 +46,12 @@ __FBSDID("$FreeBSD$"); #endif #include "cpio.h" +#include "err.h" /* * Short options for cpio. Please keep this sorted. */ -static const char *short_options = "0AaBC:F:O:cdE:f:H:hijLlmnopR:rtuvW:yZz"; +static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuvW:yZz"; /* * Long options for cpio. Please keep this sorted. @@ -68,6 +69,7 @@ static const struct option { { "insecure", 0, OPTION_INSECURE }, { "link", 0, 'l' }, { "list", 0, 't' }, + { "lzma", 0, OPTION_LZMA }, { "make-directories", 0, 'd' }, { "no-preserve-owner", 0, OPTION_NO_PRESERVE_OWNER }, { "null", 0, '0' }, @@ -75,10 +77,12 @@ static const struct option { { "owner", 1, 'R' }, { "pass-through", 0, 'p' }, { "preserve-modification-time", 0, 'm' }, + { "preserve-owner", 0, OPTION_PRESERVE_OWNER }, { "quiet", 0, OPTION_QUIET }, { "unconditional", 0, 'u' }, { "verbose", 0, 'v' }, { "version", 0, OPTION_VERSION }, + { "xz", 0, 'J' }, { NULL, 0, 0 } }; @@ -171,7 +175,7 @@ cpio_getopt(struct cpio *cpio) /* Otherwise, pick up the next word. */ opt_word = *cpio->argv; if (opt_word == NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option -%c requires an argument", opt); return ('?'); @@ -222,13 +226,13 @@ cpio_getopt(struct cpio *cpio) /* Fail if there wasn't a unique match. */ if (match == NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option %s%s is not supported", long_prefix, opt_word); return ('?'); } if (match2 != NULL) { - cpio_warnc(0, + lafe_warnc(0, "Ambiguous option %s%s (matches --%s and --%s)", long_prefix, opt_word, match->name, match2->name); return ('?'); @@ -240,7 +244,7 @@ cpio_getopt(struct cpio *cpio) if (cpio->optarg == NULL) { cpio->optarg = *cpio->argv; if (cpio->optarg == NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option %s%s requires an argument", long_prefix, match->name); return ('?'); @@ -251,7 +255,7 @@ cpio_getopt(struct cpio *cpio) } else { /* Argument forbidden: fail if there is one. */ if (cpio->optarg != NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option %s%s does not allow an argument", long_prefix, match->name); return ('?'); @@ -281,18 +285,23 @@ cpio_getopt(struct cpio *cpio) * A period can be used instead of the colon. * * Sets uid/gid return as appropriate, -1 indicates uid/gid not specified. + * TODO: If the spec uses uname/gname, then return those to the caller + * as well. If the spec provides uid/gid, just return names as NULL. + * + * Returns NULL if no error, otherwise returns error string for display. * */ -int +const char * owner_parse(const char *spec, int *uid, int *gid) { + static char errbuff[128]; const char *u, *ue, *g; *uid = -1; *gid = -1; if (spec[0] == '\0') - return (1); + return ("Invalid empty user/group spec"); /* * Split spec into [user][:.][group] @@ -320,10 +329,8 @@ owner_parse(const char *spec, int *uid, struct passwd *pwent; user = (char *)malloc(ue - u + 1); - if (user == NULL) { - cpio_warnc(errno, "Couldn't allocate memory"); - return (1); - } + if (user == NULL) + return ("Couldn't allocate memory"); memcpy(user, u, ue - u); user[ue - u] = '\0'; if ((pwent = getpwnam(user)) != NULL) { @@ -335,9 +342,10 @@ owner_parse(const char *spec, int *uid, errno = 0; *uid = strtoul(user, &end, 10); if (errno || *end != '\0') { - cpio_warnc(errno, + snprintf(errbuff, sizeof(errbuff), "Couldn't lookup user ``%s''", user); - return (1); + errbuff[sizeof(errbuff) - 1] = '\0'; + return (errbuff); } } free(user); @@ -352,11 +360,12 @@ owner_parse(const char *spec, int *uid, errno = 0; *gid = strtoul(g, &end, 10); if (errno || *end != '\0') { - cpio_warnc(errno, + snprintf(errbuff, sizeof(errbuff), "Couldn't lookup group ``%s''", g); - return (1); + errbuff[sizeof(errbuff) - 1] = '\0'; + return (errbuff); } } } - return (0); + return (NULL); } Modified: stable/8/usr.bin/cpio/config_freebsd.h ============================================================================== --- stable/8/usr.bin/cpio/config_freebsd.h Mon Aug 1 07:59:02 2011 (r224561) +++ stable/8/usr.bin/cpio/config_freebsd.h Mon Aug 1 07:59:54 2011 (r224562) @@ -25,83 +25,33 @@ * $FreeBSD$ */ -/* A default configuration for FreeBSD, used if there is no config.h. */ +/* A hand-tooled configuration for FreeBSD. */ #include <sys/param.h> /* __FreeBSD_version */ -#if __FreeBSD__ > 4 -#define HAVE_ACL_GET_PERM 0 -#define HAVE_ACL_GET_PERM_NP 1 -#define HAVE_ACL_PERMSET_T 1 -#define HAVE_ACL_USER 1 -#endif -#undef HAVE_ATTR_XATTR_H -#define HAVE_BZLIB_H 1 -#define HAVE_CHFLAGS 1 -#define HAVE_DECL_OPTARG 1 -#define HAVE_DECL_OPTIND 1 -#define HAVE_DIRENT_D_NAMLEN 1 #define HAVE_DIRENT_H 1 -#define HAVE_D_MD_ORDER 1 #define HAVE_ERRNO_H 1 -#undef HAVE_EXT2FS_EXT2_FS_H -#define HAVE_FCHDIR 1 #define HAVE_FCNTL_H 1 -#define HAVE_FNMATCH 1 -#define HAVE_FNMATCH_H 1 -#define HAVE_FNM_LEADING_DIR 1 -#define HAVE_FTRUNCATE 1 #define HAVE_FUTIMES 1 -#undef HAVE_GETXATTR #define HAVE_GRP_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_LANGINFO_H 1 -#undef HAVE_LGETXATTR -#undef HAVE_LIBACL #define HAVE_LIBARCHIVE 1 -#define HAVE_LIBBZ2 1 -#define HAVE_LIBZ 1 -#define HAVE_LIMITS_H 1 -#undef HAVE_LINUX_EXT2_FS_H -#undef HAVE_LINUX_FS_H -#undef HAVE_LISTXATTR -#undef HAVE_LLISTXATTR -#define HAVE_LOCALE_H 1 +#define HAVE_LINK 1 +#define HAVE_LSTAT 1 #define HAVE_LUTIMES 1 -#define HAVE_MALLOC 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMORY_H 1 -#define HAVE_MEMSET 1 -#if __FreeBSD_version >= 450002 /* nl_langinfo introduced */ -#define HAVE_NL_LANGINFO 1 -#endif -#define HAVE_PATHS_H 1 #define HAVE_PWD_H 1 -#define HAVE_SETLOCALE 1 +#define HAVE_READLINK 1 #define HAVE_STDARG_H 1 -#define HAVE_STDINT_H 1 #define HAVE_STDLIB_H 1 -#define HAVE_STRCHR 1 -#define HAVE_STRDUP 1 -#define HAVE_STRERROR 1 -#define HAVE_STRFTIME 1 -#define HAVE_STRINGS_H 1 #define HAVE_STRING_H 1 -#define HAVE_STRRCHR 1 -#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC -#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1 -#define HAVE_SYS_ACL_H 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYMLINK 1 +#define HAVE_SYS_CDEFS_H 1 #define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TIME_H 1 #define HAVE_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 #define HAVE_UINTMAX_T 1 #define HAVE_UNISTD_H 1 #define HAVE_UNSIGNED_LONG_LONG 1 +#define HAVE_UTIME_H 1 #define HAVE_UTIMES 1 -#define HAVE_VPRINTF 1 -#define HAVE_ZLIB_H 1 -#undef MAJOR_IN_MKDEV -#define STDC_HEADERS 1 +#define HAVE_WCSCMP 1 Modified: stable/8/usr.bin/cpio/cpio.c ============================================================================== --- stable/8/usr.bin/cpio/cpio.c Mon Aug 1 07:59:02 2011 (r224561) +++ stable/8/usr.bin/cpio/cpio.c Mon Aug 1 07:59:54 2011 (r224562) @@ -56,6 +56,9 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_STDARG_H #include <stdarg.h> #endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif #include <stdio.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> @@ -74,11 +77,17 @@ __FBSDID("$FreeBSD$"); #endif #include "cpio.h" +#include "err.h" +#include "line_reader.h" #include "matching.h" /* Fixed size of uname/gname caches. */ #define name_cache_size 101 +#ifndef O_BINARY +#define O_BINARY 0 +#endif + struct name_cache { int probes; int hits; @@ -89,7 +98,8 @@ struct name_cache { } cache[name_cache_size]; }; -static int copy_data(struct archive *, struct archive *); +static int extract_data(struct archive *, struct archive *); +const char * cpio_i64toa(int64_t); static const char *cpio_rename(const char *name); static int entry_to_archive(struct cpio *, struct archive_entry *); static int file_to_archive(struct cpio *, const char *); @@ -117,6 +127,7 @@ main(int argc, char *argv[]) static char buff[16384]; struct cpio _cpio; /* Allocated on stack. */ struct cpio *cpio; + const char *errmsg; int uid, gid; int opt; @@ -124,33 +135,26 @@ main(int argc, char *argv[]) memset(cpio, 0, sizeof(*cpio)); cpio->buff = buff; cpio->buff_size = sizeof(buff); -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure open() function will be used with a binary mode. */ - /* on cygwin, we need something similar, but instead link against */ - /* a special startup object, binmode.o */ - _set_fmode(_O_BINARY); -#endif - /* Need cpio_progname before calling cpio_warnc. */ + /* Need lafe_progname before calling lafe_warnc. */ if (*argv == NULL) - cpio_progname = "bsdcpio"; + lafe_progname = "bsdcpio"; else { #if defined(_WIN32) && !defined(__CYGWIN__) - cpio_progname = strrchr(*argv, '\\'); + lafe_progname = strrchr(*argv, '\\'); #else - cpio_progname = strrchr(*argv, '/'); + lafe_progname = strrchr(*argv, '/'); #endif - if (cpio_progname != NULL) - cpio_progname++; + if (lafe_progname != NULL) + lafe_progname++; else - cpio_progname = *argv; + lafe_progname = *argv; } cpio->uid_override = -1; cpio->gid_override = -1; cpio->argv = argv; cpio->argc = argc; - cpio->line_separator = '\n'; cpio->mode = '\0'; cpio->verbose = 0; cpio->compress = '\0'; @@ -161,19 +165,17 @@ main(int argc, char *argv[]) cpio->extract_flags |= ARCHIVE_EXTRACT_PERM; cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; cpio->extract_flags |= ARCHIVE_EXTRACT_ACL; -#if defined(_WIN32) || defined(__CYGWIN__) - if (bsdcpio_is_privileged()) -#else +#if !defined(_WIN32) && !defined(__CYGWIN__) if (geteuid() == 0) -#endif cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; +#endif cpio->bytes_per_block = 512; cpio->filename = NULL; while ((opt = cpio_getopt(cpio)) != -1) { switch (opt) { case '0': /* GNU convention: --null, -0 */ - cpio->line_separator = '\0'; + cpio->option_null = 1; break; case 'A': /* NetBSD/OpenBSD */ cpio->option_append = 1; @@ -187,7 +189,7 @@ main(int argc, char *argv[]) case 'C': /* NetBSD/OpenBSD */ cpio->bytes_per_block = atoi(cpio->optarg); if (cpio->bytes_per_block <= 0) - cpio_errc(1, 0, "Invalid blocksize %s", cpio->optarg); + lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg); break; case 'c': /* POSIX 1997 */ cpio->format = "odc"; @@ -196,13 +198,14 @@ main(int argc, char *argv[]) cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; break; case 'E': /* NetBSD/OpenBSD */ - include_from_file(cpio, cpio->optarg); + lafe_include_from_file(&cpio->matching, + cpio->optarg, cpio->option_null); break; case 'F': /* NetBSD/OpenBSD/GNU cpio */ cpio->filename = cpio->optarg; break; case 'f': /* POSIX 1997 */ - exclude(cpio, cpio->optarg); + lafe_exclude(&cpio->matching, cpio->optarg); break; case 'H': /* GNU cpio (also --format) */ cpio->format = cpio->optarg; @@ -215,10 +218,16 @@ main(int argc, char *argv[]) break; case 'i': /* POSIX 1997 */ if (cpio->mode != '\0') - cpio_errc(1, 0, + lafe_errc(1, 0, "Cannot use both -i and -%c", cpio->mode); cpio->mode = opt; break; + case 'J': /* GNU tar, others */ + cpio->compress = opt; + break; + case 'j': /* GNU tar, others */ + cpio->compress = opt; + break; case OPTION_INSECURE: cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; @@ -229,6 +238,9 @@ main(int argc, char *argv[]) case 'l': /* POSIX 1997 */ cpio->option_link = 1; break; + case OPTION_LZMA: /* GNU tar, others */ + cpio->compress = opt; + break; case 'm': /* POSIX 1997 */ cpio->extract_flags |= ARCHIVE_EXTRACT_TIME; break; @@ -243,27 +255,39 @@ main(int argc, char *argv[]) break; case 'o': /* POSIX 1997 */ if (cpio->mode != '\0') - cpio_errc(1, 0, + lafe_errc(1, 0, "Cannot use both -o and -%c", cpio->mode); cpio->mode = opt; break; case 'p': /* POSIX 1997 */ if (cpio->mode != '\0') - cpio_errc(1, 0, + lafe_errc(1, 0, "Cannot use both -p and -%c", cpio->mode); cpio->mode = opt; cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; break; + case OPTION_PRESERVE_OWNER: + cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; + break; case OPTION_QUIET: /* GNU cpio */ cpio->quiet = 1; break; case 'R': /* GNU cpio, also --owner */ - if (owner_parse(cpio->optarg, &uid, &gid)) + /* TODO: owner_parse should return uname/gname + * also; use that to set [ug]name_override. */ + errmsg = owner_parse(cpio->optarg, &uid, &gid); + if (errmsg) { + lafe_warnc(-1, "%s", errmsg); usage(); - if (uid != -1) + } + if (uid != -1) { cpio->uid_override = uid; - if (gid != -1) + cpio->uname_override = NULL; + } + if (gid != -1) { cpio->gid_override = gid; + cpio->gname_override = NULL; + } break; case 'r': /* POSIX 1997 */ cpio->option_rename = 1; @@ -290,23 +314,13 @@ main(int argc, char *argv[]) break; #endif case 'y': /* tar convention */ -#if HAVE_LIBBZ2 cpio->compress = opt; -#else - cpio_warnc(0, "bzip2 compression not supported by " - "this version of bsdcpio"); -#endif break; case 'Z': /* tar convention */ cpio->compress = opt; break; case 'z': /* tar convention */ -#if HAVE_LIBZ cpio->compress = opt; -#else - cpio_warnc(0, "gzip compression not supported by " - "this version of bsdcpio"); -#endif break; default: usage(); @@ -321,16 +335,16 @@ main(int argc, char *argv[]) cpio->mode = 'i'; /* -t requires -i */ if (cpio->option_list && cpio->mode != 'i') - cpio_errc(1, 0, "Option -t requires -i", cpio->mode); + lafe_errc(1, 0, "Option -t requires -i"); /* -n requires -it */ if (cpio->option_numeric_uid_gid && !cpio->option_list) - cpio_errc(1, 0, "Option -n requires -it"); + lafe_errc(1, 0, "Option -n requires -it"); /* Can only specify format when writing */ if (cpio->format != NULL && cpio->mode != 'o') - cpio_errc(1, 0, "Option --format requires -o"); + lafe_errc(1, 0, "Option --format requires -o"); /* -l requires -p */ if (cpio->option_link && cpio->mode != 'p') - cpio_errc(1, 0, "Option -l requires -p"); + lafe_errc(1, 0, "Option -l requires -p"); /* TODO: Flag other nonsensical combinations. */ switch (cpio->mode) { @@ -344,7 +358,7 @@ main(int argc, char *argv[]) break; case 'i': while (*cpio->argv != NULL) { - include(cpio, *cpio->argv); + lafe_include(&cpio->matching, *cpio->argv); --cpio->argc; ++cpio->argv; } @@ -355,26 +369,26 @@ main(int argc, char *argv[]) break; case 'p': if (*cpio->argv == NULL || **cpio->argv == '\0') - cpio_errc(1, 0, + lafe_errc(1, 0, "-p mode requires a target directory"); mode_pass(cpio, *cpio->argv); break; default: - cpio_errc(1, 0, + lafe_errc(1, 0, "Must specify at least one of -i, -o, or -p"); } free_cache(cpio->gname_cache); free_cache(cpio->uname_cache); - return (0); + return (cpio->return_value); } -void +static void usage(void) { const char *p; - p = cpio_progname; + p = lafe_progname; fprintf(stderr, "Brief Usage:\n"); fprintf(stderr, " List: %s -it < archive\n", p); @@ -390,12 +404,7 @@ static const char *long_help_msg = "Common Options:\n" " -v Verbose\n" "Create: %p -o [options] < [list of files] > [archive]\n" -#ifdef HAVE_BZLIB_H - " -y Compress archive with bzip2\n" -#endif -#ifdef HAVE_ZLIB_H - " -z Compress archive with gzip\n" -#endif + " -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n" " --format {odc|newc|ustar} Select archive format\n" "List: %p -it < [archive]\n" "Extract: %p -i [options] < [archive]\n"; @@ -417,7 +426,7 @@ long_help(void) const char *prog; const char *p; - prog = cpio_progname; + prog = lafe_progname; fflush(stderr); @@ -449,19 +458,33 @@ version(void) static void mode_out(struct cpio *cpio) { - unsigned long blocks; struct archive_entry *entry, *spare; - struct line_reader *lr; + struct lafe_line_reader *lr; const char *p; int r; if (cpio->option_append) - cpio_errc(1, 0, "Append mode not yet supported."); + lafe_errc(1, 0, "Append mode not yet supported."); + + cpio->archive_read_disk = archive_read_disk_new(); + if (cpio->archive_read_disk == NULL) + lafe_errc(1, 0, "Failed to allocate archive object"); + if (cpio->option_follow_links) + archive_read_disk_set_symlink_logical(cpio->archive_read_disk); + else + archive_read_disk_set_symlink_physical(cpio->archive_read_disk); + archive_read_disk_set_standard_lookup(cpio->archive_read_disk); + cpio->archive = archive_write_new(); if (cpio->archive == NULL) - cpio_errc(1, 0, "Failed to allocate archive object"); + lafe_errc(1, 0, "Failed to allocate archive object"); switch (cpio->compress) { -#ifndef SMALLER + case 'J': + r = archive_write_set_compression_xz(cpio->archive); + break; + case OPTION_LZMA: + r = archive_write_set_compression_lzma(cpio->archive); + break; case 'j': case 'y': r = archive_write_set_compression_bzip2(cpio->archive); break; @@ -471,41 +494,30 @@ mode_out(struct cpio *cpio) case 'Z': r = archive_write_set_compression_compress(cpio->archive); break; -#endif - case '\0': + default: r = archive_write_set_compression_none(cpio->archive); break; - default: - cpio_errc(1, 0, "Unrecognized compression option"); } - if (r != ARCHIVE_OK) - cpio_errc(1, 0, "Unsupported compression format"); -#ifdef SMALLER - if (strcmp(cpio->format, "cpio")) - r = archive_write_set_format_cpio(cpio->archive); - else if (strcmp(cpio->format, "odc")) - r = archive_write_set_format_cpio(cpio->archive); - else if (strcmp(cpio->format, "newc")) - r = archive_write_set_format_cpio(cpio->archive); - else if (strcmp(cpio->format, "ustar")) - r = archive_write_set_format_cpio(cpio->archive); -#else + if (r < ARCHIVE_WARN) + lafe_errc(1, 0, "Requested compression not available"); r = archive_write_set_format_by_name(cpio->archive, cpio->format); -#endif if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block); cpio->linkresolver = archive_entry_linkresolver_new(); archive_entry_linkresolver_set_strategy(cpio->linkresolver, archive_format(cpio->archive)); + /* + * The main loop: Copy each file into the output archive. + */ r = archive_write_open_file(cpio->archive, cpio->filename); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); - lr = process_lines_init("-", cpio->line_separator); - while ((p = process_lines_next(lr)) != NULL) + lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); + lr = lafe_line_reader("-", cpio->option_null); + while ((p = lafe_line_reader_next(lr)) != NULL) file_to_archive(cpio, p); - process_lines_free(lr); + lafe_line_reader_free(lr); /* * The hardlink detection may have queued up a couple of entries @@ -522,12 +534,13 @@ mode_out(struct cpio *cpio) r = archive_write_close(cpio->archive); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); if (!cpio->quiet) { - blocks = (archive_position_uncompressed(cpio->archive) + 511) - / 512; - fprintf(stderr, "%lu %s\n", blocks, + int64_t blocks = + (archive_position_uncompressed(cpio->archive) + 511) + / 512; + fprintf(stderr, "%lu %s\n", (unsigned long)blocks, blocks == 1 ? "block" : "blocks"); } archive_write_finish(cpio->archive); @@ -541,58 +554,42 @@ mode_out(struct cpio *cpio) static int file_to_archive(struct cpio *cpio, const char *srcpath) { - struct stat st; const char *destpath; struct archive_entry *entry, *spare; size_t len; const char *p; -#if !defined(_WIN32) || defined(__CYGWIN__) - int lnklen; -#endif int r; /* * Create an archive_entry describing the source file. * - * XXX TODO: rework to use archive_read_disk_entry_from_file() */ entry = archive_entry_new(); if (entry == NULL) - cpio_errc(1, 0, "Couldn't allocate entry"); + lafe_errc(1, 0, "Couldn't allocate entry"); archive_entry_copy_sourcepath(entry, srcpath); - - /* Get stat information. */ - if (cpio->option_follow_links) - r = stat(srcpath, &st); - else - r = lstat(srcpath, &st); - if (r != 0) { - cpio_warnc(errno, "Couldn't stat \"%s\"", srcpath); - archive_entry_free(entry); - return (0); + r = archive_read_disk_entry_from_file(cpio->archive_read_disk, + entry, -1, NULL); + if (r < ARCHIVE_FAILED) + lafe_errc(1, 0, "%s", + archive_error_string(cpio->archive_read_disk)); + if (r < ARCHIVE_OK) + lafe_warnc(0, "%s", + archive_error_string(cpio->archive_read_disk)); + if (r <= ARCHIVE_FAILED) { + cpio->return_value = 1; + return (r); + } + + if (cpio->uid_override >= 0) { + archive_entry_set_uid(entry, cpio->uid_override); + archive_entry_set_uname(entry, cpio->uname_override); + } + if (cpio->gid_override >= 0) { + archive_entry_set_gid(entry, cpio->gid_override); + archive_entry_set_gname(entry, cpio->gname_override); } - if (cpio->uid_override >= 0) - st.st_uid = cpio->uid_override; - if (cpio->gid_override >= 0) - st.st_gid = cpio->gid_override; - archive_entry_copy_stat(entry, &st); - -#if !defined(_WIN32) || defined(__CYGWIN__) - /* If its a symlink, pull the target. */ - if (S_ISLNK(st.st_mode)) { - lnklen = readlink(srcpath, cpio->buff, cpio->buff_size); - if (lnklen < 0) { - cpio_warnc(errno, - "%s: Couldn't read symbolic link", srcpath); - archive_entry_free(entry); - return (0); - } - cpio->buff[lnklen] = 0; - archive_entry_set_symlink(entry, cpio->buff); - } -#endif - /* * Generate a destination path for this entry. * "destination path" is the name to which it will be copied in @@ -610,7 +607,7 @@ file_to_archive(struct cpio *cpio, const free(cpio->pass_destpath); cpio->pass_destpath = malloc(cpio->pass_destpath_alloc); if (cpio->pass_destpath == NULL) - cpio_errc(1, ENOMEM, + lafe_errc(1, ENOMEM, "Can't allocate path buffer"); } strcpy(cpio->pass_destpath, cpio->destdir); @@ -631,18 +628,18 @@ file_to_archive(struct cpio *cpio, const */ spare = NULL; if (cpio->linkresolver != NULL - && !S_ISDIR(st.st_mode)) { + && archive_entry_filetype(entry) != AE_IFDIR) { archive_entry_linkify(cpio->linkresolver, &entry, &spare); } if (entry != NULL) { r = entry_to_archive(cpio, entry); archive_entry_free(entry); - } - if (spare != NULL) { - if (r == 0) - r = entry_to_archive(cpio, spare); - archive_entry_free(spare); + if (spare != NULL) { + if (r == 0) + r = entry_to_archive(cpio, spare); + archive_entry_free(spare); + } } return (r); } @@ -676,7 +673,7 @@ entry_to_archive(struct cpio *cpio, stru /* Save the original entry in case we need it later. */ t = archive_entry_clone(entry); if (t == NULL) - cpio_errc(1, ENOMEM, "Can't create link"); + lafe_errc(1, ENOMEM, "Can't create link"); /* Note: link(2) doesn't create parent directories, * so we use archive_write_header() instead as a * convenience. */ @@ -686,15 +683,15 @@ entry_to_archive(struct cpio *cpio, stru r = archive_write_header(cpio->archive, t); archive_entry_free(t); if (r != ARCHIVE_OK) - cpio_warnc(archive_errno(cpio->archive), - archive_error_string(cpio->archive)); + lafe_warnc(archive_errno(cpio->archive), + "%s", archive_error_string(cpio->archive)); if (r == ARCHIVE_FATAL) exit(1); #ifdef EXDEV if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) { /* Cross-device link: Just fall through and use * the original entry to copy the file over. */ - cpio_warnc(0, "Copying file instead"); + lafe_warnc(0, "Copying file instead"); } else #endif return (0); @@ -706,9 +703,9 @@ entry_to_archive(struct cpio *cpio, stru */ if (archive_entry_filetype(entry) == AE_IFREG) { if (archive_entry_size(entry) > 0) { - fd = open(srcpath, O_RDONLY); + fd = open(srcpath, O_RDONLY | O_BINARY); if (fd < 0) { - cpio_warnc(errno, + lafe_warnc(errno, "%s: could not open file", srcpath); goto cleanup; } @@ -720,7 +717,7 @@ entry_to_archive(struct cpio *cpio, stru r = archive_write_header(cpio->archive, entry); if (r != ARCHIVE_OK) - cpio_warnc(archive_errno(cpio->archive), + lafe_warnc(archive_errno(cpio->archive), "%s: %s", srcpath, archive_error_string(cpio->archive)); @@ -734,10 +731,10 @@ entry_to_archive(struct cpio *cpio, stru r = archive_write_data(cpio->archive, cpio->buff, bytes_read); if (r < 0) - cpio_errc(1, archive_errno(cpio->archive), - archive_error_string(cpio->archive)); + lafe_errc(1, archive_errno(cpio->archive), + "%s", archive_error_string(cpio->archive)); if (r < bytes_read) { - cpio_warnc(0, + lafe_warnc(0, "Truncated write; file may have grown while being archived."); } bytes_read = read(fd, cpio->buff, cpio->buff_size); @@ -766,7 +763,7 @@ restore_time(struct cpio *cpio, struct a (void)name; /* UNUSED */ if (!warned) - cpio_warnc(0, "Can't restore access times on this platform"); + lafe_warnc(0, "Can't restore access times on this platform"); warned = 1; return (fd); #else @@ -785,7 +782,7 @@ restore_time(struct cpio *cpio, struct a times[0].tv_sec = archive_entry_atime(entry); times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000; -#ifdef HAVE_FUTIMES +#if defined(HAVE_FUTIMES) && !defined(__CYGWIN__) if (fd >= 0 && futimes(fd, times) == 0) return (fd); #endif @@ -801,9 +798,10 @@ restore_time(struct cpio *cpio, struct a #ifdef HAVE_LUTIMES if (lutimes(name, times) != 0) #else - if (!S_ISLNK(archive_entry_mode(entry)) && utimes(name, times) != 0) + if ((AE_IFLNK != archive_entry_filetype(entry)) + && utimes(name, times) != 0) #endif - cpio_warnc(errno, "Can't update time for %s", name); + lafe_warnc(errno, "Can't update time for %s", name); #endif return (fd); } @@ -816,38 +814,32 @@ mode_in(struct cpio *cpio) struct archive_entry *entry; struct archive *ext; const char *destpath; - unsigned long blocks; int r; ext = archive_write_disk_new(); if (ext == NULL) - cpio_errc(1, 0, "Couldn't allocate restore object"); + lafe_errc(1, 0, "Couldn't allocate restore object"); r = archive_write_disk_set_options(ext, cpio->extract_flags); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108010759.p717xssi083695>