Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / sbr / RCS / addrsbr.c,v
1 head    1.13;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.13
9 date    92.10.26.22.44.26;      author jromine; state Exp;
10 branches;
11 next    1.12;
12
13 1.12
14 date    92.05.12.22.10.48;      author jromine; state Exp;
15 branches;
16 next    1.11;
17
18 1.11
19 date    92.01.31.21.43.01;      author jromine; state Exp;
20 branches;
21 next    1.10;
22
23 1.10
24 date    92.01.30.22.39.48;      author jromine; state Exp;
25 branches;
26 next    1.9;
27
28 1.9
29 date    92.01.24.19.48.48;      author jromine; state Exp;
30 branches;
31 next    1.8;
32
33 1.8
34 date    92.01.24.17.58.41;      author jromine; state Exp;
35 branches;
36 next    1.7;
37
38 1.7
39 date    90.11.05.12.26.41;      author mh;      state Exp;
40 branches;
41 next    1.6;
42
43 1.6
44 date    90.04.05.15.31.05;      author sources; state Exp;
45 branches;
46 next    1.5;
47
48 1.5
49 date    90.04.05.14.45.10;      author sources; state Exp;
50 branches;
51 next    1.4;
52
53 1.4
54 date    90.03.12.14.02.34;      author sources; state Exp;
55 branches;
56 next    1.3;
57
58 1.3
59 date    90.02.08.15.12.39;      author sources; state Exp;
60 branches;
61 next    1.2;
62
63 1.2
64 date    90.02.06.16.43.28;      author sources; state Exp;
65 branches;
66 next    1.1;
67
68 1.1
69 date    90.02.01.16.09.43;      author sources; state Exp;
70 branches;
71 next    ;
72
73
74 desc
75 @@
76
77
78 1.13
79 log
80 @use isupper with isascii
81 @
82 text
83 @/* addrsbr.c - parse addresses 822-style */
84 #ifndef lint
85 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.12 1992/05/12 22:10:48 jromine Exp jromine $";
86 #endif /* lint */
87
88 #include "../h/mh.h"
89 #include "../h/addrsbr.h"
90 #include "../zotnet/mf.h"
91 #include <stdio.h>
92 #ifdef  BERK
93 #include <ctype.h>
94 #endif /* BERK */
95
96 /* High level parsing of addresses:
97
98    The routines in zotnet/mf/mf.c parse the syntactic representations of
99    addresses.  The routines in sbr/addrsbr.c associate semantics with those
100    addresses.  
101
102    If #ifdef BERK is in effect, the routines in mf.c aren't called and only
103    the most rudimentary syntax parse is done.  The parse is not 822-conformant.
104    This causes problems as there is no semantics associated with the address
105    at all--it's just a string. (the author of the BERK code disagrees with
106    the preceding, of course.  BERK solves problems for incoming mail
107    because it will accept damn near any address.  BERK was intended to be
108    used when spost is the interface to the mail delivery system which means
109    all outgoing address interpretation is left to sendmail.  It is possible,
110    though unlikely, for BERK address parsing to interact poorly with 
111    "post". - van@@monet.berkeley.edu).
112
113    Instead, if #ifdef DUMB is in effect, a full 822-style parser is called
114    for syntax recongition.  This breaks each address into its components.
115    Note however that no semantics are assumed about the parts or their
116    totality.  This means that implicit hostnames aren't made explicit,
117    and explicit hostnames aren't expanded to their "official" represenations.
118
119    If neither BERK nor DUMB is in effect, then this module does some
120    high-level thinking about what the addresses are.  If #ifdef MF is in
121    effect, then MH will deduce UUCP-style addressing masquerading as
122    822-style addresses.
123
124    1. for MMDF systems:
125
126         string%<uucp>@@<local>  ->      string
127
128    2. for non-MMDF systems:
129
130         string@@host.<uucp>     ->      host!string
131
132    3. for any system, an address interpreted relative to the local host:
133
134         string@@<uucp>          ->      string
135
136    For cases (1) and (3) above, the leftmost host is extracted.  If it's not
137    present, the local host is used.  If #ifdef MF is not in effect or the
138    tests above fail, the address is considered to be a real 822-style address.
139
140    If an explicit host is not present, then MH checks for a bang to indicate
141    an explicit UUCP-style address.  If so, this is noted.  If not, the host is
142    defaulted, typically to the local host.  The lack of an explict host is
143    also noted.
144
145    If an explicit 822-style host is present, then MH checks to see if it
146    can expand this to the official name for the host.  If the hostname is
147    unknown, the address is so typed.
148
149    To summarize, when we're all done, here's what MH knows about the address:
150
151    BERK -       type:   local
152                 nohost: set if no '@@' or '!' in mailbox
153                 text:   exact copy of address
154                 mbox:   lowercase version of mailbox
155
156    DUMB -       type:   local, uucp, or network
157                 host:   not locally defaulted, not explicitly expanded
158                 everything else
159
160    other -      type:   local, uucp, network, unknown
161                 everything else
162  */
163
164 /* \f */
165
166 #if     !defined(DUMB) && defined(SENDMTS) && !defined(BANG)
167 #define MF
168 #define UucpChan()      "UUCP"
169 #endif /* MF */
170
171 #ifdef  BERK
172 static char *err = NULL;
173 static char adrtext[BUFSIZ];
174 #else /* not BERK */
175 static int  ingrp = 0;
176
177 static char *pers = NULL;
178 static char *mbox = NULL;
179 static char *host = NULL;
180 static char *route = NULL;
181 static char *grp = NULL;
182 static char *note = NULL;
183
184 static char err[BUFSIZ];
185 #endif /* not BERK */
186 static char adr[BUFSIZ];
187
188
189 char   *getusr ();
190
191 /* \f */
192
193 char   *getname (addrs)
194 register char   *addrs;
195 {
196 #ifdef  BERK
197     /*
198      * Berkeley uses a very simple parser since Sendmail does all the work.
199      * The only thing that does address parsing if BERK is defined is the
200      * routine "ismybox" used by "scan" & "repl" to identify the current
201      * users maildrop.
202      *
203      * This routine does essentially the same address interpretation as the
204      * routine "prescan" in "sendmail".  The intent is that MH should 
205      * make minimum assumptions about address forms since it doesn't
206      * have access to the information in the sendmail config file
207      * (God forbid that anything but sendmail has to deal with a sendmail
208      * config file) and, therefore, hasn't the faintest idea of what will
209      * or won't be a legal address.
210      *
211      * Since this parse is only used by "ismybox" and repl, it just does
212      * two things: split multiple addr on a line into separate addresses and 
213      * locate the "mailbox" portion of an address.  The parse uses rfc-822
214      * metacharacters and quoting but is much less restrictive that rfc-822.
215      * In detail, `,' or eos terminate addresses.  "Empty" addresses
216      * (e.g., `,,') are ignored.  Double quote ("), backslash, left & right
217      * paren and left and right angle brackets are metacharacters.  Left &
218      * right parens must balance as must left & right angle brackets.  Any
219      * metacharacter may be escaped by preceding it with a backslash.
220      * Any text between parens is considered a comment and ignored (i.e.,
221      * only `(', `)' and `\' are metacharacters following a `(').  Text
222      * between double quotes is considered escaped (i.e., only `"' and
223      * `\' are metacharacters following a `"').  The `mailbox' portion
224      * of an address is the non-comment text between angle-brackets if
225      * the address contains any angle brackets.  Otherwise, it is all the
226      * non-comment text.  Blanks, tabs & newlines will not be included
227      * in the mailbox portion of an address unless they are escaped.
228      */
229
230 /* Scanner states */
231 #define NORMAL  (0<<8)
232 #define QS      (1<<8)  /* in quoted string */
233 #define COM     (2<<8)  /* in comment (...) */
234 #define ERR     (3<<8)  /* found an error */
235 #define EOA     (4<<8)  /* end of address */
236
237     static char *saved_addr = NULL;     /* saved address line ptr */
238     static char *adr_ptr = NULL;        /* where to start looking for
239                                            next address on line */
240     register char *nxtout = adr;        /* where to put next character of
241                                            `mailbox' part of address */
242     register char c;
243     register int state = NORMAL;
244     register char *adrcopy = adrtext;   /* where to put next character of
245                                            address */
246     register int lbcnt = 0;             /* number of unmatched "(" */
247     register int lpcnt = 0;             /* number of unmatched "<" */
248
249     err = NULL;
250     if (! addrs) {
251         adr_ptr = NULL;
252         return NULL;
253     }
254     if (adr_ptr)
255         addrs = adr_ptr;
256     else
257         addrs = saved_addr = getcpy(addrs ? addrs : "");
258
259     /* skip any leading whitespace or commas. */
260     while ( (c = *addrs++) == ',' || isspace(c))
261         ;
262     
263     *nxtout = *adrcopy = '\0';
264     while (state != EOA) {
265         *adrcopy++ = c;
266         if (state != COM)
267             *nxtout++ = (isalpha(c) && isupper (c)) ? tolower (c) : c;
268         switch (state+c) {
269
270         case NORMAL+'\n':       /* discard newlines */
271         case QS+'\n':
272         case COM+'\n':
273         case ERR+'\n':
274             --nxtout;
275             --adrcopy;
276             break;
277
278         case NORMAL+' ':        /* skip unquoted whitespace */
279         case NORMAL+'\t':
280             --nxtout;
281             break;
282
283         case NORMAL+'"':        /* start quoted string */
284             state = QS;
285             break;
286
287         case QS+'"':            /* end quoted string */
288             state = NORMAL;
289             break;
290
291         case NORMAL+'<':
292             nxtout = adr;       /* start over accumulating address */
293             lbcnt++;
294             break;
295
296         case NORMAL+'>':
297             --lbcnt;
298             if (lbcnt < 0) {
299                 state = ERR;
300                 err = "extra >";
301             } else
302                 *(nxtout-1) = '\0';
303             break;
304
305         case NORMAL+'(':
306             state = COM;
307             --nxtout;
308         case COM+'(':
309             lpcnt++;
310             break;
311
312         case COM+')':
313             --lpcnt;
314             if (lpcnt < 0) {
315                 state = ERR;
316                 err = "extra )";
317             } else if (lpcnt == 0)
318                 state = NORMAL;
319             break;
320
321         case NORMAL+'\\':
322         case QS+'\\':
323         case COM+'\\':
324             if ((c = *addrs++) == '\n' || c == '\0') {
325                 state = EOA;
326                 err = "illegal \\";
327             }
328             *adrcopy++ = c;
329             *nxtout++ = (isalpha(c) && isupper (c)) ? tolower (c) : c;
330             break;
331
332         case NORMAL+',':
333         case ERR+',':
334         case NORMAL+'\0':
335         case ERR+'\0':
336             state = EOA;
337             if (lbcnt)
338                 err = "missing >";
339             break;
340
341         case COM+'\0':
342             state = EOA;
343             err = "missing )";
344             if (nxtout == adr)
345                 nxtout++;
346             break;
347
348         case QS+'\0':
349             state = EOA;
350             err = "missing \"";
351             break;
352         }
353         if (c != '\0')
354             c = *addrs++;
355     }
356     /*
357      * at this point adr contains the `mailbox' part of the address
358      * in lower case & minus any comment or unquoted whitespace.
359      * adrtext contains an exact copy of the address and
360      * addr points to where we should start scanning next time.
361      */
362     *(nxtout-1) = *(adrcopy-1) = '\0';
363     if (*adr && !err) {
364         adr_ptr = addrs-1;
365         return adrtext;
366     } else {
367         free (saved_addr);
368         adr_ptr = NULL;
369         return NULL;
370     }
371 #else /* not BERK */
372     register struct adrx *ap;
373
374     pers = mbox = host = route = grp = note = NULL;
375     err[0] = '\0';
376
377     if ((ap = getadrx (addrs ? addrs : "")) == NULL)
378         return NULL;
379
380     (void) strcpy (adr, ap -> text);
381     pers = ap -> pers;
382     mbox = ap -> mbox;
383     host = ap -> host;
384     route = ap -> path;
385     grp = ap -> grp;
386     ingrp = ap -> ingrp;
387     note = ap -> note;
388     if (ap -> err && *ap -> err)
389         (void) strcpy (err, ap -> err);
390
391     return adr;
392 #endif /* not BERK */
393 }
394
395 /* \f */
396
397 #ifdef  BERK
398 /* ARGSUSED */
399 #endif /* BERK */
400
401 struct mailname *getm (str, dfhost, dftype, wanthost, eresult)
402 register char   *str,
403                 *eresult;
404 char   *dfhost;
405 int     dftype,
406         wanthost;
407 {
408 #ifndef BERK
409     register char   *pp;
410 #ifndef DUMB
411     register char   *dp;
412 #endif /* not DUMB */
413 #ifdef  MF
414     char   *up = UucpChan ();
415 #endif /* MF */
416 #endif /* not BERK */
417     register struct mailname *mp;
418
419     if (err && err[0]) {
420         if (eresult)
421             (void) strcpy (eresult, err);
422         else
423             if (wanthost == AD_HOST)
424                 admonish (NULLCP, "bad address '%s' - %s", str, err);
425         return NULL;
426     }
427 #ifdef  BERK
428     if (str == NULL || *str == '\0') {
429 #else /* not BERK */
430     if (pers == NULL
431             && mbox == NULL && host == NULL && route == NULL
432             && grp == NULL) {
433 #endif /* not BERK */
434         if (eresult)
435             (void) strcpy (eresult, "null address");
436         else
437             if (wanthost == AD_HOST)
438                 admonish (NULLCP, "null address '%s'", str);
439         return NULL;
440     }
441 #ifndef BERK
442     if (mbox == NULL && grp == NULL) {
443         if (eresult)
444             (void) strcpy (eresult, "no mailbox in address");
445         else
446             if (wanthost == AD_HOST)
447                 admonish (NULLCP, "no mailbox in address '%s'", str);
448         return NULL;
449     }
450
451     if (dfhost == NULL) {
452         dfhost = LocalName ();
453         dftype = LOCALHOST;
454     }
455 #endif /* not BERK */
456
457     mp = (struct mailname  *) calloc ((unsigned) 1, sizeof *mp);
458     if (mp == NULL) {
459         if (eresult)
460            (void) strcpy (eresult, "insufficient memory to represent address");
461         else
462             if (wanthost == AD_HOST)
463                 adios (NULLCP, "insufficient memory to represent address");
464         return NULL;
465     }
466
467     mp -> m_next = NULL;
468     mp -> m_text = getcpy (str);
469 #ifdef  BERK
470     mp -> m_type = LOCALHOST;
471     mp -> m_mbox = getcpy (adr);
472     if (!index (adr, '@@') && !index (adr, '!'))
473         mp -> m_nohost = 1;
474 #else /* not BERK */
475     if (pers)
476         mp -> m_pers = getcpy (pers);
477
478     if (mbox == NULL) {
479         mp -> m_type = BADHOST;
480         mp -> m_nohost = 1;
481         mp -> m_ingrp = ingrp;
482         mp -> m_gname = getcpy (grp);
483         if (note)
484             mp -> m_note = getcpy (note);
485         return mp;
486     }
487
488 /* \f */
489
490     if (host) {
491 #ifdef MF
492 #ifdef  MMDFMTS
493         if (up && uleq (host, LocalName ())
494                 && (pp = rindex (mbox, '%'))
495                 && uleq (up, pp + 1)) {/* uucpaddr%<uucp>@@<local> */
496             *pp = NULL;
497             goto get_uucp;
498         }
499 #else /* not MMDFMTS */
500         if (up && (pp = index (host, '.')) 
501                 && uleq (up, pp + 1)) {/* uucpaddr@@host.<uucp> */
502             *pp = NULL;
503             mp -> m_host = getcpy (host);
504             mp -> m_mbox = getcpy (mbox);
505             mp -> m_type = UUCPHOST;
506             goto got_host;
507         }
508 #endif /* not MMDFMTS */
509         if (up && uleq (dfhost, LocalName ())
510                 && uleq (up, host)) {/* uucpaddr@@<uucp> [local] */
511             if (pp = index (mbox, '!')) {
512                 *pp++ = NULL;
513                 mp -> m_host = getcpy (mbox);
514                 mp -> m_mbox = getcpy (pp);
515             }
516             else {
517                 mp -> m_host = getcpy (SystemName ());
518                 mp -> m_mbox = getcpy (mbox);
519             }
520             mp -> m_type = UUCPHOST;
521             goto got_host;
522         }
523 #endif /* MF */
524         mp -> m_mbox = getcpy (mbox);
525         mp -> m_host = getcpy (host);
526     }
527     else {
528         if (pp = index (mbox, '!')) {
529             *pp++ = '\0';
530             mp -> m_mbox = getcpy (pp);
531             mp -> m_host = getcpy (mbox);
532             mp -> m_type = UUCPHOST;
533         }
534         else {
535             mp -> m_nohost = 1;
536             mp -> m_mbox = getcpy (mbox);
537 #ifdef  DUMB
538             if (route == NULL && dftype == LOCALHOST) {
539                 mp -> m_host = NULLCP;
540                 mp -> m_type = dftype;
541             }
542             else
543 #endif /* DUMB */
544             {
545                 mp -> m_host = route ? NULLCP : getcpy (dfhost);
546                 mp -> m_type = route ? NETHOST : dftype;
547             }
548         }
549         goto got_host;
550     }
551
552 /* \f */
553
554     if (wanthost == AD_NHST)
555         mp -> m_type = uleq (LocalName (), mp -> m_host)
556             ? LOCALHOST : NETHOST;
557 #ifdef  DUMB
558     else
559         mp -> m_type = uleq (LocalName (), mp -> m_host) ? LOCALHOST
560                 : NETHOST;
561 #else /* not DUMB */
562     else
563         if (pp = OfficialName (mp -> m_host)) {
564     got_real_host: ;
565             free (mp -> m_host);
566             mp -> m_host = getcpy (pp);
567             mp -> m_type = uleq (LocalName (), mp -> m_host) ? LOCALHOST
568                     : NETHOST;
569         }
570         else {
571             if (dp = index (mp -> m_host, '.')) {
572                 *dp = NULL;
573                 if (pp = OfficialName (mp -> m_host))
574                     goto got_real_host;
575                 *dp = '.';
576             }
577             mp -> m_type = BADHOST;
578         }
579 #endif /* not DUMB */
580
581 got_host: ;
582     if (route)
583         mp -> m_path = getcpy (route);
584     mp -> m_ingrp = ingrp;
585     if (grp)
586         mp -> m_gname = getcpy (grp);
587     if (note)
588         mp -> m_note = getcpy (note);
589 #endif /* not BERK */
590
591     return mp;
592 }
593
594 /* \f */
595
596 void    mnfree (mp)
597 register struct mailname *mp;
598 {
599     if (!mp)
600         return;
601
602     if (mp -> m_text)
603         free (mp -> m_text);
604     if (mp -> m_pers)
605         free (mp -> m_pers);
606     if (mp -> m_mbox)
607         free (mp -> m_mbox);
608     if (mp -> m_host)
609         free (mp -> m_host);
610     if (mp -> m_path)
611         free (mp -> m_path);
612     if (mp -> m_gname)
613         free (mp -> m_gname);
614     if (mp -> m_note)
615         free (mp -> m_note);
616 #ifdef  MHMTS
617     if (mp -> m_aka)
618         free (mp -> m_aka);
619 #endif /* MHMTS */
620
621     free ((char *) mp);
622 }
623
624 /* \f */
625
626 char   *auxformat (mp, extras)
627 register struct mailname   *mp;
628 int     extras;
629 {
630 #ifndef BERK
631 #ifdef  MF
632     char   *up = UucpChan ();
633 #endif /* MF */
634     static char addr[BUFSIZ];
635 #endif /* not BERK */
636     static char buffer[BUFSIZ];
637
638 #ifdef  BERK
639     /* this "if" is a crufty hack to handle "visible" aliases */
640     if (mp->m_pers && !extras)
641         (void) sprintf (buffer, "%s <%s>", mp->m_pers, mp->m_mbox);
642     else
643         (void) strcpy (buffer, mp -> m_text);
644 #else /* not BERK */
645
646 #ifdef  MF
647     if (up && mp -> m_type == UUCPHOST)
648 #ifdef  MMDFMTS
649         (void) sprintf (addr, "%s!%s%%%s@@%s", mp -> m_host, mp -> m_mbox,
650                 up, LocalName ());
651 #else /* not MMDFMTS */
652         (void) sprintf (addr, "%s@@%s.%s", mp -> m_mbox, mp -> m_host, up);
653 #endif /* not MMDFMTS */
654     else 
655 #endif /* MF */
656
657 #ifdef  DUMB
658         if (mp -> m_nohost)
659             (void) strcpy (addr, mp -> m_mbox ? mp -> m_mbox : "");
660         else
661 #endif /* DUMB */
662
663 #ifndef BANG
664         if (mp -> m_type != UUCPHOST)
665             (void) sprintf (addr, mp -> m_host ? "%s%s@@%s" : "%s%s",
666                 mp -> m_path ? mp -> m_path : "", mp -> m_mbox, mp -> m_host);
667         else
668 #endif /* not BANG */
669             (void) sprintf (addr, "%s!%s", mp -> m_host, mp -> m_mbox);
670
671     if (!extras)
672         return addr;
673
674     if (mp -> m_pers || mp -> m_path)
675         if (mp -> m_note)
676             (void) sprintf (buffer, "%s %s <%s>",
677                     legal_person (mp -> m_pers ? mp -> m_pers : mp -> m_mbox),
678                     mp -> m_note, addr);
679         else
680             (void) sprintf (buffer, "%s <%s>",
681                     legal_person (mp -> m_pers ? mp -> m_pers : mp -> m_mbox),
682                     addr);
683     else
684         if (mp -> m_note)
685             (void) sprintf (buffer, "%s %s", addr, mp -> m_note);
686         else
687             (void) strcpy (buffer, addr);
688 #endif /* not BERK */
689
690     return buffer;
691 }
692
693 /* \f */
694
695 #if     defined(BERK) || (defined(DUMB) && !defined(MMDFMTS) && !defined(SMTP))
696 #define REALLYDUMB
697 #else
698 #undef  REALLYDUMB
699 #endif
700
701 char   *adrsprintf (local, domain)
702 char   *local,
703        *domain;
704 {
705     static char addr[BUFSIZ];
706
707     if (local == NULL)
708 #ifdef  REALLYDUMB
709         return getusr ();
710     else
711 #endif /* REALLYDUMB */
712         local = getusr ();
713
714     if (domain == NULL)
715 #ifdef  REALLYDUMB
716         return local;
717     else
718 #endif /* REALLYDUMB */
719         domain = LocalName ();
720
721 #ifndef BANG
722     (void) sprintf (addr, "%s@@%s", local, domain);
723 #else /* BANG */
724     (void) sprintf (addr, "%s!%s", domain, local);
725 #endif /* BANG */
726
727     return addr;
728 }
729
730 /* \f */
731
732 #define W_NIL   0x0000
733 #define W_MBEG  0x0001
734 #define W_MEND  0x0002
735 #define W_MBOX  (W_MBEG | W_MEND)
736 #define W_HBEG  0x0004
737 #define W_HEND  0x0008
738 #define W_HOST  (W_HBEG | W_HEND)
739 #define WBITS   "\020\01MBEG\02MEND\03HBEG\04HEND"
740
741
742 int     ismymbox (np)
743 register struct mailname *np;
744 {
745     int     oops;
746     register int    len,
747                     i;
748     register char  *cp;
749 #ifndef BERK
750     register char  *pp;
751     char    buffer[BUFSIZ];
752 #endif /* not BERK */
753     register struct mailname   *mp;
754     static char *am = NULL;
755     static struct mailname  mq={NULL};
756
757     /* if this is the first call, init. alternate mailboxes list */
758     if (am == NULL) {
759         mq.m_next = NULL;
760         mq.m_mbox = getusr ();
761         if ((am = m_find ("alternate-mailboxes")) == NULL)
762             am = getusr ();
763         else {
764             mp = &mq;
765             oops = 0;
766             while (cp = getname (am))
767                 if ((mp -> m_next = getm (cp, NULLCP, 0, AD_NAME, NULLCP))
768                         == NULL)
769                     admonish (NULLCP, "illegal address: %s", cp), oops++;
770                 else {
771                     mp = mp -> m_next;
772                     mp -> m_type = W_NIL;
773 #ifdef  BERK
774                     /* check for wildcards on the mailbox name and
775                        set m_type accordingly. */
776                     mp -> m_ingrp = strlen (mp -> m_mbox);
777                     if (*(mp -> m_mbox) == '*') {
778                         mp -> m_type |= W_MBEG;
779                         mp -> m_mbox++;
780                         --mp -> m_ingrp;
781                     }
782                     if (mp -> m_mbox[mp -> m_ingrp - 1] == '*') {
783                         mp -> m_type |= W_MEND;
784                         mp -> m_ingrp--;
785                         mp -> m_mbox[mp -> m_ingrp] = 0;
786                     }
787 #else /* not BERK */
788                     /* owing to screwy munging, wildcarding is a great idea
789                        even under #ifndef BERK, so... */
790                     mp -> m_type = W_NIL;
791                     if (*mp -> m_mbox == '*')
792                         mp -> m_type |= W_MBEG, mp -> m_mbox++;
793                     if (*(cp = mp -> m_mbox + strlen (mp -> m_mbox) - 1)
794                             == '*')
795                         mp -> m_type |= W_MEND, *cp = '\0';
796                     if (mp -> m_host) {
797                         if (*mp -> m_host == '*')
798                             mp -> m_type |= W_HBEG, mp -> m_host++;
799                         if (*(cp = mp -> m_host + strlen (mp -> m_host) - 1)
800                                 == '*')
801                             mp -> m_type |= W_HEND, *cp = '\0';
802                     }
803                     if ((cp = getenv ("MHWDEBUG")) && *cp)
804                         fprintf (stderr, "mbox=\"%s\" host=\"%s\" %s\n",
805                             mp -> m_mbox, mp -> m_host,
806                             sprintb (buffer, (unsigned) mp -> m_type, WBITS));
807 #endif /* not BERK */
808                 }
809             if (oops)
810                 advise (NULLCP, "please fix the %s: entry in your %s file",
811                         "alternate-mailboxes", mh_profile);
812         }
813     }
814     if (np == NULL) /* XXX */
815         return 0;
816     
817 #ifdef  BERK
818     cp = np -> m_mbox;
819     if (strcmp (cp, mq.m_mbox) == 0)
820         return 1;
821 #else /* not BERK */
822     switch (np -> m_type) {
823         case NETHOST:
824             len = strlen (cp = LocalName ());
825             if (!uprf (np -> m_host, cp) || np -> m_host[len] != '.')
826                 break;
827             goto local_test;
828
829         case UUCPHOST:
830             if (!uleq (np -> m_host, SystemName ()))
831                 break;          /* fall */
832         case LOCALHOST:
833 local_test: ;
834             if (uleq (np -> m_mbox, mq.m_mbox))
835                 return 1;
836             break;
837
838         default:
839             break;
840     }
841 #endif /* not BERK */
842
843 #ifdef  BERK
844     len = strlen (cp);
845     for (mp = &mq; mp = mp -> m_next;)
846         if (len >= mp -> m_ingrp)
847             switch (mp -> m_type) {
848                 case W_NIL:     /* no wildcards */
849                     if (strcmp (cp, mp -> m_mbox) == 0)
850                         return 1;
851                     break;
852
853                 case W_MBEG:    /* wildcard at beginning */
854                     if (strcmp (&cp[len - mp -> m_ingrp], mp -> m_mbox) == 0)
855                         return 1;
856                     break;
857
858                 case W_MEND:    /* wildcard at end */
859                     if (strncmp (cp, mp -> m_mbox, mp -> m_ingrp) == 0)
860                         return 1;
861                     break;
862
863                 case W_MBEG | W_MEND: /* wildcard at beginning & end */
864                     for (i = 0; i <= len - mp -> m_ingrp; i++)
865                         if (strncmp (&cp[i], mp -> m_mbox, mp -> m_ingrp) == 0)
866                             return 1;
867             }
868 #else /* not BERK */
869     for (mp = &mq; mp = mp -> m_next;) {
870         if (np -> m_mbox == NULL)
871             continue;
872         if ((len = strlen (cp = np -> m_mbox))
873                 < (i = strlen (pp = mp -> m_mbox)))
874             continue;
875         switch (mp -> m_type & W_MBOX) {
876             case W_NIL: 
877                 if (!uleq (cp, pp))
878                     continue;
879                 break;
880             case W_MBEG: 
881                 if (!uleq (cp + len - i, pp))
882                     continue;
883                 break;
884             case W_MEND: 
885                 if (!uprf (cp, pp))
886                     continue;
887                 break;
888             case W_MBEG | W_MEND: 
889                 if (stringdex (pp, cp) < 0)
890                     continue;
891                 break;
892         }
893
894         if (mp -> m_nohost)
895             return 1;
896         if (np -> m_host == NULL)
897             continue;
898         if ((len = strlen (cp = np -> m_host))
899                 < (i = strlen (pp = mp -> m_host)))
900             continue;
901         switch (mp -> m_type & W_HOST) {
902             case W_NIL: 
903                 if (!uleq (cp, pp))
904                     continue;
905                 break;
906             case W_HBEG: 
907                 if (!uleq (cp + len - i, pp))
908                     continue;
909                 break;
910             case W_HEND: 
911                 if (!uprf (cp, pp))
912                     continue;
913                 break;
914             case W_HBEG | W_HEND: 
915                 if (stringdex (pp, cp) < 0)
916                     continue;
917                 break;
918         }
919         return 1;
920     }
921 #endif /* not BERK */
922
923     return 0;
924 }
925 @
926
927
928 1.12
929 log
930 @fix ifdefs
931 @
932 text
933 @d3 1
934 a3 1
935 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.11 1992/01/31 21:43:01 jromine Exp jromine $";
936 d185 1
937 a185 1
938             *nxtout++ = isupper (c) ? tolower (c) : c;
939 d247 1
940 a247 1
941             *nxtout++ = isupper (c) ? tolower (c) : c;
942 @
943
944
945 1.11
946 log
947 @kerberos
948 @
949 text
950 @d3 2
951 a4 2
952 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.10 1992/01/30 22:39:48 jromine Exp jromine $";
953 #endif  lint
954 d12 1
955 a12 1
956 #endif  BERK
957 d87 1
958 a87 1
959 #endif  MF
960 d92 1
961 a92 1
962 #else   not BERK
963 d103 1
964 a103 1
965 #endif  not BERK
966 d289 1
967 a289 1
968 #else   not BERK
969 d293 1
970 a293 1
971     err[0] = NULL;
972 d310 1
973 a310 1
974 #endif  not BERK
975 d317 1
976 a317 1
977 #endif  BERK
978 d330 1
979 a330 1
980 #endif  not DUMB
981 d333 2
982 a334 2
983 #endif  MF
984 #endif  not BERK
985 d347 1
986 a347 1
987 #else   not BERK
988 d351 1
989 a351 1
990 #endif  not BERK
991 d373 1
992 a373 1
993 #endif  not BERK
994 d392 1
995 a392 1
996 #else   not BERK
997 d417 1
998 a417 1
999 #else   not MMDFMTS
1000 d426 1
1001 a426 1
1002 #endif  not MMDFMTS
1003 d441 1
1004 a441 1
1005 #endif  MF
1006 d447 1
1007 a447 1
1008             *pp++ = NULL;
1009 d461 1
1010 a461 1
1011 #endif  DUMB
1012 d479 1
1013 a479 1
1014 #else   not DUMB
1015 d497 1
1016 a497 1
1017 #endif  not DUMB
1018 d507 1
1019 a507 1
1020 #endif  not BERK
1021 d537 1
1022 a537 1
1023 #endif  MHMTS
1024 d551 1
1025 a551 1
1026 #endif  MF
1027 d553 1
1028 a553 1
1029 #endif  not BERK
1030 d562 1
1031 a562 1
1032 #else   not BERK
1033 d569 1
1034 a569 1
1035 #else   not MMDFMTS
1036 d571 1
1037 a571 1
1038 #endif  not MMDFMTS
1039 d573 1
1040 a573 1
1041 #endif  MF
1042 d579 1
1043 a579 1
1044 #endif  DUMB
1045 d586 1
1046 a586 1
1047 #endif  not BANG
1048 d606 1
1049 a606 1
1050 #endif  not BERK
1051 d629 1
1052 a629 1
1053 #endif  REALLYDUMB
1054 d636 1
1055 a636 1
1056 #endif  REALLYDUMB
1057 d641 1
1058 a641 1
1059 #else   BANG
1060 d643 1
1061 a643 1
1062 #endif  BANG
1063 d670 1
1064 a670 1
1065 #endif  not BERK
1066 d705 1
1067 a705 1
1068 #else   not BERK
1069 d713 1
1070 a713 1
1071                         mp -> m_type |= W_MEND, *cp = NULL;
1072 d719 1
1073 a719 1
1074                             mp -> m_type |= W_HEND, *cp = NULL;
1075 d725 1
1076 a725 1
1077 #endif  not BERK
1078 d739 1
1079 a739 1
1080 #else   not BERK
1081 d759 1
1082 a759 1
1083 #endif  not BERK
1084 d786 1
1085 a786 1
1086 #else   not BERK
1087 d839 1
1088 a839 1
1089 #endif  not BERK
1090 @
1091
1092
1093 1.10
1094 log
1095 @remove WP
1096 @
1097 text
1098 @d3 1
1099 a3 1
1100 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.9 1992/01/24 19:48:48 jromine Exp jromine $";
1101 d703 1
1102 a703 1
1103                         mp -> m_mbox[mp -> m_ingrp] = NULL;
1104 @
1105
1106
1107 1.9
1108 log
1109 @do_wp gets set to zero by compiler
1110 @
1111 text
1112 @d3 1
1113 a3 1
1114 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.8 1992/01/24 17:58:41 jromine Exp jromine $";
1115 a108 9
1116
1117 #ifdef  WP
1118 int     do_wp;          /* initialized to zero by compiler */
1119
1120 #ifdef  BERK
1121 char   *wp_expand ();
1122 #endif
1123 #endif
1124
1125 a180 29
1126 #ifdef  WP
1127     if (do_wp && c == '<' && *addrs == '<') {
1128         register char  *cp,
1129                        *dp,
1130                        *ep;
1131
1132         if (cp = index (++addrs, '>')) {
1133             *++cp = NULL;
1134             if (dp = wp_expand (addrs, NULLCP)) {
1135                 *(addrs - 1) = NULL;
1136                 ep = concat (saved_addr, dp, cp, NULLCP);
1137                 addrs = ep + strlen (saved_addr);
1138                 while ((c = *addrs++) == ',' || isspace (c))
1139                     continue;
1140                 free (saved_addr);
1141                 saved_addr = ep;
1142                 free (dp);
1143             }
1144             else {
1145                 err = "unable to expand WhitePages query";
1146                 (void) strcpy (adrtext, addrs);
1147                 addrs = cp;
1148                 goto out;
1149             }
1150             
1151         }
1152     }
1153 #endif
1154
1155 a280 3
1156 #ifdef  WP
1157 out: ;
1158 #endif
1159 a282 1
1160 #ifndef WP
1161 a283 1
1162 #endif
1163 a286 1
1164 #ifndef WP
1165 a287 1
1166 #endif
1167 a288 3
1168 #ifdef  WP
1169     return adrtext;
1170 #endif
1171 a842 146
1172
1173 /* \f */
1174
1175 #ifdef  WP
1176 #include <signal.h>
1177
1178
1179 static char *fredproc = NULL;
1180
1181
1182 char   *wp_expand (query, error)
1183 char   *query,
1184        *error;
1185 {
1186     register int    cc,
1187                     i,
1188                     vecp;
1189     TYPESIG     (*istat) (), (*qstat) (), (*pstat) ();
1190     register char  *bp,
1191                    *cp;
1192     char   *ep,
1193             buffer[BUFSIZ],
1194             fds[10],
1195            *vec[10];
1196     static int child_id = NOTOK,
1197             pdi[2],
1198             pdo[2];
1199
1200     if (error)
1201         (void) strcpy (error, "unable to expand WhitePages query: ");
1202
1203     if (child_id == NOTOK || kill (child_id, 0) == NOTOK) {
1204         if (!isatty (fileno (stdout))) {
1205             if (error)
1206                 (void) strcat (error, "not a tty");
1207             return NULLCP;
1208         }
1209
1210         if (fredproc == NULL && (fredproc = m_find ("fredproc")) == NULL)
1211             fredproc = "fred";
1212
1213         if (pipe (pdi) == NOTOK) {
1214             if (error)
1215                 (void) strcat (error, "unable to pipe");
1216
1217             return NULLCP;
1218         }
1219
1220         if (pipe (pdo) == NOTOK) {
1221             if (error)
1222                 (void) strcat (error, "unable to pipe");
1223
1224 losing: ;
1225             (void) close (pdi[0]);
1226             (void) close (pdi[1]);
1227             return NULLCP;
1228         }
1229
1230         for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
1231             sleep (5);
1232
1233         switch (child_id) {
1234             case NOTOK:
1235                 if (error)
1236                     (void) strcat (error, "unable to fork");
1237
1238                 (void) close (pdo[0]);
1239                 (void) close (pdo[1]);
1240                 goto losing;
1241
1242             case OK:
1243                 (void) close (pdi[0]);
1244                 (void) close (pdo[1]);
1245                 (void) sprintf (fds, "%d %d", pdo[0], pdi[1]);
1246                 vecp = 0;
1247                 vec[vecp++] = r1bindex (fredproc, '/');
1248                 vec[vecp++] = "-q";
1249                 vec[vecp++] = fds;
1250                 vec[vecp] = NULL;
1251                 execvp (fredproc, vec);
1252                 _exit (-1);             /* NOTREACHED */
1253
1254             default:
1255                 (void) close (pdi[1]);
1256                 (void) close (pdo[0]);
1257                 break;
1258         }
1259     }
1260
1261     istat = signal (SIGINT, SIG_IGN);
1262     qstat = signal (SIGQUIT, SIG_IGN);
1263
1264     pstat = signal (SIGPIPE, SIG_IGN);
1265
1266     (void) sprintf (buffer, "%s\n", query);
1267     cc = write (pdo[1], buffer, i = strlen (buffer));
1268
1269     (void) signal (SIGPIPE, pstat);
1270
1271     if (cc != i) {
1272         if (error)
1273             (void) strcat (error, "write to pipe failed");
1274
1275 lost_child: ;
1276         (void) kill (child_id, SIGTERM);
1277         (void) close (pdi[0]);
1278         (void) close (pdo[1]);
1279
1280         child_id = NOTOK;
1281         return NULLCP;
1282     }
1283
1284     for (ep = (bp = buffer) + sizeof buffer - 1;
1285              (i = read (pdi[0], bp, ep - bp)) > 0; ) {
1286         for (cp = bp + i; bp < cp; bp++)
1287             if (*bp == '\n')
1288                 break;
1289         if (bp < cp)
1290             break;
1291     }
1292
1293     (void) signal (SIGINT, istat);
1294     (void) signal (SIGQUIT, qstat);
1295
1296     if (i == NOTOK) {
1297         if (error)
1298             (void) strcat (error, "read from pipe failed");
1299         goto lost_child;
1300     }
1301     if (i == 0) {
1302         if (error)
1303             (void) sprintf (error + strlen (error), "%s exited prematurely",
1304                             fredproc);
1305         goto lost_child;
1306     }
1307     *bp = NULL;
1308
1309     if (error)
1310         if (bp != buffer)
1311             error[0]  = NULL;
1312         else
1313             (void) strcpy (error, "unable to expand WhitePages query");
1314
1315     return (*buffer ? getcpy (buffer) : NULLCP);
1316 }
1317 #endif
1318 @
1319
1320
1321 1.8
1322 log
1323 @extern do_wp for shared libs
1324 @
1325 text
1326 @d3 1
1327 a3 1
1328 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.7 1990/11/05 12:26:41 mh Exp jromine $";
1329 d111 1
1330 a111 1
1331 extern int      do_wp;  /* initialized to zero in sbr/addrdef.c */
1332 @
1333
1334
1335 1.7
1336 log
1337 @fix from  Kathleen Sullivan <sullivan@@venera.isi.edu>
1338 @
1339 text
1340 @d3 1
1341 a3 1
1342 static char ident[] = "@@(#)$Id: addrsbr.c,v 1.6 90/04/05 15:31:05 sources Exp Locker: mh $";
1343 d111 1
1344 a111 1
1345 int     do_wp = 0;
1346 @
1347
1348
1349 1.6
1350 log
1351 @add ID
1352 @
1353 text
1354 @d3 1
1355 a3 1
1356 static char ident[] = "@@(#)$Id:$";
1357 d836 2
1358 d862 2
1359 @
1360
1361
1362 1.5
1363 log
1364 @add ID
1365 @
1366 text
1367 @d3 1
1368 a3 1
1369 static char ident[] = "$Id:";
1370 @
1371
1372
1373 1.4
1374 log
1375 @TYPESIG fix
1376 @
1377 text
1378 @d2 3
1379 @
1380
1381
1382 1.3
1383 log
1384 @don't consider newline part of mbox -- Van Jacobson fix
1385 @
1386 text
1387 @d901 1
1388 a901 1
1389     int     (*istat) (), (*qstat) (), (*pstat) ();
1390 @
1391
1392
1393 1.2
1394 log
1395 @WP changes
1396 @
1397 text
1398 @d139 1
1399 a139 1
1400      * In detail, `,' or newline terminate addresses.  "Empty" addresses
1401 d150 2
1402 a151 2
1403      * non-comment text.  Blanks & tabs will not be included in the mailbox
1404      * portion of an address unless they are escaped.
1405 d174 4
1406 d223 8
1407 a284 1
1408         case NORMAL+'\n':
1409 a285 1
1410         case ERR+'\n':
1411 a293 1
1412         case COM+'\n':
1413 a300 1
1414         case QS+'\n':
1415 @
1416
1417
1418 1.1
1419 log
1420 @Initial revision
1421 @
1422 text
1423 @d106 9
1424 d183 29
1425 d308 3
1426 d313 1
1427 d315 1
1428 d319 1
1429 d321 1
1430 d323 3
1431 d876 146
1432 @