From 4a331f956fd6b7e411f3c800267b09dcc7ec3b1d Mon Sep 17 00:00:00 2001 From: Christos Zoulas Date: Tue, 14 Oct 2003 19:17:17 +0000 Subject: [PATCH] Add MAGIC_ERROR --- src/apprentice.c | 33 +++++------- src/apptype.c | 17 +++---- src/compress.c | 23 ++++----- src/file.h | 5 +- src/fsmagic.c | 130 ++++++++++++++++++++++++++++------------------- src/funcs.c | 12 +++-- src/magic.c | 5 +- src/magic.h | 1 + src/readelf.c | 8 +-- src/softmagic.c | 13 ++--- 10 files changed, 134 insertions(+), 113 deletions(-) diff --git a/src/apprentice.c b/src/apprentice.c index 351c9303..6ec89813 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -50,7 +50,7 @@ #endif #ifndef lint -FILE_RCSID("@(#)$Id: apprentice.c,v 1.67 2003/10/08 17:18:28 christos Exp $") +FILE_RCSID("@(#)$Id: apprentice.c,v 1.68 2003/10/14 19:17:17 christos Exp $") #endif /* lint */ #define EATAB {while (isascii((unsigned char) *l) && \ @@ -138,7 +138,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action, int mapped; if (magicsize != FILE_MAGICSIZE) { - file_error(ms, "Magic element size %lu != %lu", + file_error(ms, 0, "Magic element size %lu != %lu", (unsigned long)sizeof(*magic), (unsigned long)FILE_MAGICSIZE); return -1; @@ -266,7 +266,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action) free(mfn); free(mlist); mlist = NULL; - file_error(ms, "Couldn't find any magic files!"); + file_error(ms, 0, "Couldn't find any magic files!"); return NULL; } return mlist; @@ -290,8 +290,7 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, f = fopen(fn, "r"); if (f == NULL) { if (errno != ENOENT) - file_error(ms, "Can't read magic file %s (%s)", - fn, strerror(errno)); + file_error(ms, errno, "Can't read magic file %s", fn); return -1; } @@ -759,7 +758,7 @@ getstr(struct magic_set *ms, char *s, char *p, int plen, int *slen) if (isspace((unsigned char) c)) break; if (p >= pmax) { - file_error(ms, "String too long: `%s'", origs); + file_error(ms, 0, "String too long: `%s'", origs); return NULL; } if(c == '\\') { @@ -967,15 +966,14 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, return -1; if (fstat(fd, &st) == -1) { - file_error(ms, "Cannot stat `%s' (%s)", dbname, - strerror(errno)); + file_error(ms, errno, "Cannot stat `%s'", dbname); goto error; } #ifdef QUICK if ((mm = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) { - file_error(ms, "Cannot map `%s' (%s)", dbname, strerror(errno)); + file_error(ms, errno, "Cannot map `%s'", dbname); goto error; } #define RET 2 @@ -985,7 +983,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, goto error; } if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) { - file_error(ms, "Read failed (%s)", strerror(errno)); + file_error(ms, errno, "Read failed"); goto error; } #define RET 1 @@ -996,7 +994,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, ptr = (uint32_t *)(void *)*magicp; if (*ptr != MAGICNO) { if (swap4(*ptr) != MAGICNO) { - file_error(ms, "Bad magic in `%s'", dbname); + file_error(ms, 0, "Bad magic in `%s'"); goto error; } needsbyteswap = 1; @@ -1007,7 +1005,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, else version = ptr[1]; if (version != VERSIONNO) { - file_error(ms, "version mismatch (%d != %d) in `%s'", + file_error(ms, 0, "version mismatch (%d != %d) in `%s'", version, VERSIONNO, dbname); goto error; } @@ -1051,27 +1049,24 @@ apprentice_compile(struct magic_set *ms, struct magic **magicp, return -1; if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { - file_error(ms, "Cannot open `%s' (%s)", dbname, strerror(errno)); + file_error(ms, errno, "Cannot open `%s'", dbname); return -1; } if (write(fd, ar, sizeof(ar)) != (ssize_t)sizeof(ar)) { - file_error(ms, "Error writing `%s' (%s)", dbname, - strerror(errno)); + file_error(ms, errno, "Error writing `%s'", dbname); return -1; } if (lseek(fd, (off_t)sizeof(struct magic), SEEK_SET) != sizeof(struct magic)) { - file_error(ms, "Error seeking `%s' (%s)", dbname, - strerror(errno)); + file_error(ms, errno, "Error seeking `%s'", dbname); return -1; } if (write(fd, *magicp, (sizeof(struct magic) * *nmagicp)) != (ssize_t)(sizeof(struct magic) * *nmagicp)) { - file_error(ms, "Error writing `%s' (%s)", dbname, - strerror(errno)); + file_error(ms, errno, "Error writing `%s'", dbname); return -1; } diff --git a/src/apptype.c b/src/apptype.c index 95a53536..35f4fbb3 100644 --- a/src/apptype.c +++ b/src/apptype.c @@ -31,7 +31,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$Id: apptype.c,v 1.3 2003/06/10 18:28:37 christos Exp $") +FILE_RCSID("@(#)$Id: apptype.c,v 1.4 2003/10/14 19:17:17 christos Exp $") #endif /* lint */ #ifdef __EMX__ @@ -47,32 +47,31 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, size_t nb) { APPTYPE rc, type; - char path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], - ext[_MAX_EXT]; + char path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], + fname[_MAX_FNAME], ext[_MAX_EXT]; char *filename; FILE *fp; if (fn) filename = strdup(fn); else if ((filename = tempnam("./", "tmp")) == NULL) { - error("can't create tempnam (%s).\n", strerror(errno)); + file_error(ms, errno, "Can't create tempnam"); + return -1; } /* qualify the filename to prevent extraneous searches */ _splitpath(filename, drive, dir, fname, ext); - sprintf(path, "%s%s%s%s", drive, + (void)sprintf(path, "%s%s%s%s", drive, (*dir == '\0') ? "./" : dir, fname, (*ext == '\0') ? "." : ext); if (fn == NULL) { if ((fp = fopen(path, "wb")) == NULL) { - file_error("Can't open tmp file `%s' (%s)", path, - strerror(errno)); + file_error(ms, errno, "Can't open tmp file `%s'", path); return -1; } if (fwrite(buf, 1, nb, fp) != nb) { - file_error("Can't write tmp file `%s' (%s)", path, - strerror(errno)); + file_error(ms, errno, "Can't write tmp file `%s'", path); return -1; } (void)fclose(fp); diff --git a/src/compress.c b/src/compress.c index 1b3d6b8f..4393b0d8 100644 --- a/src/compress.c +++ b/src/compress.c @@ -56,7 +56,7 @@ #endif #ifndef lint -FILE_RCSID("@(#)$Id: compress.c,v 1.32 2003/05/23 21:31:58 christos Exp $") +FILE_RCSID("@(#)$Id: compress.c,v 1.33 2003/10/14 19:17:17 christos Exp $") #endif @@ -200,8 +200,8 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, errno = r; #endif if (tfd == -1) { - file_error(ms, "Can't create temporary file for pipe copy (%s)", - strerror(errno)); + file_error(ms, errno, + "Can't create temporary file for pipe copy"); return -1; } @@ -215,14 +215,12 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, switch (r) { case -1: - file_error(ms, "Error copying from pipe to temp file (%s)", - strerror(errno)); + file_error(ms, errno, "Error copying from pipe to temp file"); return -1; case 0: break; default: - file_error(ms, "Error while writing to temp file (%s)", - strerror(errno)); + file_error(ms, errno, "Error while writing to temp file"); return -1; } @@ -232,8 +230,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, * can still access the phantom inode. */ if ((fd = dup2(tfd, fd)) == -1) { - file_error(ms, "Couldn't dup destcriptor for temp file (%s)", - strerror(errno)); + file_error(ms, errno, "Couldn't dup destcriptor for temp file"); return -1; } (void)close(tfd); @@ -296,13 +293,13 @@ uncompressgzipped(struct magic_set *ms, const unsigned char *old, rc = inflateInit2(&z, -15); if (rc != Z_OK) { - file_error(ms, "zlib: %s", z.msg); + file_error(ms, 0, "zlib: %s", z.msg); return 0; } rc = inflate(&z, Z_SYNC_FLUSH); if (rc != Z_OK && rc != Z_STREAM_END) { - file_error(ms, "zlib: %s", z.msg); + file_error(ms, 0, "zlib: %s", z.msg); return 0; } @@ -332,7 +329,7 @@ uncompressbuf(struct magic_set *ms, size_t method, const unsigned char *old, #endif if (pipe(fdin) == -1 || pipe(fdout) == -1) { - file_error(ms, "Cannot create pipe (%s)", strerror(errno)); + file_error(ms, errno, "Cannot create pipe"); return 0; } switch (fork()) { @@ -354,7 +351,7 @@ uncompressbuf(struct magic_set *ms, size_t method, const unsigned char *old, exit(1); /*NOTREACHED*/ case -1: - file_error(ms, "Could not fork (%s)", strerror(errno)); + file_error(ms, errno, "Could not fork"); return 0; default: /* parent */ diff --git a/src/file.h b/src/file.h index 3d2cb2cf..86344f53 100644 --- a/src/file.h +++ b/src/file.h @@ -32,7 +32,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$Id: file.h,v 1.58 2003/10/09 15:15:23 christos Exp $ + * @(#)$Id: file.h,v 1.59 2003/10/14 19:17:17 christos Exp $ */ #ifndef __file_h__ @@ -187,6 +187,7 @@ struct magic_set { char *pbuf; size_t psize; } o; + int error; int flags; int haderr; }; @@ -209,7 +210,7 @@ protected void file_delmagic(struct magic *, int type, size_t entries); protected void file_badread(struct magic_set *); protected void file_badseek(struct magic_set *); protected void file_oomem(struct magic_set *); -protected void file_error(struct magic_set *, const char *, ...); +protected void file_error(struct magic_set *, int, const char *, ...); protected void file_magwarn(const char *, ...); protected void file_mdump(struct magic *); protected void file_showstr(FILE *, const char *, size_t); diff --git a/src/fsmagic.c b/src/fsmagic.c index e51373ea..731b3b9d 100644 --- a/src/fsmagic.c +++ b/src/fsmagic.c @@ -62,13 +62,18 @@ #undef HAVE_MAJOR #ifndef lint -FILE_RCSID("@(#)$Id: fsmagic.c,v 1.41 2003/05/23 21:31:58 christos Exp $") +FILE_RCSID("@(#)$Id: fsmagic.c,v 1.42 2003/10/14 19:17:17 christos Exp $") #endif /* lint */ protected int file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) { int ret = 0; +#ifdef S_IFLNK + char buf[BUFSIZ+4]; + int nch; + struct stat tstatbuf; +#endif if (fn == NULL) return 0; @@ -85,6 +90,10 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) ret = stat(fn, sb); /* don't merge into if; see "ret =" above */ if (ret) { + if (ms->flags & MAGIC_ERROR) { + file_error(ms, errno, "Can't stat `%s'", fn); + return -1; + } if (file_printf(ms, "Can't stat `%s' (%s)", fn, strerror(errno)) == -1) return -1; @@ -189,69 +198,84 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) #endif #ifdef S_IFLNK case S_IFLNK: - { - char buf[BUFSIZ+4]; - int nch; - struct stat tstatbuf; - - if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) { - if (file_printf(ms, - "unreadable symlink `%s' (%s)", - strerror(errno)) == -1) - return -1; - return 1; + if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) { + if (ms->flags & MAGIC_ERROR) { + file_error(ms, errno, "unreadable symlink `%s'", + fn); + return -1; } - buf[nch] = '\0'; /* readlink(2) forgets this */ + if (file_printf(ms, + "unreadable symlink `%s' (%s)", fn, + strerror(errno)) == -1) + return -1; + return 1; + } + buf[nch] = '\0'; /* readlink(2) forgets this */ - /* If broken symlink, say so and quit early. */ - if (*buf == '/') { - if (stat(buf, &tstatbuf) < 0) { - if (file_printf(ms, - "broken symbolic link to `%s'", buf) == -1) - return -1; - return 1; - } - } - else { - char *tmp; - char buf2[BUFSIZ+BUFSIZ+4]; + /* If broken symlink, say so and quit early. */ + if (*buf == '/') { + if (stat(buf, &tstatbuf) < 0) { + if (ms->flags & MAGIC_ERROR) { + file_error(ms, errno, + "broken symbolic link to `%s'", buf); + return -1; + } + if (file_printf(ms, "broken symbolic link to `%s'", + buf) == -1) + return -1; + return 1; + } + } + else { + char *tmp; + char buf2[BUFSIZ+BUFSIZ+4]; - if ((tmp = strrchr(fn, '/')) == NULL) { + if ((tmp = strrchr(fn, '/')) == NULL) { tmp = buf; /* in current directory anyway */ - } - else { + } else { if (tmp - fn + 1 > BUFSIZ) { - file_printf(ms, "path too long: `%s'", fn); - return -1; + if (ms->flags & MAGIC_ERROR) { + file_error(ms, 0, + "path too long: `%s'", buf); + return -1; + } + if (file_printf(ms, + "path too long: `%s'", fn) == -1) + return -1; + return 1; } - strcpy(buf2, fn); /* take directory part */ - buf2[tmp-fn+1] = '\0'; - strcat(buf2, buf); /* plus (relative) symlink */ + (void)strcpy(buf2, fn); /* take dir part */ + buf2[tmp - fn + 1] = '\0'; + (void)strcat(buf2, buf); /* plus (rel) link */ tmp = buf2; - } - if (stat(tmp, &tstatbuf) < 0) { + } + if (stat(tmp, &tstatbuf) < 0) { + if (ms->flags & MAGIC_ERROR) { + file_error(ms, errno, + "broken symbolic link to `%s'", + buf); + return -1; + } if (file_printf(ms, - "broken symbolic link to `%s'", - buf) == -1) + "broken symbolic link to `%s'", buf) == -1) return -1; return 1; - } - } - - /* Otherwise, handle it. */ - if ((ms->flags & MAGIC_SYMLINK) != 0) { - const char *p; - ms->flags &= MAGIC_SYMLINK; - p = magic_file(ms, buf); - ms->flags |= MAGIC_SYMLINK; - return p != NULL ? 1 : -1; - } else { /* just print what it points to */ - if (file_printf(ms, "symbolic link to `%s'", - buf) == -1) - return -1; } } - return 1; + + /* Otherwise, handle it. */ + if ((ms->flags & MAGIC_SYMLINK) != 0) { + const char *p; + ms->flags &= MAGIC_SYMLINK; + p = magic_file(ms, buf); + ms->flags |= MAGIC_SYMLINK; + return p != NULL ? 1 : -1; + } else { /* just print what it points to */ + if (file_printf(ms, "symbolic link to `%s'", + buf) == -1) + return -1; + } + return 1; #endif #ifdef S_IFSOCK #ifndef __COHERENT__ @@ -264,7 +288,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) case S_IFREG: break; default: - file_error(ms, "invalid mode 0%o", sb->st_mode); + file_error(ms, 0, "invalid mode 0%o", sb->st_mode); return -1; /*NOTREACHED*/ } diff --git a/src/funcs.c b/src/funcs.c index afb7555c..54f4c1f7 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -70,7 +70,7 @@ file_printf(struct magic_set *ms, const char *fmt, ...) */ /*VARARGS*/ protected void -file_error(struct magic_set *ms, const char *f, ...) +file_error(struct magic_set *ms, int error, const char *f, ...) { va_list va; /* Only the first error is ok */ @@ -79,6 +79,7 @@ file_error(struct magic_set *ms, const char *f, ...) va_start(va, f); (void) vsnprintf(ms->o.buf, ms->o.size, f, va); ms->haderr++; + ms->error = error; va_end(va); } @@ -86,19 +87,19 @@ file_error(struct magic_set *ms, const char *f, ...) protected void file_oomem(struct magic_set *ms) { - file_error(ms, "%s", strerror(errno)); + file_error(ms, errno, "Cannot allocate memory"); } protected void file_badseek(struct magic_set *ms) { - file_error(ms, "Error seeking (%s)", strerror(errno)); + file_error(ms, errno, "Error seeking"); } protected void file_badread(struct magic_set *ms) { - file_error(ms, "Error reading (%s)", strerror(errno)); + file_error(ms, errno, "Error reading"); } protected int @@ -129,11 +130,12 @@ protected int file_reset(struct magic_set *ms) { if (ms->mlist == NULL) { - file_error(ms, "No magic files loaded"); + file_error(ms, 0, "No magic files loaded"); return -1; } ms->o.ptr = ms->o.buf; ms->haderr = 0; + ms->error = -1; return 0; } diff --git a/src/magic.c b/src/magic.c index f5473aad..ddd9b0aa 100644 --- a/src/magic.c +++ b/src/magic.c @@ -65,7 +65,7 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$Id: magic.c,v 1.12 2003/10/09 15:15:23 christos Exp $") +FILE_RCSID("@(#)$Id: magic.c,v 1.13 2003/10/14 19:17:17 christos Exp $") #endif /* lint */ #ifdef __EMX__ @@ -112,6 +112,7 @@ magic_open(int flags) return NULL; } ms->haderr = 0; + ms->error = -1; ms->mlist = NULL; return ms; } @@ -246,7 +247,7 @@ magic_file(struct magic_set *ms, const char *inname) * try looking at the first HOWMANY bytes */ if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) { - file_error(ms, "Cannot read `%s' %s", inname, strerror(errno)); + file_error(ms, errno, "Cannot read `%s'", inname); goto done; } diff --git a/src/magic.h b/src/magic.h index 9d839d97..5b37b3b4 100644 --- a/src/magic.h +++ b/src/magic.h @@ -41,6 +41,7 @@ #define MAGIC_CHECK 0x040 /* Print warnings to stderr */ #define MAGIC_PRESERVE_ATIME 0x080 /* Restore access time on exit */ #define MAGIC_RAW 0x100 /* Don't translate unprintable chars */ +#define MAGIC_ERROR 0x200 /* Handle ENOENT etc as real errors */ #ifdef __cplusplus extern "C" { diff --git a/src/readelf.c b/src/readelf.c index 2db267dc..3e69ce21 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -39,7 +39,7 @@ #include "readelf.h" #ifndef lint -FILE_RCSID("@(#)$Id: readelf.c,v 1.33 2003/09/16 15:38:46 christos Exp $") +FILE_RCSID("@(#)$Id: readelf.c,v 1.34 2003/10/14 19:17:17 christos Exp $") #endif #ifdef ELFCORE @@ -222,7 +222,7 @@ dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off, ssize_t bufsize; if (size != ph_size) { - file_error(ms, "Corrupted program header size"); + file_error(ms, 0, "Corrupted program header size"); return -1; } /* @@ -543,7 +543,7 @@ doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num, Elf64_Shdr sh64; if (size != sh_size) { - file_error(ms, "Corrupted section header size"); + file_error(ms, 0, "Corrupted section header size"); return -1; } @@ -587,7 +587,7 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off, off_t savedoffset; if (size != ph_size) { - file_error(ms, "Corrupted program header size"); + file_error(ms, 0, "Corrupted program header size"); return -1; } if (lseek(fd, off, SEEK_SET) == (off_t)-1) { diff --git a/src/softmagic.c b/src/softmagic.c index c3a03c31..6631ad87 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -44,7 +44,7 @@ #ifndef lint -FILE_RCSID("@(#)$Id: softmagic.c,v 1.60 2003/06/10 18:28:37 christos Exp $") +FILE_RCSID("@(#)$Id: softmagic.c,v 1.61 2003/10/14 19:17:17 christos Exp $") #endif /* lint */ private int match(struct magic_set *, struct magic *, uint32_t, @@ -315,7 +315,7 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m) break; default: - file_error(ms, "invalid m->type (%d) in mprint()", m->type); + file_error(ms, 0, "invalid m->type (%d) in mprint()", m->type); return -1; } return(t); @@ -587,7 +587,7 @@ mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m) case FILE_REGEX: return 1; default: - file_error(ms, "invalid type %d in mconvert()", m->type); + file_error(ms, 0, "invalid type %d in mconvert()", m->type); return 0; } } @@ -1074,7 +1074,7 @@ mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m) if (rc) { free(p->buf); regerror(rc, &rx, errmsg, sizeof(errmsg)); - file_error(ms, "regex error %d, (%s)", rc, errmsg); + file_error(ms, 0, "regex error %d, (%s)", rc, errmsg); return -1; } else { rc = regexec(&rx, p->buf, 0, 0, 0); @@ -1083,7 +1083,7 @@ mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m) } } default: - file_error(ms, "invalid type %d in mcheck()", m->type); + file_error(ms, 0, "invalid type %d in mcheck()", m->type); return -1; } @@ -1157,7 +1157,8 @@ mcheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m) default: matched = 0; - file_error(ms, "can't happen: invalid relation `%c'", m->reln); + file_error(ms, 0, "can't happen: invalid relation `%c'", + m->reln); return -1; } -- 2.50.1