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