svn commit: r207792 - head/usr.bin/cpio

Tim Kientzle kientzle at FreeBSD.org
Sat May 8 16:47:33 UTC 2010


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 <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.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 <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
 

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 <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 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 ***


More information about the svn-src-all mailing list