00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "system.h"
00029 #include "file.h"
00030 #include "debug.h"
00031
00032 FILE_RCSID("@(#)Id: softmagic.c,v 1.51 2002/07/03 18:26:38 christos Exp ")
00033
00034
00035
00036
00037 static int32_t
00038 fmagicSPrint(const fmagic fm, struct magic *m)
00039
00040
00041 {
00042 union VALUETYPE * p = &fm->val;
00043 uint32_t v;
00044 int32_t t = 0;
00045
00046 switch (m->type) {
00047 case BYTE:
00048 v = signextend(m, p->b);
00049 fmagicPrintf(fm, m->desc, (unsigned char) v);
00050
00051 t = m->offset + sizeof(char);
00052
00053 break;
00054
00055 case SHORT:
00056 case BESHORT:
00057 case LESHORT:
00058 v = signextend(m, p->h);
00059 fmagicPrintf(fm, m->desc, (unsigned short) v);
00060
00061 t = m->offset + sizeof(short);
00062
00063 break;
00064
00065 case LONG:
00066 case BELONG:
00067 case LELONG:
00068 v = signextend(m, p->l);
00069 fmagicPrintf(fm, m->desc, (uint32_t) v);
00070
00071 t = m->offset + sizeof(int32_t);
00072
00073 break;
00074
00075 case STRING:
00076 case PSTRING:
00077 if (m->reln == '=') {
00078 fmagicPrintf(fm, m->desc, m->value.s);
00079 t = m->offset + strlen(m->value.s);
00080 } else {
00081 if (*m->value.s == '\0') {
00082 char *cp = strchr(p->s,'\n');
00083 if (cp != NULL)
00084 *cp = '\0';
00085 }
00086 fmagicPrintf(fm, m->desc, p->s);
00087 t = m->offset + strlen(p->s);
00088 }
00089 break;
00090
00091 case DATE:
00092 case BEDATE:
00093 case LEDATE:
00094 fmagicPrintf(fm, m->desc, fmttime(p->l, 1));
00095
00096 t = m->offset + sizeof(time_t);
00097
00098 break;
00099
00100 case LDATE:
00101 case BELDATE:
00102 case LELDATE:
00103 fmagicPrintf(fm, m->desc, fmttime(p->l, 0));
00104
00105 t = m->offset + sizeof(time_t);
00106
00107 break;
00108
00109 case REGEX:
00110 fmagicPrintf(fm, m->desc, p->s);
00111 t = m->offset + strlen(p->s);
00112 break;
00113
00114 default:
00115 error(EXIT_FAILURE, 0, "invalid m->type (%d) in fmagicSPrint().\n", m->type);
00116 break;
00117 }
00118 return(t);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128 static int
00129 fmagicSConvert(fmagic fm, struct magic *m)
00130
00131
00132 {
00133 union VALUETYPE * p = &fm->val;
00134
00135 switch (m->type) {
00136 case BYTE:
00137 if (m->mask)
00138 switch (m->mask_op&0x7F) {
00139 case OPAND:
00140 p->b &= m->mask;
00141 break;
00142 case OPOR:
00143 p->b |= m->mask;
00144 break;
00145 case OPXOR:
00146 p->b ^= m->mask;
00147 break;
00148 case OPADD:
00149 p->b += m->mask;
00150 break;
00151 case OPMINUS:
00152 p->b -= m->mask;
00153 break;
00154 case OPMULTIPLY:
00155 p->b *= m->mask;
00156 break;
00157 case OPDIVIDE:
00158 p->b /= m->mask;
00159 break;
00160 case OPMODULO:
00161 p->b %= m->mask;
00162 break;
00163 }
00164 if (m->mask_op & OPINVERSE)
00165 p->b = ~p->b;
00166 return 1;
00167 case SHORT:
00168 if (m->mask)
00169 switch (m->mask_op&0x7F) {
00170 case OPAND:
00171 p->h &= m->mask;
00172 break;
00173 case OPOR:
00174 p->h |= m->mask;
00175 break;
00176 case OPXOR:
00177 p->h ^= m->mask;
00178 break;
00179 case OPADD:
00180 p->h += m->mask;
00181 break;
00182 case OPMINUS:
00183 p->h -= m->mask;
00184 break;
00185 case OPMULTIPLY:
00186 p->h *= m->mask;
00187 break;
00188 case OPDIVIDE:
00189 p->h /= m->mask;
00190 break;
00191 case OPMODULO:
00192 p->h %= m->mask;
00193 break;
00194 }
00195 if (m->mask_op & OPINVERSE)
00196 p->h = ~p->h;
00197 return 1;
00198 case LONG:
00199 case DATE:
00200 case LDATE:
00201 if (m->mask)
00202 switch (m->mask_op&0x7F) {
00203 case OPAND:
00204 p->l &= m->mask;
00205 break;
00206 case OPOR:
00207 p->l |= m->mask;
00208 break;
00209 case OPXOR:
00210 p->l ^= m->mask;
00211 break;
00212 case OPADD:
00213 p->l += m->mask;
00214 break;
00215 case OPMINUS:
00216 p->l -= m->mask;
00217 break;
00218 case OPMULTIPLY:
00219 p->l *= m->mask;
00220 break;
00221 case OPDIVIDE:
00222 p->l /= m->mask;
00223 break;
00224 case OPMODULO:
00225 p->l %= m->mask;
00226 break;
00227 }
00228 if (m->mask_op & OPINVERSE)
00229 p->l = ~p->l;
00230 return 1;
00231 case STRING:
00232 {
00233 int n;
00234
00235
00236 p->s[sizeof(p->s) - 1] = '\0';
00237 n = strlen(p->s) - 1;
00238 if (p->s[n] == '\n')
00239 p->s[n] = '\0';
00240 return 1;
00241 }
00242 case PSTRING:
00243 {
00244 char *ptr1 = p->s, *ptr2 = ptr1 + 1;
00245 int n = *p->s;
00246 if (n >= sizeof(p->s))
00247 n = sizeof(p->s) - 1;
00248 while (n--)
00249 *ptr1++ = *ptr2++;
00250 *ptr1 = '\0';
00251 n = strlen(p->s) - 1;
00252 if (p->s[n] == '\n')
00253 p->s[n] = '\0';
00254 return 1;
00255 }
00256 case BESHORT:
00257 p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
00258 if (m->mask)
00259 switch (m->mask_op&0x7F) {
00260 case OPAND:
00261 p->h &= m->mask;
00262 break;
00263 case OPOR:
00264 p->h |= m->mask;
00265 break;
00266 case OPXOR:
00267 p->h ^= m->mask;
00268 break;
00269 case OPADD:
00270 p->h += m->mask;
00271 break;
00272 case OPMINUS:
00273 p->h -= m->mask;
00274 break;
00275 case OPMULTIPLY:
00276 p->h *= m->mask;
00277 break;
00278 case OPDIVIDE:
00279 p->h /= m->mask;
00280 break;
00281 case OPMODULO:
00282 p->h %= m->mask;
00283 break;
00284 }
00285 if (m->mask_op & OPINVERSE)
00286 p->h = ~p->h;
00287 return 1;
00288 case BELONG:
00289 case BEDATE:
00290 case BELDATE:
00291 p->l = (int32_t)
00292 ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
00293 if (m->mask)
00294 switch (m->mask_op&0x7F) {
00295 case OPAND:
00296 p->l &= m->mask;
00297 break;
00298 case OPOR:
00299 p->l |= m->mask;
00300 break;
00301 case OPXOR:
00302 p->l ^= m->mask;
00303 break;
00304 case OPADD:
00305 p->l += m->mask;
00306 break;
00307 case OPMINUS:
00308 p->l -= m->mask;
00309 break;
00310 case OPMULTIPLY:
00311 p->l *= m->mask;
00312 break;
00313 case OPDIVIDE:
00314 p->l /= m->mask;
00315 break;
00316 case OPMODULO:
00317 p->l %= m->mask;
00318 break;
00319 }
00320 if (m->mask_op & OPINVERSE)
00321 p->l = ~p->l;
00322 return 1;
00323 case LESHORT:
00324 p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
00325 if (m->mask)
00326 switch (m->mask_op&0x7F) {
00327 case OPAND:
00328 p->h &= m->mask;
00329 break;
00330 case OPOR:
00331 p->h |= m->mask;
00332 break;
00333 case OPXOR:
00334 p->h ^= m->mask;
00335 break;
00336 case OPADD:
00337 p->h += m->mask;
00338 break;
00339 case OPMINUS:
00340 p->h -= m->mask;
00341 break;
00342 case OPMULTIPLY:
00343 p->h *= m->mask;
00344 break;
00345 case OPDIVIDE:
00346 p->h /= m->mask;
00347 break;
00348 case OPMODULO:
00349 p->h %= m->mask;
00350 break;
00351 }
00352 if (m->mask_op & OPINVERSE)
00353 p->h = ~p->h;
00354 return 1;
00355 case LELONG:
00356 case LEDATE:
00357 case LELDATE:
00358 p->l = (int32_t)
00359 ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
00360 if (m->mask)
00361 switch (m->mask_op&0x7F) {
00362 case OPAND:
00363 p->l &= m->mask;
00364 break;
00365 case OPOR:
00366 p->l |= m->mask;
00367 break;
00368 case OPXOR:
00369 p->l ^= m->mask;
00370 break;
00371 case OPADD:
00372 p->l += m->mask;
00373 break;
00374 case OPMINUS:
00375 p->l -= m->mask;
00376 break;
00377 case OPMULTIPLY:
00378 p->l *= m->mask;
00379 break;
00380 case OPDIVIDE:
00381 p->l /= m->mask;
00382 break;
00383 case OPMODULO:
00384 p->l %= m->mask;
00385 break;
00386 }
00387 if (m->mask_op & OPINVERSE)
00388 p->l = ~p->l;
00389 return 1;
00390 case REGEX:
00391 return 1;
00392 default:
00393 error(EXIT_FAILURE, 0, "invalid type %d in fmagicSConvert().\n", m->type);
00394
00395 return 0;
00396 }
00397 }
00398
00399
00400
00401 static void
00402 fmagicSDebug(int32_t offset, char *str, int len)
00403
00404
00405 {
00406 (void) fprintf(stderr, "fmagicSGet @%d: ", offset);
00407 showstr(stderr, (char *) str, len);
00408 (void) fputc('\n', stderr);
00409 (void) fputc('\n', stderr);
00410 }
00411
00412
00413 static int
00414 fmagicSGet(fmagic fm, struct magic *m)
00415
00416
00417 {
00418 unsigned char * buf = fm->buf;
00419 int nb = fm->nb;
00420 union VALUETYPE * p = &fm->val;
00421 int32_t offset = m->offset;
00422
00423
00424 if (m->type == REGEX) {
00425
00426
00427
00428
00429 char *last = NULL;
00430
00431 p->buf = buf;
00432
00433 for (; offset && (buf = strchr(buf, '\n')) != NULL; offset--, buf++)
00434 last = buf;
00435 if (last != NULL)
00436 *last = '\0';
00437 } else if (offset + sizeof(*p) <= nb)
00438 memcpy(p, buf + offset, sizeof(*p));
00439 else {
00440
00441
00442
00443
00444 int32_t have = nb - offset;
00445 memset(p, 0, sizeof(*p));
00446 if (have > 0)
00447 memcpy(p, buf + offset, have);
00448 }
00449
00450
00451 if (fm->flags & FMAGIC_FLAGS_DEBUG) {
00452 fmagicSDebug(offset, (char *) p, sizeof(*p));
00453 mdump(m);
00454 }
00455
00456 if (m->flag & INDIR) {
00457 switch (m->in_type) {
00458 case BYTE:
00459 if (m->in_offset)
00460 switch (m->in_op&0x7F) {
00461 case OPAND:
00462 offset = p->b & m->in_offset;
00463 break;
00464 case OPOR:
00465 offset = p->b | m->in_offset;
00466 break;
00467 case OPXOR:
00468 offset = p->b ^ m->in_offset;
00469 break;
00470 case OPADD:
00471 offset = p->b + m->in_offset;
00472 break;
00473 case OPMINUS:
00474 offset = p->b - m->in_offset;
00475 break;
00476 case OPMULTIPLY:
00477 offset = p->b * m->in_offset;
00478 break;
00479 case OPDIVIDE:
00480 offset = p->b / m->in_offset;
00481 break;
00482 case OPMODULO:
00483 offset = p->b % m->in_offset;
00484 break;
00485 }
00486 if (m->in_op & OPINVERSE)
00487 offset = ~offset;
00488 break;
00489 case BESHORT:
00490 if (m->in_offset)
00491 switch (m->in_op&0x7F) {
00492 case OPAND:
00493 offset = (short)((p->hs[0]<<8) | (p->hs[1])) &
00494 m->in_offset;
00495 break;
00496 case OPOR:
00497 offset = (short)((p->hs[0]<<8) | (p->hs[1])) |
00498 m->in_offset;
00499 break;
00500 case OPXOR:
00501 offset = (short)((p->hs[0]<<8) | (p->hs[1])) ^
00502 m->in_offset;
00503 break;
00504 case OPADD:
00505 offset = (short)((p->hs[0]<<8) | (p->hs[1])) +
00506 m->in_offset;
00507 break;
00508 case OPMINUS:
00509 offset = (short)((p->hs[0]<<8) | (p->hs[1])) -
00510 m->in_offset;
00511 break;
00512 case OPMULTIPLY:
00513 offset = (short)((p->hs[0]<<8) | (p->hs[1])) *
00514 m->in_offset;
00515 break;
00516 case OPDIVIDE:
00517 offset = (short)((p->hs[0]<<8) | (p->hs[1])) /
00518 m->in_offset;
00519 break;
00520 case OPMODULO:
00521 offset = (short)((p->hs[0]<<8) | (p->hs[1])) %
00522 m->in_offset;
00523 break;
00524 }
00525 if (m->in_op & OPINVERSE)
00526 offset = ~offset;
00527 break;
00528 case LESHORT:
00529 if (m->in_offset)
00530 switch (m->in_op&0x7F) {
00531 case OPAND:
00532 offset = (short)((p->hs[1]<<8) | (p->hs[0])) &
00533 m->in_offset;
00534 break;
00535 case OPOR:
00536 offset = (short)((p->hs[1]<<8) | (p->hs[0])) |
00537 m->in_offset;
00538 break;
00539 case OPXOR:
00540 offset = (short)((p->hs[1]<<8) | (p->hs[0])) ^
00541 m->in_offset;
00542 break;
00543 case OPADD:
00544 offset = (short)((p->hs[1]<<8) | (p->hs[0])) +
00545 m->in_offset;
00546 break;
00547 case OPMINUS:
00548 offset = (short)((p->hs[1]<<8) | (p->hs[0])) -
00549 m->in_offset;
00550 break;
00551 case OPMULTIPLY:
00552 offset = (short)((p->hs[1]<<8) | (p->hs[0])) *
00553 m->in_offset;
00554 break;
00555 case OPDIVIDE:
00556 offset = (short)((p->hs[1]<<8) | (p->hs[0])) /
00557 m->in_offset;
00558 break;
00559 case OPMODULO:
00560 offset = (short)((p->hs[1]<<8) | (p->hs[0])) %
00561 m->in_offset;
00562 break;
00563 }
00564 if (m->in_op & OPINVERSE)
00565 offset = ~offset;
00566 break;
00567 case SHORT:
00568 if (m->in_offset)
00569 switch (m->in_op&0x7F) {
00570 case OPAND:
00571 offset = p->h & m->in_offset;
00572 break;
00573 case OPOR:
00574 offset = p->h | m->in_offset;
00575 break;
00576 case OPXOR:
00577 offset = p->h ^ m->in_offset;
00578 break;
00579 case OPADD:
00580 offset = p->h + m->in_offset;
00581 break;
00582 case OPMINUS:
00583 offset = p->h - m->in_offset;
00584 break;
00585 case OPMULTIPLY:
00586 offset = p->h * m->in_offset;
00587 break;
00588 case OPDIVIDE:
00589 offset = p->h / m->in_offset;
00590 break;
00591 case OPMODULO:
00592 offset = p->h % m->in_offset;
00593 break;
00594 }
00595 if (m->in_op & OPINVERSE)
00596 offset = ~offset;
00597 break;
00598 case BELONG:
00599 if (m->in_offset)
00600 switch (m->in_op&0x7F) {
00601 case OPAND:
00602 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00603 (p->hl[2]<< 8) | (p->hl[3])) &
00604 m->in_offset;
00605 break;
00606 case OPOR:
00607 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00608 (p->hl[2]<< 8) | (p->hl[3])) |
00609 m->in_offset;
00610 break;
00611 case OPXOR:
00612 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00613 (p->hl[2]<< 8) | (p->hl[3])) ^
00614 m->in_offset;
00615 break;
00616 case OPADD:
00617 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00618 (p->hl[2]<< 8) | (p->hl[3])) +
00619 m->in_offset;
00620 break;
00621 case OPMINUS:
00622 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00623 (p->hl[2]<< 8) | (p->hl[3])) -
00624 m->in_offset;
00625 break;
00626 case OPMULTIPLY:
00627 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00628 (p->hl[2]<< 8) | (p->hl[3])) *
00629 m->in_offset;
00630 break;
00631 case OPDIVIDE:
00632 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00633 (p->hl[2]<< 8) | (p->hl[3])) /
00634 m->in_offset;
00635 break;
00636 case OPMODULO:
00637 offset = (int32_t)( (p->hl[0]<<24) | (p->hl[1]<<16) |
00638 (p->hl[2]<< 8) | (p->hl[3])) %
00639 m->in_offset;
00640 break;
00641 }
00642 if (m->in_op & OPINVERSE)
00643 offset = ~offset;
00644 break;
00645 case LELONG:
00646 if (m->in_offset)
00647 switch (m->in_op&0x7F) {
00648 case OPAND:
00649 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00650 (p->hl[1]<< 8) | (p->hl[0])) &
00651 m->in_offset;
00652 break;
00653 case OPOR:
00654 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00655 (p->hl[1]<< 8) | (p->hl[0])) |
00656 m->in_offset;
00657 break;
00658 case OPXOR:
00659 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00660 (p->hl[1]<< 8) | (p->hl[0])) ^
00661 m->in_offset;
00662 break;
00663 case OPADD:
00664 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00665 (p->hl[1]<< 8) | (p->hl[0])) +
00666 m->in_offset;
00667 break;
00668 case OPMINUS:
00669 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00670 (p->hl[1]<< 8) | (p->hl[0])) -
00671 m->in_offset;
00672 break;
00673 case OPMULTIPLY:
00674 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00675 (p->hl[1]<< 8) | (p->hl[0])) *
00676 m->in_offset;
00677 break;
00678 case OPDIVIDE:
00679 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00680 (p->hl[1]<< 8) | (p->hl[0])) /
00681 m->in_offset;
00682 break;
00683 case OPMODULO:
00684 offset = (int32_t)( (p->hl[3]<<24) | (p->hl[2]<<16) |
00685 (p->hl[1]<< 8) | (p->hl[0])) %
00686 m->in_offset;
00687 break;
00688 }
00689 if (m->in_op & OPINVERSE)
00690 offset = ~offset;
00691 break;
00692 case LONG:
00693 if (m->in_offset)
00694 switch (m->in_op&0x7F) {
00695 case OPAND:
00696 offset = p->l & m->in_offset;
00697 break;
00698 case OPOR:
00699 offset = p->l | m->in_offset;
00700 break;
00701 case OPXOR:
00702 offset = p->l ^ m->in_offset;
00703 break;
00704 case OPADD:
00705 offset = p->l + m->in_offset;
00706 break;
00707 case OPMINUS:
00708 offset = p->l - m->in_offset;
00709 break;
00710 case OPMULTIPLY:
00711 offset = p->l * m->in_offset;
00712 break;
00713 case OPDIVIDE:
00714 offset = p->l / m->in_offset;
00715 break;
00716 case OPMODULO:
00717 offset = p->l % m->in_offset;
00718 break;
00719
00720
00721
00722
00723
00724
00725
00726 }
00727 if (m->in_op & OPINVERSE)
00728 offset = ~offset;
00729 break;
00730 }
00731
00732
00733 if (buf == NULL || offset + sizeof(*p) > nb)
00734 return 0;
00735
00736
00737 memcpy(p, buf + offset, sizeof(*p));
00738
00739 if (fm->flags & FMAGIC_FLAGS_DEBUG) {
00740 fmagicSDebug(offset, (char *) p, sizeof(*p));
00741 mdump(m);
00742 }
00743 }
00744
00745 if (!fmagicSConvert(fm, m))
00746 return 0;
00747 return 1;
00748
00749 }
00750
00751
00752
00753 static int
00754 fmagicSCheck(const fmagic fm, struct magic *m)
00755
00756
00757 {
00758 union VALUETYPE * p = &fm->val;
00759 uint32_t l = m->value.l;
00760 uint32_t v = 0;
00761 int matched;
00762
00763 if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
00764 fprintf(stderr, "BOINK");
00765 return 1;
00766 }
00767
00768 switch (m->type) {
00769 case BYTE:
00770 v = p->b;
00771 break;
00772
00773 case SHORT:
00774 case BESHORT:
00775 case LESHORT:
00776 v = p->h;
00777 break;
00778
00779 case LONG:
00780 case BELONG:
00781 case LELONG:
00782 case DATE:
00783 case BEDATE:
00784 case LEDATE:
00785 case LDATE:
00786 case BELDATE:
00787 case LELDATE:
00788 v = p->l;
00789 break;
00790
00791 case STRING:
00792 case PSTRING:
00793 {
00794
00795
00796
00797
00798
00799
00800 unsigned char *a = (unsigned char*)m->value.s;
00801 unsigned char *b = (unsigned char*)p->s;
00802 int len = m->vallen;
00803 l = 0;
00804 v = 0;
00805 if (0L == m->mask) {
00806 while (--len >= 0)
00807 if ((v = *b++ - *a++) != '\0')
00808 break;
00809 } else {
00810 while (--len >= 0) {
00811 if ((m->mask & STRING_IGNORE_LOWERCASE) && islower(*a)) {
00812 if ((v = tolower(*b++) - *a++) != '\0')
00813 break;
00814 } else
00815 if ((m->mask & STRING_COMPACT_BLANK) && isspace(*a)) {
00816 a++;
00817 if (isspace(*b++)) {
00818 while (isspace(*b))
00819 b++;
00820 } else {
00821 v = 1;
00822 break;
00823 }
00824 } else
00825 if (isspace(*a) && (m->mask & STRING_COMPACT_OPTIONAL_BLANK)) {
00826 a++;
00827 while (isspace(*b))
00828 b++;
00829 } else {
00830 if ((v = *b++ - *a++) != '\0')
00831 break;
00832 }
00833 }
00834 }
00835 break;
00836 }
00837 case REGEX:
00838 {
00839 int rc;
00840 regex_t rx;
00841 char errmsg[512];
00842
00843 rc = regcomp(&rx, m->value.s, REG_EXTENDED|REG_NOSUB);
00844 if (rc) {
00845 (void) regerror(rc, &rx, errmsg, sizeof(errmsg));
00846 error(EXIT_FAILURE, 0, "regex error %d, (%s)\n", rc, errmsg);
00847
00848 } else {
00849 rc = regexec(&rx, p->buf, 0, NULL, 0);
00850 return !rc;
00851 }
00852 }
00853 break;
00854 default:
00855 error(EXIT_FAILURE, 0, "invalid type %d in fmagicSCheck().\n", m->type);
00856
00857 return 0;
00858 }
00859
00860 if(m->type != STRING && m->type != PSTRING)
00861 v = signextend(m, v);
00862
00863 switch (m->reln) {
00864 case 'x':
00865 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00866 (void) fprintf(stderr, "%u == *any* = 1\n", v);
00867 matched = 1;
00868 break;
00869
00870 case '!':
00871 matched = v != l;
00872 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00873 (void) fprintf(stderr, "%u != %u = %d\n",
00874 v, l, matched);
00875 break;
00876
00877 case '=':
00878 matched = v == l;
00879 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00880 (void) fprintf(stderr, "%u == %u = %d\n",
00881 v, l, matched);
00882 break;
00883
00884 case '>':
00885 if (m->flag & UNSIGNED) {
00886 matched = v > l;
00887 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00888 (void) fprintf(stderr, "%u > %u = %d\n", v, l, matched);
00889 }
00890 else {
00891 matched = (int32_t) v > (int32_t) l;
00892 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00893 (void) fprintf(stderr, "%d > %d = %d\n", v, l, matched);
00894 }
00895 break;
00896
00897 case '<':
00898 if (m->flag & UNSIGNED) {
00899 matched = v < l;
00900 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00901 (void) fprintf(stderr, "%u < %u = %d\n", v, l, matched);
00902 }
00903 else {
00904 matched = (int32_t) v < (int32_t) l;
00905 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00906 (void) fprintf(stderr, "%d < %d = %d\n", v, l, matched);
00907 }
00908 break;
00909
00910 case '&':
00911 matched = (v & l) == l;
00912 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00913 (void) fprintf(stderr, "((%x & %x) == %x) = %d\n", v, l, l, matched);
00914 break;
00915
00916 case '^':
00917 matched = (v & l) != l;
00918 if (fm->flags & FMAGIC_FLAGS_DEBUG)
00919 (void) fprintf(stderr, "((%x & %x) != %x) = %d\n", v, l, l, matched);
00920 break;
00921
00922 default:
00923 matched = 0;
00924 error(EXIT_FAILURE, 0, "fmagicSCheck: can't happen: invalid relation %d.\n", m->reln);
00925 break;
00926 }
00927
00928 return matched;
00929 }
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 static int
00961 fmagicSMatch(const fmagic fm)
00962
00963
00964 {
00965 struct magic * m;
00966 uint32_t nmagic = fm->ml->nmagic;
00967 int cont_level = 0;
00968 int need_separator = 0;
00969
00970 static int32_t * tmpoff = NULL;
00971 static int tmpdelta = 64;
00972 static size_t tmplen = 0;
00973 int32_t oldoff = 0;
00974 int firstline = 1;
00975 int ret = 0;
00976 int i;
00977
00978 for (i = 0; i < nmagic; i++) {
00979 m = &fm->ml->magic[i];
00980
00981 if (!fmagicSGet(fm, m) || !fmagicSCheck(fm, m)) {
00982
00983 while ((m+1)->cont_level != 0 && ++i < nmagic)
00984 m++;
00985 continue;
00986 }
00987
00988 if (! firstline) {
00989
00990 fmagicPrintf(fm, "\n- ");
00991 }
00992
00993 if ((cont_level+1) >= tmplen) {
00994 tmplen += tmpdelta;
00995 tmpoff = xrealloc(tmpoff, tmplen * sizeof(*tmpoff));
00996 }
00997 tmpoff[cont_level] = fmagicSPrint(fm, m);
00998 cont_level++;
00999
01000
01001
01002
01003
01004 if (m->desc[0])
01005 need_separator = 1;
01006
01007
01008 while ((m+1)->cont_level != 0 && ++i < nmagic) {
01009 m++;
01010 if (cont_level < m->cont_level)
01011 continue;
01012 if (cont_level > m->cont_level) {
01013
01014 cont_level = m->cont_level;
01015 }
01016 if (m->flag & OFFADD) {
01017 oldoff = m->offset;
01018 m->offset += tmpoff[cont_level-1];
01019 }
01020 if (fmagicSGet(fm, m) && fmagicSCheck(fm, m)) {
01021
01022
01023
01024
01025
01026
01027 if (need_separator
01028 && (m->nospflag == 0) && (m->desc[0] != '\0'))
01029 {
01030 fmagicPrintf(fm, " ");
01031 need_separator = 0;
01032 }
01033 if ((cont_level+1) >= tmplen) {
01034 tmplen += tmpdelta;
01035 tmpoff = xrealloc(tmpoff, tmplen * sizeof(*tmpoff));
01036 }
01037 tmpoff[cont_level] = fmagicSPrint(fm, m);
01038 cont_level++;
01039 if (m->desc[0])
01040 need_separator = 1;
01041 }
01042 if (m->flag & OFFADD)
01043 m->offset = oldoff;
01044 }
01045 firstline = 0;
01046 ret = 1;
01047 if (!(fm->flags & FMAGIC_FLAGS_CONTINUE))
01048 return 1;
01049 }
01050 return ret;
01051 }
01052
01053
01054
01055
01056
01057
01058
01059 int
01060 fmagicS(fmagic fm)
01061 {
01062
01063 if (fm->mlist != NULL)
01064 for (fm->ml = fm->mlist->next; fm->ml != fm->mlist; fm->ml = fm->ml->next) {
01065
01066 if (fmagicSMatch(fm))
01067 return 1;
01068
01069 }
01070
01071
01072
01073 return 0;
01074
01075 }