lclint annotations.
authorjbj <devnull@localhost>
Tue, 1 Oct 2002 11:16:54 +0000 (11:16 +0000)
committerjbj <devnull@localhost>
Tue, 1 Oct 2002 11:16:54 +0000 (11:16 +0000)
CVS patchset: 5740
CVS date: 2002/10/01 11:16:54

13 files changed:
file/.lclintrc
file/apprentice.c
file/ascmagic.c
file/compress.c
file/file.c
file/file.h
file/fsmagic.c
file/is_tar.c
file/names.h
file/print.c
file/readelf.c
file/softmagic.c
file/tar.h

index e49b67b..8a2e54d 100644 (file)
 +strict                        # lclint level
 
 # --- in progress
--branchstate
--compdef
--compmempass
--declundef
--evalorderuncon
--exitarg
--exportheader
--exportheadervar
--exportlocal
--formatconst
--globs
--globstate
--internalglobs
--macroredef
--modfilesys
--modnomods
--modobserver
--modobserveruncon
--modunconnomods
--mustmod
--noeffectuncon
--noparams
--noret
--nullassign
--nullderef
--nullpass
--nullptrarith
--nullret
--nullstate
--paramuse
--protoparammatch
--redecl
--redef
--retalias
+-branchstate           # 4
+-exitarg               # 6
+-exportheader          # 19
+-formatconst           # 9
+-globstate             # 3
+-globuse               # 4
+-macroredef            # 1
+-modobserver           # 2
+-mods                  # 7
+-moduncon              # 4
+-modunconnomods                # 12 ctype.h
+-mustmod               # 6
+-noeffectuncon         # 1
+-noparams              # 44 zlib
+-nullderef             # 2
+-nullpass              # 6
+-nullptrarith          # 1
+-paramuse              # 2
+-redecl                        # 1
+-redef                 # 4
 -retvalint
--retvalother
 -shadow
--sizeoftype
--type
--uniondef
--usereleased
--usevarargs
--varuse
--warnlintcomments
-
--dependenttrans
--immediatetrans
--kepttrans
--observertrans
--onlytrans
--readonlytrans
--statictrans
--temptrans
--unqualifiedtrans
-
--casebreak
--looploopbreak
--looploopcontinue
--loopswitchbreak
--switchloopbreak
--switchswitchbreak
--unreachable
+-sizeoftype            # 29
+-type                  # 2 zlib
+-uniondef              # 6
+-usereleased           # 1
+-usevarargs            # 1
+-warnmissingglobs      # 2
+
+-dependenttrans                # 2
+-immediatetrans                # 2
+-kepttrans             # 1
+-observertrans         # 4
+-temptrans             # 1
+-unqualifiedtrans      # 2
+
 -whileempty
 
 # --- +partial artifacts
+-declundef             # 32 tar.h
+-exportheadervar
+-exportlocal
+
+-varuse                        # 5
 
 # --- not-yet at strict level
 -bitwisesigned         # pita
 -elseifcomplete                # 95 occurences
--exportconst           # 839 occurences
--exportfcn
--exporttype
--exportvar
--fielduse              # 1 occurence <bits/sigset.h>
+-fielduse              # 21 tar.h
 -forblock              # tedious
 -ifblock               # tedious
 -incondefs             # <bits/{ipc,pthreadtypes}.h> heartburn
--matchfields           # <bits/ipc.h> heartburn
 -namechecks            # tedious ANSI compliance checks
 -ptrarith              # tedious
 
 -compdestroy
 -mustdefine
--shiftimplementation
--shiftnegative
+-shiftimplementation   # 148 ctype.h
 
 -strictops
 -strictusereleased
index 1bb71d9..60c3f3e 100644 (file)
  */
 
 #include "file.h"
-#include <stdio.h>
 #include <stdlib.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <string.h>
 #include <ctype.h>
-#include <errno.h>
-#ifdef QUICK
 #include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#ifdef QUICK
 #include <sys/mman.h>
 #endif
 
 #ifndef        lint
-FILE_RCSID("@(#)Id: apprentice.c,v 1.44 2001/08/01 14:03:19 christos Exp ")
+FILE_RCSID("@(#)Id: apprentice.c,v 1.49 2002/07/03 19:00:41 christos Exp ")
 #endif /* lint */
 
 #define        EATAB {while (isascii((unsigned char) *l) && \
@@ -67,46 +63,73 @@ FILE_RCSID("@(#)Id: apprentice.c,v 1.44 2001/08/01 14:03:19 christos Exp ")
 #define MAP_FILE 0
 #endif
 
+/*@unchecked@*/
 #ifdef __EMX__
   char PATHSEP=';';
 #else
   char PATHSEP=':';
 #endif
 
-
-static int getvalue    __P((struct magic *, char **));
-static int hextoint    __P((int));
-static char *getstr    __P((char *, char *, int, int *));
-static int parse       __P((struct magic **, uint32 *, char *, int));
-static void eatsize    __P((char **));
-static int apprentice_1        __P((const char *, int));
-static int apprentice_file     __P((struct magic **, uint32 *,
-    const char *, int));
-static void byteswap   __P((struct magic *, uint32));
-static void bs1                __P((struct magic *));
-static uint16 swap2    __P((uint16));
-static uint32 swap4    __P((uint32));
-static char *mkdbname  __P((const char *));
-static int apprentice_map      __P((struct magic **, uint32 *,
-    const char *, int));
-static int apprentice_compile  __P((struct magic **, uint32 *,
-    const char *, int));
-
+/*@unchecked@*/
 static int maxmagic = 0;
 
+/*@unchecked@*/
 struct mlist mlist;
 
+
+static int getvalue(struct magic *m, /*@out@*/ char **p)
+       /*@globals fileSystem @*/
+       /*@modifies m, *p, fileSystem @*/;
+static int hextoint(int c)
+       /*@*/;
+static char *getstr(/*@returned@*/ char *s, char *p, int plen,
+               /*@out@*/ int * slen)
+       /*@globals fileSystem @*/
+       /*@modifies *p, *slen, fileSystem @*/;
+static int parse(/*@out@*/ struct magic **magicp,
+               /*@out@*/ uint32_t *nmagicp, char *l, int action)
+       /*@globals maxmagic, fileSystem @*/
+       /*@modifies *magicp, *nmagicp, maxmagic, fileSystem @*/;
+static void eatsize(/*@out@*/ char **p)
+       /*@modifies *p @*/;
+static int apprentice_1(const char *fn, int action)
+       /*@globals lineno, mlist, fileSystem @*/
+       /*@modifies lineno, mlist, fileSystem @*/;
+static int apprentice_file(/*@out@*/ struct magic **magicp,
+               /*@out@*/ uint32_t *nmagicp, const char *fn, int action)
+       /*@globals lineno, maxmagic, fileSystem @*/
+       /*@modifies *magicp, *nmagicp, lineno, maxmagic, fileSystem @*/;
+static void byteswap(struct magic *magic, uint32_t nmagic)
+       /*@modifies magic @*/;
+static void bs1(struct magic *m)
+       /*@modifies m @*/;
+static uint16_t swap2(uint16_t sv)
+       /*@*/;
+static uint32_t swap4(uint32_t sv)
+       /*@*/;
+/*@null@*/
+static char *mkdbname(const char *fn)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+static int apprentice_map(/*@out@*/ struct magic **magicp,
+               /*@out@*/ uint32_t *nmagicp, const char *fn, int action)
+       /*@globals fileSystem @*/
+       /*@modifies *magicp, *nmagicp, fileSystem @*/;
+static int apprentice_compile(/*@out@*/ struct magic **magicp,
+               /*@out@*/ uint32_t *nmagicp, const char *fn, int action)
+       /*@globals fileSystem @*/
+       /*@modifies *magicp, *nmagicp, fileSystem @*/;
+
 #ifdef COMPILE_ONLY
 const char *magicfile;
 char *progname;
 int lineno;
 
-int main __P((int, char *[]));
+int main(int argc, char *argv[])
+       /*@*/;
 
 int
-main(argc, argv)
-       int argc;
-       char *argv[];
+main(int argc, char *argv[])
 {
        int ret;
 
@@ -130,12 +153,10 @@ main(argc, argv)
  * Handle one file.
  */
 static int
-apprentice_1(fn, action)
-       const char *fn;
-       int action;
+apprentice_1(const char *fn, int action)
 {
        struct magic *magic = NULL;
-       uint32 nmagic = 0;
+       uint32_t nmagic = 0;
        struct mlist *ml;
        int rv = -1;
 
@@ -180,10 +201,9 @@ apprentice_1(fn, action)
 }
 
 
+/* const char *fn: list of magic files */
 int
-apprentice(fn, action)
-       const char *fn;                 /* list of magic files */
-       int action;
+apprentice(const char *fn, int action)
 {
        char *p, *mfn;
        int file_err, errs = -1;
@@ -221,13 +241,11 @@ apprentice(fn, action)
 
 /*
  * parse from a file
+ * const char *fn: name of magic file
  */
 static int
-apprentice_file(magicp, nmagicp, fn, action)
-       struct magic **magicp;
-       uint32 *nmagicp;
-       const char *fn;                 /* name of magic file */
-       int action;
+apprentice_file(struct magic **magicp, uint32_t *nmagicp, const char *fn,
+               int action)
 {
        static const char hdr[] =
                "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
@@ -279,10 +297,8 @@ apprentice_file(magicp, nmagicp, fn, action)
 /*
  * extend the sign bit if the comparison is to be signed
  */
-uint32
-signextend(m, v)
-       struct magic *m;
-       uint32 v;
+uint32_t
+signextend(struct magic *m, uint32_t v)
 {
        if (!(m->flag & UNSIGNED))
                switch(m->type) {
@@ -308,11 +324,13 @@ signextend(m, v)
                case LONG:
                case BELONG:
                case LELONG:
-                       v = (int32) v;
+                       v = (int32_t) v;
                        break;
                case STRING:
                case PSTRING:
                        break;
+               case REGEX:
+                       break;
                default:
                        magwarn("can't happen: m->type=%d\n",
                                m->type);
@@ -325,11 +343,7 @@ signextend(m, v)
  * parse one line from magic file, put into magic[index++] if valid
  */
 static int
-parse(magicp, nmagicp, l, action)
-       struct magic **magicp;
-       uint32 *nmagicp;
-       char *l;
-       int action;
+parse(struct magic **magicp, uint32_t *nmagicp, char *l, int action)
 {
        int i = 0;
        struct magic *m;
@@ -479,6 +493,7 @@ parse(magicp, nmagicp, l, action)
 #define NLDATE         5
 #define NBELDATE       7
 #define NLELDATE       7
+#define NREGEX         5
 
        if (*l == 'u') {
                ++l;
@@ -534,6 +549,9 @@ parse(magicp, nmagicp, l, action)
        } else if (strncmp(l, "leldate", NLELDATE)==0) {
                m->type = LELDATE;
                l += NLELDATE;
+       } else if (strncmp(l, "regex", NREGEX)==0) {
+               m->type = REGEX;
+               l += sizeof("regex");
        } else {
                magwarn("type %s invalid", l);
                return -1;
@@ -600,14 +618,14 @@ parse(magicp, nmagicp, l, action)
                                switch (*l) {
                                case CHAR_IGNORE_LOWERCASE:
                                        m->mask |= STRING_IGNORE_LOWERCASE;
-                                       break;
+                                       /*@switchbreak@*/ break;
                                case CHAR_COMPACT_BLANK:
                                        m->mask |= STRING_COMPACT_BLANK;
-                                       break;
+                                       /*@switchbreak@*/ break;
                                case CHAR_COMPACT_OPTIONAL_BLANK:
                                        m->mask |=
                                            STRING_COMPACT_OPTIONAL_BLANK;
-                                       break;
+                                       /*@switchbreak@*/ break;
                                default:
                                        magwarn("string extension %c invalid",
                                            *l);
@@ -641,7 +659,7 @@ parse(magicp, nmagicp, l, action)
                        ++l;
                        break;
                }
-               /* FALL THROUGH */
+               /*@fallthrough@*/
        default:
                if (*l == 'x' && isascii((unsigned char)l[1]) && 
                    isspace((unsigned char)l[1])) {
@@ -679,9 +697,11 @@ GetDesc:
        while ((m->desc[i++] = *l++) != '\0' && i<MAXDESC)
                /* NULLBODY */;
 
+#ifndef COMPILE_ONLY
        if (action == CHECK) {
                mdump(m);
        }
+#endif
        ++(*nmagicp);           /* make room for next */
        return 0;
 }
@@ -692,13 +712,11 @@ GetDesc:
  * just after the number read.  Return 0 for success, non-zero for failure.
  */
 static int
-getvalue(m, p)
-       struct magic *m;
-       char **p;
+getvalue(struct magic *m, char **p)
 {
        int slen;
 
-       if (m->type == STRING || m->type == PSTRING) {
+       if (m->type == STRING || m->type == PSTRING || m->type == REGEX) {
                *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
                m->vallen = slen;
        } else
@@ -716,10 +734,7 @@ getvalue(m, p)
  * Return updated scan pointer as function result.
  */
 static char *
-getstr(s, p, plen, slen)
-       char    *s;
-       char    *p;
-       int     plen, *slen;
+getstr(char *s, char *p, int plen, int *slen)
 {
        char    *origs = s, *origp = p;
        char    *pmax = p + plen - 1;
@@ -741,31 +756,31 @@ getstr(s, p, plen, slen)
 
                        default:
                                *p++ = (char) c;
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case 'n':
                                *p++ = '\n';
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case 'r':
                                *p++ = '\r';
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case 'b':
                                *p++ = '\b';
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case 't':
                                *p++ = '\t';
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case 'f':
                                *p++ = '\f';
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case 'v':
                                *p++ = '\v';
-                               break;
+                               /*@switchbreak@*/ break;
 
                        /* \ and up to 3 octal digits */
                        case '0':
@@ -789,7 +804,7 @@ getstr(s, p, plen, slen)
                                else
                                        --s;
                                *p++ = (char)val;
-                               break;
+                               /*@switchbreak@*/ break;
 
                        /* \x and up to 2 hex digits */
                        case 'x':
@@ -805,7 +820,7 @@ getstr(s, p, plen, slen)
                                } else
                                        --s;
                                *p++ = (char)val;
-                               break;
+                               /*@switchbreak@*/ break;
                        }
                } else
                        *p++ = (char)c;
@@ -819,8 +834,7 @@ out:
 
 /* Single hex char to int; -1 if not a hex char. */
 static int
-hextoint(c)
-       int c;
+hextoint(int c)
 {
        if (!isascii((unsigned char) c))
                return -1;
@@ -838,10 +852,7 @@ hextoint(c)
  * Print a string containing C character escapes.
  */
 void
-showstr(fp, s, len)
-       FILE *fp;
-       const char *s;
-       int len;
+showstr(FILE *fp, const char *s, int len)
 {
        char    c;
 
@@ -863,31 +874,31 @@ showstr(fp, s, len)
                        
                        case '\n':
                                (void) fputc('n', fp);
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case '\r':
                                (void) fputc('r', fp);
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case '\b':
                                (void) fputc('b', fp);
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case '\t':
                                (void) fputc('t', fp);
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case '\f':
                                (void) fputc('f', fp);
-                               break;
+                               /*@switchbreak@*/ break;
 
                        case '\v':
                                (void) fputc('v', fp);
-                               break;
+                               /*@switchbreak@*/ break;
 
                        default:
                                (void) fprintf(fp, "%.3o", c & 0377);
-                               break;
+                               /*@switchbreak@*/ break;
                        }
                }
        }
@@ -897,8 +908,7 @@ showstr(fp, s, len)
  * eatsize(): Eat the size spec from a number [eg. 10UL]
  */
 static void
-eatsize(p)
-       char **p;
+eatsize(char **p)
 {
        char *l = *p;
 
@@ -912,7 +922,7 @@ eatsize(p)
        case 'b':    /* char/byte */
        case 'c':    /* char/byte */
                l++;
-               /*FALLTHROUGH*/
+               /*@fallthrough@*/
        default:
                break;
        }
@@ -921,21 +931,19 @@ eatsize(p)
 }
 
 /*
- * handle an mmaped file.
+ * handle a compiled file.
  */
 static int
-apprentice_map(magicp, nmagicp, fn, action)
-       struct magic **magicp;
-       uint32 *nmagicp;
-       const char *fn;
-       int action;
+apprentice_map(struct magic **magicp, uint32_t *nmagicp, const char *fn,
+    int action)
 {
        int fd;
        struct stat st;
-       uint32 *ptr;
-       uint32 version;
+       uint32_t *ptr;
+       uint32_t version;
        int needsbyteswap;
        char *dbname = mkdbname(fn);
+       void *mm;
 
        if (dbname == NULL)
                return -1;
@@ -950,27 +958,28 @@ apprentice_map(magicp, nmagicp, fn, action)
        }
 
 #ifdef QUICK
-       if ((*magicp = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
+       if ((mm = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
            MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
                (void)fprintf(stderr, "%s: Cannot map `%s' (%s)\n",
                    progname, dbname, strerror(errno));
                goto error;
        }
 #else
-       if ((*magicp = malloc((size_t)st.st_size)) == NULL) {
+       if ((mm = malloc((size_t)st.st_size)) == NULL) {
                (void) fprintf(stderr, "%s: Out of memory (%s).\n", progname,
                     strerror(errno));
                goto error;
        }
-       if (read(fd, *magicp, (size_t)st.st_size) != (size_t)st.st_size) {
+       if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) {
                (void) fprintf(stderr, "%s: Read failed (%s).\n", progname,
                    strerror(errno));
                goto error;
        }
 #endif
+       *magicp = mm;
        (void)close(fd);
        fd = -1;
-       ptr = (uint32 *) *magicp;
+       ptr = (uint32_t *) *magicp;
        if (*ptr != MAGICNO) {
                if (swap4(*ptr) != MAGICNO) {
                        (void)fprintf(stderr, "%s: Bad magic in `%s'\n",
@@ -999,11 +1008,11 @@ apprentice_map(magicp, nmagicp, fn, action)
 error:
        if (fd != -1)
                (void)close(fd);
-       if (*magicp) {
+       if (mm) {
 #ifdef QUICK
-               (void)munmap(*magicp, (size_t)st.st_size);
+               (void)munmap(mm, (size_t)st.st_size);
 #else
-               free(*magicp);
+               free(mm);
 #endif
        } else {
                *magicp = NULL;
@@ -1016,15 +1025,12 @@ error:
  * handle an mmaped file.
  */
 static int
-apprentice_compile(magicp, nmagicp, fn, action)
-       struct magic **magicp;
-       uint32 *nmagicp;
-       const char *fn;
-       int action;
+apprentice_compile(struct magic **magicp, uint32_t *nmagicp, const char *fn,
+    int action)
 {
        int fd;
        char *dbname = mkdbname(fn);
-       static const uint32 ar[] = {
+       static const uint32_t ar[] = {
            MAGICNO, VERSIONNO
        };
 
@@ -1063,11 +1069,11 @@ apprentice_compile(magicp, nmagicp, fn, action)
 /*
  * make a dbname
  */
-char *
-mkdbname(fn)
-       const char *fn;
+static char *
+mkdbname(const char *fn)
 {
        static const char ext[] = ".mgc";
+       /*@only@*/
        static char *buf = NULL;
        size_t len = strlen(fn) + sizeof(ext) + 1;
        if (buf == NULL)
@@ -1088,11 +1094,9 @@ mkdbname(fn)
  * Byteswap an mmap'ed file if needed
  */
 static void
-byteswap(magic, nmagic)
-       struct magic *magic;
-       uint32 nmagic;
+byteswap(struct magic *magic, uint32_t nmagic)
 {
-       uint32 i;
+       uint32_t i;
        for (i = 0; i < nmagic; i++)
                bs1(&magic[i]);
 }
@@ -1100,13 +1104,12 @@ byteswap(magic, nmagic)
 /*
  * swap a short
  */
-static uint16
-swap2(sv) 
-       uint16 sv;
+static uint16_t
+swap2(uint16_t sv)
 {
-       uint16 rv;
-       uint8 *s = (uint8 *) &sv; 
-       uint8 *d = (uint8 *) &rv; 
+       uint16_t rv;
+       uint8_t *s = (uint8_t *) &sv; 
+       uint8_t *d = (uint8_t *) &rv; 
        d[0] = s[1];
        d[1] = s[0];
        return rv;
@@ -1115,13 +1118,12 @@ swap2(sv)
 /*
  * swap an int
  */
-static uint32
-swap4(sv) 
-       uint32 sv;
+static uint32_t
+swap4(uint32_t sv)
 {
-       uint32 rv;
-       uint8 *s = (uint8 *) &sv; 
-       uint8 *d = (uint8 *) &rv; 
+       uint32_t rv;
+       uint8_t *s = (uint8_t *) &sv; 
+       uint8_t *d = (uint8_t *) &rv; 
        d[0] = s[3];
        d[1] = s[2];
        d[2] = s[1];
@@ -1133,8 +1135,7 @@ swap4(sv)
  * byteswap a single magic entry
  */
 static
-void bs1(m)
-       struct magic *m;
+void bs1(struct magic *m)
 {
        m->cont_level = swap2(m->cont_level);
        m->offset = swap4(m->offset);
index b1b8fc9..ab08de0 100644 (file)
@@ -35,7 +35,6 @@
  */
 
 #include "file.h"
-#include <stdio.h>
 #include <string.h>
 #include <memory.h>
 #include <ctype.h>
@@ -46,7 +45,7 @@
 #include "names.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)Id: ascmagic.c,v 1.30 2001/07/26 13:15:49 christos Exp ")
+FILE_RCSID("@(#)Id: ascmagic.c,v 1.32 2002/07/03 18:26:37 christos Exp ")
 #endif /* lint */
 
 typedef unsigned long unichar;
@@ -55,18 +54,30 @@ typedef unsigned long unichar;
 #define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' \
                  || (x) == 0x85 || (x) == '\f')
 
-static int looks_ascii __P((const unsigned char *, int, unichar *, int *));
-static int looks_utf8 __P((const unsigned char *, int, unichar *, int *));
-static int looks_unicode __P((const unsigned char *, int, unichar *, int *));
-static int looks_latin1 __P((const unsigned char *, int, unichar *, int *));
-static int looks_extended __P((const unsigned char *, int, unichar *, int *));
-static void from_ebcdic __P((const unsigned char *, int, unsigned char *));
-static int ascmatch __P((const unsigned char *, const unichar *, int));
-
+static int looks_ascii(const unsigned char *buf, int nbytes,
+               /*@out@*/ unichar *ubuf, /*@out@*/ int *ulen)
+       /*@modifies *ubuf, *ulen @*/;
+static int looks_utf8(const unsigned char *buf, int nbytes,
+               /*@out@*/ unichar *ubuf, /*@out@*/ int *ulen)
+       /*@modifies *ubuf, *ulen @*/;
+static int looks_unicode(const unsigned char *buf, int nbytes,
+               /*@out@*/ unichar *ubuf, /*@out@*/ int *ulen)
+       /*@modifies *ubuf, *ulen @*/;
+static int looks_latin1(const unsigned char *buf, int nbytes,
+               /*@out@*/ unichar *ubuf, /*@out@*/ int *ulen)
+       /*@modifies *ubuf, *ulen @*/;
+static int looks_extended(const unsigned char *buf, int nbytes,
+               /*@out@*/ unichar *ubuf, /*@out@*/ int *ulen)
+       /*@modifies *ubuf, *ulen @*/;
+static void from_ebcdic(const unsigned char *buf, int nbytes,
+               /*@out@*/ unsigned char *otp)
+       /*@modifies *otp @*/;
+static int ascmatch(const unsigned char *s, const unichar *us, int ulen)
+       /*@*/;
+
+/* int nbytes: size actually read */
 int
-ascmagic(buf, nbytes)
-       unsigned char *buf;
-       int nbytes;     /* size actually read */
+ascmagic(unsigned char *buf, int nbytes)
 {
        int i;
        char nbuf[HOWMANY+1];           /* one extra for terminating '\0' */
@@ -207,7 +218,7 @@ ascmagic(buf, nbytes)
                 */
                for (end = i + 1; end < nbytes; end++)
                        if (ISSPC(ubuf[end]))
-                               break;
+                               /*@innerbreak@*/ break;
 
                /*
                 * compare the word thus isolated against the token list
@@ -322,10 +333,7 @@ subtype_identified:
 }
 
 static int
-ascmatch(s, us, ulen)
-       const unsigned char *s;
-       const unichar *us;
-       int ulen;
+ascmatch(const unsigned char *s, const unichar *us, int ulen)
 {
        size_t i;
 
@@ -397,6 +405,7 @@ ascmatch(s, us, ulen)
 #define I 2   /* character appears in ISO-8859 text */
 #define X 3   /* character appears in non-ISO extended ASCII (Mac, IBM PC) */
 
+/*@unchecked@*/ /*@observer@*/
 static char text_chars[256] = {
        /*                  BEL BS HT LF    FF CR    */
        F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F,  /* 0x0X */
@@ -420,11 +429,7 @@ static char text_chars[256] = {
 };
 
 static int
-looks_ascii(buf, nbytes, ubuf, ulen)
-       const unsigned char *buf;
-       int nbytes;
-       unichar *ubuf;
-       int *ulen;
+looks_ascii(const unsigned char *buf, int nbytes, unichar *ubuf, int *ulen)
 {
        int i;
 
@@ -443,11 +448,7 @@ looks_ascii(buf, nbytes, ubuf, ulen)
 }
 
 static int
-looks_latin1(buf, nbytes, ubuf, ulen)
-       const unsigned char *buf;
-       int nbytes;
-       unichar *ubuf;
-       int *ulen;
+looks_latin1(const unsigned char *buf, int nbytes, unichar *ubuf, int *ulen)
 {
        int i;
 
@@ -466,11 +467,7 @@ looks_latin1(buf, nbytes, ubuf, ulen)
 }
 
 static int
-looks_extended(buf, nbytes, ubuf, ulen)
-       const unsigned char *buf;
-       int nbytes;
-       unichar *ubuf;
-       int *ulen;
+looks_extended(const unsigned char *buf, int nbytes, unichar *ubuf, int *ulen)
 {
        int i;
 
@@ -489,11 +486,7 @@ looks_extended(buf, nbytes, ubuf, ulen)
 }
 
 int
-looks_utf8(buf, nbytes, ubuf, ulen)
-       const unsigned char *buf;
-       int nbytes;
-       unichar *ubuf;
-       int *ulen;
+looks_utf8(const unsigned char *buf, int nbytes, unichar *ubuf, int *ulen)
 {
        int i, n;
        unichar c;
@@ -555,11 +548,7 @@ done:
 }
 
 static int
-looks_unicode(buf, nbytes, ubuf, ulen)
-       const unsigned char *buf;
-       int nbytes;
-       unichar *ubuf;
-       int *ulen;
+looks_unicode(const unsigned char *buf, int nbytes, unichar *ubuf, int *ulen)
 {
        int bigend;
        int i;
@@ -620,6 +609,7 @@ looks_unicode(buf, nbytes, ubuf, ulen)
  * between old-style and internationalized examples of text.
  */
 
+/*@unchecked@*/ /*@observer@*/
 unsigned char ebcdic_to_ascii[] = {
   0,   1,   2,   3, 156,   9, 134, 127, 151, 141, 142,  11,  12,  13,  14,  15,
  16,  17,  18,  19, 157, 133,   8, 135,  24,  25, 146, 143,  28,  29,  30,  31,
@@ -653,6 +643,7 @@ unsigned char ebcdic_to_ascii[] = {
  * cases for the NEL character can be taken out of the code.
  */
 
+/*@unchecked@*/ /*@observer@*/
 unsigned char ebcdic_1047_to_8859[] = {
 0x00,0x01,0x02,0x03,0x9C,0x09,0x86,0x7F,0x97,0x8D,0x8E,0x0B,0x0C,0x0D,0x0E,0x0F,
 0x10,0x11,0x12,0x13,0x9D,0x0A,0x08,0x87,0x18,0x19,0x92,0x8F,0x1C,0x1D,0x1E,0x1F,
@@ -676,14 +667,11 @@ unsigned char ebcdic_1047_to_8859[] = {
  * Copy buf[0 ... nbytes-1] into out[], translating EBCDIC to ASCII.
  */
 static void
-from_ebcdic(buf, nbytes, out)
-       const unsigned char *buf;
-       int nbytes;
-       unsigned char *out;
+from_ebcdic(const unsigned char *buf, int nbytes, unsigned char *otp)
 {
        int i;
 
        for (i = 0; i < nbytes; i++) {
-               out[i] = ebcdic_to_ascii[buf[i]];
+               otp[i] = ebcdic_to_ascii[buf[i]];
        }
 }
index 1f4094a..c8970a3 100644 (file)
@@ -6,7 +6,6 @@
  *                                         using method, return sizeof new
  */
 #include "file.h"
-#include <stdio.h>
 #include <stdlib.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
 #ifndef lint
-FILE_RCSID("@(#)Id: compress.c,v 1.20 2001/07/22 21:04:15 christos Exp ")
+FILE_RCSID("@(#)Id: compress.c,v 1.25 2002/07/03 18:26:37 christos Exp ")
 #endif
 
 
+/*@-nullassign@*/
+/*@unchecked@*/
 static struct {
+/*@observer@*/
        const char *magic;
        int   maglen;
+/*@observer@*/
        const char *const argv[3];
        int      silent;
 } compr[] = {
@@ -37,18 +44,31 @@ static struct {
        { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 },         /* packed */
        { "BZh",      3, { "bzip2", "-cd", NULL }, 1 },         /* bzip2-ed */
 };
+/*@=nullassign@*/
 
+/*@unchecked@*/
 static int ncompr = sizeof(compr) / sizeof(compr[0]);
 
 
-static int uncompress __P((int, const unsigned char *, unsigned char **, int));
-static int swrite __P((int, const void *, size_t));
-static int sread __P((int, void *, size_t));
+static int swrite(int fd, const void *buf, size_t n)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+static int sread(int fd, /*@out@*/ void *buf, size_t n)
+       /*@globals fileSystem @*/
+       /*@modifies *buf, fileSystem @*/;
+static int uncompressbuf(int method, const unsigned char *old,
+               /*@out@*/ unsigned char **newch, int n)
+       /*@globals fileSystem @*/
+       /*@modifies *newch, fileSystem @*/;
+#ifdef HAVE_LIBZ
+static int uncompressgzipped(const unsigned char *old,
+               /*@out@*/ unsigned char **newch, int n)
+       /*@globals fileSystem @*/
+       /*@modifies *newch, fileSystem @*/;
+#endif
 
 int
-zmagic(buf, nbytes)
-       unsigned char *buf;
-       int nbytes;
+zmagic(const char *fname, unsigned char *buf, int nbytes)
 {
        unsigned char *newbuf;
        int newsize;
@@ -58,11 +78,11 @@ zmagic(buf, nbytes)
                if (nbytes < compr[i].maglen)
                        continue;
                if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 &&
-                   (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) {
-                       tryit(newbuf, newsize, 1);
+                   (newsize = uncompressbuf(i, buf, &newbuf, nbytes)) != 0) {
+                       tryit(fname, newbuf, newsize, 1);
                        free(newbuf);
                        printf(" (");
-                       tryit(buf, nbytes, 0);
+                       tryit(fname, buf, nbytes, 0);
                        printf(")");
                        return 1;
                }
@@ -78,10 +98,7 @@ zmagic(buf, nbytes)
  * `safe' write for sockets and pipes.
  */
 static int
-swrite(fd, buf, n)
-       int fd;
-       const void *buf;
-       size_t n;
+swrite(int fd, const void *buf, size_t n)
 {
        int rv;
        size_t rn = n;
@@ -94,8 +111,8 @@ swrite(fd, buf, n)
                        return -1;
                default:
                        n -= rv;
-                       buf = ((char *)buf) + rv;
-                       break;
+                       buf = ((const char *)buf) + rv;
+                       /*@switchbreak@*/ break;
                }
        while (n > 0);
        return rn;
@@ -106,10 +123,7 @@ swrite(fd, buf, n)
  * `safe' read for sockets and pipes.
  */
 static int
-sread(fd, buf, n)
-       int fd;
-       void *buf;
-       size_t n;
+sread(int fd, void *buf, size_t n)
 {
        int rv;
        size_t rn = n;
@@ -120,27 +134,164 @@ sread(fd, buf, n)
                        if (errno == EINTR)
                                continue;
                        return -1;
+               case 0:
+                       return rn - n;
                default:
                        n -= rv;
                        buf = ((char *)buf) + rv;
-                       break;
+                       /*@switchbreak@*/ break;
                }
        while (n > 0);
        return rn;
 }
 
+int
+pipe2file(int fd, void *startbuf, size_t nbytes)
+{
+       char buf[4096];
+       int r, tfd;
+
+       (void)strcpy(buf, "/tmp/file.XXXXXX");
+#ifndef HAVE_MKSTEMP
+       {
+               char *ptr = mktemp(buf);
+               tfd = open(ptr, O_RDWR|O_TRUNC|O_EXCL|O_CREAT, 0600);
+               r = errno;
+               (void)unlink(ptr);
+               errno = r;
+       }
+#else
+       tfd = mkstemp(buf);
+       r = errno;
+       (void)unlink(buf);
+       errno = r;
+#endif
+       if (tfd == -1) {
+               error("Can't create temporary file for pipe copy (%s)\n",
+                   strerror(errno));
+               /*@notreached@*/
+       }
+
+       if (swrite(tfd, startbuf, nbytes) != nbytes)
+               r = 1;
+       else {
+               while ((r = sread(fd, buf, sizeof(buf))) > 0)
+                       if (swrite(tfd, buf, r) != r)
+                               break;
+       }
+
+       switch (r) {
+       case -1:
+               error("Error copying from pipe to temp file (%s)\n",
+                   strerror(errno));
+               /*@notreached@*/break;
+       case 0:
+               break;
+       default:
+               error("Error while writing to temp file (%s)\n",
+                   strerror(errno));
+               /*@notreached@*/
+       }
+
+       /*
+        * We duplicate the file descriptor, because fclose on a
+        * tmpfile will delete the file, but any open descriptors
+        * can still access the phantom inode.
+        */
+       if ((fd = dup2(tfd, fd)) == -1) {
+               error("Couldn't dup destcriptor for temp file(%s)\n",
+                   strerror(errno));
+               /*@notreached@*/
+       }
+       (void)close(tfd);
+       if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
+               error("Couldn't seek on temp file (%s)\n", strerror(errno));
+               /*@notreached@*/
+       }
+       return fd;
+}
+
+#ifdef HAVE_LIBZ
+
+#define FHCRC          (1 << 1)
+#define FEXTRA         (1 << 2)
+#define FNAME          (1 << 3)
+#define FCOMMENT       (1 << 4)
+
 static int
-uncompress(method, old, newch, n)
-       int method;
-       const unsigned char *old;
-       unsigned char **newch;
-       int n;
+uncompressgzipped(const unsigned char *old, unsigned char **newch, int n)
+{
+       unsigned char flg = old[3];
+       int data_start = 10;
+       z_stream z;
+       int rc;
+
+       if (flg & FEXTRA)
+               data_start += 2 + old[data_start] + old[data_start + 1] * 256;
+       if (flg & FNAME) {
+               while(old[data_start])
+                       data_start++;
+               data_start++;
+       }
+       if(flg & FCOMMENT) {
+               while(old[data_start])
+                       data_start++;
+               data_start++;
+       }
+       if(flg & FHCRC)
+               data_start += 2;
+
+       if ((*newch = (unsigned char *)malloc(HOWMANY + 1)) == NULL) {
+               return 0;
+       }
+       
+       z.next_in = (Bytef *)(old + data_start);
+       z.avail_in = n - data_start;
+       z.next_out = *newch;
+       z.avail_out = HOWMANY;
+       z.zalloc = Z_NULL;
+       z.zfree = Z_NULL;
+       z.opaque = Z_NULL;
+
+       rc = inflateInit2(&z, -15);
+       if (rc != Z_OK) {
+               (void) fprintf(stderr,"%s: zlib: %s\n", progname, z.msg);
+               return 0;
+       }
+
+       rc = inflate(&z, Z_SYNC_FLUSH);
+       if (rc != Z_OK && rc != Z_STREAM_END) {
+               fprintf(stderr,"%s: zlib: %s\n", progname, z.msg);
+               return 0;
+       }
+
+       n = z.total_out;
+       inflateEnd(&z);
+       
+       /* let's keep the nul-terminate tradition */
+       (*newch)[n++] = '\0';
+
+       return n;
+}
+#endif
+
+static int
+uncompressbuf(int method, const unsigned char *old, unsigned char **newch,
+             int n)
 {
        int fdin[2], fdout[2];
 
+       /* The buffer is NUL terminated, and we don't need that. */
+       n--;
+        
+#ifdef HAVE_LIBZ
+       if (method == 2)
+               return uncompressgzipped(old,newch,n);
+#endif
+
        if (pipe(fdin) == -1 || pipe(fdout) == -1) {
                error("cannot create pipe (%s).\n", strerror(errno));   
-               /*NOTREACHED*/
+               /*@notreached@*/
        }
        switch (fork()) {
        case 0: /* child */
@@ -159,10 +310,10 @@ uncompress(method, old, newch, n)
                execvp(compr[method].argv[0],
                       (char *const *)compr[method].argv);
                exit(1);
-               /*NOTREACHED*/
+               /*@notreached@*/break;
        case -1:
                error("could not fork (%s).\n", strerror(errno));
-               /*NOTREACHED*/
+               /*@notreached@*/break;
 
        default: /* parent */
                (void) close(fdin[0]);
@@ -173,15 +324,17 @@ uncompress(method, old, newch, n)
                }
                (void) close(fdin[1]);
                fdin[1] = -1;
-               if ((*newch = (unsigned char *) malloc(n)) == NULL) {
+               if ((*newch = (unsigned char *) malloc(HOWMANY + 1)) == NULL) {
                        n = 0;
                        goto err;
                }
-               if ((n = sread(fdout[0], *newch, n)) <= 0) {
+               if ((n = sread(fdout[0], *newch, HOWMANY)) <= 0) {
                        free(*newch);
                        n = 0;
                        goto err;
                }
+               /* NUL terminate, as every buffer is handled here. */
+               (*newch)[n++] = '\0';
 err:
                if (fdin[1] != -1)
                        (void) close(fdin[1]);
@@ -189,4 +342,5 @@ err:
                (void) wait(NULL);
                return n;
        }
+       /*@notreached@*/
 }
index b1d1dd4..0db2a29 100644 (file)
  *
  * 4. This notice may not be removed or altered.
  */
-#include <stdio.h>
+
+#include "file.h"
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <sys/types.h>
 #include <sys/param.h> /* for MAXPATHLEN */
-#include <sys/stat.h>
 #include <fcntl.h>     /* for open() */
 #ifdef RESTORE_TIME
 # if (__COHERENT__ >= 0x420)
 #include <locale.h>
 #endif
 
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>    /* for long options (is this portable?)*/
+#endif
+
 #include <netinet/in.h>                /* for byte swapping */
 
-#include "file.h"
 #include "patchlevel.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)Id: file.c,v 1.59 2001/07/23 00:02:32 christos Exp ")
+FILE_RCSID("@(#)Id: file.c,v 1.66 2002/07/03 19:00:41 christos Exp ")
 #endif /* lint */
 
 
@@ -66,6 +68,11 @@ FILE_RCSID("@(#)Id: file.c,v 1.59 2001/07/23 00:02:32 christos Exp ")
 # define USAGE  "Usage: %s [-bciknsvz] [-f namefile] [-m magicfiles] file...\n"
 #endif
 
+#ifdef __EMX__
+static char *apptypeName = NULL;
+int os2_apptype (const char *fn, char *buf, int nb);
+#endif /* __EMX__ */
+
 #ifndef MAGIC
 # define MAGIC "/etc/magic"
 #endif
@@ -74,6 +81,7 @@ FILE_RCSID("@(#)Id: file.c,v 1.59 2001/07/23 00:02:32 christos Exp ")
 #define        MAXPATHLEN      512
 #endif
 
+/*@unchecked@*/
 int                    /* Global command-line options          */
        debug = 0,      /* debugging                            */
        lflag = 0,      /* follow Symlinks (BSD only)           */
@@ -84,44 +92,91 @@ int                         /* Global command-line options          */
        nobuffer = 0,   /* Do not buffer stdout */
        kflag = 0;      /* Keep going after the first match     */
 
+/*@unchecked@*/
 int                    /* Misc globals                         */
        nmagic = 0;     /* number of valid magic[]s             */
 
+/*@unchecked@*/
 struct  magic *magic;  /* array of magic entries               */
 
+/*@unchecked@*/ /*@null@*/
 const char *magicfile = 0;     /* where the magic is           */
+/*@unchecked@*/ /*@observer@*/
 const char *default_magicfile = MAGIC;
 
+/*@unchecked@*/
 char *progname;                /* used throughout                      */
+/*@unchecked@*/
 int lineno;            /* line number in the magic file        */
 
 
-static void    unwrap          __P((char *fn));
-static void    usage           __P((void));
-#if 0
-static int     byteconv4       __P((int, int, int));
-static short   byteconv2       __P((int, int, int));
+static void    unwrap(char *fn)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+/*@exits@*/
+static void    usage(void)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+#ifdef HAVE_GETOPT_H
+static void    help(void)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
 #endif
 
-int main __P((int, char *[]));
+int main(int argc, char *argv[])
+       /*@globals debug, lflag, bflag, zflag, sflag, iflag, nobuffer, kflag,
+               default_magicfile, lineno, magicfile, mlist, optind, progname,
+               fileSystem @*/
+       /*@modifies debug, lflag, bflag, zflag, sflag, iflag, nobuffer, kflag,
+               default_magicfile, lineno, magicfile, mlist, optind, progname,
+               fileSystem @*/;
 
 /*
  * main - parse arguments and handle options
  */
 int
-main(argc, argv)
-       int argc;
-       char *argv[];
+main(int argc, char **argv)
 {
        int c;
        int action = 0, didsomefiles = 0, errflg = 0, ret = 0, app = 0;
        char *mime, *home, *usermagic;
        struct stat sb;
+#define OPTSTRING      "bcdf:ikm:nsvzCL"
+#ifdef HAVE_GETOPT_H
+       int longindex;
+/*@-nullassign -readonlytrans@*/
+       static struct option long_options[] =
+       {
+               {"version", 0, 0, 'v'},
+               {"help", 0, 0, 0},
+               {"brief", 0, 0, 'b'},
+               {"checking-printout", 0, 0, 'c'},
+               {"debug", 0, 0, 'd'},
+               {"files-from", 1, 0, 'f'},
+               {"mime", 0, 0, 'i'},
+               {"keep-going", 0, 0, 'k'},
+#ifdef S_IFLNK
+               {"dereference", 0, 0, 'L'},
+#endif
+               {"magic-file", 1, 0, 'm'},
+               {"uncompress", 0, 0, 'z'},
+               {"no-buffer", 0, 0, 'n'},
+               {"special-files", 0, 0, 's'},
+               {"compile", 0, 0, 'C'},
+               {0, 0, 0, 0},
+       };
+/*@=nullassign =readonlytrans@*/
+#endif
 
 #ifdef LC_CTYPE
        setlocale(LC_CTYPE, ""); /* makes islower etc work for other langs */
 #endif
 
+#ifdef __EMX__
+       /* sh-like wildcard expansion! Shouldn't hurt at least ... */
+       _wildcard(&argc, &argv);
+#endif
+
        if ((progname = strrchr(argv[0], '/')) != NULL)
                progname++;
        else
@@ -142,20 +197,31 @@ main(argc, argv)
                        }
                }
 
-       while ((c = getopt(argc, argv, "bcdf:ikm:nsvzCL")) != EOF)
+#ifndef HAVE_GETOPT_H
+       while ((c = getopt(argc, argv, OPTSTRING)) != -1)
+#else
+       while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
+           &longindex)) != -1)
+#endif
                switch (c) {
+#ifdef HAVE_GETOPT_H
+               case 0 :
+                       if (longindex == 1)
+                               help();
+                       /*@switchbreak@*/ break;
+#endif
                case 'b':
                        ++bflag;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'c':
                        action = CHECK;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'C':
                        action = COMPILE;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'd':
                        ++debug;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'f':
                        if (!app) {
                                ret = apprentice(magicfile, action);
@@ -165,7 +231,7 @@ main(argc, argv)
                        }
                        unwrap(optarg);
                        ++didsomefiles;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'i':
                        iflag++;
                        if ((mime = malloc(strlen(magicfile) + 6)) != NULL) {
@@ -173,19 +239,19 @@ main(argc, argv)
                                (void)strcat(mime, ".mime");
                                magicfile = mime;
                        }
-                       break;
+                       /*@switchbreak@*/ break;
                case 'k':
                        kflag = 1;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'm':
                        magicfile = optarg;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'n':
                        ++nobuffer;
-                       break;
+                       /*@switchbreak@*/ break;
                case 's':
                        sflag++;
-                       break;
+                       /*@switchbreak@*/ break;
                case 'v':
                        (void) fprintf(stdout, "%s-%d.%d\n", progname,
                                       FILE_VERSION_MAJOR, patchlevel);
@@ -194,16 +260,16 @@ main(argc, argv)
                        return 1;
                case 'z':
                        zflag++;
-                       break;
+                       /*@switchbreak@*/ break;
 #ifdef S_IFLNK
                case 'L':
                        ++lflag;
-                       break;
+                       /*@switchbreak@*/ break;
 #endif
                case '?':
                default:
                        errflg++;
-                       break;
+                       /*@switchbreak@*/ break;
                }
 
        if (errflg) {
@@ -241,8 +307,7 @@ main(argc, argv)
  * unwrap -- read a file of filenames, do each one.
  */
 static void
-unwrap(fn)
-       char *fn;
+unwrap(char *fn)
 {
        char buf[MAXPATHLEN];
        FILE *f;
@@ -254,7 +319,7 @@ unwrap(fn)
        } else {
                if ((f = fopen(fn, "r")) == NULL) {
                        error("Cannot open `%s' (%s).\n", fn, strerror(errno));
-                       /*NOTREACHED*/
+                       /*@notreached@*/
                }
 
                while (fgets(buf, MAXPATHLEN, f) != NULL) {
@@ -286,10 +351,8 @@ unwrap(fn)
  *     big_endian      whether we are a big endian host
  */
 static int
-byteconv4(from, same, big_endian)
-       int from;
-       int same;
-       int big_endian;
+byteconv4(int from, int same, int big_endian)
+       /*@*/
 {
        if (same)
                return from;
@@ -316,10 +379,8 @@ byteconv4(from, same, big_endian)
  * Same as byteconv4, but for shorts
  */
 static short
-byteconv2(from, same, big_endian)
-       int from;
-       int same;
-       int big_endian;
+byteconv2(int from, int same, int big_endian)
+       /*@*/
 {
        if (same)
                return from;
@@ -344,9 +405,7 @@ byteconv2(from, same, big_endian)
  * process - process input file
  */
 void
-process(inname, wid)
-       const char      *inname;
-       int wid;
+process(const char *inname, int wid)
 {
        int     fd = 0;
        static  const char stdname[] = "standard input";
@@ -359,7 +418,7 @@ process(inname, wid)
                if (fstat(0, &sb)<0) {
                        error("cannot fstat `%s' (%s).\n", stdname,
                              strerror(errno));
-                       /*NOTREACHED*/
+                       /*@notreached@*/
                }
                inname = stdname;
        }
@@ -393,14 +452,14 @@ process(inname, wid)
         */
        if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
                error("read failed (%s).\n", strerror(errno));
-               /*NOTREACHED*/
+               /*@notreached@*/
        }
 
        if (nbytes == 0)
                ckfputs(iflag ? "application/x-empty" : "empty", stdout);
        else {
                buf[nbytes++] = '\0';   /* null-terminate it */
-               match = tryit(buf, nbytes, zflag);
+               match = tryit(inname, buf, nbytes, zflag);
        }
 
 #ifdef BUILTIN_ELF
@@ -446,12 +505,24 @@ process(inname, wid)
 
 
 int
-tryit(buf, nb, zflag)
-       unsigned char *buf;
-       int nb, zflag;
+tryit(const char *fn, unsigned char *buf, int nb, int zfl)
 {
+
+       /*
+        * The main work is done here!
+        * We have the file name and/or the data buffer to be identified. 
+        */
+
+#ifdef __EMX__
+       /*
+        * Ok, here's the right place to add a call to some os-specific
+        * routine, e.g.
+        */
+       if (os2_apptype(fn, buf, nb) == 1)
+              return 'o';
+#endif
        /* try compression stuff */
-       if (zflag && zmagic(buf, nb))
+       if (zfl && zmagic(fn, buf, nb))
                return 'z';
 
        /* try tests in /etc/magic (or surrogate magic file) */
@@ -463,14 +534,46 @@ tryit(buf, nb, zflag)
                return 'a';
 
        /* abandon hope, all ye who remain here */
-       ckfputs("data", stdout);
+       ckfputs(iflag ? "application/octet-stream" : "data", stdout);
                return '\0';
 }
 
 static void
-usage()
+usage(void)
 {
        (void)fprintf(stderr, USAGE, progname);
        (void)fprintf(stderr, "Usage: %s -C [-m magic]\n", progname);
+#ifdef HAVE_GETOPT_H
+       (void)fputs("Try `file --help' for more information.\n", stderr);
+#endif
        exit(1);
 }
+
+#ifdef HAVE_GETOPT_H
+static void
+help(void)
+{
+       puts(
+"Usage: file [OPTION]... [FILE]...\n"
+"Determine file type of FILEs.\n"
+"\n"
+"  -m, --magic-file LIST      use LIST as a colon-separated list of magic\n"
+"                               number files\n"
+"  -z, --uncompress           try to look inside compressed files\n"
+"  -b, --brief                do not prepend filenames to output lines\n"
+"  -c, --checking-printout    print the parsed form of the magic file, use in\n"
+"                               conjunction with -m to debug a new magic file\n"
+"                               before installing it\n"
+"  -f, --files-from FILE      read the filenames to be examined from FILE\n"
+"  -i, --mime                 output mime type strings\n"
+"  -k, --keep-going           don't stop at the first match\n"
+"  -L, --dereference          causes symlinks to be followed\n"
+"  -n, --no-buffer            do not buffer output\n"
+"  -s, --special-files        treat special (block/char devices) files as\n"
+"                             ordinary ones\n"
+"      --help                 display this help and exit\n"
+"      --version              output version information and exit\n"
+);
+       exit(0);
+}
+#endif
index ead7b3a..ee5e4bd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * file.h - definitions for file(1) program
- * @(#)Id: file.h,v 1.37 2001/07/22 21:04:15 christos Exp 
+ * @(#)Id: file.h,v 1.43 2002/07/03 18:57:52 christos Exp 
  *
  * Copyright (c) Ian F. Darwin, 1987.
  * Written by Ian F. Darwin.
 #ifndef __file_h__
 #define __file_h__
 
+#ifndef __linux__
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE 
+#define _FILE_OFFSET_BITS 64
+#endif
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-typedef int int32;
-typedef unsigned int uint32;
-typedef short int16;
-typedef unsigned short uint16;
-typedef char int8;
-typedef unsigned char uint8;
+#include <errno.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+/* Do this here and now, because struct stat gets re-defined on solaris */
+#include <sys/stat.h>
 
 #ifndef HOWMANY
-# define HOWMANY 16384         /* how much of the file to look at */
+# define HOWMANY 65536         /* how much of the file to look at */
 #endif
-#define MAXMAGIS 1000          /* max entries in /etc/magic */
+#define MAXMAGIS 4096          /* max entries in /etc/magic */
 #define MAXDESC        50              /* max leng of text description */
 #define MAXstring 32           /* max leng of "string" types */
 
@@ -54,16 +61,16 @@ typedef unsigned char uint8;
 #define COMPILE        2
 
 struct magic {
-       uint16 cont_level;/* level of ">" */
-       uint8 nospflag; /* supress space character */
-       uint8 flag;
+       uint16_t cont_level;    /* level of ">" */
+       uint8_t nospflag;       /* supress space character */
+       uint8_t flag;
 #define INDIR  1               /* if '>(...)' appears,  */
 #define        UNSIGNED 2              /* comparison is unsigned */
 #define OFFADD 4               /* if '>&' appears,  */
-       uint8 reln;             /* relation (0=eq, '>'=gt, etc) */
-       uint8 vallen;           /* length of string value, if any */
-       uint8 type;             /* int, short, long or string. */
-       uint8 in_type;          /* type of indirrection */
+       uint8_t reln;           /* relation (0=eq, '>'=gt, etc) */
+       uint8_t vallen;         /* length of string value, if any */
+       uint8_t type;           /* int, short, long or string. */
+       uint8_t in_type;        /* type of indirrection */
 #define                        BYTE    1
 #define                                SHORT   2
 #define                                LONG    4
@@ -79,8 +86,9 @@ struct magic {
 #define                                LDATE   14
 #define                                BELDATE 15
 #define                                LELDATE 16
-       uint8 in_op;            /* operator for indirection */
-       uint8 mask_op;          /* operator for mask */
+#define                                REGEX   17
+       uint8_t in_op;          /* operator for indirection */
+       uint8_t mask_op;        /* operator for mask */
 #define                                OPAND   1
 #define                                OPOR    2
 #define                                OPXOR   3
@@ -90,19 +98,20 @@ struct magic {
 #define                                OPDIVIDE        7
 #define                                OPMODULO        8
 #define                                OPINVERSE       0x80
-       int32 offset;           /* offset to magic number */
-       int32 in_offset;        /* offset from indirection */
+       int32_t offset;         /* offset to magic number */
+       int32_t in_offset;      /* offset from indirection */
        union VALUETYPE {
-               unsigned char b;
-               unsigned short h;
-               uint32 l;
+               uint8_t b;
+               uint16_t h;
+               uint32_t l;
                char s[MAXstring];
-               unsigned char hs[2];    /* 2 bytes of a fixed-endian "short" */
-               unsigned char hl[4];    /* 4 bytes of a fixed-endian "long" */
+               char *buf;
+               uint8_t hs[2];  /* 2 bytes of a fixed-endian "short" */
+               uint8_t hl[4];  /* 4 bytes of a fixed-endian "long" */
        } value;                /* either number or string */
-       uint32 mask;    /* mask before comparison with value */
+       uint32_t mask;  /* mask before comparison with value */
        char desc[MAXDESC];     /* description */
-};
+} __attribute__((__packed__));
 
 #define BIT(A)   (1 << (A))
 #define STRING_IGNORE_LOWERCASE                BIT(0)
@@ -116,59 +125,42 @@ struct magic {
 /* list of magic entries */
 struct mlist {
        struct magic *magic;            /* array of magic entries */
-       uint32 nmagic;                  /* number of entries in array */
+       uint32_t nmagic;                /* number of entries in array */
        struct mlist *next, *prev;
 };
 
-#include <stdio.h>     /* Include that here, to make sure __P gets defined */
-#include <errno.h>
-
-#ifndef __P
-# if defined(__STDC__) || defined(__cplusplus)
-#  define __P(a) a
-# else
-#  define __P(a) ()
-#  define const
-# endif
-#endif
-
-extern int   apprentice                __P((const char *, int));
-extern int   ascmagic          __P((unsigned char *, int));
-extern void  error             __P((const char *, ...));
-extern void  ckfputs           __P((const char *, FILE *));
-struct stat;
-extern int   fsmagic           __P((const char *, struct stat *));
-extern char *fmttime           __P((long, int));
-extern int   is_compress       __P((const unsigned char *, int *));
-extern int   is_tar            __P((unsigned char *, int));
-extern void  magwarn           __P((const char *, ...));
-extern void  mdump             __P((struct magic *));
-extern void  process           __P((const char *, int));
-extern void  showstr           __P((FILE *, const char *, int));
-extern int   softmagic         __P((unsigned char *, int));
-extern int   tryit             __P((unsigned char *, int, int));
-extern int   zmagic            __P((unsigned char *, int));
-extern void  ckfprintf         __P((FILE *, const char *, ...));
-extern uint32 signextend       __P((struct magic *, unsigned int32));
-extern void tryelf             __P((int, unsigned char *, int));
-
+/*@unchecked@*/
 extern char *progname;         /* the program name                     */
+/*@unchecked@*/
 extern const char *magicfile;  /* name of the magic file               */
+/*@unchecked@*/
 extern int lineno;             /* current line number in magic file    */
 
+/*@unchecked@*/
 extern struct mlist mlist;     /* list of arrays of magic entries      */
 
+/*@unchecked@*/
 extern int debug;              /* enable debugging?                    */
+/*@unchecked@*/
 extern int zflag;              /* process compressed files?            */
+/*@unchecked@*/
 extern int lflag;              /* follow symbolic links?               */
+/*@unchecked@*/
 extern int sflag;              /* read/analyze block special files?    */
+/*@unchecked@*/
 extern int iflag;              /* Output types as mime-types           */
 
+#ifdef NEED_GETOPT
+/*@unchecked@*/
 extern int optind;             /* From getopt(3)                       */
+/*@unchecked@*/
 extern char *optarg;
+#endif
 
 #ifndef HAVE_STRERROR
+/*@unchecked@*/
 extern int sys_nerr;
+/*@unchecked@*/
 extern char *sys_errlist[];
 #define strerror(e) \
        (((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
@@ -182,13 +174,70 @@ extern char *sys_errlist[];
 #define QUICK
 #endif
 
-#ifdef __STDC__
+#if defined(__LCLINT__)
+#define FILE_RCSID(id)
+#else
 #define FILE_RCSID(id) \
 static const char *rcsid(const char *p) { \
        return rcsid(p = id); \
 }
-#else
-#define FILE_RCSID(id) static char rcsid[] = id;
 #endif
 
+extern int   apprentice(const char *fn, int action)
+       /*@globals lineno, mlist, fileSystem @*/
+       /*@modifies lineno, mlist, fileSystem @*/;
+extern int   ascmagic(unsigned char *buf, int nbytes)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+/*@exits@*/
+extern void  error(const char *f, ...)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+extern void  ckfputs(const char *str, FILE *fil)
+       /*@globals fileSystem @*/
+       /*@modifies fil, fileSystem @*/;
+struct stat;
+extern int   fsmagic(const char *fn, /*@out@*/ struct stat *sb)
+       /*@globals fileSystem @*/
+       /*@modifies *sb, fileSystem @*/;
+extern char *fmttime(long v, int local)
+       /*@*/;
+extern int   is_compress(const unsigned char *, int *)
+       /*@*/;
+extern int   is_tar(unsigned char *buf, int nbytes)
+       /*@*/;
+extern void  magwarn(const char *f, ...)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+extern void  mdump(struct magic *m)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+extern void  process(const char *inname, int wid)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+extern void  showstr(FILE *fp, const char *s, int len)
+       /*@globals fileSystem @*/
+       /*@modifies fp, fileSystem @*/;
+extern int   softmagic(unsigned char *buf, int nbytes)
+       /*@globals fileSystem @*/
+       /*@modifies buf, fileSystem @*/;
+extern int   tryit(const char *fn, unsigned char *buf, int nb, int zfl)
+       /*@globals fileSystem @*/
+       /*@modifies buf, fileSystem @*/;
+extern int   zmagic(const char *fname, unsigned char *buf, int nbytes)
+       /*@globals fileSystem @*/
+       /*@modifies buf, fileSystem @*/;
+extern void  ckfprintf(FILE *f, const char *fmt, ...)
+       /*@globals fileSystem @*/
+       /*@modifies f, fileSystem @*/;
+extern uint32_t signextend(struct magic *m, uint32_t v)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+extern void tryelf(int fd, unsigned char *buf, int nbytes)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+extern int pipe2file(int fd, void *startbuf, size_t nbytes)
+       /*@globals errno, fileSystem @*/
+       /*@modifies errno, fileSystem @*/;
+
 #endif /* __file_h__ */
index c7869dd..6970c0e 100644 (file)
  */
 
 #include "file.h"
-#include <stdio.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #undef HAVE_MAJOR
 
 #ifndef        lint
-FILE_RCSID("@(#)Id: fsmagic.c,v 1.33 2000/08/05 17:36:48 christos Exp ")
+FILE_RCSID("@(#)Id: fsmagic.c,v 1.36 2002/07/03 19:00:41 christos Exp ")
 #endif /* lint */
 
 int
-fsmagic(fn, sb)
-       const char *fn;
-       struct stat *sb;
+fsmagic(const char *fn, struct stat *sb)
 {
        int ret = 0;
 
@@ -228,7 +223,7 @@ fsmagic(fn, sb)
                break;
        default:
                error("invalid mode 0%o.\n", sb->st_mode);
-               /*NOTREACHED*/
+               /*@notreached@*/
        }
 
        /*
index fd184d6..6e5f77c 100644 (file)
@@ -5,25 +5,27 @@
  * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
  *
  * @(#)list.c 1.18 9/23/86 Public Domain - gnu
- * Id: is_tar.c,v 1.13 2000/08/05 17:36:48 christos Exp 
+ * Id: is_tar.c,v 1.17 2002/07/03 18:26:38 christos Exp 
  *
  * Comments changed and some code/comments reformatted
  * for file command by Ian Darwin.
  */
 
+#include "file.h"
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include "tar.h"
-#include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)Id: is_tar.c,v 1.13 2000/08/05 17:36:48 christos Exp ")
+FILE_RCSID("@(#)Id: is_tar.c,v 1.17 2002/07/03 18:26:38 christos Exp ")
 #endif
 
 #define        isodigit(c)     ( ((c) >= '0') && ((c) <= '7') )
 
-static int from_oct __P((int, char *));        /* Decode octal number */
+/* Decode octal number */
+static int from_oct(int digs, char *where)
+       /*@*/;
 
 /*
  * Return 
@@ -32,9 +34,7 @@ static int from_oct __P((int, char *));       /* Decode octal number */
  *     2 for Unix Std (POSIX) tar file.
  */
 int
-is_tar(buf, nbytes)
-       unsigned char *buf;
-       int nbytes;
+is_tar(unsigned char *buf, int nbytes)
 {
        union record *header = (union record *)buf;
        int     i;
@@ -77,9 +77,7 @@ is_tar(buf, nbytes)
  * Result is -1 if the field is invalid (all blank, or nonoctal).
  */
 static int
-from_oct(digs, where)
-       int     digs;
-       char    *where;
+from_oct(int digs, char *where)
 {
        int     value;
 
index 4dd53eb..2acf5db 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Names.h - names and types used by ascmagic in file(1).
  * These tokens are here because they can appear anywhere in
- * the first HOWMANY bytes, while tokens in /etc/magic must
+ * the first HOWMANY bytes, while tokens in MAGIC must
  * appear at fixed offsets into the file. Don't make HOWMANY
  * too high unless you have a very fast CPU.
  *
@@ -10,7 +10,7 @@
  *
  * See LEGAL.NOTICE
  *
- * Id: names.h,v 1.18 2000/08/05 17:36:49 christos Exp 
+ * Id: names.h,v 1.19 2002/05/16 15:01:41 christos Exp 
  */
 
 /*
 #define        L_BCPL  12              /* BCPL */
 #define        L_M4    13              /* M4 */
 
+/*@unchecked@*/ /*@observer@*/
 static const struct {
+/*@observer@*/ /*@null@*/
        char *human;
+/*@observer@*/ /*@null@*/
        char *mime;
 } types[] = {
        { "C program",                                  "text/x-c", },
@@ -92,7 +95,9 @@ static const struct {
  * as Java, as it comes after "the" and "The".  Perhaps we need a fancier
  * heuristic to identify Java?
  */
+/*@unchecked@*/ /*@observer@*/
 static struct names {
+/*@observer@*/ /*@null@*/
        const char *name;
        short type;
 } names[] = {
index f562c66..891a850 100644 (file)
@@ -26,8 +26,6 @@
  */
 
 #include "file.h"
-#include <stdio.h>
-#include <errno.h>
 #include <string.h>
 #ifdef __STDC__
 # include <stdarg.h>
 #include <time.h>
 
 #ifndef lint
-FILE_RCSID("@(#)Id: print.c,v 1.34 2001/08/07 16:01:26 christos Exp ")
+FILE_RCSID("@(#)Id: print.c,v 1.38 2002/07/03 18:37:44 christos Exp ")
 #endif  /* lint */
 
 #define SZOF(a)        (sizeof(a) / sizeof(a[0]))
 
+#ifndef COMPILE_ONLY
 void
-mdump(m)
-       struct magic *m;
+mdump(struct magic *m)
 {
+       /*@observer@*/
        static const char *typ[] = { "invalid", "byte", "short", "invalid",
                                     "long", "string", "date", "beshort",
                                     "belong", "bedate", "leshort", "lelong",
                                     "ledate", "pstring", "ldate", "beldate",
-                                    "leldate" };
+                                    "leldate", "regex" };
        static const char optyp[] = { '@', '&', '|', '^', '+', '-', 
                                      '*', '/', '%' };
        (void) fputc('[', stderr);
@@ -110,6 +109,7 @@ mdump(m)
                        break;
                case STRING:
                case PSTRING:
+               case REGEX:
                        showstr(stderr, m->value.s, -1);
                        break;
                case DATE:
@@ -129,15 +129,14 @@ mdump(m)
        }
        (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
 }
+#endif
 
 /*
  * ckfputs - fputs, but with error checking
  * ckfprintf - fprintf, but with error checking
  */
 void
-ckfputs(str, fil)      
-       const char *str;
-       FILE *fil;
+ckfputs(const char *str, FILE *fil)
 {
        if (fputs(str,fil) == EOF)
                error("write failed.\n");
@@ -145,23 +144,11 @@ ckfputs(str, fil)
 
 /*VARARGS*/
 void
-#ifdef __STDC__
 ckfprintf(FILE *f, const char *fmt, ...)
-#else
-ckfprintf(va_alist)
-       va_dcl
-#endif
 {
        va_list va;
-#ifdef __STDC__
+
        va_start(va, fmt);
-#else
-       FILE *f;
-       const char *fmt;
-       va_start(va);
-       f = va_arg(va, FILE *);
-       fmt = va_arg(va, const char *);
-#endif
        (void) vfprintf(f, fmt, va);
        if (ferror(f))
                error("write failed.\n");
@@ -173,21 +160,11 @@ ckfprintf(va_alist)
  */
 /*VARARGS*/
 void
-#ifdef __STDC__
 error(const char *f, ...)
-#else
-error(va_alist)
-       va_dcl
-#endif
 {
        va_list va;
-#ifdef __STDC__
+
        va_start(va, f);
-#else
-       const char *f;
-       va_start(va);
-       f = va_arg(va, const char *);
-#endif
        /* cuz we use stdout for most, stderr here */
        (void) fflush(stdout); 
 
@@ -200,21 +177,11 @@ error(va_alist)
 
 /*VARARGS*/
 void
-#ifdef __STDC__
 magwarn(const char *f, ...)
-#else
-magwarn(va_alist)
-       va_dcl
-#endif
 {
        va_list va;
-#ifdef __STDC__
+
        va_start(va, f);
-#else
-       const char *f;
-       va_start(va);
-       f = va_arg(va, const char *);
-#endif
        /* cuz we use stdout for most, stderr here */
        (void) fflush(stdout); 
 
@@ -227,10 +194,9 @@ magwarn(va_alist)
 }
 
 
+#ifndef COMPILE_ONLY
 char *
-fmttime(v, local)
-       long v;
-       int local;
+fmttime(long v, int local)
 {
        char *pp, *rt;
        time_t t = (time_t)v;
@@ -262,3 +228,4 @@ fmttime(v, local)
                *rt = '\0';
        return pp;
 }
+#endif
index b455675..212e627 100644 (file)
@@ -1,36 +1,42 @@
 #include "file.h"
 
 #ifdef BUILTIN_ELF
-#include <sys/types.h>
 #include <string.h>
-#include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#include <errno.h>
 
 #include "readelf.h"
 
 #ifndef lint
-FILE_RCSID("@(#)Id: readelf.c,v 1.17 2000/08/05 19:00:12 christos Exp ")
+FILE_RCSID("@(#)Id: readelf.c,v 1.22 2002/07/03 18:26:38 christos Exp ")
 #endif
 
 #ifdef ELFCORE
-static void dophn_core __P((int, int, int, off_t, int, size_t));
+static void dophn_core(int class, int swap, int fd, off_t off, int num,
+               size_t size)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
 #endif
-static void dophn_exec __P((int, int, int, off_t, int, size_t));
-static void doshn __P((int, int, int, off_t, int, size_t));
-
-static uint16_t getu16 __P((int, int));
-static uint32_t getu32 __P((int, uint32_t));
-static uint64_t getu64 __P((int, uint64_t));
+static void dophn_exec(int class, int swap, int fd, off_t off, int num,
+               size_t size)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+static void doshn(int class, int swap, int fd, off_t off, int num, size_t size)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+
+static uint16_t getu16(int swap, uint16_t value)
+       /*@*/;
+static uint32_t getu32(int swap, uint32_t value)
+       /*@*/;
+static uint64_t getu64(int swap, uint64_t value)
+       /*@*/;
 
 static uint16_t
-getu16(swap, value)
-       int swap;
-       uint16_t value;
+getu16(int swap, uint16_t value)
 {
        union {
                uint16_t ui;
@@ -49,9 +55,7 @@ getu16(swap, value)
 }
 
 static uint32_t
-getu32(swap, value)
-       int swap;
-       uint32_t value;
+getu32(int swap, uint32_t value)
 {
        union {
                uint32_t ui;
@@ -72,9 +76,7 @@ getu32(swap, value)
 }
 
 static uint64_t
-getu64(swap, value)
-       int swap;
-       uint64_t value;
+getu64(int swap, uint64_t value)
 {
        union {
                uint64_t ui;
@@ -130,13 +132,7 @@ getu64(swap, value)
                         : prpsoffsets64[i])
 
 static void
-doshn(class, swap, fd, off, num, size)
-       int class;
-       int swap;
-       int fd;
-       off_t off;
-       int num;
-       size_t size;
+doshn(int class, int swap, int fd, off_t off, int num, size_t size)
 {
        Elf32_Shdr sh32;
        Elf64_Shdr sh64;
@@ -161,18 +157,17 @@ doshn(class, swap, fd, off, num, size)
  * otherwise it's statically linked.
  */
 static void
-dophn_exec(class, swap, fd, off, num, size)
-       int class;
-       int swap;
-       int fd;
-       off_t off;
-       int num;
-       size_t size;
+dophn_exec(int class, int swap, int fd, off_t off, int num, size_t size)
 {
        Elf32_Phdr ph32;
+       Elf32_Nhdr *nh32 = NULL;
        Elf64_Phdr ph64;
+       Elf64_Nhdr *nh64 = NULL;
        char *linking_style = "statically";
        char *shared_libraries = "";
+       char nbuf[BUFSIZ];
+       int bufsize;
+       size_t offset, nameoffset;
 
        if (lseek(fd, off, SEEK_SET) == -1)
                error("lseek failed (%s).\n", strerror(errno));
@@ -184,16 +179,124 @@ dophn_exec(class, swap, fd, off, num, size)
                switch (ph_type) {
                case PT_DYNAMIC:
                        linking_style = "dynamically";
-                       break;
+                       /*@switchbreak@*/ break;
                case PT_INTERP:
                        shared_libraries = " (uses shared libs)";
-                       break;
+                       /*@switchbreak@*/ break;
+               case PT_NOTE:
+                       /*
+                        * This is a PT_NOTE section; loop through all the notes
+                        * in the section.
+                        */
+                       if (lseek(fd, (off_t) ph_offset, SEEK_SET) == -1)
+                               error("lseek failed (%s).\n", strerror(errno));
+                       bufsize = read(fd, nbuf, BUFSIZ);
+                       if (bufsize == -1)
+                               error(": " "read failed (%s).\n",
+                                   strerror(errno));
+                       offset = 0;
+                       for (;;) {
+                               if (offset >= bufsize)
+                                       /*@innerbreak@*/ break;
+                               if (class == ELFCLASS32)
+                                       nh32 = (Elf32_Nhdr *)&nbuf[offset];
+                               else
+                                       nh64 = (Elf64_Nhdr *)&nbuf[offset];
+                               offset += nh_size;
+       
+                               if (offset + nh_namesz >= bufsize) {
+                                       /*
+                                        * We're past the end of the buffer.
+                                        */
+                                       /*@innerbreak@*/ break;
+                               }
+
+                               nameoffset = offset;
+                               offset += nh_namesz;
+                               offset = ((offset + 3)/4)*4;
+
+                               if (offset + nh_descsz >= bufsize)
+                                       /*@innerbreak@*/ break;
+
+                               if (nh_namesz == 4 &&
+                                   strcmp(&nbuf[nameoffset], "GNU") == 0 &&
+                                   nh_type == NT_GNU_VERSION &&
+                                   nh_descsz == 16) {
+                                       uint32_t *desc =
+                                           (uint32_t *)&nbuf[offset];
+
+                                       printf(", for GNU/");
+                                       switch (getu32(swap, desc[0])) {
+                                       case GNU_OS_LINUX:
+                                               printf("Linux");
+                                               /*@switchbreak@*/ break;
+                                       case GNU_OS_HURD:
+                                               printf("Hurd");
+                                               /*@switchbreak@*/ break;
+                                       case GNU_OS_SOLARIS:
+                                               printf("Solaris");
+                                               /*@switchbreak@*/ break;
+                                       default:
+                                               printf("<unknown>");
+                                               /*@switchbreak@*/ break;
+                                       }
+                                       printf(" %d.%d.%d",
+                                           getu32(swap, desc[1]),
+                                           getu32(swap, desc[2]),
+                                           getu32(swap, desc[3]));
+                               }
+
+                               if (nh_namesz == 7 &&
+                                   strcmp(&nbuf[nameoffset], "NetBSD") == 0 &&
+                                   nh_type == NT_NETBSD_VERSION &&
+                                   nh_descsz == 4) {
+                                       printf(", for NetBSD");
+                                       /*
+                                        * Version number is stuck at 199905,
+                                        * and hence is basically content-free.
+                                        */
+                               }
+
+                               if (nh_namesz == 8 &&
+                                   strcmp(&nbuf[nameoffset], "FreeBSD") == 0 &&
+                                   nh_type == NT_FREEBSD_VERSION &&
+                                   nh_descsz == 4) {
+                                       uint32_t desc = getu32(swap,
+                                           *(uint32_t *)&nbuf[offset]);
+                                       printf(", for FreeBSD");
+                                       /*
+                                        * Contents is __FreeBSD_version,
+                                        * whose relation to OS versions is
+                                        * defined by a huge table in the
+                                        * Porters' Handbook.  Happily, the
+                                        * first three digits are the version
+                                        * number, at least in versions of
+                                        * FreeBSD that use this note.
+                                        */
+
+                                       printf(" %d.%d", desc / 100000,
+                                           desc / 10000 % 10);
+                                       if (desc / 1000 % 10 > 0)
+                                               printf(".%d",
+                                                   desc / 1000 % 10);
+                               }
+
+                               if (nh_namesz == 8 &&
+                                   strcmp(&nbuf[nameoffset], "OpenBSD") == 0 &&
+                                   nh_type == NT_OPENBSD_VERSION &&
+                                   nh_descsz == 4) {
+                                       printf(", for OpenBSD");
+                                       /* Content of note is always 0 */
+                               }
+                       }
+                       /*@switchbreak@*/ break;
                }
        }
        printf(", %s linked%s", linking_style, shared_libraries);
 }
 
 #ifdef ELFCORE
+/*@unchecked@*/
 size_t prpsoffsets32[] = {
        8,              /* FreeBSD */
        28,             /* Linux 2.0.36 */
@@ -201,6 +304,7 @@ size_t      prpsoffsets32[] = {
        84,             /* SunOS 5.x */
 };
 
+/*@unchecked@*/
 size_t prpsoffsets64[] = {
        120,            /* SunOS 5.x, 64-bit */
 };
@@ -230,25 +334,31 @@ size_t    prpsoffsets64[] = {
  * *do* have that binary, the debugger will probably tell you what
  * signal it was.)
  */
+
+#define        OS_STYLE_SVR4           0
+#define        OS_STYLE_FREEBSD        1
+#define        OS_STYLE_NETBSD         2
+
+/*@unchecked@*/ /*@observer@*/
+static const char *os_style_names[] = {
+       "SVR4",
+       "FreeBSD",
+       "NetBSD",
+};
+
 static void
-dophn_core(class, swap, fd, off, num, size)
-       int class;
-       int swap;
-       int fd;
-       off_t off;
-       int num;
-       size_t size;
+dophn_core(int class, int swap, int fd, off_t off, int num, size_t size)
 {
        Elf32_Phdr ph32;
-       Elf32_Nhdr *nh32;
+       Elf32_Nhdr *nh32 = NULL;
        Elf64_Phdr ph64;
-       Elf64_Nhdr *nh64;
+       Elf64_Nhdr *nh64 = NULL;
        size_t offset, nameoffset, noffset, reloffset;
        unsigned char c;
        int i, j;
        char nbuf[BUFSIZ];
        int bufsize;
-       int is_freebsd;
+       int os_style = -1;
 
        /*
         * Loop through all the program headers.
@@ -274,7 +384,7 @@ dophn_core(class, swap, fd, off, num, size)
                offset = 0;
                for (;;) {
                        if (offset >= bufsize)
-                               break;
+                               /*@innerbreak@*/ break;
                        if (class == ELFCLASS32)
                                nh32 = (Elf32_Nhdr *)&nbuf[offset];
                        else
@@ -283,13 +393,13 @@ dophn_core(class, swap, fd, off, num, size)
 
                        /*
                         * Check whether this note has the name "CORE" or
-                        * "FreeBSD".
+                        * "FreeBSD", or "NetBSD-CORE".
                         */
                        if (offset + nh_namesz >= bufsize) {
                                /*
                                 * We're past the end of the buffer.
                                 */
-                               break;
+                               /*@innerbreak@*/ break;
                        }
 
                        nameoffset = offset;
@@ -310,17 +420,50 @@ dophn_core(class, swap, fd, off, num, size)
                         * doesn't include the terminating null in the
                         * name....
                         */
-                       if ((nh_namesz == 4 &&
-                             strncmp(&nbuf[nameoffset], "CORE", 4) == 0) ||
-                           (nh_namesz == 5 &&
-                             strcmp(&nbuf[nameoffset], "CORE") == 0))
-                               is_freebsd = 0;
-                       else if ((nh_namesz == 8 &&
-                             strcmp(&nbuf[nameoffset], "FreeBSD") == 0))
-                               is_freebsd = 1;
-                       else
-                               continue;
-                       if (nh_type == NT_PRPSINFO) {
+                       if (os_style == -1) {
+                               if ((nh_namesz == 4 &&
+                                    strncmp(&nbuf[nameoffset],
+                                           "CORE", 4) == 0) ||
+                                   (nh_namesz == 5 &&
+                                    strcmp(&nbuf[nameoffset],
+                                           "CORE") == 0)) {
+                                       os_style = OS_STYLE_SVR4;
+                               } else
+                               if ((nh_namesz == 8 &&
+                                    strcmp(&nbuf[nameoffset],
+                                           "FreeBSD") == 0)) {
+                                       os_style = OS_STYLE_FREEBSD;
+                               } else
+                               if ((nh_namesz >= 11 &&
+                                    strncmp(&nbuf[nameoffset],
+                                            "NetBSD-CORE", 11) == 0)) {
+                                       os_style = OS_STYLE_NETBSD;
+                               } else
+                                       /*@innercontinue@*/ continue;
+                               printf(", %s-style", os_style_names[os_style]);
+                       }
+
+                       if (os_style == OS_STYLE_NETBSD &&
+                           nh_type == NT_NETBSD_CORE_PROCINFO) {
+                               uint32_t signo;
+
+                               /*
+                                * Extract the program name.  It is at
+                                * offset 0x7c, and is up to 32-bytes,
+                                * including the terminating NUL.
+                                */
+                               printf(", from '%.31s'", &nbuf[offset + 0x7c]);
+                               
+                               /*
+                                * Extract the signal number.  It is at
+                                * offset 0x08.
+                                */
+                               memcpy(&signo, &nbuf[offset + 0x08],
+                                   sizeof(signo));
+                               printf(" (signal %u)", getu32(swap, signo));
+                       } else
+                       if (os_style != OS_STYLE_NETBSD &&
+                           nh_type == NT_PRPSINFO) {
                                /*
                                 * Extract the program name.  We assume
                                 * it to be 16 characters (that's what it
@@ -365,7 +508,7 @@ dophn_core(class, swap, fd, off, num, size)
                                                        if (j == 0)
                                                                goto tryanother;
                                                        else
-                                                               break;
+                                                               /*@innerbreak@*/ break;
                                                } else {
                                                        /*
                                                         * A nonprintable
@@ -384,12 +527,12 @@ dophn_core(class, swap, fd, off, num, size)
                                         */
                                        printf(", from '%.16s'",
                                            &nbuf[offset + prpsoffsets(i)]);
-                                       break;
+                                       /*@innerbreak@*/ break;
 
                                tryanother:
                                        ;
                                }
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                        offset += nh_descsz;
                        offset = ((offset + 3)/4)*4;
@@ -399,19 +542,22 @@ dophn_core(class, swap, fd, off, num, size)
 #endif
 
 void
-tryelf(fd, buf, nbytes)
-       int fd;
-       unsigned char *buf;
-       int nbytes;
+tryelf(int fd, unsigned char *buf, int nbytes)
 {
        union {
-               int32 l;
-               char c[sizeof (int32)];
+               int32_t l;
+               char c[sizeof (int32_t)];
        } u;
        int class;
        int swap;
 
        /*
+        * If we can't seek, it must be a pipe, socket or fifo.
+        */
+       if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
+               fd = pipe2file(fd, buf, nbytes);
+
+       /*
         * ELF executables have multiple section headers in arbitrary
         * file locations and thus file(1) cannot determine it from easily.
         * Instead we traverse thru all section headers until a symbol table
@@ -433,7 +579,7 @@ tryelf(fd, buf, nbytes)
 
                u.l = 1;
                (void) memcpy(&elfhdr, buf, sizeof elfhdr);
-               swap = (u.c[sizeof(int32) - 1] + 1) != elfhdr.e_ident[5];
+               swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
 
                if (getu16(swap, elfhdr.e_type) == ET_CORE) 
 #ifdef ELFCORE
@@ -470,7 +616,7 @@ tryelf(fd, buf, nbytes)
 
                u.l = 1;
                (void) memcpy(&elfhdr, buf, sizeof elfhdr);
-               swap = (u.c[sizeof(int32) - 1] + 1) != elfhdr.e_ident[5];
+               swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
 
                if (getu16(swap, elfhdr.e_type) == ET_CORE) 
 #ifdef ELFCORE
index 4be8504..2f8923b 100644 (file)
  * 4. This notice may not be removed or altered.
  */
 
-#include <stdio.h>
+#include "file.h"
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <time.h>
-#include <sys/types.h>
+#include <regex.h>
 
-#include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)Id: softmagic.c,v 1.46 2001/07/23 00:02:32 christos Exp ")
+FILE_RCSID("@(#)Id: softmagic.c,v 1.51 2002/07/03 18:26:38 christos Exp ")
 #endif /* lint */
 
-static int match       __P((struct magic *, uint32, unsigned char *, int));
-static int mget                __P((union VALUETYPE *,
-                            unsigned char *, struct magic *, int));
-static int mcheck      __P((union VALUETYPE *, struct magic *));
-static int32 mprint    __P((union VALUETYPE *, struct magic *));
-static void mdebug     __P((int32, char *, int));
-static int mconvert    __P((union VALUETYPE *, struct magic *));
-
+/*@unchecked@*/
 extern int kflag;
 
+static int match(struct magic *magic, uint32_t nmagic,
+               unsigned char *s, int nbytes)
+       /*@globals fileSystem @*/
+       /*@modifies *magic, s, fileSystem @*/;
+static int mget(union VALUETYPE *p, unsigned char *s,
+               struct magic *m, int nbytes)
+       /*@globals fileSystem @*/
+       /*@modifies p, s, fileSystem @*/;
+static int mcheck(union VALUETYPE *p, struct magic *m)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+static int32_t mprint(union VALUETYPE *p, struct magic *m)
+       /*@globals fileSystem @*/
+       /*@modifies p, fileSystem @*/;
+static void mdebug(int32_t offset, char *str, int len)
+       /*@globals fileSystem @*/
+       /*@modifies fileSystem @*/;
+static int mconvert(union VALUETYPE *p, struct magic *m)
+       /*@globals fileSystem @*/
+       /*@modifies p, fileSystem @*/;
+
 /*
  * softmagic - lookup one file in database 
- * (already read from /etc/magic by apprentice.c).
+ * (already read from MAGIC by apprentice.c).
  * Passed the name and FILE * of one file to be typed.
  */
 /*ARGSUSED1*/          /* nbytes passed for regularity, maybe need later */
 int
-softmagic(buf, nbytes)
-       unsigned char *buf;
-       int nbytes;
+softmagic(unsigned char *buf, int nbytes)
 {
        struct mlist *ml;
 
@@ -96,24 +107,21 @@ softmagic(buf, nbytes)
  *     so that higher-level continuations are processed.
  */
 static int
-match(magic, nmagic, s, nbytes)
-       struct magic *magic;
-       uint32 nmagic;
-       unsigned char   *s;
-       int nbytes;
+match(struct magic *magic, uint32_t nmagic, unsigned char *s, int nbytes)
 {
        int magindex = 0;
        int cont_level = 0;
        int need_separator = 0;
        union VALUETYPE p;
-       static int32 *tmpoff = NULL;
+       /*@only@*/
+       static int32_t *tmpoff = NULL;
        static size_t tmplen = 0;
-       int32 oldoff = 0;
+       int32_t oldoff = 0;
        int returnval = 0; /* if a match is found it is set to 1*/
        int firstline = 1; /* a flag to print X\n  X\n- X */
 
        if (tmpoff == NULL)
-               if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
+               if ((tmpoff = (int32_t *) malloc(tmplen = 20)) == NULL)
                        error("out of memory\n");
 
        for (magindex = 0; magindex < nmagic; magindex++) {
@@ -144,7 +152,7 @@ match(magic, nmagic, s, nbytes)
                        need_separator = 1;
                /* and any continuations that match */
                if (++cont_level >= tmplen)
-                       if ((tmpoff = (int32 *) realloc(tmpoff,
+                       if ((tmpoff = (int32_t *) realloc(tmpoff,
                                                       tmplen += 20)) == NULL)
                                error("out of memory\n");
                while (magic[magindex+1].cont_level != 0 && 
@@ -191,7 +199,7 @@ match(magic, nmagic, s, nbytes)
                                         */
                                        if (++cont_level >= tmplen)
                                                if ((tmpoff = 
-                                                   (int32 *) realloc(tmpoff,
+                                                   (int32_t *) realloc(tmpoff,
                                                    tmplen += 20)) == NULL)
                                                        error("out of memory\n");
                                }
@@ -209,13 +217,11 @@ match(magic, nmagic, s, nbytes)
        return returnval;  /* This is hit if -k is set or there is no match */
 }
 
-static int32
-mprint(p, m)
-       union VALUETYPE *p;
-       struct magic *m;
+static int32_t
+mprint(union VALUETYPE *p, struct magic *m)
 {
-       uint32 v;
-       int32 t=0 ;
+       uint32_t v;
+       int32_t t=0 ;
 
 
        switch (m->type) {
@@ -237,8 +243,8 @@ mprint(p, m)
        case BELONG:
        case LELONG:
                v = signextend(m, p->l);
-               (void) printf(m->desc, (uint32) v);
-               t = m->offset + sizeof(int32);
+               (void) printf(m->desc, (uint32_t) v);
+               t = m->offset + sizeof(int32_t);
                break;
 
        case STRING:
@@ -271,10 +277,14 @@ mprint(p, m)
                (void) printf(m->desc, fmttime(p->l, 0));
                t = m->offset + sizeof(time_t);
                break;
+       case REGEX:
+               (void) printf(m->desc, p->s);
+               t = m->offset + strlen(p->s);
+               break;
 
        default:
                error("invalid m->type (%d) in mprint().\n", m->type);
-               /*NOTREACHED*/
+               /*@notreached@*/
        }
        return(t);
 }
@@ -285,9 +295,7 @@ mprint(p, m)
  * (unless you have a better idea)
  */
 static int
-mconvert(p, m)
-       union VALUETYPE *p;
-       struct magic *m;
+mconvert(union VALUETYPE *p, struct magic *m)
 {
        switch (m->type) {
        case BYTE:
@@ -295,28 +303,28 @@ mconvert(p, m)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->b &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->b |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->b ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->b += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->b -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->b *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->b /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->b %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->b = ~p->b;
@@ -326,28 +334,28 @@ mconvert(p, m)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->h &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->h |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->h ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->h += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->h -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->h *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->h /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->h %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->h = ~p->h;
@@ -359,28 +367,28 @@ mconvert(p, m)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->l &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->l |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->l ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->l += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->l -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->l *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->l /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->l %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->l = ~p->l;
@@ -416,28 +424,28 @@ mconvert(p, m)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->h &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->h |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->h ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->h += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->h -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->h *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->h /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->h %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->h = ~p->h;
@@ -445,34 +453,34 @@ mconvert(p, m)
        case BELONG:
        case BEDATE:
        case BELDATE:
-               p->l = (int32)
+               p->l = (int32_t)
                    ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
                if (m->mask)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->l &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->l |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->l ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->l += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->l -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->l *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->l /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->l %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->l = ~p->l;
@@ -483,28 +491,28 @@ mconvert(p, m)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->h &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->h |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->h ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->h += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->h -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->h *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->h /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->h %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->h = ~p->h;
@@ -512,50 +520,50 @@ mconvert(p, m)
        case LELONG:
        case LEDATE:
        case LELDATE:
-               p->l = (int32)
+               p->l = (int32_t)
                    ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
                if (m->mask)
                        switch (m->mask_op&0x7F) {
                        case OPAND:
                                p->l &= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPOR:
                                p->l |= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPXOR:
                                p->l ^= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPADD:
                                p->l += m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMINUS:
                                p->l -= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMULTIPLY:
                                p->l *= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPDIVIDE:
                                p->l /= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        case OPMODULO:
                                p->l %= m->mask;
-                               break;
+                               /*@innerbreak@*/ break;
                        }
                if (m->mask_op & OPINVERSE)
                        p->l = ~p->l;
                return 1;
+       case REGEX:
+               return 1;
        default:
                error("invalid type %d in mconvert().\n", m->type);
+               /*@notreached@*/
                return 0;
        }
 }
 
 
 static void
-mdebug(offset, str, len)
-       int32 offset;
-       char *str;
-       int len;
+mdebug(int32_t offset, char *str, int len)
 {
        (void) fprintf(stderr, "mget @%d: ", offset);
        showstr(stderr, (char *) str, len);
@@ -564,63 +572,68 @@ mdebug(offset, str, len)
 }
 
 static int
-mget(p, s, m, nbytes)
-       union VALUETYPE* p;
-       unsigned char   *s;
-       struct magic *m;
-       int nbytes;
+mget(union VALUETYPE *p, unsigned char *s, struct magic *m, int nbytes)
 {
-       int32 offset = m->offset;
+       int32_t offset = m->offset;
 
-       if (offset + sizeof(union VALUETYPE) <= nbytes)
+       if (m->type == REGEX) {
+             /*
+              * offset is interpreted as last line to search,
+              * (starting at 1), not as bytes-from start-of-file
+              */
+             char *last = NULL;
+             p->buf = s;
+             for (; offset && (s = strchr(s, '\n')) != NULL; offset--, s++)
+                   last = s;
+             if (last != NULL)
+               *last = '\0';
+       } else if (offset + sizeof(union VALUETYPE) <= nbytes)
                memcpy(p, s + offset, sizeof(union VALUETYPE));
        else {
                /*
                 * the usefulness of padding with zeroes eludes me, it
                 * might even cause problems
                 */
-               int32 have = nbytes - offset;
+               int32_t have = nbytes - offset;
                memset(p, 0, sizeof(union VALUETYPE));
                if (have > 0)
                        memcpy(p, s + offset, have);
        }
 
-
        if (debug) {
                mdebug(offset, (char *) p, sizeof(union VALUETYPE));
                mdump(m);
        }
 
        if (m->flag & INDIR) {
-
                switch (m->in_type) {
                case BYTE:
                        if (m->in_offset)
                                switch (m->in_op&0x7F) {
                                case OPAND:
                                        offset = p->b & m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
                                        offset = p->b | m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
                                        offset = p->b ^ m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
                                        offset = p->b + m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
                                        offset = p->b - m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
                                        offset = p->b * m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
                                        offset = p->b / m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
                                        offset = p->b % m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                }
                        if (m->in_op & OPINVERSE)
                                offset = ~offset;
@@ -632,42 +645,42 @@ mget(p, s, m, nbytes)
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) &
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) |
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) ^
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) +
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) -
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) *
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) /
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
                                        offset = (short)((p->hs[0]<<8)|
                                                         (p->hs[1])) %
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                }
                        if (m->in_op & OPINVERSE)
                                offset = ~offset;
@@ -679,42 +692,42 @@ mget(p, s, m, nbytes)
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) &
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) |
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) ^
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) +
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) -
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) *
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) /
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
                                        offset = (short)((p->hs[1]<<8)|
                                                         (p->hs[0])) %
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                }
                        if (m->in_op & OPINVERSE)
                                offset = ~offset;
@@ -724,28 +737,28 @@ mget(p, s, m, nbytes)
                                switch (m->in_op&0x7F) {
                                case OPAND:
                                        offset = p->h & m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
                                        offset = p->h | m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
                                        offset = p->h ^ m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
                                        offset = p->h + m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
                                        offset = p->h - m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
                                        offset = p->h * m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
                                        offset = p->h / m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
                                        offset = p->h % m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                }
                        if (m->in_op & OPINVERSE)
                                offset = ~offset;
@@ -754,61 +767,61 @@ mget(p, s, m, nbytes)
                        if (m->in_offset)
                                switch (m->in_op&0x7F) {
                                case OPAND:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) &
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) |
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) ^
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) +
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) -
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) *
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) /
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
-                                       offset = (int32)((p->hl[0]<<24)|
+                                       offset = (int32_t)((p->hl[0]<<24)|
                                                         (p->hl[1]<<16)|
                                                         (p->hl[2]<<8)|
                                                         (p->hl[3])) %
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                }
                        if (m->in_op & OPINVERSE)
                                offset = ~offset;
@@ -817,61 +830,61 @@ mget(p, s, m, nbytes)
                        if (m->in_offset)
                                switch (m->in_op&0x7F) {
                                case OPAND:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) &
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) |
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) ^
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) +
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) -
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) *
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) /
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
-                                       offset = (int32)((p->hl[3]<<24)|
+                                       offset = (int32_t)((p->hl[3]<<24)|
                                                         (p->hl[2]<<16)|
                                                         (p->hl[1]<<8)|
                                                         (p->hl[0])) %
                                                 m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                }
                        if (m->in_op & OPINVERSE)
                                offset = ~offset;
@@ -881,28 +894,28 @@ mget(p, s, m, nbytes)
                                switch (m->in_op&0x7F) {
                                case OPAND:
                                        offset = p->l & m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPOR:
                                        offset = p->l | m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPXOR:
                                        offset = p->l ^ m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPADD:
                                        offset = p->l + m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMINUS:
                                        offset = p->l - m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMULTIPLY:
                                        offset = p->l * m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPDIVIDE:
                                        offset = p->l / m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                                case OPMODULO:
                                        offset = p->l % m->in_offset;
-                                       break;
+                                       /*@innerbreak@*/ break;
                        /*      case TOOMANYSWITCHBLOCKS:
                         *              ugh = p->eye % m->strain;
                         *              rub;
@@ -932,12 +945,10 @@ mget(p, s, m, nbytes)
 }
 
 static int
-mcheck(p, m)
-       union VALUETYPE* p;
-       struct magic *m;
+mcheck(union VALUETYPE *p, struct magic *m)
 {
-       uint32 l = m->value.l;
-       uint32 v;
+       uint32_t l = m->value.l;
+       uint32_t v;
        int matched;
 
        if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
@@ -971,7 +982,7 @@ mcheck(p, m)
 
        case STRING:
        case PSTRING:
-               {
+       {
                /*
                 * What we want here is:
                 * v = strncmp(m->value.s, p->s, m->vallen);
@@ -986,13 +997,13 @@ mcheck(p, m)
                if (0L == m->mask) { /* normal string: do it fast */
                        while (--len >= 0)
                                if ((v = *b++ - *a++) != '\0')
-                                       break; 
+                                       /*@loopbreak@*/ break; 
                } else { /* combine the others */
                        while (--len >= 0) {
                                if ((m->mask & STRING_IGNORE_LOWERCASE) &&
                                    islower(*a)) {
                                        if ((v = tolower(*b++) - *a++) != '\0')
-                                               break;
+                                               /*@loopbreak@*/ break;
                                } else if ((m->mask & STRING_COMPACT_BLANK) && 
                                    isspace(*a)) { 
                                        a++;
@@ -1001,7 +1012,7 @@ mcheck(p, m)
                                                        b++;
                                        } else {
                                                v = 1;
-                                               break;
+                                               /*@loopbreak@*/ break;
                                        }
                                } else if (isspace(*a) &&
                                    (m->mask & STRING_COMPACT_OPTIONAL_BLANK)) {
@@ -1010,15 +1021,32 @@ mcheck(p, m)
                                                b++;
                                } else {
                                        if ((v = *b++ - *a++) != '\0')
-                                               break;
+                                               /*@loopbreak@*/ break;
                                }
                        }
                }
                break;
        }
+       case REGEX:
+       {
+               int rc;
+               regex_t rx;
+               char errmsg[512];
+
+               rc = regcomp(&rx, m->value.s, REG_EXTENDED|REG_NOSUB);
+               if (rc) {
+                       (void) regerror(rc, &rx, errmsg, sizeof(errmsg));
+                       error("regex error %d, (%s)\n", rc, errmsg);
+               } else {
+                       rc = regexec(&rx, p->buf, 0, 0, 0);
+                       return !rc;
+               }
+       }
+               /*@notreached@*/ break;
        default:
                error("invalid type %d in mcheck().\n", m->type);
-               return 0;/*NOTREACHED*/
+               /*@notreached@*/
+               return 0;
        }
 
        if(m->type != STRING && m->type != PSTRING)
@@ -1053,7 +1081,7 @@ mcheck(p, m)
                                               v, l, matched);
                }
                else {
-                       matched = (int32) v > (int32) l;
+                       matched = (int32_t) v > (int32_t) l;
                        if (debug)
                                (void) fprintf(stderr, "%d > %d = %d\n",
                                               v, l, matched);
@@ -1068,7 +1096,7 @@ mcheck(p, m)
                                               v, l, matched);
                }
                else {
-                       matched = (int32) v < (int32) l;
+                       matched = (int32_t) v < (int32_t) l;
                        if (debug)
                                (void) fprintf(stderr, "%d < %d = %d\n",
                                               v, l, matched);
@@ -1092,7 +1120,7 @@ mcheck(p, m)
        default:
                matched = 0;
                error("mcheck: can't happen: invalid relation %d.\n", m->reln);
-               break;/*NOTREACHED*/
+               /*@notreached@*/ break;
        }
 
        return matched;
index c03139a..6def803 100644 (file)
@@ -166,12 +166,3 @@ TAR_EXTERN struct link     *linklist;      /* Points to first link in list */
  */
 TAR_EXTERN char                read_error_flag;
 
-
-#if 0
-/*
- * Declarations of functions available to the world.
- */
-/*LINTLIBRARY*/
-#define         annorec(stream, msg)   anno(stream, msg, 0)    /* Cur rec */
-#define        annofile(stream, msg)   anno(stream, msg, 1)    /* Saved rec */
-#endif