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