Update bsdcpio to 2.8.4
Use common code from lib/libarchive/libarchive_fe Approved by: kientzle MFC after: 2 weeks
This commit is contained in:
parent
2ad1419f1b
commit
f305d4bef7
@ -3,17 +3,24 @@
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= bsdcpio
|
||||
BSDCPIO_VERSION_STRING=2.8.3
|
||||
SRCS= cpio.c cmdline.c err.c line_reader.c matching.c pathmatch.c
|
||||
BSDCPIO_VERSION_STRING=2.8.4
|
||||
|
||||
SRCS= cpio.c cmdline.c
|
||||
|
||||
.PATH: ${.CURDIR}/../../lib/libarchive/libarchive_fe
|
||||
SRCS+= err.c line_reader.c matching.c pathmatch.c
|
||||
|
||||
CFLAGS+= -DBSDCPIO_VERSION_STRING=\"${BSDCPIO_VERSION_STRING}\"
|
||||
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
|
||||
CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../lib/libarchive/libarchive_fe
|
||||
|
||||
.ifdef RELEASE_CRUNCH
|
||||
# FreeBSD's installer uses cpio in crunched binaries that are
|
||||
# statically linked, cannot use -lcrypto, and are size sensitive.
|
||||
CFLAGS+= -DSMALLER
|
||||
.endif
|
||||
DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2} ${LIBMD} ${LIBLZMA}
|
||||
LDADD= -larchive -lz -lbz2 -lmd -llzma
|
||||
DPADD= ${LIBARCHIVE} ${LIBZ} ${LIBBZ2} ${LIBMD} ${LIBLZMA} ${LIBBSDXML}
|
||||
LDADD= -larchive -lz -lbz2 -lmd -llzma -lbsdxml
|
||||
.if ${MK_OPENSSL} != "no"
|
||||
DPADD+= ${LIBCRYPTO}
|
||||
LDADD+= -lcrypto
|
||||
|
@ -175,7 +175,7 @@ cpio_getopt(struct cpio *cpio)
|
||||
/* Otherwise, pick up the next word. */
|
||||
opt_word = *cpio->argv;
|
||||
if (opt_word == NULL) {
|
||||
warnc(0,
|
||||
lafe_warnc(0,
|
||||
"Option -%c requires an argument",
|
||||
opt);
|
||||
return ('?');
|
||||
@ -226,13 +226,13 @@ cpio_getopt(struct cpio *cpio)
|
||||
|
||||
/* Fail if there wasn't a unique match. */
|
||||
if (match == NULL) {
|
||||
warnc(0,
|
||||
lafe_warnc(0,
|
||||
"Option %s%s is not supported",
|
||||
long_prefix, opt_word);
|
||||
return ('?');
|
||||
}
|
||||
if (match2 != NULL) {
|
||||
warnc(0,
|
||||
lafe_warnc(0,
|
||||
"Ambiguous option %s%s (matches --%s and --%s)",
|
||||
long_prefix, opt_word, match->name, match2->name);
|
||||
return ('?');
|
||||
@ -244,7 +244,7 @@ cpio_getopt(struct cpio *cpio)
|
||||
if (cpio->optarg == NULL) {
|
||||
cpio->optarg = *cpio->argv;
|
||||
if (cpio->optarg == NULL) {
|
||||
warnc(0,
|
||||
lafe_warnc(0,
|
||||
"Option %s%s requires an argument",
|
||||
long_prefix, match->name);
|
||||
return ('?');
|
||||
@ -255,7 +255,7 @@ cpio_getopt(struct cpio *cpio)
|
||||
} else {
|
||||
/* Argument forbidden: fail if there is one. */
|
||||
if (cpio->optarg != NULL) {
|
||||
warnc(0,
|
||||
lafe_warnc(0,
|
||||
"Option %s%s does not allow an argument",
|
||||
long_prefix, match->name);
|
||||
return ('?');
|
||||
|
@ -53,4 +53,5 @@
|
||||
#define HAVE_UNSIGNED_LONG_LONG 1
|
||||
#define HAVE_UTIME_H 1
|
||||
#define HAVE_UTIMES 1
|
||||
#define HAVE_WCSCMP 1
|
||||
|
||||
|
@ -136,19 +136,19 @@ main(int argc, char *argv[])
|
||||
cpio->buff = buff;
|
||||
cpio->buff_size = sizeof(buff);
|
||||
|
||||
/* Need progname before calling warnc. */
|
||||
/* Need lafe_progname before calling lafe_warnc. */
|
||||
if (*argv == NULL)
|
||||
progname = "bsdcpio";
|
||||
lafe_progname = "bsdcpio";
|
||||
else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
progname = strrchr(*argv, '\\');
|
||||
lafe_progname = strrchr(*argv, '\\');
|
||||
#else
|
||||
progname = strrchr(*argv, '/');
|
||||
lafe_progname = strrchr(*argv, '/');
|
||||
#endif
|
||||
if (progname != NULL)
|
||||
progname++;
|
||||
if (lafe_progname != NULL)
|
||||
lafe_progname++;
|
||||
else
|
||||
progname = *argv;
|
||||
lafe_progname = *argv;
|
||||
}
|
||||
|
||||
cpio->uid_override = -1;
|
||||
@ -189,7 +189,7 @@ main(int argc, char *argv[])
|
||||
case 'C': /* NetBSD/OpenBSD */
|
||||
cpio->bytes_per_block = atoi(cpio->optarg);
|
||||
if (cpio->bytes_per_block <= 0)
|
||||
errc(1, 0, "Invalid blocksize %s", cpio->optarg);
|
||||
lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
|
||||
break;
|
||||
case 'c': /* POSIX 1997 */
|
||||
cpio->format = "odc";
|
||||
@ -198,14 +198,14 @@ main(int argc, char *argv[])
|
||||
cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
|
||||
break;
|
||||
case 'E': /* NetBSD/OpenBSD */
|
||||
include_from_file(&cpio->matching,
|
||||
lafe_include_from_file(&cpio->matching,
|
||||
cpio->optarg, cpio->option_null);
|
||||
break;
|
||||
case 'F': /* NetBSD/OpenBSD/GNU cpio */
|
||||
cpio->filename = cpio->optarg;
|
||||
break;
|
||||
case 'f': /* POSIX 1997 */
|
||||
exclude(&cpio->matching, cpio->optarg);
|
||||
lafe_exclude(&cpio->matching, cpio->optarg);
|
||||
break;
|
||||
case 'H': /* GNU cpio (also --format) */
|
||||
cpio->format = cpio->optarg;
|
||||
@ -218,7 +218,7 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'i': /* POSIX 1997 */
|
||||
if (cpio->mode != '\0')
|
||||
errc(1, 0,
|
||||
lafe_errc(1, 0,
|
||||
"Cannot use both -i and -%c", cpio->mode);
|
||||
cpio->mode = opt;
|
||||
break;
|
||||
@ -255,13 +255,13 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'o': /* POSIX 1997 */
|
||||
if (cpio->mode != '\0')
|
||||
errc(1, 0,
|
||||
lafe_errc(1, 0,
|
||||
"Cannot use both -o and -%c", cpio->mode);
|
||||
cpio->mode = opt;
|
||||
break;
|
||||
case 'p': /* POSIX 1997 */
|
||||
if (cpio->mode != '\0')
|
||||
errc(1, 0,
|
||||
lafe_errc(1, 0,
|
||||
"Cannot use both -p and -%c", cpio->mode);
|
||||
cpio->mode = opt;
|
||||
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
||||
@ -277,7 +277,7 @@ main(int argc, char *argv[])
|
||||
* also; use that to set [ug]name_override. */
|
||||
errmsg = owner_parse(cpio->optarg, &uid, &gid);
|
||||
if (errmsg) {
|
||||
warnc(-1, "%s", errmsg);
|
||||
lafe_warnc(-1, "%s", errmsg);
|
||||
usage();
|
||||
}
|
||||
if (uid != -1) {
|
||||
@ -335,16 +335,16 @@ main(int argc, char *argv[])
|
||||
cpio->mode = 'i';
|
||||
/* -t requires -i */
|
||||
if (cpio->option_list && cpio->mode != 'i')
|
||||
errc(1, 0, "Option -t requires -i");
|
||||
lafe_errc(1, 0, "Option -t requires -i");
|
||||
/* -n requires -it */
|
||||
if (cpio->option_numeric_uid_gid && !cpio->option_list)
|
||||
errc(1, 0, "Option -n requires -it");
|
||||
lafe_errc(1, 0, "Option -n requires -it");
|
||||
/* Can only specify format when writing */
|
||||
if (cpio->format != NULL && cpio->mode != 'o')
|
||||
errc(1, 0, "Option --format requires -o");
|
||||
lafe_errc(1, 0, "Option --format requires -o");
|
||||
/* -l requires -p */
|
||||
if (cpio->option_link && cpio->mode != 'p')
|
||||
errc(1, 0, "Option -l requires -p");
|
||||
lafe_errc(1, 0, "Option -l requires -p");
|
||||
/* TODO: Flag other nonsensical combinations. */
|
||||
|
||||
switch (cpio->mode) {
|
||||
@ -358,7 +358,7 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'i':
|
||||
while (*cpio->argv != NULL) {
|
||||
include(&cpio->matching, *cpio->argv);
|
||||
lafe_include(&cpio->matching, *cpio->argv);
|
||||
--cpio->argc;
|
||||
++cpio->argv;
|
||||
}
|
||||
@ -369,12 +369,12 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
case 'p':
|
||||
if (*cpio->argv == NULL || **cpio->argv == '\0')
|
||||
errc(1, 0,
|
||||
lafe_errc(1, 0,
|
||||
"-p mode requires a target directory");
|
||||
mode_pass(cpio, *cpio->argv);
|
||||
break;
|
||||
default:
|
||||
errc(1, 0,
|
||||
lafe_errc(1, 0,
|
||||
"Must specify at least one of -i, -o, or -p");
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@ usage(void)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = progname;
|
||||
p = lafe_progname;
|
||||
|
||||
fprintf(stderr, "Brief Usage:\n");
|
||||
fprintf(stderr, " List: %s -it < archive\n", p);
|
||||
@ -426,7 +426,7 @@ long_help(void)
|
||||
const char *prog;
|
||||
const char *p;
|
||||
|
||||
prog = progname;
|
||||
prog = lafe_progname;
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
@ -459,16 +459,16 @@ static void
|
||||
mode_out(struct cpio *cpio)
|
||||
{
|
||||
struct archive_entry *entry, *spare;
|
||||
struct line_reader *lr;
|
||||
struct lafe_line_reader *lr;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
if (cpio->option_append)
|
||||
errc(1, 0, "Append mode not yet supported.");
|
||||
lafe_errc(1, 0, "Append mode not yet supported.");
|
||||
|
||||
cpio->archive_read_disk = archive_read_disk_new();
|
||||
if (cpio->archive_read_disk == NULL)
|
||||
errc(1, 0, "Failed to allocate archive object");
|
||||
lafe_errc(1, 0, "Failed to allocate archive object");
|
||||
if (cpio->option_follow_links)
|
||||
archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
|
||||
else
|
||||
@ -477,7 +477,7 @@ mode_out(struct cpio *cpio)
|
||||
|
||||
cpio->archive = archive_write_new();
|
||||
if (cpio->archive == NULL)
|
||||
errc(1, 0, "Failed to allocate archive object");
|
||||
lafe_errc(1, 0, "Failed to allocate archive object");
|
||||
switch (cpio->compress) {
|
||||
case 'J':
|
||||
r = archive_write_set_compression_xz(cpio->archive);
|
||||
@ -499,10 +499,10 @@ mode_out(struct cpio *cpio)
|
||||
break;
|
||||
}
|
||||
if (r < ARCHIVE_WARN)
|
||||
errc(1, 0, "Requested compression not available");
|
||||
lafe_errc(1, 0, "Requested compression not available");
|
||||
r = archive_write_set_format_by_name(cpio->archive, cpio->format);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block);
|
||||
cpio->linkresolver = archive_entry_linkresolver_new();
|
||||
archive_entry_linkresolver_set_strategy(cpio->linkresolver,
|
||||
@ -513,11 +513,11 @@ mode_out(struct cpio *cpio)
|
||||
*/
|
||||
r = archive_write_open_file(cpio->archive, cpio->filename);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lr = line_reader("-", cpio->option_null);
|
||||
while ((p = line_reader_next(lr)) != NULL)
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lr = lafe_line_reader("-", cpio->option_null);
|
||||
while ((p = lafe_line_reader_next(lr)) != NULL)
|
||||
file_to_archive(cpio, p);
|
||||
line_reader_free(lr);
|
||||
lafe_line_reader_free(lr);
|
||||
|
||||
/*
|
||||
* The hardlink detection may have queued up a couple of entries
|
||||
@ -534,7 +534,7 @@ mode_out(struct cpio *cpio)
|
||||
|
||||
r = archive_write_close(cpio->archive);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks =
|
||||
@ -566,15 +566,15 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
||||
*/
|
||||
entry = archive_entry_new();
|
||||
if (entry == NULL)
|
||||
errc(1, 0, "Couldn't allocate entry");
|
||||
lafe_errc(1, 0, "Couldn't allocate entry");
|
||||
archive_entry_copy_sourcepath(entry, srcpath);
|
||||
r = archive_read_disk_entry_from_file(cpio->archive_read_disk,
|
||||
entry, -1, NULL);
|
||||
if (r < ARCHIVE_FAILED)
|
||||
errc(1, 0, "%s",
|
||||
lafe_errc(1, 0, "%s",
|
||||
archive_error_string(cpio->archive_read_disk));
|
||||
if (r < ARCHIVE_OK)
|
||||
warnc(0, "%s",
|
||||
lafe_warnc(0, "%s",
|
||||
archive_error_string(cpio->archive_read_disk));
|
||||
if (r <= ARCHIVE_FAILED) {
|
||||
cpio->return_value = 1;
|
||||
@ -607,7 +607,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
||||
free(cpio->pass_destpath);
|
||||
cpio->pass_destpath = malloc(cpio->pass_destpath_alloc);
|
||||
if (cpio->pass_destpath == NULL)
|
||||
errc(1, ENOMEM,
|
||||
lafe_errc(1, ENOMEM,
|
||||
"Can't allocate path buffer");
|
||||
}
|
||||
strcpy(cpio->pass_destpath, cpio->destdir);
|
||||
@ -673,7 +673,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
/* Save the original entry in case we need it later. */
|
||||
t = archive_entry_clone(entry);
|
||||
if (t == NULL)
|
||||
errc(1, ENOMEM, "Can't create link");
|
||||
lafe_errc(1, ENOMEM, "Can't create link");
|
||||
/* Note: link(2) doesn't create parent directories,
|
||||
* so we use archive_write_header() instead as a
|
||||
* convenience. */
|
||||
@ -683,7 +683,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
r = archive_write_header(cpio->archive, t);
|
||||
archive_entry_free(t);
|
||||
if (r != ARCHIVE_OK)
|
||||
warnc(archive_errno(cpio->archive),
|
||||
lafe_warnc(archive_errno(cpio->archive),
|
||||
"%s", archive_error_string(cpio->archive));
|
||||
if (r == ARCHIVE_FATAL)
|
||||
exit(1);
|
||||
@ -691,7 +691,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
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. */
|
||||
warnc(0, "Copying file instead");
|
||||
lafe_warnc(0, "Copying file instead");
|
||||
} else
|
||||
#endif
|
||||
return (0);
|
||||
@ -705,7 +705,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
if (archive_entry_size(entry) > 0) {
|
||||
fd = open(srcpath, O_RDONLY | O_BINARY);
|
||||
if (fd < 0) {
|
||||
warnc(errno,
|
||||
lafe_warnc(errno,
|
||||
"%s: could not open file", srcpath);
|
||||
goto cleanup;
|
||||
}
|
||||
@ -717,7 +717,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
r = archive_write_header(cpio->archive, entry);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
warnc(archive_errno(cpio->archive),
|
||||
lafe_warnc(archive_errno(cpio->archive),
|
||||
"%s: %s",
|
||||
srcpath,
|
||||
archive_error_string(cpio->archive));
|
||||
@ -731,10 +731,10 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
r = archive_write_data(cpio->archive,
|
||||
cpio->buff, bytes_read);
|
||||
if (r < 0)
|
||||
errc(1, archive_errno(cpio->archive),
|
||||
lafe_errc(1, archive_errno(cpio->archive),
|
||||
"%s", archive_error_string(cpio->archive));
|
||||
if (r < bytes_read) {
|
||||
warnc(0,
|
||||
lafe_warnc(0,
|
||||
"Truncated write; file may have grown while being archived.");
|
||||
}
|
||||
bytes_read = read(fd, cpio->buff, cpio->buff_size);
|
||||
@ -763,7 +763,7 @@ restore_time(struct cpio *cpio, struct archive_entry *entry,
|
||||
(void)name; /* UNUSED */
|
||||
|
||||
if (!warned)
|
||||
warnc(0, "Can't restore access times on this platform");
|
||||
lafe_warnc(0, "Can't restore access times on this platform");
|
||||
warned = 1;
|
||||
return (fd);
|
||||
#else
|
||||
@ -801,7 +801,7 @@ restore_time(struct cpio *cpio, struct archive_entry *entry,
|
||||
if ((AE_IFLNK != archive_entry_filetype(entry))
|
||||
&& utimes(name, times) != 0)
|
||||
#endif
|
||||
warnc(errno, "Can't update time for %s", name);
|
||||
lafe_warnc(errno, "Can't update time for %s", name);
|
||||
#endif
|
||||
return (fd);
|
||||
}
|
||||
@ -818,28 +818,28 @@ mode_in(struct cpio *cpio)
|
||||
|
||||
ext = archive_write_disk_new();
|
||||
if (ext == NULL)
|
||||
errc(1, 0, "Couldn't allocate restore object");
|
||||
lafe_errc(1, 0, "Couldn't allocate restore object");
|
||||
r = archive_write_disk_set_options(ext, cpio->extract_flags);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(ext));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(ext));
|
||||
a = archive_read_new();
|
||||
if (a == NULL)
|
||||
errc(1, 0, "Couldn't allocate archive object");
|
||||
lafe_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))
|
||||
errc(1, archive_errno(a),
|
||||
lafe_errc(1, archive_errno(a),
|
||||
"%s", archive_error_string(a));
|
||||
for (;;) {
|
||||
r = archive_read_next_header(a, &entry);
|
||||
if (r == ARCHIVE_EOF)
|
||||
break;
|
||||
if (r != ARCHIVE_OK) {
|
||||
errc(1, archive_errno(a),
|
||||
lafe_errc(1, archive_errno(a),
|
||||
"%s", archive_error_string(a));
|
||||
}
|
||||
if (excluded(cpio->matching, archive_entry_pathname(entry)))
|
||||
if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
|
||||
continue;
|
||||
if (cpio->option_rename) {
|
||||
destpath = cpio_rename(archive_entry_pathname(entry));
|
||||
@ -867,10 +867,10 @@ mode_in(struct cpio *cpio)
|
||||
}
|
||||
r = archive_read_close(a);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(a));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(a));
|
||||
r = archive_write_close(ext);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(ext));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(ext));
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks = (archive_position_uncompressed(a) + 511)
|
||||
/ 512;
|
||||
@ -899,13 +899,13 @@ extract_data(struct archive *ar, struct archive *aw)
|
||||
if (r == ARCHIVE_EOF)
|
||||
return (ARCHIVE_OK);
|
||||
if (r != ARCHIVE_OK) {
|
||||
warnc(archive_errno(ar),
|
||||
lafe_warnc(archive_errno(ar),
|
||||
"%s", archive_error_string(ar));
|
||||
exit(1);
|
||||
}
|
||||
r = archive_write_data_block(aw, block, size, offset);
|
||||
if (r != ARCHIVE_OK) {
|
||||
warnc(archive_errno(aw),
|
||||
lafe_warnc(archive_errno(aw),
|
||||
"%s", archive_error_string(aw));
|
||||
return (r);
|
||||
}
|
||||
@ -921,22 +921,22 @@ mode_list(struct cpio *cpio)
|
||||
|
||||
a = archive_read_new();
|
||||
if (a == NULL)
|
||||
errc(1, 0, "Couldn't allocate archive object");
|
||||
lafe_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))
|
||||
errc(1, archive_errno(a),
|
||||
lafe_errc(1, archive_errno(a),
|
||||
"%s", archive_error_string(a));
|
||||
for (;;) {
|
||||
r = archive_read_next_header(a, &entry);
|
||||
if (r == ARCHIVE_EOF)
|
||||
break;
|
||||
if (r != ARCHIVE_OK) {
|
||||
errc(1, archive_errno(a),
|
||||
lafe_errc(1, archive_errno(a),
|
||||
"%s", archive_error_string(a));
|
||||
}
|
||||
if (excluded(cpio->matching, archive_entry_pathname(entry)))
|
||||
if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
|
||||
continue;
|
||||
if (cpio->verbose)
|
||||
list_item_verbose(cpio, entry);
|
||||
@ -945,7 +945,7 @@ mode_list(struct cpio *cpio)
|
||||
}
|
||||
r = archive_read_close(a);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(a));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(a));
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks = (archive_position_uncompressed(a) + 511)
|
||||
/ 512;
|
||||
@ -1040,7 +1040,7 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
|
||||
static void
|
||||
mode_pass(struct cpio *cpio, const char *destdir)
|
||||
{
|
||||
struct line_reader *lr;
|
||||
struct lafe_line_reader *lr;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
@ -1052,31 +1052,31 @@ mode_pass(struct cpio *cpio, const char *destdir)
|
||||
|
||||
cpio->archive = archive_write_disk_new();
|
||||
if (cpio->archive == NULL)
|
||||
errc(1, 0, "Failed to allocate archive object");
|
||||
lafe_errc(1, 0, "Failed to allocate archive object");
|
||||
r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
cpio->linkresolver = archive_entry_linkresolver_new();
|
||||
archive_write_disk_set_standard_lookup(cpio->archive);
|
||||
|
||||
cpio->archive_read_disk = archive_read_disk_new();
|
||||
if (cpio->archive_read_disk == NULL)
|
||||
errc(1, 0, "Failed to allocate archive object");
|
||||
lafe_errc(1, 0, "Failed to allocate archive object");
|
||||
if (cpio->option_follow_links)
|
||||
archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
|
||||
else
|
||||
archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
|
||||
archive_read_disk_set_standard_lookup(cpio->archive_read_disk);
|
||||
|
||||
lr = line_reader("-", cpio->option_null);
|
||||
while ((p = line_reader_next(lr)) != NULL)
|
||||
lr = lafe_line_reader("-", cpio->option_null);
|
||||
while ((p = lafe_line_reader_next(lr)) != NULL)
|
||||
file_to_archive(cpio, p);
|
||||
line_reader_free(lr);
|
||||
lafe_line_reader_free(lr);
|
||||
|
||||
archive_entry_linkresolver_free(cpio->linkresolver);
|
||||
r = archive_write_close(cpio->archive);
|
||||
if (r != ARCHIVE_OK)
|
||||
errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks =
|
||||
@ -1160,7 +1160,7 @@ lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable,
|
||||
if (*name_cache_variable == NULL) {
|
||||
*name_cache_variable = malloc(sizeof(struct name_cache));
|
||||
if (*name_cache_variable == NULL)
|
||||
errc(1, ENOMEM, "No more memory");
|
||||
lafe_errc(1, ENOMEM, "No more memory");
|
||||
memset(*name_cache_variable, 0, sizeof(struct name_cache));
|
||||
(*name_cache_variable)->size = name_cache_size;
|
||||
}
|
||||
@ -1217,7 +1217,7 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
|
||||
if (pwent == NULL) {
|
||||
*name = NULL;
|
||||
if (errno != 0 && errno != ENOENT)
|
||||
warnc(errno, "getpwuid(%d) failed", id);
|
||||
lafe_warnc(errno, "getpwuid(%d) failed", id);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
@ -1244,7 +1244,7 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
|
||||
if (grent == NULL) {
|
||||
*name = NULL;
|
||||
if (errno != 0)
|
||||
warnc(errno, "getgrgid(%d) failed", id);
|
||||
lafe_warnc(errno, "getgrgid(%d) failed", id);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ struct cpio {
|
||||
struct name_cache *gname_cache;
|
||||
|
||||
/* Work data. */
|
||||
struct matching *matching;
|
||||
struct lafe_matching *matching;
|
||||
char *buff;
|
||||
size_t buff_size;
|
||||
};
|
||||
|
@ -1,171 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
@ -1,284 +0,0 @@
|
||||
/*-
|
||||
* 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$");
|
||||
|
||||
#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 "err.h"
|
||||
#include "line_reader.h"
|
||||
#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 matching **);
|
||||
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 matching **matching, const char *pattern)
|
||||
{
|
||||
|
||||
if (*matching == NULL)
|
||||
initialize_matching(matching);
|
||||
add_pattern(&((*matching)->exclusions), pattern);
|
||||
(*matching)->exclusions_count++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
exclude_from_file(struct matching **matching, const char *pathname)
|
||||
{
|
||||
struct line_reader *lr;
|
||||
const char *p;
|
||||
int ret = 0;
|
||||
|
||||
lr = line_reader(pathname, 0);
|
||||
while ((p = line_reader_next(lr)) != NULL) {
|
||||
if (exclude(matching, p) != 0)
|
||||
ret = -1;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
add_pattern(struct match **list, const char *pattern)
|
||||
{
|
||||
struct match *match;
|
||||
size_t len;
|
||||
|
||||
len = strlen(pattern);
|
||||
match = malloc(sizeof(*match) + len + 1);
|
||||
if (match == NULL)
|
||||
errc(1, errno, "Out of memory");
|
||||
strcpy(match->pattern, pattern);
|
||||
/* Both "foo/" and "foo" should match "foo/bar". */
|
||||
if (len && match->pattern[len - 1] == '/')
|
||||
match->pattern[strlen(match->pattern)-1] = '\0';
|
||||
match->next = *list;
|
||||
*list = match;
|
||||
match->matches = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
excluded(struct matching *matching, const char *pathname)
|
||||
{
|
||||
struct match *match;
|
||||
struct match *matched;
|
||||
|
||||
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'
|
||||
*
|
||||
*/
|
||||
static 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.
|
||||
*/
|
||||
static int
|
||||
match_inclusion(struct match *match, const char *pathname)
|
||||
{
|
||||
#if 0
|
||||
return (pathmatch(match->pattern, pathname, 0));
|
||||
#else
|
||||
return (pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cleanup_exclusions(struct matching **matching)
|
||||
{
|
||||
struct match *p, *q;
|
||||
|
||||
if (*matching == NULL)
|
||||
return;
|
||||
|
||||
for (p = (*matching)->inclusions; p != NULL; ) {
|
||||
q = p;
|
||||
p = p->next;
|
||||
free(q);
|
||||
}
|
||||
|
||||
for (p = (*matching)->exclusions; p != NULL; ) {
|
||||
q = p;
|
||||
p = p->next;
|
||||
free(q);
|
||||
}
|
||||
|
||||
free(*matching);
|
||||
*matching = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_matching(struct matching **matching)
|
||||
{
|
||||
*matching = calloc(sizeof(**matching), 1);
|
||||
if (*matching == NULL)
|
||||
errc(1, errno, "No memory");
|
||||
}
|
||||
|
||||
int
|
||||
unmatched_inclusions(struct matching *matching)
|
||||
{
|
||||
|
||||
if (matching == NULL)
|
||||
return (0);
|
||||
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);
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*-
|
||||
* 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
|
||||
|
||||
struct matching;
|
||||
|
||||
int exclude(struct matching **matching, const char *pattern);
|
||||
int exclude_from_file(struct matching **matching,
|
||||
const char *pathname);
|
||||
int include(struct matching **matching, const char *pattern);
|
||||
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
|
@ -1,255 +0,0 @@
|
||||
/*-
|
||||
* 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[0] == '.' && s[1] == '/')
|
||||
|| (s[0] == '.' && s[1] == '\0'))
|
||||
++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);
|
||||
}
|
||||
return (*s == '\0');
|
||||
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);
|
||||
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;
|
||||
case '\\':
|
||||
/* Trailing '\\' matches itself. */
|
||||
if (p[1] == '\0') {
|
||||
if (*s != '\\')
|
||||
return (0);
|
||||
} else {
|
||||
++p;
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (*s != '/' && *s != '\0')
|
||||
return (0);
|
||||
/* Note: pattern "/\./" won't match "/";
|
||||
* pm_slashskip() correctly stops at backslash. */
|
||||
p = pm_slashskip(p);
|
||||
s = pm_slashskip(s);
|
||||
if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
|
||||
return (1);
|
||||
--p; /* Counteract the increment below. */
|
||||
--s;
|
||||
break;
|
||||
case '$':
|
||||
/* '$' is special only at end of pattern and only
|
||||
* if PATHMATCH_NO_ANCHOR_END is specified. */
|
||||
if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
|
||||
/* "dir" == "dir/" == "dir/." */
|
||||
return (*pm_slashskip(s) == '\0');
|
||||
}
|
||||
/* Otherwise, '$' is not special. */
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
++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;
|
||||
}
|
||||
|
||||
if (*p == '/' && *s != '/')
|
||||
return (0);
|
||||
|
||||
/* Certain patterns and file names anchor implicitly. */
|
||||
if (*p == '*' || *p == '/' || *p == '/') {
|
||||
while (*p == '/')
|
||||
++p;
|
||||
while (*s == '/')
|
||||
++s;
|
||||
return (pm(p, s, flags));
|
||||
}
|
||||
|
||||
/* If start is unanchored, try to match start of each path element. */
|
||||
if (flags & PATHMATCH_NO_ANCHOR_START) {
|
||||
for ( ; s != NULL; s = strchr(s, '/')) {
|
||||
if (*s == '/')
|
||||
s++;
|
||||
if (pm(p, s, flags))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Default: Match from beginning. */
|
||||
return (pm(p, s, flags));
|
||||
}
|
@ -2,24 +2,30 @@
|
||||
|
||||
# Where to find the cpio sources (for the internal unit tests)
|
||||
CPIO_SRCDIR=${.CURDIR}/..
|
||||
.PATH: ${CPIO_SRCDIR}
|
||||
|
||||
# Some cpio sources are pulled in for white-box tests
|
||||
CPIO_SRCS= cmdline.c err.c pathmatch.c
|
||||
.PATH: ${CPIO_SRCDIR}
|
||||
CPIO_SRCS= cmdline.c
|
||||
|
||||
.PATH: ${.CURDIR}/../../../lib/libarchive/libarchive_fe
|
||||
TAR_SRCS= err.c pathmatch.c
|
||||
|
||||
TESTS= \
|
||||
test_0.c \
|
||||
test_basic.c \
|
||||
test_format_newc.c \
|
||||
test_gcpio_compat.c \
|
||||
test_option_B_upper.c \
|
||||
test_option_C_upper.c \
|
||||
test_option_J_upper.c \
|
||||
test_option_L_upper.c \
|
||||
test_option_Z_upper.c \
|
||||
test_option_a.c \
|
||||
test_option_B.c \
|
||||
test_option_c.c \
|
||||
test_option_d.c \
|
||||
test_option_f.c \
|
||||
test_option_help.c \
|
||||
test_option_L.c \
|
||||
test_option_ell.c \
|
||||
test_option_l.c \
|
||||
test_option_lzma.c \
|
||||
test_option_m.c \
|
||||
test_option_t.c \
|
||||
test_option_u.c \
|
||||
@ -34,6 +40,7 @@ TESTS= \
|
||||
# Build the test program
|
||||
SRCS= list.h \
|
||||
${CPIO_SRCS} \
|
||||
${TAR_SRCS} \
|
||||
${TESTS} \
|
||||
main.c
|
||||
|
||||
@ -46,9 +53,11 @@ DPADD=${LIBARCHIVE} ${LIBBZ2} ${LIBZ} ${LIBLZMA}
|
||||
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
|
||||
CFLAGS+= -I..
|
||||
LDADD= -larchive -lz -lbz2 -llzma
|
||||
CFLAGS+= -static -g -O2 -Wall
|
||||
#CFLAGS+= -static -g -O2 -Wall
|
||||
CFLAGS+= -g -O2 -Wall
|
||||
CFLAGS+= -I${.OBJDIR}
|
||||
CFLAGS+= -I${CPIO_SRCDIR}
|
||||
CFLAGS+= -I${.CURDIR}/../../../lib/libarchive/libarchive_fe
|
||||
|
||||
# Uncomment to link against dmalloc
|
||||
#LDADD+= -L/usr/local/lib -ldmalloc
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -45,47 +45,84 @@
|
||||
#error Oops: No config.h and no pre-built configuration in test.h.
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include "../cpio_windows.h"
|
||||
#endif
|
||||
#if defined(__CYGWIN__)
|
||||
/* In cygwin-1.7.x, the .nlinks field of directories is
|
||||
* deliberately inaccurate, because to populate it requires
|
||||
* stat'ing every file in the directory, which is slow.
|
||||
* So, as an optimization cygwin doesn't do that in newer
|
||||
* releases; all correct applications on any platform should
|
||||
* never rely on it being > 1, so this optimization doesn't
|
||||
* impact the operation of correctly coded applications.
|
||||
* Therefore, the cpio test should not check its accuracy
|
||||
*/
|
||||
# define NLINKS_INACCURATE_FOR_DIRS
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> /* Windows requires this before sys/stat.h */
|
||||
#include <sys/stat.h>
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef USE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#if HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#ifdef HAVE_DIRECT_H
|
||||
#include <direct.h>
|
||||
#define dirent direct
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <wchar.h>
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h> /* For __FBSDID */
|
||||
/*
|
||||
* System-specific tweaks. We really want to minimize these
|
||||
* as much as possible, since they make it harder to understand
|
||||
* the mainline code.
|
||||
*/
|
||||
|
||||
/* Windows (including Visual Studio and MinGW but not Cygwin) */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include "../cpio_windows.h"
|
||||
#if !defined(__BORLANDC__)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
#define LOCALE_DE "deu"
|
||||
#else
|
||||
#undef __FBSDID
|
||||
#define LOCALE_DE "de_DE.UTF-8"
|
||||
#endif
|
||||
|
||||
/* Visual Studio */
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf sprintf_s
|
||||
#endif
|
||||
|
||||
/* Cygwin */
|
||||
#if defined(__CYGWIN__)
|
||||
/* Cygwin-1.7.x is lazy about populating nlinks, so don't
|
||||
* expect it to be accurate. */
|
||||
# define NLINKS_INACCURATE_FOR_DIRS
|
||||
#endif
|
||||
|
||||
#if defined(__HAIKU__) || defined(__QNXNTO__)
|
||||
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Get a real definition for __FBSDID if we can */
|
||||
#if HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
/* If not, define it so as to avoid dangling semicolons. */
|
||||
#ifndef __FBSDID
|
||||
#define __FBSDID(a) struct _undefined_hack
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Redefine DEFINE_TEST for use in defining the test functions.
|
||||
*/
|
||||
@ -93,40 +130,81 @@
|
||||
#define DEFINE_TEST(name) void name(void); void name(void)
|
||||
|
||||
/* An implementation of the standard assert() macro */
|
||||
#define assert(e) test_assert(__FILE__, __LINE__, (e), #e, NULL)
|
||||
|
||||
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
|
||||
/* chdir() and error if it fails */
|
||||
#define assertChdir(path) \
|
||||
assertion_chdir(__FILE__, __LINE__, path)
|
||||
/* Assert two integers are the same. Reports value of each one if not. */
|
||||
#define assertEqualInt(v1,v2) \
|
||||
test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||
|
||||
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||
/* Assert two strings are the same. Reports value of each one if not. */
|
||||
#define assertEqualString(v1,v2) \
|
||||
test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||
/* As above, but v1 and v2 are wchar_t * */
|
||||
#define assertEqualWString(v1,v2) \
|
||||
test_assert_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||
/* As above, but raw blocks of bytes. */
|
||||
#define assertEqualMem(v1, v2, l) \
|
||||
test_assert_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
|
||||
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
|
||||
/* Assert two files are the same; allow printf-style expansion of second name.
|
||||
* See below for comments about variable arguments here...
|
||||
*/
|
||||
#define assertEqualFile \
|
||||
test_setup(__FILE__, __LINE__);test_assert_equal_file
|
||||
assertion_setup(__FILE__, __LINE__);assertion_equal_file
|
||||
/* Assert that a file is empty; supports printf-style arguments. */
|
||||
#define assertEmptyFile \
|
||||
test_setup(__FILE__, __LINE__);test_assert_empty_file
|
||||
assertion_setup(__FILE__, __LINE__);assertion_empty_file
|
||||
/* Assert that a file is not empty; supports printf-style arguments. */
|
||||
#define assertNonEmptyFile \
|
||||
assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
|
||||
#define assertFileAtime(pathname, sec, nsec) \
|
||||
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
|
||||
#define assertFileAtimeRecent(pathname) \
|
||||
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
|
||||
#define assertFileBirthtime(pathname, sec, nsec) \
|
||||
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
|
||||
#define assertFileBirthtimeRecent(pathname) \
|
||||
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
|
||||
/* Assert that a file exists; supports printf-style arguments. */
|
||||
#define assertFileExists \
|
||||
test_setup(__FILE__, __LINE__);test_assert_file_exists
|
||||
assertion_setup(__FILE__, __LINE__);assertion_file_exists
|
||||
/* Assert that a file exists; supports printf-style arguments. */
|
||||
#define assertFileNotExists \
|
||||
test_setup(__FILE__, __LINE__);test_assert_file_not_exists
|
||||
assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
|
||||
/* Assert that file contents match a string; supports printf-style arguments. */
|
||||
#define assertFileContents \
|
||||
test_setup(__FILE__, __LINE__);test_assert_file_contents
|
||||
assertion_setup(__FILE__, __LINE__);assertion_file_contents
|
||||
#define assertFileMtime(pathname, sec, nsec) \
|
||||
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
|
||||
#define assertFileMtimeRecent(pathname) \
|
||||
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
|
||||
#define assertFileNLinks(pathname, nlinks) \
|
||||
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
|
||||
#define assertFileSize(pathname, size) \
|
||||
assertion_file_size(__FILE__, __LINE__, pathname, size)
|
||||
#define assertTextFileContents \
|
||||
test_setup(__FILE__, __LINE__);test_assert_text_file_contents
|
||||
assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
|
||||
#define assertIsDir(pathname, mode) \
|
||||
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
|
||||
#define assertIsHardlink(path1, path2) \
|
||||
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
|
||||
#define assertIsNotHardlink(path1, path2) \
|
||||
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
|
||||
#define assertIsReg(pathname, mode) \
|
||||
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
|
||||
#define assertIsSymlink(pathname, contents) \
|
||||
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
|
||||
/* Create a directory, report error if it fails. */
|
||||
#define assertMakeDir(dirname, mode) \
|
||||
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
|
||||
#define assertMakeFile(path, mode, contents) \
|
||||
assertion_make_file(__FILE__, __LINE__, path, mode, contents)
|
||||
#define assertMakeHardlink(newfile, oldfile) \
|
||||
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
|
||||
#define assertMakeSymlink(newfile, linkto) \
|
||||
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
|
||||
#define assertUmask(mask) \
|
||||
assertion_umask(__FILE__, __LINE__, mask)
|
||||
|
||||
/*
|
||||
* This would be simple with C99 variadic macros, but I don't want to
|
||||
@ -135,27 +213,60 @@
|
||||
* but effective.
|
||||
*/
|
||||
#define skipping \
|
||||
test_setup(__FILE__, __LINE__);test_skipping
|
||||
assertion_setup(__FILE__, __LINE__);test_skipping
|
||||
|
||||
/* Function declarations. These are defined in test_utility.c. */
|
||||
void failure(const char *fmt, ...);
|
||||
void test_setup(const char *, int);
|
||||
int assertion_assert(const char *, int, int, const char *, void *);
|
||||
int assertion_chdir(const char *, int, const char *);
|
||||
int assertion_empty_file(const char *, ...);
|
||||
int assertion_equal_file(const char *, const char *, ...);
|
||||
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
|
||||
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
|
||||
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
|
||||
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
|
||||
int assertion_file_atime(const char *, int, const char *, long, long);
|
||||
int assertion_file_atime_recent(const char *, int, const char *);
|
||||
int assertion_file_birthtime(const char *, int, const char *, long, long);
|
||||
int assertion_file_birthtime_recent(const char *, int, const char *);
|
||||
int assertion_file_contents(const void *, int, const char *, ...);
|
||||
int assertion_file_exists(const char *, ...);
|
||||
int assertion_file_mtime(const char *, int, const char *, long, long);
|
||||
int assertion_file_mtime_recent(const char *, int, const char *);
|
||||
int assertion_file_nlinks(const char *, int, const char *, int);
|
||||
int assertion_file_not_exists(const char *, ...);
|
||||
int assertion_file_size(const char *, int, const char *, long);
|
||||
int assertion_is_dir(const char *, int, const char *, int);
|
||||
int assertion_is_hardlink(const char *, int, const char *, const char *);
|
||||
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
|
||||
int assertion_is_reg(const char *, int, const char *, int);
|
||||
int assertion_is_symlink(const char *, int, const char *, const char *);
|
||||
int assertion_make_dir(const char *, int, const char *, int);
|
||||
int assertion_make_file(const char *, int, const char *, int, const char *);
|
||||
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
|
||||
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
|
||||
int assertion_non_empty_file(const char *, ...);
|
||||
int assertion_text_file_contents(const char *buff, const char *f);
|
||||
int assertion_umask(const char *, int, int);
|
||||
void assertion_setup(const char *, int);
|
||||
|
||||
void test_skipping(const char *fmt, ...);
|
||||
int test_assert(const char *, int, int, const char *, void *);
|
||||
int test_assert_empty_file(const char *, ...);
|
||||
int test_assert_equal_file(const char *, const char *, ...);
|
||||
int test_assert_equal_int(const char *, int, int, const char *, int, const char *, void *);
|
||||
int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
|
||||
int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
|
||||
int test_assert_equal_mem(const char *, int, const char *, const char *, const char *, const char *, size_t, const char *, void *);
|
||||
int test_assert_file_contents(const void *, int, const char *, ...);
|
||||
int test_assert_text_file_contents(const char *buff, const char *f);
|
||||
int test_assert_file_exists(const char *, ...);
|
||||
int test_assert_file_not_exists(const char *, ...);
|
||||
|
||||
/* Like sprintf, then system() */
|
||||
int systemf(const char * fmt, ...);
|
||||
|
||||
/* Delay until time() returns a value after this. */
|
||||
void sleepUntilAfter(time_t);
|
||||
|
||||
/* Return true if this platform can create symlinks. */
|
||||
int canSymlink(void);
|
||||
|
||||
/* Return true if this platform can run the "gzip" program. */
|
||||
int canGzip(void);
|
||||
|
||||
/* Return true if this platform can run the "gunzip" program. */
|
||||
int canGunzip(void);
|
||||
|
||||
/* Suck file into string allocated via malloc(). Call free() when done. */
|
||||
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
|
||||
char *slurpfile(size_t *, const char *fmt, ...);
|
||||
@ -168,4 +279,7 @@ void extract_reference_file(const char *);
|
||||
*/
|
||||
|
||||
/* Pathname of exe to be tested. */
|
||||
const char *testprogfile;
|
||||
/* Name of exe to use in printf-formatted command strings. */
|
||||
/* On Windows, this includes leading/trailing quotes. */
|
||||
const char *testprog;
|
||||
|
@ -39,11 +39,11 @@ DEFINE_TEST(test_0)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
failure("File %s does not exist?!", testprog);
|
||||
if (!assertEqualInt(0, stat(testprog, &st)))
|
||||
failure("File %s does not exist?!", testprogfile);
|
||||
if (!assertEqualInt(0, stat(testprogfile, &st)))
|
||||
exit(1);
|
||||
|
||||
failure("%s is not executable?!", testprog);
|
||||
failure("%s is not executable?!", testprogfile);
|
||||
if (!assert((st.st_mode & 0111) != 0))
|
||||
exit(1);
|
||||
|
||||
|
@ -26,106 +26,32 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
static void
|
||||
verify_files(const char *target)
|
||||
verify_files(const char *msg)
|
||||
{
|
||||
struct stat st, st2;
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
char buff[128];
|
||||
#endif
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Verify unpacked files.
|
||||
*/
|
||||
|
||||
/* Regular file with 2 links. */
|
||||
r = lstat("file", &st);
|
||||
failure("Failed to stat file %s/file, errno=%d", target, errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Group members bits and others bits do not work. */
|
||||
assertEqualInt(0600, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0644, st.st_mode & 0777);
|
||||
#endif
|
||||
assertEqualInt(10, st.st_size);
|
||||
failure("file %s/file should have 2 links", target);
|
||||
assertEqualInt(2, st.st_nlink);
|
||||
}
|
||||
assertIsReg("file", 0644);
|
||||
failure(msg);
|
||||
assertFileSize("file", 10);
|
||||
assertFileNLinks("file", 2);
|
||||
|
||||
/* Another name for the same file. */
|
||||
r = lstat("linkfile", &st2);
|
||||
failure("Failed to stat file %s/linkfile, errno=%d", target, errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st2.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Group members bits and others bits do not work. */
|
||||
assertEqualInt(0600, st2.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0644, st2.st_mode & 0777);
|
||||
#endif
|
||||
assertEqualInt(10, st2.st_size);
|
||||
failure("file %s/linkfile should have 2 links", target);
|
||||
assertEqualInt(2, st2.st_nlink);
|
||||
/* Verify that the two are really hardlinked. */
|
||||
assertEqualInt(st.st_dev, st2.st_dev);
|
||||
failure("%s/linkfile and %s/file should be hardlinked",
|
||||
target, target);
|
||||
assertEqualInt(st.st_ino, st2.st_ino);
|
||||
}
|
||||
assertIsHardlink("linkfile", "file");
|
||||
|
||||
/* Symlink */
|
||||
r = lstat("symlink", &st);
|
||||
failure("Failed to stat file %s/symlink, errno=%d", target, errno);
|
||||
assertEqualInt(r, 0);
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
if (r == 0) {
|
||||
failure("symlink should be a symlink; actual mode is %o",
|
||||
st.st_mode);
|
||||
assert(S_ISLNK(st.st_mode));
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
r = readlink("symlink", buff, sizeof(buff));
|
||||
assertEqualInt(r, 4);
|
||||
buff[r] = '\0';
|
||||
assertEqualString(buff, "file");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (canSymlink())
|
||||
assertIsSymlink("symlink", "file");
|
||||
|
||||
/* Another file with 1 link and different permissions. */
|
||||
r = lstat("file2", &st);
|
||||
failure("Failed to stat file %s/file2, errno=%d", target, errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st.st_mode));
|
||||
failure("%s/file2: st.st_mode = %o", target, st.st_mode);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Execution bit and group members bits and others
|
||||
* bits do not work. */
|
||||
assertEqualInt(0600, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0777, st.st_mode & 0777);
|
||||
#endif
|
||||
assertEqualInt(10, st.st_size);
|
||||
failure("file %s/file2 should have 1 link", target);
|
||||
assertEqualInt(1, st.st_nlink);
|
||||
}
|
||||
assertIsReg("file2", 0777);
|
||||
assertFileSize("file2", 10);
|
||||
assertFileNLinks("file2", 1);
|
||||
|
||||
/* dir */
|
||||
r = lstat("dir", &st);
|
||||
if (r == 0) {
|
||||
assertEqualInt(r, 0);
|
||||
assert(S_ISDIR(st.st_mode));
|
||||
failure("%s/dir: st.st_mode = %o", target, st.st_mode);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0700, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0775, st.st_mode & 0777);
|
||||
#endif
|
||||
}
|
||||
assertIsDir("dir", 0775);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -136,7 +62,7 @@ basic_cpio(const char *target,
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!assertEqualInt(0, mkdir(target, 0775)))
|
||||
if (!assertMakeDir(target, 0775))
|
||||
return;
|
||||
|
||||
/* Use the cpio program to create an archive. */
|
||||
@ -145,7 +71,7 @@ basic_cpio(const char *target,
|
||||
failure("Error invoking %s -o %s", testprog, pack_options);
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
chdir(target);
|
||||
assertChdir(target);
|
||||
|
||||
/* Verify stderr. */
|
||||
failure("Expected: %s, options=%s", se, pack_options);
|
||||
@ -163,9 +89,9 @@ basic_cpio(const char *target,
|
||||
failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
|
||||
assertTextFileContents(se, "unpack.err");
|
||||
|
||||
verify_files(target);
|
||||
verify_files(pack_options);
|
||||
|
||||
chdir("..");
|
||||
assertChdir("..");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -173,7 +99,7 @@ passthrough(const char *target)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!assertEqualInt(0, mkdir(target, 0775)))
|
||||
if (!assertMakeDir(target, 0775))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -184,77 +110,64 @@ passthrough(const char *target)
|
||||
failure("Error invoking %s -p", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
chdir(target);
|
||||
assertChdir(target);
|
||||
|
||||
/* Verify stderr. */
|
||||
failure("Error invoking %s -p in dir %s",
|
||||
testprog, target);
|
||||
assertTextFileContents("1 block\n", "stderr");
|
||||
|
||||
verify_files(target);
|
||||
chdir("..");
|
||||
verify_files("passthrough");
|
||||
assertChdir("..");
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_basic)
|
||||
{
|
||||
int fd;
|
||||
int filelist;
|
||||
int oldumask;
|
||||
FILE *filelist;
|
||||
const char *msg;
|
||||
|
||||
oldumask = umask(0);
|
||||
assertUmask(0);
|
||||
|
||||
/*
|
||||
* Create an assortment of files on disk.
|
||||
*/
|
||||
filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
|
||||
filelist = fopen("filelist", "w");
|
||||
|
||||
/* File with 10 bytes content. */
|
||||
fd = open("file", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
write(filelist, "file\n", 5);
|
||||
assertMakeFile("file", 0644, "1234567890");
|
||||
fprintf(filelist, "file\n");
|
||||
|
||||
/* hardlink to above file. */
|
||||
assertEqualInt(0, link("file", "linkfile"));
|
||||
write(filelist, "linkfile\n", 9);
|
||||
assertMakeHardlink("linkfile", "file");
|
||||
fprintf(filelist, "linkfile\n");
|
||||
|
||||
/* Symlink to above file. */
|
||||
assertEqualInt(0, symlink("file", "symlink"));
|
||||
write(filelist, "symlink\n", 8);
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file");
|
||||
fprintf(filelist, "symlink\n");
|
||||
}
|
||||
|
||||
/* Another file with different permissions. */
|
||||
fd = open("file2", O_CREAT | O_WRONLY, 0777);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
write(filelist, "file2\n", 6);
|
||||
assertMakeFile("file2", 0777, "1234567890");
|
||||
fprintf(filelist, "file2\n");
|
||||
|
||||
/* Directory. */
|
||||
assertEqualInt(0, mkdir("dir", 0775));
|
||||
write(filelist, "dir\n", 4);
|
||||
assertMakeDir("dir", 0775);
|
||||
fprintf(filelist, "dir\n");
|
||||
/* All done. */
|
||||
close(filelist);
|
||||
fclose(filelist);
|
||||
|
||||
umask(022);
|
||||
assertUmask(022);
|
||||
|
||||
/* Archive/dearchive with a variety of options. */
|
||||
basic_cpio("copy", "", "", "2 blocks\n");
|
||||
basic_cpio("copy_odc", "--format=odc", "", "2 blocks\n");
|
||||
msg = canSymlink() ? "2 blocks\n" : "1 block\n";
|
||||
basic_cpio("copy", "", "", msg);
|
||||
basic_cpio("copy_odc", "--format=odc", "", msg);
|
||||
basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
|
||||
basic_cpio("copy_cpio", "-H odc", "", "2 blocks\n");
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/*
|
||||
* On Windows, symbolic link does not work.
|
||||
* Currentry copying file instead. therefore block size is
|
||||
* different.
|
||||
*/
|
||||
basic_cpio("copy_ustar", "-H ustar", "", "10 blocks\n");
|
||||
#else
|
||||
basic_cpio("copy_ustar", "-H ustar", "", "9 blocks\n");
|
||||
#endif
|
||||
basic_cpio("copy_cpio", "-H odc", "", msg);
|
||||
msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
|
||||
basic_cpio("copy_ustar", "-H ustar", "", msg);
|
||||
|
||||
/* Copy in one step using -p */
|
||||
passthrough("passthrough");
|
||||
|
||||
umask(oldumask);
|
||||
}
|
||||
|
107
usr.bin/cpio/test/test_cmdline.c
Normal file
107
usr.bin/cpio/test/test_cmdline.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 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 "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Test the command-line parsing.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_cmdline)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
/* Create an empty file. */
|
||||
f = fopen("empty", "wb");
|
||||
assert(f != NULL);
|
||||
fclose(f);
|
||||
|
||||
failure("-Q is an invalid option on every cpio program I know of");
|
||||
assert(0 != systemf("%s -i -Q <empty >1.out 2>1.err", testprog));
|
||||
assertEmptyFile("1.out");
|
||||
|
||||
failure("-f requires an argument");
|
||||
assert(0 != systemf("%s -if <empty >2.out 2>2.err", testprog));
|
||||
assertEmptyFile("2.out");
|
||||
|
||||
failure("-f requires an argument");
|
||||
assert(0 != systemf("%s -i -f <empty >3.out 2>3.err", testprog));
|
||||
assertEmptyFile("3.out");
|
||||
|
||||
failure("--format requires an argument");
|
||||
assert(0 != systemf("%s -i --format <empty >4.out 2>4.err", testprog));
|
||||
assertEmptyFile("4.out");
|
||||
|
||||
failure("--badopt is an invalid option");
|
||||
assert(0 != systemf("%s -i --badop <empty >5.out 2>5.err", testprog));
|
||||
assertEmptyFile("5.out");
|
||||
|
||||
failure("--badopt is an invalid option");
|
||||
assert(0 != systemf("%s -i --badopt <empty >6.out 2>6.err", testprog));
|
||||
assertEmptyFile("6.out");
|
||||
|
||||
failure("--n is ambiguous");
|
||||
assert(0 != systemf("%s -i --n <empty >7.out 2>7.err", testprog));
|
||||
assertEmptyFile("7.out");
|
||||
|
||||
failure("--create forbids an argument");
|
||||
assert(0 != systemf("%s --create=arg <empty >8.out 2>8.err", testprog));
|
||||
assertEmptyFile("8.out");
|
||||
|
||||
failure("-i with empty input should succeed");
|
||||
assert(0 == systemf("%s -i <empty >9.out 2>9.err", testprog));
|
||||
assertEmptyFile("9.out");
|
||||
|
||||
failure("-o with empty input should succeed");
|
||||
assert(0 == systemf("%s -o <empty >10.out 2>10.err", testprog));
|
||||
|
||||
failure("-i -p is nonsense");
|
||||
assert(0 != systemf("%s -i -p <empty >11.out 2>11.err", testprog));
|
||||
assertEmptyFile("11.out");
|
||||
|
||||
failure("-p -i is nonsense");
|
||||
assert(0 != systemf("%s -p -i <empty >12.out 2>12.err", testprog));
|
||||
assertEmptyFile("12.out");
|
||||
|
||||
failure("-i -o is nonsense");
|
||||
assert(0 != systemf("%s -i -o <empty >13.out 2>13.err", testprog));
|
||||
assertEmptyFile("13.out");
|
||||
|
||||
failure("-o -i is nonsense");
|
||||
assert(0 != systemf("%s -o -i <empty >14.out 2>14.err", testprog));
|
||||
assertEmptyFile("14.out");
|
||||
|
||||
failure("-o -p is nonsense");
|
||||
assert(0 != systemf("%s -o -p <empty >15.out 2>15.err", testprog));
|
||||
assertEmptyFile("15.out");
|
||||
|
||||
failure("-p -o is nonsense");
|
||||
assert(0 != systemf("%s -p -o <empty >16.out 2>16.err", testprog));
|
||||
assertEmptyFile("16.out");
|
||||
|
||||
failure("-p with empty input should fail");
|
||||
assert(0 != systemf("%s -p <empty >17.out 2>17.err", testprog));
|
||||
assertEmptyFile("17.out");
|
||||
}
|
@ -25,6 +25,13 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* Number of bytes needed to pad 'n' to multiple of 'block', assuming
|
||||
* that 'block' is a power of two. This trick can be more easily
|
||||
* remembered as -n & (block - 1), but many compilers quite reasonably
|
||||
* warn about "-n" when n is an unsigned value. (~(n) + 1) is the
|
||||
* same thing, but written in a way that won't offend anyone. */
|
||||
#define PAD(n, block) ((~(n) + 1) & ((block) - 1))
|
||||
|
||||
static int
|
||||
is_hex(const char *p, size_t l)
|
||||
{
|
||||
@ -63,60 +70,67 @@ from_hex(const char *p, size_t l)
|
||||
|
||||
DEFINE_TEST(test_format_newc)
|
||||
{
|
||||
int fd, list;
|
||||
FILE *list;
|
||||
int r;
|
||||
int devmajor, devminor, ino, gid;
|
||||
int uid = -1;
|
||||
time_t t, t2, now;
|
||||
char *p, *e;
|
||||
size_t s, fs, ns;
|
||||
mode_t oldmask;
|
||||
|
||||
oldmask = umask(0);
|
||||
assertUmask(0);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
uid = getuid();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create an assortment of files.
|
||||
* TODO: Extend this to cover more filetypes.
|
||||
*/
|
||||
list = open("list", O_CREAT | O_WRONLY, 0644);
|
||||
list = fopen("list", "w");
|
||||
|
||||
/* "file1" */
|
||||
fd = open("file1", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
assertEqualInt(6, write(list, "file1\n", 6));
|
||||
assertMakeFile("file1", 0644, "1234567890");
|
||||
fprintf(list, "file1\n");
|
||||
|
||||
/* "hardlink" */
|
||||
assertEqualInt(0, link("file1", "hardlink"));
|
||||
assertEqualInt(9, write(list, "hardlink\n", 9));
|
||||
assertMakeHardlink("hardlink", "file1");
|
||||
fprintf(list, "hardlink\n");
|
||||
|
||||
/* Another hardlink, but this one won't be archived. */
|
||||
assertEqualInt(0, link("file1", "hardlink2"));
|
||||
assertMakeHardlink("hardlink2", "file1");
|
||||
|
||||
/* "symlink" */
|
||||
assertEqualInt(0, symlink("file1", "symlink"));
|
||||
assertEqualInt(8, write(list, "symlink\n", 8));
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file1");
|
||||
fprintf(list, "symlink\n");
|
||||
}
|
||||
|
||||
/* "dir" */
|
||||
assertEqualInt(0, mkdir("dir", 0775));
|
||||
assertEqualInt(4, write(list, "dir\n", 4));
|
||||
assertMakeDir("dir", 0775);
|
||||
fprintf(list, "dir\n");
|
||||
|
||||
/* Record some facts about what we just created: */
|
||||
now = time(NULL); /* They were all created w/in last two seconds. */
|
||||
|
||||
/* Use the cpio program to create an archive. */
|
||||
close(list);
|
||||
fclose(list);
|
||||
r = systemf("%s -o --format=newc <list >newc.out 2>newc.err",
|
||||
testprog);
|
||||
if (!assertEqualInt(r, 0))
|
||||
return;
|
||||
|
||||
/* Verify that nothing went to stderr. */
|
||||
if (canSymlink()) {
|
||||
assertTextFileContents("2 blocks\n", "newc.err");
|
||||
} else {
|
||||
assertTextFileContents("1 block\n", "newc.err");
|
||||
}
|
||||
|
||||
/* Verify that stdout is a well-formed cpio file in "newc" format. */
|
||||
p = slurpfile(&s, "newc.out");
|
||||
assertEqualInt(s, 1024);
|
||||
assertEqualInt(s, canSymlink() ? 1024 : 512);
|
||||
e = p;
|
||||
|
||||
/*
|
||||
@ -134,7 +148,9 @@ DEFINE_TEST(test_format_newc)
|
||||
#else
|
||||
assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
|
||||
if (uid < 0)
|
||||
uid = from_hex(e + 22, 8);
|
||||
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
|
||||
gid = from_hex(e + 30, 8); /* gid */
|
||||
assertEqualMem(e + 38, "00000003", 8); /* nlink */
|
||||
t = from_hex(e + 46, 8); /* mtime */
|
||||
@ -147,56 +163,47 @@ DEFINE_TEST(test_format_newc)
|
||||
" field should be zero");
|
||||
assertEqualInt(0, from_hex(e + 54, 8)); /* File size */
|
||||
fs = from_hex(e + 54, 8);
|
||||
fs += 3 & -fs;
|
||||
fs += PAD(fs, 4);
|
||||
devmajor = from_hex(e + 62, 8); /* devmajor */
|
||||
devminor = from_hex(e + 70, 8); /* devminor */
|
||||
assert(is_hex(e + 78, 8)); /* rdevmajor */
|
||||
assert(is_hex(e + 86, 8)); /* rdevminor */
|
||||
assertEqualMem(e + 94, "00000006", 8); /* Name size */
|
||||
ns = from_hex(e + 94, 8);
|
||||
ns += 3 & (-ns - 2);
|
||||
ns += PAD(ns + 2, 4);
|
||||
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
|
||||
assertEqualMem(e + 110, "file1\0", 6); /* Name contents */
|
||||
/* Since there's another link, no file contents here. */
|
||||
/* But add in file size so that an error here doesn't cascade. */
|
||||
e += 110 + fs + ns;
|
||||
|
||||
if (canSymlink()) {
|
||||
/* "symlink" pointing to "file1" */
|
||||
assert(is_hex(e, 110));
|
||||
assertEqualMem(e + 0, "070701", 6); /* Magic */
|
||||
assert(is_hex(e + 6, 8)); /* ino */
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
/* On Windows, symbolic link and group members bits and
|
||||
* others bits do not work. */
|
||||
assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
|
||||
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
|
||||
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
|
||||
assertEqualMem(e + 38, "00000001", 8); /* nlink */
|
||||
t2 = from_hex(e + 46, 8); /* mtime */
|
||||
failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
|
||||
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Symbolic link does not work. */
|
||||
assertEqualMem(e + 54, "0000000a", 8); /* File size */
|
||||
#else
|
||||
assertEqualMem(e + 54, "00000005", 8); /* File size */
|
||||
#endif
|
||||
fs = from_hex(e + 54, 8);
|
||||
fs += 3 & -fs;
|
||||
fs += PAD(fs, 4);
|
||||
assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
|
||||
assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
|
||||
assert(is_hex(e + 78, 8)); /* rdevmajor */
|
||||
assert(is_hex(e + 86, 8)); /* rdevminor */
|
||||
assertEqualMem(e + 94, "00000008", 8); /* Name size */
|
||||
ns = from_hex(e + 94, 8);
|
||||
ns += 3 & (-ns - 2);
|
||||
ns += PAD(ns + 2, 4);
|
||||
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
|
||||
assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */
|
||||
#endif
|
||||
e += 110 + fs + ns;
|
||||
}
|
||||
|
||||
/* "dir" */
|
||||
assert(is_hex(e, 110));
|
||||
@ -206,9 +213,10 @@ DEFINE_TEST(test_format_newc)
|
||||
/* Group members bits and others bits do not work. */
|
||||
assertEqualInt(0x41c0, from_hex(e + 14, 8) & 0xffc0); /* Mode */
|
||||
#else
|
||||
assertEqualInt(0x41fd, from_hex(e + 14, 8)); /* Mode */
|
||||
/* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
|
||||
assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
|
||||
#endif
|
||||
assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
|
||||
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
|
||||
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
|
||||
#ifndef NLINKS_INACCURATE_FOR_DIRS
|
||||
assertEqualMem(e + 38, "00000002", 8); /* nlink */
|
||||
@ -218,14 +226,14 @@ DEFINE_TEST(test_format_newc)
|
||||
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
|
||||
assertEqualMem(e + 54, "00000000", 8); /* File size */
|
||||
fs = from_hex(e + 54, 8);
|
||||
fs += 3 & -fs;
|
||||
fs += PAD(fs, 4);
|
||||
assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
|
||||
assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
|
||||
assert(is_hex(e + 78, 8)); /* rdevmajor */
|
||||
assert(is_hex(e + 86, 8)); /* rdevminor */
|
||||
assertEqualMem(e + 94, "00000004", 8); /* Name size */
|
||||
ns = from_hex(e + 94, 8);
|
||||
ns += 3 & (-ns - 2);
|
||||
ns += PAD(ns + 2, 4);
|
||||
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
|
||||
assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */
|
||||
e += 110 + fs + ns;
|
||||
@ -243,7 +251,7 @@ DEFINE_TEST(test_format_newc)
|
||||
#else
|
||||
assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_hex(e + 22, 8), getuid()); /* uid */
|
||||
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
|
||||
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
|
||||
assertEqualMem(e + 38, "00000003", 8); /* nlink */
|
||||
t2 = from_hex(e + 46, 8); /* mtime */
|
||||
@ -251,17 +259,17 @@ DEFINE_TEST(test_format_newc)
|
||||
assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
|
||||
assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
|
||||
fs = from_hex(e + 54, 8);
|
||||
fs += 3 & -fs;
|
||||
fs += PAD(fs, 4);
|
||||
assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
|
||||
assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
|
||||
assert(is_hex(e + 78, 8)); /* rdevmajor */
|
||||
assert(is_hex(e + 86, 8)); /* rdevminor */
|
||||
assertEqualMem(e + 94, "00000009", 8); /* Name size */
|
||||
ns = from_hex(e + 94, 8);
|
||||
ns += 3 & (-ns - 2);
|
||||
ns += PAD(ns + 2, 4);
|
||||
assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
|
||||
assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */
|
||||
assertEqualMem(e + 110 + ns, "123456789\0\0\0", 12); /* File contents */
|
||||
assertEqualMem(e + 110 + ns, "1234567890\0\0", 12); /* File contents */
|
||||
e += 110 + ns + fs;
|
||||
|
||||
/* Last entry is end-of-archive marker. */
|
||||
@ -283,6 +291,4 @@ DEFINE_TEST(test_format_newc)
|
||||
assertEqualMem(e + 110, "TRAILER!!!\0\0", 12); /* Name */
|
||||
|
||||
free(p);
|
||||
|
||||
umask(oldmask);
|
||||
}
|
||||
|
@ -28,15 +28,11 @@ __FBSDID("$FreeBSD$");
|
||||
static void
|
||||
unpack_test(const char *from, const char *options, const char *se)
|
||||
{
|
||||
struct stat st, st2;
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
char buff[128];
|
||||
#endif
|
||||
int r;
|
||||
|
||||
/* Create a work dir named after the file we're unpacking. */
|
||||
assertEqualInt(0, mkdir(from, 0775));
|
||||
chdir(from);
|
||||
assertMakeDir(from, 0775);
|
||||
assertChdir(from);
|
||||
|
||||
/*
|
||||
* Use cpio to unpack the sample archive
|
||||
@ -49,96 +45,64 @@ unpack_test(const char *from, const char *options, const char *se)
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
/* Verify that nothing went to stderr. */
|
||||
failure("Error invoking %s -i %s < %s", testprog, options, from);
|
||||
if (canSymlink()) {
|
||||
failure("Error invoking %s -i %s < %s",
|
||||
testprog, options, from);
|
||||
assertTextFileContents(se, "unpack.err");
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify unpacked files.
|
||||
*/
|
||||
|
||||
/* Regular file with 2 links. */
|
||||
r = lstat("file", &st);
|
||||
failure("Failed to stat file %s/file, errno=%d", from, errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0600, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0644, st.st_mode & 0777);
|
||||
#endif
|
||||
failure("file %s/file", from);
|
||||
assertEqualInt(10, st.st_size);
|
||||
failure("file %s/file", from);
|
||||
assertEqualInt(2, st.st_nlink);
|
||||
}
|
||||
assertIsReg("file", 0644);
|
||||
failure("%s", from);
|
||||
assertFileSize("file", 10);
|
||||
assertFileSize("linkfile", 10);
|
||||
failure("%s", from);
|
||||
assertFileNLinks("file", 2);
|
||||
|
||||
/* Another name for the same file. */
|
||||
r = lstat("linkfile", &st2);
|
||||
failure("Failed to stat file %s/linkfile, errno=%d", from, errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st2.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0600, st2.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0644, st2.st_mode & 0777);
|
||||
#endif
|
||||
failure("file %s/file", from);
|
||||
assertEqualInt(10, st2.st_size);
|
||||
failure("file %s/file", from);
|
||||
assertEqualInt(2, st2.st_nlink);
|
||||
failure("file and linkfile should be hardlinked");
|
||||
assertEqualInt(st.st_dev, st2.st_dev);
|
||||
failure("file %s/file", from);
|
||||
assertEqualInt(st.st_ino, st2.st_ino);
|
||||
}
|
||||
failure("%s", from);
|
||||
assertIsHardlink("linkfile", "file");
|
||||
assertFileSize("file", 10);
|
||||
assertFileSize("linkfile", 10);
|
||||
|
||||
/* Symlink */
|
||||
r = lstat("symlink", &st);
|
||||
failure("Failed to stat file %s/symlink, errno=%d", from, errno);
|
||||
assertEqualInt(r, 0);
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
if (r == 0) {
|
||||
failure("symlink should be a symlink; actual mode is %o",
|
||||
st.st_mode);
|
||||
assert(S_ISLNK(st.st_mode));
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
r = readlink("symlink", buff, sizeof(buff));
|
||||
assertEqualInt(r, 4);
|
||||
buff[r] = '\0';
|
||||
assertEqualString(buff, "file");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (canSymlink())
|
||||
assertIsSymlink("symlink", "file");
|
||||
|
||||
/* dir */
|
||||
r = lstat("dir", &st);
|
||||
if (r == 0) {
|
||||
assertEqualInt(r, 0);
|
||||
assert(S_ISDIR(st.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0700, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0775, st.st_mode & 0777);
|
||||
#endif
|
||||
}
|
||||
assertIsDir("dir", 0775);
|
||||
|
||||
chdir("..");
|
||||
assertChdir("..");
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_gcpio_compat)
|
||||
{
|
||||
int oldumask;
|
||||
|
||||
oldumask = umask(0);
|
||||
assertUmask(0);
|
||||
|
||||
/* Dearchive sample files with a variety of options. */
|
||||
unpack_test("test_gcpio_compat_ref.bin", "", "1 block\n");
|
||||
unpack_test("test_gcpio_compat_ref.crc", "", "2 blocks\n");
|
||||
unpack_test("test_gcpio_compat_ref.newc", "", "2 blocks\n");
|
||||
if (canSymlink()) {
|
||||
unpack_test("test_gcpio_compat_ref.bin",
|
||||
"--no-preserve-owner", "1 block\n");
|
||||
unpack_test("test_gcpio_compat_ref.crc",
|
||||
"--no-preserve-owner", "2 blocks\n");
|
||||
unpack_test("test_gcpio_compat_ref.newc",
|
||||
"--no-preserve-owner", "2 blocks\n");
|
||||
/* gcpio-2.9 only reads 6 blocks here */
|
||||
unpack_test("test_gcpio_compat_ref.ustar", "", "7 blocks\n");
|
||||
|
||||
umask(oldumask);
|
||||
unpack_test("test_gcpio_compat_ref.ustar",
|
||||
"--no-preserve-owner", "7 blocks\n");
|
||||
} else {
|
||||
unpack_test("test_gcpio_compat_ref_nosym.bin",
|
||||
"--no-preserve-owner", "1 block\n");
|
||||
unpack_test("test_gcpio_compat_ref_nosym.crc",
|
||||
"--no-preserve-owner", "2 blocks\n");
|
||||
unpack_test("test_gcpio_compat_ref_nosym.newc",
|
||||
"--no-preserve-owner", "2 blocks\n");
|
||||
/* gcpio-2.9 only reads 6 blocks here */
|
||||
unpack_test("test_gcpio_compat_ref_nosym.ustar",
|
||||
"--no-preserve-owner", "7 blocks\n");
|
||||
}
|
||||
}
|
||||
|
17
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu
Normal file
17
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.bin.uu
Normal file
@ -0,0 +1,17 @@
|
||||
$FreeBSD$
|
||||
|
||||
begin 644 test_gcpio_compat_ref_nosym.bin
|
||||
MQW%4`-[Z_4'H`^@#`@`VNZU*NQX$``````!D:7(`QW%4`-SZI('H`^@#`@`G
|
||||
MNZU*NQX%````"@!F:6QE```Q,C,T-38W.#D*QW%4`-SZI('H`^@#`@`GNZU*
|
||||
MNQX)````"@!L:6YK9FEL90``,3(S-#4V-S@Y"L=Q``````````````$`````
|
||||
M````"P``````5%)!24Q%4B$A(0``````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
1````````````````````````
|
||||
`
|
||||
end
|
17
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu
Normal file
17
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.crc.uu
Normal file
@ -0,0 +1,17 @@
|
||||
$FreeBSD$
|
||||
|
||||
begin 644 test_gcpio_compat_ref_nosym.crc
|
||||
M,#<P-S`R,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13@P,#`P,#`P
|
||||
M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
|
||||
M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#(P,#4V1D%$0S`P,#`X
|
||||
M,4$T,#`P,#`S13@P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
|
||||
M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
|
||||
M,&9I;&4``#`W,#<P,C`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
|
||||
M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
|
||||
M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,44W;&EN:V9I;&4``#$R,S0U-C<X
|
||||
M.0H``#`W,#<P,C`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
|
||||
M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
|
||||
M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
|
||||
1````````````````````````
|
||||
`
|
||||
end
|
17
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu
Normal file
17
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.newc.uu
Normal file
@ -0,0 +1,17 @@
|
||||
$FreeBSD$
|
||||
|
||||
begin 644 test_gcpio_compat_ref_nosym.newc
|
||||
M,#<P-S`Q,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13@P,#`P,#`P
|
||||
M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
|
||||
M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#$P,#4V1D%$0S`P,#`X
|
||||
M,4$T,#`P,#`S13@P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
|
||||
M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
|
||||
M,&9I;&4``#`W,#<P,3`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
|
||||
M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
|
||||
M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,#`P;&EN:V9I;&4``#$R,S0U-C<X
|
||||
M.0H``#`W,#<P,3`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
|
||||
M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
|
||||
M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
|
||||
1````````````````````````
|
||||
`
|
||||
end
|
74
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu
Normal file
74
usr.bin/cpio/test/test_gcpio_compat_ref_nosym.ustar.uu
Normal file
@ -0,0 +1,74 @@
|
||||
$FreeBSD$
|
||||
|
||||
begin 644 test_gcpio_compat_ref_nosym.ustar
|
||||
M9&ER+P``````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#`W-S4`,#`P,3<U,``P,#`Q-S4P`#`P,#`P,#`P,#`P
|
||||
M`#$Q,C4S,C$W,C<S`#`P,3$S-3$`-0``````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
|
||||
M````````````````````````````````````=&EM````````````````````
|
||||
M```````````````````P,#`P,C<S`#8V,#`P-C8`````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````!F:6QE````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````,#`P,#8T-``P,#`Q-S4P`#`P
|
||||
M,#$W-3``,#`P,#`P,#`P,3(`,3$R-3,R,3<R-S,`,#`Q,30R,P`P````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````'5S=&%R`#`P=&EM``````````````````````````````````````!T
|
||||
M:6T``````````````````````````````````````#`P,#`R-S,`-C8P,#`T
|
||||
M-P``````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````````````````````#$R,S0U-C<X.0H`
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````;&EN:V9I;&4`````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````#`P,#`V-#0`,#`P,3<U,``P,#`Q-S4P`#`P,#`P
|
||||
M,#`P,#`P`#$Q,C4S,C$W,C<S`#`P,3,Q,S<`,69I;&4`````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````````````!U<W1A<@`P
|
||||
M,'1I;0``````````````````````````````````````=&EM````````````
|
||||
M```````````````````````````P,#`P,C<S`#8V,#`P-#<`````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
,````````````````
|
||||
`
|
||||
end
|
@ -26,29 +26,27 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
DEFINE_TEST(test_option_B)
|
||||
DEFINE_TEST(test_option_B_upper)
|
||||
{
|
||||
struct stat st;
|
||||
int r, fd;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Create a file on disk.
|
||||
*/
|
||||
fd = open("file", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
close(fd);
|
||||
assertMakeFile("file", 0644, NULL);
|
||||
|
||||
/* Create an archive without -B; this should be 512 bytes. */
|
||||
r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertFileContents("1 block\n", 8, "small.err");
|
||||
assertTextFileContents("1 block\n", "small.err");
|
||||
assertEqualInt(0, stat("small.cpio", &st));
|
||||
assertEqualInt(512, st.st_size);
|
||||
|
||||
/* Create an archive with -B; this should be 5120 bytes. */
|
||||
r = systemf("echo file | %s -oB > large.cpio 2>large.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertFileContents("1 block\n", 8, "large.err");
|
||||
assertTextFileContents("1 block\n", "large.err");
|
||||
assertEqualInt(0, stat("large.cpio", &st));
|
||||
assertEqualInt(5120, st.st_size);
|
||||
}
|
@ -6,8 +6,7 @@
|
||||
* 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.
|
||||
* 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.
|
||||
@ -22,21 +21,42 @@
|
||||
* 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$
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef LAFE_PATHMATCH_H
|
||||
#define LAFE_PATHMATCH_H
|
||||
|
||||
/* Don't anchor at beginning unless the pattern starts with "^" */
|
||||
#define PATHMATCH_NO_ANCHOR_START 1
|
||||
/* Don't anchor at end unless the pattern ends with "$" */
|
||||
#define PATHMATCH_NO_ANCHOR_END 2
|
||||
DEFINE_TEST(test_option_C_upper)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* Note that "^" and "$" are not special unless you set the corresponding
|
||||
* flag above. */
|
||||
/*
|
||||
* Create a file on disk.
|
||||
*/
|
||||
assertMakeFile("file", 0644, NULL);
|
||||
|
||||
int pathmatch(const char *p, const char *s, int flags);
|
||||
/* Create an archive without -C; this should be 512 bytes. */
|
||||
r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "small.err");
|
||||
assertFileSize("small.cpio", 512);
|
||||
|
||||
#endif
|
||||
/* Create an archive with -C 513; this should be 513 bytes. */
|
||||
r = systemf("echo file | %s -o -C 513 > 513.cpio 2>513.err",
|
||||
testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "513.err");
|
||||
assertFileSize("513.cpio", 513);
|
||||
|
||||
/* Create an archive with -C 12345; this should be 12345 bytes. */
|
||||
r = systemf("echo file | %s -o -C12345 > 12345.cpio 2>12345.err",
|
||||
testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "12345.err");
|
||||
assertFileSize("12345.cpio", 12345);
|
||||
|
||||
/* Create an archive with invalid -C request */
|
||||
assert(0 != systemf("echo file | %s -o -C > bad.cpio 2>bad.err",
|
||||
testprog));
|
||||
assertEmptyFile("bad.cpio");
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Joerg Sonnenberger
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -21,23 +21,36 @@
|
||||
* 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$
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef LAFE_ERR_H
|
||||
#define LAFE_ERR_H
|
||||
DEFINE_TEST(test_option_J_upper)
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
||||
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
||||
#define __LA_DEAD __attribute__((__noreturn__))
|
||||
#else
|
||||
#define __LA_DEAD
|
||||
#endif
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
extern const char *progname;
|
||||
|
||||
void warnc(int code, const char *fmt, ...);
|
||||
void errc(int eval, int code, const char *fmt, ...) __LA_DEAD;
|
||||
|
||||
#endif
|
||||
/* Archive it with xz compression. */
|
||||
r = systemf("echo f | %s -o -J >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without xz support");
|
||||
return;
|
||||
}
|
||||
failure("-J option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
/* Check that the archive file has an xz signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\3757zXZ", 5);
|
||||
}
|
@ -25,60 +25,77 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_L)
|
||||
/* This is a little pointless, as Windows doesn't support symlinks
|
||||
* (except for the seriously crippled CreateSymbolicLink API) so these
|
||||
* tests won't run on Windows. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#define CAT "type"
|
||||
#else
|
||||
#define CAT "cat"
|
||||
#endif
|
||||
|
||||
DEFINE_TEST(test_option_L_upper)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, filelist;
|
||||
FILE *filelist;
|
||||
int r;
|
||||
|
||||
filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
|
||||
if (!canSymlink()) {
|
||||
skipping("Symlink tests");
|
||||
return;
|
||||
}
|
||||
|
||||
filelist = fopen("filelist", "w");
|
||||
|
||||
/* Create a file and a symlink to the file. */
|
||||
fd = open("file", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
write(filelist, "file\n", 5);
|
||||
assertMakeFile("file", 0644, "1234567890");
|
||||
fprintf(filelist, "file\n");
|
||||
|
||||
/* Symlink to above file. */
|
||||
assertEqualInt(0, symlink("file", "symlink"));
|
||||
write(filelist, "symlink\n", 8);
|
||||
assertMakeSymlink("symlink", "file");
|
||||
fprintf(filelist, "symlink\n");
|
||||
|
||||
close(filelist);
|
||||
fclose(filelist);
|
||||
|
||||
r = systemf("cat filelist | %s -pd copy >copy.out 2>copy.err", testprog);
|
||||
r = systemf(CAT " filelist | %s -pd copy >copy.out 2>copy.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEqualInt(0, lstat("copy/symlink", &st));
|
||||
failure("Regular -p without -L should preserve symlinks.");
|
||||
assert(S_ISLNK(st.st_mode));
|
||||
assertTextFileContents("1 block\n", "copy.err");
|
||||
|
||||
r = systemf("cat filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
|
||||
failure("Regular -p without -L should preserve symlinks.");
|
||||
assertIsSymlink("copy/symlink", NULL);
|
||||
|
||||
r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEmptyFile("copy-L.out");
|
||||
assertFileContents("1 block\n", 8, "copy-L.err");
|
||||
assertEqualInt(0, lstat("copy-L/symlink", &st));
|
||||
assertTextFileContents("1 block\n", "copy-L.err");
|
||||
failure("-pdL should dereference symlinks and turn them into files.");
|
||||
assert(!S_ISLNK(st.st_mode));
|
||||
assertIsReg("copy-L/symlink", -1);
|
||||
|
||||
r = systemf("cat filelist | %s -o >archive.out 2>archive.err", testprog);
|
||||
r = systemf(CAT " filelist | %s -o >archive.out 2>archive.err", testprog);
|
||||
failure("Error invoking %s -o ", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "archive.err");
|
||||
|
||||
assertEqualInt(0, mkdir("unpack", 0755));
|
||||
r = systemf("cat archive.out | (cd unpack ; %s -i >unpack.out 2>unpack.err)", testprog);
|
||||
assertMakeDir("unpack", 0755);
|
||||
assertChdir("unpack");
|
||||
r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
|
||||
failure("Error invoking %s -i", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEqualInt(0, lstat("unpack/symlink", &st));
|
||||
assert(S_ISLNK(st.st_mode));
|
||||
assertTextFileContents("1 block\n", "unpack.err");
|
||||
assertChdir("..");
|
||||
|
||||
r = systemf("cat filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
|
||||
assertIsSymlink("unpack/symlink", NULL);
|
||||
|
||||
r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
|
||||
failure("Error invoking %s -oL", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "archive-L.err");
|
||||
|
||||
assertEqualInt(0, mkdir("unpack-L", 0755));
|
||||
r = systemf("cat archive-L.out | (cd unpack-L ; %s -i >unpack-L.out 2>unpack-L.err)", testprog);
|
||||
assertMakeDir("unpack-L", 0755);
|
||||
assertChdir("unpack-L");
|
||||
r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
|
||||
failure("Error invoking %s -i < archive-L.out", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEqualInt(0, lstat("unpack-L/symlink", &st));
|
||||
assert(!S_ISLNK(st.st_mode));
|
||||
assertTextFileContents("1 block\n", "unpack-L.err");
|
||||
assertChdir("..");
|
||||
assertIsReg("unpack-L/symlink", -1);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Joerg Sonnenberger
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -21,17 +21,36 @@
|
||||
* 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$
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef LAFE_LINE_READER_H
|
||||
#define LAFE_LINE_READER_H
|
||||
DEFINE_TEST(test_option_Z_upper)
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
struct line_reader;
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
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
|
||||
/* Archive it with compress compression. */
|
||||
r = systemf("echo f | %s -oZ >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without compress support");
|
||||
return;
|
||||
}
|
||||
failure("-Z option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
/* Check that the archive file has a compress signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x1f\x9d", 2);
|
||||
}
|
@ -23,10 +23,10 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <sys/utime.h>
|
||||
#else
|
||||
#if defined(HAVE_UTIME_H)
|
||||
#include <utime.h>
|
||||
#elif defined(HAVE_SYS_UTIME_H)
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
@ -57,19 +57,15 @@ test_create(void)
|
||||
struct utimbuf times;
|
||||
static const int numfiles = sizeof(files) / sizeof(files[0]);
|
||||
int i;
|
||||
int fd;
|
||||
|
||||
for (i = 0; i < numfiles; ++i) {
|
||||
fd = open(files[i].name, O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
/*
|
||||
* Note: Have to write at least one byte to the file.
|
||||
* cpio doesn't bother reading the file if it's zero length,
|
||||
* so the atime never gets changed in that case, which
|
||||
* makes the tests below rather pointless.
|
||||
*/
|
||||
assertEqualInt(1, write(fd, "a", 1));
|
||||
close(fd);
|
||||
assertMakeFile(files[i].name, 0644, "a");
|
||||
|
||||
/* If utime() isn't supported on your platform, just
|
||||
* #ifdef this section out. Most of the test below is
|
||||
@ -87,26 +83,21 @@ test_create(void)
|
||||
}
|
||||
|
||||
/* Wait until the atime on the last file is actually in the past. */
|
||||
/* If utime() is supported above, there's no sleep here which
|
||||
* makes the test faster. */
|
||||
while (files[numfiles - 1].atime_sec >= time(NULL))
|
||||
sleep(1);
|
||||
sleepUntilAfter(files[numfiles - 1].atime_sec);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_option_a)
|
||||
{
|
||||
struct stat st;
|
||||
int r;
|
||||
int f;
|
||||
char buff[64];
|
||||
char *p;
|
||||
|
||||
/* Create all of the test files. */
|
||||
test_create();
|
||||
|
||||
/* Sanity check; verify that atimes really do get modified. */
|
||||
f = open(files[0].name, O_RDONLY);
|
||||
assertEqualInt(1, read(f,buff, 1));
|
||||
assertEqualInt(0, close(f));
|
||||
assert((p = slurpfile(NULL, "f0")) != NULL);
|
||||
free(p);
|
||||
assertEqualInt(0, stat("f0", &st));
|
||||
if (st.st_atime == files[0].atime_sec) {
|
||||
skipping("Cannot verify -a option\n"
|
||||
|
@ -53,41 +53,44 @@ from_octal(const char *p, size_t l)
|
||||
|
||||
DEFINE_TEST(test_option_c)
|
||||
{
|
||||
int fd, filelist;
|
||||
FILE *filelist;
|
||||
int r;
|
||||
int uid = -1;
|
||||
int dev, ino, gid;
|
||||
time_t t, now;
|
||||
char *p, *e;
|
||||
size_t s;
|
||||
mode_t oldmask;
|
||||
|
||||
oldmask = umask(0);
|
||||
assertUmask(0);
|
||||
|
||||
#if !defined(_WIN32)
|
||||
uid = getuid();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create an assortment of files.
|
||||
* TODO: Extend this to cover more filetypes.
|
||||
*/
|
||||
filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
|
||||
filelist = fopen("filelist", "w");
|
||||
|
||||
/* "file" */
|
||||
fd = open("file", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
assertEqualInt(5, write(filelist, "file\n", 5));
|
||||
assertMakeFile("file", 0644, "1234567890");
|
||||
fprintf(filelist, "file\n");
|
||||
|
||||
/* "symlink" */
|
||||
assertEqualInt(0, symlink("file", "symlink"));
|
||||
assertEqualInt(8, write(filelist, "symlink\n", 8));
|
||||
if (canSymlink()) {
|
||||
assertMakeSymlink("symlink", "file");
|
||||
fprintf(filelist, "symlink\n");
|
||||
}
|
||||
|
||||
/* "dir" */
|
||||
assertEqualInt(0, mkdir("dir", 0775));
|
||||
assertMakeDir("dir", 0775);
|
||||
/* Record some facts about what we just created: */
|
||||
now = time(NULL); /* They were all created w/in last two seconds. */
|
||||
assertEqualInt(4, write(filelist, "dir\n", 4));
|
||||
fprintf(filelist, "dir\n");
|
||||
|
||||
/* Use the cpio program to create an archive. */
|
||||
close(filelist);
|
||||
fclose(filelist);
|
||||
r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog);
|
||||
/* Verify that nothing went to stderr. */
|
||||
assertTextFileContents("1 block\n", "basic.err");
|
||||
@ -120,7 +123,9 @@ DEFINE_TEST(test_option_c)
|
||||
#else
|
||||
assertEqualMem(e + 18, "100644", 6); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_octal(e + 24, 6), getuid()); /* uid */
|
||||
if (uid < 0)
|
||||
uid = from_octal(e + 24, 6);
|
||||
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
|
||||
assert(is_octal(e + 30, 6)); /* gid */
|
||||
gid = from_octal(e + 30, 6);
|
||||
assertEqualMem(e + 36, "000001", 6); /* nlink */
|
||||
@ -133,20 +138,21 @@ DEFINE_TEST(test_option_c)
|
||||
assertEqualMem(e + 59, "000005", 6); /* Name size */
|
||||
assertEqualMem(e + 65, "00000000012", 11); /* File size */
|
||||
assertEqualMem(e + 76, "file\0", 5); /* Name contents */
|
||||
assertEqualMem(e + 81, "123456789\0", 10); /* File contents */
|
||||
assertEqualMem(e + 81, "1234567890", 10); /* File contents */
|
||||
e += 91;
|
||||
|
||||
/* Second entry is "symlink" pointing to "file" */
|
||||
/* "symlink" pointing to "file" */
|
||||
if (canSymlink()) {
|
||||
assert(is_octal(e, 76)); /* Entire header is octal digits. */
|
||||
assertEqualMem(e + 0, "070707", 6); /* Magic */
|
||||
assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */
|
||||
assert(dev != from_octal(e + 12, 6)); /* ino */
|
||||
assert(ino != from_octal(e + 12, 6)); /* ino */
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
/* On Windows, symbolic link and group members bits and
|
||||
* others bits do not work. */
|
||||
assertEqualMem(e + 18, "120777", 6); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_octal(e + 24, 6), getuid()); /* uid */
|
||||
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
|
||||
assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
|
||||
assertEqualMem(e + 36, "000001", 6); /* nlink */
|
||||
failure("file entries should have rdev == 0 (dev was 0%o)",
|
||||
@ -156,23 +162,13 @@ DEFINE_TEST(test_option_c)
|
||||
assert(t <= now); /* File wasn't created in future. */
|
||||
assert(t >= now - 2); /* File was created w/in last 2 secs. */
|
||||
assertEqualMem(e + 59, "000010", 6); /* Name size */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* On Windows, symbolic link does not work. */
|
||||
assertEqualMem(e + 65, "00000000012", 11); /* File size */
|
||||
#else
|
||||
assertEqualMem(e + 65, "00000000004", 11); /* File size */
|
||||
#endif
|
||||
assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* On Windows, symbolic link does not work. */
|
||||
assertEqualMem(e + 84, "123456789\0", 10); /* File contents. */
|
||||
e += 94;
|
||||
#else
|
||||
assertEqualMem(e + 84, "file", 4); /* Symlink target. */
|
||||
e += 88;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Second entry is "dir" */
|
||||
/* "dir" */
|
||||
assert(is_octal(e, 76));
|
||||
assertEqualMem(e + 0, "070707", 6); /* Magic */
|
||||
/* Dev should be same as first entry. */
|
||||
@ -185,9 +181,11 @@ DEFINE_TEST(test_option_c)
|
||||
/* Group members bits and others bits do not work. */
|
||||
assertEqualMem(e + 18, "040777", 6); /* Mode */
|
||||
#else
|
||||
/* Accept 042775 to accomodate systems where sgid bit propagates. */
|
||||
if (memcmp(e + 18, "042775", 6) != 0)
|
||||
assertEqualMem(e + 18, "040775", 6); /* Mode */
|
||||
#endif
|
||||
assertEqualInt(from_octal(e + 24, 6), getuid()); /* uid */
|
||||
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
|
||||
/* Gid should be same as first entry. */
|
||||
assert(is_octal(e + 30, 6)); /* gid */
|
||||
assertEqualInt(gid, from_octal(e + 30, 6));
|
||||
@ -220,6 +218,4 @@ DEFINE_TEST(test_option_c)
|
||||
assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */
|
||||
|
||||
free(p);
|
||||
|
||||
umask(oldmask);
|
||||
}
|
||||
|
@ -28,41 +28,37 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_d)
|
||||
{
|
||||
struct stat st;
|
||||
int r, fd;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Create a file in a directory.
|
||||
*/
|
||||
assertEqualInt(0, mkdir("dir", 0755));
|
||||
fd = open("dir/file", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
close(fd);
|
||||
assertMakeDir("dir", 0755);
|
||||
assertMakeFile("dir/file", 0644, NULL);
|
||||
|
||||
/* Create an archive. */
|
||||
r = systemf("echo dir/file | %s -o > archive.cpio 2>archive.err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "archive.err");
|
||||
assertEqualInt(0, stat("archive.cpio", &st));
|
||||
assertEqualInt(512, st.st_size);
|
||||
assertFileSize("archive.cpio", 512);
|
||||
|
||||
/* Dearchive without -d, this should fail. */
|
||||
assertEqualInt(0, mkdir("without-d", 0755));
|
||||
assertEqualInt(0, chdir("without-d"));
|
||||
assertMakeDir("without-d", 0755);
|
||||
assertChdir("without-d");
|
||||
r = systemf("%s -i < ../archive.cpio >out 2>err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEmptyFile("out");
|
||||
/* And the file should not be restored. */
|
||||
assert(0 != stat("dir/file", &st));
|
||||
assertFileNotExists("dir/file");
|
||||
|
||||
/* Dearchive with -d, this should succeed. */
|
||||
assertEqualInt(0, chdir(".."));
|
||||
assertEqualInt(0, mkdir("with-d", 0755));
|
||||
assertEqualInt(0, chdir("with-d"));
|
||||
assertChdir("..");
|
||||
assertMakeDir("with-d", 0755);
|
||||
assertChdir("with-d");
|
||||
r = systemf("%s -id < ../archive.cpio >out 2>err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEmptyFile("out");
|
||||
assertTextFileContents("1 block\n", "err");
|
||||
/* And the file should be restored. */
|
||||
assertEqualInt(0, stat("dir/file", &st));
|
||||
assertFileExists("dir/file");
|
||||
}
|
||||
|
@ -33,44 +33,44 @@ unpack(const char *dirname, const char *option)
|
||||
{
|
||||
int r;
|
||||
|
||||
assertEqualInt(0, mkdir(dirname, 0755));
|
||||
assertEqualInt(0, chdir(dirname));
|
||||
assertMakeDir(dirname, 0755);
|
||||
assertChdir(dirname);
|
||||
extract_reference_file("test_option_f.cpio");
|
||||
r = systemf("%s -i %s < test_option_f.cpio > copy-no-a.out 2>copy-no-a.err", testprog, option);
|
||||
assertEqualInt(0, r);
|
||||
assertEqualInt(0, chdir(".."));
|
||||
assertChdir("..");
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_option_f)
|
||||
{
|
||||
/* Calibrate: No -f option, so everything should be extracted. */
|
||||
unpack("t0", "");
|
||||
assertEqualInt(0, access("t0/a123", F_OK));
|
||||
assertEqualInt(0, access("t0/a234", F_OK));
|
||||
assertEqualInt(0, access("t0/b123", F_OK));
|
||||
assertEqualInt(0, access("t0/b234", F_OK));
|
||||
unpack("t0", "--no-preserve-owner");
|
||||
assertFileExists("t0/a123");
|
||||
assertFileExists("t0/a234");
|
||||
assertFileExists("t0/b123");
|
||||
assertFileExists("t0/b234");
|
||||
|
||||
/* Don't extract 'a*' files. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Single quotes isn't used by command.exe. */
|
||||
unpack("t1", "-f a*");
|
||||
unpack("t1", "--no-preserve-owner -f a*");
|
||||
#else
|
||||
unpack("t1", "-f 'a*'");
|
||||
unpack("t1", "--no-preserve-owner -f 'a*'");
|
||||
#endif
|
||||
assert(0 != access("t1/a123", F_OK));
|
||||
assert(0 != access("t1/a234", F_OK));
|
||||
assertEqualInt(0, access("t1/b123", F_OK));
|
||||
assertEqualInt(0, access("t1/b234", F_OK));
|
||||
assertFileNotExists("t1/a123");
|
||||
assertFileNotExists("t1/a234");
|
||||
assertFileExists("t1/b123");
|
||||
assertFileExists("t1/b234");
|
||||
|
||||
/* Don't extract 'b*' files. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Single quotes isn't used by command.exe. */
|
||||
unpack("t2", "-f b*");
|
||||
unpack("t2", "--no-preserve-owner -f b*");
|
||||
#else
|
||||
unpack("t2", "-f 'b*'");
|
||||
unpack("t2", "--no-preserve-owner -f 'b*'");
|
||||
#endif
|
||||
assertEqualInt(0, access("t2/a123", F_OK));
|
||||
assertEqualInt(0, access("t2/a234", F_OK));
|
||||
assert(0 != access("t2/b123", F_OK));
|
||||
assert(0 != access("t2/b234", F_OK));
|
||||
assertFileExists("t2/a123");
|
||||
assertFileExists("t2/a234");
|
||||
assertFileNotExists("t2/b123");
|
||||
assertFileNotExists("t2/b234");
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ DEFINE_TEST(test_option_help)
|
||||
|
||||
/* Exercise --help option. */
|
||||
r = systemf("%s --help >help.stdout 2>help.stderr", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
failure("--help should generate nothing to stderr.");
|
||||
assertEmptyFile("help.stderr");
|
||||
/* Help message should start with name of program. */
|
||||
@ -67,6 +68,7 @@ DEFINE_TEST(test_option_help)
|
||||
|
||||
/* -h option should generate the same output. */
|
||||
r = systemf("%s -h >h.stdout 2>h.stderr", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
failure("-h should generate nothing to stderr.");
|
||||
assertEmptyFile("h.stderr");
|
||||
failure("stdout should be same for -h and --help");
|
||||
@ -74,6 +76,7 @@ DEFINE_TEST(test_option_help)
|
||||
|
||||
/* -W help should be another synonym. */
|
||||
r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
failure("-W help should generate nothing to stderr.");
|
||||
assertEmptyFile("Whelp.stderr");
|
||||
failure("stdout should be same for -W help and --help");
|
||||
|
@ -25,26 +25,12 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* This is called "test_option_ell" instead of "test_option_l" to
|
||||
* avoid any conflicts with "test_option_L" on case-insensitive
|
||||
* filesystems.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_option_ell)
|
||||
DEFINE_TEST(test_option_l)
|
||||
{
|
||||
struct stat st, st2;
|
||||
int fd;
|
||||
int r;
|
||||
|
||||
/* Create a file. */
|
||||
fd = open("f", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(1, write(fd, "a", 1));
|
||||
close(fd);
|
||||
|
||||
/* Stat it. */
|
||||
assertEqualInt(0, stat("f", &st));
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Copy the file to the "copy" dir. */
|
||||
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
|
||||
@ -52,8 +38,7 @@ DEFINE_TEST(test_option_ell)
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
/* Check that the copy is a true copy and not a link. */
|
||||
assertEqualInt(0, stat("copy/f", &st2));
|
||||
assert(st2.st_ino != st.st_ino);
|
||||
assertIsNotHardlink("f", "copy/f");
|
||||
|
||||
/* Copy the file to the "link" dir with the -l option. */
|
||||
r = systemf("echo f | %s -pld link >link.out 2>link.err",
|
||||
@ -61,6 +46,5 @@ DEFINE_TEST(test_option_ell)
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
/* Check that this is a link and not a copy. */
|
||||
assertEqualInt(0, stat("link/f", &st2));
|
||||
assert(st2.st_ino == st.st_ino);
|
||||
assertIsHardlink("f", "link/f");
|
||||
}
|
@ -6,8 +6,7 @@
|
||||
* 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.
|
||||
* 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.
|
||||
@ -23,52 +22,35 @@
|
||||
* (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"
|
||||
#include "test.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 "err.h"
|
||||
|
||||
const char *progname;
|
||||
|
||||
static void
|
||||
vwarnc(int code, const char *fmt, va_list ap)
|
||||
DEFINE_TEST(test_option_lzma)
|
||||
{
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
if (code != 0)
|
||||
fprintf(stderr, ": %s", strerror(code));
|
||||
fprintf(stderr, "\n");
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with lzma compression. */
|
||||
r = systemf("echo f | %s -o --lzma >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without lzma support");
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
warnc(int code, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vwarnc(code, fmt, ap);
|
||||
va_end(ap);
|
||||
failure("--lzma option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
errc(int eval, int code, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vwarnc(code, fmt, ap);
|
||||
va_end(ap);
|
||||
exit(eval);
|
||||
/* Check that the archive file has an lzma signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x5d\00\00", 3);
|
||||
}
|
@ -28,9 +28,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_m)
|
||||
{
|
||||
struct stat st;
|
||||
int r;
|
||||
time_t now;
|
||||
|
||||
/*
|
||||
* The reference archive has one file with an mtime in 1970, 1
|
||||
@ -38,33 +36,28 @@ DEFINE_TEST(test_option_m)
|
||||
*/
|
||||
|
||||
/* Restored without -m, the result should have a current mtime. */
|
||||
assertEqualInt(0, mkdir("without-m", 0755));
|
||||
assertEqualInt(0, chdir("without-m"));
|
||||
assertMakeDir("without-m", 0755);
|
||||
assertChdir("without-m");
|
||||
extract_reference_file("test_option_m.cpio");
|
||||
r = systemf("%s -i < test_option_m.cpio >out 2>err", testprog);
|
||||
now = time(NULL);
|
||||
r = systemf("%s --no-preserve-owner -i < test_option_m.cpio >out 2>err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEmptyFile("out");
|
||||
assertTextFileContents("1 block\n", "err");
|
||||
assertEqualInt(0, stat("file", &st));
|
||||
/* Should have been created within the last few seconds. */
|
||||
assert(st.st_mtime <= now);
|
||||
assert(st.st_mtime > now - 5);
|
||||
assertFileMtimeRecent("file");
|
||||
|
||||
/* With -m, it should have an mtime in 1970. */
|
||||
assertEqualInt(0, chdir(".."));
|
||||
assertEqualInt(0, mkdir("with-m", 0755));
|
||||
assertEqualInt(0, chdir("with-m"));
|
||||
assertChdir("..");
|
||||
assertMakeDir("with-m", 0755);
|
||||
assertChdir("with-m");
|
||||
extract_reference_file("test_option_m.cpio");
|
||||
r = systemf("%s -im < test_option_m.cpio >out 2>err", testprog);
|
||||
now = time(NULL);
|
||||
r = systemf("%s --no-preserve-owner -im < test_option_m.cpio >out 2>err", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertEmptyFile("out");
|
||||
assertTextFileContents("1 block\n", "err");
|
||||
assertEqualInt(0, stat("file", &st));
|
||||
/*
|
||||
* mtime in reference archive is '1' == 1 second after
|
||||
* midnight Jan 1, 1970 UTC.
|
||||
*/
|
||||
assertEqualInt(1, st.st_mtime);
|
||||
assertFileMtime("file", 1, 0);
|
||||
}
|
||||
|
@ -71,12 +71,22 @@ DEFINE_TEST(test_option_t)
|
||||
testprog);
|
||||
assertEqualInt(r, 0);
|
||||
assertTextFileContents("1 block\n", "itnv.err");
|
||||
extract_reference_file("test_option_tnv.stdout");
|
||||
/* This does work because numeric IDs come from archive. */
|
||||
/* Unfortunately, the timestamp still gets localized, so
|
||||
* we can't just compare against a fixed result. */
|
||||
/* TODO: Fix this. */
|
||||
/* assertEqualFile("itnv.out", "test_option_tnv.stdout"); */
|
||||
p = slurpfile(NULL, "itnv.out");
|
||||
/* Since -n uses numeric UID/GID, this part should be the
|
||||
* same on every system. */
|
||||
assertEqualMem(p, "-rw-r--r-- 1 1000 1000 0 ",42);
|
||||
/* Date varies depending on local timezone. */
|
||||
if (memcmp(p + 42, "Dec 31 1969", 12) == 0) {
|
||||
/* East of Greenwich we get Dec 31, 1969. */
|
||||
} else {
|
||||
/* West of Greenwich get Jan 1, 1970 */
|
||||
assertEqualMem(p + 42, "Jan ", 4);
|
||||
/* Some systems format "Jan 01", some "Jan 1" */
|
||||
assert(p[46] == ' ' || p[46] == '0');
|
||||
assertEqualMem(p + 47, "1 1970 ", 8);
|
||||
}
|
||||
assertEqualMem(p + 54, " file", 5);
|
||||
free(p);
|
||||
|
||||
/* But "-n" without "-t" is an error. */
|
||||
assert(0 != systemf("%s -in < test_option_t.cpio >in.out 2>in.err",
|
||||
|
@ -23,10 +23,10 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <sys/utime.h>
|
||||
#else
|
||||
#if defined(HAVE_UTIME_H)
|
||||
#include <utime.h>
|
||||
#elif defined(HAVE_SYS_UTIME_H)
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
@ -35,14 +35,10 @@ DEFINE_TEST(test_option_u)
|
||||
struct utimbuf times;
|
||||
char *p;
|
||||
size_t s;
|
||||
int fd;
|
||||
int r;
|
||||
|
||||
/* Create a file. */
|
||||
fd = open("f", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(1, write(fd, "a", 1));
|
||||
close(fd);
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Copy the file to the "copy" dir. */
|
||||
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
|
||||
@ -55,10 +51,7 @@ DEFINE_TEST(test_option_u)
|
||||
assertEqualMem(p, "a", 1);
|
||||
|
||||
/* Recreate the file with a single "b" */
|
||||
fd = open("f", O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(1, write(fd, "b", 1));
|
||||
close(fd);
|
||||
assertMakeFile("f", 0644, "b");
|
||||
|
||||
/* Set the mtime to the distant past. */
|
||||
memset(×, 0, sizeof(times));
|
||||
|
@ -74,14 +74,14 @@ verify(const char *p, size_t s)
|
||||
/* Skip a single trailing a,b,c, or d. */
|
||||
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
|
||||
++q;
|
||||
/* All terminated by a newline. */
|
||||
/* All terminated by end-of-line: \r, \r\n, or \n */
|
||||
assert(s >= 1);
|
||||
failure("Version: %s", p);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualMem(q, "\r\n", 2);
|
||||
#else
|
||||
assertEqualMem(q, "\n", 1);
|
||||
#endif
|
||||
if (*q == '\x0d') {
|
||||
if (q[1] != '\0')
|
||||
assertEqualMem(q, "\x0d\x0a", 2);
|
||||
} else
|
||||
assertEqualMem(q, "\x0a", 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,32 +28,30 @@ __FBSDID("$FreeBSD$");
|
||||
DEFINE_TEST(test_option_y)
|
||||
{
|
||||
char *p;
|
||||
int fd;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
fd = open("f", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(1, write(fd, "a", 1));
|
||||
close(fd);
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with bzip2 compression. */
|
||||
r = systemf("echo f | %s -oy >archive.out 2>archive.err",
|
||||
testprog);
|
||||
failure("-y (bzip) option seems to be broken");
|
||||
if (assertEqualInt(r, 0)) {
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (strstr(p, "bzip2 compression not supported") != NULL) {
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without bzip2 support");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
failure("-y option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
assertTextFileContents("1 block\n", "archive.err");
|
||||
/* Check that the archive file has a bzip2 signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "BZh9", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,32 +28,29 @@ __FBSDID("$FreeBSD$");
|
||||
DEFINE_TEST(test_option_z)
|
||||
{
|
||||
char *p;
|
||||
int fd;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
fd = open("f", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(1, write(fd, "a", 1));
|
||||
close(fd);
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with gzip compression. */
|
||||
r = systemf("echo f | %s -oz >archive.out 2>archive.err",
|
||||
testprog);
|
||||
failure("-z option seems to be broken");
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (strstr(p, "gzip compression not supported") != NULL) {
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without gzip support");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
failure("-z option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
/* Check that the archive file has a gzip signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assert(s > 4);
|
||||
assertEqualMem(p, "\x1f\x8b\x08\x00", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include "../cpio.h"
|
||||
#include "err.h"
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
#if !defined(_WIN32)
|
||||
#define ROOT "root"
|
||||
static int root_uids[] = { 0 };
|
||||
/* Solaris 9 root has gid 1 (other) */
|
||||
static int root_gids[] = { 0, 1 };
|
||||
#elif defined(__CYGWIN__)
|
||||
/* On cygwin, the Administrator user most likely exists (unless
|
||||
* it has been renamed or is in a non-English localization), but
|
||||
* its primary group membership depends on how the user set up
|
||||
@ -40,12 +45,9 @@ __FBSDID("$FreeBSD$");
|
||||
#define ROOT "Administrator"
|
||||
static int root_uids[] = { 500 };
|
||||
static int root_gids[] = { 513, 545, 544 };
|
||||
#else
|
||||
#define ROOT "root"
|
||||
static int root_uids[] = { 0 };
|
||||
static int root_gids[] = { 0 };
|
||||
#endif
|
||||
|
||||
#if defined(ROOT)
|
||||
static int
|
||||
int_in_list(int i, int *l, size_t n)
|
||||
{
|
||||
@ -55,54 +57,54 @@ int_in_list(int i, int *l, size_t n)
|
||||
failure("%d", i);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFINE_TEST(test_owner_parse)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* TODO: Does this need cygwin style handling of uid/gid ? */
|
||||
skipping("Windows cannot handle uid/gid as UNIX like system");
|
||||
#if !defined(ROOT)
|
||||
skipping("No uid/gid configuration for this OS");
|
||||
#else
|
||||
int uid, gid;
|
||||
|
||||
assertEqualInt(0, owner_parse(ROOT, &uid, &gid));
|
||||
assert(NULL == owner_parse(ROOT, &uid, &gid));
|
||||
assert(int_in_list(uid, root_uids,
|
||||
sizeof(root_uids)/sizeof(root_uids[0])));
|
||||
assertEqualInt(-1, gid);
|
||||
|
||||
|
||||
assertEqualInt(0, owner_parse(ROOT ":", &uid, &gid));
|
||||
assert(NULL == owner_parse(ROOT ":", &uid, &gid));
|
||||
assert(int_in_list(uid, root_uids,
|
||||
sizeof(root_uids)/sizeof(root_uids[0])));
|
||||
assert(int_in_list(gid, root_gids,
|
||||
sizeof(root_gids)/sizeof(root_gids[0])));
|
||||
|
||||
assertEqualInt(0, owner_parse(ROOT ".", &uid, &gid));
|
||||
assert(NULL == owner_parse(ROOT ".", &uid, &gid));
|
||||
assert(int_in_list(uid, root_uids,
|
||||
sizeof(root_uids)/sizeof(root_uids[0])));
|
||||
assert(int_in_list(gid, root_gids,
|
||||
sizeof(root_gids)/sizeof(root_gids[0])));
|
||||
|
||||
assertEqualInt(0, owner_parse("111", &uid, &gid));
|
||||
assert(NULL == owner_parse("111", &uid, &gid));
|
||||
assertEqualInt(111, uid);
|
||||
assertEqualInt(-1, gid);
|
||||
|
||||
assertEqualInt(0, owner_parse("112:", &uid, &gid));
|
||||
assert(NULL == owner_parse("112:", &uid, &gid));
|
||||
assertEqualInt(112, uid);
|
||||
/* Can't assert gid, since we don't know gid for user #112. */
|
||||
|
||||
assertEqualInt(0, owner_parse("113.", &uid, &gid));
|
||||
assert(NULL == owner_parse("113.", &uid, &gid));
|
||||
assertEqualInt(113, uid);
|
||||
/* Can't assert gid, since we don't know gid for user #113. */
|
||||
|
||||
assertEqualInt(0, owner_parse(":114", &uid, &gid));
|
||||
assert(NULL == owner_parse(":114", &uid, &gid));
|
||||
assertEqualInt(-1, uid);
|
||||
assertEqualInt(114, gid);
|
||||
|
||||
assertEqualInt(0, owner_parse(".115", &uid, &gid));
|
||||
assert(NULL == owner_parse(".115", &uid, &gid));
|
||||
assertEqualInt(-1, uid);
|
||||
assertEqualInt(115, gid);
|
||||
|
||||
assertEqualInt(0, owner_parse("116:117", &uid, &gid));
|
||||
assert(NULL == owner_parse("116:117", &uid, &gid));
|
||||
assertEqualInt(116, uid);
|
||||
assertEqualInt(117, gid);
|
||||
|
||||
@ -112,19 +114,9 @@ DEFINE_TEST(test_owner_parse)
|
||||
* users.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: Rework owner_parse to either return a char * pointing
|
||||
* to an error message or accept a function pointer to an
|
||||
* error-reporting routine so that the following tests don't
|
||||
* generate any output.
|
||||
*
|
||||
* Alternatively, redirect stderr temporarily to suppress the output.
|
||||
*/
|
||||
|
||||
cpio_progname = "Ignore this message";
|
||||
assertEqualInt(1, owner_parse(":nonexistentgroup", &uid, &gid));
|
||||
assertEqualInt(1, owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
|
||||
assertEqualInt(1,
|
||||
assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid));
|
||||
assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
|
||||
assert(NULL !=
|
||||
owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid));
|
||||
#endif
|
||||
}
|
||||
|
@ -31,33 +31,28 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_passthrough_dotdot)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, r;
|
||||
int filelist;
|
||||
int oldumask;
|
||||
int r;
|
||||
FILE *filelist;
|
||||
|
||||
oldumask = umask(0);
|
||||
assertUmask(0);
|
||||
|
||||
/*
|
||||
* Create an assortment of files on disk.
|
||||
*/
|
||||
filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
|
||||
filelist = fopen("filelist", "w");
|
||||
|
||||
/* Directory. */
|
||||
assertEqualInt(0, mkdir("dir", 0755));
|
||||
assertEqualInt(0, chdir("dir"));
|
||||
assertMakeDir("dir", 0755);
|
||||
assertChdir("dir");
|
||||
|
||||
write(filelist, ".\n", 2);
|
||||
fprintf(filelist, ".\n");
|
||||
|
||||
/* File with 10 bytes content. */
|
||||
fd = open("file", O_CREAT | O_WRONLY, 0642);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
write(filelist, "file\n", 5);
|
||||
assertMakeFile("file", 0642, "1234567890");
|
||||
fprintf(filelist, "file\n");
|
||||
|
||||
/* All done. */
|
||||
close(filelist);
|
||||
fclose(filelist);
|
||||
|
||||
|
||||
/*
|
||||
@ -68,26 +63,14 @@ DEFINE_TEST(test_passthrough_dotdot)
|
||||
failure("Error invoking %s -pd ..", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
assertEqualInt(0, chdir(".."));
|
||||
assertChdir("..");
|
||||
|
||||
/* Verify stderr and stdout. */
|
||||
assertTextFileContents("../.\n../file\n1 block\n", "stderr");
|
||||
assertEmptyFile("stdout");
|
||||
|
||||
/* Regular file. */
|
||||
r = lstat("file", &st);
|
||||
failure("Failed to stat file, errno=%d", errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0600, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0642, st.st_mode & 0777);
|
||||
#endif
|
||||
assertEqualInt(10, st.st_size);
|
||||
assertEqualInt(1, st.st_nlink);
|
||||
}
|
||||
|
||||
umask(oldumask);
|
||||
assertIsReg("file", 0642);
|
||||
assertFileSize("file", 10);
|
||||
assertFileNLinks("file", 1);
|
||||
}
|
||||
|
@ -36,33 +36,28 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_passthrough_reverse)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, r;
|
||||
int filelist;
|
||||
int oldumask;
|
||||
int r;
|
||||
FILE *filelist;
|
||||
|
||||
oldumask = umask(0);
|
||||
assertUmask(0);
|
||||
|
||||
/*
|
||||
* Create an assortment of files on disk.
|
||||
*/
|
||||
filelist = open("filelist", O_CREAT | O_WRONLY, 0644);
|
||||
filelist = fopen("filelist", "w");
|
||||
|
||||
/* Directory. */
|
||||
assertEqualInt(0, mkdir("dir", 0743));
|
||||
assertMakeDir("dir", 0743);
|
||||
|
||||
/* File with 10 bytes content. */
|
||||
fd = open("dir/file", O_CREAT | O_WRONLY, 0644);
|
||||
assert(fd >= 0);
|
||||
assertEqualInt(10, write(fd, "123456789", 10));
|
||||
close(fd);
|
||||
write(filelist, "dir/file\n", 9);
|
||||
assertMakeFile("dir/file", 0644, "1234567890");
|
||||
fprintf(filelist, "dir/file\n");
|
||||
|
||||
/* Write dir last. */
|
||||
write(filelist, "dir\n", 4);
|
||||
fprintf(filelist, "dir\n");
|
||||
|
||||
/* All done. */
|
||||
close(filelist);
|
||||
fclose(filelist);
|
||||
|
||||
|
||||
/*
|
||||
@ -72,7 +67,7 @@ DEFINE_TEST(test_passthrough_reverse)
|
||||
failure("Error invoking %s -pd out", testprog);
|
||||
assertEqualInt(r, 0);
|
||||
|
||||
assertEqualInt(0, chdir("out"));
|
||||
assertChdir("out");
|
||||
|
||||
/* Verify stderr and stdout. */
|
||||
assertTextFileContents("out/dir/file\nout/dir\n1 block\n",
|
||||
@ -80,33 +75,11 @@ DEFINE_TEST(test_passthrough_reverse)
|
||||
assertEmptyFile("../stdout");
|
||||
|
||||
/* dir */
|
||||
r = lstat("dir", &st);
|
||||
if (r == 0) {
|
||||
assertEqualInt(r, 0);
|
||||
assert(S_ISDIR(st.st_mode));
|
||||
failure("st.st_mode=0%o", st.st_mode);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0700, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0743, st.st_mode & 0777);
|
||||
#endif
|
||||
}
|
||||
assertIsDir("dir", 0743);
|
||||
|
||||
|
||||
/* Regular file. */
|
||||
r = lstat("dir/file", &st);
|
||||
failure("Failed to stat dir/file, errno=%d", errno);
|
||||
assertEqualInt(r, 0);
|
||||
if (r == 0) {
|
||||
assert(S_ISREG(st.st_mode));
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
assertEqualInt(0600, st.st_mode & 0700);
|
||||
#else
|
||||
assertEqualInt(0644, st.st_mode & 0777);
|
||||
#endif
|
||||
assertEqualInt(10, st.st_size);
|
||||
assertEqualInt(1, st.st_nlink);
|
||||
}
|
||||
|
||||
umask(oldumask);
|
||||
assertIsReg("dir/file", 0644);
|
||||
assertFileSize("dir/file", 10);
|
||||
assertFileNLinks("dir/file", 1);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "../pathmatch.h"
|
||||
#include "pathmatch.h"
|
||||
|
||||
/*
|
||||
* Verify that the pattern matcher implements the wildcard logic specified
|
||||
@ -45,126 +45,126 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_pathmatch)
|
||||
{
|
||||
assertEqualInt(1, pathmatch("a/b/c", "a/b/c", 0));
|
||||
assertEqualInt(0, pathmatch("a/b/", "a/b/c", 0));
|
||||
assertEqualInt(0, pathmatch("a/b", "a/b/c", 0));
|
||||
assertEqualInt(0, pathmatch("a/b/c", "a/b/", 0));
|
||||
assertEqualInt(0, pathmatch("a/b/c", "a/b", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));
|
||||
|
||||
/* Empty pattern only matches empty string. */
|
||||
assertEqualInt(1, pathmatch("","", 0));
|
||||
assertEqualInt(0, pathmatch("","a", 0));
|
||||
assertEqualInt(1, pathmatch("*","", 0));
|
||||
assertEqualInt(1, pathmatch("*","a", 0));
|
||||
assertEqualInt(1, pathmatch("*","abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("","", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("","a", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*","", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*","a", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
|
||||
/* SUSv2: * matches / */
|
||||
assertEqualInt(1, pathmatch("*","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(1, pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(1, pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(1, pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(0, pathmatch("?", "", 0));
|
||||
assertEqualInt(0, pathmatch("?", "\0", 0));
|
||||
assertEqualInt(1, pathmatch("?", "a", 0));
|
||||
assertEqualInt(0, pathmatch("?", "ab", 0));
|
||||
assertEqualInt(1, pathmatch("?", ".", 0));
|
||||
assertEqualInt(1, pathmatch("?", "?", 0));
|
||||
assertEqualInt(1, pathmatch("a", "a", 0));
|
||||
assertEqualInt(0, pathmatch("a", "ab", 0));
|
||||
assertEqualInt(0, pathmatch("a", "ab", 0));
|
||||
assertEqualInt(1, pathmatch("a?c", "abc", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("?", "", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("?", "a", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("?", ".", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("?", "?", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("a", "a", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
|
||||
/* SUSv2: ? matches / */
|
||||
assertEqualInt(1, pathmatch("a?c", "a/c", 0));
|
||||
assertEqualInt(1, pathmatch("a?*c*", "a/c", 0));
|
||||
assertEqualInt(1, pathmatch("*a*", "a/c", 0));
|
||||
assertEqualInt(1, pathmatch("*a*", "/a/c", 0));
|
||||
assertEqualInt(1, pathmatch("*a*", "defaaaaaaa", 0));
|
||||
assertEqualInt(0, pathmatch("a*", "defghi", 0));
|
||||
assertEqualInt(0, pathmatch("*a*", "defghi", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));
|
||||
|
||||
/* Character classes */
|
||||
assertEqualInt(1, pathmatch("abc[def", "abc[def", 0));
|
||||
assertEqualInt(0, pathmatch("abc[def]", "abc[def", 0));
|
||||
assertEqualInt(0, pathmatch("abc[def", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[def]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[def]", "abce", 0));
|
||||
assertEqualInt(1, pathmatch("abc[def]", "abcf", 0));
|
||||
assertEqualInt(0, pathmatch("abc[def]", "abcg", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d*f]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d*f]", "abc*", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d*f]", "abcdefghi", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d*", "abcdefghi", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d*", "abc[defghi", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-f]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-f]", "abce", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-f]", "abcf", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d-f]", "abcg", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d-fh-k]", "abca", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abce", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abcf", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d-fh-k]", "abcg", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abch", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abci", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abcj", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-k]", "abck", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d-fh-k]", "abcl", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d-fh-k]", "abc-", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));
|
||||
|
||||
/* [] matches nothing, [!] is the same as ? */
|
||||
assertEqualInt(0, pathmatch("abc[]efg", "abcdefg", 0));
|
||||
assertEqualInt(0, pathmatch("abc[]efg", "abcqefg", 0));
|
||||
assertEqualInt(0, pathmatch("abc[]efg", "abcefg", 0));
|
||||
assertEqualInt(1, pathmatch("abc[!]efg", "abcdefg", 0));
|
||||
assertEqualInt(1, pathmatch("abc[!]efg", "abcqefg", 0));
|
||||
assertEqualInt(0, pathmatch("abc[!]efg", "abcefg", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));
|
||||
|
||||
/* I assume: Trailing '-' is non-special. */
|
||||
assertEqualInt(0, pathmatch("abc[d-fh-]", "abcl", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-]", "abch", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-]", "abc-", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-fh-]", "abc-", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
|
||||
|
||||
/* ']' can be backslash-quoted within a character class. */
|
||||
assertEqualInt(1, pathmatch("abc[\\]]", "abc]", 0));
|
||||
assertEqualInt(1, pathmatch("abc[\\]d]", "abc]", 0));
|
||||
assertEqualInt(1, pathmatch("abc[\\]d]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d\\]]", "abc]", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d\\]]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d]e]", "abcde]", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d\\]e]", "abc]", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d\\]e]", "abcd]e", 0));
|
||||
assertEqualInt(0, pathmatch("abc[d]e]", "abc]", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));
|
||||
|
||||
/* backslash-quoted chars can appear as either end of a range. */
|
||||
assertEqualInt(1, pathmatch("abc[\\d-f]gh", "abcegh", 0));
|
||||
assertEqualInt(0, pathmatch("abc[\\d-f]gh", "abcggh", 0));
|
||||
assertEqualInt(0, pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d-\\f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
|
||||
/* backslash-quoted '-' isn't special. */
|
||||
assertEqualInt(0, pathmatch("abc[d\\-f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, pathmatch("abc[d\\-f]gh", "abc-gh", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
|
||||
|
||||
/* Leading '!' negates a character class. */
|
||||
assertEqualInt(0, pathmatch("abc[!d]", "abcd", 0));
|
||||
assertEqualInt(1, pathmatch("abc[!d]", "abce", 0));
|
||||
assertEqualInt(1, pathmatch("abc[!d]", "abcc", 0));
|
||||
assertEqualInt(0, pathmatch("abc[!d-z]", "abcq", 0));
|
||||
assertEqualInt(1, pathmatch("abc[!d-gi-z]", "abch", 0));
|
||||
assertEqualInt(1, pathmatch("abc[!fgijkl]", "abch", 0));
|
||||
assertEqualInt(0, pathmatch("abc[!fghijkl]", "abch", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));
|
||||
|
||||
/* Backslash quotes next character. */
|
||||
assertEqualInt(0, pathmatch("abc\\[def]", "abc\\d", 0));
|
||||
assertEqualInt(1, pathmatch("abc\\[def]", "abc[def]", 0));
|
||||
assertEqualInt(0, pathmatch("abc\\\\[def]", "abc[def]", 0));
|
||||
assertEqualInt(0, pathmatch("abc\\\\[def]", "abc\\[def]", 0));
|
||||
assertEqualInt(1, pathmatch("abc\\\\[def]", "abc\\d", 0));
|
||||
assertEqualInt(1, pathmatch("abcd\\", "abcd\\", 0));
|
||||
assertEqualInt(0, pathmatch("abcd\\", "abcd\\[", 0));
|
||||
assertEqualInt(0, pathmatch("abcd\\", "abcde", 0));
|
||||
assertEqualInt(0, pathmatch("abcd\\[", "abcd\\", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("abcd\\[", "abcd\\", 0));
|
||||
|
||||
/*
|
||||
* Because '.' and '/' have special meanings, we can
|
||||
@ -172,72 +172,72 @@ DEFINE_TEST(test_pathmatch)
|
||||
* differently. (But quoting a character with '\\' suppresses
|
||||
* special meanings!)
|
||||
*/
|
||||
assertEqualInt(0, pathmatch("a/b/", "a/bc", 0));
|
||||
assertEqualInt(1, pathmatch("a/./b", "a/b", 0));
|
||||
assertEqualInt(0, pathmatch("a\\/./b", "a/b", 0));
|
||||
assertEqualInt(0, pathmatch("a/\\./b", "a/b", 0));
|
||||
assertEqualInt(0, pathmatch("a/.\\/b", "a/b", 0));
|
||||
assertEqualInt(0, pathmatch("a\\/\\.\\/b", "a/b", 0));
|
||||
assertEqualInt(1, pathmatch("./abc/./def/", "abc/def/", 0));
|
||||
assertEqualInt(1, pathmatch("abc/def", "./././abc/./def", 0));
|
||||
assertEqualInt(1, pathmatch("abc/def/././//", "./././abc/./def/", 0));
|
||||
assertEqualInt(1, pathmatch(".////abc/.//def", "./././abc/./def", 0));
|
||||
assertEqualInt(1, pathmatch("./abc?def/", "abc/def/", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/b/", "a/bc", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0));
|
||||
assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
|
||||
failure("\"?./\" is not the same as \"/./\"");
|
||||
assertEqualInt(0, pathmatch("./abc?./def/", "abc/def/", 0));
|
||||
assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
|
||||
failure("Trailing '/' should match no trailing '/'");
|
||||
assertEqualInt(1, pathmatch("./abc/./def/", "abc/def", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
|
||||
failure("Trailing '/./' is still the same directory.");
|
||||
assertEqualInt(1, pathmatch("./abc/./def/./", "abc/def", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
|
||||
failure("Trailing '/.' is still the same directory.");
|
||||
assertEqualInt(1, pathmatch("./abc/./def/.", "abc/def", 0));
|
||||
assertEqualInt(1, pathmatch("./abc/./def", "abc/def/", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
|
||||
failure("Trailing '/./' is still the same directory.");
|
||||
assertEqualInt(1, pathmatch("./abc/./def", "abc/def/./", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
|
||||
failure("Trailing '/.' is still the same directory.");
|
||||
assertEqualInt(1, pathmatch("./abc*/./def", "abc/def/.", 0));
|
||||
assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));
|
||||
|
||||
/* Matches not anchored at beginning. */
|
||||
assertEqualInt(0,
|
||||
pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
|
||||
lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
|
||||
assertEqualInt(1,
|
||||
pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
|
||||
lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
|
||||
assertEqualInt(0,
|
||||
pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
|
||||
lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
|
||||
assertEqualInt(1,
|
||||
pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
|
||||
lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
|
||||
assertEqualInt(0,
|
||||
pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
|
||||
lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
|
||||
assertEqualInt(0,
|
||||
pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
|
||||
lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
|
||||
|
||||
/* Matches not anchored at end. */
|
||||
assertEqualInt(0,
|
||||
pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(0,
|
||||
pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(0,
|
||||
pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(0,
|
||||
pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(1,
|
||||
pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
|
||||
assertEqualInt(0,
|
||||
pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user