diff options
author | Joerg Sonnenberger <joerg.sonnenberger@gmail.com> | 2009-05-26 08:47:02 -0400 |
---|---|---|
committer | Joerg Sonnenberger <joerg.sonnenberger@gmail.com> | 2009-05-26 08:47:02 -0400 |
commit | 71d1bfe0f4f12d101def081c2ce170bb337b7841 (patch) | |
tree | 9096ab5d8261e5249fa31a2ec1332447d971d00e | |
parent | 83b3130331a1d5145bdd9f726d21876f15f2665d (diff) | |
download | libarchive-71d1bfe0f4f12d101def081c2ce170bb337b7841.tar.gz |
Refactor common frontend code into a separate library.
SVN-Revision: 1118
-rw-r--r-- | Makefile.am | 43 | ||||
-rw-r--r-- | cpio/cmdline.c | 17 | ||||
-rw-r--r-- | cpio/cpio.c | 266 | ||||
-rw-r--r-- | cpio/cpio.h | 17 | ||||
-rw-r--r-- | cpio/cpio_cygwin.c | 5 | ||||
-rw-r--r-- | cpio/cpio_windows.c | 5 | ||||
-rw-r--r-- | cpio/test/test_owner_parse.c | 4 | ||||
-rw-r--r-- | cpio/test/test_pathmatch.c | 280 | ||||
-rw-r--r-- | libarchive_fe/err.c (renamed from cpio/err.c) | 19 | ||||
-rw-r--r-- | libarchive_fe/err.h (renamed from cpio/matching.h) | 20 | ||||
-rw-r--r-- | libarchive_fe/lafe_platform.h | 53 | ||||
-rw-r--r-- | libarchive_fe/line_reader.c | 159 | ||||
-rw-r--r-- | libarchive_fe/line_reader.h | 35 | ||||
-rw-r--r-- | libarchive_fe/matching.c (renamed from cpio/matching.c) | 144 | ||||
-rw-r--r-- | libarchive_fe/matching.h | 46 | ||||
-rw-r--r-- | libarchive_fe/pathmatch.c (renamed from cpio/pathmatch.c) | 6 | ||||
-rw-r--r-- | libarchive_fe/pathmatch.h (renamed from cpio/pathmatch.h) | 8 | ||||
-rw-r--r-- | tar/bsdtar.c | 63 | ||||
-rw-r--r-- | tar/bsdtar.h | 18 | ||||
-rw-r--r-- | tar/bsdtar_cygwin.c | 5 | ||||
-rw-r--r-- | tar/bsdtar_windows.c | 5 | ||||
-rw-r--r-- | tar/cmdline.c | 13 | ||||
-rw-r--r-- | tar/matching.c | 478 | ||||
-rw-r--r-- | tar/read.c | 35 | ||||
-rw-r--r-- | tar/siginfo.c | 7 | ||||
-rw-r--r-- | tar/subst.c | 24 | ||||
-rw-r--r-- | tar/util.c | 137 | ||||
-rw-r--r-- | tar/write.c | 130 |
28 files changed, 813 insertions, 1229 deletions
diff --git a/Makefile.am b/Makefile.am index 3997f4e9..d8646dd9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,6 +6,7 @@ AUTOMAKE_OPTIONS= foreign subdir-objects # What to build and install # lib_LTLIBRARIES= libarchive.la +noinst_LTLIBRARIES= libarchive_fe.la bin_PROGRAMS= $(bsdtar_programs) $(bsdcpio_programs) man_MANS= $(libarchive_man_MANS) $(bsdtar_man_MANS) $(bsdcpio_man_MANS) BUILT_SOURCES= libarchive/test/list.h tar/test/list.h cpio/test/list.h @@ -172,8 +173,6 @@ libarchive_la_SOURCES+= \ libarchive/filter_fork_windows.c endif - -libarchive_la_CPPFLAGS=-I $(top_builddir)/libarchive # -no-undefined marks that libarchive doesn't rely on symbols # defined in the application. This is mandatory for cygwin. libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION) @@ -303,7 +302,7 @@ libarchive_test_SOURCES= \ libarchive/test/test_write_format_zip_no_compression.c \ libarchive/test/test_write_open_memory.c -libarchive_test_CPPFLAGS= -I$(top_builddir)/libarchive -I$(top_srcdir)/libarchive -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC +libarchive_test_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC libarchive_test_LDADD=@PROG_LDADD_EXTRA@ @@ -346,6 +345,15 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/CMakeLists.txt \ libarchive/test/README +# +# Common code for libarchive frontends (cpio, tar) +# +libarchive_fe_la_SOURCES= \ + libarchive_fe/err.c \ + libarchive_fe/line_reader.c \ + libarchive_fe/matching.c \ + libarchive_fe/pathmatch.c + # # @@ -359,7 +367,6 @@ bsdtar_SOURCES= \ tar/bsdtar_platform.h \ tar/cmdline.c \ tar/getdate.c \ - tar/matching.c \ tar/read.c \ tar/siginfo.c \ tar/subst.c \ @@ -379,7 +386,7 @@ bsdtar_SOURCES+= \ tar/bsdtar_cygwin.c endif -bsdtar_DEPENDENCIES= libarchive.la +bsdtar_DEPENDENCIES= libarchive.la libarchive_fe.la if STATIC_BSDTAR bsdtar_static= -static @@ -387,8 +394,9 @@ else bsdtar_static= endif -bsdtar_LDADD= libarchive.la @PROG_LDADD_EXTRA@ -bsdtar_CPPFLAGS= -I$(top_builddir)/libarchive -I$(top_srcdir)/libarchive +bsdtar_LDADD= libarchive.la libarchive_fe.la @PROG_LDADD_EXTRA@ +bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe + bsdtar_LDFLAGS= $(bsdtar_static) bsdtar_EXTRA_DIST= \ tar/bsdtar.1 \ @@ -464,12 +472,7 @@ bsdcpio_SOURCES= \ cpio/cmdline.c \ cpio/cpio.c \ cpio/cpio.h \ - cpio/cpio_platform.h \ - cpio/err.c \ - cpio/matching.c \ - cpio/matching.h \ - cpio/pathmatch.c \ - cpio/pathmatch.h + cpio/cpio_platform.h if INC_WINDOWS_FILES bsdcpio_SOURCES+= \ @@ -482,7 +485,7 @@ bsdcpio_SOURCES+= \ cpio/cpio_cygwin.c endif -bsdcpio_DEPENDENCIES = libarchive.la +bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la if STATIC_BSDCPIO @@ -491,8 +494,8 @@ else bsdcpio_static= endif -bsdcpio_LDADD= libarchive.la @PROG_LDADD_EXTRA@ -bsdcpio_CPPFLAGS= -I$(top_builddir)/libarchive -I$(top_srcdir)/libarchive +bsdcpio_LDADD= libarchive_fe.la libarchive.la @PROG_LDADD_EXTRA@ +bsdcpio_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe bsdcpio_LDFLAGS= $(bsdcpio_static) bsdcpio_EXTRA_DIST= \ cpio/test/list.h \ @@ -520,8 +523,6 @@ endif bsdcpio_test_SOURCES= \ cpio/cmdline.c \ - cpio/err.c \ - cpio/pathmatch.c \ cpio/test/main.c \ cpio/test/test.h \ cpio/test/test_0.c \ @@ -552,8 +553,10 @@ bsdcpio_test_SOURCES= \ cpio/test/test_passthrough_reverse.c \ cpio/test/test_pathmatch.c -bsdcpio_test_CPPFLAGS= -I$(top_builddir)/libarchive -I$(top_srcdir)/libarchive -I$(top_builddir)/cpio/test -bsdcpio_test_LDADD=@PROG_LDADD_EXTRA@ +bsdcpio_test_CPPFLAGS= \ + -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ + -I$(top_srcdir)/cpio -I$(top_builddir)/cpio/test +bsdcpio_test_LDADD=libarchive_fe.la @PROG_LDADD_EXTRA@ cpio/test/list.h: Makefile cat $(top_srcdir)/cpio/test/test_*.c | grep DEFINE_TEST > cpio/test/list.h diff --git a/cpio/cmdline.c b/cpio/cmdline.c index 0082b138..33307bb3 100644 --- a/cpio/cmdline.c +++ b/cpio/cmdline.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.5 2008/12/06 07:30:40 kientzl #endif #include "cpio.h" +#include "err.h" /* * Short options for cpio. Please keep this sorted. @@ -173,7 +174,7 @@ cpio_getopt(struct cpio *cpio) /* Otherwise, pick up the next word. */ opt_word = *cpio->argv; if (opt_word == NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option -%c requires an argument", opt); return ('?'); @@ -224,13 +225,13 @@ cpio_getopt(struct cpio *cpio) /* Fail if there wasn't a unique match. */ if (match == NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option %s%s is not supported", long_prefix, opt_word); return ('?'); } if (match2 != NULL) { - cpio_warnc(0, + lafe_warnc(0, "Ambiguous option %s%s (matches --%s and --%s)", long_prefix, opt_word, match->name, match2->name); return ('?'); @@ -242,7 +243,7 @@ cpio_getopt(struct cpio *cpio) if (cpio->optarg == NULL) { cpio->optarg = *cpio->argv; if (cpio->optarg == NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option %s%s requires an argument", long_prefix, match->name); return ('?'); @@ -253,7 +254,7 @@ cpio_getopt(struct cpio *cpio) } else { /* Argument forbidden: fail if there is one. */ if (cpio->optarg != NULL) { - cpio_warnc(0, + lafe_warnc(0, "Option %s%s does not allow an argument", long_prefix, match->name); return ('?'); @@ -315,14 +316,14 @@ owner_parse(const char *spec, int *uid, int *gid) user = (char *)malloc(ue - u + 1); if (user == NULL) { - cpio_warnc(errno, "Couldn't allocate memory"); + lafe_warnc(errno, "Couldn't allocate memory"); return (1); } memcpy(user, u, ue - u); user[ue - u] = '\0'; pwent = getpwnam(user); if (pwent == NULL) { - cpio_warnc(errno, "Couldn't lookup user ``%s''", user); + lafe_warnc(errno, "Couldn't lookup user ``%s''", user); return (1); } free(user); @@ -336,7 +337,7 @@ owner_parse(const char *spec, int *uid, int *gid) if (grp != NULL) *gid = grp->gr_gid; else { - cpio_warnc(errno, "Couldn't look up group ``%s''", g); + lafe_warnc(errno, "Couldn't look up group ``%s''", g); return (1); } } diff --git a/cpio/cpio.c b/cpio/cpio.c index 2cc46abd..a4cebd3a 100644 --- a/cpio/cpio.c +++ b/cpio/cpio.c @@ -74,6 +74,8 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle #endif #include "cpio.h" +#include "err.h" +#include "line_reader.h" #include "matching.h" /* Fixed size of uname/gname caches. */ @@ -131,19 +133,19 @@ main(int argc, char *argv[]) _set_fmode(_O_BINARY); #endif - /* Need cpio_progname before calling cpio_warnc. */ + /* Need lafe_progname before calling lafe_warnc. */ if (*argv == NULL) - cpio_progname = "bsdcpio"; + lafe_progname = "bsdcpio"; else { #if defined(_WIN32) && !defined(__CYGWIN__) - cpio_progname = strrchr(*argv, '\\'); + lafe_progname = strrchr(*argv, '\\'); #else - cpio_progname = strrchr(*argv, '/'); + lafe_progname = strrchr(*argv, '/'); #endif - if (cpio_progname != NULL) - cpio_progname++; + if (lafe_progname != NULL) + lafe_progname++; else - cpio_progname = *argv; + lafe_progname = *argv; } cpio->uid_override = -1; @@ -187,7 +189,7 @@ main(int argc, char *argv[]) case 'C': /* NetBSD/OpenBSD */ cpio->bytes_per_block = atoi(cpio->optarg); if (cpio->bytes_per_block <= 0) - cpio_errc(1, 0, "Invalid blocksize %s", cpio->optarg); + lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg); break; case 'c': /* POSIX 1997 */ cpio->format = "odc"; @@ -196,13 +198,13 @@ main(int argc, char *argv[]) cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; break; case 'E': /* NetBSD/OpenBSD */ - include_from_file(cpio, cpio->optarg); + lafe_include_from_file(&cpio->matching, cpio->optarg); break; case 'F': /* NetBSD/OpenBSD/GNU cpio */ cpio->filename = cpio->optarg; break; case 'f': /* POSIX 1997 */ - exclude(cpio, cpio->optarg); + lafe_exclude(&cpio->matching, cpio->optarg); break; case 'H': /* GNU cpio (also --format) */ cpio->format = cpio->optarg; @@ -215,7 +217,7 @@ main(int argc, char *argv[]) break; case 'i': /* POSIX 1997 */ if (cpio->mode != '\0') - cpio_errc(1, 0, + lafe_errc(1, 0, "Cannot use both -i and -%c", cpio->mode); cpio->mode = opt; break; @@ -252,13 +254,13 @@ main(int argc, char *argv[]) break; case 'o': /* POSIX 1997 */ if (cpio->mode != '\0') - cpio_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') - cpio_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; @@ -320,16 +322,16 @@ main(int argc, char *argv[]) cpio->mode = 'i'; /* -t requires -i */ if (cpio->option_list && cpio->mode != 'i') - cpio_errc(1, 0, "Option -t requires -i", cpio->mode); + lafe_errc(1, 0, "Option -t requires -i", cpio->mode); /* -n requires -it */ if (cpio->option_numeric_uid_gid && !cpio->option_list) - cpio_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') - cpio_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') - cpio_errc(1, 0, "Option -l requires -p"); + lafe_errc(1, 0, "Option -l requires -p"); /* TODO: Flag other nonsensical combinations. */ switch (cpio->mode) { @@ -343,7 +345,7 @@ main(int argc, char *argv[]) break; case 'i': while (*cpio->argv != NULL) { - include(cpio, *cpio->argv); + lafe_include(&cpio->matching, *cpio->argv); --cpio->argc; ++cpio->argv; } @@ -354,12 +356,12 @@ main(int argc, char *argv[]) break; case 'p': if (*cpio->argv == NULL || **cpio->argv == '\0') - cpio_errc(1, 0, + lafe_errc(1, 0, "-p mode requires a target directory"); mode_pass(cpio, *cpio->argv); break; default: - cpio_errc(1, 0, + lafe_errc(1, 0, "Must specify at least one of -i, -o, or -p"); } @@ -373,7 +375,7 @@ usage(void) { const char *p; - p = cpio_progname; + p = lafe_progname; fprintf(stderr, "Brief Usage:\n"); fprintf(stderr, " List: %s -it < archive\n", p); @@ -411,7 +413,7 @@ long_help(void) const char *prog; const char *p; - prog = cpio_progname; + prog = lafe_progname; fflush(stderr); @@ -445,15 +447,15 @@ mode_out(struct cpio *cpio) { unsigned long blocks; struct archive_entry *entry, *spare; - struct line_reader *lr; + struct lafe_line_reader *lr; const char *p; int r; if (cpio->option_append) - cpio_errc(1, 0, "Append mode not yet supported."); + lafe_errc(1, 0, "Append mode not yet supported."); cpio->archive = archive_write_new(); if (cpio->archive == NULL) - cpio_errc(1, 0, "Failed to allocate archive object"); + lafe_errc(1, 0, "Failed to allocate archive object"); switch (cpio->compress) { case 'J': r = archive_write_set_compression_xz(cpio->archive); @@ -475,10 +477,10 @@ mode_out(struct cpio *cpio) break; } if (r < ARCHIVE_WARN) - cpio_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) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + lafe_errc(1, 0, archive_error_string(cpio->archive)); archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block); cpio->linkresolver = archive_entry_linkresolver_new(); archive_entry_linkresolver_set_strategy(cpio->linkresolver, @@ -486,11 +488,11 @@ mode_out(struct cpio *cpio) r = archive_write_open_file(cpio->archive, cpio->filename); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); - lr = process_lines_init("-", cpio->line_separator); - while ((p = process_lines_next(lr)) != NULL) + lafe_errc(1, 0, archive_error_string(cpio->archive)); + lr = lafe_line_reader("-", cpio->line_separator); + while ((p = lafe_line_reader_next(lr)) != NULL) file_to_archive(cpio, p); - process_lines_free(lr); + lafe_line_reader_free(lr); /* * The hardlink detection may have queued up a couple of entries @@ -507,7 +509,7 @@ mode_out(struct cpio *cpio) r = archive_write_close(cpio->archive); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + lafe_errc(1, 0, archive_error_string(cpio->archive)); if (!cpio->quiet) { blocks = (archive_position_uncompressed(cpio->archive) + 511) @@ -543,7 +545,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath) */ entry = archive_entry_new(); if (entry == NULL) - cpio_errc(1, 0, "Couldn't allocate entry"); + lafe_errc(1, 0, "Couldn't allocate entry"); archive_entry_copy_sourcepath(entry, srcpath); /* Get stat information. */ @@ -552,7 +554,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath) else r = lstat(srcpath, &st); if (r != 0) { - cpio_warnc(errno, "Couldn't stat \"%s\"", srcpath); + lafe_warnc(errno, "Couldn't stat \"%s\"", srcpath); archive_entry_free(entry); return (0); } @@ -568,7 +570,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath) if (S_ISLNK(st.st_mode)) { lnklen = readlink(srcpath, cpio->buff, cpio->buff_size); if (lnklen < 0) { - cpio_warnc(errno, + lafe_warnc(errno, "%s: Couldn't read symbolic link", srcpath); archive_entry_free(entry); return (0); @@ -595,7 +597,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) - cpio_errc(1, ENOMEM, + lafe_errc(1, ENOMEM, "Can't allocate path buffer"); } strcpy(cpio->pass_destpath, cpio->destdir); @@ -661,7 +663,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) - cpio_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. */ @@ -671,7 +673,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) - cpio_warnc(archive_errno(cpio->archive), + lafe_warnc(archive_errno(cpio->archive), archive_error_string(cpio->archive)); if (r == ARCHIVE_FATAL) exit(1); @@ -679,7 +681,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. */ - cpio_warnc(0, "Copying file instead"); + lafe_warnc(0, "Copying file instead"); } else #endif return (0); @@ -693,7 +695,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry) if (archive_entry_size(entry) > 0) { fd = open(srcpath, O_RDONLY); if (fd < 0) { - cpio_warnc(errno, + lafe_warnc(errno, "%s: could not open file", srcpath); goto cleanup; } @@ -705,7 +707,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry) r = archive_write_header(cpio->archive, entry); if (r != ARCHIVE_OK) - cpio_warnc(archive_errno(cpio->archive), + lafe_warnc(archive_errno(cpio->archive), "%s: %s", srcpath, archive_error_string(cpio->archive)); @@ -719,10 +721,10 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry) r = archive_write_data(cpio->archive, cpio->buff, bytes_read); if (r < 0) - cpio_errc(1, archive_errno(cpio->archive), + lafe_errc(1, archive_errno(cpio->archive), archive_error_string(cpio->archive)); if (r < bytes_read) { - cpio_warnc(0, + lafe_warnc(0, "Truncated write; file may have grown while being archived."); } bytes_read = read(fd, cpio->buff, cpio->buff_size); @@ -751,7 +753,7 @@ restore_time(struct cpio *cpio, struct archive_entry *entry, (void)name; /* UNUSED */ if (!warned) - cpio_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 @@ -788,7 +790,7 @@ restore_time(struct cpio *cpio, struct archive_entry *entry, #else if (!S_ISLNK(archive_entry_mode(entry)) && utimes(name, times) != 0) #endif - cpio_warnc(errno, "Can't update time for %s", name); + lafe_warnc(errno, "Can't update time for %s", name); #endif return (fd); } @@ -806,28 +808,28 @@ mode_in(struct cpio *cpio) ext = archive_write_disk_new(); if (ext == NULL) - cpio_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) - cpio_errc(1, 0, archive_error_string(ext)); + lafe_errc(1, 0, archive_error_string(ext)); a = archive_read_new(); if (a == NULL) - cpio_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)) - cpio_errc(1, archive_errno(a), + lafe_errc(1, archive_errno(a), archive_error_string(a)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { - cpio_errc(1, archive_errno(a), + lafe_errc(1, archive_errno(a), archive_error_string(a)); } - if (excluded(cpio, 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)); @@ -853,10 +855,10 @@ mode_in(struct cpio *cpio) } r = archive_read_close(a); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); r = archive_write_close(ext); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(ext)); + lafe_errc(1, 0, archive_error_string(ext)); if (!cpio->quiet) { blocks = (archive_position_uncompressed(a) + 511) / 512; @@ -881,13 +883,13 @@ copy_data(struct archive *ar, struct archive *aw) if (r == ARCHIVE_EOF) return (ARCHIVE_OK); if (r != ARCHIVE_OK) { - cpio_warnc(archive_errno(ar), + lafe_warnc(archive_errno(ar), "%s", archive_error_string(ar)); return (r); } r = archive_write_data_block(aw, block, size, offset); if (r != ARCHIVE_OK) { - cpio_warnc(archive_errno(aw), + lafe_warnc(archive_errno(aw), archive_error_string(aw)); return (r); } @@ -904,22 +906,22 @@ mode_list(struct cpio *cpio) a = archive_read_new(); if (a == NULL) - cpio_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)) - cpio_errc(1, archive_errno(a), + lafe_errc(1, archive_errno(a), archive_error_string(a)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { - cpio_errc(1, archive_errno(a), + lafe_errc(1, archive_errno(a), archive_error_string(a)); } - if (excluded(cpio, archive_entry_pathname(entry))) + if (lafe_excluded(cpio->matching, archive_entry_pathname(entry))) continue; if (cpio->verbose) list_item_verbose(cpio, entry); @@ -928,7 +930,7 @@ mode_list(struct cpio *cpio) } r = archive_read_close(a); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); if (!cpio->quiet) { blocks = (archive_position_uncompressed(a) + 511) / 512; @@ -1028,7 +1030,7 @@ static void mode_pass(struct cpio *cpio, const char *destdir) { unsigned long blocks; - struct line_reader *lr; + struct lafe_line_reader *lr; const char *p; int r; @@ -1040,21 +1042,21 @@ mode_pass(struct cpio *cpio, const char *destdir) cpio->archive = archive_write_disk_new(); if (cpio->archive == NULL) - cpio_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) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + lafe_errc(1, 0, archive_error_string(cpio->archive)); cpio->linkresolver = archive_entry_linkresolver_new(); archive_write_disk_set_standard_lookup(cpio->archive); - lr = process_lines_init("-", cpio->line_separator); - while ((p = process_lines_next(lr)) != NULL) + lr = lafe_line_reader("-", cpio->line_separator); + while ((p = lafe_line_reader_next(lr)) != NULL) file_to_archive(cpio, p); - process_lines_free(lr); + lafe_line_reader_free(lr); archive_entry_linkresolver_free(cpio->linkresolver); r = archive_write_close(cpio->archive); if (r != ARCHIVE_OK) - cpio_errc(1, 0, archive_error_string(cpio->archive)); + lafe_errc(1, 0, archive_error_string(cpio->archive)); if (!cpio->quiet) { blocks = (archive_position_uncompressed(cpio->archive) + 511) @@ -1109,130 +1111,6 @@ cpio_rename(const char *name) return (ret); } - -/* - * Read lines from file and do something with each one. If option_null - * is set, lines are terminated with zero bytes; otherwise, they're - * terminated with newlines. - * - * This uses a self-sizing buffer to handle arbitrarily-long lines. - */ -struct line_reader { - FILE *f; - char *buff, *buff_end, *line_start, *line_end, *p; - char *pathname; - size_t buff_length; - int separator; - int ret; -}; - -struct line_reader * -process_lines_init(const char *pathname, char separator) -{ - struct line_reader *lr; - - lr = calloc(1, sizeof(*lr)); - if (lr == NULL) - cpio_errc(1, ENOMEM, "Can't open %s", pathname); - - lr->separator = separator; - lr->pathname = strdup(pathname); - - if (strcmp(pathname, "-") == 0) - lr->f = stdin; - else - lr->f = fopen(pathname, "r"); - if (lr->f == NULL) - cpio_errc(1, errno, "Couldn't open %s", pathname); - lr->buff_length = 8192; - lr->buff = malloc(lr->buff_length); - if (lr->buff == NULL) - cpio_errc(1, ENOMEM, "Can't read %s", pathname); - lr->line_start = lr->line_end = lr->buff_end = lr->buff; - - return (lr); -} - -const char * -process_lines_next(struct line_reader *lr) -{ - size_t bytes_wanted, bytes_read, new_buff_size; - char *line_start, *p; - - for (;;) { - /* If there's a line in the buffer, return it immediately. */ - while (lr->line_end < lr->buff_end) { - if (*lr->line_end == lr->separator) { - *lr->line_end = '\0'; - line_start = lr->line_start; - lr->line_start = lr->line_end + 1; - lr->line_end = lr->line_start; - return (line_start); - } else - lr->line_end++; - } - - /* If we're at end-of-file, process the final data. */ - if (lr->f == NULL) { - /* If there's more text, return one last line. */ - if (lr->line_end > lr->line_start) { - *lr->line_end = '\0'; - line_start = lr->line_start; - lr->line_start = lr->line_end + 1; - lr->line_end = lr->line_start; - return (line_start); - } - /* Otherwise, we're done. */ - return (NULL); - } - - /* Buffer only has part of a line. */ - if (lr->line_start > lr->buff) { - /* Move a leftover fractional line to the beginning. */ - memmove(lr->buff, lr->line_start, - lr->buff_end - lr->line_start); - lr->buff_end -= lr->line_start - lr->buff; - lr->line_end -= lr->line_start - lr->buff; - lr->line_start = lr->buff; - } else { - /* Line is too big; enlarge the buffer. */ - new_buff_size = lr->buff_length * 2; - if (new_buff_size <= lr->buff_length) - cpio_errc(1, ENOMEM, - "Line too long in %s", lr->pathname); - lr->buff_length = new_buff_size; - p = realloc(lr->buff, new_buff_size); - if (p == NULL) - cpio_errc(1, ENOMEM, - "Line too long in %s", lr->pathname); - lr->buff_end = p + (lr->buff_end - lr->buff); - lr->line_end = p + (lr->line_end - lr->buff); - lr->line_start = lr->buff = p; - } - - /* Get some more data into the buffer. */ - bytes_wanted = lr->buff + lr->buff_length - lr->buff_end; - bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f); - lr->buff_end += bytes_read; - - if (ferror(lr->f)) - cpio_errc(1, errno, "Can't read %s", lr->pathname); - if (feof(lr->f)) { - if (lr->f != stdin) - fclose(lr->f); - lr->f = NULL; - } - } -} - -void -process_lines_free(struct line_reader *lr) -{ - free(lr->buff); - free(lr->pathname); - free(lr); -} - static void free_cache(struct name_cache *cache) { @@ -1261,7 +1139,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) - cpio_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; } @@ -1318,7 +1196,7 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id) if (pwent == NULL) { *name = NULL; if (errno != 0) - cpio_warnc(errno, "getpwuid(%d) failed", id); + lafe_warnc(errno, "getpwuid(%d) failed", id); return (errno); } @@ -1345,7 +1223,7 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id) if (grent == NULL) { *name = NULL; if (errno != 0) - cpio_warnc(errno, "getgrgid(%d) failed", id); + lafe_warnc(errno, "getgrgid(%d) failed", id); return (errno); } diff --git a/cpio/cpio.h b/cpio/cpio.h index 7843c6f0..4b38b5ff 100644 --- a/cpio/cpio.h +++ b/cpio/cpio.h @@ -31,6 +31,8 @@ #include "cpio_platform.h" #include <stdio.h> +#include "matching.h" + /* * The internal state for the "cpio" program. * @@ -83,17 +85,11 @@ struct cpio { struct name_cache *gname_cache; /* Work data. */ - struct matching *matching; + struct lafe_matching *matching; char *buff; size_t buff_size; }; -/* Name of this program; used in error reporting, initialized in main(). */ -const char *cpio_progname; - -void cpio_errc(int _eval, int _code, const char *fmt, ...) __LA_DEAD; -void cpio_warnc(int _code, const char *fmt, ...); - int owner_parse(const char *, int *, int *); @@ -106,13 +102,6 @@ enum { OPTION_VERSION }; -struct line_reader; - -struct line_reader *process_lines_init(const char *, char separator); -const char *process_lines_next(struct line_reader *); -void process_lines_free(struct line_reader *); - int cpio_getopt(struct cpio *cpio); -int include_from_file(struct cpio *, const char *); #endif diff --git a/cpio/cpio_cygwin.c b/cpio/cpio_cygwin.c index f2157c55..7e27d2cf 100644 --- a/cpio/cpio_cygwin.c +++ b/cpio/cpio_cygwin.c @@ -41,6 +41,7 @@ #include <sddl.h> #include "cpio.h" +#include "err.h" #ifndef LIST_H static int @@ -123,12 +124,12 @@ bsdcpio_is_privileged() }; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &thandle) == 0) { - cpio_warnc(EPERM, "Failed to check privilege"); + lafe_warnc(EPERM, "Failed to check privilege"); return (0); } ret = _is_privileged(thandle, sidlist); if (ret < 0) { - cpio_warnc(errno, "Failed to check privilege"); + lafe_warnc(errno, "Failed to check privilege"); return (0); } return (ret); diff --git a/cpio/cpio_windows.c b/cpio/cpio_windows.c index ea67d986..e4c14b5e 100644 --- a/cpio/cpio_windows.c +++ b/cpio/cpio_windows.c @@ -41,6 +41,7 @@ #include <sddl.h> #include "cpio.h" +#include "err.h" #define EPOC_TIME (116444736000000000ULL) @@ -978,12 +979,12 @@ bsdcpio_is_privileged() }; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &thandle) == 0) { - cpio_warnc(EPERM, "Failed to check privilege"); + lafe_warnc(EPERM, "Failed to check privilege"); return (0); } ret = _is_privileged(thandle, sidlist); if (ret < 0) { - cpio_warnc(errno, "Failed to check privilege"); + lafe_warnc(errno, "Failed to check privilege"); return (0); } return (ret); diff --git a/cpio/test/test_owner_parse.c b/cpio/test/test_owner_parse.c index 1e9434fb..b756a2f8 100644 --- a/cpio/test/test_owner_parse.c +++ b/cpio/test/test_owner_parse.c @@ -26,6 +26,7 @@ __FBSDID("$FreeBSD$"); #include "../cpio.h" +#include "err.h" #if defined(__CYGWIN__) /* On cygwin, the Administrator user most likely exists (unless @@ -47,7 +48,6 @@ __FBSDID("$FreeBSD$"); #define ROOT_GID 0 #endif - DEFINE_TEST(test_owner_parse) { #if defined(_WIN32) && !defined(__CYGWIN__) @@ -56,7 +56,7 @@ DEFINE_TEST(test_owner_parse) #else int uid, gid; - cpio_progname = "Ignore this message"; + lafe_progname = "Ignore this message"; assertEqualInt(0, owner_parse(ROOT, &uid, &gid)); assertEqualInt(ROOT_UID, uid); diff --git a/cpio/test/test_pathmatch.c b/cpio/test/test_pathmatch.c index a596eda1..177c2bcc 100644 --- a/cpio/test/test_pathmatch.c +++ b/cpio/test/test_pathmatch.c @@ -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)); } diff --git a/cpio/err.c b/libarchive_fe/err.c index ad9c0e19..eb3f9f3e 100644 --- a/cpio/err.c +++ b/libarchive_fe/err.c @@ -24,8 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include "cpio_platform.h" +#include "lafe_platform.h" __FBSDID("$FreeBSD$"); #ifdef HAVE_STDARG_H @@ -39,12 +38,14 @@ __FBSDID("$FreeBSD$"); #include <string.h> #endif -#include "cpio.h" +#include "err.h" + +const char *lafe_progname; static void -cpio_vwarnc(int code, const char *fmt, va_list ap) +lafe_vwarnc(int code, const char *fmt, va_list ap) { - fprintf(stderr, "%s: ", cpio_progname); + fprintf(stderr, "%s: ", lafe_progname); vfprintf(stderr, fmt, ap); if (code != 0) fprintf(stderr, ": %s", strerror(code)); @@ -52,22 +53,22 @@ cpio_vwarnc(int code, const char *fmt, va_list ap) } void -cpio_warnc(int code, const char *fmt, ...) +lafe_warnc(int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - cpio_vwarnc(code, fmt, ap); + lafe_vwarnc(code, fmt, ap); va_end(ap); } void -cpio_errc(int eval, int code, const char *fmt, ...) +lafe_errc(int eval, int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - cpio_vwarnc(code, fmt, ap); + lafe_vwarnc(code, fmt, ap); va_end(ap); exit(eval); } diff --git a/cpio/matching.h b/libarchive_fe/err.h index a66bc86b..164e2d38 100644 --- a/cpio/matching.h +++ b/libarchive_fe/err.h @@ -1,13 +1,12 @@ /*- - * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2009 Joerg Sonnenberger * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * 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,19 +21,14 @@ * 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 +#ifndef LAFE_ERR_H +#define LAFE_ERR_H -#include "cpio.h" +extern const char *lafe_progname; -int exclude(struct cpio *, const char *pattern); -int include(struct cpio *, const char *pattern); -int excluded(struct cpio *cpio, const char *pathname); -void cleanup_exclusions(struct cpio *cpio); -int unmatched_inclusions(struct cpio *cpio); +void lafe_warnc(int code, const char *fmt, ...); +void lafe_errc(int eval, int code, const char *fmt, ...); #endif diff --git a/libarchive_fe/lafe_platform.h b/libarchive_fe/lafe_platform.h new file mode 100644 index 00000000..dceb5aaf --- /dev/null +++ b/libarchive_fe/lafe_platform.h @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/usr.bin/cpio/cpio_platform.h,v 1.2 2008/12/06 07:15:42 kientzle Exp $ + */ + +/* + * This header is the first thing included in any of the libarchive_fe + * source files. As far as possible, platform-specific issues should + * be dealt with here and not within individual source files. + */ + +#ifndef LAFE_PLATFORM_H_INCLUDED +#define LAFE_PLATFORM_H_INCLUDED + +#if defined(PLATFORM_CONFIG_H) +/* Use hand-built config.h in environments that need it. */ +#include PLATFORM_CONFIG_H +#else +/* Read config.h or die trying. */ +#include "config.h" +#endif + +/* No non-FreeBSD platform will have __FBSDID, so just define it here. */ +#ifdef __FreeBSD__ +#include <sys/cdefs.h> /* For __FBSDID */ +#elif !defined(__FBSDID) +/* Just leaving this macro replacement empty leads to a dangling semicolon. */ +#define __FBSDID(a) struct _undefined_hack +#endif + +#endif diff --git a/libarchive_fe/line_reader.c b/libarchive_fe/line_reader.c new file mode 100644 index 00000000..ee5252db --- /dev/null +++ b/libarchive_fe/line_reader.c @@ -0,0 +1,159 @@ +/*- + * 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 "lafe_platform.h" +__FBSDID("$FreeBSD$"); + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "err.h" +#include "line_reader.h" + +/* + * 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 lafe_line_reader { + FILE *f; + char *buff, *buff_end, *line_start, *line_end, *p; + char *pathname; + size_t buff_length; + int separator; + int ret; +}; + +struct lafe_line_reader * +lafe_line_reader(const char *pathname, char separator) +{ + struct lafe_line_reader *lr; + + lr = calloc(1, sizeof(*lr)); + if (lr == NULL) + lafe_errc(1, ENOMEM, "Can't open %s", pathname); + + lr->separator = separator; + lr->pathname = strdup(pathname); + + if (strcmp(pathname, "-") == 0) + lr->f = stdin; + else + lr->f = fopen(pathname, "r"); + if (lr->f == NULL) + lafe_errc(1, errno, "Couldn't open %s", pathname); + lr->buff_length = 8192; + lr->buff = malloc(lr->buff_length); + if (lr->buff == NULL) + lafe_errc(1, ENOMEM, "Can't read %s", pathname); + lr->line_start = lr->line_end = lr->buff_end = lr->buff; + + return (lr); +} + +const char * +lafe_line_reader_next(struct lafe_line_reader *lr) +{ + size_t bytes_wanted, bytes_read, new_buff_size; + char *line_start, *p; + + for (;;) { + /* If there's a line in the buffer, return it immediately. */ + while (lr->line_end < lr->buff_end) { + if (*lr->line_end == lr->separator) { + *lr->line_end = '\0'; + line_start = lr->line_start; + lr->line_start = lr->line_end + 1; + lr->line_end = lr->line_start; + return (line_start); + } else + lr->line_end++; + } + + /* If we're at end-of-file, process the final data. */ + if (lr->f == NULL) { + /* If there's more text, return one last line. */ + if (lr->line_end > lr->line_start) { + *lr->line_end = '\0'; + line_start = lr->line_start; + lr->line_start = lr->line_end + 1; + lr->line_end = lr->line_start; + return (line_start); + } + /* Otherwise, we're done. */ + return (NULL); + } + + /* Buffer only has part of a line. */ + if (lr->line_start > lr->buff) { + /* Move a leftover fractional line to the beginning. */ + memmove(lr->buff, lr->line_start, + lr->buff_end - lr->line_start); + lr->buff_end -= lr->line_start - lr->buff; + lr->line_end -= lr->line_start - lr->buff; + lr->line_start = lr->buff; + } else { + /* Line is too big; enlarge the buffer. */ + new_buff_size = lr->buff_length * 2; + if (new_buff_size <= lr->buff_length) + lafe_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) + lafe_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)) + lafe_errc(1, errno, "Can't read %s", lr->pathname); + if (feof(lr->f)) { + if (lr->f != stdin) + fclose(lr->f); + lr->f = NULL; + } + } +} + +void +lafe_line_reader_free(struct lafe_line_reader *lr) +{ + free(lr->buff); + free(lr->pathname); + free(lr); +} diff --git a/libarchive_fe/line_reader.h b/libarchive_fe/line_reader.h new file mode 100644 index 00000000..7bb1742c --- /dev/null +++ b/libarchive_fe/line_reader.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2009 Joerg Sonnenberger + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LAFE_LINE_READER_H +#define LAFE_LINE_READER_H + +struct lafe_line_reader; + +struct lafe_line_reader *lafe_line_reader(const char *, char separator); +const char *lafe_line_reader_next(struct lafe_line_reader *); +void lafe_line_reader_free(struct lafe_line_reader *); + +#endif diff --git a/cpio/matching.c b/libarchive_fe/matching.c index 2e244c44..af5bde4e 100644 --- a/cpio/matching.c +++ b/libarchive_fe/matching.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "cpio_platform.h" +#include "lafe_platform.h" __FBSDID("$FreeBSD: src/usr.bin/cpio/matching.c,v 1.2 2008/06/21 02:20:20 kientzle Exp $"); #ifdef HAVE_ERRNO_H @@ -36,6 +36,8 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/matching.c,v 1.2 2008/06/21 02:20:20 kientz #include <string.h> #endif +#include "err.h" +#include "line_reader.h" #include "matching.h" #include "pathmatch.h" @@ -45,7 +47,7 @@ struct match { char pattern[1]; }; -struct matching { +struct lafe_matching { struct match *exclusions; int exclusions_count; struct match *inclusions; @@ -54,7 +56,7 @@ struct matching { }; static void add_pattern(struct match **list, const char *pattern); -static void initialize_matching(struct cpio *); +static void initialize_matching(struct lafe_matching **); static int match_exclusion(struct match *, const char *pathname); static int match_inclusion(struct match *, const char *pathname); @@ -70,52 +72,57 @@ static int match_inclusion(struct match *, const char *pathname); */ int -exclude(struct cpio *cpio, const char *pattern) +lafe_exclude(struct lafe_matching **matching, const char *pattern) { - struct matching *matching; - if (cpio->matching == NULL) - initialize_matching(cpio); - matching = cpio->matching; - add_pattern(&(matching->exclusions), pattern); - matching->exclusions_count++; + if (*matching == NULL) + initialize_matching(matching); + add_pattern(&((*matching)->exclusions), pattern); + (*matching)->exclusions_count++; return (0); } -#if 0 int -exclude_from_file(struct cpio *cpio, const char *pathname) +lafe_exclude_from_file(struct lafe_matching **matching, const char *pathname) { - return (process_lines(cpio, pathname, &exclude)); + struct lafe_line_reader *lr; + const char *p; + int ret = 0; + + lr = lafe_line_reader(pathname, '\n'); + while ((p = lafe_line_reader_next(lr)) != NULL) { + if (lafe_exclude(matching, p) != 0) + ret = -1; + } + lafe_line_reader_free(lr); + return (ret); } -#endif int -include(struct cpio *cpio, const char *pattern) +lafe_include(struct lafe_matching **matching, const char *pattern) { - struct matching *matching; - - if (cpio->matching == NULL) - initialize_matching(cpio); - matching = cpio->matching; - add_pattern(&(matching->inclusions), pattern); - matching->inclusions_count++; - matching->inclusions_unmatched_count++; + + 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 cpio *cpio, const char *pathname) +lafe_include_from_file(struct lafe_matching **matching, const char *pathname) { - struct line_reader *lr; + struct lafe_line_reader *lr; const char *p; int ret = 0; - lr = process_lines_init(pathname, '\n'); - while ((p = process_lines_next(lr)) != NULL) - if (include(cpio, p) != 0) + lr = lafe_line_reader(pathname, '\n'); + while ((p = lafe_line_reader_next(lr)) != NULL) { + if (lafe_include(matching, p) != 0) ret = -1; - process_lines_free(lr); + } + lafe_line_reader_free(lr); return (ret); } @@ -128,7 +135,7 @@ add_pattern(struct match **list, const char *pattern) len = strlen(pattern); match = malloc(sizeof(*match) + len + 1); if (match == NULL) - cpio_errc(1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); strcpy(match->pattern, pattern); /* Both "foo/" and "foo" should match "foo/bar". */ if (len && match->pattern[len - 1] == '/') @@ -140,13 +147,11 @@ add_pattern(struct match **list, const char *pattern) int -excluded(struct cpio *cpio, const char *pathname) +lafe_excluded(struct lafe_matching *matching, const char *pathname) { - struct matching *matching; struct match *match; struct match *matched; - matching = cpio->matching; if (matching == NULL) return (0); @@ -198,10 +203,10 @@ excluded(struct cpio *cpio, const char *pathname) * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar' * */ -int +static int match_exclusion(struct match *match, const char *pathname) { - return (pathmatch(match->pattern, + return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); } @@ -210,50 +215,69 @@ match_exclusion(struct match *match, const char *pathname) * Again, mimic gtar: inclusions are always anchored (have to match * the beginning of the path) even though exclusions are not anchored. */ -int +static int match_inclusion(struct match *match, const char *pathname) { - return (pathmatch(match->pattern, pathname, 0)); +#if 0 + return (lafe_pathmatch(match->pattern, pathname, 0)); +#else + return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END)); +#endif } void -cleanup_exclusions(struct cpio *cpio) +lafe_cleanup_exclusions(struct lafe_matching **matching) { struct match *p, *q; - if (cpio->matching) { - p = cpio->matching->inclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - p = cpio->matching->exclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - free(cpio->matching); + 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 cpio *cpio) +initialize_matching(struct lafe_matching **matching) { - cpio->matching = malloc(sizeof(*cpio->matching)); - if (cpio->matching == NULL) - cpio_errc(1, errno, "No memory"); - memset(cpio->matching, 0, sizeof(*cpio->matching)); + *matching = calloc(sizeof(**matching), 1); + if (*matching == NULL) + lafe_errc(1, errno, "No memory"); } int -unmatched_inclusions(struct cpio *cpio) +lafe_unmatched_inclusions(struct lafe_matching *matching) { - struct matching *matching; - matching = cpio->matching; if (matching == NULL) return (0); return (matching->inclusions_unmatched_count); } + +int +lafe_unmatched_inclusions_warn(struct lafe_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) + lafe_warnc(0, "%s: %s", p->pattern, msg); + } + + return (matching->inclusions_unmatched_count); +} diff --git a/libarchive_fe/matching.h b/libarchive_fe/matching.h new file mode 100644 index 00000000..5cdc0166 --- /dev/null +++ b/libarchive_fe/matching.h @@ -0,0 +1,46 @@ +/*- + * 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 lafe_matching; + +int lafe_exclude(struct lafe_matching **matching, const char *pattern); +int lafe_exclude_from_file(struct lafe_matching **matching, + const char *pathname); +int lafe_include(struct lafe_matching **matching, const char *pattern); +int lafe_include_from_file(struct lafe_matching **matching, + const char *pathname); + +int lafe_excluded(struct lafe_matching *, const char *pathname); +void lafe_cleanup_exclusions(struct lafe_matching **); +int lafe_unmatched_inclusions(struct lafe_matching *); +int lafe_unmatched_inclusions_warn(struct lafe_matching *, const char *msg); + +#endif diff --git a/cpio/pathmatch.c b/libarchive_fe/pathmatch.c index 8b7272e0..80a0b6aa 100644 --- a/cpio/pathmatch.c +++ b/libarchive_fe/pathmatch.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "cpio_platform.h" +#include "lafe_platform.h" __FBSDID("$FreeBSD$"); #ifdef HAVE_STRING_H @@ -145,7 +145,7 @@ pm(const char *p, const char *s, int flags) if (*p == '\0') return (1); while (*s) { - if (pathmatch(p, s, flags)) + if (lafe_pathmatch(p, s, flags)) return (1); ++s; } @@ -217,7 +217,7 @@ pm(const char *p, const char *s, int flags) /* Main entry point. */ int -pathmatch(const char *p, const char *s, int flags) +lafe_pathmatch(const char *p, const char *s, int flags) { /* Empty pattern only matches the empty string. */ if (p == NULL || *p == '\0') diff --git a/cpio/pathmatch.h b/libarchive_fe/pathmatch.h index fd2c2575..a92f3aef 100644 --- a/cpio/pathmatch.h +++ b/libarchive_fe/pathmatch.h @@ -26,17 +26,17 @@ * $FreeBSD$ */ -#ifndef PATHMATCH_H -#define PATHMATCH_H +#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 PATHMATCH_NO_ANCHOR_END 2 /* Note that "^" and "$" are not special unless you set the corresponding * flag above. */ -int pathmatch(const char *p, const char *s, int flags); +int lafe_pathmatch(const char *p, const char *s, int flags); #endif diff --git a/tar/bsdtar.c b/tar/bsdtar.c index 665e60ac..25249e0f 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle #endif #include "bsdtar.h" +#include "err.h" /* * Per POSIX.1-1988, tar defaults to reading/writing archives to/from @@ -120,26 +121,26 @@ main(int argc, char **argv) _set_fmode(_O_BINARY); #endif - /* Need bsdtar->progname before calling bsdtar_warnc. */ + /* Need lafe_progname before calling lafe_warnc. */ if (*argv == NULL) - bsdtar->progname = "bsdtar"; + lafe_progname = "bsdtar"; else { #if defined(_WIN32) && !defined(__CYGWIN__) - bsdtar->progname = strrchr(*argv, '\\'); + lafe_progname = strrchr(*argv, '\\'); #else - bsdtar->progname = strrchr(*argv, '/'); + lafe_progname = strrchr(*argv, '/'); #endif - if (bsdtar->progname != NULL) - bsdtar->progname++; + if (lafe_progname != NULL) + lafe_progname++; else - bsdtar->progname = *argv; + lafe_progname = *argv; } time(&now); #if HAVE_SETLOCALE if (setlocale(LC_ALL, "") == NULL) - bsdtar_warnc(bsdtar, 0, "Failed to set default locale"); + lafe_warnc(0, "Failed to set default locale"); #endif #if defined(HAVE_NL_LANGINFO) && defined(HAVE_D_MD_ORDER) bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd'); @@ -188,7 +189,7 @@ main(int argc, char **argv) case 'b': /* SUSv2 */ t = atoi(bsdtar->optarg); if (t <= 0 || t > 1024) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Argument to -b is out of range (1..1024)"); bsdtar->bytes_per_block = 512 * t; break; @@ -205,8 +206,8 @@ main(int argc, char **argv) bsdtar->option_chroot = 1; break; case OPTION_EXCLUDE: /* GNU tar */ - if (exclude(bsdtar, bsdtar->optarg)) - bsdtar_errc(bsdtar, 1, 0, + if (lafe_exclude(&bsdtar->matching, bsdtar->optarg)) + lafe_errc(1, 0, "Couldn't exclude %s\n", bsdtar->optarg); break; case OPTION_FORMAT: /* GNU tar, others */ @@ -251,21 +252,21 @@ main(int argc, char **argv) * noone else needs this to filter entries * when transforming archives. */ - if (include(bsdtar, bsdtar->optarg)) - bsdtar_errc(bsdtar, 1, 0, + if (lafe_include(&bsdtar->matching, bsdtar->optarg)) + lafe_errc(1, 0, "Failed to add %s to inclusion list", bsdtar->optarg); break; case 'j': /* GNU tar */ if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; break; case 'J': /* GNU tar 1.21 and later */ if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; @@ -285,7 +286,7 @@ main(int argc, char **argv) break; case OPTION_LZMA: if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; @@ -310,7 +311,7 @@ main(int argc, char **argv) { struct stat st; if (stat(bsdtar->optarg, &st) != 0) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't open file %s", bsdtar->optarg); bsdtar->newer_ctime_sec = st.st_ctime; bsdtar->newer_ctime_nsec = @@ -324,7 +325,7 @@ main(int argc, char **argv) { struct stat st; if (stat(bsdtar->optarg, &st) != 0) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't open file %s", bsdtar->optarg); bsdtar->newer_mtime_sec = st.st_mtime; bsdtar->newer_mtime_nsec = @@ -395,7 +396,7 @@ main(int argc, char **argv) #if HAVE_REGEX_H add_substitution(bsdtar, bsdtar->optarg); #else - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "-s is not supported by this version of bsdtar"); usage(bsdtar); #endif @@ -441,8 +442,8 @@ main(int argc, char **argv) bsdtar->option_interactive = 1; break; case 'X': /* GNU tar */ - if (exclude_from_file(bsdtar, bsdtar->optarg)) - bsdtar_errc(bsdtar, 1, 0, + if (lafe_exclude_from_file(&bsdtar->matching, bsdtar->optarg)) + lafe_errc(1, 0, "failed to process exclusions from file %s", bsdtar->optarg); break; @@ -451,21 +452,21 @@ main(int argc, char **argv) break; case 'y': /* FreeBSD version of GNU tar */ if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; break; case 'Z': /* GNU tar */ if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; break; case 'z': /* GNU tar, star, many others */ if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; @@ -490,7 +491,7 @@ main(int argc, char **argv) /* Otherwise, a mode is required. */ if (bsdtar->mode == '\0') - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Must specify one of -c, -r, -t, -u, -x"); /* Check boolean options only permitted in certain modes. */ @@ -564,13 +565,13 @@ main(int argc, char **argv) break; } - cleanup_exclusions(bsdtar); + lafe_cleanup_exclusions(&bsdtar->matching); #if HAVE_REGEX_H cleanup_substitution(bsdtar); #endif if (bsdtar->return_value != 0) - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Error exit delayed from previous errors."); return (bsdtar->return_value); } @@ -579,7 +580,7 @@ static void set_mode(struct bsdtar *bsdtar, char opt) { if (bsdtar->mode != '\0' && bsdtar->mode != opt) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, bsdtar->mode); bsdtar->mode = opt; } @@ -591,7 +592,7 @@ static void only_mode(struct bsdtar *bsdtar, const char *opt, const char *valid_modes) { if (strchr(valid_modes, bsdtar->mode) == NULL) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Option %s is not permitted in mode -%c", opt, bsdtar->mode); } @@ -602,7 +603,7 @@ usage(struct bsdtar *bsdtar) { const char *p; - p = bsdtar->progname; + p = lafe_progname; fprintf(stderr, "Usage:\n"); fprintf(stderr, " List: %s -tf <archive-filename>\n", p); @@ -662,7 +663,7 @@ long_help(struct bsdtar *bsdtar) const char *prog; const char *p; - prog = bsdtar->progname; + prog = lafe_progname; fflush(stderr); diff --git a/tar/bsdtar.h b/tar/bsdtar.h index 26fe0d3f..5ca76ccf 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -28,6 +28,8 @@ #include "bsdtar_platform.h" #include <stdio.h> +#include "matching.h" + #define DEFAULT_BYTES_PER_BLOCK (20*512) /* @@ -78,7 +80,6 @@ struct bsdtar { /* Miscellaneous state information */ struct archive *archive; - const char *progname; int argc; char **argv; const char *optarg; @@ -98,7 +99,7 @@ struct bsdtar { struct archive_dir *archive_dir; /* for write.c */ struct name_cache *gname_cache; /* for write.c */ char *buff; /* for write.c */ - struct matching *matching; /* for matching.c */ + struct lafe_matching *matching; /* for matching.c */ struct security *security; /* for read.c */ struct name_cache *uname_cache; /* for write.c */ struct siginfo_data *siginfo; /* for siginfo.c */ @@ -135,21 +136,10 @@ enum { }; -void bsdtar_errc(struct bsdtar *, int _eval, int _code, - const char *fmt, ...) __LA_DEAD; int bsdtar_getopt(struct bsdtar *); -void bsdtar_warnc(struct bsdtar *, int _code, const char *fmt, ...); -void cleanup_exclusions(struct bsdtar *); void do_chdir(struct bsdtar *); int edit_pathname(struct bsdtar *, struct archive_entry *); -int exclude(struct bsdtar *, const char *pattern); -int exclude_from_file(struct bsdtar *, const char *pathname); -int excluded(struct bsdtar *, const char *pathname); -int include(struct bsdtar *, const char *pattern); -int include_from_file(struct bsdtar *, const char *pathname); int pathcmp(const char *a, const char *b); -int process_lines(struct bsdtar *bsdtar, const char *pathname, - int (*process)(struct bsdtar *, const char *)); void safe_fprintf(FILE *, const char *fmt, ...); void set_chdir(struct bsdtar *, const char *newdir); void siginfo_init(struct bsdtar *); @@ -162,8 +152,6 @@ void tar_mode_r(struct bsdtar *bsdtar); void tar_mode_t(struct bsdtar *bsdtar); void tar_mode_u(struct bsdtar *bsdtar); void tar_mode_x(struct bsdtar *bsdtar); -int unmatched_inclusions(struct bsdtar *bsdtar); -int unmatched_inclusions_warn(struct bsdtar *bsdtar, const char *msg); void usage(struct bsdtar *); int yes(const char *fmt, ...); diff --git a/tar/bsdtar_cygwin.c b/tar/bsdtar_cygwin.c index d31f1122..72dc9574 100644 --- a/tar/bsdtar_cygwin.c +++ b/tar/bsdtar_cygwin.c @@ -41,6 +41,7 @@ #include <sddl.h> #include "bsdtar.h" +#include "err.h" #ifndef LIST_H static int @@ -124,12 +125,12 @@ bsdtar_is_privileged(struct bsdtar *bsdtar) (void)bsdtar;/* UNUSED */ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &thandle) == 0) { - bsdtar_warnc(bsdtar, EPERM, "Failed to check privilege"); + lafe_warnc(EPERM, "Failed to check privilege"); return (0); } ret = _is_privileged(thandle, sidlist); if (ret < 0) { - bsdtar_warnc(bsdtar, errno, "Failed to check privilege"); + lafe_warnc(errno, "Failed to check privilege"); return (0); } return (ret); diff --git a/tar/bsdtar_windows.c b/tar/bsdtar_windows.c index c4e77b45..4a39446e 100644 --- a/tar/bsdtar_windows.c +++ b/tar/bsdtar_windows.c @@ -41,6 +41,7 @@ #include <sddl.h> #include "bsdtar.h" +#include "err.h" #define EPOC_TIME (116444736000000000ULL) @@ -1112,12 +1113,12 @@ bsdtar_is_privileged(struct bsdtar *bsdtar) (void)bsdtar;/* UNUSED */ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &thandle) == 0) { - bsdtar_warnc(bsdtar, EPERM, "Failed to check privilege"); + lafe_warnc(EPERM, "Failed to check privilege"); return (0); } ret = _is_privileged(thandle, sidlist); if (ret < 0) { - bsdtar_warnc(bsdtar, errno, "Failed to check privilege"); + lafe_warnc(errno, "Failed to check privilege"); return (0); } return (ret); diff --git a/tar/cmdline.c b/tar/cmdline.c index efaeafdc..ba3e8a1b 100644 --- a/tar/cmdline.c +++ b/tar/cmdline.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #endif #include "bsdtar.h" +#include "err.h" /* * Short options for tar. Please keep this sorted. @@ -220,7 +221,7 @@ bsdtar_getopt(struct bsdtar *bsdtar) if (p[1] == ':') { bsdtar->optarg = *bsdtar->argv; if (bsdtar->optarg == NULL) { - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Option %c requires an argument", opt); return ('?'); @@ -287,7 +288,7 @@ bsdtar_getopt(struct bsdtar *bsdtar) /* Otherwise, pick up the next word. */ opt_word = *bsdtar->argv; if (opt_word == NULL) { - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Option -%c requires an argument", opt); return ('?'); @@ -338,13 +339,13 @@ bsdtar_getopt(struct bsdtar *bsdtar) /* Fail if there wasn't a unique match. */ if (match == NULL) { - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Option %s%s is not supported", long_prefix, opt_word); return ('?'); } if (match2 != NULL) { - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Ambiguous option %s%s (matches --%s and --%s)", long_prefix, opt_word, match->name, match2->name); return ('?'); @@ -356,7 +357,7 @@ bsdtar_getopt(struct bsdtar *bsdtar) if (bsdtar->optarg == NULL) { bsdtar->optarg = *bsdtar->argv; if (bsdtar->optarg == NULL) { - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Option %s%s requires an argument", long_prefix, match->name); return ('?'); @@ -367,7 +368,7 @@ bsdtar_getopt(struct bsdtar *bsdtar) } else { /* Argument forbidden: fail if there is one. */ if (bsdtar->optarg != NULL) { - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Option %s%s does not allow an argument", long_prefix, match->name); return ('?'); diff --git a/tar/matching.c b/tar/matching.c deleted file mode 100644 index acc60dba..00000000 --- a/tar/matching.c +++ /dev/null @@ -1,478 +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 "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/matching.c,v 1.16 2008/08/18 18:13:40 kientzle Exp $"); - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include "bsdtar.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 bsdtar *, struct match **list, - const char *pattern); -static int bsdtar_fnmatch(const char *p, const char *s); -static void initialize_matching(struct bsdtar *); -static int match_exclusion(struct match *, const char *pathname); -static int match_inclusion(struct match *, const char *pathname); -static int pathmatch(const char *p, const char *s); - -/* - * 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 bsdtar *bsdtar, const char *pattern) -{ - struct matching *matching; - - if (bsdtar->matching == NULL) - initialize_matching(bsdtar); - matching = bsdtar->matching; - add_pattern(bsdtar, &(matching->exclusions), pattern); - matching->exclusions_count++; - return (0); -} - -int -exclude_from_file(struct bsdtar *bsdtar, const char *pathname) -{ - return (process_lines(bsdtar, pathname, &exclude)); -} - -int -include(struct bsdtar *bsdtar, const char *pattern) -{ - struct matching *matching; - - if (bsdtar->matching == NULL) - initialize_matching(bsdtar); - matching = bsdtar->matching; - add_pattern(bsdtar, &(matching->inclusions), pattern); - matching->inclusions_count++; - matching->inclusions_unmatched_count++; - return (0); -} - -int -include_from_file(struct bsdtar *bsdtar, const char *pathname) -{ - return (process_lines(bsdtar, pathname, &include)); -} - -static void -add_pattern(struct bsdtar *bsdtar, struct match **list, const char *pattern) -{ - struct match *match; - - match = malloc(sizeof(*match) + strlen(pattern) + 1); - if (match == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); - strcpy(match->pattern, pattern); - /* Both "foo/" and "foo" should match "foo/bar". */ - if (match->pattern[strlen(match->pattern)-1] == '/') - match->pattern[strlen(match->pattern)-1] = '\0'; - match->next = *list; - *list = match; - match->matches = 0; -} - - -int -excluded(struct bsdtar *bsdtar, const char *pathname) -{ - struct matching *matching; - struct match *match; - struct match *matched; - - matching = bsdtar->matching; - if (matching == NULL) - return (0); - - /* Exclusions take priority */ - for (match = matching->exclusions; match != NULL; match = match->next){ - if (match_exclusion(match, pathname)) - return (1); - } - - /* Then check for inclusions */ - matched = NULL; - for (match = matching->inclusions; match != NULL; match = match->next){ - if (match_inclusion(match, pathname)) { - /* - * If this pattern has never been matched, - * then we're done. - */ - if (match->matches == 0) { - match->matches++; - matching->inclusions_unmatched_count--; - return (0); - } - /* - * Otherwise, remember the match but keep checking - * in case we can tick off an unmatched pattern. - */ - matched = match; - } - } - /* - * We didn't find a pattern that had never been matched, but - * we did find a match, so count it and exit. - */ - if (matched != NULL) { - matched->matches++; - return (0); - } - - /* If there were inclusions, default is to exclude. */ - if (matching->inclusions != NULL) - return (1); - - /* No explicit inclusions, default is to match. */ - return (0); -} - -/* - * This is a little odd, but it matches the default behavior of - * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar' - * - */ -static int -match_exclusion(struct match *match, const char *pathname) -{ - const char *p; - - if (*match->pattern == '*' || *match->pattern == '/') - return (pathmatch(match->pattern, pathname) == 0); - - for (p = pathname; p != NULL; p = strchr(p, '/')) { - if (*p == '/') - p++; - if (pathmatch(match->pattern, p) == 0) - return (1); - } - return (0); -} - -/* - * Again, mimic gtar: inclusions are always anchored (have to match - * the beginning of the path) even though exclusions are not anchored. - */ -int -match_inclusion(struct match *match, const char *pathname) -{ - return (pathmatch(match->pattern, pathname) == 0); -} - -void -cleanup_exclusions(struct bsdtar *bsdtar) -{ - struct match *p, *q; - - if (bsdtar->matching) { - p = bsdtar->matching->inclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - p = bsdtar->matching->exclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - free(bsdtar->matching); - } -} - -static void -initialize_matching(struct bsdtar *bsdtar) -{ - bsdtar->matching = malloc(sizeof(*bsdtar->matching)); - if (bsdtar->matching == NULL) - bsdtar_errc(bsdtar, 1, errno, "No memory"); - memset(bsdtar->matching, 0, sizeof(*bsdtar->matching)); -} - -int -unmatched_inclusions(struct bsdtar *bsdtar) -{ - struct matching *matching; - - matching = bsdtar->matching; - if (matching == NULL) - return (0); - return (matching->inclusions_unmatched_count); -} - - -int -unmatched_inclusions_warn(struct bsdtar *bsdtar, const char *msg) -{ - struct matching *matching; - struct match *p; - - matching = bsdtar->matching; - if (matching == NULL) - return (0); - - p = matching->inclusions; - while (p != NULL) { - if (p->matches == 0) { - bsdtar->return_value = 1; - bsdtar_warnc(bsdtar, 0, "%s: %s", - p->pattern, msg); - } - p = p->next; - } - return (matching->inclusions_unmatched_count); -} - -/* - * TODO: Extend this so that the following matches work: - * "foo//bar" == "foo/bar" - * "foo/./bar" == "foo/bar" - * "./foo" == "foo" - * - * The POSIX fnmatch() function doesn't handle any of these, but - * all are common situations that arise when paths are generated within - * large scripts. E.g., the following is quite common: - * MYPATH=foo/ TARGET=$MYPATH/bar - * It may be worthwhile to edit such paths at write time as well, - * especially when such editing may avoid the need for long pathname - * extensions. - */ -static int -pathmatch(const char *pattern, const char *string) -{ - /* - * Strip leading "./" or ".//" so that, e.g., - * "foo" matches "./foo". In particular, this - * opens up an optimization for the writer to - * elide leading "./". - */ - if (pattern[0] == '.' && pattern[1] == '/') { - pattern += 2; - while (pattern[0] == '/') - ++pattern; - } - if (string[0] == '.' && string[1] == '/') { - string += 2; - while (string[0] == '/') - ++string; - } - return (bsdtar_fnmatch(pattern, string)); -} - - -#if defined(HAVE_FNMATCH) && defined(HAVE_FNM_LEADING_DIR) - -/* Use system fnmatch() if it suits our needs. */ -/* On Linux, _GNU_SOURCE must be defined to get FNM_LEADING_DIR. */ -#define _GNU_SOURCE -#include <fnmatch.h> -static int -bsdtar_fnmatch(const char *pattern, const char *string) -{ - return (fnmatch(pattern, string, FNM_LEADING_DIR)); -} - -#else -/* - * The following was hacked from BSD C library - * code: src/lib/libc/gen/fnmatch.c,v 1.15 2002/02/01 - * - * In particular, most of the flags were ripped out: this always - * behaves like FNM_LEADING_DIR is set and other flags specified - * by POSIX are unset. - * - * Normally, I would not conditionally compile something like this: If - * I have to support it anyway, everyone may as well use it. ;-) - * However, the full POSIX spec for fnmatch() includes a lot of - * advanced character handling that I'm not ready to put in here, so - * it's probably best if people use a local version when it's available. - */ - -/* - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * 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. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -static int -bsdtar_fnmatch(const char *pattern, const char *string) -{ - const char *saved_pattern; - int negate, matched; - char c; - - for (;;) { - switch (c = *pattern++) { - case '\0': - if (*string == '/' || *string == '\0') - return (0); - return (1); - case '?': - if (*string == '\0') - return (1); - ++string; - break; - case '*': - c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') - c = *++pattern; - - /* Optimize for pattern with * at end. */ - if (c == '\0') - return (0); - - /* General case, use recursion. */ - while (*string != '\0') { - if (!bsdtar_fnmatch(pattern, string)) - return (0); - ++string; - } - return (1); - case '[': - if (*string == '\0') - return (1); - saved_pattern = pattern; - if (*pattern == '!' || *pattern == '^') { - negate = 1; - ++pattern; - } else - negate = 0; - matched = 0; - c = *pattern++; - do { - if (c == '\\') - c = *pattern++; - if (c == '\0') { - pattern = saved_pattern; - c = '['; - goto norm; - } - if (*pattern == '-') { - char c2 = *(pattern + 1); - if (c2 == '\0') { - pattern = saved_pattern; - c = '['; - goto norm; - } - if (c2 == ']') { - /* [a-] is not a range. */ - if (c == *string - || '-' == *string) - matched = 1; - pattern ++; - } else { - if (c <= *string - && *string <= c2) - matched = 1; - pattern += 2; - } - } else if (c == *string) - matched = 1; - c = *pattern++; - } while (c != ']'); - if (matched == negate) - return (1); - ++string; - break; - case '\\': - if ((c = *pattern++) == '\0') { - c = '\\'; - --pattern; - } - /* FALLTHROUGH */ - default: - norm: - if (c != *string) - return (1); - string++; - break; - } - } - /* NOTREACHED */ -} - -#endif @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.40 2008/08/21 06:41:14 kientzle E #endif #include "bsdtar.h" +#include "err.h" static void list_item_verbose(struct bsdtar *, FILE *, struct archive_entry *); @@ -77,7 +78,8 @@ void tar_mode_t(struct bsdtar *bsdtar) { read_archive(bsdtar, 't'); - unmatched_inclusions_warn(bsdtar, "Not found in archive"); + if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0) + bsdtar->return_value = 1; } void @@ -88,7 +90,8 @@ tar_mode_x(struct bsdtar *bsdtar) read_archive(bsdtar, 'x'); - unmatched_inclusions_warn(bsdtar, "Not found in archive"); + if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0) + bsdtar->return_value = 1; /* Restore old SIGINFO + SIGUSR1 handlers. */ siginfo_done(bsdtar); } @@ -114,12 +117,12 @@ read_archive(struct bsdtar *bsdtar, char mode) int r; while (*bsdtar->argv) { - include(bsdtar, *bsdtar->argv); + lafe_include(&bsdtar->matching, *bsdtar->argv); bsdtar->argv++; } if (bsdtar->names_from_file != NULL) - include_from_file(bsdtar, bsdtar->names_from_file); + lafe_include_from_file(&bsdtar->matching, bsdtar->names_from_file); a = archive_read_new(); if (bsdtar->compress_program != NULL) @@ -128,11 +131,11 @@ read_archive(struct bsdtar *bsdtar, char mode) archive_read_support_compression_all(a); archive_read_support_format_all(a); if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : DEFAULT_BYTES_PER_BLOCK)) - bsdtar_errc(bsdtar, 1, 0, "Error opening archive: %s", + lafe_errc(1, 0, "Error opening archive: %s", archive_error_string(a)); do_chdir(bsdtar); @@ -146,9 +149,9 @@ read_archive(struct bsdtar *bsdtar, char mode) if (mode == 'x' && bsdtar->option_chroot) { #if HAVE_CHROOT if (chroot(".") != 0) - bsdtar_errc(bsdtar, 1, errno, "Can't chroot to \".\""); + lafe_errc(1, errno, "Can't chroot to \".\""); #else - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "chroot isn't supported on this platform"); #endif } @@ -156,19 +159,19 @@ read_archive(struct bsdtar *bsdtar, char mode) for (;;) { /* Support --fast-read option */ if (bsdtar->option_fast_read && - unmatched_inclusions(bsdtar) == 0) + lafe_unmatched_inclusions(bsdtar->matching) == 0) break; r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); + lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (r == ARCHIVE_RETRY) { /* Retryable error: try again */ - bsdtar_warnc(bsdtar, 0, "Retrying..."); + lafe_warnc(0, "Retrying..."); continue; } if (r == ARCHIVE_FATAL) @@ -209,7 +212,7 @@ read_archive(struct bsdtar *bsdtar, char mode) * rewrite, there would be no way to exclude foo1/bar * while allowing foo2/bar.) */ - if (excluded(bsdtar, archive_entry_pathname(entry))) + if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry))) continue; /* Excluded by a pattern test. */ if (mode == 't') { @@ -232,17 +235,17 @@ read_archive(struct bsdtar *bsdtar, char mode) r = archive_read_data_skip(a); if (r == ARCHIVE_WARN) { fprintf(out, "\n"); - bsdtar_warnc(bsdtar, 0, "%s", + lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_RETRY) { fprintf(out, "\n"); - bsdtar_warnc(bsdtar, 0, "%s", + lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) { fprintf(out, "\n"); - bsdtar_warnc(bsdtar, 0, "%s", + lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; break; @@ -297,7 +300,7 @@ read_archive(struct bsdtar *bsdtar, char mode) r = archive_read_close(a); if (r != ARCHIVE_OK) - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); + lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; diff --git a/tar/siginfo.c b/tar/siginfo.c index 5f28e230..8ecdaa7e 100644 --- a/tar/siginfo.c +++ b/tar/siginfo.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/siginfo.c,v 1.2 2008/05/22 21:08:36 cperciva #include <string.h> #include "bsdtar.h" +#include "err.h" /* Is there a pending SIGINFO or SIGUSR1? */ static volatile sig_atomic_t siginfo_received = 0; @@ -73,7 +74,7 @@ siginfo_init(struct bsdtar *bsdtar) /* Allocate space for internal structure. */ if ((bsdtar->siginfo = malloc(sizeof(struct siginfo_data))) == NULL) - bsdtar_errc(bsdtar, 1, errno, "malloc failed"); + lafe_errc(1, errno, "malloc failed"); /* Set the strings to NULL so that free() is safe. */ bsdtar->siginfo->path = bsdtar->siginfo->oper = NULL; @@ -99,9 +100,9 @@ siginfo_setinfo(struct bsdtar *bsdtar, const char * oper, const char * path, /* Duplicate strings and store entry size. */ if ((bsdtar->siginfo->oper = strdup(oper)) == NULL) - bsdtar_errc(bsdtar, 1, errno, "Cannot strdup"); + lafe_errc(1, errno, "Cannot strdup"); if ((bsdtar->siginfo->path = strdup(path)) == NULL) - bsdtar_errc(bsdtar, 1, errno, "Cannot strdup"); + lafe_errc(1, errno, "Cannot strdup"); bsdtar->siginfo->size = size; } diff --git a/tar/subst.c b/tar/subst.c index 9e864984..08fc705d 100644 --- a/tar/subst.c +++ b/tar/subst.c @@ -38,6 +38,8 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/subst.c,v 1.4 2008/06/15 10:08:16 kientzle E #define REG_BASIC 0 #endif +#include "err.h" + struct subst_rule { struct subst_rule *next; regex_t re; @@ -56,7 +58,7 @@ init_substitution(struct bsdtar *bsdtar) bsdtar->substitution = subst = malloc(sizeof(*subst)); if (subst == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); subst->first_rule = subst->last_rule = NULL; } @@ -76,7 +78,7 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text) rule = malloc(sizeof(*rule)); if (rule == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); rule->next = NULL; if (subst->last_rule == NULL) @@ -86,32 +88,32 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text) subst->last_rule = rule; if (*rule_text == '\0') - bsdtar_errc(bsdtar, 1, 0, "Empty replacement string"); + lafe_errc(1, 0, "Empty replacement string"); end_pattern = strchr(rule_text + 1, *rule_text); if (end_pattern == NULL) - bsdtar_errc(bsdtar, 1, 0, "Invalid replacement string"); + lafe_errc(1, 0, "Invalid replacement string"); pattern = malloc(end_pattern - rule_text); if (pattern == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); memcpy(pattern, rule_text + 1, end_pattern - rule_text - 1); pattern[end_pattern - rule_text - 1] = '\0'; if ((r = regcomp(&rule->re, pattern, REG_BASIC)) != 0) { char buf[80]; regerror(r, &rule->re, buf, sizeof(buf)); - bsdtar_errc(bsdtar, 1, 0, "Invalid regular expression: %s", buf); + lafe_errc(1, 0, "Invalid regular expression: %s", buf); } free(pattern); start_subst = end_pattern + 1; end_pattern = strchr(start_subst, *rule_text); if (end_pattern == NULL) - bsdtar_errc(bsdtar, 1, 0, "Invalid replacement string"); + lafe_errc(1, 0, "Invalid replacement string"); rule->result = malloc(end_pattern - start_subst + 1); if (rule->result == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); memcpy(rule->result, start_subst, end_pattern - start_subst); rule->result[end_pattern - start_subst] = '\0'; @@ -134,7 +136,7 @@ add_substitution(struct bsdtar *bsdtar, const char *rule_text) rule->symlink = 1; break; default: - bsdtar_errc(bsdtar, 1, 0, "Invalid replacement flag %c", *end_pattern); + lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern); } } } @@ -152,7 +154,7 @@ realloc_strncat(struct bsdtar *bsdtar, char **str, const char *append, size_t le new_str = malloc(old_len + len + 1); if (new_str == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); memcpy(new_str, *str, old_len); memcpy(new_str + old_len, append, len); new_str[old_len + len] = '\0'; @@ -173,7 +175,7 @@ realloc_strcat(struct bsdtar *bsdtar, char **str, const char *append) new_str = malloc(old_len + strlen(append) + 1); if (new_str == NULL) - bsdtar_errc(bsdtar, 1, errno, "Out of memory"); + lafe_errc(1, errno, "Out of memory"); memcpy(new_str, *str, old_len); strcpy(new_str + old_len, append); free(*str); @@ -54,9 +54,8 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/util.c,v 1.23 2008/12/15 06:00:25 kientzle E #endif #include "bsdtar.h" +#include "err.h" -static void bsdtar_vwarnc(struct bsdtar *, int code, - const char *fmt, va_list ap); static size_t bsdtar_expand_char(char *, size_t, char); static const char *strip_components(const char *path, int elements); @@ -202,37 +201,6 @@ bsdtar_expand_char(char *buff, size_t offset, char c) return (i - offset); } -static void -bsdtar_vwarnc(struct bsdtar *bsdtar, int code, const char *fmt, va_list ap) -{ - fprintf(stderr, "%s: ", bsdtar->progname); - vfprintf(stderr, fmt, ap); - if (code != 0) - fprintf(stderr, ": %s", strerror(code)); - fprintf(stderr, "\n"); -} - -void -bsdtar_warnc(struct bsdtar *bsdtar, int code, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - bsdtar_vwarnc(bsdtar, code, fmt, ap); - va_end(ap); -} - -void -bsdtar_errc(struct bsdtar *bsdtar, int eval, int code, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - bsdtar_vwarnc(bsdtar, code, fmt, ap); - va_end(ap); - exit(eval); -} - int yes(const char *fmt, ...) { @@ -268,95 +236,6 @@ yes(const char *fmt, ...) return (0); } -/* - * 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. - * If the "process" function returns non-zero for any line, this - * function will return non-zero after attempting to process all - * remaining lines. - */ -int -process_lines(struct bsdtar *bsdtar, const char *pathname, - int (*process)(struct bsdtar *, const char *)) -{ - FILE *f; - char *buff, *buff_end, *line_start, *line_end, *p; - size_t buff_length, new_buff_length, bytes_read, bytes_wanted; - int separator; - int ret; - - separator = bsdtar->option_null ? '\0' : '\n'; - ret = 0; - - if (strcmp(pathname, "-") == 0) - f = stdin; - else - f = fopen(pathname, "r"); - if (f == NULL) - bsdtar_errc(bsdtar, 1, errno, "Couldn't open %s", pathname); - buff_length = 8192; - buff = malloc(buff_length); - if (buff == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read %s", pathname); - line_start = line_end = buff_end = buff; - for (;;) { - /* Get some more data into the buffer. */ - bytes_wanted = buff + buff_length - buff_end; - bytes_read = fread(buff_end, 1, bytes_wanted, f); - buff_end += bytes_read; - /* Process all complete lines in the buffer. */ - while (line_end < buff_end) { - if (*line_end == separator) { - *line_end = '\0'; - if ((*process)(bsdtar, line_start) != 0) - ret = -1; - line_start = line_end + 1; - line_end = line_start; - } else - line_end++; - } - if (feof(f)) - break; - if (ferror(f)) - bsdtar_errc(bsdtar, 1, errno, - "Can't read %s", pathname); - if (line_start > buff) { - /* Move a leftover fractional line to the beginning. */ - memmove(buff, line_start, buff_end - line_start); - buff_end -= line_start - buff; - line_end -= line_start - buff; - line_start = buff; - } else { - /* Line is too big; enlarge the buffer. */ - new_buff_length = buff_length * 2; - if (new_buff_length <= buff_length) - bsdtar_errc(bsdtar, 1, ENOMEM, - "Line too long in %s", pathname); - buff_length = new_buff_length; - p = realloc(buff, buff_length); - if (p == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, - "Line too long in %s", pathname); - buff_end = p + (buff_end - buff); - line_end = p + (line_end - buff); - line_start = buff = p; - } - } - /* At end-of-file, handle the final line. */ - if (line_end > line_start) { - *line_end = '\0'; - if ((*process)(bsdtar, line_start) != 0) - ret = -1; - } - free(buff); - if (f != stdin) - fclose(f); - return (ret); -} - /*- * The logic here for -C <dir> attempts to avoid * chdir() as long as possible. For example: @@ -398,7 +277,7 @@ set_chdir(struct bsdtar *bsdtar, const char *newdir) free(old_pending); } if (bsdtar->pending_chdir == NULL) - bsdtar_errc(bsdtar, 1, errno, "No memory"); + lafe_errc(1, errno, "No memory"); } void @@ -408,7 +287,7 @@ do_chdir(struct bsdtar *bsdtar) return; if (chdir(bsdtar->pending_chdir) != 0) { - bsdtar_errc(bsdtar, 1, 0, "could not chdir to '%s'\n", + lafe_errc(1, 0, "could not chdir to '%s'\n", bsdtar->pending_chdir); } free(bsdtar->pending_chdir); @@ -458,7 +337,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry) #if HAVE_REGEX_H r = apply_substitution(bsdtar, name, &subst_name, 0); if (r == -1) { - bsdtar_warnc(bsdtar, 0, "Invalid substitution, skipping entry"); + lafe_warnc(0, "Invalid substitution, skipping entry"); return 1; } if (r == 1) { @@ -474,7 +353,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry) if (archive_entry_hardlink(entry)) { r = apply_substitution(bsdtar, archive_entry_hardlink(entry), &subst_name, 1); if (r == -1) { - bsdtar_warnc(bsdtar, 0, "Invalid substitution, skipping entry"); + lafe_warnc(0, "Invalid substitution, skipping entry"); return 1; } if (r == 1) { @@ -485,7 +364,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry) if (archive_entry_symlink(entry) != NULL) { r = apply_substitution(bsdtar, archive_entry_symlink(entry), &subst_name, 1); if (r == -1) { - bsdtar_warnc(bsdtar, 0, "Invalid substitution, skipping entry"); + lafe_warnc(0, "Invalid substitution, skipping entry"); return 1; } if (r == 1) { @@ -559,11 +438,11 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry) if (p != name && !bsdtar->warned_lead_slash) { /* Generate a warning the first time this happens. */ if (slashonly) - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Removing leading '%c' from member names", name[0]); else - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "Removing leading drive letter from " "member names"); bsdtar->warned_lead_slash = 1; diff --git a/tar/write.c b/tar/write.c index 3ed846e8..8bcbff4c 100644 --- a/tar/write.c +++ b/tar/write.c @@ -82,6 +82,8 @@ __FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.79 2008/11/27 05:49:52 kientzle #endif #include "bsdtar.h" +#include "err.h" +#include "line_reader.h" #include "tree.h" /* Size of buffer for holding file data prior to writing. */ @@ -121,8 +123,6 @@ static int append_archive_filename(struct bsdtar *, struct archive *, const char *fname); static void archive_names_from_file(struct bsdtar *bsdtar, struct archive *a); -static int archive_names_from_file_helper(struct bsdtar *bsdtar, - const char *line); static int copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina); static int new_enough(struct bsdtar *, const char *path, @@ -143,7 +143,7 @@ tar_mode_c(struct bsdtar *bsdtar) int r; if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); + lafe_errc(1, 0, "no files or directories specified"); a = archive_write_new(); @@ -197,21 +197,21 @@ tar_mode_c(struct bsdtar *bsdtar) r = archive_write_set_compression_compress(a); break; default: - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Unrecognized compression option -%c", bsdtar->create_compression); } if (r != ARCHIVE_OK) { - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Unsupported compression option -%c", bsdtar->create_compression); } } if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_file(a, bsdtar->filename)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); write_archive(a, bsdtar); } @@ -235,7 +235,7 @@ tar_mode_r(struct bsdtar *bsdtar) bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666); if (bsdtar->fd < 0) - bsdtar_errc(bsdtar, 1, errno, + lafe_errc(1, errno, "Cannot open %s", bsdtar->filename); a = archive_read_new(); @@ -244,14 +244,14 @@ tar_mode_r(struct bsdtar *bsdtar) archive_read_support_format_gnutar(a); r = archive_read_open_fd(a, bsdtar->fd, 10240); if (r != ARCHIVE_OK) - bsdtar_errc(bsdtar, 1, archive_errno(a), + lafe_errc(1, archive_errno(a), "Can't read archive %s: %s", bsdtar->filename, archive_error_string(a)); while (0 == archive_read_next_header(a, &entry)) { if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_finish(a); close(bsdtar->fd); - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Cannot append to compressed archive."); } /* Keep going until we hit end-of-archive */ @@ -280,7 +280,7 @@ tar_mode_r(struct bsdtar *bsdtar) format &= ARCHIVE_FORMAT_BASE_MASK; if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK) && format != ARCHIVE_FORMAT_EMPTY) { - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Format %s is incompatible with the archive %s.", bsdtar->create_format, bsdtar->filename); } @@ -298,9 +298,9 @@ tar_mode_r(struct bsdtar *bsdtar) } lseek(bsdtar->fd, end_offset, SEEK_SET); /* XXX check return val XXX */ if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); write_archive(a, bsdtar); /* XXX check return val XXX */ @@ -328,7 +328,7 @@ tar_mode_u(struct bsdtar *bsdtar) bsdtar->fd = open(bsdtar->filename, O_RDWR); if (bsdtar->fd < 0) - bsdtar_errc(bsdtar, 1, errno, + lafe_errc(1, errno, "Cannot open %s", bsdtar->filename); a = archive_read_new(); @@ -338,7 +338,7 @@ tar_mode_u(struct bsdtar *bsdtar) if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Can't open %s: %s", bsdtar->filename, archive_error_string(a)); } @@ -348,7 +348,7 @@ tar_mode_u(struct bsdtar *bsdtar) if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_finish(a); close(bsdtar->fd); - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Cannot append to compressed archive."); } add_dir_list(bsdtar, archive_entry_pathname(entry), @@ -379,13 +379,13 @@ tar_mode_u(struct bsdtar *bsdtar) } else archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK); if (0 != lseek(bsdtar->fd, end_offset, SEEK_SET)) - bsdtar_errc(bsdtar, 1, 0, "Could not seek to archive end"); + lafe_errc(1, 0, "Could not seek to archive end"); if (0 != ftruncate(bsdtar->fd, end_offset)) - bsdtar_errc(bsdtar, 1, 0, "Could not truncate archive"); + lafe_errc(1, 0, "Could not truncate archive"); if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) - bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); + lafe_errc(1, 0, archive_error_string(a)); write_archive(a, bsdtar); @@ -416,14 +416,14 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL) - bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory"); + lafe_errc(1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) - bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); + lafe_errc(1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) - bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object"); + lafe_errc(1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) @@ -437,7 +437,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { - bsdtar_warnc(bsdtar, 1, 0, + lafe_warnc(1, 0, "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; @@ -472,7 +472,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) } if (archive_write_close(a)) { - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); + lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } @@ -505,33 +505,33 @@ cleanup: void archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) { + struct lafe_line_reader *lr; + const char *line; + bsdtar->archive = a; bsdtar->next_line_is_dir = 0; - process_lines(bsdtar, bsdtar->names_from_file, - archive_names_from_file_helper); + + lr = lafe_line_reader(bsdtar->names_from_file, '\n'); + while ((line = lafe_line_reader_next(lr)) != NULL) { + if (bsdtar->next_line_is_dir) { + set_chdir(bsdtar, line); + bsdtar->next_line_is_dir = 0; + } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) + bsdtar->next_line_is_dir = 1; + else { + if (*line != '/') + do_chdir(bsdtar); /* Handle a deferred -C */ + write_hierarchy(bsdtar, bsdtar->archive, line); + } + } + lafe_line_reader_free(lr); if (bsdtar->next_line_is_dir) - bsdtar_errc(bsdtar, 1, errno, + lafe_errc(1, errno, "Unexpected end of filename list; " "directory expected after -C"); } -static int -archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line) -{ - if (bsdtar->next_line_is_dir) { - set_chdir(bsdtar, line); - bsdtar->next_line_is_dir = 0; - } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) - bsdtar->next_line_is_dir = 1; - else { - if (*line != '/') - do_chdir(bsdtar); /* Handle a deferred -C */ - write_hierarchy(bsdtar, bsdtar->archive, line); - } - return (0); -} - /* * Copy from specified archive to current archive. Returns non-zero * for write errors (which force us to terminate the entire archiving @@ -553,7 +553,7 @@ append_archive_filename(struct bsdtar *bsdtar, struct archive *a, archive_read_support_format_all(ina); archive_read_support_compression_all(ina); if (archive_read_open_file(ina, filename, 10240)) { - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(ina)); + lafe_warnc(0, "%s", archive_error_string(ina)); bsdtar->return_value = 1; return (0); } @@ -561,7 +561,7 @@ append_archive_filename(struct bsdtar *bsdtar, struct archive *a, rc = append_archive(bsdtar, a, ina); if (archive_errno(ina)) { - bsdtar_warnc(bsdtar, 0, "Error reading archive %s: %s", + lafe_warnc(0, "Error reading archive %s: %s", filename, archive_error_string(ina)); bsdtar->return_value = 1; } @@ -580,7 +580,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) if (!new_enough(bsdtar, archive_entry_pathname(in_entry), archive_entry_stat(in_entry))) continue; - if (excluded(bsdtar, archive_entry_pathname(in_entry))) + if (lafe_excluded(bsdtar->matching, archive_entry_pathname(in_entry))) continue; if (bsdtar->option_interactive && !yes("copy '%s'", archive_entry_pathname(in_entry))) @@ -596,7 +596,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) e = archive_write_header(a, in_entry); if (e != ARCHIVE_OK) { if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, 0, "%s: %s", + lafe_warnc(0, "%s: %s", archive_entry_pathname(in_entry), archive_error_string(a)); else @@ -635,7 +635,7 @@ copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) bytes_written = archive_write_data(a, bsdtar->buff, bytes_read); if (bytes_written < bytes_read) { - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); + lafe_warnc(0, "%s", archive_error_string(a)); return (-1); } progress += bytes_written; @@ -662,7 +662,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) tree = tree_open(path); if (!tree) { - bsdtar_warnc(bsdtar, errno, "%s: Cannot open", path); + lafe_warnc(errno, "%s: Cannot open", path); bsdtar->return_value = 1; return; } @@ -675,11 +675,11 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) int descend; if (tree_ret == TREE_ERROR_FATAL) - bsdtar_errc(bsdtar, 1, tree_errno(tree), + lafe_errc(1, tree_errno(tree), "%s: Unable to continue traversing directory tree", name); if (tree_ret == TREE_ERROR_DIR) { - bsdtar_warnc(bsdtar, errno, + lafe_warnc(errno, "%s: Couldn't visit directory", name); bsdtar->return_value = 1; } @@ -690,7 +690,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) * If this file/dir is excluded by a filename * pattern, skip it. */ - if (excluded(bsdtar, name)) + if (lafe_excluded(bsdtar->matching, name)) continue; /* @@ -699,7 +699,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) lst = tree_current_lstat(tree); if (lst == NULL) { /* Couldn't lstat(); must not exist. */ - bsdtar_warnc(bsdtar, errno, "%s: Cannot stat", name); + lafe_warnc(errno, "%s: Cannot stat", name); /* Return error if files disappear during traverse. */ bsdtar->return_value = 1; continue; @@ -793,7 +793,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) r = archive_read_disk_entry_from_file(bsdtar->diskreader, entry, -1, st); if (r != ARCHIVE_OK) - bsdtar_warnc(bsdtar, archive_errno(bsdtar->diskreader), + lafe_warnc(archive_errno(bsdtar->diskreader), archive_error_string(bsdtar->diskreader)); if (r < ARCHIVE_WARN) continue; @@ -894,7 +894,7 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a, fd = open(pathname, O_RDONLY); if (fd == -1) { if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, errno, + lafe_warnc(errno, "%s: could not open file", pathname); else fprintf(stderr, ": %s", strerror(errno)); @@ -905,7 +905,7 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a, e = archive_write_header(a, entry); if (e != ARCHIVE_OK) { if (!bsdtar->verbose) - bsdtar_warnc(bsdtar, 0, "%s: %s", + lafe_warnc(0, "%s: %s", archive_entry_pathname(entry), archive_error_string(a)); else @@ -952,12 +952,12 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a, bytes_read); if (bytes_written < 0) { /* Write failed; this is bad */ - bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); + lafe_warnc(0, "%s", archive_error_string(a)); return (-1); } if (bytes_written < bytes_read) { /* Write was truncated; warn but continue. */ - bsdtar_warnc(bsdtar, 0, + lafe_warnc(0, "%s: Truncated write; file may have grown while being archived.", archive_entry_pathname(entry)); return (0); @@ -1042,11 +1042,11 @@ add_dir_list(struct bsdtar *bsdtar, const char *path, p = malloc(sizeof(*p)); if (p == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read archive directory"); + lafe_errc(1, ENOMEM, "Can't read archive directory"); p->name = strdup(path); if (p->name == NULL) - bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read archive directory"); + lafe_errc(1, ENOMEM, "Can't read archive directory"); p->mtime_sec = mtime_sec; p->mtime_nsec = mtime_nsec; p->next = NULL; @@ -1064,19 +1064,19 @@ test_for_append(struct bsdtar *bsdtar) struct stat s; if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); + lafe_errc(1, 0, "no files or directories specified"); if (bsdtar->filename == NULL) - bsdtar_errc(bsdtar, 1, 0, "Cannot append to stdout."); + lafe_errc(1, 0, "Cannot append to stdout."); if (bsdtar->create_compression != 0) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Cannot append to %s with compression", bsdtar->filename); if (stat(bsdtar->filename, &s) != 0) return; if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode)) - bsdtar_errc(bsdtar, 1, 0, + lafe_errc(1, 0, "Cannot append to %s: not a regular file.", bsdtar->filename); } |