mirror of
https://github.com/opnsense/src.git
synced 2026-04-15 14:29:58 -04:00
ar: provide error exit status upon failure
Previously ar and ranlib returned with exit status 0 (success) in the case of a missing file or other error. Update to use error handling similar to that added by ELF Tool Chain after that project forked FreeBSD's ar. PR: PR257599 [exp-run] Reported by: Shawn Webb, gehmehgeh (on HardenedBSD IRC) Reviewed by: markj Obtained from: elftoolchain MFC after: 2 months Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31402
This commit is contained in:
parent
c6902e7796
commit
38911b3c2c
6 changed files with 100 additions and 77 deletions
|
|
@ -33,8 +33,8 @@ __FBSDID("$FreeBSD$");
|
|||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "y.tab.h"
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ SAVE|save { return (SAVE); }
|
|||
[-_A-Za-z0-9/:$.\\]+ {
|
||||
yylval.str = strdup(yytext);
|
||||
if (yylval.str == NULL)
|
||||
errc(EX_SOFTWARE, errno, "strdup failed");
|
||||
errc(EXIT_FAILURE, errno, "strdup failed");
|
||||
return (FNAME);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ directory_cmd
|
|||
;
|
||||
|
||||
end_cmd
|
||||
: END { arscp_end(EX_OK); }
|
||||
: END { arscp_end(EXIT_SUCCESS); }
|
||||
;
|
||||
|
||||
extract_cmd
|
||||
|
|
@ -655,9 +655,9 @@ ar_mode_script(struct bsdar *ar)
|
|||
interactive = isatty(fileno(stdin));
|
||||
while(yyparse()) {
|
||||
if (!interactive)
|
||||
arscp_end(1);
|
||||
arscp_end(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Script ends without END */
|
||||
arscp_end(EX_OK);
|
||||
arscp_end(EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$");
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "ar.h"
|
||||
|
||||
|
|
@ -102,10 +101,11 @@ main(int argc, char **argv)
|
|||
struct bsdar *bsdar, bsdar_storage;
|
||||
char *p;
|
||||
size_t len;
|
||||
int i, opt, Dflag, Uflag;
|
||||
int exitcode, i, opt, Dflag, Uflag;
|
||||
|
||||
bsdar = &bsdar_storage;
|
||||
memset(bsdar, 0, sizeof(*bsdar));
|
||||
exitcode = EXIT_SUCCESS;
|
||||
Dflag = 0;
|
||||
Uflag = 0;
|
||||
|
||||
|
|
@ -151,9 +151,10 @@ main(int argc, char **argv)
|
|||
bsdar->options |= AR_D;
|
||||
bsdar->options |= AR_S;
|
||||
while ((bsdar->filename = *argv++) != NULL)
|
||||
ar_mode_s(bsdar);
|
||||
if (ar_mode_s(bsdar))
|
||||
exitcode = EXIT_FAILURE;
|
||||
|
||||
exit(EX_OK);
|
||||
exit(exitcode);
|
||||
} else {
|
||||
if (argc < 2)
|
||||
bsdar_usage();
|
||||
|
|
@ -161,7 +162,7 @@ main(int argc, char **argv)
|
|||
if (*argv[1] != '-') {
|
||||
len = strlen(argv[1]) + 2;
|
||||
if ((p = malloc(len)) == NULL)
|
||||
bsdar_errc(bsdar, EX_SOFTWARE, errno,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, errno,
|
||||
"malloc failed");
|
||||
*p = '-';
|
||||
(void)strlcpy(p + 1, argv[1], len - 1);
|
||||
|
|
@ -262,23 +263,23 @@ main(int argc, char **argv)
|
|||
bsdar_usage();
|
||||
|
||||
if (bsdar->options & AR_A && bsdar->options & AR_B)
|
||||
bsdar_errc(bsdar, EX_USAGE, 0,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0,
|
||||
"only one of -a and -[bi] options allowed");
|
||||
|
||||
if (bsdar->options & AR_J && bsdar->options & AR_Z)
|
||||
bsdar_errc(bsdar, EX_USAGE, 0,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0,
|
||||
"only one of -j and -z options allowed");
|
||||
|
||||
if (bsdar->options & AR_S && bsdar->options & AR_SS)
|
||||
bsdar_errc(bsdar, EX_USAGE, 0,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0,
|
||||
"only one of -s and -S options allowed");
|
||||
|
||||
if (bsdar->options & (AR_A | AR_B)) {
|
||||
if (*argv == NULL)
|
||||
bsdar_errc(bsdar, EX_USAGE, 0,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0,
|
||||
"no position operand specified");
|
||||
if ((bsdar->posarg = basename(*argv)) == NULL)
|
||||
bsdar_errc(bsdar, EX_SOFTWARE, errno,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, errno,
|
||||
"basename failed");
|
||||
argc--;
|
||||
argv++;
|
||||
|
|
@ -310,7 +311,7 @@ main(int argc, char **argv)
|
|||
|
||||
if (bsdar->mode == 'M') {
|
||||
ar_mode_script(bsdar);
|
||||
exit(EX_OK);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if ((bsdar->filename = *argv) == NULL)
|
||||
|
|
@ -321,44 +322,47 @@ main(int argc, char **argv)
|
|||
|
||||
if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
|
||||
bsdar->options & AR_S) {
|
||||
ar_mode_s(bsdar);
|
||||
exitcode = ar_mode_s(bsdar);
|
||||
if (!bsdar->mode)
|
||||
exit(EX_OK);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
switch(bsdar->mode) {
|
||||
case 'd':
|
||||
ar_mode_d(bsdar);
|
||||
exitcode = ar_mode_d(bsdar);
|
||||
break;
|
||||
case 'm':
|
||||
ar_mode_m(bsdar);
|
||||
exitcode = ar_mode_m(bsdar);
|
||||
break;
|
||||
case 'p':
|
||||
ar_mode_p(bsdar);
|
||||
exitcode = ar_mode_p(bsdar);
|
||||
break;
|
||||
case 'q':
|
||||
ar_mode_q(bsdar);
|
||||
exitcode = ar_mode_q(bsdar);
|
||||
break;
|
||||
case 'r':
|
||||
ar_mode_r(bsdar);
|
||||
exitcode = ar_mode_r(bsdar);
|
||||
break;
|
||||
case 't':
|
||||
ar_mode_t(bsdar);
|
||||
exitcode = ar_mode_t(bsdar);
|
||||
break;
|
||||
case 'x':
|
||||
ar_mode_x(bsdar);
|
||||
exitcode = ar_mode_x(bsdar);
|
||||
break;
|
||||
default:
|
||||
bsdar_usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
for (i = 0; i < bsdar->argc; i++)
|
||||
if (bsdar->argv[i] != NULL)
|
||||
for (i = 0; i < bsdar->argc; i++) {
|
||||
if (bsdar->argv[i] != NULL) {
|
||||
bsdar_warnc(bsdar, 0, "%s: not found in archive",
|
||||
bsdar->argv[i]);
|
||||
exitcode = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
exit(EX_OK);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -366,7 +370,7 @@ set_mode(struct bsdar *bsdar, char opt)
|
|||
{
|
||||
|
||||
if (bsdar->mode != '\0' && bsdar->mode != opt)
|
||||
bsdar_errc(bsdar, EX_USAGE, 0,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0,
|
||||
"Can't specify both -%c and -%c", opt, bsdar->mode);
|
||||
bsdar->mode = opt;
|
||||
}
|
||||
|
|
@ -376,7 +380,7 @@ only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes)
|
|||
{
|
||||
|
||||
if (strchr(valid_modes, bsdar->mode) == NULL)
|
||||
bsdar_errc(bsdar, EX_USAGE, 0,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0,
|
||||
"Option %s is not permitted in mode -%c", opt, bsdar->mode);
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +399,7 @@ bsdar_usage(void)
|
|||
(void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
|
||||
(void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n");
|
||||
(void)fprintf(stderr, "\tar -V\n");
|
||||
exit(EX_USAGE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -404,19 +408,19 @@ ranlib_usage(void)
|
|||
|
||||
(void)fprintf(stderr, "usage: ranlib [-DtU] archive ...\n");
|
||||
(void)fprintf(stderr, "\tranlib -V\n");
|
||||
exit(EX_USAGE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
bsdar_version(void)
|
||||
{
|
||||
(void)printf("BSD ar %s - %s\n", BSDAR_VERSION, archive_version_string());
|
||||
exit(EX_OK);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
ranlib_version(void)
|
||||
{
|
||||
(void)printf("ranlib %s - %s\n", BSDAR_VERSION, archive_version_string());
|
||||
exit(EX_OK);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
*/
|
||||
#define AC(CALL) do { \
|
||||
if ((CALL)) \
|
||||
bsdar_errc(bsdar, EX_SOFTWARE, archive_errno(a), "%s", \
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, archive_errno(a), "%s", \
|
||||
archive_error_string(a)); \
|
||||
} while (0)
|
||||
|
||||
|
|
@ -117,13 +117,13 @@ struct bsdar {
|
|||
void bsdar_errc(struct bsdar *, int _eval, int _code,
|
||||
const char *fmt, ...) __dead2;
|
||||
void bsdar_warnc(struct bsdar *, int _code, const char *fmt, ...);
|
||||
void ar_mode_d(struct bsdar *bsdar);
|
||||
void ar_mode_m(struct bsdar *bsdar);
|
||||
void ar_mode_p(struct bsdar *bsdar);
|
||||
void ar_mode_q(struct bsdar *bsdar);
|
||||
void ar_mode_r(struct bsdar *bsdar);
|
||||
void ar_mode_s(struct bsdar *bsdar);
|
||||
void ar_mode_t(struct bsdar *bsdar);
|
||||
void ar_mode_x(struct bsdar *bsdar);
|
||||
void ar_mode_A(struct bsdar *bsdar);
|
||||
int ar_mode_d(struct bsdar *bsdar);
|
||||
int ar_mode_m(struct bsdar *bsdar);
|
||||
int ar_mode_p(struct bsdar *bsdar);
|
||||
int ar_mode_q(struct bsdar *bsdar);
|
||||
int ar_mode_r(struct bsdar *bsdar);
|
||||
int ar_mode_s(struct bsdar *bsdar);
|
||||
int ar_mode_t(struct bsdar *bsdar);
|
||||
int ar_mode_x(struct bsdar *bsdar);
|
||||
int ar_mode_A(struct bsdar *bsdar);
|
||||
void ar_mode_script(struct bsdar *ar);
|
||||
|
|
|
|||
|
|
@ -37,38 +37,38 @@ __FBSDID("$FreeBSD$");
|
|||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "ar.h"
|
||||
|
||||
static void read_archive(struct bsdar *bsdar, char mode);
|
||||
static int read_archive(struct bsdar *bsdar, char mode);
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_p(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
read_archive(bsdar, 'p');
|
||||
return (read_archive(bsdar, 'p'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_t(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
read_archive(bsdar, 't');
|
||||
return (read_archive(bsdar, 't'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_x(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
read_archive(bsdar, 'x');
|
||||
return (read_archive(bsdar, 'x'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle read modes: 'x', 't' and 'p'.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
read_archive(struct bsdar *bsdar, char mode)
|
||||
{
|
||||
struct archive *a;
|
||||
|
|
@ -85,13 +85,15 @@ read_archive(struct bsdar *bsdar, char mode)
|
|||
char **av;
|
||||
char buf[25];
|
||||
char find;
|
||||
int flags, r, i;
|
||||
int exitcode, flags, r, i;
|
||||
|
||||
if ((a = archive_read_new()) == NULL)
|
||||
bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed");
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, 0, "archive_read_new failed");
|
||||
archive_read_support_format_ar(a);
|
||||
AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ));
|
||||
|
||||
exitcode = EXIT_SUCCESS;
|
||||
|
||||
for (;;) {
|
||||
r = archive_read_next_header(a, &entry);
|
||||
if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
|
||||
|
|
@ -120,7 +122,7 @@ read_archive(struct bsdar *bsdar, char mode)
|
|||
if (*av == NULL)
|
||||
continue;
|
||||
if ((bname = basename(*av)) == NULL)
|
||||
bsdar_errc(bsdar, EX_SOFTWARE, errno,
|
||||
bsdar_errc(bsdar, EXIT_FAILURE, errno,
|
||||
"basename failed");
|
||||
if (strcmp(bname, name) != 0)
|
||||
continue;
|
||||
|
|
@ -206,11 +208,19 @@ read_archive(struct bsdar *bsdar, char mode)
|
|||
r = archive_read_extract(a, entry, flags);
|
||||
}
|
||||
|
||||
if (r)
|
||||
if (r) {
|
||||
bsdar_warnc(bsdar, archive_errno(a), "%s",
|
||||
archive_error_string(a));
|
||||
exitcode = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r == ARCHIVE_FATAL)
|
||||
exitcode = EXIT_FAILURE;
|
||||
|
||||
AC(archive_read_close(a));
|
||||
AC(archive_read_free(a));
|
||||
|
||||
return (exitcode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,52 +67,52 @@ static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj,
|
|||
static void prefault_buffer(const char *buf, size_t s);
|
||||
static void read_objs(struct bsdar *bsdar, const char *archive,
|
||||
int checkargv);
|
||||
static void write_archive(struct bsdar *bsdar, char mode);
|
||||
static int write_archive(struct bsdar *bsdar, char mode);
|
||||
static void write_cleanup(struct bsdar *bsdar);
|
||||
static void write_data(struct bsdar *bsdar, struct archive *a,
|
||||
const void *buf, size_t s);
|
||||
static void write_objs(struct bsdar *bsdar);
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_d(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
write_archive(bsdar, 'd');
|
||||
return (write_archive(bsdar, 'd'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_m(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
write_archive(bsdar, 'm');
|
||||
return (write_archive(bsdar, 'm'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_q(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
write_archive(bsdar, 'q');
|
||||
return (write_archive(bsdar, 'q'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_r(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
write_archive(bsdar, 'r');
|
||||
return (write_archive(bsdar, 'r'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_s(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
write_archive(bsdar, 's');
|
||||
return (write_archive(bsdar, 's'));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ar_mode_A(struct bsdar *bsdar)
|
||||
{
|
||||
|
||||
write_archive(bsdar, 'A');
|
||||
return (write_archive(bsdar, 'A'));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -378,16 +378,17 @@ read_objs(struct bsdar *bsdar, const char *archive, int checkargv)
|
|||
/*
|
||||
* Determine the constitution of resulting archive.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
write_archive(struct bsdar *bsdar, char mode)
|
||||
{
|
||||
struct ar_obj *nobj, *obj, *obj_temp, *pos;
|
||||
struct stat sb;
|
||||
const char *bname;
|
||||
char **av;
|
||||
int i;
|
||||
int exitcode, i;
|
||||
|
||||
TAILQ_INIT(&bsdar->v_obj);
|
||||
exitcode = EXIT_SUCCESS;
|
||||
nobj = NULL;
|
||||
pos = NULL;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
|
|
@ -400,14 +401,14 @@ write_archive(struct bsdar *bsdar, char mode)
|
|||
if (errno != ENOENT) {
|
||||
bsdar_warnc(bsdar, 0, "stat %s failed",
|
||||
bsdar->filename);
|
||||
return;
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* We do not create archive in mode 'd', 'm' and 's'. */
|
||||
if (mode != 'r' && mode != 'q') {
|
||||
bsdar_warnc(bsdar, 0, "%s: no such file",
|
||||
bsdar->filename);
|
||||
return;
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Issue a warning if -c is not specified when creating. */
|
||||
|
|
@ -491,8 +492,10 @@ write_archive(struct bsdar *bsdar, char mode)
|
|||
*/
|
||||
nobj = create_obj_from_file(bsdar, *av,
|
||||
obj->mtime);
|
||||
if (nobj == NULL)
|
||||
if (nobj == NULL) {
|
||||
exitcode = EXIT_FAILURE;
|
||||
goto skip_obj;
|
||||
}
|
||||
}
|
||||
|
||||
if (bsdar->options & AR_V)
|
||||
|
|
@ -526,8 +529,12 @@ new_archive:
|
|||
av = &bsdar->argv[i];
|
||||
if (*av != NULL && (mode == 'r' || mode == 'q')) {
|
||||
nobj = create_obj_from_file(bsdar, *av, 0);
|
||||
if (nobj != NULL)
|
||||
insert_obj(bsdar, nobj, pos);
|
||||
if (nobj == NULL) {
|
||||
exitcode = EXIT_FAILURE;
|
||||
*av = NULL;
|
||||
continue;
|
||||
}
|
||||
insert_obj(bsdar, nobj, pos);
|
||||
if (bsdar->options & AR_V && nobj != NULL)
|
||||
(void)fprintf(stdout, "a - %s\n", *av);
|
||||
*av = NULL;
|
||||
|
|
@ -537,6 +544,8 @@ new_archive:
|
|||
write_objs:
|
||||
write_objs(bsdar);
|
||||
write_cleanup(bsdar);
|
||||
|
||||
return (exitcode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue