[BACK]Return to funcs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / file

Diff for /src/usr.bin/file/Attic/funcs.c between version 1.4 and 1.5

version 1.4, 2007/07/09 16:39:48 version 1.5, 2008/05/08 01:40:56
Line 12 
Line 12 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. The name of the author may not be used to endorse or promote products  
  *    derived from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Line 29 
Line 27 
  */   */
 #include "file.h"  #include "file.h"
 #include "magic.h"  #include "magic.h"
 #include <limits.h>  
 #include <stdarg.h>  #include <stdarg.h>
 #include <stddef.h>  
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <ctype.h>  #include <ctype.h>
   #if defined(HAVE_WCHAR_H)
   #include <wchar.h>
   #endif
   #if defined(HAVE_WCTYPE_H)
   #include <wctype.h>
   #endif
   #if defined(HAVE_LIMITS_H)
   #include <limits.h>
   #endif
   #ifndef SIZE_T_MAX
   #ifdef __LP64__
   #define SIZE_T_MAX (size_t)0xfffffffffffffffffU
   #else
   #define SIZE_T_MAX (size_t)0xffffffffU
   #endif
   #endif
   
 #ifndef lint  #ifndef lint
 FILE_RCSID("@(#)$Id$")  FILE_RCSID("@(#)$Id$")
 #endif  /* lint */  #endif  /* lint */
   
   #ifndef HAVE_VSNPRINTF
   int vsnprintf(char *, size_t, const char *, va_list);
   #endif
   
 /*  /*
  * Like printf, only we print to a buffer and advance it.   * Like printf, only we print to a buffer and advance it.
  */   */
Line 46 
Line 63 
 file_printf(struct magic_set *ms, const char *fmt, ...)  file_printf(struct magic_set *ms, const char *fmt, ...)
 {  {
         va_list ap;          va_list ap;
         int len;          size_t len, size;
         size_t size;  
         char *buf;          char *buf;
         ptrdiff_t diff;  
   
         va_start(ap, fmt);          va_start(ap, fmt);
   
Line 58 
Line 73 
                 file_error(ms, errno, "vsnprintf failed");                  file_error(ms, errno, "vsnprintf failed");
                 return -1;                  return -1;
         } else if (len >= ms->o.left) {          } else if (len >= ms->o.left) {
                   long diff;      /* XXX: really ptrdiff_t */
   
                 va_end(ap);                  va_end(ap);
                 size = (ms->o.size - ms->o.left) + len + 1024;                  size = (ms->o.size - ms->o.left) + len + 1024;
                 if ((buf = realloc(ms->o.buf, size)) == NULL) {                  if ((buf = realloc(ms->o.buf, size)) == NULL) {
                         file_oomem(ms);                          file_oomem(ms, size);
                         return -1;                          return -1;
                 }                  }
                 diff = ms->o.ptr - ms->o.buf;                  diff = ms->o.ptr - ms->o.buf;
Line 77 
Line 94 
                         return -1;                          return -1;
                 }                  }
         }          }
           va_end(ap);
         ms->o.ptr += len;          ms->o.ptr += len;
         ms->o.left -= len;          ms->o.left -= len;
         va_end(ap);  
         return 0;          return 0;
 }  }
   
Line 87 
Line 104 
  * error - print best error message possible   * error - print best error message possible
  */   */
 /*VARARGS*/  /*VARARGS*/
 protected void  private void
 file_error(struct magic_set *ms, int error, const char *f, ...)  file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
       uint32_t lineno)
 {  {
         va_list va;          size_t len;
         /* Only the first error is ok */          /* Only the first error is ok */
         if (ms->haderr)          if (ms->haderr)
                 return;                  return;
         va_start(va, f);          len = 0;
         (void)vsnprintf(ms->o.buf, ms->o.size, f, va);          if (lineno != 0) {
         va_end(va);                  (void)snprintf(ms->o.buf, ms->o.size, "line %u: ", lineno);
                   len = strlen(ms->o.buf);
           }
           (void)vsnprintf(ms->o.buf + len, ms->o.size - len, f, va);
         if (error > 0) {          if (error > 0) {
                 size_t len = strlen(ms->o.buf);                  len = strlen(ms->o.buf);
                 (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",                  (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
                     strerror(error));                      strerror(error));
         }          }
Line 106 
Line 127 
         ms->error = error;          ms->error = error;
 }  }
   
   /*VARARGS*/
   protected void
   file_error(struct magic_set *ms, int error, const char *f, ...)
   {
           va_list va;
           va_start(va, f);
           file_error_core(ms, error, f, va, 0);
           va_end(va);
   }
   
   /*
    * Print an error with magic line number.
    */
   /*VARARGS*/
 protected void  protected void
 file_oomem(struct magic_set *ms)  file_magerror(struct magic_set *ms, const char *f, ...)
 {  {
         file_error(ms, errno, "cannot allocate memory");          va_list va;
           va_start(va, f);
           file_error_core(ms, 0, f, va, ms->line);
           va_end(va);
 }  }
   
 protected void  protected void
   file_oomem(struct magic_set *ms, size_t len)
   {
           file_error(ms, errno, "cannot allocate %zu bytes", len);
   }
   
   protected void
 file_badseek(struct magic_set *ms)  file_badseek(struct magic_set *ms)
 {  {
         file_error(ms, errno, "error seeking");          file_error(ms, errno, "error seeking");
Line 125 
Line 168 
         file_error(ms, errno, "error reading");          file_error(ms, errno, "error reading");
 }  }
   
   #ifndef COMPILE_ONLY
 protected int  protected int
 file_buffer(struct magic_set *ms, const void *buf, size_t nb)  file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
       size_t nb)
 {  {
     int m;      int m;
   
   #ifdef __EMX__
       if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
           switch (file_os2_apptype(ms, inname, buf, nb)) {
           case -1:
               return -1;
           case 0:
               break;
           default:
               return 1;
           }
       }
   #endif
   
     /* try compression stuff */      /* try compression stuff */
     if ((m = file_zmagic(ms, buf, nb)) == 0) {      if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
           (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
         /* Check if we have a tar file */          /* Check if we have a tar file */
         if ((m = file_is_tar(ms, buf, nb)) == 0) {          if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
               (m = file_is_tar(ms, buf, nb)) == 0) {
             /* try tests in /etc/magic (or surrogate magic file) */              /* try tests in /etc/magic (or surrogate magic file) */
             if ((m = file_softmagic(ms, buf, nb)) == 0) {              if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
                   (m = file_softmagic(ms, buf, nb)) == 0) {
                 /* try known keywords, check whether it is ASCII */                  /* try known keywords, check whether it is ASCII */
                 if ((m = file_ascmagic(ms, buf, nb)) == 0) {                  if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
                       (m = file_ascmagic(ms, buf, nb)) == 0) {
                     /* abandon hope, all ye who remain here */                      /* abandon hope, all ye who remain here */
                     if (file_printf(ms, ms->flags & MAGIC_MIME ?                      if (file_printf(ms, ms->flags & MAGIC_MIME ?
                         "application/octet-stream" : "data") == -1)                          (nb ? "application/octet-stream" :
                               "application/empty") :
                           (nb ? "data" :
                               "empty")) == -1)
                             return -1;                              return -1;
                     m = 1;                      m = 1;
                 }                  }
             }              }
         }          }
     }      }
   #ifdef BUILTIN_ELF
       if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && nb > 5 && fd != -1) {
           /*
            * We matched something in the file, so this *might*
            * be an ELF file, and the file is at least 5 bytes
            * long, so if it's an ELF file it has at least one
            * byte past the ELF magic number - try extracting
            * information from the ELF headers that cannot easily
            * be extracted with rules in the magic file.
            */
           (void)file_tryelf(ms, fd, buf, nb);
       }
   #endif
     return m;      return m;
 }  }
   #endif
   
 protected int  protected int
 file_reset(struct magic_set *ms)  file_reset(struct magic_set *ms)
Line 157 
Line 237 
                 return -1;                  return -1;
         }          }
         ms->o.ptr = ms->o.buf;          ms->o.ptr = ms->o.buf;
           ms->o.left = ms->o.size;
         ms->haderr = 0;          ms->haderr = 0;
         ms->error = -1;          ms->error = -1;
         return 0;          return 0;
 }  }
   
   #define OCTALIFY(n, o)  \
           /*LINTED*/ \
           (void)(*(n)++ = '\\', \
           *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
           *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
           *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
           (o)++)
   
 protected const char *  protected const char *
 file_getbuffer(struct magic_set *ms)  file_getbuffer(struct magic_set *ms)
 {  {
Line 175 
Line 264 
                 return ms->o.buf;                  return ms->o.buf;
   
         len = ms->o.size - ms->o.left;          len = ms->o.size - ms->o.left;
           /* * 4 is for octal representation, + 1 is for NUL */
         if (len > (SIZE_T_MAX - 1) / 4) {          if (len > (SIZE_T_MAX - 1) / 4) {
                 file_oomem(ms);                  file_oomem(ms, len);
                 return NULL;                  return NULL;
         }          }
         /* * 4 is for octal representation, + 1 is for NUL */  
         psize = len * 4 + 1;          psize = len * 4 + 1;
         if (ms->o.psize < psize) {          if (ms->o.psize < psize) {
                 if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) {                  if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) {
                         file_oomem(ms);                          file_oomem(ms, psize);
                         return NULL;                          return NULL;
                 }                  }
                 ms->o.psize = psize;                  ms->o.psize = psize;
                 ms->o.pbuf = pbuf;                  ms->o.pbuf = pbuf;
         }          }
   
   #if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
           {
                   mbstate_t state;
                   wchar_t nextchar;
                   int mb_conv = 1;
                   size_t bytesconsumed;
                   char *eop;
                   (void)memset(&state, 0, sizeof(mbstate_t));
   
                   np = ms->o.pbuf;
                   op = ms->o.buf;
                   eop = op + strlen(ms->o.buf);
   
                   while (op < eop) {
                           bytesconsumed = mbrtowc(&nextchar, op,
                               (size_t)(eop - op), &state);
                           if (bytesconsumed == (size_t)(-1) ||
                               bytesconsumed == (size_t)(-2)) {
                                   mb_conv = 0;
                                   break;
                           }
   
                           if (iswprint(nextchar)) {
                                   (void)memcpy(np, op, bytesconsumed);
                                   op += bytesconsumed;
                                   np += bytesconsumed;
                           } else {
                                   while (bytesconsumed-- > 0)
                                           OCTALIFY(np, op);
                           }
                   }
                   *np = '\0';
   
                   /* Parsing succeeded as a multi-byte sequence */
                   if (mb_conv != 0)
                           return ms->o.pbuf;
           }
   #endif
   
         for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {          for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {
                 if (isprint((unsigned char)*op)) {                  if (isprint((unsigned char)*op)) {
                         *np++ = *op;                          *np++ = *op;
                 } else {                  } else {
                         *np++ = '\\';                          OCTALIFY(np, op);
                         *np++ = ((*op >> 6) & 3) + '0';  
                         *np++ = ((*op >> 3) & 7) + '0';  
                         *np++ = ((*op >> 0) & 7) + '0';  
                 }                  }
         }          }
         *np = '\0';          *np = '\0';
         return ms->o.pbuf;          return ms->o.pbuf;
 }  }
   
   protected int
   file_check_mem(struct magic_set *ms, unsigned int level)
   {
           size_t len;
   
           if (level >= ms->c.len) {
                   len = (ms->c.len += 20) * sizeof(*ms->c.li);
                   ms->c.li = (ms->c.li == NULL) ? malloc(len) :
                       realloc(ms->c.li, len);
                   if (ms->c.li == NULL) {
                           file_oomem(ms, len);
                           return -1;
                   }
           }
           ms->c.li[level].got_match = 0;
   #ifdef ENABLE_CONDITIONALS
           ms->c.li[level].last_match = 0;
           ms->c.li[level].last_cond = COND_NONE;
   #endif /* ENABLE_CONDITIONALS */
           return 0;
   }
   /*
    * Yes these wrappers suffer from buffer overflows, but if your OS does not
    * have the real functions, maybe you should consider replacing your OS?
    */
   #ifndef HAVE_VSNPRINTF
   int
   vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
   {
           return vsprintf(buf, fmt, ap);
   }
   #endif
   
   #ifndef HAVE_SNPRINTF
   /*ARGSUSED*/
   int
   snprintf(char *buf, size_t len, const char *fmt, ...)
   {
           int rv;
           va_list ap;
           va_start(ap, fmt);
           rv = vsprintf(buf, fmt, ap);
           va_end(ap);
           return rv;
   }
   #endif

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5