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