|
|
1.1 ! root 1: /* picksbr.c - routines to help pick along... */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include "../zotnet/tws.h" ! 5: #include <stdio.h> ! 6: ! 7: /* */ ! 8: ! 9: static struct swit parswit[] = { ! 10: #define PRAND 0 ! 11: "and", 0, ! 12: #define PROR 1 ! 13: "or", 0, ! 14: #define PRNOT 2 ! 15: "not", 0, ! 16: #define PRLBR 3 ! 17: "lbrace", 0, ! 18: #define PRRBR 4 ! 19: "rbrace", 0, ! 20: ! 21: #define PRCC 5 ! 22: "cc pattern", 0, ! 23: #define PRDATE 6 ! 24: "date pattern", 0, ! 25: #define PRFROM 7 ! 26: "from pattern", 0, ! 27: #define PRSRCH 8 ! 28: "search pattern", 0, ! 29: #define PRSUBJ 9 ! 30: "subject pattern", 0, ! 31: #define PRTO 10 ! 32: "to pattern", 0, ! 33: #define PROTHR 11 ! 34: "-othercomponent pattern", 15, ! 35: ! 36: #define PRAFTR 12 ! 37: "after date", 0, ! 38: #define PRBEFR 13 ! 39: "before date", 0, ! 40: #define PRDATF 14 ! 41: "datefield field", 5, ! 42: ! 43: NULL, NULL ! 44: }; ! 45: ! 46: /* DEFINITIONS FOR PATTERN MATCHING */ ! 47: ! 48: /* We really should be using re_comp() and re_exec() here. Unfortunately, ! 49: pick advertises that lowercase characters matches characters of both ! 50: cases. Since re_exec() doesn't exhibit this behavior, we are stuck ! 51: with this version. Furthermore, we need to be able to save and restore ! 52: the state of the pattern matcher in order to do things "efficiently". ! 53: ! 54: The matching power of this algorithm isn't as powerful as the re_xxx() ! 55: routines (no \(xxx\) and \n constructs). Such is life. ! 56: */ ! 57: ! 58: ! 59: #define CCHR 2 ! 60: #define CDOT 4 ! 61: #define CCL 6 ! 62: #define NCCL 8 ! 63: #define CDOL 10 ! 64: #define CEOF 11 ! 65: ! 66: #define STAR 01 ! 67: ! 68: #define LBSIZE 1024 ! 69: #define ESIZE 256 ! 70: ! 71: ! 72: static char linebuf[LBSIZE + 1]; ! 73: ! 74: static char cc[] = { /* the magic array for case-independence */ ! 75: 0000,0001,0002,0003,0004,0005,0006,0007, ! 76: 0010,0011,0012,0013,0014,0015,0016,0017, ! 77: 0020,0021,0022,0023,0024,0025,0026,0027, ! 78: 0030,0031,0032,0033,0034,0035,0036,0037, ! 79: 0040,0041,0042,0043,0044,0045,0046,0047, ! 80: 0050,0051,0052,0053,0054,0055,0056,0057, ! 81: 0060,0061,0062,0063,0064,0065,0066,0067, ! 82: 0070,0071,0072,0073,0074,0075,0076,0077, ! 83: 0100,0141,0142,0143,0144,0145,0146,0147, ! 84: 0150,0151,0152,0153,0154,0155,0156,0157, ! 85: 0160,0161,0162,0163,0164,0165,0166,0167, ! 86: 0170,0171,0172,0133,0134,0135,0136,0137, ! 87: 0140,0141,0142,0143,0144,0145,0146,0147, ! 88: 0150,0151,0152,0153,0154,0155,0156,0157, ! 89: 0160,0161,0162,0163,0164,0165,0166,0167, ! 90: 0170,0171,0172,0173,0174,0175,0176,0177, ! 91: }; ! 92: ! 93: /* DEFINITIONS FOR DATE MATCHING */ ! 94: ! 95: struct tws *tws_parse (), *tws_special (); ! 96: ! 97: ! 98: long time (); ! 99: ! 100: /* DEFINITIONS FOR NEXUS */ ! 101: ! 102: #define nxtarg() (*argp ? *argp++ : NULL) ! 103: #define prvarg() argp-- ! 104: ! 105: ! 106: #define padvise if (!talked++) advise ! 107: ! 108: ! 109: struct nexus { ! 110: int (*n_action) (); ! 111: ! 112: union { ! 113: struct { /* for {OR,AND,NOT}action */ ! 114: struct nexus *un_L_child; ! 115: struct nexus *un_R_child; ! 116: } st1; ! 117: #define n_L_child un.st1.un_L_child ! 118: #define n_R_child un.st1.un_R_child ! 119: ! 120: struct { /* for GREPaction */ ! 121: int un_header; ! 122: int un_circf; ! 123: char un_expbuf[ESIZE]; ! 124: char *un_patbuf; ! 125: } st2; ! 126: #define n_header un.st2.un_header ! 127: #define n_circf un.st2.un_circf ! 128: #define n_expbuf un.st2.un_expbuf ! 129: #define n_patbuf un.st2.un_patbuf ! 130: ! 131: struct { /* for TWSaction */ ! 132: char *un_datef; ! 133: int un_after; ! 134: struct tws un_tws; ! 135: } st3; ! 136: #define n_datef un.st3.un_datef ! 137: #define n_after un.st3.un_after ! 138: #define n_tws un.st3.un_tws ! 139: ! 140: } un; ! 141: }; ! 142: ! 143: static int talked; ! 144: static int pdebug = 0; ! 145: ! 146: static char *datesw; ! 147: static char **argp; ! 148: ! 149: static struct nexus *head; ! 150: ! 151: ! 152: struct nexus *parse (), *exp1 (), *exp2 (), *exp3 (), *newnexus (); ! 153: ! 154: int ORaction (), ANDaction (), NOTaction (), GREPaction (), TWSaction (); ! 155: ! 156: /* */ ! 157: ! 158: int pcompile (vec, date) ! 159: register char **vec, ! 160: *date; ! 161: { ! 162: register char *cp; ! 163: ! 164: if ((cp = getenv ("MHPDEBUG")) && *cp) ! 165: pdebug++; ! 166: ! 167: argp = vec; ! 168: if ((datesw = date) == NULL) ! 169: datesw = "date"; ! 170: talked = 0; ! 171: ! 172: if ((head = parse ()) == NULL) ! 173: return (talked ? 0 : 1); ! 174: ! 175: if (*argp) { ! 176: padvise (NULLCP, "%s unexpected", *argp); ! 177: return 0; ! 178: } ! 179: ! 180: return 1; ! 181: } ! 182: ! 183: /* */ ! 184: ! 185: static struct nexus *parse () { ! 186: register char *cp; ! 187: register struct nexus *n, ! 188: *o; ! 189: ! 190: if ((n = exp1 ()) == NULL || (cp = nxtarg ()) == NULL) ! 191: return n; ! 192: ! 193: if (*cp != '-') { ! 194: padvise (NULLCP, "%s unexpected", cp); ! 195: return NULL; ! 196: } ! 197: ! 198: if (*++cp == '-') ! 199: goto header; ! 200: switch (smatch (cp, parswit)) { ! 201: case AMBIGSW: ! 202: ambigsw (cp, parswit); ! 203: talked++; ! 204: return NULL; ! 205: case UNKWNSW: ! 206: fprintf (stderr, "-%s unknown\n", cp); ! 207: talked++; ! 208: return NULL; ! 209: ! 210: case PROR: ! 211: o = newnexus (ORaction); ! 212: o -> n_L_child = n; ! 213: if (o -> n_R_child = parse ()) ! 214: return o; ! 215: padvise (NULLCP, "missing disjunctive"); ! 216: return NULL; ! 217: ! 218: header: ; ! 219: default: ! 220: prvarg (); ! 221: return n; ! 222: } ! 223: } ! 224: ! 225: /* */ ! 226: ! 227: static struct nexus *exp1 () { ! 228: register char *cp; ! 229: register struct nexus *n, ! 230: *o; ! 231: ! 232: if ((n = exp2 ()) == NULL || (cp = nxtarg ()) == NULL) ! 233: return n; ! 234: ! 235: if (*cp != '-') { ! 236: padvise (NULLCP, "%s unexpected", cp); ! 237: return NULL; ! 238: } ! 239: ! 240: if (*++cp == '-') ! 241: goto header; ! 242: switch (smatch (cp, parswit)) { ! 243: case AMBIGSW: ! 244: ambigsw (cp, parswit); ! 245: talked++; ! 246: return NULL; ! 247: case UNKWNSW: ! 248: fprintf (stderr, "-%s unknown\n", cp); ! 249: talked++; ! 250: return NULL; ! 251: ! 252: case PRAND: ! 253: o = newnexus (ANDaction); ! 254: o -> n_L_child = n; ! 255: if (o -> n_R_child = exp1 ()) ! 256: return o; ! 257: padvise (NULLCP, "missing conjunctive"); ! 258: return NULL; ! 259: ! 260: header: ; ! 261: default: ! 262: prvarg (); ! 263: return n; ! 264: } ! 265: } ! 266: ! 267: /* */ ! 268: ! 269: static struct nexus *exp2 () { ! 270: register char *cp; ! 271: register struct nexus *n; ! 272: ! 273: if ((cp = nxtarg ()) == NULL) ! 274: return NULL; ! 275: ! 276: if (*cp != '-') { ! 277: prvarg (); ! 278: return exp3 (); ! 279: } ! 280: ! 281: if (*++cp == '-') ! 282: goto header; ! 283: switch (smatch (cp, parswit)) { ! 284: case AMBIGSW: ! 285: ambigsw (cp, parswit); ! 286: talked++; ! 287: return NULL; ! 288: case UNKWNSW: ! 289: fprintf (stderr, "-%s unknown\n", cp); ! 290: talked++; ! 291: return NULL; ! 292: ! 293: case PRNOT: ! 294: n = newnexus (NOTaction); ! 295: if (n -> n_L_child = exp3 ()) ! 296: return n; ! 297: padvise (NULLCP, "missing negation"); ! 298: return NULL; ! 299: ! 300: header: ; ! 301: default: ! 302: prvarg (); ! 303: return exp3 (); ! 304: } ! 305: } ! 306: ! 307: /* */ ! 308: ! 309: static struct nexus *exp3 () { ! 310: int i; ! 311: register char *cp, ! 312: *dp; ! 313: char buffer[BUFSIZ]; ! 314: register struct nexus *n; ! 315: ! 316: if ((cp = nxtarg ()) == NULL) ! 317: return NULL; ! 318: ! 319: if (*cp != '-') { ! 320: padvise (NULLCP, "%s unexpected", cp); ! 321: return NULL; ! 322: } ! 323: ! 324: if (*++cp == '-') { ! 325: dp = ++cp; ! 326: goto header; ! 327: } ! 328: switch (i = smatch (cp, parswit)) { ! 329: case AMBIGSW: ! 330: ambigsw (cp, parswit); ! 331: talked++; ! 332: return NULL; ! 333: case UNKWNSW: ! 334: fprintf (stderr, "-%s unknown\n", cp); ! 335: talked++; ! 336: return NULL; ! 337: ! 338: case PRLBR: ! 339: if ((n = parse ()) == NULL) { ! 340: padvise (NULLCP, "missing group"); ! 341: return NULL; ! 342: } ! 343: if ((cp = nxtarg ()) == NULL) { ! 344: padvise (NULLCP, "missing -rbrace"); ! 345: return NULL; ! 346: } ! 347: if (*cp++ == '-' && smatch (cp, parswit) == PRRBR) ! 348: return n; ! 349: padvise (NULLCP, "%s unexpected", --cp); ! 350: return NULL; ! 351: ! 352: default: ! 353: prvarg (); ! 354: return NULL; ! 355: ! 356: case PRCC: ! 357: case PRDATE: ! 358: case PRFROM: ! 359: case PRTO: ! 360: case PRSUBJ: ! 361: dp = *brkstring (parswit[i].sw, " ", NULLCP); ! 362: header: ; ! 363: if (!(cp = nxtarg ())) {/* allow -xyz arguments */ ! 364: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 365: return NULL; ! 366: } ! 367: n = newnexus (GREPaction); ! 368: n -> n_header = 1; ! 369: (void) sprintf (buffer, "^%s[ \t]*:.*%s", dp, cp); ! 370: dp = buffer; ! 371: goto pattern; ! 372: ! 373: case PRSRCH: ! 374: n = newnexus (GREPaction); ! 375: n -> n_header = 0; ! 376: if (!(cp = nxtarg ())) {/* allow -xyz arguments */ ! 377: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 378: return NULL; ! 379: } ! 380: dp = cp; ! 381: pattern: ; ! 382: if (!gcompile (n, dp)) { ! 383: padvise (NULLCP, "pattern error in %s %s", argp[-2], cp); ! 384: return NULL; ! 385: } ! 386: n -> n_patbuf = getcpy (dp); ! 387: return n; ! 388: ! 389: case PROTHR: ! 390: padvise (NULLCP, "internal error!"); ! 391: return NULL; ! 392: ! 393: case PRDATF: ! 394: if (!(datesw = nxtarg ()) || *datesw == '-') { ! 395: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 396: return NULL; ! 397: } ! 398: return exp3 (); ! 399: ! 400: case PRAFTR: ! 401: case PRBEFR: ! 402: if (!(cp = nxtarg ())) {/* allow -xyz arguments */ ! 403: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 404: return NULL; ! 405: } ! 406: n = newnexus (TWSaction); ! 407: n -> n_datef = datesw; ! 408: if (!tcompile (cp, &n -> n_tws, n -> n_after = i == PRAFTR)) { ! 409: padvise (NULLCP, "unable to parse %s %s", argp[-2], cp); ! 410: return NULL; ! 411: } ! 412: return n; ! 413: } ! 414: } ! 415: ! 416: /* */ ! 417: ! 418: static struct nexus *newnexus (action) ! 419: register int (*action) (); ! 420: { ! 421: register struct nexus *p; ! 422: ! 423: if ((p = (struct nexus *) calloc ((unsigned) 1, sizeof *p)) == NULL) ! 424: adios (NULLCP, "unable to allocate component storage"); ! 425: ! 426: p -> n_action = action; ! 427: return p; ! 428: } ! 429: ! 430: /* */ ! 431: ! 432: #define args(a) a, fp, msgnum, start, stop ! 433: #define params args (n) ! 434: #define plist \ ! 435: register struct nexus *n; \ ! 436: register FILE *fp; \ ! 437: int msgnum; \ ! 438: long start, \ ! 439: stop; ! 440: ! 441: int pmatches (fp, msgnum, start, stop) ! 442: register FILE *fp; ! 443: int msgnum; ! 444: long start, ! 445: stop; ! 446: { ! 447: if (!head) ! 448: return 1; ! 449: ! 450: if (!talked++ && pdebug) ! 451: PRaction (head, 0); ! 452: ! 453: return (*head -> n_action) (args (head)); ! 454: } ! 455: ! 456: /* */ ! 457: ! 458: static PRaction (n, level) ! 459: register struct nexus *n; ! 460: register int level; ! 461: { ! 462: register int i; ! 463: ! 464: for (i = 0; i < level; i++) ! 465: fprintf (stderr, "| "); ! 466: ! 467: if (n -> n_action == ORaction) { ! 468: fprintf (stderr, "OR\n"); ! 469: PRaction (n -> n_L_child, level + 1); ! 470: PRaction (n -> n_R_child, level + 1); ! 471: return; ! 472: } ! 473: if (n -> n_action == ANDaction) { ! 474: fprintf (stderr, "AND\n"); ! 475: PRaction (n -> n_L_child, level + 1); ! 476: PRaction (n -> n_R_child, level + 1); ! 477: return; ! 478: } ! 479: if (n -> n_action == NOTaction) { ! 480: fprintf (stderr, "NOT\n"); ! 481: PRaction (n -> n_L_child, level + 1); ! 482: return; ! 483: } ! 484: if (n -> n_action == GREPaction) { ! 485: fprintf (stderr, "PATTERN(%s) %s\n", ! 486: n -> n_header ? "header" : "body", n -> n_patbuf); ! 487: return; ! 488: } ! 489: if (n -> n_action == TWSaction) { ! 490: fprintf (stderr, "TEMPORAL(%s) %s: %s\n", ! 491: n -> n_after ? "after" : "before", n -> n_datef, ! 492: dasctime (&n -> n_tws, TW_NULL)); ! 493: return; ! 494: } ! 495: fprintf (stderr, "UNKNOWN(0x%x)\n", (*n -> n_action)); ! 496: } ! 497: ! 498: /* */ ! 499: ! 500: static int ORaction (params) ! 501: plist ! 502: { ! 503: if ((*n -> n_L_child -> n_action) (args (n -> n_L_child))) ! 504: return 1; ! 505: return (*n -> n_R_child -> n_action) (args (n -> n_R_child)); ! 506: } ! 507: ! 508: ! 509: static int ANDaction (params) ! 510: plist ! 511: { ! 512: if (!(*n -> n_L_child -> n_action) (args (n -> n_L_child))) ! 513: return 0; ! 514: return (*n -> n_R_child -> n_action) (args (n -> n_R_child)); ! 515: } ! 516: ! 517: ! 518: static int NOTaction (params) ! 519: plist ! 520: { ! 521: return (!(*n -> n_L_child -> n_action) (args (n -> n_L_child))); ! 522: } ! 523: ! 524: /* */ ! 525: ! 526: static int gcompile (n, astr) ! 527: register struct nexus *n; ! 528: register char *astr; ! 529: { ! 530: register int c; ! 531: int cclcnt; ! 532: register char *ep, ! 533: *dp, ! 534: *sp, ! 535: *lastep; ! 536: ! 537: dp = (ep = n -> n_expbuf) + sizeof n -> n_expbuf; ! 538: sp = astr; ! 539: if (*sp == '^') { ! 540: n -> n_circf = 1; ! 541: sp++; ! 542: } ! 543: else ! 544: n -> n_circf = 0; ! 545: for (;;) { ! 546: if (ep >= dp) ! 547: goto cerror; ! 548: if ((c = *sp++) != '*') ! 549: lastep = ep; ! 550: switch (c) { ! 551: case '\0': ! 552: *ep++ = CEOF; ! 553: return 1; ! 554: ! 555: case '.': ! 556: *ep++ = CDOT; ! 557: continue; ! 558: ! 559: case '*': ! 560: if (lastep == 0) ! 561: goto defchar; ! 562: *lastep |= STAR; ! 563: continue; ! 564: ! 565: case '$': ! 566: if (*sp != '\0') ! 567: goto defchar; ! 568: *ep++ = CDOL; ! 569: continue; ! 570: ! 571: case '[': ! 572: *ep++ = CCL; ! 573: *ep++ = 0; ! 574: cclcnt = 1; ! 575: if ((c = *sp++) == '^') { ! 576: c = *sp++; ! 577: ep[-2] = NCCL; ! 578: } ! 579: do { ! 580: *ep++ = c; ! 581: cclcnt++; ! 582: if (c == '\0' || ep >= dp) ! 583: goto cerror; ! 584: } while ((c = *sp++) != ']'); ! 585: lastep[1] = cclcnt; ! 586: continue; ! 587: ! 588: case '\\': ! 589: if ((c = *sp++) == '\0') ! 590: goto cerror; ! 591: defchar: ! 592: default: ! 593: *ep++ = CCHR; ! 594: *ep++ = c; ! 595: } ! 596: } ! 597: ! 598: cerror: ; ! 599: return 0; ! 600: } ! 601: ! 602: /* */ ! 603: ! 604: /* ARGSUSED */ ! 605: ! 606: static int GREPaction (params) ! 607: plist ! 608: { ! 609: int c, ! 610: body, ! 611: lf; ! 612: long pos = start; ! 613: register char *p1, ! 614: *p2, ! 615: *ebp, ! 616: *cbp; ! 617: char ibuf[BUFSIZ]; ! 618: ! 619: (void) fseek (fp, start, 0); ! 620: body = 0; ! 621: ebp = cbp = ibuf; ! 622: for (;;) { ! 623: if (body && n -> n_header) ! 624: return 0; ! 625: p1 = linebuf; ! 626: p2 = cbp; ! 627: lf = 0; ! 628: for (;;) { ! 629: if (p2 >= ebp) { ! 630: if (fgets (ibuf, sizeof ibuf, fp) == NULL ! 631: || (stop && pos >= stop)) { ! 632: if (lf) ! 633: break; ! 634: return 0; ! 635: } ! 636: pos += (long) strlen (ibuf); ! 637: p2 = ibuf; ! 638: ebp = ibuf + strlen (ibuf); ! 639: } ! 640: c = *p2++; ! 641: if (lf && c != '\n') ! 642: if (c != ' ' && c != '\t') { ! 643: --p2; ! 644: break; ! 645: } ! 646: else ! 647: lf = 0; ! 648: if (c == '\n') ! 649: if (body) ! 650: break; ! 651: else { ! 652: if (lf) { ! 653: body++; ! 654: break; ! 655: } ! 656: lf++; ! 657: c = ' '; ! 658: } ! 659: if (c && p1 < &linebuf[LBSIZE - 1]) ! 660: *p1++ = c; ! 661: } ! 662: ! 663: *p1++ = NULL; ! 664: cbp = p2; ! 665: p1 = linebuf; ! 666: p2 = n -> n_expbuf; ! 667: ! 668: if (n -> n_circf) { ! 669: if (advance (p1, p2)) ! 670: return 1; ! 671: continue; ! 672: } ! 673: ! 674: if (*p2 == CCHR) { ! 675: c = p2[1]; ! 676: do { ! 677: if (*p1 == c || cc[*p1] == c) ! 678: if (advance (p1, p2)) ! 679: return 1; ! 680: } while (*p1++); ! 681: continue; ! 682: } ! 683: ! 684: do { ! 685: if (advance (p1, p2)) ! 686: return 1; ! 687: } while (*p1++); ! 688: } ! 689: } ! 690: ! 691: /* */ ! 692: ! 693: static int advance (alp, aep) ! 694: register char *alp, ! 695: *aep; ! 696: { ! 697: register char *lp, ! 698: *ep, ! 699: *curlp; ! 700: ! 701: lp = alp; ! 702: ep = aep; ! 703: for (;;) ! 704: switch (*ep++) { ! 705: case CCHR: ! 706: if (*ep++ == *lp++ || ep[-1] == cc[lp[-1]]) ! 707: continue; ! 708: return 0; ! 709: ! 710: case CDOT: ! 711: if (*lp++) ! 712: continue; ! 713: return 0; ! 714: ! 715: case CDOL: ! 716: if (*lp == 0) ! 717: continue; ! 718: return 0; ! 719: ! 720: case CEOF: ! 721: return 1; ! 722: ! 723: case CCL: ! 724: if (cclass (ep, *lp++, 1)) { ! 725: ep += *ep; ! 726: continue; ! 727: } ! 728: return 0; ! 729: ! 730: case NCCL: ! 731: if (cclass (ep, *lp++, 0)) { ! 732: ep += *ep; ! 733: continue; ! 734: } ! 735: return 0; ! 736: ! 737: case CDOT | STAR: ! 738: curlp = lp; ! 739: while (*lp++) ! 740: continue; ! 741: goto star; ! 742: ! 743: case CCHR | STAR: ! 744: curlp = lp; ! 745: while (*lp++ == *ep || cc[lp[-1]] == *ep) ! 746: continue; ! 747: ep++; ! 748: goto star; ! 749: ! 750: case CCL | STAR: ! 751: case NCCL | STAR: ! 752: curlp = lp; ! 753: while (cclass (ep, *lp++, ep[-1] == (CCL | STAR))) ! 754: continue; ! 755: ep += *ep; ! 756: goto star; ! 757: ! 758: star: ! 759: do { ! 760: lp--; ! 761: if (advance (lp, ep)) ! 762: return (1); ! 763: } while (lp > curlp); ! 764: return 0; ! 765: ! 766: default: ! 767: admonish (NULLCP, "advance() botch -- you lose big"); ! 768: return 0; ! 769: } ! 770: } ! 771: ! 772: /* */ ! 773: ! 774: static int cclass (aset, ac, af) ! 775: register char *aset; ! 776: { ! 777: register int n; ! 778: register char c, ! 779: *set; ! 780: ! 781: set = aset; ! 782: if ((c = ac) == 0) ! 783: return (0); ! 784: ! 785: n = *set++; ! 786: while (--n) ! 787: if (*set++ == c) ! 788: return (af); ! 789: ! 790: return (!af); ! 791: } ! 792: ! 793: /* */ ! 794: ! 795: static int tcompile (ap, tb, isafter) ! 796: register char *ap; ! 797: register struct tws *tb; ! 798: int isafter; ! 799: { ! 800: register struct tws *tw; ! 801: ! 802: if ((tw = tws_parse (ap, isafter)) == NULL) ! 803: return 0; ! 804: ! 805: twscopy (tb, tw); ! 806: return 1; ! 807: } ! 808: ! 809: /* */ ! 810: ! 811: static struct tws *tws_parse (ap, isafter) ! 812: register char *ap; ! 813: int isafter; ! 814: { ! 815: char buffer[BUFSIZ]; ! 816: register struct tws *tw, ! 817: *ts; ! 818: ! 819: if ((tw = tws_special (ap)) != NULL) { ! 820: tw -> tw_sec = tw -> tw_min = isafter ? 59 : 0; ! 821: tw -> tw_hour = isafter ? 23 : 0; ! 822: return tw; ! 823: } ! 824: if ((tw = dparsetime (ap)) != NULL) ! 825: return tw; ! 826: ! 827: if ((ts = dtwstime ()) == NULL) ! 828: return NULL; ! 829: ! 830: (void) sprintf (buffer, "%s %s", ap, dtwszone (ts)); ! 831: if ((tw = dparsetime (buffer)) != NULL) ! 832: return tw; ! 833: ! 834: (void) sprintf (buffer, "%s %02d:%02d:%02d %s", ap, ! 835: ts -> tw_hour, ts -> tw_min, ts -> tw_sec, dtwszone (ts)); ! 836: if ((tw = dparsetime (buffer)) != NULL) ! 837: return tw; ! 838: ! 839: (void) sprintf (buffer, "%02d %s %02d %s", ! 840: ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year, ap); ! 841: if ((tw = dparsetime (buffer)) != NULL) ! 842: return tw; ! 843: ! 844: (void) sprintf (buffer, "%02d %s %02d %s %s", ! 845: ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year, ! 846: ap, dtwszone (ts)); ! 847: if ((tw = dparsetime (buffer)) != NULL) ! 848: return tw; ! 849: ! 850: return NULL; ! 851: } ! 852: ! 853: /* */ ! 854: ! 855: static struct tws *tws_special (ap) ! 856: register char *ap; ! 857: { ! 858: int i; ! 859: long clock; ! 860: register struct tws *tw; ! 861: ! 862: (void) time (&clock); ! 863: if (uleq (ap, "Today")) ! 864: return dlocaltime (&clock); ! 865: if (uleq (ap, "Yesterday")) { ! 866: clock -= (long) (60 * 60 * 24); ! 867: return dlocaltime (&clock); ! 868: } ! 869: if (uleq (ap, "Tomorrow")) { ! 870: clock += (long) (60 * 60 * 24); ! 871: return dlocaltime (&clock); ! 872: } ! 873: ! 874: for (i = 0; tw_ldotw[i]; i++) ! 875: if (uleq (ap, tw_ldotw[i])) ! 876: break; ! 877: if (tw_ldotw[i]) { ! 878: if ((tw = dlocaltime (&clock)) == NULL) ! 879: return NULL; ! 880: if ((i -= tw -> tw_wday) > 0) ! 881: i -= 7; ! 882: } ! 883: else ! 884: if (*ap != '-') ! 885: return NULL; ! 886: else /* -ddd days ago */ ! 887: i = atoi (ap); /* we should error check this */ ! 888: ! 889: clock += (long) ((60 * 60 * 24) * i); ! 890: return dlocaltime (&clock); ! 891: } ! 892: ! 893: /* */ ! 894: ! 895: /* ARGSUSED */ ! 896: ! 897: static int TWSaction (params) ! 898: plist ! 899: { ! 900: int state; ! 901: register char *bp; ! 902: char buf[BUFSIZ], ! 903: name[NAMESZ]; ! 904: register struct tws *tw; ! 905: ! 906: (void) fseek (fp, start, 0); ! 907: for (state = FLD, bp = NULL;;) { ! 908: switch (state = m_getfld (state, name, buf, sizeof buf, fp)) { ! 909: case FLD: ! 910: case FLDEOF: ! 911: case FLDPLUS: ! 912: if (bp != NULL) ! 913: free (bp), bp = NULL; ! 914: bp = add (buf, NULLCP); ! 915: while (state == FLDPLUS) { ! 916: state = m_getfld (state, name, buf, sizeof buf, fp); ! 917: bp = add (buf, bp); ! 918: } ! 919: if (uleq (name, n -> n_datef)) ! 920: break; ! 921: if (state != FLDEOF) ! 922: continue; ! 923: ! 924: case BODY: ! 925: case BODYEOF: ! 926: case FILEEOF: ! 927: case LENERR: ! 928: case FMTERR: ! 929: if (state == LENERR || state == FMTERR) ! 930: advise (NULLCP, "format error in message %d", msgnum); ! 931: if (bp != NULL) ! 932: free (bp); ! 933: return 0; ! 934: ! 935: default: ! 936: adios (NULLCP, "internal error -- you lose"); ! 937: } ! 938: break; ! 939: } ! 940: ! 941: /* */ ! 942: ! 943: if ((tw = dparsetime (bp)) == NULL) ! 944: advise (NULLCP, "unable to parse %s field in message %d, matching...", ! 945: n -> n_datef, msgnum), state = 1; ! 946: else ! 947: state = n -> n_after ? (twsort (tw, &n -> n_tws) > 0) ! 948: : (twsort (tw, &n -> n_tws) < 0); ! 949: ! 950: if (bp != NULL) ! 951: free (bp); ! 952: return state; ! 953: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.