diff options
Diffstat (limited to 'src/file.c')
-rw-r--r-- | src/file.c | 174 |
1 files changed, 134 insertions, 40 deletions
diff --git a/src/file.c b/src/file.c index fad3160d15fe..87dd1bb60f4c 100644 --- a/src/file.c +++ b/src/file.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.172 2016/10/24 15:21:07 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.175 2018/03/02 16:11:37 christos Exp $") #endif /* lint */ #include "magic.h" @@ -59,26 +59,38 @@ FILE_RCSID("@(#)$File: file.c,v 1.172 2016/10/24 15:21:07 christos Exp $") #endif #if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION) -#include <getopt.h> -#ifndef HAVE_GETOPT_LONG -int getopt_long(int argc, char * const *argv, const char *optstring, const struct option *longopts, int *longindex); +# include <getopt.h> +# ifndef HAVE_GETOPT_LONG +int getopt_long(int, char * const *, const char *, + const struct option *, int *); +# endif +# else +# include "mygetopt.h" #endif + +#ifdef S_IFLNK +# define IFLNK_h "h" +# define IFLNK_L "L" #else -#include "mygetopt.h" +# define IFLNK_h "" +# define IFLNK_L "" #endif -#ifdef S_IFLNK -#define FILE_FLAGS "-bcEhikLlNnprsvzZ0" +#ifdef HAVE_LIBSECCOMP +# define SECCOMP_S "S" #else -#define FILE_FLAGS "-bcEiklNnprsvzZ0" +# define SECCOMP_S "" #endif +#define FILE_FLAGS "bcCdE" IFLNK_h "ik" IFLNK_L "lNnprs" SECCOMP_S "vzZ0" +#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsSvzZ0" + # define USAGE \ - "Usage: %s [" FILE_FLAGS \ - "] [--apple] [--extension] [--mime-encoding] [--mime-type]\n" \ - " [-e testname] [-F separator] [-f namefile] [-m magicfiles] " \ - "file ...\n" \ - " %s -C [-m magicfiles]\n" \ + "Usage: %s [-" FILE_FLAGS "] [--apple] [--extension] [--mime-encoding]\n" \ + " [--mime-type] [-e <testname>] [-F <separator>] " \ + " [-f <namefile>]\n" \ + " [-m <magicfiles>] [-P <parameter=value>] <file> ...\n" \ + " %s -C [-m <magicfiles>]\n" \ " %s [--help]\n" private int /* Global command-line options */ @@ -102,8 +114,7 @@ private const struct option long_options[] = { #undef OPT #undef OPT_LONGONLY {0, 0, NULL, 0} -}; -#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvzZ0" + }; private const struct { const char *name; @@ -135,7 +146,6 @@ private struct { { "bytes", MAGIC_PARAM_BYTES_MAX, 0 }, }; -private char *progname; /* used throughout */ private int posixly; #ifdef __dead @@ -165,9 +175,13 @@ main(int argc, char *argv[]) size_t i; int action = 0, didsomefiles = 0, errflg = 0; int flags = 0, e = 0; +#ifdef HAVE_LIBSECCOMP + int sandbox = 1; +#endif struct magic_set *magic = NULL; int longindex; const char *magicfile = NULL; /* where the magic is */ + char *progname; /* makes islower etc work for other langs */ #ifdef HAVE_SETLOCALE @@ -184,6 +198,9 @@ main(int argc, char *argv[]) else progname = argv[0]; + file_setprogname(progname); + + #ifdef S_IFLNK posixly = getenv("POSIXLY_CORRECT") != NULL; flags |= posixly ? MAGIC_SYMLINK : 0; @@ -280,12 +297,18 @@ main(int argc, char *argv[]) case 's': flags |= MAGIC_DEVICES; break; +#ifdef HAVE_LIBSECCOMP + case 'S': + sandbox = 0; + break; +#endif case 'v': if (magicfile == NULL) magicfile = magic_getpath(magicfile, action); - (void)fprintf(stdout, "%s-%s\n", progname, VERSION); + (void)fprintf(stdout, "%s-%s\n", file_getprogname(), + VERSION); (void)fprintf(stdout, "magic file from %s\n", - magicfile); + magicfile); return 0; case 'z': flags |= MAGIC_COMPRESS; @@ -314,10 +337,19 @@ main(int argc, char *argv[]) if (e) return e; +#ifdef HAVE_LIBSECCOMP +#if 0 + if (sandbox && enable_sandbox_basic() == -1) +#else + if (sandbox && enable_sandbox_full() == -1) +#endif + file_err(EXIT_FAILURE, "SECCOMP initialisation failed"); +#endif /* HAVE_LIBSECCOMP */ + if (MAGIC_VERSION != magic_version()) - (void)fprintf(stderr, "%s: compiled magic version [%d] " + file_warnx("Compiled magic version [%d] " "does not match with shared library magic version [%d]\n", - progname, MAGIC_VERSION, magic_version()); + MAGIC_VERSION, magic_version()); switch(action) { case FILE_CHECK: @@ -329,8 +361,7 @@ main(int argc, char *argv[]) */ magic = magic_open(flags|MAGIC_CHECK); if (magic == NULL) { - (void)fprintf(stderr, "%s: %s\n", progname, - strerror(errno)); + file_warn("Can't create magic"); return 1; } @@ -349,8 +380,7 @@ main(int argc, char *argv[]) abort(); } if (c == -1) { - (void)fprintf(stderr, "%s: %s\n", progname, - magic_error(magic)); + file_warnx("%s", magic_error(magic)); e = 1; goto out; } @@ -398,11 +428,8 @@ applyparam(magic_t magic) for (i = 0; i < __arraycount(pm); i++) { if (pm[i].value == 0) continue; - if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) { - (void)fprintf(stderr, "%s: Can't set %s %s\n", progname, - pm[i].name, strerror(errno)); - exit(1); - } + if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) + file_err(EXIT_FAILURE, "Can't set %s", pm[i].name); } } @@ -422,8 +449,7 @@ setparam(const char *p) return; } badparm: - (void)fprintf(stderr, "%s: Unknown param %s\n", progname, p); - exit(1); + file_errx(EXIT_FAILURE, "Unknown param %s", p); } private struct magic_set * @@ -434,17 +460,16 @@ load(const char *magicfile, int flags) const char *e; if (magic == NULL) { - (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno)); + file_warn("Can't create magic"); return NULL; } if (magic_load(magic, magicfile) == -1) { - (void)fprintf(stderr, "%s: %s\n", - progname, magic_error(magic)); + file_warn("%s", magic_error(magic)); magic_close(magic); return NULL; } if ((e = magic_error(magic)) != NULL) - (void)fprintf(stderr, "%s: Warning: %s\n", progname, e); + file_warn("%s", e); return magic; } @@ -466,8 +491,7 @@ unwrap(struct magic_set *ms, const char *fn) wid = 1; } else { if ((f = fopen(fn, "r")) == NULL) { - (void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n", - progname, fn, strerror(errno)); + file_warn("Cannot open `%s'", fn); return 1; } @@ -567,8 +591,9 @@ file_mbswidth(const char *s) private void usage(void) { - (void)fprintf(stderr, USAGE, progname, progname, progname); - exit(1); + const char *pn = file_getprogname(); + (void)fprintf(stderr, USAGE, pn, pn, pn); + exit(EXIT_FAILURE); } private void @@ -629,5 +654,74 @@ help(void) #undef OPT #undef OPT_LONGONLY fprintf(stdout, "\nReport bugs to http://bugs.gw.com/\n"); - exit(0); + exit(EXIT_SUCCESS); +} + +private const char *file_progname; + +protected void +file_setprogname(const char *progname) +{ + file_progname = progname; +} + +protected const char * +file_getprogname(void) +{ + return file_progname; +} + +protected void +file_err(int e, const char *fmt, ...) +{ + va_list ap; + int se = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, " (%s)\n", strerror(se)); + exit(e); +} + +protected void +file_errx(int e, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(e); +} + +protected void +file_warn(const char *fmt, ...) +{ + va_list ap; + int se = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, " (%s)\n", strerror(se)); + errno = se; +} + +protected void +file_warnx(const char *fmt, ...) +{ + va_list ap; + int se = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + errno = se; } |