Annotation of 43BSD/contrib/mh/sbr/addrsbr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.