]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/sbr/RCS/addrsbr.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / 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 @