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

Diff for /src/usr.bin/file/Attic/softmagic.c between version 1.13 and 1.14

version 1.13, 2008/05/08 01:40:56 version 1.14, 2009/04/24 18:54:34
Line 43 
Line 43 
 #endif  /* lint */  #endif  /* lint */
   
 private int match(struct magic_set *, struct magic *, uint32_t,  private int match(struct magic_set *, struct magic *, uint32_t,
     const unsigned char *, size_t);      const unsigned char *, size_t, int);
 private int mget(struct magic_set *, const unsigned char *,  private int mget(struct magic_set *, const unsigned char *,
     struct magic *, size_t, unsigned int);      struct magic *, size_t, unsigned int);
 private int magiccheck(struct magic_set *, struct magic *);  private int magiccheck(struct magic_set *, struct magic *);
Line 59 
Line 59 
 private void cvt_64(union VALUETYPE *, const struct magic *);  private void cvt_64(union VALUETYPE *, const struct magic *);
   
 /*  /*
    * Macro to give description string according to whether we want plain
    * text or MIME type
    */
   #define MAGIC_DESC ((ms->flags & MAGIC_MIME) ? m->mimetype : m->desc)
   
   /*
  * softmagic - lookup one file in parsed, in-memory copy of database   * softmagic - lookup one file in parsed, in-memory copy of database
  * Passed the name and FILE * of one file to be typed.   * Passed the name and FILE * of one file to be typed.
  */   */
 /*ARGSUSED1*/           /* nbytes passed for regularity, maybe need later */  /*ARGSUSED1*/           /* nbytes passed for regularity, maybe need later */
 protected int  protected int
 file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)  file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, int mode)
 {  {
         struct mlist *ml;          struct mlist *ml;
         int rv;          int rv;
         for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)          for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
                 if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes)) != 0)                  if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode)) != 0)
                         return rv;                          return rv;
   
         return 0;          return 0;
Line 104 
Line 110 
  */   */
 private int  private int
 match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,  match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
     const unsigned char *s, size_t nbytes)      const unsigned char *s, size_t nbytes, int mode)
 {  {
         uint32_t magindex = 0;          uint32_t magindex = 0;
         unsigned int cont_level = 0;          unsigned int cont_level = 0;
Line 118 
Line 124 
   
         for (magindex = 0; magindex < nmagic; magindex++) {          for (magindex = 0; magindex < nmagic; magindex++) {
                 int flush;                  int flush;
                   struct magic *m = &magic[magindex];
   
                 ms->offset = magic[magindex].offset;                  if ((m->flag & BINTEST) != mode) {
                 ms->line = magic[magindex].lineno;                          /* Skip sub-tests */
                           while (magic[magindex + 1].cont_level != 0 &&
                                  ++magindex < nmagic)
                                   continue;
                           continue; /* Skip to next top-level test*/
                   }
   
                   ms->offset = m->offset;
                   ms->line = m->lineno;
   
                 /* if main entry matches, print it... */                  /* if main entry matches, print it... */
                 flush = !mget(ms, s, &magic[magindex], nbytes, cont_level);                  flush = !mget(ms, s, m, nbytes, cont_level);
                 if (flush) {                  if (flush) {
                         if (magic[magindex].reln == '!')                          if (m->reln == '!')
                                 flush = 0;                                  flush = 0;
                 } else {                  } else {
                         switch (magiccheck(ms, &magic[magindex])) {                          switch (magiccheck(ms, m)) {
                         case -1:                          case -1:
                                 return -1;                                  return -1;
                         case 0:                          case 0:
Line 153 
Line 168 
                  * If we are going to print something, we'll need to print                   * If we are going to print something, we'll need to print
                  * a blank before we print something else.                   * a blank before we print something else.
                  */                   */
                 if (magic[magindex].desc[0]) {                  if (*MAGIC_DESC) {
                         need_separator = 1;                          need_separator = 1;
                         printed_something = 1;                          printed_something = 1;
                         if (print_sep(ms, firstline) == -1)                          if (print_sep(ms, firstline) == -1)
                                 return -1;                                  return -1;
                 }                  }
   
                 if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex]))                  if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1)
                     == -1)  
                         return -1;                          return -1;
   
                 /* and any continuations that match */                  /* and any continuations that match */
Line 170 
Line 184 
   
                 while (magic[magindex+1].cont_level != 0 &&                  while (magic[magindex+1].cont_level != 0 &&
                     ++magindex < nmagic) {                      ++magindex < nmagic) {
                         ms->line = magic[magindex].lineno; /* for messages */                          m = &magic[magindex];
                           ms->line = m->lineno; /* for messages */
   
                         if (cont_level < magic[magindex].cont_level)                          if (cont_level < m->cont_level)
                                 continue;                                  continue;
                         if (cont_level > magic[magindex].cont_level) {                          if (cont_level > m->cont_level) {
                                 /*                                  /*
                                  * We're at the end of the level                                   * We're at the end of the level
                                  * "cont_level" continuations.                                   * "cont_level" continuations.
                                  */                                   */
                                 cont_level = magic[magindex].cont_level;                                  cont_level = m->cont_level;
                         }                          }
                         ms->offset = magic[magindex].offset;                          ms->offset = m->offset;
                         if (magic[magindex].flag & OFFADD) {                          if (m->flag & OFFADD) {
                                 ms->offset +=                                  ms->offset +=
                                     ms->c.li[cont_level - 1].off;                                      ms->c.li[cont_level - 1].off;
                         }                          }
   
 #ifdef ENABLE_CONDITIONALS  #ifdef ENABLE_CONDITIONALS
                         if (magic[magindex].cond == COND_ELSE ||                          if (m->cond == COND_ELSE ||
                             magic[magindex].cond == COND_ELIF) {                              m->cond == COND_ELIF) {
                                 if (ms->c.li[cont_level].last_match == 1)                                  if (ms->c.li[cont_level].last_match == 1)
                                         continue;                                          continue;
                         }                          }
 #endif  #endif
                         flush = !mget(ms, s, &magic[magindex], nbytes,                          flush = !mget(ms, s, m, nbytes, cont_level);
                             cont_level);                          if (flush && m->reln != '!')
                         if (flush && magic[magindex].reln != '!')  
                                 continue;                                  continue;
   
                         switch (flush ? 1 : magiccheck(ms, &magic[magindex])) {                          switch (flush ? 1 : magiccheck(ms, m)) {
                         case -1:                          case -1:
                                 return -1;                                  return -1;
                         case 0:                          case 0:
Line 211 
Line 225 
 #ifdef ENABLE_CONDITIONALS  #ifdef ENABLE_CONDITIONALS
                                 ms->c.li[cont_level].last_match = 1;                                  ms->c.li[cont_level].last_match = 1;
 #endif  #endif
                                 if (magic[magindex].type != FILE_DEFAULT)                                  if (m->type != FILE_DEFAULT)
                                         ms->c.li[cont_level].got_match = 1;                                          ms->c.li[cont_level].got_match = 1;
                                 else if (ms->c.li[cont_level].got_match) {                                  else if (ms->c.li[cont_level].got_match) {
                                         ms->c.li[cont_level].got_match = 0;                                          ms->c.li[cont_level].got_match = 0;
Line 221 
Line 235 
                                  * If we are going to print something,                                   * If we are going to print something,
                                  * make sure that we have a separator first.                                   * make sure that we have a separator first.
                                  */                                   */
                                 if (magic[magindex].desc[0]) {                                  if (*MAGIC_DESC) {
                                         printed_something = 1;                                          printed_something = 1;
                                         if (print_sep(ms, firstline) == -1)                                          if (print_sep(ms, firstline) == -1)
                                                 return -1;                                                  return -1;
Line 234 
Line 248 
                                  */                                   */
                                 /* space if previous printed */                                  /* space if previous printed */
                                 if (need_separator                                  if (need_separator
                                     && (magic[magindex].nospflag == 0)                                      && ((m->flag & NOSPACE) == 0)
                                     && (magic[magindex].desc[0] != '\0')) {                                      && *MAGIC_DESC) {
                                         if (file_printf(ms, " ") == -1)                                          if (file_printf(ms, " ") == -1)
                                                 return -1;                                                  return -1;
                                         need_separator = 0;                                          need_separator = 0;
                                 }                                  }
                                 if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) == -1)                                  if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1)
                                         return -1;                                          return -1;
                                 if (magic[magindex].desc[0])                                  if (*MAGIC_DESC)
                                         need_separator = 1;                                          need_separator = 1;
   
                                 /*                                  /*
Line 255 
Line 269 
                                 break;                                  break;
                         }                          }
                 }                  }
                 firstline = 0;                  if (printed_something) {
                 if (printed_something)                          firstline = 0;
                         returnval = 1;                          returnval = 1;
                   }
                 if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {                  if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
                         return 1; /* don't keep searching */                          return 1; /* don't keep searching */
                 }                  }
Line 271 
Line 286 
         regex_t rx;          regex_t rx;
         int rc;          int rc;
   
         if (strchr(m->desc, '%') == NULL)          if (strchr(MAGIC_DESC, '%') == NULL)
                 return 0;                  return 0;
   
         rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);          rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
Line 281 
Line 296 
                 file_magerror(ms, "regex error %d, (%s)", rc, errmsg);                  file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
                 return -1;                  return -1;
         } else {          } else {
                 rc = regexec(&rx, m->desc, 0, 0, 0);                  rc = regexec(&rx, MAGIC_DESC, 0, 0, 0);
                 regfree(&rx);                  regfree(&rx);
                 return !rc;                  return !rc;
         }          }
Line 311 
Line 326 
 mprint(struct magic_set *ms, struct magic *m)  mprint(struct magic_set *ms, struct magic *m)
 {  {
         uint64_t v;          uint64_t v;
           float vf;
           double vd;
         int64_t t = 0;          int64_t t = 0;
         char buf[512];          char *buf;
         union VALUETYPE *p = &ms->ms_value;          union VALUETYPE *p = &ms->ms_value;
   
         switch (m->type) {          switch (m->type) {
Line 322 
Line 339 
                 case -1:                  case -1:
                         return -1;                          return -1;
                 case 1:                  case 1:
                         if (snprintf(buf, sizeof(buf), "%c",                          if (asprintf(&buf, "%c", (unsigned char)v) < 0)
                             (unsigned char)v) < 0)  
                                 return -1;                                  return -1;
                         if (file_printf(ms, m->desc, buf) == -1)                          if (file_printf(ms, MAGIC_DESC, buf) == -1)
                                 return -1;                                  return -1;
                         break;                          break;
                 default:                  default:
                         if (file_printf(ms, m->desc, (unsigned char) v) == -1)                          if (file_printf(ms, MAGIC_DESC, (unsigned char) v) == -1)
                                 return -1;                                  return -1;
                         break;                          break;
                 }                  }
Line 344 
Line 360 
                 case -1:                  case -1:
                         return -1;                          return -1;
                 case 1:                  case 1:
                         if (snprintf(buf, sizeof(buf), "%hu",                          if (asprintf(&buf, "%hu", (unsigned short)v) < 0)
                             (unsigned short)v) < 0)  
                                 return -1;                                  return -1;
                         if (file_printf(ms, m->desc, buf) == -1)                          if (file_printf(ms, MAGIC_DESC, buf) == -1)
                                 return -1;                                  return -1;
                         break;                          break;
                 default:                  default:
                         if (file_printf(ms, m->desc, (unsigned short) v) == -1)                          if (file_printf(ms, MAGIC_DESC, (unsigned short) v) == -1)
                                 return -1;                                  return -1;
                         break;                          break;
                 }                  }
Line 367 
Line 382 
                 case -1:                  case -1:
                         return -1;                          return -1;
                 case 1:                  case 1:
                         if (snprintf(buf, sizeof(buf), "%u", (uint32_t)v) < 0)                          if (asprintf(&buf, "%u", (uint32_t)v) < 0)
                                 return -1;                                  return -1;
                         if (file_printf(ms, m->desc, buf) == -1)                          if (file_printf(ms, MAGIC_DESC, buf) == -1)
                                 return -1;                                  return -1;
                         break;                          break;
                 default:                  default:
                         if (file_printf(ms, m->desc, (uint32_t) v) == -1)                          if (file_printf(ms, MAGIC_DESC, (uint32_t) v) == -1)
                                 return -1;                                  return -1;
                         break;                          break;
                 }                  }
Line 384 
Line 399 
         case FILE_BEQUAD:          case FILE_BEQUAD:
         case FILE_LEQUAD:          case FILE_LEQUAD:
                 v = file_signextend(ms, m, p->q);                  v = file_signextend(ms, m, p->q);
                 if (file_printf(ms, m->desc, (uint64_t) v) == -1)                  if (file_printf(ms, MAGIC_DESC, (uint64_t) v) == -1)
                         return -1;                          return -1;
                 t = ms->offset + sizeof(int64_t);                  t = ms->offset + sizeof(int64_t);
                 break;                  break;
Line 394 
Line 409 
         case FILE_BESTRING16:          case FILE_BESTRING16:
         case FILE_LESTRING16:          case FILE_LESTRING16:
                 if (m->reln == '=' || m->reln == '!') {                  if (m->reln == '=' || m->reln == '!') {
                         if (file_printf(ms, m->desc, m->value.s) == -1)                          if (file_printf(ms, MAGIC_DESC, m->value.s) == -1)
                                 return -1;                                  return -1;
                         t = ms->offset + m->vallen;                          t = ms->offset + m->vallen;
                 }                  }
                 else {                  else {
                         if (*m->value.s == '\0')                          if (*m->value.s == '\0')
                                 p->s[strcspn(p->s, "\n")] = '\0';                                  p->s[strcspn(p->s, "\n")] = '\0';
                         if (file_printf(ms, m->desc, p->s) == -1)                          if (file_printf(ms, MAGIC_DESC, p->s) == -1)
                                 return -1;                                  return -1;
                         t = ms->offset + strlen(p->s);                          t = ms->offset + strlen(p->s);
                           if (m->type == FILE_PSTRING)
                                   t++;
                 }                  }
                 break;                  break;
   
Line 411 
Line 428 
         case FILE_BEDATE:          case FILE_BEDATE:
         case FILE_LEDATE:          case FILE_LEDATE:
         case FILE_MEDATE:          case FILE_MEDATE:
                 if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1)                  if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 1)) == -1)
                         return -1;                          return -1;
                 t = ms->offset + sizeof(time_t);                  t = ms->offset + sizeof(time_t);
                 break;                  break;
Line 420 
Line 437 
         case FILE_BELDATE:          case FILE_BELDATE:
         case FILE_LELDATE:          case FILE_LELDATE:
         case FILE_MELDATE:          case FILE_MELDATE:
                 if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1)                  if (file_printf(ms, MAGIC_DESC, file_fmttime(p->l, 0)) == -1)
                         return -1;                          return -1;
                 t = ms->offset + sizeof(time_t);                  t = ms->offset + sizeof(time_t);
                 break;                  break;
Line 428 
Line 445 
         case FILE_QDATE:          case FILE_QDATE:
         case FILE_BEQDATE:          case FILE_BEQDATE:
         case FILE_LEQDATE:          case FILE_LEQDATE:
                 if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 1))                  if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 1))
                     == -1)                      == -1)
                         return -1;                          return -1;
                 t = ms->offset + sizeof(uint64_t);                  t = ms->offset + sizeof(uint64_t);
Line 437 
Line 454 
         case FILE_QLDATE:          case FILE_QLDATE:
         case FILE_BEQLDATE:          case FILE_BEQLDATE:
         case FILE_LEQLDATE:          case FILE_LEQLDATE:
                 if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, 0))                  if (file_printf(ms, MAGIC_DESC, file_fmttime((uint32_t)p->q, 0))
                     == -1)                      == -1)
                         return -1;                          return -1;
                 t = ms->offset + sizeof(uint64_t);                  t = ms->offset + sizeof(uint64_t);
                 break;                  break;
   
           case FILE_FLOAT:
           case FILE_BEFLOAT:
           case FILE_LEFLOAT:
                   vf = p->f;
                   switch (check_fmt(ms, m)) {
                   case -1:
                           return -1;
                   case 1:
                           if (asprintf(&buf, "%g", vf) < 0)
                                   return -1;
                           if (file_printf(ms, MAGIC_DESC, buf) == -1)
                                   return -1;
                           break;
                   default:
                           if (file_printf(ms, MAGIC_DESC, vf) == -1)
                                   return -1;
                           break;
                   }
                   t = ms->offset + sizeof(float);
                   break;
   
           case FILE_DOUBLE:
           case FILE_BEDOUBLE:
           case FILE_LEDOUBLE:
                   vd = p->d;
                   switch (check_fmt(ms, m)) {
                   case -1:
                           return -1;
                   case 1:
                           if (asprintf(&buf, "%g", vd) < 0)
                                   return -1;
                           if (file_printf(ms, MAGIC_DESC, buf) == -1)
                                   return -1;
                           break;
                   default:
                           if (file_printf(ms, MAGIC_DESC, vd) == -1)
                                   return -1;
                           break;
                   }
                   t = ms->offset + sizeof(double);
                   break;
   
         case FILE_REGEX: {          case FILE_REGEX: {
                 char *cp;                  char *cp;
                 int rval;                  int rval;
Line 452 
Line 511 
                         file_oomem(ms, ms->search.rm_len);                          file_oomem(ms, ms->search.rm_len);
                         return -1;                          return -1;
                 }                  }
                 rval = file_printf(ms, m->desc, cp);                  rval = file_printf(ms, MAGIC_DESC, cp);
                 free(cp);                  free(cp);
   
                 if (rval == -1)                  if (rval == -1)
Line 466 
Line 525 
         }          }
   
         case FILE_SEARCH:          case FILE_SEARCH:
                 if (file_printf(ms, m->desc, m->value.s) == -1)                  if (file_printf(ms, MAGIC_DESC, m->value.s) == -1)
                         return -1;                          return -1;
                 if ((m->str_flags & REGEX_OFFSET_START))                  if ((m->str_flags & REGEX_OFFSET_START))
                         t = ms->search.offset;                          t = ms->search.offset;
Line 475 
Line 534 
                 break;                  break;
   
         case FILE_DEFAULT:          case FILE_DEFAULT:
                 if (file_printf(ms, m->desc, m->value.s) == -1)                  if (file_printf(ms, MAGIC_DESC, m->value.s) == -1)
                         return -1;                          return -1;
                 t = ms->offset;                  t = ms->offset;
                 break;                  break;
Line 543 
Line 602 
         DO_CVT(q, (uint64_t));          DO_CVT(q, (uint64_t));
 }  }
   
   #define DO_CVT2(fld, cast) \
           if (m->num_mask) \
                   switch (m->mask_op & FILE_OPS_MASK) { \
                   case FILE_OPADD: \
                           p->fld += cast m->num_mask; \
                           break; \
                   case FILE_OPMINUS: \
                           p->fld -= cast m->num_mask; \
                           break; \
                   case FILE_OPMULTIPLY: \
                           p->fld *= cast m->num_mask; \
                           break; \
                   case FILE_OPDIVIDE: \
                           p->fld /= cast m->num_mask; \
                           break; \
                   } \
   
   private void
   cvt_float(union VALUETYPE *p, const struct magic *m)
   {
           DO_CVT2(f, (float));
   }
   
   private void
   cvt_double(union VALUETYPE *p, const struct magic *m)
   {
           DO_CVT2(d, (double));
   }
   
 /*  /*
  * Convert the byte order of the data we are looking at   * Convert the byte order of the data we are looking at
  * While we're here, let's apply the mask operation   * While we're here, let's apply the mask operation
Line 609 
Line 697 
         case FILE_BEQUAD:          case FILE_BEQUAD:
         case FILE_BEQDATE:          case FILE_BEQDATE:
         case FILE_BEQLDATE:          case FILE_BEQLDATE:
                 p->q = (int64_t)                  p->q = (uint64_t)
                     (((int64_t)p->hq[0]<<56)|((int64_t)p->hq[1]<<48)|                      (((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
                      ((int64_t)p->hq[2]<<40)|((int64_t)p->hq[3]<<32)|                       ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
                      (p->hq[4]<<24)|(p->hq[5]<<16)|(p->hq[6]<<8)|(p->hq[7]));                       ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
                        ((uint64_t)p->hq[6]<<8)|((uint64_t)p->hq[7]));
                 cvt_64(p, m);                  cvt_64(p, m);
                 return 1;                  return 1;
         case FILE_LESHORT:          case FILE_LESHORT:
Line 629 
Line 718 
         case FILE_LEQUAD:          case FILE_LEQUAD:
         case FILE_LEQDATE:          case FILE_LEQDATE:
         case FILE_LEQLDATE:          case FILE_LEQLDATE:
                 p->q = (int64_t)                  p->q = (uint64_t)
                     (((int64_t)p->hq[7]<<56)|((int64_t)p->hq[6]<<48)|                      (((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
                      ((int64_t)p->hq[5]<<40)|((int64_t)p->hq[4]<<32)|                       ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
                      (p->hq[3]<<24)|(p->hq[2]<<16)|(p->hq[1]<<8)|(p->hq[0]));                       ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
                        ((uint64_t)p->hq[1]<<8)|((uint64_t)p->hq[0]));
                 cvt_64(p, m);                  cvt_64(p, m);
                 return 1;                  return 1;
         case FILE_MELONG:          case FILE_MELONG:
Line 642 
Line 732 
                     ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));                      ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));
                 cvt_32(p, m);                  cvt_32(p, m);
                 return 1;                  return 1;
           case FILE_FLOAT:
                   cvt_float(p, m);
                   return 1;
           case FILE_BEFLOAT:
                   p->l =  ((uint32_t)p->hl[0]<<24)|((uint32_t)p->hl[1]<<16)|
                           ((uint32_t)p->hl[2]<<8) |((uint32_t)p->hl[3]);
                   cvt_float(p, m);
                   return 1;
           case FILE_LEFLOAT:
                   p->l =  ((uint32_t)p->hl[3]<<24)|((uint32_t)p->hl[2]<<16)|
                           ((uint32_t)p->hl[1]<<8) |((uint32_t)p->hl[0]);
                   cvt_float(p, m);
                   return 1;
           case FILE_DOUBLE:
                   cvt_double(p, m);
                   return 1;
           case FILE_BEDOUBLE:
                   p->q =  ((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
                           ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
                           ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
                           ((uint64_t)p->hq[6]<<8) |((uint64_t)p->hq[7]);
                   cvt_double(p, m);
                   return 1;
           case FILE_LEDOUBLE:
                   p->q =  ((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
                           ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
                           ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
                           ((uint64_t)p->hq[1]<<8) |((uint64_t)p->hq[0]);
                   cvt_double(p, m);
                   return 1;
         case FILE_REGEX:          case FILE_REGEX:
         case FILE_SEARCH:          case FILE_SEARCH:
         case FILE_DEFAULT:          case FILE_DEFAULT:
Line 675 
Line 795 
                 case FILE_SEARCH:                  case FILE_SEARCH:
                         ms->search.s = (const char *)s + offset;                          ms->search.s = (const char *)s + offset;
                         ms->search.s_len = nbytes - offset;                          ms->search.s_len = nbytes - offset;
                           ms->search.offset = offset;
                         return 0;                          return 0;
   
                 case FILE_REGEX: {                  case FILE_REGEX: {
                         /*  
                          * offset is interpreted as last line to search,  
                          * (starting at 1), not as bytes-from start-of-file  
                          */  
                         const char *b;                          const char *b;
                         const char *c;                          const char *c;
                         const char *last;       /* end of search region */                          const char *last;       /* end of search region */
Line 728 
Line 845 
                                     offset);                                      offset);
                                 return -1;                                  return -1;
                         }                          }
                         for (/*EMPTY*/; src < esrc; src++, dst++) {                          for (/*EMPTY*/; src < esrc; src += 2, dst++) {
                                 if (dst < edst)                                  if (dst < edst)
                                         *dst = *src++;                                          *dst = *src;
                                 else                                  else
                                         break;                                          break;
                                 if (*dst == '\0')                                  if (*dst == '\0') {
                                         *dst = ' ';                                          if (type == FILE_BESTRING16 ?
                                               *(src - 1) != '\0' :
                                               *(src + 1) != '\0')
                                                   *dst = ' ';
                                   }
                         }                          }
                         *edst = '\0';                          *edst = '\0';
                         return 0;                          return 0;
Line 772 
Line 893 
     struct magic *m, size_t nbytes, unsigned int cont_level)      struct magic *m, size_t nbytes, unsigned int cont_level)
 {  {
         uint32_t offset = ms->offset;          uint32_t offset = ms->offset;
         uint32_t count = m->str_count;          uint32_t count = m->str_range;
         union VALUETYPE *p = &ms->ms_value;          union VALUETYPE *p = &ms->ms_value;
   
         if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)          if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
Line 1233 
Line 1354 
                                 case FILE_OPMODULO:                                  case FILE_OPMODULO:
                                         offset = p->l % off;                                          offset = p->l % off;
                                         break;                                          break;
                         /*      case TOOMANYSWITCHBLOCKS:  
                          *              ugh = p->eye % m->strain;  
                          *              rub;  
                          *      case BEER:  
                          *              off = p->tab & m->in_gest;  
                          *              sleep;  
                          */  
                                 }                                  }
                         } else                          } else
                                 offset = p->l;                                  offset = p->l;
Line 1287 
Line 1401 
         case FILE_BELDATE:          case FILE_BELDATE:
         case FILE_LELDATE:          case FILE_LELDATE:
         case FILE_MELDATE:          case FILE_MELDATE:
           case FILE_FLOAT:
           case FILE_BEFLOAT:
           case FILE_LEFLOAT:
                 if (nbytes < (offset + 4))                  if (nbytes < (offset + 4))
                         return 0;                          return 0;
                 break;                  break;
   
           case FILE_DOUBLE:
           case FILE_BEDOUBLE:
           case FILE_LEDOUBLE:
                   if (nbytes < (offset + 8))
                           return 0;
                   break;
   
         case FILE_STRING:          case FILE_STRING:
         case FILE_PSTRING:          case FILE_PSTRING:
         case FILE_SEARCH:          case FILE_SEARCH:
Line 1326 
Line 1450 
         uint64_t v;          uint64_t v;
   
         /*          /*
          * What we want here is:           * What we want here is v = strncmp(s1, s2, len),
          * v = strncmp(m->value.s, p->s, m->vallen);           * but ignoring any nulls.
          * but ignoring any nulls.  bcmp doesn't give -/+/0  
          * and isn't universally available anyway.  
          */           */
         v = 0;          v = 0;
         if (0L == flags) { /* normal string: do it fast */          if (0L == flags) { /* normal string: do it fast */
Line 1393 
Line 1515 
 {  {
         uint64_t l = m->value.q;          uint64_t l = m->value.q;
         uint64_t v;          uint64_t v;
           float fl, fv;
           double dl, dv;
         int matched;          int matched;
         union VALUETYPE *p = &ms->ms_value;          union VALUETYPE *p = &ms->ms_value;
   
Line 1434 
Line 1558 
                 v = p->q;                  v = p->q;
                 break;                  break;
   
           case FILE_FLOAT:
           case FILE_BEFLOAT:
           case FILE_LEFLOAT:
                   fl = m->value.f;
                   fv = p->f;
                   switch (m->reln) {
                   case 'x':
                           matched = 1;
                           break;
   
                   case '!':
                           matched = fv != fl;
                           break;
   
                   case '=':
                           matched = fv == fl;
                           break;
   
                   case '>':
                           matched = fv > fl;
                           break;
   
                   case '<':
                           matched = fv < fl;
                           break;
   
                   default:
                           matched = 0;
                           file_magerror(ms, "cannot happen with float: invalid relation `%c'", m->reln);
                           return -1;
                   }
                   return matched;
   
           case FILE_DOUBLE:
           case FILE_BEDOUBLE:
           case FILE_LEDOUBLE:
                   dl = m->value.d;
                   dv = p->d;
                   switch (m->reln) {
                   case 'x':
                           matched = 1;
                           break;
   
                   case '!':
                           matched = dv != dl;
                           break;
   
                   case '=':
                           matched = dv == dl;
                           break;
   
                   case '>':
                           matched = dv > dl;
                           break;
   
                   case '<':
                           matched = dv < dl;
                           break;
   
                   default:
                           matched = 0;
                           file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln);
                           return -1;
                   }
                   return matched;
   
         case FILE_DEFAULT:          case FILE_DEFAULT:
                 l = 0;                  l = 0;
                 v = 0;                  v = 0;
Line 1461 
Line 1651 
                 slen = MIN(m->vallen, sizeof(m->value.s));                  slen = MIN(m->vallen, sizeof(m->value.s));
                 l = 0;                  l = 0;
                 v = 0;                  v = 0;
                 ms->search.offset = m->offset;  
   
                 for (idx = 0; m->str_count == 0 || idx < m->str_count; idx++) {                  for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
                         if (slen + idx > ms->search.s_len)                          if (slen + idx > ms->search.s_len)
                                 break;                                  break;
   
                         v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags);                          v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags);
                         if (v == 0) {   /* found match */                          if (v == 0) {   /* found match */
                                 ms->search.offset = m->offset + idx;                                  ms->search.offset += idx;
                                 break;                                  break;
                         }                          }
                 }                  }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14