summaryrefslogtreecommitdiff
path: root/src/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/file.c')
-rw-r--r--src/file.c119
1 files changed, 79 insertions, 40 deletions
diff --git a/src/file.c b/src/file.c
index 546fd8b..fad3160 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.160 2014/12/16 23:18:40 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.172 2016/10/24 15:21:07 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -68,14 +68,14 @@ int getopt_long(int argc, char * const *argv, const char *optstring, const struc
#endif
#ifdef S_IFLNK
-#define FILE_FLAGS "-bcEhikLlNnprsvz0"
+#define FILE_FLAGS "-bcEhikLlNnprsvzZ0"
#else
-#define FILE_FLAGS "-bcEiklNnprsvz0"
+#define FILE_FLAGS "-bcEiklNnprsvzZ0"
#endif
# define USAGE \
"Usage: %s [" FILE_FLAGS \
- "] [--apple] [--mime-encoding] [--mime-type]\n" \
+ "] [--apple] [--extension] [--mime-encoding] [--mime-type]\n" \
" [-e testname] [-F separator] [-f namefile] [-m magicfiles] " \
"file ...\n" \
" %s -C [-m magicfiles]\n" \
@@ -89,16 +89,21 @@ private int /* Global command-line options */
private const char *separator = ":"; /* Default field separator */
private const struct option long_options[] = {
-#define OPT(shortname, longname, opt, doc) \
+#define OPT_HELP 1
+#define OPT_APPLE 2
+#define OPT_EXTENSIONS 3
+#define OPT_MIME_TYPE 4
+#define OPT_MIME_ENCODING 5
+#define OPT(shortname, longname, opt, def, doc) \
{longname, opt, NULL, shortname},
-#define OPT_LONGONLY(longname, opt, doc) \
- {longname, opt, NULL, 0},
+#define OPT_LONGONLY(longname, opt, def, doc, id) \
+ {longname, opt, NULL, id},
#include "file_opts.h"
#undef OPT
#undef OPT_LONGONLY
{0, 0, NULL, 0}
};
-#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvz0"
+#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvzZ0"
private const struct {
const char *name;
@@ -126,12 +131,21 @@ private struct {
{ "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
{ "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
{ "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 },
+ { "regex", MAGIC_PARAM_REGEX_MAX, 0 },
+ { "bytes", MAGIC_PARAM_BYTES_MAX, 0 },
};
private char *progname; /* used throughout */
+private int posixly;
+#ifdef __dead
+__dead
+#endif
private void usage(void);
-private void docprint(const char *);
+private void docprint(const char *, int);
+#ifdef __dead
+__dead
+#endif
private void help(void);
private int unwrap(struct magic_set *, const char *);
@@ -171,29 +185,29 @@ main(int argc, char *argv[])
progname = argv[0];
#ifdef S_IFLNK
- flags |= getenv("POSIXLY_CORRECT") ? MAGIC_SYMLINK : 0;
+ posixly = getenv("POSIXLY_CORRECT") != NULL;
+ flags |= posixly ? MAGIC_SYMLINK : 0;
#endif
while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
&longindex)) != -1)
switch (c) {
- case 0 :
- switch (longindex) {
- case 0:
- help();
- break;
- case 10:
- flags |= MAGIC_APPLE;
- break;
- case 11:
- flags |= MAGIC_MIME_TYPE;
- break;
- case 12:
- flags |= MAGIC_MIME_ENCODING;
- break;
- }
+ case OPT_HELP:
+ help();
+ break;
+ case OPT_APPLE:
+ flags |= MAGIC_APPLE;
+ break;
+ case OPT_EXTENSIONS:
+ flags |= MAGIC_EXTENSION;
+ break;
+ case OPT_MIME_TYPE:
+ flags |= MAGIC_MIME_TYPE;
+ break;
+ case OPT_MIME_ENCODING:
+ flags |= MAGIC_MIME_ENCODING;
break;
case '0':
- nulsep = 1;
+ nulsep++;
break;
case 'b':
bflag++;
@@ -227,6 +241,7 @@ main(int argc, char *argv[])
if (magic == NULL)
if ((magic = load(magicfile, flags)) == NULL)
return 1;
+ applyparam(magic);
e |= unwrap(magic, optarg);
++didsomefiles;
break;
@@ -262,7 +277,6 @@ main(int argc, char *argv[])
case 'r':
flags |= MAGIC_RAW;
break;
- break;
case 's':
flags |= MAGIC_DEVICES;
break;
@@ -276,6 +290,10 @@ main(int argc, char *argv[])
case 'z':
flags |= MAGIC_COMPRESS;
break;
+
+ case 'Z':
+ flags |= MAGIC_COMPRESS|MAGIC_COMPRESS_TRANSP;
+ break;
#ifdef S_IFLNK
case 'L':
flags |= MAGIC_SYMLINK;
@@ -333,9 +351,10 @@ main(int argc, char *argv[])
if (c == -1) {
(void)fprintf(stderr, "%s: %s\n", progname,
magic_error(magic));
- return 1;
+ e = 1;
+ goto out;
}
- return 0;
+ goto out;
default:
if (magic == NULL)
if ((magic = load(magicfile, flags)) == NULL)
@@ -365,6 +384,7 @@ main(int argc, char *argv[])
e |= process(magic, argv[optind], wid);
}
+out:
if (magic)
magic_close(magic);
return e;
@@ -411,6 +431,8 @@ private struct magic_set *
load(const char *magicfile, int flags)
{
struct magic_set *magic = magic_open(flags);
+ const char *e;
+
if (magic == NULL) {
(void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
return NULL;
@@ -421,6 +443,8 @@ load(const char *magicfile, int flags)
magic_close(magic);
return NULL;
}
+ if ((e = magic_error(magic)) != NULL)
+ (void)fprintf(stderr, "%s: Warning: %s\n", progname, e);
return magic;
}
@@ -477,24 +501,28 @@ unwrap(struct magic_set *ms, const char *fn)
private int
process(struct magic_set *ms, const char *inname, int wid)
{
- const char *type;
+ const char *type, c = nulsep > 1 ? '\0' : '\n';
int std_in = strcmp(inname, "-") == 0;
if (wid > 0 && !bflag) {
(void)printf("%s", std_in ? "/dev/stdin" : inname);
if (nulsep)
(void)putc('\0', stdout);
- (void)printf("%s", separator);
- (void)printf("%*s ",
- (int) (nopad ? 0 : (wid - file_mbswidth(inname))), "");
+ if (nulsep < 2) {
+ (void)printf("%s", separator);
+ (void)printf("%*s ",
+ (int) (nopad ? 0 : (wid - file_mbswidth(inname))),
+ "");
+ }
}
type = magic_file(ms, std_in ? NULL : inname);
+
if (type == NULL) {
- (void)printf("ERROR: %s\n", magic_error(ms));
+ (void)printf("ERROR: %s%c", magic_error(ms), c);
return 1;
} else {
- (void)printf("%s\n", type);
+ (void)printf("%s%c", type, c);
return 0;
}
}
@@ -544,7 +572,17 @@ usage(void)
}
private void
-docprint(const char *opts)
+defprint(int def)
+{
+ if (!def)
+ return;
+ if (((def & 1) && posixly) || ((def & 2) && !posixly))
+ fprintf(stdout, " (default)");
+ fputc('\n', stdout);
+}
+
+private void
+docprint(const char *opts, int def)
{
size_t i;
int comma;
@@ -553,6 +591,7 @@ docprint(const char *opts)
p = strstr(opts, "%o");
if (p == NULL) {
fprintf(stdout, "%s", opts);
+ defprint(def);
return;
}
@@ -580,12 +619,12 @@ help(void)
"Usage: file [OPTION...] [FILE...]\n"
"Determine type of FILEs.\n"
"\n", stdout);
-#define OPT(shortname, longname, opt, doc) \
+#define OPT(shortname, longname, opt, def, doc) \
fprintf(stdout, " -%c, --" longname, shortname), \
- docprint(doc);
-#define OPT_LONGONLY(longname, opt, doc) \
+ docprint(doc, def);
+#define OPT_LONGONLY(longname, opt, def, doc, id) \
fprintf(stdout, " --" longname), \
- docprint(doc);
+ docprint(doc, def);
#include "file_opts.h"
#undef OPT
#undef OPT_LONGONLY