Merge from vendor branch LIBARCHIVE:
authorPeter Avalos <pavalos@dragonflybsd.org>
Sat, 12 Jul 2008 14:42:23 +0000 (14:42 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sat, 12 Jul 2008 14:42:23 +0000 (14:42 +0000)
Import libarchive-2.5.5.

52 files changed:
contrib/libarchive-2/NEWS
contrib/libarchive-2/cpio/bsdcpio.1 [new file with mode: 0644]
contrib/libarchive-2/cpio/cmdline.c [new file with mode: 0644]
contrib/libarchive-2/cpio/cpio.c [new file with mode: 0644]
contrib/libarchive-2/cpio/cpio.h [new file with mode: 0644]
contrib/libarchive-2/cpio/cpio_platform.h [new file with mode: 0644]
contrib/libarchive-2/cpio/err.c [copied from contrib/libarchive-2/libarchive/archive_entry_strmode.c with 51% similarity]
contrib/libarchive-2/cpio/matching.c [new file with mode: 0644]
contrib/libarchive-2/cpio/matching.h [new file with mode: 0644]
contrib/libarchive-2/cpio/pathmatch.c [new file with mode: 0644]
contrib/libarchive-2/cpio/pathmatch.h [new file with mode: 0644]
contrib/libarchive-2/libarchive/archive.h
contrib/libarchive-2/libarchive/archive_endian.h
contrib/libarchive-2/libarchive/archive_entry.3
contrib/libarchive-2/libarchive/archive_entry.c
contrib/libarchive-2/libarchive/archive_entry.h
contrib/libarchive-2/libarchive/archive_entry_link_resolver.c
contrib/libarchive-2/libarchive/archive_entry_private.h
contrib/libarchive-2/libarchive/archive_entry_strmode.c
contrib/libarchive-2/libarchive/archive_platform.h
contrib/libarchive-2/libarchive/archive_read.3
contrib/libarchive-2/libarchive/archive_read_extract.c
contrib/libarchive-2/libarchive/archive_read_support_compression_bzip2.c
contrib/libarchive-2/libarchive/archive_read_support_compression_program.c
contrib/libarchive-2/libarchive/archive_read_support_format_ar.c
contrib/libarchive-2/libarchive/archive_read_support_format_iso9660.c
contrib/libarchive-2/libarchive/archive_read_support_format_mtree.c
contrib/libarchive-2/libarchive/archive_read_support_format_tar.c
contrib/libarchive-2/libarchive/archive_read_support_format_zip.c
contrib/libarchive-2/libarchive/archive_string.c
contrib/libarchive-2/libarchive/archive_string.h
contrib/libarchive-2/libarchive/archive_util.c
contrib/libarchive-2/libarchive/archive_write.3
contrib/libarchive-2/libarchive/archive_write_disk.3
contrib/libarchive-2/libarchive/archive_write_disk.c
contrib/libarchive-2/libarchive/archive_write_set_compression_program.c
contrib/libarchive-2/libarchive/archive_write_set_format_ar.c
contrib/libarchive-2/libarchive/archive_write_set_format_pax.c
contrib/libarchive-2/libarchive/archive_write_set_format_ustar.c
contrib/libarchive-2/libarchive/cpio.5
contrib/libarchive-2/libarchive/filter_fork.c
contrib/libarchive-2/libarchive/libarchive-formats.5
contrib/libarchive-2/libarchive/tar.5
contrib/libarchive-2/tar/bsdtar.1
contrib/libarchive-2/tar/bsdtar.c
contrib/libarchive-2/tar/bsdtar.h
contrib/libarchive-2/tar/matching.c
contrib/libarchive-2/tar/read.c
contrib/libarchive-2/tar/subst.c
contrib/libarchive-2/tar/util.c
contrib/libarchive-2/tar/write.c
contrib/libarchive-2/version

index b7e578e..36005fd 100644 (file)
@@ -1,4 +1,12 @@
 
+Jul 02, 2008: libarchive 2.5.5 released
+
+Jul 02, 2008: libarchive 2.5.5b released
+Jul 01, 2008: bsdcpio is being used by enough people, we can call it 1.0.0 now
+Jun 20, 2008: bsdcpio: If a -l link fails with EXDEV, copy the file instead
+Jun 19, 2008: bsdcpio: additional long options for better GNU cpio compat
+Jun 15, 2008: Many small portability and bugfixes since 2.5.4b.
+
 May 25, 2008: libarchive 2.5.4b released
 May 21, 2008: Joerg Sonnenberger: fix bsdtar hardlink handling for newc format
 
diff --git a/contrib/libarchive-2/cpio/bsdcpio.1 b/contrib/libarchive-2/cpio/bsdcpio.1
new file mode 100644 (file)
index 0000000..d4a1857
--- /dev/null
@@ -0,0 +1,367 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 21, 2007
+.Dt BSDCPIO 1
+.Os
+.Sh NAME
+.Nm cpio
+.Nd copy files to and from archives
+.Sh SYNOPSIS
+.Nm
+.Brq Fl i
+.Op Ar options
+.Op Ar pattern ...
+.Op Ar < archive
+.Nm
+.Brq Fl o
+.Op Ar options
+.Ar < name-list
+.Op Ar > archive
+.Nm
+.Brq Fl p
+.Op Ar options
+.Ar dest-dir
+.Ar < name-list
+.Sh DESCRIPTION
+.Nm
+copies files between archives and directories.
+This implementation can extract from tar, pax, cpio, zip, jar, ar,
+and ISO 9660 cdrom images and can create tar, pax, cpio, ar,
+and shar archives.
+.Pp
+The first option to
+.Nm
+is a mode indicator from the following list:
+.Bl -tag -compact -width indent
+.It Fl i
+Input.
+Read an archive from standard input (unless overriden) and extract the
+contents to disk or (if the
+.Fl t
+option is specified)
+list the contents to standard output.
+If one or more file patterns are specified, only files matching
+one of the patterns will be extracted.
+.It Fl o
+Output.
+Read a list of filenames from standard input and produce a new archive
+on standard output (unless overriden) containing the specified items.
+.It Fl p
+Pass-through.
+Read a list of filenames from standard input and copy the files to the
+specified directory.
+.El
+.Pp
+.Sh OPTIONS
+Unless specifically stated otherwise, options are applicable in
+all operating modes.
+.Bl -tag -width indent
+.It Fl A
+(o mode only)
+Append to the specified archive.
+(Not yet implemented.)
+.It Fl a
+(o and p modes)
+Reset access times on files after they are read.
+.It Fl B
+(o mode only)
+Block output to records of 5120 bytes.
+.It Fl C Ar size
+(o mode only)
+Block output to records of
+.Ar size
+bytes.
+.It Fl c
+(o mode only)
+Use the old POSIX portable character format.
+Equivalent to
+.Fl -format Ar odc .
+.It Fl d
+(i and p modes)
+Create directories as necessary.
+.It Fl E Ar file
+(i mode only)
+Read list of file name patterns from
+.Ar file
+to list and extract.
+.It Fl F Ar file
+Read archive from or write archive to
+.Ar file .
+.It Fl f Ar pattern
+(i mode only)
+Ignore files that match
+.Ar pattern .
+.It Fl -format Ar format
+(o mode only)
+Produce the output archive in the specified format.
+Supported formats include:
+.Pp
+.Bl -tag -width "iso9660" -compact
+.It Ar cpio
+Synonym for
+.Ar odc .
+.It Ar newc
+The SVR4 portable cpio format.
+.It Ar odc
+The old POSIX.1 portable octet-oriented cpio format.
+.It Ar pax
+The POSIX.1 pax format, an extension of the ustar format.
+.It Ar ustar
+The POSIX.1 tar format.
+.El
+.Pp
+The default format is
+.Ar odc .
+See
+.Xr libarchive_formats 5
+for more complete information about the
+formats currently supported by the underlying
+.Xr libarchive 3
+library.
+.It Fl I Ar file
+Read archive from
+.Ar file .
+.It Fl i
+Input mode.
+See above for description.
+.It Fl -insecure
+(i and p mode only)
+Disable security checks during extraction or copying.
+This allows extraction via symbolic links and path names containing
+.Sq ..
+in the name.
+.It Fl L
+(o and p modes)
+All symbolic links will be followed.
+Normally, symbolic links are archived and copied as symbolic links.
+With this option, the target of the link will be archived or copied instead.
+.It Fl l
+(p mode only)
+Create links from the target directory to the original files,
+instead of copying.
+.It Fl m
+(i and p modes)
+Set file modification time on created files to match
+those in the source.
+.It Fl O Ar file
+Write archive to
+.Ar file .
+.It Fl o
+Output mode.
+See above for description.
+.It Fl p
+Pass-through mode.
+See above for description.
+.It Fl -quiet
+Suppress unnecessary messages.
+.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc
+Set the owner and/or group on files in the output.
+If group is specified with no user
+(for example,
+.Fl R Ar :wheel )
+then the group will be set but not the user.
+If the user is specified with a trailing colon and no group
+(for example,
+.Fl R Ar root: )
+then the group will be set to the user's default group.
+If the user is specified with no trailing colon, then
+the user will be set but not the group.
+In
+.Fl i
+and
+.Fl p
+modes, this option can only be used by the super-user.
+(For compatibility, a period can be used in place of the colon.)
+.It Fl r
+(All modes.)
+Rename files interactively.
+For each file, a prompt is written to
+.Pa /dev/tty
+containing the name of the file and a line is read from
+.Pa /dev/tty .
+If the line read is blank, the file is skipped.
+If the line contains a single period, the file is processed normally.
+Otherwise, the line is taken to be the new name of the file.
+.It Fl t
+(i mode only)
+List the contents of the archive to stdout;
+do not restore the contents to disk.
+.It Fl u
+(i and p modes)
+Unconditionally overwrite existing files.
+Ordinarily, an older file will not overwrite a newer file on disk.
+.It Fl v
+Print the name of each file to stderr as it is processed.
+With
+.Fl t ,
+provide a detailed listing of each file.
+.It Fl -version
+Print the program version information and exit.
+.It Fl y
+(o mode only)
+Compress the archive with bzip2-compatible compression before writing it.
+In input mode, this option is ignored;
+bzip2 compression is recognized automatically on input.
+.It Fl Z
+(o mode only)
+Compress the archive with compress-compatible compression before writing it.
+In input mode, this option is ignored;
+compression is recognized automatically on input.
+.It Fl z
+(o mode only)
+Compress the archive with gzip-compatible compression before writing it.
+In input mode, this option is ignored;
+gzip compression is recognized automatically on input.
+.El
+.Sh ENVIRONMENT
+The following environment variables affect the execution of
+.Nm :
+.Bl -tag -width ".Ev BLOCKSIZE"
+.It Ev LANG
+The locale to use.
+See
+.Xr environ 7
+for more information.
+.It Ev TZ
+The timezone to use when displaying dates.
+See
+.Xr environ 7
+for more information.
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+The
+.Nm
+command is traditionally used to copy file heirarchies in conjunction
+with the
+.Xr find 1
+command.
+The first example here simply copies all files from
+.Pa src
+to
+.Pa dest :
+.Dl Nm find Pa src | Nm Fl pmud Pa dest
+.Pp
+By carefully selecting options to the
+.Xr find 1
+command and combining it with other standard utilities,
+it is possible to exercise very fine control over which files are copied.
+This next example copies files from
+.Pa src
+to
+.Pa dest
+that are more than 2 days old and whose names match a particular pattern:
+.Dl Nm find Pa src Fl mtime Ar +2 | Nm grep foo[bar] | Nm Fl pdmu Pa dest
+.Pp
+This example copies files from
+.Pa src
+to
+.Pa dest
+that are more than 2 days old and which contain the word
+.Do foobar Dc :
+.Dl Nm find Pa src Fl mtime Ar +2 | Nm xargs Nm grep -l foobar | Nm Fl pdmu Pa dest
+.Sh COMPATIBILITY
+The mode options i, o, and p and the options
+a, B, c, d, f, l, m, r, t, u, and v comply with SUSv2.
+.Pp
+The old POSIX.1 standard specified that only
+.Fl i ,
+.Fl o ,
+and
+.Fl p
+were interpreted as command-line options.
+Each took a single argument of a list of modifier
+characters.
+For example, the standard syntax allows
+.Fl imu
+but does not support
+.Fl miu
+or
+.Fl i Fl m Fl u ,
+since
+.Ar m
+and
+.Ar u
+are only modifiers to
+.Fl i ,
+they are not command-line options in their own right.
+The syntax supported by this implementation is backwards-compatible
+with the standard.
+For best compatibility, scripts should limit themselves to the
+standard syntax.
+.Sh SEE ALSO
+.Xr bzip2 1 ,
+.Xr tar 1 ,
+.Xr gzip 1 ,
+.Xr mt 1 ,
+.Xr pax 1 ,
+.Xr libarchive 3 ,
+.Xr cpio 5 ,
+.Xr libarchive-formats 5 ,
+.Xr tar 5
+.Sh STANDARDS
+There is no current POSIX standard for the cpio command; it appeared
+in
+.St -p1003.1-96
+but was dropped from
+.St -p1003.1-2001 .
+.Pp
+The cpio, ustar, and pax interchange file formats are defined by
+.St -p1003.1-2001
+for the pax command.
+.Sh HISTORY
+The original
+.Nm cpio
+and
+.Nm find
+utilities were written by Dick Haight
+while working in AT&T's Unix Support Group.
+They first appeared in 1977 in PWB/UNIX 1.0, the
+.Dq Programmer's Work Bench
+system developed for use within AT&T.
+They were first released outside of AT&T as part of System III Unix in 1981.
+As a result,
+.Nm cpio
+actually predates
+.Nm tar ,
+even though it was not well-known outside of AT&T until some time later.
+.Pp
+This is a complete re-implementation based on the
+.Xr libarchive 3
+library.
+.Sh BUGS
+The cpio archive format has several basic limitations:
+It does not store user and group names, only numbers.
+As a result, it cannot be reliably used to transfer
+files between systems with dissimilar user and group numbering.
+Older cpio formats limit the user and group numbers to
+16 or 18 bits, which is insufficient for modern systems.
+The cpio archive formats cannot support files over 4 gigabytes,
+except for the
+.Dq odc
+variant, which can support files up to 8 gigabytes.
diff --git a/contrib/libarchive-2/cpio/cmdline.c b/contrib/libarchive-2/cpio/cmdline.c
new file mode 100644 (file)
index 0000000..a602e39
--- /dev/null
@@ -0,0 +1,256 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "cpio_platform.h"
+__FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.3 2008/06/21 02:20:20 kientzle Exp $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_GETOPT_LONG
+#include <getopt.h>
+#else
+struct option {
+       const char *name;
+       int has_arg;
+       int *flag;
+       int val;
+};
+#define        no_argument 0
+#define        required_argument 1
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "cpio.h"
+
+/*
+ *
+ * Option parsing routines for bsdcpio.
+ *
+ */
+
+
+static const char *cpio_opts = "0AaBC:F:O:cdE:f:H:hijLlmopR:rtuvW:yZz";
+
+/*
+ * On systems that lack getopt_long, long options can be specified
+ * using -W longopt and -W longopt=value, e.g. "-W version" is the
+ * same as "--version" and "-W format=ustar" is the same as "--format
+ * ustar".  This does not rely the GNU getopt() "W;" extension, so
+ * should work correctly on any system with a POSIX-compliant
+ * getopt().
+ */
+
+/*
+ * If you add anything, be very careful to keep this list properly
+ * sorted, as the -W logic below relies on it.
+ */
+static const struct option cpio_longopts[] = {
+       { "create",             no_argument,       NULL, 'o' },
+       { "extract",            no_argument,       NULL, 'i' },
+       { "file",               required_argument, NULL, 'F' },
+       { "format",             required_argument, NULL, 'H' },
+       { "help",               no_argument,       NULL, 'h' },
+       { "insecure",           no_argument,       NULL, OPTION_INSECURE },
+       { "link",               no_argument,       NULL, 'l' },
+       { "list",               no_argument,       NULL, 't' },
+       { "make-directories",   no_argument,       NULL, 'd' },
+       { "null",               no_argument,       NULL, '0' },
+       { "owner",              required_argument, NULL, 'R' },
+       { "pass-through",       no_argument,       NULL, 'p' },
+       { "preserve-modification-time", no_argument, NULL, 'm' },
+       { "quiet",              no_argument,       NULL, OPTION_QUIET },
+       { "unconditional",      no_argument,       NULL, 'u' },
+       { "verbose",            no_argument,       NULL, 'v' },
+       { "version",            no_argument,       NULL, OPTION_VERSION },
+       { NULL, 0, NULL, 0 }
+};
+
+/*
+ * Parse command-line options using system-provided getopt() or getopt_long().
+ * If option is -W, then parse argument as a long option.
+ */
+int
+cpio_getopt(struct cpio *cpio)
+{
+       char *p, *q;
+       const struct option *option, *option2;
+       int opt;
+       int option_index;
+       size_t option_length;
+
+       option_index = -1;
+
+#ifdef HAVE_GETOPT_LONG
+       opt = getopt_long(cpio->argc, cpio->argv, cpio_opts,
+           cpio_longopts, &option_index);
+#else
+       opt = getopt(cpio->argc, cpio->argv, cpio_opts);
+#endif
+
+       /* Support long options through -W longopt=value */
+       if (opt == 'W') {
+               p = optarg;
+               q = strchr(optarg, '=');
+               if (q != NULL) {
+                       option_length = (size_t)(q - p);
+                       optarg = q + 1;
+               } else {
+                       option_length = strlen(p);
+                       optarg = NULL;
+               }
+               option = cpio_longopts;
+               while (option->name != NULL &&
+                   (strlen(option->name) < option_length ||
+                   strncmp(p, option->name, option_length) != 0 )) {
+                       option++;
+               }
+
+               if (option->name != NULL) {
+                       option2 = option;
+                       opt = option->val;
+
+                       /* If the first match was exact, we're done. */
+                       if (strncmp(p, option->name, strlen(option->name)) == 0) {
+                               while (option->name != NULL)
+                                       option++;
+                       } else {
+                               /* Check if there's another match. */
+                               option++;
+                               while (option->name != NULL &&
+                                   (strlen(option->name) < option_length ||
+                                   strncmp(p, option->name, option_length) != 0)) {
+                                       option++;
+                               }
+                       }
+                       if (option->name != NULL)
+                               cpio_errc(1, 0,
+                                   "Ambiguous option %s "
+                                   "(matches both %s and %s)",
+                                   p, option2->name, option->name);
+
+                       if (option2->has_arg == required_argument
+                           && optarg == NULL)
+                               cpio_errc(1, 0,
+                                   "Option \"%s\" requires argument", p);
+               } else {
+                       opt = '?';
+               }
+       }
+
+       return (opt);
+}
+
+
+/*
+ * Parse the argument to the -R or --owner flag.
+ *
+ * The format is one of the following:
+ *   <user>    - Override user but not group
+ *   <user>:   - Override both, group is user's default group
+ *   <user>:<group> - Override both
+ *   :<group>  - Override group but not user
+ *
+ * A period can be used instead of the colon.
+ *
+ * Sets uid/gid as appropriate, -1 indicates uid/gid not specified.
+ *
+ */
+int
+owner_parse(const char *spec, int *uid, int *gid)
+{
+       const char *u, *ue, *g;
+
+       *uid = -1;
+       *gid = -1;
+
+       /*
+        * Split spec into [user][:.][group]
+        *  u -> first char of username, NULL if no username
+        *  ue -> first char after username (colon, period, or \0)
+        *  g -> first char of group name
+        */
+       if (*spec == ':' || *spec == '.') {
+               /* If spec starts with ':' or '.', then just group. */
+               ue = u = NULL;
+               g = spec + 1;
+       } else {
+               /* Otherwise, [user] or [user][:] or [user][:][group] */
+               ue = u = spec;
+               while (*ue != ':' && *ue != '.' && *ue != '\0')
+                       ++ue;
+               g = ue;
+               if (*g != '\0') /* Skip : or . to find first char of group. */
+                       ++g;
+       }
+
+       if (u != NULL) {
+               /* Look up user: ue is first char after end of user. */
+               char *user;
+               struct passwd *pwent;
+
+               user = (char *)malloc(ue - u + 1);
+               if (user == NULL) {
+                       cpio_warnc(errno, "Couldn't allocate memory");
+                       return (1);
+               }
+               memcpy(user, u, ue - u);
+               user[ue - u] = '\0';
+               pwent = getpwnam(user);
+               if (pwent == NULL) {
+                       cpio_warnc(errno, "Couldn't lookup user ``%s''", user);
+                       return (1);
+               }
+               free(user);
+               *uid = pwent->pw_uid;
+               if (*ue != '\0' && *g == '\0')
+                       *gid = pwent->pw_gid;
+       }
+       if (*g != '\0') {
+               struct group *grp;
+               grp = getgrnam(g);
+               if (grp != NULL)
+                       *gid = grp->gr_gid;
+               else {
+                       cpio_warnc(errno, "Couldn't look up group ``%s''", g);
+                       return (1);
+               }
+       }
+       return (0);
+}
diff --git a/contrib/libarchive-2/cpio/cpio.c b/contrib/libarchive-2/cpio/cpio.c
new file mode 100644 (file)
index 0000000..76a91cf
--- /dev/null
@@ -0,0 +1,1026 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "cpio_platform.h"
+__FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.4 2008/06/24 15:18:40 kientzle Exp $");
+
+#include <sys/types.h>
+#include <archive.h>
+#include <archive_entry.h>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "cpio.h"
+#include "matching.h"
+
+static int     copy_data(struct archive *, struct archive *);
+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 *);
+static void    long_help(void);
+static void    mode_in(struct cpio *);
+static void    mode_list(struct cpio *);
+static void    mode_out(struct cpio *);
+static void    mode_pass(struct cpio *, const char *);
+static void    restore_time(struct cpio *, struct archive_entry *,
+                   const char *, int fd);
+static void    usage(void);
+static void    version(void);
+
+int
+main(int argc, char *argv[])
+{
+       static char buff[16384];
+       struct cpio _cpio; /* Allocated on stack. */
+       struct cpio *cpio;
+       int uid, gid;
+       int opt;
+
+       cpio = &_cpio;
+       memset(cpio, 0, sizeof(*cpio));
+       cpio->buff = buff;
+       cpio->buff_size = sizeof(buff);
+
+       /* Need cpio_progname before calling cpio_warnc. */
+       if (*argv == NULL)
+               cpio_progname = "bsdcpio";
+       else {
+               cpio_progname = strrchr(*argv, '/');
+               if (cpio_progname != NULL)
+                       cpio_progname++;
+               else
+                       cpio_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';
+       /* TODO: Implement old binary format in libarchive, use that here. */
+       cpio->format = "odc"; /* Default format */
+       cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR;
+       cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
+       cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
+       cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
+       /* TODO: If run by root, set owner as well. */
+       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';
+                       break;
+               case 'A': /* NetBSD/OpenBSD */
+                       cpio->option_append = 1;
+                       break;
+               case 'a': /* POSIX 1997 */
+                       cpio->option_atime_restore = 1;
+                       break;
+               case 'B': /* POSIX 1997 */
+                       cpio->bytes_per_block = 5120;
+                       break;
+               case 'C': /* NetBSD/OpenBSD */
+                       cpio->bytes_per_block = atoi(optarg);
+                       if (cpio->bytes_per_block <= 0)
+                               cpio_errc(1, 0, "Invalid blocksize %s", optarg);
+                       break;
+               case 'c': /* POSIX 1997 */
+                       cpio->format = "odc";
+                       break;
+               case 'd': /* POSIX 1997 */
+                       cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
+                       break;
+               case 'E': /* NetBSD/OpenBSD */
+                       include_from_file(cpio, optarg);
+                       break;
+               case 'F': /* NetBSD/OpenBSD/GNU cpio */
+                       cpio->filename = optarg;
+                       break;
+               case 'f': /* POSIX 1997 */
+                       exclude(cpio, optarg);
+                       break;
+               case 'H': /* GNU cpio (also --format) */
+                       cpio->format = optarg;
+                       break;
+               case 'h':
+                       long_help();
+                       break;
+               case 'I': /* NetBSD/OpenBSD */
+                       cpio->filename = optarg;
+                       break;
+               case 'i': /* POSIX 1997 */
+                       cpio->mode = opt;
+                       break;
+               case OPTION_INSECURE:
+                       cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS;
+                       cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
+                       break;
+               case 'L': /* GNU cpio */
+                       cpio->option_follow_links = 1;
+                       break;
+               case 'l': /* POSIX 1997 */
+                       cpio->option_link = 1;
+                       break;
+               case 'm': /* POSIX 1997 */
+                       cpio->extract_flags |= ARCHIVE_EXTRACT_TIME;
+                       break;
+               case 'O': /* GNU cpio */
+                       cpio->filename = optarg;
+                       break;
+               case 'o': /* POSIX 1997 */
+                       cpio->mode = opt;
+                       break;
+               case 'p': /* POSIX 1997 */
+                       cpio->mode = opt;
+                       cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
+                       break;
+               case OPTION_QUIET: /* GNU cpio */
+                       cpio->quiet = 1;
+                       break;
+               case 'R': /* GNU cpio, also --owner */
+                       if (owner_parse(optarg, &uid, &gid))
+                               usage();
+                       if (uid != -1)
+                               cpio->uid_override = uid;
+                       if (gid != -1)
+                               cpio->gid_override = gid;
+                       break;
+               case 'r': /* POSIX 1997 */
+                       cpio->option_rename = 1;
+                       break;
+               case 't': /* POSIX 1997 */
+                       cpio->option_list = 1;
+                       break;
+               case 'u': /* POSIX 1997 */
+                       cpio->extract_flags
+                           &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
+                       break;
+               case 'v': /* POSIX 1997 */
+                       cpio->verbose++;
+                       break;
+               case OPTION_VERSION: /* GNU convention */
+                       version();
+                       break;
+#if 0
+               /*
+                * cpio_getopt() handles -W specially, so it's not
+                * available here.
+                */
+               case 'W': /* Obscure, but useful GNU convention. */
+                       break;
+#endif
+               case 'y': /* tar convention */
+                       cpio->compress = opt;
+                       break;
+               case 'Z': /* tar convention */
+                       cpio->compress = opt;
+                       break;
+               case 'z': /* tar convention */
+                       cpio->compress = opt;
+                       break;
+               default:
+                       usage();
+               }
+       }
+
+       /* TODO: Sanity-check args, error out on nonsensical combinations. */
+
+       cpio->argc -= optind;
+       cpio->argv += optind;
+
+       switch (cpio->mode) {
+       case 'o':
+               mode_out(cpio);
+               break;
+       case 'i':
+               while (*cpio->argv != NULL) {
+                       include(cpio, *cpio->argv);
+                       --cpio->argc;
+                       ++cpio->argv;
+               }
+               if (cpio->option_list)
+                       mode_list(cpio);
+               else
+                       mode_in(cpio);
+               break;
+       case 'p':
+               if (*cpio->argv == NULL || **cpio->argv == '\0')
+                       cpio_errc(1, 0,
+                           "-p mode requires a target directory");
+               mode_pass(cpio, *cpio->argv);
+               break;
+       default:
+               cpio_errc(1, 0,
+                   "Must specify at least one of -i, -o, or -p");
+       }
+
+       return (0);
+}
+
+void
+usage(void)
+{
+       const char      *p;
+
+       p = cpio_progname;
+
+       fprintf(stderr, "Brief Usage:\n");
+       fprintf(stderr, "  List:    %s -it < archive\n", p);
+       fprintf(stderr, "  Extract: %s -i < archive\n", p);
+       fprintf(stderr, "  Create:  %s -o < filenames > archive\n", p);
+#ifdef HAVE_GETOPT_LONG
+       fprintf(stderr, "  Help:    %s --help\n", p);
+#else
+       fprintf(stderr, "  Help:    %s -h\n", p);
+#endif
+       exit(1);
+}
+
+static const char *long_help_msg =
+       "First option must be a mode specifier:\n"
+       "  -i Input  -o Output  -p Pass\n"
+       "Common Options:\n"
+       "  -v    Verbose\n"
+       "Create: %p -o [options]  < [list of files] > [archive]\n"
+       "  -z, -y  Compress archive with gzip/bzip2\n"
+       "  --format {odc|newc|ustar}  Select archive format\n"
+       "List: %p -it < [archive]\n"
+       "Extract: %p -i [options] < [archive]\n";
+
+
+/*
+ * Note that the word 'bsdcpio' will always appear in the first line
+ * of output.
+ *
+ * In particular, /bin/sh scripts that need to test for the presence
+ * of bsdcpio can use the following template:
+ *
+ * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \
+ *          echo bsdcpio; else echo not bsdcpio; fi
+ */
+static void
+long_help(void)
+{
+       const char      *prog;
+       const char      *p;
+
+       prog = cpio_progname;
+
+       fflush(stderr);
+
+       p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : "";
+       printf("%s%s: manipulate archive files\n", prog, p);
+
+       for (p = long_help_msg; *p != '\0'; p++) {
+               if (*p == '%') {
+                       if (p[1] == 'p') {
+                               fputs(prog, stdout);
+                               p++;
+                       } else
+                               putchar('%');
+               } else
+                       putchar(*p);
+       }
+       version();
+}
+
+static void
+version(void)
+{
+       fprintf(stdout,"bsdcpio %s -- %s\n",
+           BSDCPIO_VERSION_STRING,
+           archive_version());
+       exit(0);
+}
+
+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.");
+       cpio->archive = archive_write_new();
+       if (cpio->archive == NULL)
+               cpio_errc(1, 0, "Failed to allocate archive object");
+       switch (cpio->compress) {
+       case 'j': case 'y':
+               archive_write_set_compression_bzip2(cpio->archive);
+               break;
+       case 'z':
+               archive_write_set_compression_gzip(cpio->archive);
+               break;
+       case 'Z':
+               archive_write_set_compression_compress(cpio->archive);
+               break;
+       default:
+               archive_write_set_compression_none(cpio->archive);
+               break;
+       }
+       r = archive_write_set_format_by_name(cpio->archive, cpio->format);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, 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));
+
+       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)
+               file_to_archive(cpio, p);
+       process_lines_free(lr);
+
+       /*
+        * The hardlink detection may have queued up a couple of entries
+        * that can now be flushed.
+        */
+       entry = NULL;
+       archive_entry_linkify(cpio->linkresolver, &entry, &spare);
+       while (entry != NULL) {
+               entry_to_archive(cpio, entry);
+               archive_entry_free(entry);
+               entry = NULL;
+               archive_entry_linkify(cpio->linkresolver, &entry, &spare);
+       }
+
+       r = archive_write_close(cpio->archive);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(cpio->archive));
+
+       if (!cpio->quiet) {
+               blocks = (archive_position_uncompressed(cpio->archive) + 511)
+                             / 512;
+               fprintf(stderr, "%lu %s\n", blocks,
+                   blocks == 1 ? "block" : "blocks");
+       }
+       archive_write_finish(cpio->archive);
+}
+
+/*
+ * This is used by both out mode (to copy objects from disk into
+ * an archive) and pass mode (to copy objects from disk to
+ * an archive_write_disk "archive").
+ */
+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;
+       int lnklen;
+       int r;
+
+       /*
+        * Create an archive_entry describing the source file.
+        */
+       entry = archive_entry_new();
+       if (entry == NULL)
+               cpio_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);
+       }
+
+       if (cpio->uid_override >= 0)
+               st.st_uid = cpio->uid_override;
+       if (cpio->gid_override >= 0)
+               st.st_gid = cpio->uid_override;
+       archive_entry_copy_stat(entry, &st);
+
+       /* 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);
+       }
+
+       /*
+        * Generate a destination path for this entry.
+        * "destination path" is the name to which it will be copied in
+        * pass mode or the name that will go into the archive in
+        * output mode.
+        */
+       destpath = srcpath;
+       if (cpio->destdir) {
+               len = strlen(cpio->destdir) + strlen(srcpath) + 8;
+               if (len >= cpio->pass_destpath_alloc) {
+                       while (len >= cpio->pass_destpath_alloc) {
+                               cpio->pass_destpath_alloc += 512;
+                               cpio->pass_destpath_alloc *= 2;
+                       }
+                       free(cpio->pass_destpath);
+                       cpio->pass_destpath = malloc(cpio->pass_destpath_alloc);
+                       if (cpio->pass_destpath == NULL)
+                               cpio_errc(1, ENOMEM,
+                                   "Can't allocate path buffer");
+               }
+               strcpy(cpio->pass_destpath, cpio->destdir);
+               p = srcpath;
+               while (p[0] == '/')
+                       ++p;
+               strcat(cpio->pass_destpath, p);
+               destpath = cpio->pass_destpath;
+       }
+       if (cpio->option_rename)
+               destpath = cpio_rename(destpath);
+       if (destpath == NULL)
+               return (0);
+       archive_entry_copy_pathname(entry, destpath);
+
+       /*
+        * If we're trying to preserve hardlinks, match them here.
+        */
+       spare = NULL;
+       if (cpio->linkresolver != NULL
+           && !S_ISDIR(st.st_mode)) {
+               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);
+       }
+       return (r);
+}
+
+static int
+entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
+{
+       const char *destpath = archive_entry_pathname(entry);
+       const char *srcpath = archive_entry_sourcepath(entry);
+       int fd = -1;
+       ssize_t bytes_read;
+       int r;
+
+       /* Print out the destination name to the user. */
+       if (cpio->verbose)
+               fprintf(stderr,"%s", destpath);
+
+       /*
+        * Option_link only makes sense in pass mode and for
+        * regular files.  Also note: if a link operation fails
+        * because of cross-device restrictions, we'll fall back
+        * to copy mode for that entry.
+        *
+        * TODO: Test other cpio implementations to see if they
+        * hard-link anything other than regular files here.
+        */
+       if (cpio->option_link
+           && archive_entry_filetype(entry) == AE_IFREG)
+       {
+               struct archive_entry *t;
+               /* 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");
+               /* Note: link(2) doesn't create parent directories,
+                * so we use archive_write_header() instead as a
+                * convenience. */
+               archive_entry_set_hardlink(t, srcpath);
+               /* This is a straight link that carries no data. */
+               archive_entry_set_size(t, 0);
+               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));
+               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");
+               } else
+#endif
+               return (0);
+       }
+
+       /*
+        * Make sure we can open the file (if necessary) before
+        * trying to write the header.
+        */
+       if (archive_entry_filetype(entry) == AE_IFREG) {
+               if (archive_entry_size(entry) > 0) {
+                       fd = open(srcpath, O_RDONLY);
+                       if (fd < 0) {
+                               cpio_warnc(errno,
+                                   "%s: could not open file", srcpath);
+                               goto cleanup;
+                       }
+               }
+       } else {
+               archive_entry_set_size(entry, 0);
+       }
+
+       r = archive_write_header(cpio->archive, entry);
+
+       if (r != ARCHIVE_OK)
+               cpio_warnc(archive_errno(cpio->archive),
+                   "%s: %s",
+                   destpath,
+                   archive_error_string(cpio->archive));
+
+       if (r == ARCHIVE_FATAL)
+               exit(1);
+
+       if (r >= ARCHIVE_WARN && fd >= 0) {
+               bytes_read = read(fd, cpio->buff, cpio->buff_size);
+               while (bytes_read > 0) {
+                       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));
+                       if (r < bytes_read) {
+                               cpio_warnc(0,
+                                   "Truncated write; file may have grown while being archived.");
+                       }
+                       bytes_read = read(fd, cpio->buff, cpio->buff_size);
+               }
+       }
+
+       restore_time(cpio, entry, srcpath, fd);
+
+cleanup:
+       if (cpio->verbose)
+               fprintf(stderr,"\n");
+       if (fd >= 0)
+               close(fd);
+       return (0);
+}
+
+static void
+restore_time(struct cpio *cpio, struct archive_entry *entry,
+    const char *name, int fd)
+{
+#ifndef HAVE_UTIMES
+       static int warned = 0;
+
+       (void)cpio; /* UNUSED */
+       (void)entry; /* UNUSED */
+       (void)name; /* UNUSED */
+       (void)fd; /* UNUSED */
+
+       if (!warned)
+               cpio_warnc(0, "Can't restore access times on this platform");
+       warned = 1;
+       return;
+#else
+       struct timeval times[2];
+
+       if (!cpio->option_atime_restore)
+               return;
+
+        times[1].tv_sec = archive_entry_mtime(entry);
+        times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000;
+
+        times[0].tv_sec = archive_entry_atime(entry);
+        times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000;
+
+#ifdef HAVE_FUTIMES
+        if (fd >= 0 && futimes(fd, times) == 0)
+               return;
+#endif
+
+#ifdef HAVE_LUTIMES
+        if (lutimes(name, times) != 0)
+#else
+        if (!S_ISLNK(archive_entry_mode(entry)) && utimes(name, times) != 0)
+#endif
+                cpio_warnc(errno, "Can't update time for %s", name);
+#endif
+}
+
+
+static void
+mode_in(struct cpio *cpio)
+{
+       struct archive *a;
+       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");
+       r = archive_write_disk_set_options(ext, cpio->extract_flags);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(ext));
+       a = archive_read_new();
+       if (a == NULL)
+               cpio_errc(1, 0, "Couldn't allocate archive object");
+       archive_read_support_compression_all(a);
+       archive_read_support_format_all(a);
+
+       if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
+               cpio_errc(1, archive_errno(a),
+                   archive_error_string(a));
+       for (;;) {
+               r = archive_read_next_header(a, &entry);
+               if (r == ARCHIVE_EOF)
+                       break;
+               if (r != ARCHIVE_OK) {
+                       cpio_errc(1, archive_errno(a),
+                           archive_error_string(a));
+               }
+               if (excluded(cpio, archive_entry_pathname(entry)))
+                       continue;
+               if (cpio->option_rename) {
+                       destpath = cpio_rename(archive_entry_pathname(entry));
+                       archive_entry_set_pathname(entry, destpath);
+               } else
+                       destpath = archive_entry_pathname(entry);
+               if (destpath == NULL)
+                       continue;
+               if (cpio->verbose)
+                       fprintf(stdout, "%s\n", destpath);
+               if (cpio->uid_override >= 0)
+                       archive_entry_set_uid(entry, cpio->uid_override);
+               if (cpio->gid_override >= 0)
+                       archive_entry_set_gid(entry, cpio->gid_override);
+               r = archive_write_header(ext, entry);
+               if (r != ARCHIVE_OK) {
+                       fprintf(stderr, "%s: %s\n",
+                           archive_entry_pathname(entry),
+                           archive_error_string(ext));
+               } else if (archive_entry_size(entry) > 0) {
+                       r = copy_data(a, ext);
+               }
+       }
+       r = archive_read_close(a);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(a));
+       r = archive_write_close(ext);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(ext));
+       if (!cpio->quiet) {
+               blocks = (archive_position_uncompressed(a) + 511)
+                             / 512;
+               fprintf(stderr, "%lu %s\n", blocks,
+                   blocks == 1 ? "block" : "blocks");
+       }
+       archive_read_finish(a);
+       archive_write_finish(ext);
+       exit(0);
+}
+
+static int
+copy_data(struct archive *ar, struct archive *aw)
+{
+       int r;
+       size_t size;
+       const void *block;
+       off_t offset;
+
+       for (;;) {
+               r = archive_read_data_block(ar, &block, &size, &offset);
+               if (r == ARCHIVE_EOF)
+                       return (ARCHIVE_OK);
+               if (r != ARCHIVE_OK) {
+                       cpio_warnc(archive_errno(ar),
+                           "%s", archive_error_string(ar));
+                       return (r);
+               }
+               r = archive_write_data_block(aw, block, size, offset);
+               if (r != ARCHIVE_OK) {
+                       cpio_warnc(archive_errno(aw),
+                           archive_error_string(aw));
+                       return (r);
+               }
+       }
+}
+
+static void
+mode_list(struct cpio *cpio)
+{
+       struct archive *a;
+       struct archive_entry *entry;
+       unsigned long blocks;
+       int r;
+
+       a = archive_read_new();
+       if (a == NULL)
+               cpio_errc(1, 0, "Couldn't allocate archive object");
+       archive_read_support_compression_all(a);
+       archive_read_support_format_all(a);
+
+       if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
+               cpio_errc(1, archive_errno(a),
+                   archive_error_string(a));
+       for (;;) {
+               r = archive_read_next_header(a, &entry);
+               if (r == ARCHIVE_EOF)
+                       break;
+               if (r != ARCHIVE_OK) {
+                       cpio_errc(1, archive_errno(a),
+                           archive_error_string(a));
+               }
+               if (excluded(cpio, archive_entry_pathname(entry)))
+                       continue;
+               if (cpio->verbose) {
+                       /* TODO: uname/gname lookups */
+                       /* TODO: Clean this up. */
+                       fprintf(stdout,
+                           "%s%3d %8s%8s " CPIO_FILESIZE_PRINTF " %s\n",
+                           archive_entry_strmode(entry),
+                           archive_entry_nlink(entry),
+                           archive_entry_uname(entry),
+                           archive_entry_gname(entry),
+                           (CPIO_FILESIZE_TYPE)archive_entry_size(entry),
+                           archive_entry_pathname(entry));
+               } else
+                       fprintf(stdout, "%s\n", archive_entry_pathname(entry));
+       }
+       r = archive_read_close(a);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(a));
+       if (!cpio->quiet) {
+               blocks = (archive_position_uncompressed(a) + 511)
+                             / 512;
+               fprintf(stderr, "%lu %s\n", blocks,
+                   blocks == 1 ? "block" : "blocks");
+       }
+       archive_read_finish(a);
+       exit(0);
+}
+
+static void
+mode_pass(struct cpio *cpio, const char *destdir)
+{
+       struct line_reader *lr;
+       const char *p;
+       int r;
+
+       /* Ensure target dir has a trailing '/' to simplify path surgery. */
+       cpio->destdir = malloc(strlen(destdir) + 8);
+       strcpy(cpio->destdir, destdir);
+       if (destdir[strlen(destdir) - 1] != '/')
+               strcat(cpio->destdir, "/");
+
+       cpio->archive = archive_write_disk_new();
+       if (cpio->archive == NULL)
+               cpio_errc(1, 0, "Failed to allocate archive object");
+       r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(cpio->archive));
+       cpio->linkresolver = archive_entry_linkresolver_new();
+       archive_write_disk_set_standard_lookup(cpio->archive);
+       lr = process_lines_init("-", cpio->line_separator);
+       while ((p = process_lines_next(lr)) != NULL)
+               file_to_archive(cpio, p);
+       process_lines_free(lr);
+
+       archive_entry_linkresolver_free(cpio->linkresolver);
+       r = archive_write_close(cpio->archive);
+       if (r != ARCHIVE_OK)
+               cpio_errc(1, 0, archive_error_string(cpio->archive));
+       archive_write_finish(cpio->archive);
+}
+
+/*
+ * Prompt for a new name for this entry.  Returns a pointer to the
+ * new name or NULL if the entry should not be copied.  This
+ * implements the semantics defined in POSIX.1-1996, which specifies
+ * that an input of '.' means the name should be unchanged.  GNU cpio
+ * treats '.' as a literal new name.
+ */
+static const char *
+cpio_rename(const char *name)
+{
+       static char buff[1024];
+       FILE *t;
+       char *p, *ret;
+
+       t = fopen("/dev/tty", "r+");
+       if (t == NULL)
+               return (name);
+       fprintf(t, "%s (Enter/./(new name))? ", name);
+       fflush(t);
+
+       p = fgets(buff, sizeof(buff), t);
+       fclose(t);
+       if (p == NULL)
+               /* End-of-file is a blank line. */
+               return (NULL);
+
+       while (*p == ' ' || *p == '\t')
+               ++p;
+       if (*p == '\n' || *p == '\0')
+               /* Empty line. */
+               return (NULL);
+       if (*p == '.' && p[1] == '\n')
+               /* Single period preserves original name. */
+               return (name);
+       ret = p;
+       /* Trim the final newline. */
+       while (*p != '\0' && *p != '\n')
+               ++p;
+       /* Overwrite the final \n with a null character. */
+       *p = '\0';
+       return (ret);
+}
+
+
+/*
+ * Read lines from file and do something with each one.  If option_null
+ * is set, lines are terminated with zero bytes; otherwise, they're
+ * terminated with newlines.
+ *
+ * This uses a self-sizing buffer to handle arbitrarily-long lines.
+ */
+struct line_reader {
+       FILE *f;
+       char *buff, *buff_end, *line_start, *line_end, *p;
+       char *pathname;
+       size_t buff_length;
+       int separator;
+       int ret;
+};
+
+struct line_reader *
+process_lines_init(const char *pathname, char separator)
+{
+       struct line_reader *lr;
+
+       lr = calloc(1, sizeof(*lr));
+       if (lr == NULL)
+               cpio_errc(1, ENOMEM, "Can't open %s", pathname);
+
+       lr->separator = separator;
+       lr->pathname = strdup(pathname);
+
+       if (strcmp(pathname, "-") == 0)
+               lr->f = stdin;
+       else
+               lr->f = fopen(pathname, "r");
+       if (lr->f == NULL)
+               cpio_errc(1, errno, "Couldn't open %s", pathname);
+       lr->buff_length = 8192;
+       lr->buff = malloc(lr->buff_length);
+       if (lr->buff == NULL)
+               cpio_errc(1, ENOMEM, "Can't read %s", pathname);
+       lr->line_start = lr->line_end = lr->buff_end = lr->buff;
+
+       return (lr);
+}
+
+const char *
+process_lines_next(struct line_reader *lr)
+{
+       size_t bytes_wanted, bytes_read, new_buff_size;
+       char *line_start, *p;
+
+       for (;;) {
+               /* If there's a line in the buffer, return it immediately. */
+               while (lr->line_end < lr->buff_end) {
+                       if (*lr->line_end == lr->separator) {
+                               *lr->line_end = '\0';
+                               line_start = lr->line_start;
+                               lr->line_start = lr->line_end + 1;
+                               lr->line_end = lr->line_start;
+                               return (line_start);
+                       } else
+                               lr->line_end++;
+               }
+
+               /* If we're at end-of-file, process the final data. */
+               if (lr->f == NULL) {
+                       /* If there's more text, return one last line. */
+                       if (lr->line_end > lr->line_start) {
+                               *lr->line_end = '\0';
+                               line_start = lr->line_start;
+                               lr->line_start = lr->line_end + 1;
+                               lr->line_end = lr->line_start;
+                               return (line_start);
+                       }
+                       /* Otherwise, we're done. */
+                       return (NULL);
+               }
+
+               /* Buffer only has part of a line. */
+               if (lr->line_start > lr->buff) {
+                       /* Move a leftover fractional line to the beginning. */
+                       memmove(lr->buff, lr->line_start,
+                           lr->buff_end - lr->line_start);
+                       lr->buff_end -= lr->line_start - lr->buff;
+                       lr->line_end -= lr->line_start - lr->buff;
+                       lr->line_start = lr->buff;
+               } else {
+                       /* Line is too big; enlarge the buffer. */
+                       new_buff_size = lr->buff_length * 2;
+                       if (new_buff_size <= lr->buff_length)
+                               cpio_errc(1, ENOMEM,
+                                   "Line too long in %s", lr->pathname);
+                       lr->buff_length = new_buff_size;
+                       p = realloc(lr->buff, new_buff_size);
+                       if (p == NULL)
+                               cpio_errc(1, ENOMEM,
+                                   "Line too long in %s", lr->pathname);
+                       lr->buff_end = p + (lr->buff_end - lr->buff);
+                       lr->line_end = p + (lr->line_end - lr->buff);
+                       lr->line_start = lr->buff = p;
+               }
+
+               /* Get some more data into the buffer. */
+               bytes_wanted = lr->buff + lr->buff_length - lr->buff_end;
+               bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f);
+               lr->buff_end += bytes_read;
+
+               if (ferror(lr->f))
+                       cpio_errc(1, errno, "Can't read %s", lr->pathname);
+               if (feof(lr->f)) {
+                       if (lr->f != stdin)
+                               fclose(lr->f);
+                       lr->f = NULL;
+               }
+       }
+}
+
+void
+process_lines_free(struct line_reader *lr)
+{
+       free(lr->buff);
+       free(lr->pathname);
+       free(lr);
+}
diff --git a/contrib/libarchive-2/cpio/cpio.h b/contrib/libarchive-2/cpio/cpio.h
new file mode 100644 (file)
index 0000000..3afd952
--- /dev/null
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: src/usr.bin/cpio/cpio.h,v 1.2 2008/06/21 02:20:20 kientzle Exp $
+ */
+
+#ifndef CPIO_H_INCLUDED
+#define CPIO_H_INCLUDED
+
+#include "cpio_platform.h"
+#include <stdio.h>
+
+#define        DEFAULT_BYTES_PER_BLOCK (20*512)
+
+/*
+ * The internal state for the "cpio" program.
+ *
+ * Keeping all of the state in a structure like this simplifies memory
+ * leak testing (at exit, anything left on the heap is suspect).  A
+ * pointer to this structure is passed to most cpio internal
+ * functions.
+ */
+struct cpio {
+       /* Options */
+       char             *filename;
+       char              mode; /* -i -o -p */
+       char              compress; /* -j, -y, or -z */
+       const char       *format; /* -H format */
+       int               bytes_per_block; /* -b block_size */
+       int               verbose;   /* -v */
+       int               quiet;   /* --quiet */
+       int               extract_flags; /* Flags for extract operation */
+       char              symlink_mode; /* H or L, per BSD conventions */
+       const char       *compress_program;
+       char              line_separator; /* --null ? '\0' : '\n' */
+       int               option_append; /* -A, only relevant for -o */
+       int               option_atime_restore; /* -a */
+       int               option_follow_links; /* -L */
+       int               option_link; /* -l */
+       int               option_list; /* -t */
+       int               option_rename; /* -r */
+       char             *destdir;
+       size_t            pass_destpath_alloc;
+       char             *pass_destpath;
+       int               uid_override;
+       int               gid_override;
+
+       /* If >= 0, then close this when done. */
+       int               fd;
+
+       /* Miscellaneous state information */
+       struct archive   *archive;
+       int               argc;
+       char            **argv;
+       int               return_value; /* Value returned by main() */
+       struct archive_entry_linkresolver *linkresolver;
+
+       /* Work data. */
+       struct matching  *matching;
+       char             *buff;
+       size_t            buff_size;
+};
+
+/* Name of this program; used in error reporting, initialized in main(). */
+const char *cpio_progname;
+
+void   cpio_errc(int _eval, int _code, const char *fmt, ...);
+void   cpio_warnc(int _code, const char *fmt, ...);
+
+int    owner_parse(const char *, int *, int *);
+
+
+/* Fake short equivalents for long options that otherwise lack them. */
+enum {
+       OPTION_INSECURE = 1,
+       OPTION_QUIET,
+       OPTION_VERSION
+};
+
+struct line_reader;
+
+struct line_reader *process_lines_init(const char *, char separator);
+const char *process_lines_next(struct line_reader *);
+void   process_lines_free(struct line_reader *);
+
+int    cpio_getopt(struct cpio *cpio);
+int    include_from_file(struct cpio *, const char *);
+
+#endif
diff --git a/contrib/libarchive-2/cpio/cpio_platform.h b/contrib/libarchive-2/cpio/cpio_platform.h
new file mode 100644 (file)
index 0000000..3145198
--- /dev/null
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This header is the first thing included in any of the cpio
+ * source files.  As far as possible, platform-specific issues should
+ * be dealt with here and not within individual source files.
+ */
+
+#ifndef CPIO_PLATFORM_H_INCLUDED
+#define        CPIO_PLATFORM_H_INCLUDED
+
+#if defined(PLATFORM_CONFIG_H)
+/* Use hand-built config.h in environments that need it. */
+#include PLATFORM_CONFIG_H
+#elif defined(HAVE_CONFIG_H)
+/* Most POSIX platforms use the 'configure' script to build config.h */
+#include "../config.h"
+#else
+/* Warn if cpio hasn't been (automatically or manually) configured. */
+#error Oops: No config.h and no built-in configuration in cpio_platform.h.
+#endif /* !HAVE_CONFIG_H */
+
+/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>  /* For __FBSDID */
+#else
+/* Just leaving this macro replacement empty leads to a dangling semicolon. */
+#define        __FBSDID(a)     struct _undefined_hack
+#endif
+
+#ifdef HAVE_LIBARCHIVE
+/* If we're using the platform libarchive, include system headers. */
+#include <archive.h>
+#include <archive_entry.h>
+#else
+/* Otherwise, include user headers. */
+#include "archive.h"
+#include "archive_entry.h"
+#endif
+
+/*
+ * We need to be able to display a filesize using printf().  The type
+ * and format string here must be compatible with one another and
+ * large enough for any file.
+ */
+#if HAVE_UINTMAX_T
+#define        CPIO_FILESIZE_TYPE      uintmax_t
+#define        CPIO_FILESIZE_PRINTF    "%ju"
+#else
+#if HAVE_UNSIGNED_LONG_LONG
+#define        CPIO_FILESIZE_TYPE      unsigned long long
+#define        CPIO_FILESIZE_PRINTF    "%llu"
+#else
+#define        CPIO_FILESIZE_TYPE      unsigned long
+#define        CPIO_FILESIZE_PRINTF    "%lu"
+#endif
+#endif
+
+#endif /* !CPIO_PLATFORM_H_INCLUDED */
@@ -6,7 +6,8 @@
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.3 2008/05/23 04:57:28 cperciva Exp $");
 
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
+#include "cpio_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
 #endif
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
 
-#include "archive_entry.h"
-#include "archive_entry_private.h"
+#include "cpio.h"
 
-const char *
-archive_entry_strmode(struct archive_entry *entry)
+static void
+cpio_vwarnc(int code, const char *fmt, va_list ap)
 {
-       static const mode_t permbits[] =
-           { 0400, 0200, 0100, 0040, 0020, 0010, 0004, 0002, 0001 };
-       char *bp = entry->strmode;
-       mode_t mode;
-       int i;
-
-       /* Fill in a default string, then selectively override. */
-       strcpy(bp, "?rwxrwxrwx ");
+       fprintf(stderr, "%s: ", cpio_progname);
+       vfprintf(stderr, fmt, ap);
+       if (code != 0)
+               fprintf(stderr, ": %s", strerror(code));
+       fprintf(stderr, "\n");
+}
 
-       mode = archive_entry_mode(entry);
-       switch (archive_entry_filetype(entry)) {
-       case AE_IFREG:  bp[0] = '-'; break;
-       case AE_IFBLK:  bp[0] = 'b'; break;
-       case AE_IFCHR:  bp[0] = 'c'; break;
-       case AE_IFDIR:  bp[0] = 'd'; break;
-       case AE_IFLNK:  bp[0] = 'l'; break;
-       case AE_IFSOCK: bp[0] = 's'; break;
-       case AE_IFIFO:  bp[0] = 'p'; break;
-       }
+void
+cpio_warnc(int code, const char *fmt, ...)
+{
+       va_list ap;
 
-       for (i = 0; i < 9; i++)
-               if (!(mode & permbits[i]))
-                       bp[i+1] = '-';
+       va_start(ap, fmt);
+       cpio_vwarnc(code, fmt, ap);
+       va_end(ap);
+}
 
-       if (mode & S_ISUID) {
-               if (mode & 0100) bp[3] = 's';
-               else bp[3] = 'S';
-       }
-       if (mode & S_ISGID) {
-               if (mode & 0010) bp[6] = 's';
-               else bp[6] = 'S';
-       }
-       if (mode & S_ISVTX) {
-               if (mode & 0001) bp[9] = 't';
-               else bp[9] = 'T';
-       }
-       if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
-               bp[10] = '+';
+void
+cpio_errc(int eval, int code, const char *fmt, ...)
+{
+       va_list ap;
 
-       return (bp);
+       va_start(ap, fmt);
+       cpio_vwarnc(code, fmt, ap);
+       va_end(ap);
+       exit(eval);
 }
diff --git a/contrib/libarchive-2/cpio/matching.c b/contrib/libarchive-2/cpio/matching.c
new file mode 100644 (file)
index 0000000..3e4ddc3
--- /dev/null
@@ -0,0 +1,259 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cpio_platform.h"
+__FBSDID("$FreeBSD: src/usr.bin/cpio/matching.c,v 1.2 2008/06/21 02:20:20 kientzle Exp $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "matching.h"
+#include "pathmatch.h"
+
+struct match {
+       struct match     *next;
+       int               matches;
+       char              pattern[1];
+};
+
+struct matching {
+       struct match     *exclusions;
+       int               exclusions_count;
+       struct match     *inclusions;
+       int               inclusions_count;
+       int               inclusions_unmatched_count;
+};
+
+static void    add_pattern(struct match **list, const char *pattern);
+static void    initialize_matching(struct cpio *);
+static int     match_exclusion(struct match *, const char *pathname);
+static int     match_inclusion(struct match *, const char *pathname);
+
+/*
+ * The matching logic here needs to be re-thought.  I started out to
+ * try to mimic gtar's matching logic, but it's not entirely
+ * consistent.  In particular 'tar -t' and 'tar -x' interpret patterns
+ * on the command line as anchored, but --exclude doesn't.
+ */
+
+/*
+ * Utility functions to manage exclusion/inclusion patterns
+ */
+
+int
+exclude(struct cpio *cpio, const char *pattern)
+{
+       struct matching *matching;
+
+       if (cpio->matching == NULL)
+               initialize_matching(cpio);
+       matching = cpio->matching;
+       add_pattern(&(matching->exclusions), pattern);
+       matching->exclusions_count++;
+       return (0);
+}
+
+#if 0
+int
+exclude_from_file(struct cpio *cpio, const char *pathname)
+{
+       return (process_lines(cpio, pathname, &exclude));
+}
+#endif
+
+int
+include(struct cpio *cpio, const char *pattern)
+{
+       struct matching *matching;
+
+       if (cpio->matching == NULL)
+               initialize_matching(cpio);
+       matching = cpio->matching;
+       add_pattern(&(matching->inclusions), pattern);
+       matching->inclusions_count++;
+       matching->inclusions_unmatched_count++;
+       return (0);
+}
+
+int
+include_from_file(struct cpio *cpio, const char *pathname)
+{
+       struct line_reader *lr;
+       const char *p;
+       int ret = 0;
+
+       lr = process_lines_init(pathname, '\n');
+       while ((p = process_lines_next(lr)) != NULL)
+               if (include(cpio, p) != 0)
+                       ret = -1;
+       process_lines_free(lr);
+       return (ret);
+}
+
+static void
+add_pattern(struct match **list, const char *pattern)
+{
+       struct match *match;
+
+       match = malloc(sizeof(*match) + strlen(pattern) + 1);
+       if (match == NULL)
+               cpio_errc(1, errno, "Out of memory");
+       if (pattern[0] == '/')
+               pattern++;
+       strcpy(match->pattern, pattern);
+       /* Both "foo/" and "foo" should match "foo/bar". */
+       if (match->pattern[strlen(match->pattern)-1] == '/')
+               match->pattern[strlen(match->pattern)-1] = '\0';
+       match->next = *list;
+       *list = match;
+       match->matches = 0;
+}
+
+
+int
+excluded(struct cpio *cpio, const char *pathname)
+{
+       struct matching *matching;
+       struct match *match;
+       struct match *matched;
+
+       matching = cpio->matching;
+       if (matching == NULL)
+               return (0);
+
+       /* Exclusions take priority */
+       for (match = matching->exclusions; match != NULL; match = match->next){
+               if (match_exclusion(match, pathname))
+                       return (1);
+       }
+
+       /* Then check for inclusions */
+       matched = NULL;
+       for (match = matching->inclusions; match != NULL; match = match->next){
+               if (match_inclusion(match, pathname)) {
+                       /*
+                        * If this pattern has never been matched,
+                        * then we're done.
+                        */
+                       if (match->matches == 0) {
+                               match->matches++;
+                               matching->inclusions_unmatched_count++;
+                               return (0);
+                       }
+                       /*
+                        * Otherwise, remember the match but keep checking
+                        * in case we can tick off an unmatched pattern.
+                        */
+                       matched = match;
+               }
+       }
+       /*
+        * We didn't find a pattern that had never been matched, but
+        * we did find a match, so count it and exit.
+        */
+       if (matched != NULL) {
+               matched->matches++;
+               return (0);
+       }
+
+       /* If there were inclusions, default is to exclude. */
+       if (matching->inclusions != NULL)
+           return (1);
+
+       /* No explicit inclusions, default is to match. */
+       return (0);
+}
+
+/*
+ * This is a little odd, but it matches the default behavior of
+ * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
+ *
+ */
+int
+match_exclusion(struct match *match, const char *pathname)
+{
+       return (pathmatch(match->pattern,
+                   pathname,
+                   PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
+}
+
+/*
+ * Again, mimic gtar:  inclusions are always anchored (have to match
+ * the beginning of the path) even though exclusions are not anchored.
+ */
+int
+match_inclusion(struct match *match, const char *pathname)
+{
+       return (pathmatch(match->pattern, pathname, 0));
+}
+
+void
+cleanup_exclusions(struct cpio *cpio)
+{
+       struct match *p, *q;
+
+       if (cpio->matching) {
+               p = cpio->matching->inclusions;
+               while (p != NULL) {
+                       q = p;
+                       p = p->next;
+                       free(q);
+               }
+               p = cpio->matching->exclusions;
+               while (p != NULL) {
+                       q = p;
+                       p = p->next;
+                       free(q);
+               }
+               free(cpio->matching);
+       }
+}
+
+static void
+initialize_matching(struct cpio *cpio)
+{
+       cpio->matching = malloc(sizeof(*cpio->matching));
+       if (cpio->matching == NULL)
+               cpio_errc(1, errno, "No memory");
+       memset(cpio->matching, 0, sizeof(*cpio->matching));
+}
+
+int
+unmatched_inclusions(struct cpio *cpio)
+{
+       struct matching *matching;
+
+       matching = cpio->matching;
+       if (matching == NULL)
+               return (0);
+       return (matching->inclusions_unmatched_count);
+}
diff --git a/contrib/libarchive-2/cpio/matching.h b/contrib/libarchive-2/cpio/matching.h
new file mode 100644 (file)
index 0000000..a66bc86
--- /dev/null
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef MATCHING_H
+#define MATCHING_H
+
+#include "cpio.h"
+
+int    exclude(struct cpio *, const char *pattern);
+int    include(struct cpio *, const char *pattern);
+int    excluded(struct cpio *cpio, const char *pathname);
+void   cleanup_exclusions(struct cpio *cpio);
+int    unmatched_inclusions(struct cpio *cpio);
+
+#endif
diff --git a/contrib/libarchive-2/cpio/pathmatch.c b/contrib/libarchive-2/cpio/pathmatch.c
new file mode 100644 (file)
index 0000000..d33bd34
--- /dev/null
@@ -0,0 +1,250 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cpio_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "pathmatch.h"
+
+/*
+ * Check whether a character 'c' is matched by a list specification [...]:
+ *    * Leading '!' negates the class.
+ *    * <char>-<char> is a range of characters
+ *    * \<char> removes any special meaning for <char>
+ *
+ * Some interesting boundary cases:
+ *   a-d-e is one range (a-d) followed by two single characters - and e.
+ *   \a-\d is same as a-d
+ *   a\-d is three single characters: a, d, -
+ *   Trailing - is not special (so [a-] is two characters a and -).
+ *   Initial - is not special ([a-] is same as [-a] is same as [\\-a])
+ *   This function never sees a trailing \.
+ *   [] always fails
+ *   [!] always succeeds
+ */
+static int
+pm_list(const char *start, const char *end, const char c, int flags)
+{
+       const char *p = start;
+       char rangeStart = '\0', nextRangeStart;
+       int match = 1, nomatch = 0;
+
+       /* This will be used soon... */
+       (void)flags; /* UNUSED */
+
+       /* If this is a negated class, return success for nomatch. */
+       if (*p == '!' && p < end) {
+               match = 0;
+               nomatch = 1;
+               ++p;
+       }
+
+       while (p < end) {
+               nextRangeStart = '\0';
+               switch (*p) {
+               case '-':
+                       /* Trailing or initial '-' is not special. */
+                       if ((rangeStart == '\0') || (p == end - 1)) {
+                               if (*p == c)
+                                       return (match);
+                       } else {
+                               char rangeEnd = *++p;
+                               if (rangeEnd == '\\')
+                                       rangeEnd = *++p;
+                               if ((rangeStart <= c) && (c <= rangeEnd))
+                                       return (match);
+                       }
+                       break;
+               case '\\':
+                       ++p;
+                       /* Fall through */
+               default:
+                       if (*p == c)
+                               return (match);
+                       nextRangeStart = *p; /* Possible start of range. */
+               }
+               rangeStart = nextRangeStart;
+               ++p;
+       }
+       return (nomatch);
+}
+
+/*
+ * If s is pointing to "./", ".//", "./././" or the like, skip it.
+ */
+static const char *
+pm_slashskip(const char *s) {
+       while (*s == '.' || *s == '/') {
+               if (s[0] != '/' && s[1] != '/')
+                       break;
+               ++s;
+       }
+       return (s);
+}
+
+static int
+pm(const char *p, const char *s, int flags)
+{
+       const char *end;
+
+       /*
+        * Ignore leading './', './/', '././', etc.
+        */
+       if (s[0] == '.' && s[1] == '/')
+               s = pm_slashskip(s + 1);
+       if (p[0] == '.' && p[1] == '/')
+               p = pm_slashskip(p + 1);
+
+       for (;;) {
+               switch (*p) {
+               case '\0':
+                       if (s[0] == '/') {
+                               if (flags & PATHMATCH_NO_ANCHOR_END)
+                                       return (1);
+                               /* "dir" == "dir/" == "dir/." */
+                               s = pm_slashskip(s);
+                               if (s[0] == '.' && s[1] == '\0')
+                                       return (1);
+                       }
+                       return (*s == '\0');
+                       break;
+               case '?':
+                       /* ? always succeds, unless we hit end of 's' */
+                       if (*s == '\0')
+                               return (0);
+                       break;
+               case '*':
+                       /* "*" == "**" == "***" ... */
+                       while (*p == '*')
+                               ++p;
+                       /* Trailing '*' always succeeds. */
+                       if (*p == '\0')
+                               return (1);
+                       while (*s) {
+                               if (pathmatch(p, s, flags))
+                                       return (1);
+                               ++s;
+                       }
+                       return (0);
+                       break;
+               case '[':
+                       /*
+                        * Find the end of the [...] character class,
+                        * ignoring \] that might occur within the class.
+                        */
+                       end = p + 1;
+                       while (*end != '\0' && *end != ']') {
+                               if (*end == '\\' && end[1] != '\0')
+                                       ++end;
+                               ++end;
+                       }
+                       if (*end == ']') {
+                               /* We found [...], try to match it. */
+                               if (!pm_list(p + 1, end, *s, flags))
+                                       return (0);
+                               p = end; /* Jump to trailing ']' char. */
+                               break;
+                       } else
+                               /* No final ']', so just match '['. */
+                               if (*p != *s)
+                                       return (0);
+                       break;
+               default:
+                       if (*p == *s)
+                               break;
+                       if ((*s == '\0') && (*p == '/')) {
+                               p = pm_slashskip(p);
+                               if (*p == '\0')
+                                       return (1);
+                               if (p[0] == '.' && p[1] == '\0')
+                                       return (1);
+                               return (0);
+                       }
+                       return (0);
+                       break;
+               case '\\':
+                       /* Trailing '\\' matches itself. */
+                       if (p[1] == '\0') {
+                               if (*s != '\\')
+                                       return (0);
+                       } else {
+                               ++p;
+                               if (*p != *s)
+                                       return (0);
+                       }
+                       break;
+               }
+               /*
+                * TODO: pattern of "\/\.\/" should not match plain "/",
+                * it should only match explicit "/./".
+                */
+               if (*p == '/')
+                       p = pm_slashskip(p);
+               else
+                       ++p;
+               if (*s == '/')
+                       s = pm_slashskip(s);
+               else
+                       ++s;
+       }
+}
+
+/* Main entry point. */
+int
+pathmatch(const char *p, const char *s, int flags)
+{
+       /* Empty pattern only matches the empty string. */
+       if (p == NULL || *p == '\0')
+               return (s == NULL || *s == '\0');
+
+       /* Leading '^' anchors the start of the pattern. */
+       if (*p == '^') {
+               ++p;
+               flags &= ~PATHMATCH_NO_ANCHOR_START;
+       }
+
+       /* Certain patterns anchor implicitly. */
+       if (*p == '*' || *p == '/')
+               return (pm(p, s, flags));
+
+       /* If start is unanchored, try to match start of each path element. */
+       if (flags & PATHMATCH_NO_ANCHOR_START) {
+               for ( ; p != NULL; p = strchr(p, '/')) {
+                       if (*p == '/')
+                               p++;
+                       if (pm(p, s, flags))
+                               return (1);
+               }
+               return (0);
+       }
+
+       /* Default: Match from beginning. */
+       return (pm(p, s, flags));
+}
diff --git a/contrib/libarchive-2/cpio/pathmatch.h b/contrib/libarchive-2/cpio/pathmatch.h
new file mode 100644 (file)
index 0000000..990fa1f
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef PATHMATCH_H
+#define PATHMATCH_H
+
+#define PATHMATCH_NO_ANCHOR_START      1
+#define PATHMATCH_NO_ANCHOR_END        2
+
+int pathmatch(const char *p, const char *s, int flags);
+
+#endif
index 6bfe81e..3f9f6e1 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.49 2008/03/14 22:19:50 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.50 2008/05/26 17:00:22 kientzle Exp $
  */
 
 #ifndef ARCHIVE_H_INCLUDED
@@ -112,13 +112,13 @@ extern "C" {
  *             (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
  * #endif
  */
-#define        ARCHIVE_VERSION_NUMBER 2005004
+#define        ARCHIVE_VERSION_NUMBER 2005005
 __LA_DECL int          archive_version_number(void);
 
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define        ARCHIVE_VERSION_STRING "libarchive 2.5.4b"
+#define        ARCHIVE_VERSION_STRING "libarchive 2.5.5"
 __LA_DECL const char * archive_version_string(void);
 
 #if ARCHIVE_VERSION_NUMBER < 3000000
index 61af416..550be16 100644 (file)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive_endian.h,v 1.2 2008/02/26 07:17:47 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive_endian.h,v 1.3 2008/05/26 17:00:22 kientzle Exp $
  *
  * Borrowed from FreeBSD's <sys/endian.h>
  */
index e2d4ab1..9ceb18b 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.17 2008/03/14 23:00:53 kientzle Exp $
+.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
 .\"
 .Dd May 12, 2008
 .Dt archive_entry 3
index 210685a..69921c3 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry.c,v 1.51 2008/03/14 23:19:46 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry.c,v 1.52 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
index f8601b9..ee96c56 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive_entry.h,v 1.26 2008/03/14 23:00:53 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive_entry.h,v 1.27 2008/05/26 17:00:22 kientzle Exp $
  */
 
 #ifndef ARCHIVE_ENTRY_H_INCLUDED
index c0770c2..4deee26 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_link_resolver.c,v 1.1 2007/12/30 04:58:21 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_link_resolver.c,v 1.3 2008/06/15 04:31:43 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -181,6 +181,9 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
        /* If it has only one link, then we're done. */
        if (archive_entry_nlink(*e) == 1)
                return;
+       /* Directories never have hardlinks. */
+       if (archive_entry_filetype(*e) == AE_IFDIR)
+               return;
 
        switch (res->strategy) {
        case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR:
index f893fb9..0289290 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive_entry_private.h,v 1.3 2008/03/31 06:24:39 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive_entry_private.h,v 1.4 2008/05/26 17:00:22 kientzle Exp $
  */
 
 #ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
index cfe6ae3..16cb3f7 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.3 2008/05/23 04:57:28 cperciva Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -57,6 +57,11 @@ archive_entry_strmode(struct archive_entry *entry)
        case AE_IFLNK:  bp[0] = 'l'; break;
        case AE_IFSOCK: bp[0] = 's'; break;
        case AE_IFIFO:  bp[0] = 'p'; break;
+       default:
+               if (archive_entry_hardlink(entry) != NULL) {
+                       bp[0] = 'h';
+                       break;
+               }
        }
 
        for (i = 0; i < 9; i++)
index 41fd4e5..99dfacc 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.29 2008/02/19 06:06:13 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.30 2008/05/26 17:00:22 kientzle Exp $
  */
 
 /*
index dbbe1f7..13063d9 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/archive_read.3,v 1.36 2008/03/10 14:45:29 jkoshy Exp $
+.\" $FreeBSD: src/lib/libarchive/archive_read.3,v 1.37 2008/05/26 17:00:22 kientzle Exp $
 .\"
 .Dd August 19, 2006
 .Dt archive_read 3
index ab01f7d..e102799 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.60 2008/01/18 04:53:45 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
index e6397df..824b0cd 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_bzip2.c,v 1.17 2008/02/19 05:44:59 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_bzip2.c,v 1.18 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
index 206215c..4f25d6e 100644 (file)
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_program.c,v 1.2 2007/07/20 01:28:50 kientzle Exp $");
-
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_program.c,v 1.4 2008/06/15 10:45:57 kientzle Exp $");
 
 /* This capability is only available on POSIX systems. */
-#if !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL)
+#if !defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
+    !(defined(HAVE_FORK) || defined(HAVE_VFORK))
 
 /*
  * On non-Posix systems, allow the program to build, but choke if
@@ -177,6 +177,12 @@ restart_read:
                state->child_in_buf_avail = ret;
        }
 
+       if (state->child_stdin == -1) {
+               fcntl(state->child_stdout, F_SETFL, 0);
+               __archive_check_child(state->child_stdin, state->child_stdout);
+               goto restart_read;
+       }
+
        do {
                ret = write(state->child_stdin, state->child_in_buf,
                    state->child_in_buf_avail);
@@ -191,7 +197,7 @@ restart_read:
                goto restart_read;
        } else if (ret == 0 || (ret == -1 && errno == EPIPE)) {
                close(state->child_stdin);
-               state->child_stdout = -1;
+               state->child_stdin = -1;
                fcntl(state->child_stdout, F_SETFL, 0);
                goto restart_read;
        } else {
index 15d7e7c..baf80bd 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_ar.c,v 1.9 2008/03/12 21:10:26 kaiw Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_ar.c,v 1.10 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
index e0825a3..481220d 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_iso9660.c,v 1.25 2008/02/19 06:02:01 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_iso9660.c,v 1.26 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
index 72232ed..33597e0 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_mtree.c,v 1.5 2008/05/19 18:06:48 cperciva Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_mtree.c,v 1.9 2008/06/21 19:06:37 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -308,7 +308,7 @@ process_global_unset(struct archive_read *a,
        size_t len;
 
        line += 6;
-       if ((next = strchr(line, '=')) != NULL) {
+       if (strchr(line, '=') != NULL) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                    "/unset shall not contain `='");
                return ARCHIVE_FATAL;
@@ -663,7 +663,8 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
                                *use_next = 1;
                        }
                        /* Don't hold a non-regular file open. */
-                       close(mtree->fd);
+                       if (mtree->fd >= 0)
+                               close(mtree->fd);
                        mtree->fd = -1;
                        st = NULL;
                        return r;
@@ -759,7 +760,7 @@ parse_device(struct archive *a, struct archive_entry *entry, char *val)
        }
        ++comma1;
        comma2 = strchr(comma1, ',');
-       if (comma1 == NULL) {
+       if (comma2 == NULL) {
                archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
                    "Malformed device attribute");
                return (ARCHIVE_WARN);
@@ -1019,7 +1020,7 @@ skip(struct archive_read *a)
 }
 
 /*
- * Since parsing octal escapes always makes strings shorter,
+ * Since parsing backslash sequences always makes strings shorter,
  * we can always do this conversion in-place.
  */
 static void
@@ -1040,13 +1041,57 @@ parse_escapes(char *src, struct mtree_entry *mentry)
                if (c == '/' && mentry != NULL)
                        mentry->full = 1;
                if (c == '\\') {
-                       if (src[0] >= '0' && src[0] <= '3'
-                           && src[1] >= '0' && src[1] <= '7'
-                           && src[2] >= '0' && src[2] <= '7') {
-                               c = (src[0] - '0') << 6;
-                               c |= (src[1] - '0') << 3;
-                               c |= (src[2] - '0');
-                               src += 3;
+                       switch (src[0]) {
+                       case '0':
+                               if (src[1] < '0' || src[1] > '7') {
+                                       c = 0;
+                                       ++src;
+                                       break;
+                               }
+                               /* FALLTHROUGH */
+                       case '1':
+                       case '2':
+                       case '3':
+                               if (src[1] >= '0' && src[1] <= '7' &&
+                                   src[2] >= '0' && src[2] <= '7') {
+                                       c = (src[0] - '0') << 6;
+                                       c |= (src[1] - '0') << 3;
+                                       c |= (src[2] - '0');
+                                       src += 3;
+                               }
+                               break;
+                       case 'a':
+                               c = '\a';
+                               ++src;
+                               break;
+                       case 'b':
+                               c = '\b';
+                               ++src;
+                               break;
+                       case 'f':
+                               c = '\f';
+                               ++src;
+                               break;
+                       case 'n':
+                               c = '\n';
+                               ++src;
+                               break;
+                       case 'r':
+                               c = '\r';
+                               ++src;
+                               break;
+                       case 's':
+                               c = ' ';
+                               ++src;
+                               break;
+                       case 't':
+                               c = '\t';
+                               ++src;
+                               break;
+                       case 'v':
+                               c = '\v';
+                               ++src;
+                               break;
                        }
                }
                *dest++ = c;
@@ -1189,6 +1234,7 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
        const void *t;
        const char *s;
        void *p;
+       char *u;
 
        /* Accumulate line in a line buffer. */
        for (;;) {
@@ -1221,10 +1267,32 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
                total_size += bytes_read;
                /* Null terminate. */
                mtree->line.s[total_size] = '\0';
-               /* If we found '\n', clean up and return. */
-               if (p != NULL) {
-                       *start = mtree->line.s;
-                       return (total_size);
+               /* If we found an unescaped '\n', clean up and return. */
+               if (p == NULL)
+                       continue;
+               for (u = mtree->line.s; *u; ++u) {
+                       if (u[0] == '\n') {
+                               *start = mtree->line.s;
+                               return total_size;
+                       }
+                       if (u[0] == '#') {
+                               if (p == NULL)
+                                       break;
+                               *start = mtree->line.s;
+                               return total_size;
+                       }
+                       if (u[0] != '\\')
+                               continue;
+                       if (u[1] == '\\') {
+                               ++u;
+                               continue;
+                       }
+                       if (u[1] == '\n') {
+                               memmove(u, u + 1,
+                                   total_size - (u - mtree->line.s) + 1);
+                               --total_size;
+                               continue;    
+                       }
                }
        }
 }
index 6d7f048..0c2f007 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.67 2008/03/15 01:43:58 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.69 2008/05/27 04:46:12 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -2362,7 +2362,7 @@ url_decode(const char *in)
        if (out == NULL)
                return (NULL);
        for (s = in, d = out; *s != '\0'; ) {
-               if (*s == '%') {
+               if (s[0] == '%' && s[1] != '\0' && s[2] != '\0') {
                        /* Try to convert % escape */
                        int digit1 = tohex(s[1]);
                        int digit2 = tohex(s[2]);
index a105297..f04f69b 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.22 2008/02/27 06:05:59 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.24 2008/06/15 05:15:53 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -564,8 +564,8 @@ archive_read_format_zip_read_data(struct archive_read *a,
                         */
                        r = ARCHIVE_FATAL;
                } else {
-                       /* We know compressed size; just skip it. */
-                       archive_read_format_zip_read_data_skip(a);
+                       /* We can't decompress this entry, but we will
+                        * be able to skip() it and try the next entry. */
                        r = ARCHIVE_WARN;
                }
                break;
@@ -747,6 +747,10 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
 
        zip = (struct zip *)(a->format->data);
 
+       /* If we've already read to end of data, we're done. */
+       if (zip->end_of_entry_cleanup)
+               return (ARCHIVE_OK);
+
        /*
         * If the length is at the end, we have no choice but
         * to decompress all the data to find the end marker.
index 7c378de..21fe571 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_string.c,v 1.11 2007/07/15 19:13:59 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_string.c,v 1.16 2008/06/15 11:28:56 kientzle Exp $");
 
 /*
  * Basic resizable string support, to simplify manipulating arbitrary-sized
@@ -41,14 +41,6 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_string.c,v 1.11 2007/07/15 19:13:
 #include <wchar.h>
 #endif
 
-#ifdef __sgi
-/*
- * The following prototype is missing on IRXI,
- * even though the function is implemented in libc.
- */
-size_t wcrtomb(char *, wchar_t, mbstate_t *);
-#endif
-
 #include "archive_private.h"
 #include "archive_string.h"
 
@@ -172,14 +164,13 @@ __archive_strappend_int(struct archive_string *as, int d, int base)
 }
 
 /*
- * Home-grown wcrtomb for UTF-8.
+ * Home-grown wctomb for UTF-8.
  */
-static size_t
-my_wcrtomb_utf8(char *p, wchar_t wc, mbstate_t *s)
+static int
+my_wctomb_utf8(char *p, wchar_t wc)
 {
-       (void)s; /* UNUSED */
-
        if (p == NULL)
+               /* UTF-8 doesn't use shift states. */
                return (0);
        if (wc <= 0x7f) {
                p[0] = (char)wc;
@@ -208,24 +199,25 @@ my_wcrtomb_utf8(char *p, wchar_t wc, mbstate_t *s)
         * Awkward point:  UTF-8 <-> wchar_t conversions
         * can actually fail.
         */
-       return ((size_t)-1);
+       return (-1);
 }
 
 static int
 my_wcstombs(struct archive_string *as, const wchar_t *w,
-    size_t (*func)(char *, wchar_t, mbstate_t *))
+    int (*func)(char *, wchar_t))
 {
-       size_t n;
+       int n;
        char *p;
-       mbstate_t shift_state;
        char buff[256];
 
+       /* Clear the shift state before starting. */
+       (*func)(NULL, L'\0');
+
        /*
         * Convert one wide char at a time into 'buff', whenever that
         * fills, append it to the string.
         */
        p = buff;
-       wcrtomb(NULL, L'\0', &shift_state);
        while (*w != L'\0') {
                /* Flush the buffer when we have <=16 bytes free. */
                /* (No encoding has a single character >16 bytes.) */
@@ -234,8 +226,8 @@ my_wcstombs(struct archive_string *as, const wchar_t *w,
                        archive_strcat(as, buff);
                        p = buff;
                }
-               n = (*func)(p, *w++, &shift_state);
-               if (n == (size_t)-1)
+               n = (*func)(p, *w++);
+               if (n == -1)
                        return (-1);
                p += n;
        }
@@ -251,7 +243,7 @@ my_wcstombs(struct archive_string *as, const wchar_t *w,
 struct archive_string *
 __archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
 {
-       if (my_wcstombs(as, w, my_wcrtomb_utf8))
+       if (my_wcstombs(as, w, my_wctomb_utf8))
                return (NULL);
        return (as);
 }
@@ -260,42 +252,40 @@ __archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
  * Translates a wide character string into current locale character set
  * and appends to the archive_string.  Note: returns NULL if conversion
  * fails.
- *
- * TODO: use my_wcrtomb_utf8 if !HAVE_WCRTOMB (add configure logic first!)
  */
 struct archive_string *
 __archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
 {
-       if (my_wcstombs(as, w, wcrtomb))
+#if HAVE_WCTOMB
+       if (my_wcstombs(as, w, wctomb))
+               return (NULL);
+#else
+       /* TODO: Can we do better than this?  Are there platforms
+        * that have locale support but don't have wctomb()? */
+       if (my_wcstombs(as, w, my_wctomb_utf8))
                return (NULL);
+#endif
        return (as);
 }
 
 
 /*
- * Home-grown mbrtowc for UTF-8.  Some systems lack UTF-8
- * (or even lack mbrtowc()) and we need UTF-8 support for pax
+ * Home-grown mbtowc for UTF-8.  Some systems lack UTF-8
+ * (or even lack mbtowc()) and we need UTF-8 support for pax
  * format.  So please don't replace this with a call to the
- * standard mbrtowc() function!
+ * standard mbtowc() function!
  */
-static size_t
-my_mbrtowc_utf8(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
+static int
+my_mbtowc_utf8(wchar_t *pwc, const char *s, size_t n)
 {
         int ch;
 
-       /*
-        * This argument is here to make the prototype identical to the
-        * standard mbrtowc(), so I can build generic string processors
-        * that just accept a pointer to a suitable mbrtowc() function.
-        */
-       (void)ps; /* UNUSED */
-
        /* Standard behavior:  a NULL value for 's' just resets shift state. */
         if (s == NULL)
                 return (0);
        /* If length argument is zero, don't look at the first character. */
        if (n <= 0)
-               return ((size_t)-2);
+               return (-1);
 
         /*
         * Decode 1-4 bytes depending on the value of the first byte.
@@ -310,16 +300,16 @@ my_mbrtowc_utf8(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
         }
        if ((ch & 0xe0) == 0xc0) {
                if (n < 2)
-                       return ((size_t)-2);
-               if ((s[1] & 0xc0) != 0x80) return (size_t)-1;
+                       return (-1);
+               if ((s[1] & 0xc0) != 0x80) return (-1);
                 *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
                return (2);
         }
        if ((ch & 0xf0) == 0xe0) {
                if (n < 3)
-                       return ((size_t)-2);
-               if ((s[1] & 0xc0) != 0x80) return (size_t)-1;
-               if ((s[2] & 0xc0) != 0x80) return (size_t)-1;
+                       return (-1);
+               if ((s[1] & 0xc0) != 0x80) return (-1);
+               if ((s[2] & 0xc0) != 0x80) return (-1);
                 *pwc = ((ch & 0x0f) << 12)
                    | ((s[1] & 0x3f) << 6)
                    | (s[2] & 0x3f);
@@ -327,10 +317,10 @@ my_mbrtowc_utf8(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
         }
        if ((ch & 0xf8) == 0xf0) {
                if (n < 4)
-                       return ((size_t)-2);
-               if ((s[1] & 0xc0) != 0x80) return (size_t)-1;
-               if ((s[2] & 0xc0) != 0x80) return (size_t)-1;
-               if ((s[3] & 0xc0) != 0x80) return (size_t)-1;
+                       return (-1);
+               if ((s[1] & 0xc0) != 0x80) return (-1);
+               if ((s[2] & 0xc0) != 0x80) return (-1);
+               if ((s[3] & 0xc0) != 0x80) return (-1);
                 *pwc = ((ch & 0x07) << 18)
                    | ((s[1] & 0x3f) << 12)
                    | ((s[2] & 0x3f) << 6)
@@ -338,7 +328,7 @@ my_mbrtowc_utf8(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
                return (4);
         }
        /* Invalid first byte. */
-       return ((size_t)-1);
+       return (-1);
 }
 
 /*
@@ -350,7 +340,7 @@ __archive_string_utf8_w(struct archive_string *as)
 {
        wchar_t *ws, *dest;
        const char *src;
-       size_t n;
+       int n;
        int err;
 
        ws = (wchar_t *)malloc((as->length + 1) * sizeof(wchar_t));
@@ -360,10 +350,10 @@ __archive_string_utf8_w(struct archive_string *as)
        dest = ws;
        src = as->s;
        while (*src != '\0') {
-               n = my_mbrtowc_utf8(dest, src, 8, NULL);
+               n = my_mbtowc_utf8(dest, src, 8);
                if (n == 0)
                        break;
-               if (n == (size_t)-1 || n == (size_t)-2) {
+               if (n < 0) {
                        free(ws);
                        return (NULL);
                }
index 61e7077..e59c33a 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive_string.h,v 1.10 2008/03/14 22:00:09 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive_string.h,v 1.12 2008/06/15 05:11:08 kientzle Exp $
  *
  */
 
@@ -30,6 +30,9 @@
 #define        ARCHIVE_STRING_H_INCLUDED
 
 #include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>  /* required for wchar_t on some systems */
+#endif
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
index 55dd1fa..7fb4696 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_util.c,v 1.17 2008/03/14 22:31:57 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_util.c,v 1.18 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
index fff84f7..14003f4 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/archive_write.3,v 1.23 2008/03/10 14:44:41 jkoshy Exp $
+.\" $FreeBSD: src/lib/libarchive/archive_write.3,v 1.24 2008/05/26 17:00:23 kientzle Exp $
 .\"
 .Dd May 11, 2008
 .Dt archive_write 3
index f71d7d5..d68a0ff 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/archive_write_disk.3,v 1.2 2008/03/10 14:44:41 jkoshy Exp $
+.\" $FreeBSD: src/lib/libarchive/archive_write_disk.3,v 1.3 2008/05/26 17:00:23 kientzle Exp $
 .\"
 .Dd March 2, 2007
 .Dt archive_write_disk 3
index 8010c13..238173c 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.24 2008/03/15 04:20:50 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.26 2008/06/21 19:05:29 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -64,9 +64,6 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.24 2008/03/15 04
 #ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>  /* for Linux file flags */
 #endif
-#ifdef HAVE_LINUX_EXT2_FS_H
-#include <linux/ext2_fs.h>     /* for Linux file flags */
-#endif
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
@@ -613,8 +610,8 @@ _archive_write_finish_entry(struct archive *_a)
        /* Restore metadata. */
 
        /*
-        * Look up the "real" UID only if we're going to need it.  We
-        * need this for TODO_SGID because chown() requires both.
+        * Look up the "real" UID only if we're going to need it.
+        * TODO: the TODO_SGID condition can be dropped here, can't it?
         */
        if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
                a->uid = a->lookup_uid(a->lookup_uid_data,
@@ -622,6 +619,7 @@ _archive_write_finish_entry(struct archive *_a)
                    archive_entry_uid(a->entry));
        }
        /* Look up the "real" GID only if we're going to need it. */
+       /* TODO: the TODO_SUID condition can be dropped here, can't it? */
        if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
                a->gid = a->lookup_gid(a->lookup_gid_data,
                    archive_entry_gname(a->entry),
@@ -1023,7 +1021,10 @@ create_filesystem_object(struct archive_write_disk *a)
                        a->deferred |= (a->todo & TODO_TIMES);
                        a->todo &= ~TODO_TIMES;
                        /* Never use an immediate chmod(). */
-                       if (mode != final_mode)
+                       /* We can't avoid the chmod() entirely if EXTRACT_PERM
+                        * because of SysV SGID inheritance. */
+                       if ((mode != final_mode)
+                           || (a->flags & ARCHIVE_EXTRACT_PERM))
                                a->deferred |= (a->todo & TODO_MODE);
                        a->todo &= ~TODO_MODE;
                }
@@ -1351,7 +1352,7 @@ cleanup_pathname(struct archive_write_disk *a)
        if (*src == '\0') {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                    "Invalid empty pathname");
-               return (ARCHIVE_WARN);
+               return (ARCHIVE_FAILED);
        }
 
        /* Skip leading '/'. */
@@ -1382,7 +1383,7 @@ cleanup_pathname(struct archive_write_disk *a)
                                                archive_set_error(&a->archive,
                                                    ARCHIVE_ERRNO_MISC,
                                                    "Path contains '..'");
-                                               return (ARCHIVE_WARN);
+                                               return (ARCHIVE_FAILED);
                                        }
                                        lastdotdot = 1;
                                } else
@@ -1421,7 +1422,7 @@ cleanup_pathname(struct archive_write_disk *a)
                archive_set_error(&a->archive,
                    ARCHIVE_ERRNO_MISC,
                    "Path contains trailing '..'");
-               return (ARCHIVE_WARN);
+               return (ARCHIVE_FAILED);
        }
        if (dest == a->name) {
                /*
@@ -1565,8 +1566,8 @@ create_dir(struct archive_write_disk *a, char *path)
 /*
  * Note: Although we can skip setting the user id if the desired user
  * id matches the current user, we cannot skip setting the group, as
- * many systems set the gid bit based on the containing directory.  So
- * we have to perform a chown syscall if we want to restore the SGID
+ * many systems set the gid based on the containing directory.  So
+ * we have to perform a chown syscall if we want to set the SGID
  * bit.  (The alternative is to stat() and then possibly chown(); it's
  * more efficient to skip the stat() and just always chown().)  Note
  * that a successful chown() here clears the TODO_SGID_CHECK bit, which
index b8b20c8..69c5d42 100644 (file)
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_program.c,v 1.1 2007/05/29 01:00:19 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_compression_program.c,v 1.3 2008/06/15 10:45:57 kientzle Exp $");
 
 /* This capability is only available on POSIX systems. */
-#if !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL)
+#if !defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
+    !(defined(HAVE_FORK) || defined(HAVE_VFORK))
+#include "archive.h"
 
 /*
  * On non-Posix systems, allow the program to build, but choke if
@@ -180,6 +182,12 @@ restart_write:
        if (ret == -1 && errno != EAGAIN)
                return (-1);
 
+       if (state->child_stdout == -1) {
+               fcntl(state->child_stdin, F_SETFL, 0);
+               __archive_check_child(state->child_stdin, state->child_stdout);
+               goto restart_write;
+       }
+
        do {
                ret = read(state->child_stdout,
                    state->child_buf + state->child_buf_avail,
index 1731844..7176e6e 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ar.c,v 1.6 2008/03/15 11:04:45 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ar.c,v 1.7 2008/05/26 17:00:23 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
index 89f89bc..3e294cd 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_pax.c,v 1.46 2008/03/15 11:04:45 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_pax.c,v 1.47 2008/05/26 17:00:23 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
index 970fee8..8aed25d 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.26 2008/03/15 11:04:45 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.27 2008/05/26 17:00:23 kientzle Exp $");
 
 
 #ifdef HAVE_ERRNO_H
index 8f024c5..f544628 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/cpio.5,v 1.1 2007/12/30 04:58:22 kientzle Exp $
+.\" $FreeBSD: src/lib/libarchive/cpio.5,v 1.2 2008/05/26 17:00:23 kientzle Exp $
 .\"
 .Dd October 5, 2007
 .Dt CPIO 5
index 3c2d829..c746a18 100644 (file)
 #include "archive_platform.h"
 
 /* This capability is only available on POSIX systems. */
-#if defined(HAVE_PIPE) && defined(HAVE_VFORK) && defined(HAVE_FCNTL)
+#if defined(HAVE_PIPE) && defined(HAVE_FCNTL) && \
+    (defined(HAVE_FORK) || defined(HAVE_VFORK))
 
-__FBSDID("$FreeBSD: src/lib/libarchive/filter_fork.c,v 1.2 2007/12/30 04:58:22 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/filter_fork.c,v 1.4 2008/06/15 10:45:57 kientzle Exp $");
 
 #if defined(HAVE_POLL)
 #  if defined(HAVE_POLL_H)
@@ -75,7 +76,11 @@ __archive_create_child(const char *path, int *child_stdin, int *child_stdout)
                stdout_pipe[1] = tmp;
        }
 
+#if HAVE_VFORK
        switch ((child = vfork())) {
+#else
+       switch ((child = fork())) {
+#endif
        case -1:
                goto stdout_opened;
        case 0:
@@ -118,23 +123,35 @@ __archive_check_child(int in, int out)
 {
 #if defined(HAVE_POLL)
        struct pollfd fds[2];
+       int idx;
 
-       fds[0].fd = in;
-       fds[0].events = POLLOUT;
-       fds[1].fd = out;
-       fds[1].events = POLLIN;
+       idx = 0;
+       if (in != -1) {
+               fds[idx].fd = in;
+               fds[idx].events = POLLOUT;
+               ++idx;
+       }
+       if (out != -1) {
+               fds[idx].fd = out;
+               fds[idx].events = POLLIN;
+               ++idx;
+       }
 
-       poll(fds, 2, -1); /* -1 == INFTIM, wait forever */
+       poll(fds, idx, -1); /* -1 == INFTIM, wait forever */
 #elif defined(HAVE_SELECT)
        fd_set fds_in, fds_out, fds_error;
 
        FD_ZERO(&fds_in);
-       FD_SET(out, &fds_in);
        FD_ZERO(&fds_out);
-       FD_SET(in, &fds_out);
        FD_ZERO(&fds_error);
-       FD_SET(in, &fds_error);
-       FD_SET(out, &fds_error);
+       if (out != -1) {
+               FD_SET(out, &fds_in);
+               FD_SET(out, &fds_error);
+       }
+       if (in != -1) {
+               FD_SET(in, &fds_out);
+               FD_SET(in, &fds_error);
+       }
        select(in < out ? out + 1 : in + 1, &fds_in, &fds_out, &fds_error, NULL);
 #else
        sleep(1);
index f570935..dd054a9 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/libarchive-formats.5,v 1.15 2007/12/30 04:58:22 kientzle Exp $
+.\" $FreeBSD: src/lib/libarchive/libarchive-formats.5,v 1.16 2008/05/26 17:00:23 kientzle Exp $
 .\"
 .Dd April 27, 2004
 .Dt libarchive-formats 3
index c873a93..0687326 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/tar.5,v 1.17 2007/01/09 08:05:56 kientzle Exp $
+.\" $FreeBSD: src/lib/libarchive/tar.5,v 1.18 2008/05/26 17:00:23 kientzle Exp $
 .\"
 .Dd May 20, 2004
 .Dt TAR 5
index 542b0f3..e790d60 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.42 2008/05/17 15:55:29 cperciva Exp $
+.\" $FreeBSD: src/usr.bin/tar/bsdtar.1,v 1.43 2008/05/26 17:10:10 kientzle Exp $
 .\"
 .Dd May 15, 2008
 .Dt BSDTAR 1
index 2491dda..1c13cc6 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.90 2008/05/19 18:38:01 cperciva Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.91 2008/05/26 17:10:10 kientzle Exp $");
 
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
index 9d4733c..4153a44 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/usr.bin/tar/bsdtar.h,v 1.32 2008/05/22 21:08:36 cperciva Exp $
+ * $FreeBSD: src/usr.bin/tar/bsdtar.h,v 1.33 2008/05/26 17:10:10 kientzle Exp $
  */
 
 #include "bsdtar_platform.h"
index 59be17b..952055f 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/matching.c,v 1.12 2008/03/18 06:18:49 kientzle Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/matching.c,v 1.13 2008/05/26 17:10:10 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
index e1905b2..fbb8253 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.37 2008/05/18 06:24:47 cperciva Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.38 2008/05/26 17:10:10 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -388,7 +388,7 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
        if (abs(tim - now) > (365/2)*86400)
                fmt = bsdtar->day_first ? "%e %b  %Y" : "%b %e  %Y";
        else
-               fmt = bsdtar->day_first ? "%e %b %R" : "%b %e %R";
+               fmt = bsdtar->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
        strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
        fprintf(out, " %s ", tmp);
        safe_fprintf(out, "%s", archive_entry_pathname(entry));
index 9fcd4d9..1c32fb0 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: src/usr.bin/tar/subst.c,v 1.4 2008/06/15 10:08:16 kientzle Exp $");
 
 #if HAVE_REGEX_H
 #include "bsdtar.h"
@@ -34,11 +34,15 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <string.h>
 
+#ifndef REG_BASIC
+#define        REG_BASIC 0
+#endif
+
 struct subst_rule {
        struct subst_rule *next;
        regex_t re;
        char *result;
-       int global:1, print:1, symlink:1;
+       unsigned int global:1, print:1, symlink:1;
 };
 
 struct substitution {
@@ -222,7 +226,15 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, int s
                                realloc_strncat(bsdtar, result, rule->result + j, i - j - 1);
                                j = i;
                                break;
-                       case '1' ... '9':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                       case '8':
+                       case '9':
                                realloc_strncat(bsdtar, result, rule->result + j, i - j - 1);
                                if ((size_t)(c - '0') > (size_t)(rule->re.re_nsub)) {
                                        free(*result);
index 1d50dcd..ee1e40d 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/util.c,v 1.18 2008/01/02 00:21:27 kientzle Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/util.c,v 1.20 2008/06/09 14:03:55 cperciva Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -369,9 +369,11 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
        }
        if (r == 1) {
                archive_entry_copy_pathname(entry, subst_name);
-               free(subst_name);
-               if (*subst_name == '\0')
+               if (*subst_name == '\0') {
+                       free(subst_name);
                        return -1;
+               } else
+                       free(subst_name);
                name = archive_entry_pathname(entry);
        }
 
index 432612a..1a6e928 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.69 2008/05/23 05:07:22 cperciva Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.70 2008/05/26 17:10:10 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -62,9 +62,6 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.69 2008/05/23 05:07:22 cperciva
 #ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>  /* for Linux file flags */
 #endif
-#ifdef HAVE_LINUX_EXT2_FS_H
-#include <linux/ext2_fs.h>     /* for Linux file flags */
-#endif
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif