softmagic.c 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. /*
  2. * softmagic - interpret variable magic from MAGIC
  3. *
  4. * Copyright (c) Ian F. Darwin, 1987.
  5. * Written by Ian F. Darwin.
  6. *
  7. * This software is not subject to any license of the American Telephone
  8. * and Telegraph Company or of the Regents of the University of California.
  9. *
  10. * Permission is granted to anyone to use this software for any purpose on
  11. * any computer system, and to alter it and redistribute it freely, subject
  12. * to the following restrictions:
  13. *
  14. * 1. The author is not responsible for the consequences of use of this
  15. * software, no matter how awful, even if they arise from flaws in it.
  16. *
  17. * 2. The origin of this software must not be misrepresented, either by
  18. * explicit claim or by omission. Since few users ever read sources,
  19. * credits must appear in the documentation.
  20. *
  21. * 3. Altered versions must be plainly marked as such, and must not be
  22. * misrepresented as being the original software. Since few users
  23. * ever read sources, credits must appear in the documentation.
  24. *
  25. * 4. This notice may not be removed or altered.
  26. */
  27. #include "file.h"
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <ctype.h>
  31. #include <stdlib.h>
  32. #include <time.h>
  33. #include <sys/types.h>
  34. #include "file.h"
  35. #ifndef lint
  36. FILE_RCSID("@(#)$Id: softmagic.c,v 1.46 2001/07/23 00:02:32 christos Exp $")
  37. #endif /* lint */
  38. static int match __P((struct magic *, uint32, unsigned char *, int));
  39. static int mget __P((union VALUETYPE *,
  40. unsigned char *, struct magic *, int));
  41. static int mcheck __P((union VALUETYPE *, struct magic *));
  42. static int32 mprint __P((union VALUETYPE *, struct magic *));
  43. static void mdebug __P((int32, char *, int));
  44. static int mconvert __P((union VALUETYPE *, struct magic *));
  45. extern int kflag;
  46. /*
  47. * softmagic - lookup one file in database
  48. * (already read from /etc/magic by apprentice.c).
  49. * Passed the name and FILE * of one file to be typed.
  50. */
  51. /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
  52. int
  53. softmagic(buf, nbytes)
  54. unsigned char *buf;
  55. int nbytes;
  56. {
  57. struct mlist *ml;
  58. for (ml = mlist.next; ml != &mlist; ml = ml->next)
  59. if (match(ml->magic, ml->nmagic, buf, nbytes))
  60. return 1;
  61. return 0;
  62. }
  63. /*
  64. * Go through the whole list, stopping if you find a match. Process all
  65. * the continuations of that match before returning.
  66. *
  67. * We support multi-level continuations:
  68. *
  69. * At any time when processing a successful top-level match, there is a
  70. * current continuation level; it represents the level of the last
  71. * successfully matched continuation.
  72. *
  73. * Continuations above that level are skipped as, if we see one, it
  74. * means that the continuation that controls them - i.e, the
  75. * lower-level continuation preceding them - failed to match.
  76. *
  77. * Continuations below that level are processed as, if we see one,
  78. * it means we've finished processing or skipping higher-level
  79. * continuations under the control of a successful or unsuccessful
  80. * lower-level continuation, and are now seeing the next lower-level
  81. * continuation and should process it. The current continuation
  82. * level reverts to the level of the one we're seeing.
  83. *
  84. * Continuations at the current level are processed as, if we see
  85. * one, there's no lower-level continuation that may have failed.
  86. *
  87. * If a continuation matches, we bump the current continuation level
  88. * so that higher-level continuations are processed.
  89. */
  90. static int
  91. match(magic, nmagic, s, nbytes)
  92. struct magic *magic;
  93. uint32 nmagic;
  94. unsigned char *s;
  95. int nbytes;
  96. {
  97. int magindex = 0;
  98. int cont_level = 0;
  99. int need_separator = 0;
  100. union VALUETYPE p;
  101. static int32 *tmpoff = NULL;
  102. static size_t tmplen = 0;
  103. int32 oldoff = 0;
  104. int returnval = 0; /* if a match is found it is set to 1*/
  105. int firstline = 1; /* a flag to print X\n X\n- X */
  106. if (tmpoff == NULL)
  107. if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
  108. error("out of memory\n");
  109. for (magindex = 0; magindex < nmagic; magindex++) {
  110. /* if main entry matches, print it... */
  111. if (!mget(&p, s, &magic[magindex], nbytes) ||
  112. !mcheck(&p, &magic[magindex])) {
  113. /*
  114. * main entry didn't match,
  115. * flush its continuations
  116. */
  117. while (magindex < nmagic &&
  118. magic[magindex + 1].cont_level != 0)
  119. magindex++;
  120. continue;
  121. }
  122. if (! firstline) { /* we found another match */
  123. /* put a newline and '-' to do some simple formatting*/
  124. printf("\n- ");
  125. }
  126. tmpoff[cont_level] = mprint(&p, &magic[magindex]);
  127. /*
  128. * If we printed something, we'll need to print
  129. * a blank before we print something else.
  130. */
  131. if (magic[magindex].desc[0])
  132. need_separator = 1;
  133. /* and any continuations that match */
  134. if (++cont_level >= tmplen)
  135. if ((tmpoff = (int32 *) realloc(tmpoff,
  136. tmplen += 20)) == NULL)
  137. error("out of memory\n");
  138. while (magic[magindex+1].cont_level != 0 &&
  139. ++magindex < nmagic) {
  140. if (cont_level >= magic[magindex].cont_level) {
  141. if (cont_level > magic[magindex].cont_level) {
  142. /*
  143. * We're at the end of the level
  144. * "cont_level" continuations.
  145. */
  146. cont_level = magic[magindex].cont_level;
  147. }
  148. if (magic[magindex].flag & OFFADD) {
  149. oldoff=magic[magindex].offset;
  150. magic[magindex].offset +=
  151. tmpoff[cont_level-1];
  152. }
  153. if (mget(&p, s, &magic[magindex], nbytes) &&
  154. mcheck(&p, &magic[magindex])) {
  155. /*
  156. * This continuation matched.
  157. * Print its message, with
  158. * a blank before it if
  159. * the previous item printed
  160. * and this item isn't empty.
  161. */
  162. /* space if previous printed */
  163. if (need_separator
  164. && (magic[magindex].nospflag == 0)
  165. && (magic[magindex].desc[0] != '\0')
  166. ) {
  167. (void) putchar(' ');
  168. need_separator = 0;
  169. }
  170. tmpoff[cont_level] =
  171. mprint(&p, &magic[magindex]);
  172. if (magic[magindex].desc[0])
  173. need_separator = 1;
  174. /*
  175. * If we see any continuations
  176. * at a higher level,
  177. * process them.
  178. */
  179. if (++cont_level >= tmplen)
  180. if ((tmpoff =
  181. (int32 *) realloc(tmpoff,
  182. tmplen += 20)) == NULL)
  183. error("out of memory\n");
  184. }
  185. if (magic[magindex].flag & OFFADD) {
  186. magic[magindex].offset = oldoff;
  187. }
  188. }
  189. }
  190. firstline = 0;
  191. returnval = 1;
  192. if (!kflag) {
  193. return 1; /* don't keep searching */
  194. }
  195. }
  196. return returnval; /* This is hit if -k is set or there is no match */
  197. }
  198. static int32
  199. mprint(p, m)
  200. union VALUETYPE *p;
  201. struct magic *m;
  202. {
  203. uint32 v;
  204. int32 t=0 ;
  205. switch (m->type) {
  206. case BYTE:
  207. v = signextend(m, p->b);
  208. (void) printf(m->desc, (unsigned char) v);
  209. t = m->offset + sizeof(char);
  210. break;
  211. case SHORT:
  212. case BESHORT:
  213. case LESHORT:
  214. v = signextend(m, p->h);
  215. (void) printf(m->desc, (unsigned short) v);
  216. t = m->offset + sizeof(short);
  217. break;
  218. case LONG:
  219. case BELONG:
  220. case LELONG:
  221. v = signextend(m, p->l);
  222. (void) printf(m->desc, (uint32) v);
  223. t = m->offset + sizeof(int32);
  224. break;
  225. case STRING:
  226. case PSTRING:
  227. if (m->reln == '=') {
  228. (void) printf(m->desc, m->value.s);
  229. t = m->offset + strlen(m->value.s);
  230. }
  231. else {
  232. char *cp = strchr(p->s,'\n');
  233. if (cp)
  234. *cp = '\0';
  235. (void) printf(m->desc, p->s);
  236. t = m->offset + strlen(p->s);
  237. }
  238. break;
  239. case DATE:
  240. case BEDATE:
  241. case LEDATE:
  242. (void) printf(m->desc, fmttime(p->l, 1));
  243. t = m->offset + sizeof(time_t);
  244. break;
  245. case LDATE:
  246. case BELDATE:
  247. case LELDATE:
  248. (void) printf(m->desc, fmttime(p->l, 0));
  249. t = m->offset + sizeof(time_t);
  250. break;
  251. default:
  252. error("invalid m->type (%d) in mprint().\n", m->type);
  253. /*NOTREACHED*/
  254. }
  255. return(t);
  256. }
  257. /*
  258. * Convert the byte order of the data we are looking at
  259. * While we're here, let's apply the mask operation
  260. * (unless you have a better idea)
  261. */
  262. static int
  263. mconvert(p, m)
  264. union VALUETYPE *p;
  265. struct magic *m;
  266. {
  267. switch (m->type) {
  268. case BYTE:
  269. if (m->mask)
  270. switch (m->mask_op&0x7F) {
  271. case OPAND:
  272. p->b &= m->mask;
  273. break;
  274. case OPOR:
  275. p->b |= m->mask;
  276. break;
  277. case OPXOR:
  278. p->b ^= m->mask;
  279. break;
  280. case OPADD:
  281. p->b += m->mask;
  282. break;
  283. case OPMINUS:
  284. p->b -= m->mask;
  285. break;
  286. case OPMULTIPLY:
  287. p->b *= m->mask;
  288. break;
  289. case OPDIVIDE:
  290. p->b /= m->mask;
  291. break;
  292. case OPMODULO:
  293. p->b %= m->mask;
  294. break;
  295. }
  296. if (m->mask_op & OPINVERSE)
  297. p->b = ~p->b;
  298. return 1;
  299. case SHORT:
  300. if (m->mask)
  301. switch (m->mask_op&0x7F) {
  302. case OPAND:
  303. p->h &= m->mask;
  304. break;
  305. case OPOR:
  306. p->h |= m->mask;
  307. break;
  308. case OPXOR:
  309. p->h ^= m->mask;
  310. break;
  311. case OPADD:
  312. p->h += m->mask;
  313. break;
  314. case OPMINUS:
  315. p->h -= m->mask;
  316. break;
  317. case OPMULTIPLY:
  318. p->h *= m->mask;
  319. break;
  320. case OPDIVIDE:
  321. p->h /= m->mask;
  322. break;
  323. case OPMODULO:
  324. p->h %= m->mask;
  325. break;
  326. }
  327. if (m->mask_op & OPINVERSE)
  328. p->h = ~p->h;
  329. return 1;
  330. case LONG:
  331. case DATE:
  332. case LDATE:
  333. if (m->mask)
  334. switch (m->mask_op&0x7F) {
  335. case OPAND:
  336. p->l &= m->mask;
  337. break;
  338. case OPOR:
  339. p->l |= m->mask;
  340. break;
  341. case OPXOR:
  342. p->l ^= m->mask;
  343. break;
  344. case OPADD:
  345. p->l += m->mask;
  346. break;
  347. case OPMINUS:
  348. p->l -= m->mask;
  349. break;
  350. case OPMULTIPLY:
  351. p->l *= m->mask;
  352. break;
  353. case OPDIVIDE:
  354. p->l /= m->mask;
  355. break;
  356. case OPMODULO:
  357. p->l %= m->mask;
  358. break;
  359. }
  360. if (m->mask_op & OPINVERSE)
  361. p->l = ~p->l;
  362. return 1;
  363. case STRING:
  364. {
  365. int n;
  366. /* Null terminate and eat *trailing* return */
  367. p->s[sizeof(p->s) - 1] = '\0';
  368. n = strlen(p->s) - 1;
  369. if (p->s[n] == '\n')
  370. p->s[n] = '\0';
  371. return 1;
  372. }
  373. case PSTRING:
  374. {
  375. char *ptr1 = p->s, *ptr2 = ptr1 + 1;
  376. int n = *p->s;
  377. if (n >= sizeof(p->s))
  378. n = sizeof(p->s) - 1;
  379. while (n--)
  380. *ptr1++ = *ptr2++;
  381. *ptr1 = '\0';
  382. n = strlen(p->s) - 1;
  383. if (p->s[n] == '\n')
  384. p->s[n] = '\0';
  385. return 1;
  386. }
  387. case BESHORT:
  388. p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
  389. if (m->mask)
  390. switch (m->mask_op&0x7F) {
  391. case OPAND:
  392. p->h &= m->mask;
  393. break;
  394. case OPOR:
  395. p->h |= m->mask;
  396. break;
  397. case OPXOR:
  398. p->h ^= m->mask;
  399. break;
  400. case OPADD:
  401. p->h += m->mask;
  402. break;
  403. case OPMINUS:
  404. p->h -= m->mask;
  405. break;
  406. case OPMULTIPLY:
  407. p->h *= m->mask;
  408. break;
  409. case OPDIVIDE:
  410. p->h /= m->mask;
  411. break;
  412. case OPMODULO:
  413. p->h %= m->mask;
  414. break;
  415. }
  416. if (m->mask_op & OPINVERSE)
  417. p->h = ~p->h;
  418. return 1;
  419. case BELONG:
  420. case BEDATE:
  421. case BELDATE:
  422. p->l = (int32)
  423. ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
  424. if (m->mask)
  425. switch (m->mask_op&0x7F) {
  426. case OPAND:
  427. p->l &= m->mask;
  428. break;
  429. case OPOR:
  430. p->l |= m->mask;
  431. break;
  432. case OPXOR:
  433. p->l ^= m->mask;
  434. break;
  435. case OPADD:
  436. p->l += m->mask;
  437. break;
  438. case OPMINUS:
  439. p->l -= m->mask;
  440. break;
  441. case OPMULTIPLY:
  442. p->l *= m->mask;
  443. break;
  444. case OPDIVIDE:
  445. p->l /= m->mask;
  446. break;
  447. case OPMODULO:
  448. p->l %= m->mask;
  449. break;
  450. }
  451. if (m->mask_op & OPINVERSE)
  452. p->l = ~p->l;
  453. return 1;
  454. case LESHORT:
  455. p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
  456. if (m->mask)
  457. switch (m->mask_op&0x7F) {
  458. case OPAND:
  459. p->h &= m->mask;
  460. break;
  461. case OPOR:
  462. p->h |= m->mask;
  463. break;
  464. case OPXOR:
  465. p->h ^= m->mask;
  466. break;
  467. case OPADD:
  468. p->h += m->mask;
  469. break;
  470. case OPMINUS:
  471. p->h -= m->mask;
  472. break;
  473. case OPMULTIPLY:
  474. p->h *= m->mask;
  475. break;
  476. case OPDIVIDE:
  477. p->h /= m->mask;
  478. break;
  479. case OPMODULO:
  480. p->h %= m->mask;
  481. break;
  482. }
  483. if (m->mask_op & OPINVERSE)
  484. p->h = ~p->h;
  485. return 1;
  486. case LELONG:
  487. case LEDATE:
  488. case LELDATE:
  489. p->l = (int32)
  490. ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
  491. if (m->mask)
  492. switch (m->mask_op&0x7F) {
  493. case OPAND:
  494. p->l &= m->mask;
  495. break;
  496. case OPOR:
  497. p->l |= m->mask;
  498. break;
  499. case OPXOR:
  500. p->l ^= m->mask;
  501. break;
  502. case OPADD:
  503. p->l += m->mask;
  504. break;
  505. case OPMINUS:
  506. p->l -= m->mask;
  507. break;
  508. case OPMULTIPLY:
  509. p->l *= m->mask;
  510. break;
  511. case OPDIVIDE:
  512. p->l /= m->mask;
  513. break;
  514. case OPMODULO:
  515. p->l %= m->mask;
  516. break;
  517. }
  518. if (m->mask_op & OPINVERSE)
  519. p->l = ~p->l;
  520. return 1;
  521. default:
  522. error("invalid type %d in mconvert().\n", m->type);
  523. return 0;
  524. }
  525. }
  526. static void
  527. mdebug(offset, str, len)
  528. int32 offset;
  529. char *str;
  530. int len;
  531. {
  532. (void) fprintf(stderr, "mget @%d: ", offset);
  533. showstr(stderr, (char *) str, len);
  534. (void) fputc('\n', stderr);
  535. (void) fputc('\n', stderr);
  536. }
  537. static int
  538. mget(p, s, m, nbytes)
  539. union VALUETYPE* p;
  540. unsigned char *s;
  541. struct magic *m;
  542. int nbytes;
  543. {
  544. int32 offset = m->offset;
  545. if (offset + sizeof(union VALUETYPE) <= nbytes)
  546. memcpy(p, s + offset, sizeof(union VALUETYPE));
  547. else {
  548. /*
  549. * the usefulness of padding with zeroes eludes me, it
  550. * might even cause problems
  551. */
  552. int32 have = nbytes - offset;
  553. memset(p, 0, sizeof(union VALUETYPE));
  554. if (have > 0)
  555. memcpy(p, s + offset, have);
  556. }
  557. if (debug) {
  558. mdebug(offset, (char *) p, sizeof(union VALUETYPE));
  559. mdump(m);
  560. }
  561. if (m->flag & INDIR) {
  562. switch (m->in_type) {
  563. case BYTE:
  564. if (m->in_offset)
  565. switch (m->in_op&0x7F) {
  566. case OPAND:
  567. offset = p->b & m->in_offset;
  568. break;
  569. case OPOR:
  570. offset = p->b | m->in_offset;
  571. break;
  572. case OPXOR:
  573. offset = p->b ^ m->in_offset;
  574. break;
  575. case OPADD:
  576. offset = p->b + m->in_offset;
  577. break;
  578. case OPMINUS:
  579. offset = p->b - m->in_offset;
  580. break;
  581. case OPMULTIPLY:
  582. offset = p->b * m->in_offset;
  583. break;
  584. case OPDIVIDE:
  585. offset = p->b / m->in_offset;
  586. break;
  587. case OPMODULO:
  588. offset = p->b % m->in_offset;
  589. break;
  590. }
  591. if (m->in_op & OPINVERSE)
  592. offset = ~offset;
  593. break;
  594. case BESHORT:
  595. if (m->in_offset)
  596. switch (m->in_op&0x7F) {
  597. case OPAND:
  598. offset = (short)((p->hs[0]<<8)|
  599. (p->hs[1])) &
  600. m->in_offset;
  601. break;
  602. case OPOR:
  603. offset = (short)((p->hs[0]<<8)|
  604. (p->hs[1])) |
  605. m->in_offset;
  606. break;
  607. case OPXOR:
  608. offset = (short)((p->hs[0]<<8)|
  609. (p->hs[1])) ^
  610. m->in_offset;
  611. break;
  612. case OPADD:
  613. offset = (short)((p->hs[0]<<8)|
  614. (p->hs[1])) +
  615. m->in_offset;
  616. break;
  617. case OPMINUS:
  618. offset = (short)((p->hs[0]<<8)|
  619. (p->hs[1])) -
  620. m->in_offset;
  621. break;
  622. case OPMULTIPLY:
  623. offset = (short)((p->hs[0]<<8)|
  624. (p->hs[1])) *
  625. m->in_offset;
  626. break;
  627. case OPDIVIDE:
  628. offset = (short)((p->hs[0]<<8)|
  629. (p->hs[1])) /
  630. m->in_offset;
  631. break;
  632. case OPMODULO:
  633. offset = (short)((p->hs[0]<<8)|
  634. (p->hs[1])) %
  635. m->in_offset;
  636. break;
  637. }
  638. if (m->in_op & OPINVERSE)
  639. offset = ~offset;
  640. break;
  641. case LESHORT:
  642. if (m->in_offset)
  643. switch (m->in_op&0x7F) {
  644. case OPAND:
  645. offset = (short)((p->hs[1]<<8)|
  646. (p->hs[0])) &
  647. m->in_offset;
  648. break;
  649. case OPOR:
  650. offset = (short)((p->hs[1]<<8)|
  651. (p->hs[0])) |
  652. m->in_offset;
  653. break;
  654. case OPXOR:
  655. offset = (short)((p->hs[1]<<8)|
  656. (p->hs[0])) ^
  657. m->in_offset;
  658. break;
  659. case OPADD:
  660. offset = (short)((p->hs[1]<<8)|
  661. (p->hs[0])) +
  662. m->in_offset;
  663. break;
  664. case OPMINUS:
  665. offset = (short)((p->hs[1]<<8)|
  666. (p->hs[0])) -
  667. m->in_offset;
  668. break;
  669. case OPMULTIPLY:
  670. offset = (short)((p->hs[1]<<8)|
  671. (p->hs[0])) *
  672. m->in_offset;
  673. break;
  674. case OPDIVIDE:
  675. offset = (short)((p->hs[1]<<8)|
  676. (p->hs[0])) /
  677. m->in_offset;
  678. break;
  679. case OPMODULO:
  680. offset = (short)((p->hs[1]<<8)|
  681. (p->hs[0])) %
  682. m->in_offset;
  683. break;
  684. }
  685. if (m->in_op & OPINVERSE)
  686. offset = ~offset;
  687. break;
  688. case SHORT:
  689. if (m->in_offset)
  690. switch (m->in_op&0x7F) {
  691. case OPAND:
  692. offset = p->h & m->in_offset;
  693. break;
  694. case OPOR:
  695. offset = p->h | m->in_offset;
  696. break;
  697. case OPXOR:
  698. offset = p->h ^ m->in_offset;
  699. break;
  700. case OPADD:
  701. offset = p->h + m->in_offset;
  702. break;
  703. case OPMINUS:
  704. offset = p->h - m->in_offset;
  705. break;
  706. case OPMULTIPLY:
  707. offset = p->h * m->in_offset;
  708. break;
  709. case OPDIVIDE:
  710. offset = p->h / m->in_offset;
  711. break;
  712. case OPMODULO:
  713. offset = p->h % m->in_offset;
  714. break;
  715. }
  716. if (m->in_op & OPINVERSE)
  717. offset = ~offset;
  718. break;
  719. case BELONG:
  720. if (m->in_offset)
  721. switch (m->in_op&0x7F) {
  722. case OPAND:
  723. offset = (int32)((p->hl[0]<<24)|
  724. (p->hl[1]<<16)|
  725. (p->hl[2]<<8)|
  726. (p->hl[3])) &
  727. m->in_offset;
  728. break;
  729. case OPOR:
  730. offset = (int32)((p->hl[0]<<24)|
  731. (p->hl[1]<<16)|
  732. (p->hl[2]<<8)|
  733. (p->hl[3])) |
  734. m->in_offset;
  735. break;
  736. case OPXOR:
  737. offset = (int32)((p->hl[0]<<24)|
  738. (p->hl[1]<<16)|
  739. (p->hl[2]<<8)|
  740. (p->hl[3])) ^
  741. m->in_offset;
  742. break;
  743. case OPADD:
  744. offset = (int32)((p->hl[0]<<24)|
  745. (p->hl[1]<<16)|
  746. (p->hl[2]<<8)|
  747. (p->hl[3])) +
  748. m->in_offset;
  749. break;
  750. case OPMINUS:
  751. offset = (int32)((p->hl[0]<<24)|
  752. (p->hl[1]<<16)|
  753. (p->hl[2]<<8)|
  754. (p->hl[3])) -
  755. m->in_offset;
  756. break;
  757. case OPMULTIPLY:
  758. offset = (int32)((p->hl[0]<<24)|
  759. (p->hl[1]<<16)|
  760. (p->hl[2]<<8)|
  761. (p->hl[3])) *
  762. m->in_offset;
  763. break;
  764. case OPDIVIDE:
  765. offset = (int32)((p->hl[0]<<24)|
  766. (p->hl[1]<<16)|
  767. (p->hl[2]<<8)|
  768. (p->hl[3])) /
  769. m->in_offset;
  770. break;
  771. case OPMODULO:
  772. offset = (int32)((p->hl[0]<<24)|
  773. (p->hl[1]<<16)|
  774. (p->hl[2]<<8)|
  775. (p->hl[3])) %
  776. m->in_offset;
  777. break;
  778. }
  779. if (m->in_op & OPINVERSE)
  780. offset = ~offset;
  781. break;
  782. case LELONG:
  783. if (m->in_offset)
  784. switch (m->in_op&0x7F) {
  785. case OPAND:
  786. offset = (int32)((p->hl[3]<<24)|
  787. (p->hl[2]<<16)|
  788. (p->hl[1]<<8)|
  789. (p->hl[0])) &
  790. m->in_offset;
  791. break;
  792. case OPOR:
  793. offset = (int32)((p->hl[3]<<24)|
  794. (p->hl[2]<<16)|
  795. (p->hl[1]<<8)|
  796. (p->hl[0])) |
  797. m->in_offset;
  798. break;
  799. case OPXOR:
  800. offset = (int32)((p->hl[3]<<24)|
  801. (p->hl[2]<<16)|
  802. (p->hl[1]<<8)|
  803. (p->hl[0])) ^
  804. m->in_offset;
  805. break;
  806. case OPADD:
  807. offset = (int32)((p->hl[3]<<24)|
  808. (p->hl[2]<<16)|
  809. (p->hl[1]<<8)|
  810. (p->hl[0])) +
  811. m->in_offset;
  812. break;
  813. case OPMINUS:
  814. offset = (int32)((p->hl[3]<<24)|
  815. (p->hl[2]<<16)|
  816. (p->hl[1]<<8)|
  817. (p->hl[0])) -
  818. m->in_offset;
  819. break;
  820. case OPMULTIPLY:
  821. offset = (int32)((p->hl[3]<<24)|
  822. (p->hl[2]<<16)|
  823. (p->hl[1]<<8)|
  824. (p->hl[0])) *
  825. m->in_offset;
  826. break;
  827. case OPDIVIDE:
  828. offset = (int32)((p->hl[3]<<24)|
  829. (p->hl[2]<<16)|
  830. (p->hl[1]<<8)|
  831. (p->hl[0])) /
  832. m->in_offset;
  833. break;
  834. case OPMODULO:
  835. offset = (int32)((p->hl[3]<<24)|
  836. (p->hl[2]<<16)|
  837. (p->hl[1]<<8)|
  838. (p->hl[0])) %
  839. m->in_offset;
  840. break;
  841. }
  842. if (m->in_op & OPINVERSE)
  843. offset = ~offset;
  844. break;
  845. case LONG:
  846. if (m->in_offset)
  847. switch (m->in_op&0x7F) {
  848. case OPAND:
  849. offset = p->l & m->in_offset;
  850. break;
  851. case OPOR:
  852. offset = p->l | m->in_offset;
  853. break;
  854. case OPXOR:
  855. offset = p->l ^ m->in_offset;
  856. break;
  857. case OPADD:
  858. offset = p->l + m->in_offset;
  859. break;
  860. case OPMINUS:
  861. offset = p->l - m->in_offset;
  862. break;
  863. case OPMULTIPLY:
  864. offset = p->l * m->in_offset;
  865. break;
  866. case OPDIVIDE:
  867. offset = p->l / m->in_offset;
  868. break;
  869. case OPMODULO:
  870. offset = p->l % m->in_offset;
  871. break;
  872. /* case TOOMANYSWITCHBLOCKS:
  873. * ugh = p->eye % m->strain;
  874. * rub;
  875. * case BEER:
  876. * off = p->tab & m->in_gest;
  877. * sleep;
  878. */
  879. }
  880. if (m->in_op & OPINVERSE)
  881. offset = ~offset;
  882. break;
  883. }
  884. if (offset + sizeof(union VALUETYPE) > nbytes)
  885. return 0;
  886. memcpy(p, s + offset, sizeof(union VALUETYPE));
  887. if (debug) {
  888. mdebug(offset, (char *) p, sizeof(union VALUETYPE));
  889. mdump(m);
  890. }
  891. }
  892. if (!mconvert(p, m))
  893. return 0;
  894. return 1;
  895. }
  896. static int
  897. mcheck(p, m)
  898. union VALUETYPE* p;
  899. struct magic *m;
  900. {
  901. uint32 l = m->value.l;
  902. uint32 v;
  903. int matched;
  904. if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
  905. fprintf(stderr, "BOINK");
  906. return 1;
  907. }
  908. switch (m->type) {
  909. case BYTE:
  910. v = p->b;
  911. break;
  912. case SHORT:
  913. case BESHORT:
  914. case LESHORT:
  915. v = p->h;
  916. break;
  917. case LONG:
  918. case BELONG:
  919. case LELONG:
  920. case DATE:
  921. case BEDATE:
  922. case LEDATE:
  923. case LDATE:
  924. case BELDATE:
  925. case LELDATE:
  926. v = p->l;
  927. break;
  928. case STRING:
  929. case PSTRING:
  930. {
  931. /*
  932. * What we want here is:
  933. * v = strncmp(m->value.s, p->s, m->vallen);
  934. * but ignoring any nulls. bcmp doesn't give -/+/0
  935. * and isn't universally available anyway.
  936. */
  937. unsigned char *a = (unsigned char*)m->value.s;
  938. unsigned char *b = (unsigned char*)p->s;
  939. int len = m->vallen;
  940. l = 0;
  941. v = 0;
  942. if (0L == m->mask) { /* normal string: do it fast */
  943. while (--len >= 0)
  944. if ((v = *b++ - *a++) != '\0')
  945. break;
  946. } else { /* combine the others */
  947. while (--len >= 0) {
  948. if ((m->mask & STRING_IGNORE_LOWERCASE) &&
  949. islower(*a)) {
  950. if ((v = tolower(*b++) - *a++) != '\0')
  951. break;
  952. } else if ((m->mask & STRING_COMPACT_BLANK) &&
  953. isspace(*a)) {
  954. a++;
  955. if (isspace(*b++)) {
  956. while (isspace(*b))
  957. b++;
  958. } else {
  959. v = 1;
  960. break;
  961. }
  962. } else if (isspace(*a) &&
  963. (m->mask & STRING_COMPACT_OPTIONAL_BLANK)) {
  964. a++;
  965. while (isspace(*b))
  966. b++;
  967. } else {
  968. if ((v = *b++ - *a++) != '\0')
  969. break;
  970. }
  971. }
  972. }
  973. break;
  974. }
  975. default:
  976. error("invalid type %d in mcheck().\n", m->type);
  977. return 0;/*NOTREACHED*/
  978. }
  979. if(m->type != STRING && m->type != PSTRING)
  980. v = signextend(m, v);
  981. switch (m->reln) {
  982. case 'x':
  983. if (debug)
  984. (void) fprintf(stderr, "%u == *any* = 1\n", v);
  985. matched = 1;
  986. break;
  987. case '!':
  988. matched = v != l;
  989. if (debug)
  990. (void) fprintf(stderr, "%u != %u = %d\n",
  991. v, l, matched);
  992. break;
  993. case '=':
  994. matched = v == l;
  995. if (debug)
  996. (void) fprintf(stderr, "%u == %u = %d\n",
  997. v, l, matched);
  998. break;
  999. case '>':
  1000. if (m->flag & UNSIGNED) {
  1001. matched = v > l;
  1002. if (debug)
  1003. (void) fprintf(stderr, "%u > %u = %d\n",
  1004. v, l, matched);
  1005. }
  1006. else {
  1007. matched = (int32) v > (int32) l;
  1008. if (debug)
  1009. (void) fprintf(stderr, "%d > %d = %d\n",
  1010. v, l, matched);
  1011. }
  1012. break;
  1013. case '<':
  1014. if (m->flag & UNSIGNED) {
  1015. matched = v < l;
  1016. if (debug)
  1017. (void) fprintf(stderr, "%u < %u = %d\n",
  1018. v, l, matched);
  1019. }
  1020. else {
  1021. matched = (int32) v < (int32) l;
  1022. if (debug)
  1023. (void) fprintf(stderr, "%d < %d = %d\n",
  1024. v, l, matched);
  1025. }
  1026. break;
  1027. case '&':
  1028. matched = (v & l) == l;
  1029. if (debug)
  1030. (void) fprintf(stderr, "((%x & %x) == %x) = %d\n",
  1031. v, l, l, matched);
  1032. break;
  1033. case '^':
  1034. matched = (v & l) != l;
  1035. if (debug)
  1036. (void) fprintf(stderr, "((%x & %x) != %x) = %d\n",
  1037. v, l, l, matched);
  1038. break;
  1039. default:
  1040. matched = 0;
  1041. error("mcheck: can't happen: invalid relation %d.\n", m->reln);
  1042. break;/*NOTREACHED*/
  1043. }
  1044. return matched;
  1045. }