diff --git a/usr.bin/tar/bsdtar.c b/usr.bin/tar/bsdtar.c index 747f009ace1..a74db38cfda 100644 --- a/usr.bin/tar/bsdtar.c +++ b/usr.bin/tar/bsdtar.c @@ -48,11 +48,11 @@ __FBSDID("$FreeBSD$"); #include "bsdtar.h" -static void long_help(void); -static void only_mode(char mode, const char *opt, +static void long_help(struct bsdtar *); +static void only_mode(struct bsdtar *, char mode, const char *opt, const char *valid); -static const char *progname; -static char ** rewrite_argv(int *argc, char ** src_argv, +static char ** rewrite_argv(struct bsdtar *, + int *argc, char ** src_argv, const char *optstring); const char *tar_opts = "b:C:cF:f:HhjkLlmnOoPprtT:UuvwXxyZz"; @@ -120,10 +120,6 @@ main(int argc, char **argv) char mode; char buff[16]; - if (setlocale(LC_ALL, "") == NULL) - bsdtar_warnc(0, "Failed to set default locale"); - mode = '\0'; - /* * Use a pointer for consistency, but stack-allocated storage * for ease of cleanup. @@ -132,6 +128,10 @@ main(int argc, char **argv) memset(bsdtar, 0, sizeof(*bsdtar)); bsdtar->fd = -1; /* Mark as "unused" */ + if (setlocale(LC_ALL, "") == NULL) + bsdtar_warnc(bsdtar, 0, "Failed to set default locale"); + mode = '\0'; + /* Look up uid/uname of current user for future reference */ bsdtar->user_uid = geteuid(); bsdtar->user_uname = NULL; @@ -154,10 +154,14 @@ main(int argc, char **argv) if (bsdtar->user_uid == 0) bsdtar->extract_flags = ARCHIVE_EXTRACT_OWNER; - progname = *argv; + bsdtar->progname = strrchr(*argv, '/'); + if (bsdtar->progname != NULL) + bsdtar->progname++; + else + bsdtar->progname = *argv; /* Rewrite traditional-style tar arguments, if used. */ - argv = rewrite_argv(&argc, argv, tar_opts); + argv = rewrite_argv(bsdtar, &argc, argv, tar_opts); bsdtar->argv = argv; bsdtar->argc = argc; @@ -180,7 +184,7 @@ main(int argc, char **argv) break; case 'c': /* SUSv2 */ if (mode != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, mode); mode = opt; @@ -211,12 +215,12 @@ main(int argc, char **argv) break; #ifdef HAVE_GETOPT_LONG case OPTION_HELP: - long_help(); + long_help(bsdtar); break; #endif case 'j': /* GNU tar */ if (bsdtar->create_compression != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; @@ -267,14 +271,14 @@ main(int argc, char **argv) break; case 'r': /* SUSv2 */ if (mode != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, mode); mode = opt; break; case 't': /* SUSv2 */ if (mode != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, mode); mode = opt; @@ -289,7 +293,7 @@ main(int argc, char **argv) break; case 'u': /* SUSv2 */ if (mode != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, mode); mode = opt; @@ -305,31 +309,31 @@ main(int argc, char **argv) break; case 'x': /* SUSv2 */ if (mode != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, mode); mode = opt; break; case 'y': /* FreeBSD version of GNU tar */ if (bsdtar->create_compression != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; break; case 'Z': /* GNU tar */ - bsdtar_warnc(0, ".Z compression not supported"); - usage(); + bsdtar_warnc(bsdtar, 0, ".Z compression not supported"); + usage(bsdtar); break; case 'z': /* GNU tar, star */ if (bsdtar->create_compression != '\0') - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", opt, bsdtar->create_compression); bsdtar->create_compression = opt; break; default: - usage(); + usage(bsdtar); } } @@ -337,38 +341,39 @@ main(int argc, char **argv) * Sanity-check options. */ if (mode == '\0') - bsdtar_errc(1, 0, "Must specify one of -c, -r, -t, -u, -x"); + bsdtar_errc(bsdtar, 1, 0, + "Must specify one of -c, -r, -t, -u, -x"); /* Check boolean options only permitted in certain modes. */ if (bsdtar->option_absolute_paths) - only_mode(mode, "-P", "xcru"); + only_mode(bsdtar, mode, "-P", "xcru"); if (bsdtar->option_dont_traverse_mounts) - only_mode(mode, "-X", "cru"); + only_mode(bsdtar, mode, "-X", "cru"); if (bsdtar->option_fast_read) - only_mode(mode, "--fast-read", "xt"); + only_mode(bsdtar, mode, "--fast-read", "xt"); if (bsdtar->option_honor_nodump) - only_mode(mode, "--nodump", "cru"); + only_mode(bsdtar, mode, "--nodump", "cru"); if (bsdtar->option_no_subdirs) - only_mode(mode, "-n", "cru"); + only_mode(bsdtar, mode, "-n", "cru"); if (bsdtar->option_stdout) - only_mode(mode, "-O", "x"); + only_mode(bsdtar, mode, "-O", "x"); if (bsdtar->option_warn_links) - only_mode(mode, "-l", "cr"); + only_mode(bsdtar, mode, "-l", "cr"); /* Check other parameters only permitted in certain modes. */ if (bsdtar->create_compression != '\0') { strcpy(buff, "-?"); buff[1] = bsdtar->create_compression; - only_mode(mode, buff, "cxt"); + only_mode(bsdtar, mode, buff, "cxt"); } if (bsdtar->create_format != NULL) - only_mode(mode, "-F", "c"); + only_mode(bsdtar, mode, "-F", "c"); if (bsdtar->names_from_file != NULL) - only_mode(mode, "-T", "cru"); + only_mode(bsdtar, mode, "-T", "cru"); if (bsdtar->symlink_mode != '\0') { strcpy(buff, "-X"); buff[1] = bsdtar->symlink_mode; - only_mode(mode, buff, "cru"); + only_mode(bsdtar, mode, buff, "cru"); } bsdtar->argc -= optind; @@ -403,10 +408,12 @@ main(int argc, char **argv) * Verify that the mode is correct. */ static void -only_mode(char mode, const char *opt, const char *valid_modes) +only_mode(struct bsdtar *bsdtar, char mode, + const char *opt, const char *valid_modes) { if (strchr(valid_modes, mode) == NULL) - bsdtar_errc(1, 0, "Option %s is not permitted in mode -%c", + bsdtar_errc(bsdtar, 1, 0, + "Option %s is not permitted in mode -%c", opt, mode); } @@ -428,7 +435,8 @@ only_mode(char mode, const char *opt, const char *valid_modes) * It is used to determine which option letters have trailing arguments. */ char ** -rewrite_argv(int *argc, char ** src_argv, const char *optstring) +rewrite_argv(struct bsdtar *bsdtar, int *argc, char ** src_argv, + const char *optstring) { char **new_argv, **dest_argv; const char *p; @@ -440,14 +448,14 @@ rewrite_argv(int *argc, char ** src_argv, const char *optstring) *argc += strlen(src_argv[1]) - 1; new_argv = malloc((*argc + 1) * sizeof(new_argv[0])); if (new_argv == NULL) - bsdtar_errc(1, errno, "No Memory"); + bsdtar_errc(bsdtar, 1, errno, "No Memory"); dest_argv = new_argv; *dest_argv++ = *src_argv++; dest = malloc(strlen(*src_argv) * 3); if (dest == NULL) - bsdtar_errc(1, errno, "No memory"); + bsdtar_errc(bsdtar, 1, errno, "No memory"); for (src = *src_argv++; *src != '\0'; src++) { *dest_argv++ = dest; *dest++ = '-'; @@ -460,7 +468,7 @@ rewrite_argv(int *argc, char ** src_argv, const char *optstring) if (p[1] != ':') /* No arg required, done. */ break; if (*src_argv == NULL) /* No arg available? Error. */ - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Option %c requires an argument", *src); *dest_argv++ = *src_argv++; @@ -476,15 +484,11 @@ rewrite_argv(int *argc, char ** src_argv, const char *optstring) } void -usage(void) +usage(struct bsdtar *bsdtar) { const char *p; - p = strrchr(progname, '/'); - if (p != NULL) - p++; - else - p = progname; + p = bsdtar->progname; printf("Basic Usage:\n"); printf(" List: %s -tf [archive-filename]\n", p); @@ -522,17 +526,13 @@ static const char *long_help_msg[] = { static void -long_help(void) +long_help(struct bsdtar *bsdtar) { const char *prog; const char *p; const char **msg; - prog = strrchr(progname, '/'); - if (prog != NULL) - prog++; - else - prog = progname; + prog = bsdtar->progname; printf("%s: manipulate archive files\n", prog); @@ -551,9 +551,3 @@ long_help(void) } } } - -const char * -bsdtar_progname(void) -{ - return (progname); -} diff --git a/usr.bin/tar/bsdtar.h b/usr.bin/tar/bsdtar.h index aa39caa0c8c..84f2580c1fd 100644 --- a/usr.bin/tar/bsdtar.h +++ b/usr.bin/tar/bsdtar.h @@ -65,6 +65,7 @@ struct bsdtar { int fd; /* Miscellaneous state information */ + const char *progname; int argc; char **argv; size_t gs_width; /* For 'list_item' in read.c */ @@ -84,10 +85,10 @@ struct bsdtar { struct name_cache *uname_cache; /* for write.c */ }; -const char *bsdtar_progname(void); -void bsdtar_errc(int _eval, int _code, const char *fmt, ...); +void bsdtar_errc(struct bsdtar *, int _eval, int _code, + const char *fmt, ...); void bsdtar_strmode(struct archive_entry *entry, char *bp); -void bsdtar_warnc(int _code, const char *fmt, ...); +void bsdtar_warnc(struct bsdtar *, int _code, const char *fmt, ...); void cleanup_exclusions(struct bsdtar *); void exclude(struct bsdtar *, const char *pattern); int excluded(struct bsdtar *, const char *pathname); @@ -99,6 +100,6 @@ 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); -void usage(void); +void usage(struct bsdtar *); int yes(const char *fmt, ...); diff --git a/usr.bin/tar/matching.c b/usr.bin/tar/matching.c index 9b4e7255ae9..6a3f65bd036 100644 --- a/usr.bin/tar/matching.c +++ b/usr.bin/tar/matching.c @@ -49,7 +49,8 @@ struct matching { }; -static void add_pattern(struct match **list, const char *pattern); +static void add_pattern(struct bsdtar *, struct match **list, + const char *pattern); static void initialize_matching(struct bsdtar *); static int match_exclusion(struct match *, const char *pathname); static int match_inclusion(struct match *, const char *pathname); @@ -73,7 +74,7 @@ exclude(struct bsdtar *bsdtar, const char *pattern) if (bsdtar->matching == NULL) initialize_matching(bsdtar); matching = bsdtar->matching; - add_pattern(&(matching->exclusions), pattern); + add_pattern(bsdtar, &(matching->exclusions), pattern); matching->exclusions_count++; } @@ -85,19 +86,19 @@ include(struct bsdtar *bsdtar, const char *pattern) if (bsdtar->matching == NULL) initialize_matching(bsdtar); matching = bsdtar->matching; - add_pattern(&(matching->inclusions), pattern); + add_pattern(bsdtar, &(matching->inclusions), pattern); matching->inclusions_count++; matching->inclusions_unmatched_count++; } static void -add_pattern(struct match **list, const char *pattern) +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(1, errno, "Out of memory"); + bsdtar_errc(bsdtar, 1, errno, "Out of memory"); if (pattern[0] == '/') pattern++; strcpy(match->pattern, pattern); @@ -224,7 +225,7 @@ initialize_matching(struct bsdtar *bsdtar) { bsdtar->matching = malloc(sizeof(*bsdtar->matching)); if (bsdtar->matching == NULL) - bsdtar_errc(1, errno, "No memory"); + bsdtar_errc(bsdtar, 1, errno, "No memory"); memset(bsdtar->matching, 0, sizeof(*bsdtar->matching)); } diff --git a/usr.bin/tar/read.c b/usr.bin/tar/read.c index af1a28e7b75..c44d9abb1ac 100644 --- a/usr.bin/tar/read.c +++ b/usr.bin/tar/read.c @@ -84,7 +84,7 @@ read_archive(struct bsdtar *bsdtar, char mode) archive_read_support_compression_all(a); archive_read_support_format_all(a); if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block)) - bsdtar_errc(1, 0, "Error opening archive: %s", + bsdtar_errc(bsdtar, 1, 0, "Error opening archive: %s", archive_error_string(a)); if (bsdtar->verbose > 2) @@ -92,7 +92,8 @@ read_archive(struct bsdtar *bsdtar, char mode) archive_compression_name(a)); if (bsdtar->start_dir != NULL && chdir(bsdtar->start_dir)) - bsdtar_errc(1, errno, "chdir(%s) failed", bsdtar->start_dir); + bsdtar_errc(bsdtar, 1, errno, + "chdir(%s) failed", bsdtar->start_dir); for (;;) { /* Support --fast-read option */ @@ -104,15 +105,15 @@ read_archive(struct bsdtar *bsdtar, char mode) if (r == ARCHIVE_EOF) break; if (r == ARCHIVE_WARN) - bsdtar_warnc(0, "%s", archive_error_string(a)); + bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); if (r == ARCHIVE_FATAL) { - bsdtar_warnc(0, "%s", archive_error_string(a)); + bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); break; } if (r == ARCHIVE_RETRY) { /* Retryable error: try again */ - bsdtar_warnc(0, "%s", archive_error_string(a)); - bsdtar_warnc(0, "Retrying..."); + bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); + bsdtar_warnc(bsdtar, 0, "Retrying..."); continue; } @@ -138,11 +139,12 @@ read_archive(struct bsdtar *bsdtar, char mode) case ARCHIVE_WARN: case ARCHIVE_RETRY: fprintf(stdout, "\n"); - bsdtar_warnc(0, "%s", archive_error_string(a)); + bsdtar_warnc(bsdtar, 0, "%s", + archive_error_string(a)); break; case ARCHIVE_FATAL: fprintf(stdout, "\n"); - bsdtar_errc(1, 0, "%s", + bsdtar_errc(bsdtar, 1, 0, "%s", archive_error_string(a)); break; } @@ -323,7 +325,8 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry) while (pn != NULL && pn[0] != '\0') { if (pn[0] == '.' && pn[1] == '.' && (pn[2] == '\0' || pn[2] == '/')) { - bsdtar_warnc(0,"Skipping pathname containing .."); + bsdtar_warnc(bsdtar, 0, + "Skipping pathname containing .."); return (1); } pn = strchr(pn, '/'); @@ -368,7 +371,7 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry) /* User asked us to remove problems. */ unlink(bsdtar->security->path); } else { - bsdtar_warnc(0, + bsdtar_warnc(bsdtar, 0, "Cannot extract %s through symlink %s", name, bsdtar->security->path); return (1); diff --git a/usr.bin/tar/util.c b/usr.bin/tar/util.c index 97179503d61..46bc7260807 100644 --- a/usr.bin/tar/util.c +++ b/usr.bin/tar/util.c @@ -38,7 +38,8 @@ __FBSDID("$FreeBSD$"); #include "bsdtar.h" -static void bsdtar_vwarnc(int code, const char *fmt, va_list ap); +static void bsdtar_vwarnc(struct bsdtar *, int code, + const char *fmt, va_list ap); /* * Print a string, taking care with any non-printable characters. @@ -103,41 +104,32 @@ safe_fprintf(FILE *f, const char *fmt, ...) } static void -bsdtar_vwarnc(int code, const char *fmt, va_list ap) +bsdtar_vwarnc(struct bsdtar *bsdtar, int code, const char *fmt, va_list ap) { - const char *p; - - p = strrchr(bsdtar_progname(), '/'); - if (p != NULL) - p++; - else - p = bsdtar_progname(); - fprintf(stderr, "%s: ", p); - + fprintf(stderr, "%s: ", bsdtar->progname); vfprintf(stderr, fmt, ap); if (code != 0) fprintf(stderr, ": %s", strerror(code)); - fprintf(stderr, "\n"); } void -bsdtar_warnc(int code, const char *fmt, ...) +bsdtar_warnc(struct bsdtar *bsdtar, int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - bsdtar_vwarnc(code, fmt, ap); + bsdtar_vwarnc(bsdtar, code, fmt, ap); va_end(ap); } void -bsdtar_errc(int eval, int code, const char *fmt, ...) +bsdtar_errc(struct bsdtar *bsdtar, int eval, int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - bsdtar_vwarnc(code, fmt, ap); + bsdtar_vwarnc(bsdtar, code, fmt, ap); va_end(ap); exit(eval); } diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c index 25a19f4bd17..e9cfcd047f7 100644 --- a/usr.bin/tar/write.c +++ b/usr.bin/tar/write.c @@ -134,7 +134,7 @@ tar_mode_c(struct bsdtar *bsdtar) int r; if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - bsdtar_errc(1, 0, "no files or directories specified"); + bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); a = archive_write_new(); @@ -147,7 +147,7 @@ tar_mode_c(struct bsdtar *bsdtar) fprintf(stderr, "Can't use format %s: %s\n", bsdtar->create_format, archive_error_string(a)); - usage(); + usage(bsdtar); } } @@ -164,8 +164,7 @@ tar_mode_c(struct bsdtar *bsdtar) r = archive_write_open_file(a, bsdtar->filename); if (r != ARCHIVE_OK) - bsdtar_errc(1, archive_errno(a), - archive_error_string(a)); + bsdtar_errc(bsdtar, 1, 0, archive_error_string(a)); write_archive(a, bsdtar); @@ -191,7 +190,8 @@ tar_mode_r(struct bsdtar *bsdtar) bsdtar->fd = open(bsdtar->filename, O_RDWR); if (bsdtar->fd < 0) - bsdtar_errc(1, errno, "Cannot open %s", bsdtar->filename); + bsdtar_errc(bsdtar, 1, errno, + "Cannot open %s", bsdtar->filename); a = archive_read_new(); archive_read_support_compression_all(a); @@ -202,7 +202,7 @@ tar_mode_r(struct bsdtar *bsdtar) if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_finish(a); close(bsdtar->fd); - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Cannot append to compressed archive."); } /* Keep going until we hit end-of-archive */ @@ -255,7 +255,8 @@ tar_mode_u(struct bsdtar *bsdtar) bsdtar->fd = open(bsdtar->filename, O_RDWR); if (bsdtar->fd < 0) - bsdtar_errc(1, errno, "Cannot open %s", bsdtar->filename); + bsdtar_errc(bsdtar, 1, errno, + "Cannot open %s", bsdtar->filename); a = archive_read_new(); archive_read_support_compression_all(a); @@ -268,7 +269,7 @@ tar_mode_u(struct bsdtar *bsdtar) if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { archive_read_finish(a); close(bsdtar->fd); - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "Cannot append to compressed archive."); } add_dir_list(bsdtar, archive_entry_pathname(entry), @@ -325,7 +326,8 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) pending_dir = NULL; if (bsdtar->start_dir != NULL && chdir(bsdtar->start_dir)) - bsdtar_errc(1, errno, "chdir(%s) failed", bsdtar->start_dir); + bsdtar_errc(bsdtar, 1, errno, + "chdir(%s) failed", bsdtar->start_dir); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); @@ -386,7 +388,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) /* Handle a deferred -C request, see * comments above. */ if (chdir(pending_dir)) - bsdtar_errc(1, 0, + bsdtar_errc(bsdtar, 1, 0, "could not chdir to '%s'\n", pending_dir); free(pending_dir); @@ -432,14 +434,15 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) */ if (strcmp(buff, "-C") == 0) { if (fgets(buff, sizeof(buff), f) == NULL) - bsdtar_errc(1, errno, + bsdtar_errc(bsdtar, 1, errno, "Unexpected end of filename list; " "directory expected after -C"); l = strlen(buff); if (buff[l-1] == '\n') buff[l-1] = '\0'; if (chdir(buff)) - bsdtar_errc(1, errno, "chdir(%s) failed", buff); + bsdtar_errc(bsdtar, 1, errno, + "chdir(%s) failed", buff); } else { write_heirarchy(bsdtar, a, buff); } @@ -482,7 +485,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, const char *filename) bytes_written = archive_write_data(a, buff, bytes_read); if (bytes_written < bytes_read) { - bsdtar_warnc( archive_errno(a), "%s", + bsdtar_warnc(bsdtar, archive_errno(a), "%s", archive_error_string(a)); exit(1); } @@ -494,8 +497,8 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, const char *filename) } if (archive_errno(ina)) - bsdtar_warnc(0, "Error reading archive %s: %s", filename, - archive_error_string(ina)); + bsdtar_warnc(bsdtar, 0, "Error reading archive %s: %s", + filename, archive_error_string(ina)); return (0); /* TODO: Return non-zero on error */ } @@ -537,21 +540,22 @@ write_heirarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) if (!fts) { - bsdtar_warnc(errno, "%s: Cannot open", path); + bsdtar_warnc(bsdtar, errno, "%s: Cannot open", path); return; } while ((ftsent = fts_read(fts))) { switch (ftsent->fts_info) { case FTS_NS: - bsdtar_warnc(ftsent->fts_errno, "%s: Could not stat", - ftsent->fts_path); + bsdtar_warnc(bsdtar, ftsent->fts_errno, + "%s: Could not stat", ftsent->fts_path); break; case FTS_ERR: - bsdtar_warnc(ftsent->fts_errno, "%s", ftsent->fts_path); + bsdtar_warnc(bsdtar, ftsent->fts_errno, "%s", + ftsent->fts_path); break; case FTS_DNR: - bsdtar_warnc(ftsent->fts_errno, + bsdtar_warnc(bsdtar, ftsent->fts_errno, "%s: Cannot read directory contents", ftsent->fts_path); break; @@ -686,7 +690,8 @@ write_heirarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) case FTS_DP: break; default: - bsdtar_warnc(0, "%s: Heirarchy traversal error %d\n", + bsdtar_warnc(bsdtar, 0, + "%s: Heirarchy traversal error %d\n", ftsent->fts_path, ftsent->fts_info); break; @@ -694,9 +699,9 @@ write_heirarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) } if (errno) - bsdtar_warnc(errno, "%s", path); + bsdtar_warnc(bsdtar, errno, "%s", path); if (fts_close(fts)) - bsdtar_warnc(errno, "fts_close failed"); + bsdtar_warnc(bsdtar, errno, "fts_close failed"); free(fts_argv[0]); } @@ -752,7 +757,7 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, struct stat *st, lnklen = readlink(accpath, linkbuffer, PATH_MAX); if (lnklen < 0) { if (!bsdtar->verbose) - bsdtar_warnc(errno, + bsdtar_warnc(bsdtar, errno, "%s: Couldn't read symbolic link", pathname); else @@ -796,7 +801,7 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, struct stat *st, fd = open(accpath, O_RDONLY); if (fd < 0) { if (!bsdtar->verbose) - bsdtar_warnc(errno, "%s", pathname); + bsdtar_warnc(bsdtar, errno, "%s", pathname); else fprintf(stderr, ": %s", strerror(errno)); goto cleanup; @@ -806,7 +811,7 @@ write_entry(struct bsdtar *bsdtar, struct archive *a, struct stat *st, e = archive_write_header(a, entry); if (e != ARCHIVE_OK) { if (!bsdtar->verbose) - bsdtar_warnc(0, "%s: %s", pathname, + bsdtar_warnc(bsdtar, 0, "%s: %s", pathname, archive_error_string(a)); else fprintf(stderr, ": %s", archive_error_string(a)); @@ -877,7 +882,7 @@ create_cleanup(struct bsdtar * bsdtar) struct links_entry *lp = links_cache->buckets[i]->next; if (bsdtar->option_warn_links) - bsdtar_warnc(0, + bsdtar_warnc(bsdtar, 0, "Missing links to %s", links_cache->buckets[i]->name); if (links_cache->buckets[i]->name != NULL) @@ -892,7 +897,6 @@ create_cleanup(struct bsdtar * bsdtar) bsdtar->links_cache = NULL; } - free_cache(bsdtar->uname_cache); bsdtar->uname_cache = NULL; free_cache(bsdtar->gname_cache); @@ -914,7 +918,7 @@ lookup_hardlink(struct bsdtar *bsdtar, struct archive_entry *entry, if (links_cache == NULL) { bsdtar->links_cache = malloc(sizeof(struct links_cache)); if (bsdtar->links_cache == NULL) - bsdtar_errc(1, ENOMEM, + bsdtar_errc(bsdtar, 1, ENOMEM, "No memory for hardlink detection."); links_cache = bsdtar->links_cache; memset(links_cache, 0, sizeof(struct links_cache)); @@ -922,7 +926,7 @@ lookup_hardlink(struct bsdtar *bsdtar, struct archive_entry *entry, links_cache->buckets = malloc(links_cache->number_buckets * sizeof(links_cache->buckets[0])); if (links_cache->buckets == NULL) { - bsdtar_errc(1, ENOMEM, + bsdtar_errc(bsdtar, 1, ENOMEM, "No memory for hardlink detection."); } for (i = 0; i < links_cache->number_buckets; i++) @@ -965,9 +969,10 @@ lookup_hardlink(struct bsdtar *bsdtar, struct archive_entry *entry, links_cache->number_buckets = new_size; } else { links_cache->stop_allocating = 1; - bsdtar_warnc(ENOMEM, "No more memory for recording " - "hard links; Remaining hard links will be " - "dumped as full files."); + bsdtar_warnc(bsdtar, ENOMEM, + "No more memory for recording hard links"); + bsdtar_warnc(bsdtar, 0, + "Remaining links will be dumped as full files"); } } @@ -1007,9 +1012,10 @@ lookup_hardlink(struct bsdtar *bsdtar, struct archive_entry *entry, le = malloc(sizeof(struct links_entry)); if (le == NULL) { links_cache->stop_allocating = 1; - bsdtar_warnc(ENOMEM, "No more memory for recording " - "hard links; Remaining hard links will be dumped " - "as full files."); + bsdtar_warnc(bsdtar, ENOMEM, + "No more memory for recording hard links"); + bsdtar_warnc(bsdtar, 0, + "Remaining hard links will be dumped as full files"); return; } if (links_cache->buckets[hash] != NULL) @@ -1194,7 +1200,7 @@ lookup_uname_helper(struct bsdtar *bsdtar, const char **name, id_t id) if (pwent == NULL) { *name = NULL; if (errno != 0) - bsdtar_warnc(errno, "getpwuid(%d) failed", id); + bsdtar_warnc(bsdtar, errno, "getpwuid(%d) failed", id); return (errno); } @@ -1220,7 +1226,7 @@ lookup_gname_helper(struct bsdtar *bsdtar, const char **name, id_t id) if (grent == NULL && errno != 0) { *name = NULL; if (errno != 0) - bsdtar_warnc(errno, "getgrgid(%d) failed", id); + bsdtar_warnc(bsdtar, errno, "getgrgid(%d) failed", id); return (errno); } @@ -1301,18 +1307,20 @@ test_for_append(struct bsdtar *bsdtar) struct stat s; if (*bsdtar->argv == NULL) - bsdtar_errc(1, 0, "no files or directories specified"); + bsdtar_errc(bsdtar, 1, 0, "no files or directories specified"); if (bsdtar->filename == NULL) - bsdtar_errc(1, 0, "Cannot append to stdout."); + bsdtar_errc(bsdtar, 1, 0, "Cannot append to stdout."); if (bsdtar->create_compression != 0) - bsdtar_errc(1, 0, "Cannot append to %s with compression", - bsdtar->filename); + bsdtar_errc(bsdtar, 1, 0, + "Cannot append to %s with compression", bsdtar->filename); if (stat(bsdtar->filename, &s) != 0) - bsdtar_errc(1, errno, "Cannot stat %s", bsdtar->filename); + bsdtar_errc(bsdtar, 1, errno, + "Cannot stat %s", bsdtar->filename); if (!S_ISREG(s.st_mode)) - bsdtar_errc(1, 0, "Cannot append to %s: not a regular file.", + bsdtar_errc(bsdtar, 1, 0, + "Cannot append to %s: not a regular file.", bsdtar->filename); }