bsdcpio 2.8.3
This commit is contained in:
parent
9122b590b2
commit
b6cb607644
@ -3,8 +3,8 @@
|
|||||||
.include <bsd.own.mk>
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
PROG= bsdcpio
|
PROG= bsdcpio
|
||||||
BSDCPIO_VERSION_STRING=2.7.0
|
BSDCPIO_VERSION_STRING=2.8.3
|
||||||
SRCS= cpio.c cmdline.c err.c matching.c pathmatch.c
|
SRCS= cpio.c cmdline.c err.c line_reader.c matching.c pathmatch.c
|
||||||
CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\"
|
CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\"
|
||||||
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
|
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
|
||||||
.ifdef RELEASE_CRUNCH
|
.ifdef RELEASE_CRUNCH
|
||||||
|
@ -80,6 +80,9 @@ specified directory.
|
|||||||
Unless specifically stated otherwise, options are applicable in
|
Unless specifically stated otherwise, options are applicable in
|
||||||
all operating modes.
|
all operating modes.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
.It Fl 0
|
||||||
|
Read filenames separated by NUL characters instead of newlines.
|
||||||
|
This is necessary if any of the filenames being read might contain newlines.
|
||||||
.It Fl A
|
.It Fl A
|
||||||
(o mode only)
|
(o mode only)
|
||||||
Append to the specified archive.
|
Append to the specified archive.
|
||||||
@ -142,6 +145,11 @@ for more complete information about the
|
|||||||
formats currently supported by the underlying
|
formats currently supported by the underlying
|
||||||
.Xr libarchive 3
|
.Xr libarchive 3
|
||||||
library.
|
library.
|
||||||
|
.It Fl H Ar format
|
||||||
|
Synonym for
|
||||||
|
.Fl -format .
|
||||||
|
.It Fl h , Fl -help
|
||||||
|
Print usage information.
|
||||||
.It Fl I Ar file
|
.It Fl I Ar file
|
||||||
Read archive from
|
Read archive from
|
||||||
.Ar file .
|
.Ar file .
|
||||||
@ -154,6 +162,14 @@ Disable security checks during extraction or copying.
|
|||||||
This allows extraction via symbolic links and path names containing
|
This allows extraction via symbolic links and path names containing
|
||||||
.Sq ..
|
.Sq ..
|
||||||
in the name.
|
in the name.
|
||||||
|
.It Fl J
|
||||||
|
(o mode only)
|
||||||
|
Compress the file with xz-compatible compression before writing it.
|
||||||
|
In input mode, this option is ignored; xz compression is recognized
|
||||||
|
automatically on input.
|
||||||
|
.It Fl j
|
||||||
|
Synonym for
|
||||||
|
.Fl y .
|
||||||
.It Fl L
|
.It Fl L
|
||||||
(o and p modes)
|
(o and p modes)
|
||||||
All symbolic links will be followed.
|
All symbolic links will be followed.
|
||||||
@ -163,6 +179,11 @@ With this option, the target of the link will be archived or copied instead.
|
|||||||
(p mode only)
|
(p mode only)
|
||||||
Create links from the target directory to the original files,
|
Create links from the target directory to the original files,
|
||||||
instead of copying.
|
instead of copying.
|
||||||
|
.It Fl lzma
|
||||||
|
(o mode only)
|
||||||
|
Compress the file with lzma-compatible compression before writing it.
|
||||||
|
In input mode, this option is ignored; lzma compression is recognized
|
||||||
|
automatically on input.
|
||||||
.It Fl m
|
.It Fl m
|
||||||
(i and p modes)
|
(i and p modes)
|
||||||
Set file modification time on created files to match
|
Set file modification time on created files to match
|
||||||
@ -176,6 +197,10 @@ By default,
|
|||||||
displays the user and group names when they are provided in the
|
displays the user and group names when they are provided in the
|
||||||
archive, or looks up the user and group names in the system
|
archive, or looks up the user and group names in the system
|
||||||
password database.
|
password database.
|
||||||
|
.It Fl no-preserve-owner
|
||||||
|
(i mode only)
|
||||||
|
Do not attempt to restore file ownership.
|
||||||
|
This is the default when run by non-root users.
|
||||||
.It Fl O Ar file
|
.It Fl O Ar file
|
||||||
Write archive to
|
Write archive to
|
||||||
.Ar file .
|
.Ar file .
|
||||||
@ -185,6 +210,10 @@ See above for description.
|
|||||||
.It Fl p
|
.It Fl p
|
||||||
Pass-through mode.
|
Pass-through mode.
|
||||||
See above for description.
|
See above for description.
|
||||||
|
.It Fl preserve-owner
|
||||||
|
(i mode only)
|
||||||
|
Restore file ownership.
|
||||||
|
This is the default when run by the root user.
|
||||||
.It Fl -quiet
|
.It Fl -quiet
|
||||||
Suppress unnecessary messages.
|
Suppress unnecessary messages.
|
||||||
.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc
|
.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc
|
||||||
@ -266,7 +295,7 @@ for more information.
|
|||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
command is traditionally used to copy file hierarchies in conjunction
|
command is traditionally used to copy file heirarchies in conjunction
|
||||||
with the
|
with the
|
||||||
.Xr find 1
|
.Xr find 1
|
||||||
command.
|
command.
|
||||||
|
@ -46,11 +46,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cpio.h"
|
#include "cpio.h"
|
||||||
|
#include "err.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Short options for cpio. Please keep this sorted.
|
* Short options for cpio. Please keep this sorted.
|
||||||
*/
|
*/
|
||||||
static const char *short_options = "0AaBC:F:O:cdE:f:H:hijLlmnopR:rtuvVW:yZz";
|
static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuvW:yZz";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Long options for cpio. Please keep this sorted.
|
* Long options for cpio. Please keep this sorted.
|
||||||
@ -61,7 +62,6 @@ static const struct option {
|
|||||||
int equivalent; /* Equivalent short option. */
|
int equivalent; /* Equivalent short option. */
|
||||||
} cpio_longopts[] = {
|
} cpio_longopts[] = {
|
||||||
{ "create", 0, 'o' },
|
{ "create", 0, 'o' },
|
||||||
{ "dot", 0, 'V' },
|
|
||||||
{ "extract", 0, 'i' },
|
{ "extract", 0, 'i' },
|
||||||
{ "file", 1, 'F' },
|
{ "file", 1, 'F' },
|
||||||
{ "format", 1, 'H' },
|
{ "format", 1, 'H' },
|
||||||
@ -69,6 +69,7 @@ static const struct option {
|
|||||||
{ "insecure", 0, OPTION_INSECURE },
|
{ "insecure", 0, OPTION_INSECURE },
|
||||||
{ "link", 0, 'l' },
|
{ "link", 0, 'l' },
|
||||||
{ "list", 0, 't' },
|
{ "list", 0, 't' },
|
||||||
|
{ "lzma", 0, OPTION_LZMA },
|
||||||
{ "make-directories", 0, 'd' },
|
{ "make-directories", 0, 'd' },
|
||||||
{ "no-preserve-owner", 0, OPTION_NO_PRESERVE_OWNER },
|
{ "no-preserve-owner", 0, OPTION_NO_PRESERVE_OWNER },
|
||||||
{ "null", 0, '0' },
|
{ "null", 0, '0' },
|
||||||
@ -76,10 +77,12 @@ static const struct option {
|
|||||||
{ "owner", 1, 'R' },
|
{ "owner", 1, 'R' },
|
||||||
{ "pass-through", 0, 'p' },
|
{ "pass-through", 0, 'p' },
|
||||||
{ "preserve-modification-time", 0, 'm' },
|
{ "preserve-modification-time", 0, 'm' },
|
||||||
|
{ "preserve-owner", 0, OPTION_PRESERVE_OWNER },
|
||||||
{ "quiet", 0, OPTION_QUIET },
|
{ "quiet", 0, OPTION_QUIET },
|
||||||
{ "unconditional", 0, 'u' },
|
{ "unconditional", 0, 'u' },
|
||||||
{ "verbose", 0, 'v' },
|
{ "verbose", 0, 'v' },
|
||||||
{ "version", 0, OPTION_VERSION },
|
{ "version", 0, OPTION_VERSION },
|
||||||
|
{ "xz", 0, 'J' },
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -172,7 +175,7 @@ cpio_getopt(struct cpio *cpio)
|
|||||||
/* Otherwise, pick up the next word. */
|
/* Otherwise, pick up the next word. */
|
||||||
opt_word = *cpio->argv;
|
opt_word = *cpio->argv;
|
||||||
if (opt_word == NULL) {
|
if (opt_word == NULL) {
|
||||||
cpio_warnc(0,
|
warnc(0,
|
||||||
"Option -%c requires an argument",
|
"Option -%c requires an argument",
|
||||||
opt);
|
opt);
|
||||||
return ('?');
|
return ('?');
|
||||||
@ -223,13 +226,13 @@ cpio_getopt(struct cpio *cpio)
|
|||||||
|
|
||||||
/* Fail if there wasn't a unique match. */
|
/* Fail if there wasn't a unique match. */
|
||||||
if (match == NULL) {
|
if (match == NULL) {
|
||||||
cpio_warnc(0,
|
warnc(0,
|
||||||
"Option %s%s is not supported",
|
"Option %s%s is not supported",
|
||||||
long_prefix, opt_word);
|
long_prefix, opt_word);
|
||||||
return ('?');
|
return ('?');
|
||||||
}
|
}
|
||||||
if (match2 != NULL) {
|
if (match2 != NULL) {
|
||||||
cpio_warnc(0,
|
warnc(0,
|
||||||
"Ambiguous option %s%s (matches --%s and --%s)",
|
"Ambiguous option %s%s (matches --%s and --%s)",
|
||||||
long_prefix, opt_word, match->name, match2->name);
|
long_prefix, opt_word, match->name, match2->name);
|
||||||
return ('?');
|
return ('?');
|
||||||
@ -241,7 +244,7 @@ cpio_getopt(struct cpio *cpio)
|
|||||||
if (cpio->optarg == NULL) {
|
if (cpio->optarg == NULL) {
|
||||||
cpio->optarg = *cpio->argv;
|
cpio->optarg = *cpio->argv;
|
||||||
if (cpio->optarg == NULL) {
|
if (cpio->optarg == NULL) {
|
||||||
cpio_warnc(0,
|
warnc(0,
|
||||||
"Option %s%s requires an argument",
|
"Option %s%s requires an argument",
|
||||||
long_prefix, match->name);
|
long_prefix, match->name);
|
||||||
return ('?');
|
return ('?');
|
||||||
@ -252,7 +255,7 @@ cpio_getopt(struct cpio *cpio)
|
|||||||
} else {
|
} else {
|
||||||
/* Argument forbidden: fail if there is one. */
|
/* Argument forbidden: fail if there is one. */
|
||||||
if (cpio->optarg != NULL) {
|
if (cpio->optarg != NULL) {
|
||||||
cpio_warnc(0,
|
warnc(0,
|
||||||
"Option %s%s does not allow an argument",
|
"Option %s%s does not allow an argument",
|
||||||
long_prefix, match->name);
|
long_prefix, match->name);
|
||||||
return ('?');
|
return ('?');
|
||||||
@ -283,17 +286,20 @@ cpio_getopt(struct cpio *cpio)
|
|||||||
*
|
*
|
||||||
* Sets uid/gid return as appropriate, -1 indicates uid/gid not specified.
|
* Sets uid/gid return as appropriate, -1 indicates uid/gid not specified.
|
||||||
*
|
*
|
||||||
|
* Returns NULL if no error, otherwise returns error string for display.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
int
|
const char *
|
||||||
owner_parse(const char *spec, int *uid, int *gid)
|
owner_parse(const char *spec, int *uid, int *gid)
|
||||||
{
|
{
|
||||||
|
static char errbuff[128];
|
||||||
const char *u, *ue, *g;
|
const char *u, *ue, *g;
|
||||||
|
|
||||||
*uid = -1;
|
*uid = -1;
|
||||||
*gid = -1;
|
*gid = -1;
|
||||||
|
|
||||||
if (spec[0] == '\0')
|
if (spec[0] == '\0')
|
||||||
return (1);
|
return ("Invalid empty user/group spec");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Split spec into [user][:.][group]
|
* Split spec into [user][:.][group]
|
||||||
@ -321,10 +327,8 @@ owner_parse(const char *spec, int *uid, int *gid)
|
|||||||
struct passwd *pwent;
|
struct passwd *pwent;
|
||||||
|
|
||||||
user = (char *)malloc(ue - u + 1);
|
user = (char *)malloc(ue - u + 1);
|
||||||
if (user == NULL) {
|
if (user == NULL)
|
||||||
cpio_warnc(errno, "Couldn't allocate memory");
|
return ("Couldn't allocate memory");
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
memcpy(user, u, ue - u);
|
memcpy(user, u, ue - u);
|
||||||
user[ue - u] = '\0';
|
user[ue - u] = '\0';
|
||||||
if ((pwent = getpwnam(user)) != NULL) {
|
if ((pwent = getpwnam(user)) != NULL) {
|
||||||
@ -336,9 +340,10 @@ owner_parse(const char *spec, int *uid, int *gid)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
*uid = strtoul(user, &end, 10);
|
*uid = strtoul(user, &end, 10);
|
||||||
if (errno || *end != '\0') {
|
if (errno || *end != '\0') {
|
||||||
cpio_warnc(errno,
|
snprintf(errbuff, sizeof(errbuff),
|
||||||
"Couldn't lookup user ``%s''", user);
|
"Couldn't lookup user ``%s''", user);
|
||||||
return (1);
|
errbuff[sizeof(errbuff) - 1] = '\0';
|
||||||
|
return (errbuff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(user);
|
free(user);
|
||||||
@ -353,11 +358,12 @@ owner_parse(const char *spec, int *uid, int *gid)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
*gid = strtoul(g, &end, 10);
|
*gid = strtoul(g, &end, 10);
|
||||||
if (errno || *end != '\0') {
|
if (errno || *end != '\0') {
|
||||||
cpio_warnc(errno,
|
snprintf(errbuff, sizeof(errbuff),
|
||||||
"Couldn't lookup group ``%s''", g);
|
"Couldn't lookup group ``%s''", g);
|
||||||
return (1);
|
errbuff[sizeof(errbuff) - 1] = '\0';
|
||||||
|
return (errbuff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (0);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -25,83 +25,32 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* A default configuration for FreeBSD, used if there is no config.h. */
|
/* A hand-tooled configuration for FreeBSD. */
|
||||||
|
|
||||||
#include <sys/param.h> /* __FreeBSD_version */
|
#include <sys/param.h> /* __FreeBSD_version */
|
||||||
|
|
||||||
#if __FreeBSD__ > 4
|
|
||||||
#define HAVE_ACL_GET_PERM 0
|
|
||||||
#define HAVE_ACL_GET_PERM_NP 1
|
|
||||||
#define HAVE_ACL_PERMSET_T 1
|
|
||||||
#define HAVE_ACL_USER 1
|
|
||||||
#endif
|
|
||||||
#undef HAVE_ATTR_XATTR_H
|
|
||||||
#define HAVE_BZLIB_H 1
|
|
||||||
#define HAVE_CHFLAGS 1
|
|
||||||
#define HAVE_DECL_OPTARG 1
|
|
||||||
#define HAVE_DECL_OPTIND 1
|
|
||||||
#define HAVE_DIRENT_D_NAMLEN 1
|
|
||||||
#define HAVE_DIRENT_H 1
|
#define HAVE_DIRENT_H 1
|
||||||
#define HAVE_D_MD_ORDER 1
|
|
||||||
#define HAVE_ERRNO_H 1
|
#define HAVE_ERRNO_H 1
|
||||||
#undef HAVE_EXT2FS_EXT2_FS_H
|
|
||||||
#define HAVE_FCHDIR 1
|
|
||||||
#define HAVE_FCNTL_H 1
|
#define HAVE_FCNTL_H 1
|
||||||
#define HAVE_FNMATCH 1
|
|
||||||
#define HAVE_FNMATCH_H 1
|
|
||||||
#define HAVE_FNM_LEADING_DIR 1
|
|
||||||
#define HAVE_FTRUNCATE 1
|
|
||||||
#define HAVE_FUTIMES 1
|
#define HAVE_FUTIMES 1
|
||||||
#undef HAVE_GETXATTR
|
|
||||||
#define HAVE_GRP_H 1
|
#define HAVE_GRP_H 1
|
||||||
#define HAVE_INTTYPES_H 1
|
|
||||||
#define HAVE_LANGINFO_H 1
|
|
||||||
#undef HAVE_LGETXATTR
|
|
||||||
#undef HAVE_LIBACL
|
|
||||||
#define HAVE_LIBARCHIVE 1
|
#define HAVE_LIBARCHIVE 1
|
||||||
#define HAVE_LIBBZ2 1
|
#define HAVE_LINK 1
|
||||||
#define HAVE_LIBZ 1
|
#define HAVE_LSTAT 1
|
||||||
#define HAVE_LIMITS_H 1
|
|
||||||
#undef HAVE_LINUX_EXT2_FS_H
|
|
||||||
#undef HAVE_LINUX_FS_H
|
|
||||||
#undef HAVE_LISTXATTR
|
|
||||||
#undef HAVE_LLISTXATTR
|
|
||||||
#define HAVE_LOCALE_H 1
|
|
||||||
#define HAVE_LUTIMES 1
|
#define HAVE_LUTIMES 1
|
||||||
#define HAVE_MALLOC 1
|
|
||||||
#define HAVE_MEMMOVE 1
|
|
||||||
#define HAVE_MEMORY_H 1
|
|
||||||
#define HAVE_MEMSET 1
|
|
||||||
#if __FreeBSD_version >= 450002 /* nl_langinfo introduced */
|
|
||||||
#define HAVE_NL_LANGINFO 1
|
|
||||||
#endif
|
|
||||||
#define HAVE_PATHS_H 1
|
|
||||||
#define HAVE_PWD_H 1
|
#define HAVE_PWD_H 1
|
||||||
#define HAVE_SETLOCALE 1
|
#define HAVE_READLINK 1
|
||||||
#define HAVE_STDARG_H 1
|
#define HAVE_STDARG_H 1
|
||||||
#define HAVE_STDINT_H 1
|
|
||||||
#define HAVE_STDLIB_H 1
|
#define HAVE_STDLIB_H 1
|
||||||
#define HAVE_STRCHR 1
|
|
||||||
#define HAVE_STRDUP 1
|
|
||||||
#define HAVE_STRERROR 1
|
|
||||||
#define HAVE_STRFTIME 1
|
|
||||||
#define HAVE_STRINGS_H 1
|
|
||||||
#define HAVE_STRING_H 1
|
#define HAVE_STRING_H 1
|
||||||
#define HAVE_STRRCHR 1
|
#define HAVE_SYMLINK 1
|
||||||
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
#define HAVE_SYS_CDEFS_H 1
|
||||||
#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
|
|
||||||
#define HAVE_SYS_ACL_H 1
|
|
||||||
#define HAVE_SYS_IOCTL_H 1
|
|
||||||
#define HAVE_SYS_PARAM_H 1
|
|
||||||
#define HAVE_SYS_STAT_H 1
|
#define HAVE_SYS_STAT_H 1
|
||||||
|
#define HAVE_SYS_TIME_H 1
|
||||||
#define HAVE_TIME_H 1
|
#define HAVE_TIME_H 1
|
||||||
#define HAVE_SYS_TYPES_H 1
|
|
||||||
#define HAVE_UINTMAX_T 1
|
#define HAVE_UINTMAX_T 1
|
||||||
#define HAVE_UNISTD_H 1
|
#define HAVE_UNISTD_H 1
|
||||||
#define HAVE_UNSIGNED_LONG_LONG 1
|
#define HAVE_UNSIGNED_LONG_LONG 1
|
||||||
|
#define HAVE_UTIME_H 1
|
||||||
#define HAVE_UTIMES 1
|
#define HAVE_UTIMES 1
|
||||||
#define HAVE_VPRINTF 1
|
|
||||||
#define HAVE_ZLIB_H 1
|
|
||||||
#undef MAJOR_IN_MKDEV
|
|
||||||
#define STDC_HEADERS 1
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@
|
|||||||
#include "cpio_platform.h"
|
#include "cpio_platform.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define DEFAULT_BYTES_PER_BLOCK (20*512)
|
#include "matching.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The internal state for the "cpio" program.
|
* The internal state for the "cpio" program.
|
||||||
@ -52,17 +52,16 @@ struct cpio {
|
|||||||
const char *format; /* -H format */
|
const char *format; /* -H format */
|
||||||
int bytes_per_block; /* -b block_size */
|
int bytes_per_block; /* -b block_size */
|
||||||
int verbose; /* -v */
|
int verbose; /* -v */
|
||||||
int dot; /* -V */
|
|
||||||
int quiet; /* --quiet */
|
int quiet; /* --quiet */
|
||||||
int extract_flags; /* Flags for extract operation */
|
int extract_flags; /* Flags for extract operation */
|
||||||
char symlink_mode; /* H or L, per BSD conventions */
|
char symlink_mode; /* H or L, per BSD conventions */
|
||||||
const char *compress_program;
|
const char *compress_program;
|
||||||
char line_separator; /* --null ? '\0' : '\n' */
|
|
||||||
int option_append; /* -A, only relevant for -o */
|
int option_append; /* -A, only relevant for -o */
|
||||||
int option_atime_restore; /* -a */
|
int option_atime_restore; /* -a */
|
||||||
int option_follow_links; /* -L */
|
int option_follow_links; /* -L */
|
||||||
int option_link; /* -l */
|
int option_link; /* -l */
|
||||||
int option_list; /* -t */
|
int option_list; /* -t */
|
||||||
|
char option_null; /* --null */
|
||||||
int option_numeric_uid_gid; /* -n */
|
int option_numeric_uid_gid; /* -n */
|
||||||
int option_rename; /* -r */
|
int option_rename; /* -r */
|
||||||
char *destdir;
|
char *destdir;
|
||||||
@ -77,6 +76,7 @@ struct cpio {
|
|||||||
|
|
||||||
/* Miscellaneous state information */
|
/* Miscellaneous state information */
|
||||||
struct archive *archive;
|
struct archive *archive;
|
||||||
|
struct archive *archive_read_disk;
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
int return_value; /* Value returned by main() */
|
int return_value; /* Value returned by main() */
|
||||||
@ -91,30 +91,19 @@ struct cpio {
|
|||||||
size_t buff_size;
|
size_t buff_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Name of this program; used in error reporting, initialized in main(). */
|
const char *owner_parse(const char *, int *, int *);
|
||||||
const char *cpio_progname;
|
|
||||||
|
|
||||||
void cpio_errc(int _eval, int _code, const char *fmt, ...) __LA_DEAD;
|
|
||||||
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. */
|
/* Fake short equivalents for long options that otherwise lack them. */
|
||||||
enum {
|
enum {
|
||||||
OPTION_INSECURE = 1,
|
OPTION_INSECURE = 1,
|
||||||
|
OPTION_LZMA,
|
||||||
OPTION_NO_PRESERVE_OWNER,
|
OPTION_NO_PRESERVE_OWNER,
|
||||||
|
OPTION_PRESERVE_OWNER,
|
||||||
OPTION_QUIET,
|
OPTION_QUIET,
|
||||||
OPTION_VERSION
|
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 cpio_getopt(struct cpio *cpio);
|
||||||
int include_from_file(struct cpio *, const char *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,19 +37,18 @@
|
|||||||
#if defined(PLATFORM_CONFIG_H)
|
#if defined(PLATFORM_CONFIG_H)
|
||||||
/* Use hand-built config.h in environments that need it. */
|
/* Use hand-built config.h in environments that need it. */
|
||||||
#include PLATFORM_CONFIG_H
|
#include PLATFORM_CONFIG_H
|
||||||
#elif defined(HAVE_CONFIG_H)
|
|
||||||
/* Most POSIX platforms use the 'configure' script to build config.h */
|
|
||||||
#include "config.h"
|
|
||||||
#else
|
#else
|
||||||
/* Warn if cpio hasn't been (automatically or manually) configured. */
|
/* Read config.h or die trying. */
|
||||||
#error Oops: No config.h and no built-in configuration in cpio_platform.h.
|
#include "config.h"
|
||||||
#endif /* !HAVE_CONFIG_H */
|
#endif
|
||||||
|
|
||||||
/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
|
/* Get a real definition for __FBSDID if we can */
|
||||||
#ifdef __FreeBSD__
|
#if HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h> /* For __FBSDID */
|
#include <sys/cdefs.h>
|
||||||
#elif !defined(__FBSDID)
|
#endif
|
||||||
/* Just leaving this macro replacement empty leads to a dangling semicolon. */
|
|
||||||
|
/* If not, define it so as to avoid dangling semicolons. */
|
||||||
|
#ifndef __FBSDID
|
||||||
#define __FBSDID(a) struct _undefined_hack
|
#define __FBSDID(a) struct _undefined_hack
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -63,24 +62,6 @@
|
|||||||
#include "archive_entry.h"
|
#include "archive_entry.h"
|
||||||
#endif
|
#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
|
|
||||||
|
|
||||||
/* How to mark functions that don't return. */
|
/* How to mark functions that don't return. */
|
||||||
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
||||||
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
||||||
@ -89,9 +70,7 @@
|
|||||||
#define __LA_DEAD
|
#define __LA_DEAD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
#include "cpio_cygwin.h"
|
|
||||||
#elif defined(_WIN32) /* && !__CYGWIN__ */
|
|
||||||
#include "cpio_windows.h"
|
#include "cpio_windows.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "cpio_platform.h"
|
#include "cpio_platform.h"
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
@ -39,12 +38,14 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cpio.h"
|
#include "err.h"
|
||||||
|
|
||||||
|
const char *progname;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cpio_vwarnc(int code, const char *fmt, va_list ap)
|
vwarnc(int code, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: ", cpio_progname);
|
fprintf(stderr, "%s: ", progname);
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
fprintf(stderr, ": %s", strerror(code));
|
fprintf(stderr, ": %s", strerror(code));
|
||||||
@ -52,22 +53,22 @@ cpio_vwarnc(int code, const char *fmt, va_list ap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cpio_warnc(int code, const char *fmt, ...)
|
warnc(int code, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
cpio_vwarnc(code, fmt, ap);
|
vwarnc(code, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cpio_errc(int eval, int code, const char *fmt, ...)
|
errc(int eval, int code, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
cpio_vwarnc(code, fmt, ap);
|
vwarnc(code, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
exit(eval);
|
exit(eval);
|
||||||
}
|
}
|
||||||
|
43
usr.bin/cpio/err.h
Normal file
43
usr.bin/cpio/err.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2009 Joerg Sonnenberger
|
||||||
|
* 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LAFE_ERR_H
|
||||||
|
#define LAFE_ERR_H
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
||||||
|
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
||||||
|
#define __LA_DEAD __attribute__((__noreturn__))
|
||||||
|
#else
|
||||||
|
#define __LA_DEAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const char *progname;
|
||||||
|
|
||||||
|
void warnc(int code, const char *fmt, ...);
|
||||||
|
void errc(int eval, int code, const char *fmt, ...) __LA_DEAD;
|
||||||
|
|
||||||
|
#endif
|
171
usr.bin/cpio/line_reader.c
Normal file
171
usr.bin/cpio/line_reader.c
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2008 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$");
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "err.h"
|
||||||
|
#include "line_reader.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
|
||||||
|
#define strdup _strdup
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 nullSeparator; /* Lines separated by null, not CR/CRLF/etc. */
|
||||||
|
int ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct line_reader *
|
||||||
|
line_reader(const char *pathname, int nullSeparator)
|
||||||
|
{
|
||||||
|
struct line_reader *lr;
|
||||||
|
|
||||||
|
lr = calloc(1, sizeof(*lr));
|
||||||
|
if (lr == NULL)
|
||||||
|
errc(1, ENOMEM, "Can't open %s", pathname);
|
||||||
|
|
||||||
|
lr->nullSeparator = nullSeparator;
|
||||||
|
lr->pathname = strdup(pathname);
|
||||||
|
|
||||||
|
if (strcmp(pathname, "-") == 0)
|
||||||
|
lr->f = stdin;
|
||||||
|
else
|
||||||
|
lr->f = fopen(pathname, "r");
|
||||||
|
if (lr->f == NULL)
|
||||||
|
errc(1, errno, "Couldn't open %s", pathname);
|
||||||
|
lr->buff_length = 8192;
|
||||||
|
lr->buff = malloc(lr->buff_length);
|
||||||
|
if (lr->buff == NULL)
|
||||||
|
errc(1, ENOMEM, "Can't read %s", pathname);
|
||||||
|
lr->line_start = lr->line_end = lr->buff_end = lr->buff;
|
||||||
|
|
||||||
|
return (lr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
line_reader_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->nullSeparator) {
|
||||||
|
if (*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 if (*lr->line_end == '\x0a' || *lr->line_end == '\x0d') {
|
||||||
|
*lr->line_end = '\0';
|
||||||
|
line_start = lr->line_start;
|
||||||
|
lr->line_start = lr->line_end + 1;
|
||||||
|
lr->line_end = lr->line_start;
|
||||||
|
if (line_start[0] != '\0')
|
||||||
|
return (line_start);
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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))
|
||||||
|
errc(1, errno, "Can't read %s", lr->pathname);
|
||||||
|
if (feof(lr->f)) {
|
||||||
|
if (lr->f != stdin)
|
||||||
|
fclose(lr->f);
|
||||||
|
lr->f = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
line_reader_free(struct line_reader *lr)
|
||||||
|
{
|
||||||
|
free(lr->buff);
|
||||||
|
free(lr->pathname);
|
||||||
|
free(lr);
|
||||||
|
}
|
37
usr.bin/cpio/line_reader.h
Normal file
37
usr.bin/cpio/line_reader.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2009 Joerg Sonnenberger
|
||||||
|
* 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LAFE_LINE_READER_H
|
||||||
|
#define LAFE_LINE_READER_H
|
||||||
|
|
||||||
|
struct line_reader;
|
||||||
|
|
||||||
|
struct line_reader *line_reader(const char *, int nullSeparator);
|
||||||
|
const char *line_reader_next(struct line_reader *);
|
||||||
|
void line_reader_free(struct line_reader *);
|
||||||
|
|
||||||
|
#endif
|
@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "err.h"
|
||||||
|
#include "line_reader.h"
|
||||||
#include "matching.h"
|
#include "matching.h"
|
||||||
#include "pathmatch.h"
|
#include "pathmatch.h"
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ struct matching {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void add_pattern(struct match **list, const char *pattern);
|
static void add_pattern(struct match **list, const char *pattern);
|
||||||
static void initialize_matching(struct cpio *);
|
static void initialize_matching(struct matching **);
|
||||||
static int match_exclusion(struct match *, const char *pathname);
|
static int match_exclusion(struct match *, const char *pathname);
|
||||||
static int match_inclusion(struct match *, const char *pathname);
|
static int match_inclusion(struct match *, const char *pathname);
|
||||||
|
|
||||||
@ -70,52 +72,58 @@ static int match_inclusion(struct match *, const char *pathname);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
exclude(struct cpio *cpio, const char *pattern)
|
exclude(struct matching **matching, const char *pattern)
|
||||||
{
|
{
|
||||||
struct matching *matching;
|
|
||||||
|
|
||||||
if (cpio->matching == NULL)
|
if (*matching == NULL)
|
||||||
initialize_matching(cpio);
|
initialize_matching(matching);
|
||||||
matching = cpio->matching;
|
add_pattern(&((*matching)->exclusions), pattern);
|
||||||
add_pattern(&(matching->exclusions), pattern);
|
(*matching)->exclusions_count++;
|
||||||
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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
include_from_file(struct cpio *cpio, const char *pathname)
|
exclude_from_file(struct matching **matching, const char *pathname)
|
||||||
{
|
{
|
||||||
struct line_reader *lr;
|
struct line_reader *lr;
|
||||||
const char *p;
|
const char *p;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
lr = process_lines_init(pathname, '\n');
|
lr = line_reader(pathname, 0);
|
||||||
while ((p = process_lines_next(lr)) != NULL)
|
while ((p = line_reader_next(lr)) != NULL) {
|
||||||
if (include(cpio, p) != 0)
|
if (exclude(matching, p) != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
process_lines_free(lr);
|
}
|
||||||
|
line_reader_free(lr);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
include(struct matching **matching, const char *pattern)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*matching == NULL)
|
||||||
|
initialize_matching(matching);
|
||||||
|
add_pattern(&((*matching)->inclusions), pattern);
|
||||||
|
(*matching)->inclusions_count++;
|
||||||
|
(*matching)->inclusions_unmatched_count++;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
include_from_file(struct matching **matching, const char *pathname,
|
||||||
|
int nullSeparator)
|
||||||
|
{
|
||||||
|
struct line_reader *lr;
|
||||||
|
const char *p;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
lr = line_reader(pathname, nullSeparator);
|
||||||
|
while ((p = line_reader_next(lr)) != NULL) {
|
||||||
|
if (include(matching, p) != 0)
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
line_reader_free(lr);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,15 +131,15 @@ static void
|
|||||||
add_pattern(struct match **list, const char *pattern)
|
add_pattern(struct match **list, const char *pattern)
|
||||||
{
|
{
|
||||||
struct match *match;
|
struct match *match;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
match = malloc(sizeof(*match) + strlen(pattern) + 1);
|
len = strlen(pattern);
|
||||||
|
match = malloc(sizeof(*match) + len + 1);
|
||||||
if (match == NULL)
|
if (match == NULL)
|
||||||
cpio_errc(1, errno, "Out of memory");
|
errc(1, errno, "Out of memory");
|
||||||
if (pattern[0] == '/')
|
|
||||||
pattern++;
|
|
||||||
strcpy(match->pattern, pattern);
|
strcpy(match->pattern, pattern);
|
||||||
/* Both "foo/" and "foo" should match "foo/bar". */
|
/* Both "foo/" and "foo" should match "foo/bar". */
|
||||||
if (match->pattern[strlen(match->pattern)-1] == '/')
|
if (len && match->pattern[len - 1] == '/')
|
||||||
match->pattern[strlen(match->pattern)-1] = '\0';
|
match->pattern[strlen(match->pattern)-1] = '\0';
|
||||||
match->next = *list;
|
match->next = *list;
|
||||||
*list = match;
|
*list = match;
|
||||||
@ -140,13 +148,11 @@ add_pattern(struct match **list, const char *pattern)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
excluded(struct cpio *cpio, const char *pathname)
|
excluded(struct matching *matching, const char *pathname)
|
||||||
{
|
{
|
||||||
struct matching *matching;
|
|
||||||
struct match *match;
|
struct match *match;
|
||||||
struct match *matched;
|
struct match *matched;
|
||||||
|
|
||||||
matching = cpio->matching;
|
|
||||||
if (matching == NULL)
|
if (matching == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
@ -166,7 +172,7 @@ excluded(struct cpio *cpio, const char *pathname)
|
|||||||
*/
|
*/
|
||||||
if (match->matches == 0) {
|
if (match->matches == 0) {
|
||||||
match->matches++;
|
match->matches++;
|
||||||
matching->inclusions_unmatched_count++;
|
matching->inclusions_unmatched_count--;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -198,7 +204,7 @@ excluded(struct cpio *cpio, const char *pathname)
|
|||||||
* gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar'
|
* gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar'
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
match_exclusion(struct match *match, const char *pathname)
|
match_exclusion(struct match *match, const char *pathname)
|
||||||
{
|
{
|
||||||
return (pathmatch(match->pattern,
|
return (pathmatch(match->pattern,
|
||||||
@ -210,50 +216,69 @@ match_exclusion(struct match *match, const char *pathname)
|
|||||||
* Again, mimic gtar: inclusions are always anchored (have to match
|
* Again, mimic gtar: inclusions are always anchored (have to match
|
||||||
* the beginning of the path) even though exclusions are not anchored.
|
* the beginning of the path) even though exclusions are not anchored.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
match_inclusion(struct match *match, const char *pathname)
|
match_inclusion(struct match *match, const char *pathname)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
return (pathmatch(match->pattern, pathname, 0));
|
return (pathmatch(match->pattern, pathname, 0));
|
||||||
|
#else
|
||||||
|
return (pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cleanup_exclusions(struct cpio *cpio)
|
cleanup_exclusions(struct matching **matching)
|
||||||
{
|
{
|
||||||
struct match *p, *q;
|
struct match *p, *q;
|
||||||
|
|
||||||
if (cpio->matching) {
|
if (*matching == NULL)
|
||||||
p = cpio->matching->inclusions;
|
return;
|
||||||
while (p != NULL) {
|
|
||||||
|
for (p = (*matching)->inclusions; p != NULL; ) {
|
||||||
q = p;
|
q = p;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
free(q);
|
free(q);
|
||||||
}
|
}
|
||||||
p = cpio->matching->exclusions;
|
|
||||||
while (p != NULL) {
|
for (p = (*matching)->exclusions; p != NULL; ) {
|
||||||
q = p;
|
q = p;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
free(q);
|
free(q);
|
||||||
}
|
}
|
||||||
free(cpio->matching);
|
|
||||||
}
|
free(*matching);
|
||||||
|
*matching = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initialize_matching(struct cpio *cpio)
|
initialize_matching(struct matching **matching)
|
||||||
{
|
{
|
||||||
cpio->matching = malloc(sizeof(*cpio->matching));
|
*matching = calloc(sizeof(**matching), 1);
|
||||||
if (cpio->matching == NULL)
|
if (*matching == NULL)
|
||||||
cpio_errc(1, errno, "No memory");
|
errc(1, errno, "No memory");
|
||||||
memset(cpio->matching, 0, sizeof(*cpio->matching));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
unmatched_inclusions(struct cpio *cpio)
|
unmatched_inclusions(struct matching *matching)
|
||||||
{
|
{
|
||||||
struct matching *matching;
|
|
||||||
|
|
||||||
matching = cpio->matching;
|
|
||||||
if (matching == NULL)
|
if (matching == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
return (matching->inclusions_unmatched_count);
|
return (matching->inclusions_unmatched_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
unmatched_inclusions_warn(struct matching *matching, const char *msg)
|
||||||
|
{
|
||||||
|
struct match *p;
|
||||||
|
|
||||||
|
if (matching == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
for (p = matching->inclusions; p != NULL; p = p->next) {
|
||||||
|
if (p->matches == 0)
|
||||||
|
warnc(0, "%s: %s", p->pattern, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (matching->inclusions_unmatched_count);
|
||||||
|
}
|
||||||
|
@ -29,12 +29,18 @@
|
|||||||
#ifndef MATCHING_H
|
#ifndef MATCHING_H
|
||||||
#define MATCHING_H
|
#define MATCHING_H
|
||||||
|
|
||||||
#include "cpio.h"
|
struct matching;
|
||||||
|
|
||||||
int exclude(struct cpio *, const char *pattern);
|
int exclude(struct matching **matching, const char *pattern);
|
||||||
int include(struct cpio *, const char *pattern);
|
int exclude_from_file(struct matching **matching,
|
||||||
int excluded(struct cpio *cpio, const char *pathname);
|
const char *pathname);
|
||||||
void cleanup_exclusions(struct cpio *cpio);
|
int include(struct matching **matching, const char *pattern);
|
||||||
int unmatched_inclusions(struct cpio *cpio);
|
int include_from_file(struct matching **matching,
|
||||||
|
const char *pathname, int nullSeparator);
|
||||||
|
|
||||||
|
int excluded(struct matching *, const char *pathname);
|
||||||
|
void cleanup_exclusions(struct matching **);
|
||||||
|
int unmatched_inclusions(struct matching *);
|
||||||
|
int unmatched_inclusions_warn(struct matching *, const char *msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -131,7 +131,6 @@ pm(const char *p, const char *s, int flags)
|
|||||||
s = pm_slashskip(s);
|
s = pm_slashskip(s);
|
||||||
}
|
}
|
||||||
return (*s == '\0');
|
return (*s == '\0');
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
/* ? always succeds, unless we hit end of 's' */
|
/* ? always succeds, unless we hit end of 's' */
|
||||||
if (*s == '\0')
|
if (*s == '\0')
|
||||||
@ -150,7 +149,6 @@ pm(const char *p, const char *s, int flags)
|
|||||||
++s;
|
++s;
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
break;
|
|
||||||
case '[':
|
case '[':
|
||||||
/*
|
/*
|
||||||
* Find the end of the [...] character class,
|
* Find the end of the [...] character class,
|
||||||
@ -229,9 +227,17 @@ pathmatch(const char *p, const char *s, int flags)
|
|||||||
flags &= ~PATHMATCH_NO_ANCHOR_START;
|
flags &= ~PATHMATCH_NO_ANCHOR_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Certain patterns anchor implicitly. */
|
if (*p == '/' && *s != '/')
|
||||||
if (*p == '*' || *p == '/')
|
return (0);
|
||||||
|
|
||||||
|
/* Certain patterns and file names anchor implicitly. */
|
||||||
|
if (*p == '*' || *p == '/' || *p == '/') {
|
||||||
|
while (*p == '/')
|
||||||
|
++p;
|
||||||
|
while (*s == '/')
|
||||||
|
++s;
|
||||||
return (pm(p, s, flags));
|
return (pm(p, s, flags));
|
||||||
|
}
|
||||||
|
|
||||||
/* If start is unanchored, try to match start of each path element. */
|
/* If start is unanchored, try to match start of each path element. */
|
||||||
if (flags & PATHMATCH_NO_ANCHOR_START) {
|
if (flags & PATHMATCH_NO_ANCHOR_START) {
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PATHMATCH_H
|
#ifndef LAFE_PATHMATCH_H
|
||||||
#define PATHMATCH_H
|
#define LAFE_PATHMATCH_H
|
||||||
|
|
||||||
/* Don't anchor at beginning unless the pattern starts with "^" */
|
/* Don't anchor at beginning unless the pattern starts with "^" */
|
||||||
#define PATHMATCH_NO_ANCHOR_START 1
|
#define PATHMATCH_NO_ANCHOR_START 1
|
||||||
|
Loading…
Reference in New Issue
Block a user