]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/sbr/addrsbr.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / sbr / addrsbr.c
1 /* addrsbr.c - parse addresses 822-style */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: addrsbr.c,v 1.13 1992/10/26 22:44:26 jromine Exp $";
4 #endif /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/addrsbr.h"
8 #include "../zotnet/mf.h"
9 #include <stdio.h>
10 #ifdef BERK
11 #include <ctype.h>
12 #endif /* BERK */
13
14 /* High level parsing of addresses:
15
16 The routines in zotnet/mf/mf.c parse the syntactic representations of
17 addresses. The routines in sbr/addrsbr.c associate semantics with those
18 addresses.
19
20 If #ifdef BERK is in effect, the routines in mf.c aren't called and only
21 the most rudimentary syntax parse is done. The parse is not 822-conformant.
22 This causes problems as there is no semantics associated with the address
23 at all--it's just a string. (the author of the BERK code disagrees with
24 the preceding, of course. BERK solves problems for incoming mail
25 because it will accept damn near any address. BERK was intended to be
26 used when spost is the interface to the mail delivery system which means
27 all outgoing address interpretation is left to sendmail. It is possible,
28 though unlikely, for BERK address parsing to interact poorly with
29 "post". - van@monet.berkeley.edu).
30
31 Instead, if #ifdef DUMB is in effect, a full 822-style parser is called
32 for syntax recongition. This breaks each address into its components.
33 Note however that no semantics are assumed about the parts or their
34 totality. This means that implicit hostnames aren't made explicit,
35 and explicit hostnames aren't expanded to their "official" represenations.
36
37 If neither BERK nor DUMB is in effect, then this module does some
38 high-level thinking about what the addresses are. If #ifdef MF is in
39 effect, then MH will deduce UUCP-style addressing masquerading as
40 822-style addresses.
41
42 1. for MMDF systems:
43
44 string%<uucp>@<local> -> string
45
46 2. for non-MMDF systems:
47
48 string@host.<uucp> -> host!string
49
50 3. for any system, an address interpreted relative to the local host:
51
52 string@<uucp> -> string
53
54 For cases (1) and (3) above, the leftmost host is extracted. If it's not
55 present, the local host is used. If #ifdef MF is not in effect or the
56 tests above fail, the address is considered to be a real 822-style address.
57
58 If an explicit host is not present, then MH checks for a bang to indicate
59 an explicit UUCP-style address. If so, this is noted. If not, the host is
60 defaulted, typically to the local host. The lack of an explict host is
61 also noted.
62
63 If an explicit 822-style host is present, then MH checks to see if it
64 can expand this to the official name for the host. If the hostname is
65 unknown, the address is so typed.
66
67 To summarize, when we're all done, here's what MH knows about the address:
68
69 BERK - type: local
70 nohost: set if no '@' or '!' in mailbox
71 text: exact copy of address
72 mbox: lowercase version of mailbox
73
74 DUMB - type: local, uucp, or network
75 host: not locally defaulted, not explicitly expanded
76 everything else
77
78 other - type: local, uucp, network, unknown
79 everything else
80 */
81
82 /* \f */
83
84 #if !defined(DUMB) && defined(SENDMTS) && !defined(BANG)
85 #define MF
86 #define UucpChan() "UUCP"
87 #endif /* MF */
88
89 #ifdef BERK
90 static char *err = NULL;
91 static char adrtext[BUFSIZ];
92 #else /* not BERK */
93 static int ingrp = 0;
94
95 static char *pers = NULL;
96 static char *mbox = NULL;
97 static char *host = NULL;
98 static char *route = NULL;
99 static char *grp = NULL;
100 static char *note = NULL;
101
102 static char err[BUFSIZ];
103 #endif /* not BERK */
104 static char adr[BUFSIZ];
105
106
107 char *getusr ();
108
109 /* \f */
110
111 char *getname (addrs)
112 register char *addrs;
113 {
114 #ifdef BERK
115 /*
116 * Berkeley uses a very simple parser since Sendmail does all the work.
117 * The only thing that does address parsing if BERK is defined is the
118 * routine "ismybox" used by "scan" & "repl" to identify the current
119 * users maildrop.
120 *
121 * This routine does essentially the same address interpretation as the
122 * routine "prescan" in "sendmail". The intent is that MH should
123 * make minimum assumptions about address forms since it doesn't
124 * have access to the information in the sendmail config file
125 * (God forbid that anything but sendmail has to deal with a sendmail
126 * config file) and, therefore, hasn't the faintest idea of what will
127 * or won't be a legal address.
128 *
129 * Since this parse is only used by "ismybox" and repl, it just does
130 * two things: split multiple addr on a line into separate addresses and
131 * locate the "mailbox" portion of an address. The parse uses rfc-822
132 * metacharacters and quoting but is much less restrictive that rfc-822.
133 * In detail, `,' or eos terminate addresses. "Empty" addresses
134 * (e.g., `,,') are ignored. Double quote ("), backslash, left & right
135 * paren and left and right angle brackets are metacharacters. Left &
136 * right parens must balance as must left & right angle brackets. Any
137 * metacharacter may be escaped by preceding it with a backslash.
138 * Any text between parens is considered a comment and ignored (i.e.,
139 * only `(', `)' and `\' are metacharacters following a `('). Text
140 * between double quotes is considered escaped (i.e., only `"' and
141 * `\' are metacharacters following a `"'). The `mailbox' portion
142 * of an address is the non-comment text between angle-brackets if
143 * the address contains any angle brackets. Otherwise, it is all the
144 * non-comment text. Blanks, tabs & newlines will not be included
145 * in the mailbox portion of an address unless they are escaped.
146 */
147
148 /* Scanner states */
149 #define NORMAL (0<<8)
150 #define QS (1<<8) /* in quoted string */
151 #define COM (2<<8) /* in comment (...) */
152 #define ERR (3<<8) /* found an error */
153 #define EOA (4<<8) /* end of address */
154
155 static char *saved_addr = NULL; /* saved address line ptr */
156 static char *adr_ptr = NULL; /* where to start looking for
157 next address on line */
158 register char *nxtout = adr; /* where to put next character of
159 `mailbox' part of address */
160 register char c;
161 register int state = NORMAL;
162 register char *adrcopy = adrtext; /* where to put next character of
163 address */
164 register int lbcnt = 0; /* number of unmatched "(" */
165 register int lpcnt = 0; /* number of unmatched "<" */
166
167 err = NULL;
168 if (! addrs) {
169 adr_ptr = NULL;
170 return NULL;
171 }
172 if (adr_ptr)
173 addrs = adr_ptr;
174 else
175 addrs = saved_addr = getcpy(addrs ? addrs : "");
176
177 /* skip any leading whitespace or commas. */
178 while ( (c = *addrs++) == ',' || isspace(c))
179 ;
180
181 *nxtout = *adrcopy = '\0';
182 while (state != EOA) {
183 *adrcopy++ = c;
184 if (state != COM)
185 *nxtout++ = (isalpha(c) && isupper (c)) ? tolower (c) : c;
186 switch (state+c) {
187
188 case NORMAL+'\n': /* discard newlines */
189 case QS+'\n':
190 case COM+'\n':
191 case ERR+'\n':
192 --nxtout;
193 --adrcopy;
194 break;
195
196 case NORMAL+' ': /* skip unquoted whitespace */
197 case NORMAL+'\t':
198 --nxtout;
199 break;
200
201 case NORMAL+'"': /* start quoted string */
202 state = QS;
203 break;
204
205 case QS+'"': /* end quoted string */
206 state = NORMAL;
207 break;
208
209 case NORMAL+'<':
210 nxtout = adr; /* start over accumulating address */
211 lbcnt++;
212 break;
213
214 case NORMAL+'>':
215 --lbcnt;
216 if (lbcnt < 0) {
217 state = ERR;
218 err = "extra >";
219 } else
220 *(nxtout-1) = '\0';
221 break;
222
223 case NORMAL+'(':
224 state = COM;
225 --nxtout;
226 case COM+'(':
227 lpcnt++;
228 break;
229
230 case COM+')':
231 --lpcnt;
232 if (lpcnt < 0) {
233 state = ERR;
234 err = "extra )";
235 } else if (lpcnt == 0)
236 state = NORMAL;
237 break;
238
239 case NORMAL+'\\':
240 case QS+'\\':
241 case COM+'\\':
242 if ((c = *addrs++) == '\n' || c == '\0') {
243 state = EOA;
244 err = "illegal \\";
245 }
246 *adrcopy++ = c;
247 *nxtout++ = (isalpha(c) && isupper (c)) ? tolower (c) : c;
248 break;
249
250 case NORMAL+',':
251 case ERR+',':
252 case NORMAL+'\0':
253 case ERR+'\0':
254 state = EOA;
255 if (lbcnt)
256 err = "missing >";
257 break;
258
259 case COM+'\0':
260 state = EOA;
261 err = "missing )";
262 if (nxtout == adr)
263 nxtout++;
264 break;
265
266 case QS+'\0':
267 state = EOA;
268 err = "missing \"";
269 break;
270 }
271 if (c != '\0')
272 c = *addrs++;
273 }
274 /*
275 * at this point adr contains the `mailbox' part of the address
276 * in lower case & minus any comment or unquoted whitespace.
277 * adrtext contains an exact copy of the address and
278 * addr points to where we should start scanning next time.
279 */
280 *(nxtout-1) = *(adrcopy-1) = '\0';
281 if (*adr && !err) {
282 adr_ptr = addrs-1;
283 return adrtext;
284 } else {
285 free (saved_addr);
286 adr_ptr = NULL;
287 return NULL;
288 }
289 #else /* not BERK */
290 register struct adrx *ap;
291
292 pers = mbox = host = route = grp = note = NULL;
293 err[0] = '\0';
294
295 if ((ap = getadrx (addrs ? addrs : "")) == NULL)
296 return NULL;
297
298 (void) strcpy (adr, ap -> text);
299 pers = ap -> pers;
300 mbox = ap -> mbox;
301 host = ap -> host;
302 route = ap -> path;
303 grp = ap -> grp;
304 ingrp = ap -> ingrp;
305 note = ap -> note;
306 if (ap -> err && *ap -> err)
307 (void) strcpy (err, ap -> err);
308
309 return adr;
310 #endif /* not BERK */
311 }
312
313 /* \f */
314
315 #ifdef BERK
316 /* ARGSUSED */
317 #endif /* BERK */
318
319 struct mailname *getm (str, dfhost, dftype, wanthost, eresult)
320 register char *str,
321 *eresult;
322 char *dfhost;
323 int dftype,
324 wanthost;
325 {
326 #ifndef BERK
327 register char *pp;
328 #ifndef DUMB
329 register char *dp;
330 #endif /* not DUMB */
331 #ifdef MF
332 char *up = UucpChan ();
333 #endif /* MF */
334 #endif /* not BERK */
335 register struct mailname *mp;
336
337 if (err && err[0]) {
338 if (eresult)
339 (void) strcpy (eresult, err);
340 else
341 if (wanthost == AD_HOST)
342 admonish (NULLCP, "bad address '%s' - %s", str, err);
343 return NULL;
344 }
345 #ifdef BERK
346 if (str == NULL || *str == '\0') {
347 #else /* not BERK */
348 if (pers == NULL
349 && mbox == NULL && host == NULL && route == NULL
350 && grp == NULL) {
351 #endif /* not BERK */
352 if (eresult)
353 (void) strcpy (eresult, "null address");
354 else
355 if (wanthost == AD_HOST)
356 admonish (NULLCP, "null address '%s'", str);
357 return NULL;
358 }
359 #ifndef BERK
360 if (mbox == NULL && grp == NULL) {
361 if (eresult)
362 (void) strcpy (eresult, "no mailbox in address");
363 else
364 if (wanthost == AD_HOST)
365 admonish (NULLCP, "no mailbox in address '%s'", str);
366 return NULL;
367 }
368
369 if (dfhost == NULL) {
370 dfhost = LocalName ();
371 dftype = LOCALHOST;
372 }
373 #endif /* not BERK */
374
375 mp = (struct mailname *) calloc ((unsigned) 1, sizeof *mp);
376 if (mp == NULL) {
377 if (eresult)
378 (void) strcpy (eresult, "insufficient memory to represent address");
379 else
380 if (wanthost == AD_HOST)
381 adios (NULLCP, "insufficient memory to represent address");
382 return NULL;
383 }
384
385 mp -> m_next = NULL;
386 mp -> m_text = getcpy (str);
387 #ifdef BERK
388 mp -> m_type = LOCALHOST;
389 mp -> m_mbox = getcpy (adr);
390 if (!index (adr, '@') && !index (adr, '!'))
391 mp -> m_nohost = 1;
392 #else /* not BERK */
393 if (pers)
394 mp -> m_pers = getcpy (pers);
395
396 if (mbox == NULL) {
397 mp -> m_type = BADHOST;
398 mp -> m_nohost = 1;
399 mp -> m_ingrp = ingrp;
400 mp -> m_gname = getcpy (grp);
401 if (note)
402 mp -> m_note = getcpy (note);
403 return mp;
404 }
405
406 /* \f */
407
408 if (host) {
409 #ifdef MF
410 #ifdef MMDFMTS
411 if (up && uleq (host, LocalName ())
412 && (pp = rindex (mbox, '%'))
413 && uleq (up, pp + 1)) {/* uucpaddr%<uucp>@<local> */
414 *pp = NULL;
415 goto get_uucp;
416 }
417 #else /* not MMDFMTS */
418 if (up && (pp = index (host, '.'))
419 && uleq (up, pp + 1)) {/* uucpaddr@host.<uucp> */
420 *pp = NULL;
421 mp -> m_host = getcpy (host);
422 mp -> m_mbox = getcpy (mbox);
423 mp -> m_type = UUCPHOST;
424 goto got_host;
425 }
426 #endif /* not MMDFMTS */
427 if (up && uleq (dfhost, LocalName ())
428 && uleq (up, host)) {/* uucpaddr@<uucp> [local] */
429 if (pp = index (mbox, '!')) {
430 *pp++ = NULL;
431 mp -> m_host = getcpy (mbox);
432 mp -> m_mbox = getcpy (pp);
433 }
434 else {
435 mp -> m_host = getcpy (SystemName ());
436 mp -> m_mbox = getcpy (mbox);
437 }
438 mp -> m_type = UUCPHOST;
439 goto got_host;
440 }
441 #endif /* MF */
442 mp -> m_mbox = getcpy (mbox);
443 mp -> m_host = getcpy (host);
444 }
445 else {
446 if (pp = index (mbox, '!')) {
447 *pp++ = '\0';
448 mp -> m_mbox = getcpy (pp);
449 mp -> m_host = getcpy (mbox);
450 mp -> m_type = UUCPHOST;
451 }
452 else {
453 mp -> m_nohost = 1;
454 mp -> m_mbox = getcpy (mbox);
455 #ifdef DUMB
456 if (route == NULL && dftype == LOCALHOST) {
457 mp -> m_host = NULLCP;
458 mp -> m_type = dftype;
459 }
460 else
461 #endif /* DUMB */
462 {
463 mp -> m_host = route ? NULLCP : getcpy (dfhost);
464 mp -> m_type = route ? NETHOST : dftype;
465 }
466 }
467 goto got_host;
468 }
469
470 /* \f */
471
472 if (wanthost == AD_NHST)
473 mp -> m_type = uleq (LocalName (), mp -> m_host)
474 ? LOCALHOST : NETHOST;
475 #ifdef DUMB
476 else
477 mp -> m_type = uleq (LocalName (), mp -> m_host) ? LOCALHOST
478 : NETHOST;
479 #else /* not DUMB */
480 else
481 if (pp = OfficialName (mp -> m_host)) {
482 got_real_host: ;
483 free (mp -> m_host);
484 mp -> m_host = getcpy (pp);
485 mp -> m_type = uleq (LocalName (), mp -> m_host) ? LOCALHOST
486 : NETHOST;
487 }
488 else {
489 if (dp = index (mp -> m_host, '.')) {
490 *dp = NULL;
491 if (pp = OfficialName (mp -> m_host))
492 goto got_real_host;
493 *dp = '.';
494 }
495 mp -> m_type = BADHOST;
496 }
497 #endif /* not DUMB */
498
499 got_host: ;
500 if (route)
501 mp -> m_path = getcpy (route);
502 mp -> m_ingrp = ingrp;
503 if (grp)
504 mp -> m_gname = getcpy (grp);
505 if (note)
506 mp -> m_note = getcpy (note);
507 #endif /* not BERK */
508
509 return mp;
510 }
511
512 /* \f */
513
514 void mnfree (mp)
515 register struct mailname *mp;
516 {
517 if (!mp)
518 return;
519
520 if (mp -> m_text)
521 free (mp -> m_text);
522 if (mp -> m_pers)
523 free (mp -> m_pers);
524 if (mp -> m_mbox)
525 free (mp -> m_mbox);
526 if (mp -> m_host)
527 free (mp -> m_host);
528 if (mp -> m_path)
529 free (mp -> m_path);
530 if (mp -> m_gname)
531 free (mp -> m_gname);
532 if (mp -> m_note)
533 free (mp -> m_note);
534 #ifdef MHMTS
535 if (mp -> m_aka)
536 free (mp -> m_aka);
537 #endif /* MHMTS */
538
539 free ((char *) mp);
540 }
541
542 /* \f */
543
544 char *auxformat (mp, extras)
545 register struct mailname *mp;
546 int extras;
547 {
548 #ifndef BERK
549 #ifdef MF
550 char *up = UucpChan ();
551 #endif /* MF */
552 static char addr[BUFSIZ];
553 #endif /* not BERK */
554 static char buffer[BUFSIZ];
555
556 #ifdef BERK
557 /* this "if" is a crufty hack to handle "visible" aliases */
558 if (mp->m_pers && !extras)
559 (void) sprintf (buffer, "%s <%s>", mp->m_pers, mp->m_mbox);
560 else
561 (void) strcpy (buffer, mp -> m_text);
562 #else /* not BERK */
563
564 #ifdef MF
565 if (up && mp -> m_type == UUCPHOST)
566 #ifdef MMDFMTS
567 (void) sprintf (addr, "%s!%s%%%s@%s", mp -> m_host, mp -> m_mbox,
568 up, LocalName ());
569 #else /* not MMDFMTS */
570 (void) sprintf (addr, "%s@%s.%s", mp -> m_mbox, mp -> m_host, up);
571 #endif /* not MMDFMTS */
572 else
573 #endif /* MF */
574
575 #ifdef DUMB
576 if (mp -> m_nohost)
577 (void) strcpy (addr, mp -> m_mbox ? mp -> m_mbox : "");
578 else
579 #endif /* DUMB */
580
581 #ifndef BANG
582 if (mp -> m_type != UUCPHOST)
583 (void) sprintf (addr, mp -> m_host ? "%s%s@%s" : "%s%s",
584 mp -> m_path ? mp -> m_path : "", mp -> m_mbox, mp -> m_host);
585 else
586 #endif /* not BANG */
587 (void) sprintf (addr, "%s!%s", mp -> m_host, mp -> m_mbox);
588
589 if (!extras)
590 return addr;
591
592 if (mp -> m_pers || mp -> m_path)
593 if (mp -> m_note)
594 (void) sprintf (buffer, "%s %s <%s>",
595 legal_person (mp -> m_pers ? mp -> m_pers : mp -> m_mbox),
596 mp -> m_note, addr);
597 else
598 (void) sprintf (buffer, "%s <%s>",
599 legal_person (mp -> m_pers ? mp -> m_pers : mp -> m_mbox),
600 addr);
601 else
602 if (mp -> m_note)
603 (void) sprintf (buffer, "%s %s", addr, mp -> m_note);
604 else
605 (void) strcpy (buffer, addr);
606 #endif /* not BERK */
607
608 return buffer;
609 }
610
611 /* \f */
612
613 #if defined(BERK) || (defined(DUMB) && !defined(MMDFMTS) && !defined(SMTP))
614 #define REALLYDUMB
615 #else
616 #undef REALLYDUMB
617 #endif
618
619 char *adrsprintf (local, domain)
620 char *local,
621 *domain;
622 {
623 static char addr[BUFSIZ];
624
625 if (local == NULL)
626 #ifdef REALLYDUMB
627 return getusr ();
628 else
629 #endif /* REALLYDUMB */
630 local = getusr ();
631
632 if (domain == NULL)
633 #ifdef REALLYDUMB
634 return local;
635 else
636 #endif /* REALLYDUMB */
637 domain = LocalName ();
638
639 #ifndef BANG
640 (void) sprintf (addr, "%s@%s", local, domain);
641 #else /* BANG */
642 (void) sprintf (addr, "%s!%s", domain, local);
643 #endif /* BANG */
644
645 return addr;
646 }
647
648 /* \f */
649
650 #define W_NIL 0x0000
651 #define W_MBEG 0x0001
652 #define W_MEND 0x0002
653 #define W_MBOX (W_MBEG | W_MEND)
654 #define W_HBEG 0x0004
655 #define W_HEND 0x0008
656 #define W_HOST (W_HBEG | W_HEND)
657 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
658
659
660 int ismymbox (np)
661 register struct mailname *np;
662 {
663 int oops;
664 register int len,
665 i;
666 register char *cp;
667 #ifndef BERK
668 register char *pp;
669 char buffer[BUFSIZ];
670 #endif /* not BERK */
671 register struct mailname *mp;
672 static char *am = NULL;
673 static struct mailname mq={NULL};
674
675 /* if this is the first call, init. alternate mailboxes list */
676 if (am == NULL) {
677 mq.m_next = NULL;
678 mq.m_mbox = getusr ();
679 if ((am = m_find ("alternate-mailboxes")) == NULL)
680 am = getusr ();
681 else {
682 mp = &mq;
683 oops = 0;
684 while (cp = getname (am))
685 if ((mp -> m_next = getm (cp, NULLCP, 0, AD_NAME, NULLCP))
686 == NULL)
687 admonish (NULLCP, "illegal address: %s", cp), oops++;
688 else {
689 mp = mp -> m_next;
690 mp -> m_type = W_NIL;
691 #ifdef BERK
692 /* check for wildcards on the mailbox name and
693 set m_type accordingly. */
694 mp -> m_ingrp = strlen (mp -> m_mbox);
695 if (*(mp -> m_mbox) == '*') {
696 mp -> m_type |= W_MBEG;
697 mp -> m_mbox++;
698 --mp -> m_ingrp;
699 }
700 if (mp -> m_mbox[mp -> m_ingrp - 1] == '*') {
701 mp -> m_type |= W_MEND;
702 mp -> m_ingrp--;
703 mp -> m_mbox[mp -> m_ingrp] = 0;
704 }
705 #else /* not BERK */
706 /* owing to screwy munging, wildcarding is a great idea
707 even under #ifndef BERK, so... */
708 mp -> m_type = W_NIL;
709 if (*mp -> m_mbox == '*')
710 mp -> m_type |= W_MBEG, mp -> m_mbox++;
711 if (*(cp = mp -> m_mbox + strlen (mp -> m_mbox) - 1)
712 == '*')
713 mp -> m_type |= W_MEND, *cp = '\0';
714 if (mp -> m_host) {
715 if (*mp -> m_host == '*')
716 mp -> m_type |= W_HBEG, mp -> m_host++;
717 if (*(cp = mp -> m_host + strlen (mp -> m_host) - 1)
718 == '*')
719 mp -> m_type |= W_HEND, *cp = '\0';
720 }
721 if ((cp = getenv ("MHWDEBUG")) && *cp)
722 fprintf (stderr, "mbox=\"%s\" host=\"%s\" %s\n",
723 mp -> m_mbox, mp -> m_host,
724 sprintb (buffer, (unsigned) mp -> m_type, WBITS));
725 #endif /* not BERK */
726 }
727 if (oops)
728 advise (NULLCP, "please fix the %s: entry in your %s file",
729 "alternate-mailboxes", mh_profile);
730 }
731 }
732 if (np == NULL) /* XXX */
733 return 0;
734
735 #ifdef BERK
736 cp = np -> m_mbox;
737 if (strcmp (cp, mq.m_mbox) == 0)
738 return 1;
739 #else /* not BERK */
740 switch (np -> m_type) {
741 case NETHOST:
742 len = strlen (cp = LocalName ());
743 if (!uprf (np -> m_host, cp) || np -> m_host[len] != '.')
744 break;
745 goto local_test;
746
747 case UUCPHOST:
748 if (!uleq (np -> m_host, SystemName ()))
749 break; /* fall */
750 case LOCALHOST:
751 local_test: ;
752 if (uleq (np -> m_mbox, mq.m_mbox))
753 return 1;
754 break;
755
756 default:
757 break;
758 }
759 #endif /* not BERK */
760
761 #ifdef BERK
762 len = strlen (cp);
763 for (mp = &mq; mp = mp -> m_next;)
764 if (len >= mp -> m_ingrp)
765 switch (mp -> m_type) {
766 case W_NIL: /* no wildcards */
767 if (strcmp (cp, mp -> m_mbox) == 0)
768 return 1;
769 break;
770
771 case W_MBEG: /* wildcard at beginning */
772 if (strcmp (&cp[len - mp -> m_ingrp], mp -> m_mbox) == 0)
773 return 1;
774 break;
775
776 case W_MEND: /* wildcard at end */
777 if (strncmp (cp, mp -> m_mbox, mp -> m_ingrp) == 0)
778 return 1;
779 break;
780
781 case W_MBEG | W_MEND: /* wildcard at beginning & end */
782 for (i = 0; i <= len - mp -> m_ingrp; i++)
783 if (strncmp (&cp[i], mp -> m_mbox, mp -> m_ingrp) == 0)
784 return 1;
785 }
786 #else /* not BERK */
787 for (mp = &mq; mp = mp -> m_next;) {
788 if (np -> m_mbox == NULL)
789 continue;
790 if ((len = strlen (cp = np -> m_mbox))
791 < (i = strlen (pp = mp -> m_mbox)))
792 continue;
793 switch (mp -> m_type & W_MBOX) {
794 case W_NIL:
795 if (!uleq (cp, pp))
796 continue;
797 break;
798 case W_MBEG:
799 if (!uleq (cp + len - i, pp))
800 continue;
801 break;
802 case W_MEND:
803 if (!uprf (cp, pp))
804 continue;
805 break;
806 case W_MBEG | W_MEND:
807 if (stringdex (pp, cp) < 0)
808 continue;
809 break;
810 }
811
812 if (mp -> m_nohost)
813 return 1;
814 if (np -> m_host == NULL)
815 continue;
816 if ((len = strlen (cp = np -> m_host))
817 < (i = strlen (pp = mp -> m_host)))
818 continue;
819 switch (mp -> m_type & W_HOST) {
820 case W_NIL:
821 if (!uleq (cp, pp))
822 continue;
823 break;
824 case W_HBEG:
825 if (!uleq (cp + len - i, pp))
826 continue;
827 break;
828 case W_HEND:
829 if (!uprf (cp, pp))
830 continue;
831 break;
832 case W_HBEG | W_HEND:
833 if (stringdex (pp, cp) < 0)
834 continue;
835 break;
836 }
837 return 1;
838 }
839 #endif /* not BERK */
840
841 return 0;
842 }