From owner-svn-src-all@FreeBSD.ORG Sat May 8 16:47:33 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 71FDE106566C; Sat, 8 May 2010 16:47:33 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [69.147.83.44]) by mx1.freebsd.org (Postfix) with ESMTP id 60B4F8FC0C; Sat, 8 May 2010 16:47:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o48GlXgS071720; Sat, 8 May 2010 16:47:33 GMT (envelope-from kientzle@svn.freebsd.org) Received: (from kientzle@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o48GlXxV071713; Sat, 8 May 2010 16:47:33 GMT (envelope-from kientzle@svn.freebsd.org) Message-Id: <201005081647.o48GlXxV071713@svn.freebsd.org> From: Tim Kientzle Date: Sat, 8 May 2010 16:47:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207792 - head/usr.bin/cpio X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 May 2010 16:47:33 -0000 Author: kientzle Date: Sat May 8 16:47:33 2010 New Revision: 207792 URL: http://svn.freebsd.org/changeset/base/207792 Log: bsdcpio 2.8.3 Added: head/usr.bin/cpio/err.h (contents, props changed) head/usr.bin/cpio/line_reader.c (contents, props changed) head/usr.bin/cpio/line_reader.h (contents, props changed) Modified: head/usr.bin/cpio/Makefile head/usr.bin/cpio/bsdcpio.1 head/usr.bin/cpio/cmdline.c head/usr.bin/cpio/config_freebsd.h head/usr.bin/cpio/cpio.c head/usr.bin/cpio/cpio.h head/usr.bin/cpio/cpio_platform.h head/usr.bin/cpio/err.c head/usr.bin/cpio/matching.c head/usr.bin/cpio/matching.h head/usr.bin/cpio/pathmatch.c head/usr.bin/cpio/pathmatch.h Modified: head/usr.bin/cpio/Makefile ============================================================================== --- head/usr.bin/cpio/Makefile Sat May 8 16:29:02 2010 (r207791) +++ head/usr.bin/cpio/Makefile Sat May 8 16:47:33 2010 (r207792) @@ -3,8 +3,8 @@ .include PROG= bsdcpio -BSDCPIO_VERSION_STRING=2.7.0 -SRCS= cpio.c cmdline.c err.c matching.c pathmatch.c +BSDCPIO_VERSION_STRING=2.8.3 +SRCS= cpio.c cmdline.c err.c line_reader.c matching.c pathmatch.c CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\" CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\" .ifdef RELEASE_CRUNCH Modified: head/usr.bin/cpio/bsdcpio.1 ============================================================================== --- head/usr.bin/cpio/bsdcpio.1 Sat May 8 16:29:02 2010 (r207791) +++ head/usr.bin/cpio/bsdcpio.1 Sat May 8 16:47:33 2010 (r207792) @@ -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 @@ -266,7 +295,7 @@ for more information. .Sh EXAMPLES The .Nm -command is traditionally used to copy file hierarchies in conjunction +command is traditionally used to copy file heirarchies in conjunction with the .Xr find 1 command. Modified: head/usr.bin/cpio/cmdline.c ============================================================================== --- head/usr.bin/cpio/cmdline.c Sat May 8 16:29:02 2010 (r207791) +++ head/usr.bin/cpio/cmdline.c Sat May 8 16:47:33 2010 (r207792) @@ -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:rtuvVW:yZz"; +static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuvW:yZz"; /* * Long options for cpio. Please keep this sorted. @@ -61,7 +62,6 @@ static const struct option { int equivalent; /* Equivalent short option. */ } cpio_longopts[] = { { "create", 0, 'o' }, - { "dot", 0, 'V' }, { "extract", 0, 'i' }, { "file", 1, 'F' }, { "format", 1, 'H' }, @@ -69,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' }, @@ -76,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 } }; @@ -172,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, + warnc(0, "Option -%c requires an argument", opt); return ('?'); @@ -223,13 +226,13 @@ cpio_getopt(struct cpio *cpio) /* Fail if there wasn't a unique match. */ if (match == NULL) { - cpio_warnc(0, + warnc(0, "Option %s%s is not supported", long_prefix, opt_word); return ('?'); } if (match2 != NULL) { - cpio_warnc(0, + warnc(0, "Ambiguous option %s%s (matches --%s and --%s)", long_prefix, opt_word, match->name, match2->name); return ('?'); @@ -241,7 +244,7 @@ cpio_getopt(struct cpio *cpio) if (cpio->optarg == NULL) { cpio->optarg = *cpio->argv; if (cpio->optarg == NULL) { - cpio_warnc(0, + warnc(0, "Option %s%s requires an argument", long_prefix, match->name); return ('?'); @@ -252,7 +255,7 @@ cpio_getopt(struct cpio *cpio) } else { /* Argument forbidden: fail if there is one. */ if (cpio->optarg != NULL) { - cpio_warnc(0, + warnc(0, "Option %s%s does not allow an argument", long_prefix, match->name); return ('?'); @@ -283,17 +286,20 @@ cpio_getopt(struct cpio *cpio) * * Sets uid/gid return as appropriate, -1 indicates uid/gid not specified. * + * 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] @@ -321,10 +327,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) { @@ -336,9 +340,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); @@ -353,11 +358,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: head/usr.bin/cpio/config_freebsd.h ============================================================================== --- head/usr.bin/cpio/config_freebsd.h Sat May 8 16:29:02 2010 (r207791) +++ head/usr.bin/cpio/config_freebsd.h Sat May 8 16:47:33 2010 (r207792) @@ -25,83 +25,32 @@ * $FreeBSD$ */ -/* A default configuration for FreeBSD, used if there is no config.h. */ +/* A hand-tooled configuration for FreeBSD. */ #include /* __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 Modified: head/usr.bin/cpio/cpio.c ============================================================================== --- head/usr.bin/cpio/cpio.c Sat May 8 16:29:02 2010 (r207791) +++ head/usr.bin/cpio/cpio.c Sat May 8 16:47:33 2010 (r207792) @@ -56,6 +56,9 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_STDARG_H #include #endif +#ifdef HAVE_STDINT_H +#include +#endif #include #ifdef HAVE_STDLIB_H #include @@ -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 progname before calling warnc. */ if (*argv == NULL) - cpio_progname = "bsdcpio"; + progname = "bsdcpio"; else { #if defined(_WIN32) && !defined(__CYGWIN__) - cpio_progname = strrchr(*argv, '\\'); + progname = strrchr(*argv, '\\'); #else - cpio_progname = strrchr(*argv, '/'); + progname = strrchr(*argv, '/'); #endif - if (cpio_progname != NULL) - cpio_progname++; + if (progname != NULL) + progname++; else - cpio_progname = *argv; + 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); + 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); + 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); + 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, + 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,23 +255,29 @@ main(int argc, char *argv[]) break; case 'o': /* POSIX 1997 */ if (cpio->mode != '\0') - cpio_errc(1, 0, + 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, + 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)) + errmsg = owner_parse(cpio->optarg, &uid, &gid); + if (errmsg) { + warnc(-1, "%s", errmsg); usage(); + } if (uid != -1) cpio->uid_override = uid; if (gid != -1) @@ -278,9 +296,6 @@ 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; @@ -293,23 +308,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(); @@ -324,19 +329,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); + 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"); + 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"); + 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"); - /* -v overrides -V */ - if (cpio->dot && cpio->verbose) - cpio->dot = 0; + errc(1, 0, "Option -l requires -p"); /* TODO: Flag other nonsensical combinations. */ switch (cpio->mode) { @@ -350,7 +352,7 @@ main(int argc, char *argv[]) break; case 'i': while (*cpio->argv != NULL) { - include(cpio, *cpio->argv); + include(&cpio->matching, *cpio->argv); --cpio->argc; ++cpio->argv; } @@ -361,26 +363,26 @@ main(int argc, char *argv[]) break; case 'p': if (*cpio->argv == NULL || **cpio->argv == '\0') - cpio_errc(1, 0, + errc(1, 0, "-p mode requires a target directory"); mode_pass(cpio, *cpio->argv); break; default: - cpio_errc(1, 0, + 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 = progname; fprintf(stderr, "Brief Usage:\n"); fprintf(stderr, " List: %s -it < archive\n", p); @@ -394,14 +396,9 @@ 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 filenames -V one dot per file\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"; @@ -423,7 +420,7 @@ long_help(void) const char *prog; const char *p; - prog = cpio_progname; + prog = progname; fflush(stderr); @@ -455,19 +452,33 @@ version(void) static void mode_out(struct cpio *cpio) { - unsigned long blocks; struct archive_entry *entry, *spare; struct line_reader *lr; const char *p; int r; if (cpio->option_append) - cpio_errc(1, 0, "Append mode not yet supported."); + errc(1, 0, "Append mode not yet supported."); + + cpio->archive_read_disk = archive_read_disk_new(); + if (cpio->archive_read_disk == NULL) + 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"); + 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; @@ -477,41 +488,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) + 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)); + 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) + errc(1, 0, "%s", archive_error_string(cpio->archive)); + lr = line_reader("-", cpio->option_null); + while ((p = line_reader_next(lr)) != NULL) file_to_archive(cpio, p); - process_lines_free(lr); + line_reader_free(lr); /* * The hardlink detection may have queued up a couple of entries @@ -527,15 +527,14 @@ mode_out(struct cpio *cpio) } r = archive_write_close(cpio->archive); - if (cpio->dot) - fprintf(stderr, "\n"); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + 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); @@ -549,57 +548,37 @@ 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"); + 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) + errc(1, 0, "%s", + archive_error_string(cpio->archive_read_disk)); + if (r < ARCHIVE_OK) + 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) - st.st_uid = cpio->uid_override; + archive_entry_set_uid(entry, 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 + archive_entry_set_gid(entry, cpio->gid_override); /* * Generate a destination path for this entry. @@ -618,7 +597,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, + errc(1, ENOMEM, "Can't allocate path buffer"); } strcpy(cpio->pass_destpath, cpio->destdir); @@ -639,18 +618,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); } @@ -667,8 +646,6 @@ entry_to_archive(struct cpio *cpio, stru /* 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 @@ -686,7 +663,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"); + 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. */ @@ -696,15 +673,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)); + 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"); + warnc(0, "Copying file instead"); } else #endif return (0); @@ -716,9 +693,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, + warnc(errno, "%s: could not open file", srcpath); goto cleanup; } @@ -730,7 +707,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), + warnc(archive_errno(cpio->archive), "%s: %s", srcpath, archive_error_string(cpio->archive)); @@ -744,10 +721,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)); + errc(1, archive_errno(cpio->archive), + "%s", archive_error_string(cpio->archive)); if (r < bytes_read) { - cpio_warnc(0, + warnc(0, "Truncated write; file may have grown while being archived."); } bytes_read = read(fd, cpio->buff, cpio->buff_size); @@ -776,7 +753,7 @@ restore_time(struct cpio *cpio, struct a (void)name; /* UNUSED */ if (!warned) - cpio_warnc(0, "Can't restore access times on this platform"); + warnc(0, "Can't restore access times on this platform"); warned = 1; return (fd); #else @@ -795,7 +772,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 @@ -811,9 +788,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); + warnc(errno, "Can't update time for %s", name); #endif return (fd); } @@ -826,38 +804,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"); + errc(1, 0, "Couldn't allocate restore object"); r = archive_write_disk_set_options(ext, cpio->extract_flags); if (r != ARCHIVE_OK) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***