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