X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Faddrsbr.c;h=db5b42e67d33d35f2618c4c571e79f28bfc8410a;hp=4ab3feced82bac18d538fff366d04836deea6d84;hb=ee8d01d64e8832304256de53db07228e2be67f6a;hpb=a485ed478abbd599d8c9aab48934e7a26733ecb1 diff --git a/sbr/addrsbr.c b/sbr/addrsbr.c index 4ab3fec..db5b42e 100644 --- a/sbr/addrsbr.c +++ b/sbr/addrsbr.c @@ -1,65 +1,35 @@ /* - * addrsbr.c -- parse addresses 822-style - * - * This code is Copyright (c) 2002, by the authors of nmh. See the - * COPYRIGHT file in the root directory of the nmh distribution for - * complete copyright information. - */ - +** addrsbr.c -- parse addresses 822-style +** +** This code is Copyright (c) 2002, by the authors of nmh. See the +** COPYRIGHT file in the root directory of the nmh distribution for +** complete copyright information. +*/ + +#include #include +#include #include #include /* - * High level parsing of addresses: - * - * The routines in sbr/mf.c parse the syntactic representations of - * addresses. The routines in sbr/addrsbr.c associate semantics with those - * addresses. - * - * If #ifdef DUMB is in effect, a full 822-style parser is called - * for syntax recongition. This breaks each address into its components. - * Note however that no semantics are assumed about the parts or their - * totality. This means that implicit hostnames aren't made explicit, - * and explicit hostnames aren't expanded to their "official" represenations. - * - * If DUMB is not in effect, then this module does some - * high-level thinking about what the addresses are. - * - * 1. for MMDF systems: - * - * string%@ -> string - * - * 2. for non-MMDF systems: - * - * string@host. -> host!string - * - * 3. for any system, an address interpreted relative to the local host: - * - * string@ -> string - * - * For cases (1) and (3) above, the leftmost host is extracted. If it's not - * present, the local host is used. If the tests above fail, the address is - * considered to be a real 822-style address. - * - * If an explicit host is not present, then MH checks for a bang to indicate - * an explicit UUCP-style address. If so, this is noted. If not, the host is - * defaulted, typically to the local host. The lack of an explict host is - * also noted. - * - * If an explicit 822-style host is present, then MH checks to see if it - * can expand this to the official name for the host. If the hostname is - * unknown, the address is so typed. - * - * To summarize, when we're all done, here's what MH knows about the address: - * - * DUMB - type: local, uucp, or network - * host: not locally defaulted, not explicitly expanded - * everything else - * - * other - type: local, uucp, network, unknown - * everything else - */ +** High level parsing of addresses: +** +** The routines in sbr/mf.c parse the syntactic representations of +** addresses. The routines in sbr/addrsbr.c associate semantics with those +** addresses. +** +** A full 822-style parser is called for syntax recongition. This breaks +** each address into its components. Note however that no semantics are +** assumed about the parts or their totality. This means that implicit +** hostnames aren't made explicit, and explicit hostnames aren't expanded +** to their "official" represenations. +** +** To summarize, when we're all done, here's what MH knows about the address: +** type: local or network +** host: not locally defaulted, not explicitly expanded +** everything else +*/ static int ingrp = 0; @@ -73,27 +43,18 @@ static char err[BUFSIZ]; static char adr[BUFSIZ]; -extern boolean username_extension_masquerading; /* defined in mts.c */ - - -/* - * external prototypes - */ -char *getusername (void); - - char * -getname (char *addrs) +getname(char *addrs) { struct adrx *ap; pers = mbox = host = route = grp = note = NULL; err[0] = '\0'; - if ((ap = getadrx (addrs ? addrs : "")) == NULL) + if ((ap = getadrx(addrs ? addrs : "")) == NULL) return NULL; - strncpy (adr, ap->text, sizeof(adr)); + strncpy(adr, ap->text, sizeof(adr)); pers = ap->pers; mbox = ap->mbox; host = ap->host; @@ -102,265 +63,163 @@ getname (char *addrs) ingrp = ap->ingrp; note = ap->note; if (ap->err && *ap->err) - strncpy (err, ap->err, sizeof(err)); + strncpy(err, ap->err, sizeof(err)); return adr; } struct mailname * -getm (char *str, char *dfhost, int dftype, int wanthost, char *eresult) +getm(char *str, char *dfhost, int dftype, int wanthost, char *eresult) { - char *pp; struct mailname *mp; -#ifndef DUMB - char *dp; -#endif /* not DUMB */ if (err[0]) { if (eresult) - strcpy (eresult, err); + strcpy(eresult, err); else if (wanthost == AD_HOST) - admonish (NULL, "bad address '%s' - %s", str, err); + admonish(NULL, "bad address '%s' - %s", str, err); return NULL; } if (pers == NULL && mbox == NULL && host == NULL && route == NULL && grp == NULL) { if (eresult) - strcpy (eresult, "null address"); + strcpy(eresult, "null address"); else if (wanthost == AD_HOST) - admonish (NULL, "null address '%s'", str); + admonish(NULL, "null address '%s'", str); return NULL; } if (mbox == NULL && grp == NULL) { if (eresult) - strcpy (eresult, "no mailbox in address"); + strcpy(eresult, "no mailbox in address"); else if (wanthost == AD_HOST) - admonish (NULL, "no mailbox in address '%s'", str); + admonish(NULL, "no mailbox in address '%s'", str); return NULL; } if (dfhost == NULL) { - dfhost = LocalName (); + dfhost = LocalName(); dftype = LOCALHOST; } - mp = (struct mailname *) calloc ((size_t) 1, sizeof(*mp)); + mp = mh_xcalloc(1, sizeof(*mp)); if (mp == NULL) { if (eresult) - strcpy (eresult, "insufficient memory to represent address"); + strcpy(eresult, "insufficient memory to represent address"); else if (wanthost == AD_HOST) - adios (NULL, "insufficient memory to represent address"); + adios(EX_OSERR, NULL, "insufficient memory to represent address"); return NULL; } mp->m_next = NULL; - mp->m_text = getcpy (str); + mp->m_text = mh_xstrdup(str); if (pers) - mp->m_pers = getcpy (pers); + mp->m_pers = mh_xstrdup(pers); if (mbox == NULL) { mp->m_type = BADHOST; mp->m_nohost = 1; mp->m_ingrp = ingrp; - mp->m_gname = getcpy (grp); + mp->m_gname = mh_xstrdup(grp); if (note) - mp->m_note = getcpy (note); + mp->m_note = mh_xstrdup(note); return mp; } if (host) { - mp->m_mbox = getcpy (mbox); - mp->m_host = getcpy (host); + mp->m_mbox = mh_xstrdup(mbox); + mp->m_host = mh_xstrdup(host); } else { - if ((pp = strchr(mbox, '!'))) { - *pp++ = '\0'; - mp->m_mbox = getcpy (pp); - mp->m_host = getcpy (mbox); - mp->m_type = UUCPHOST; + mp->m_nohost = 1; + mp->m_mbox = mh_xstrdup(mbox); + if (route == NULL && dftype == LOCALHOST) { + mp->m_host = NULL; + mp->m_type = dftype; } else { - mp->m_nohost = 1; - mp->m_mbox = getcpy (mbox); -#ifdef DUMB - if (route == NULL && dftype == LOCALHOST) { - mp->m_host = NULL; - mp->m_type = dftype; - } else -#endif /* DUMB */ - { - mp->m_host = route ? NULL : getcpy (dfhost); - mp->m_type = route ? NETHOST : dftype; - } + mp->m_host = route ? NULL : mh_xstrdup(dfhost); + mp->m_type = route ? NETHOST : dftype; } goto got_host; } if (wanthost == AD_NHST) - mp->m_type = !mh_strcasecmp (LocalName (), mp->m_host) + mp->m_type = !mh_strcasecmp(LocalName(), mp->m_host) ? LOCALHOST : NETHOST; -#ifdef DUMB - else - mp->m_type = mh_strcasecmp (LocalName(), mp->m_host) ? NETHOST : LOCALHOST; -#else /* not DUMB */ else - if (pp = OfficialName (mp->m_host)) { - got_real_host: ; - free (mp->m_host); - mp->m_host = getcpy (pp); - mp->m_type = mh_strcasecmp (LocalName(), mp->m_host) ? NETHOST : LOCALHOST; - } else { - if (dp = strchr(mp->m_host, '.')) { - *dp = NULL; - if (pp = OfficialName (mp->m_host)) - goto got_real_host; - *dp = '.'; - } - mp->m_type = BADHOST; - } -#endif /* not DUMB */ + mp->m_type = mh_strcasecmp(LocalName(), mp->m_host) ? NETHOST : LOCALHOST; got_host: ; if (route) - mp->m_path = getcpy (route); + mp->m_path = mh_xstrdup(route); mp->m_ingrp = ingrp; if (grp) - mp->m_gname = getcpy (grp); + mp->m_gname = mh_xstrdup(grp); if (note) - mp->m_note = getcpy (note); + mp->m_note = mh_xstrdup(note); return mp; } void -mnfree (struct mailname *mp) +mnfree(struct mailname *mp) { if (!mp) return; if (mp->m_text) - free (mp->m_text); + mh_free0(&(mp->m_text)); if (mp->m_pers) - free (mp->m_pers); + mh_free0(&(mp->m_pers)); if (mp->m_mbox) - free (mp->m_mbox); + mh_free0(&(mp->m_mbox)); if (mp->m_host) - free (mp->m_host); + mh_free0(&(mp->m_host)); if (mp->m_path) - free (mp->m_path); + mh_free0(&(mp->m_path)); if (mp->m_gname) - free (mp->m_gname); + mh_free0(&(mp->m_gname)); if (mp->m_note) - free (mp->m_note); + mh_free0(&(mp->m_note)); - free ((char *) mp); + mh_free0(&mp); } #define empty(s) ((s) ? (s) : "") char * -auxformat (struct mailname *mp, int extras) +adrformat(struct mailname *mp) { static char addr[BUFSIZ]; static char buffer[BUFSIZ]; -#ifdef DUMB if (mp->m_nohost) - strncpy (addr, mp->m_mbox ? mp->m_mbox : "", sizeof(addr)); + strncpy(addr, mp->m_mbox ? mp->m_mbox : "", sizeof(addr)); else -#endif /* DUMB */ - -#ifndef BANG - if (mp->m_type != UUCPHOST) - snprintf (addr, sizeof(addr), mp->m_host ? "%s%s@%s" : "%s%s", + snprintf(addr, sizeof(addr), mp->m_host ? "%s%s@%s" : "%s%s", empty(mp->m_path), empty(mp->m_mbox), mp->m_host); - else -#endif /* not BANG */ - snprintf (addr, sizeof(addr), "%s!%s", mp->m_host, mp->m_mbox); - - if (!extras) - return addr; if (mp->m_pers || mp->m_path) { if (mp->m_note) - snprintf (buffer, sizeof(buffer), "%s %s <%s>", - legal_person (mp->m_pers ? mp->m_pers : mp->m_mbox), + snprintf(buffer, sizeof(buffer), "%s %s <%s>", + legal_person(mp->m_pers ? mp->m_pers : mp->m_mbox), mp->m_note, addr); else - snprintf (buffer, sizeof(buffer), "%s <%s>", - legal_person (mp->m_pers ? mp->m_pers : mp->m_mbox), + snprintf(buffer, sizeof(buffer), "%s <%s>", + legal_person(mp->m_pers ? mp->m_pers : mp->m_mbox), addr); } else if (mp->m_note) - snprintf (buffer, sizeof(buffer), "%s %s", addr, mp->m_note); + snprintf(buffer, sizeof(buffer), "%s %s", addr, mp->m_note); else - strncpy (buffer, addr, sizeof(buffer)); + strncpy(buffer, addr, sizeof(buffer)); return buffer; } -/* - * address specific "sprintf" - */ - -char * -adrsprintf (char *username, char *domain) -{ - int snprintf_return; - static char addr[BUFSIZ]; - - if (username == NULL) - username = getusername(); - - if (username_extension_masquerading) { - /* mts.conf contains "masquerade:[...]username_extension[...]", - * so tack on the value of the $USERNAME_EXTENSION environment - * variable, if set, to username. - */ - char* extension = getenv("USERNAME_EXTENSION"); - static char username_with_extension[BUFSIZ]; - - if (extension != NULL && *extension != '\0') { - snprintf_return = snprintf(username_with_extension, - sizeof(username_with_extension), - "%s%s", username, extension); - - if (snprintf_return < 0 || - snprintf_return >= sizeof(username_with_extension)) - adios(NULL, "snprintf() error writing username (%d chars) and" - " $USERNAME_EXTENSION (%d chars) to array of BUFSIZ (%d)" - " chars", - strlen(username), strlen(extension), BUFSIZ); - - username = username_with_extension; - } - } - -#ifdef REALLYDUMB - return username; -#endif - - if (domain == NULL) - domain = LocalName(); - -#ifndef BANG - snprintf_return = snprintf (addr, sizeof(addr), "%s@%s", username, domain); -#else /* BANG */ - snprintf_return = snprintf (addr, sizeof(addr), "%s!%s", domain, username); -#endif /* BANG */ - - if (snprintf_return < 0 || snprintf_return >= sizeof(addr)) - adios(NULL, "snprintf() error writing username (%d chars), domain (%d" - " chars), and 1 separator char to array of BUFSIZ (%d) chars", - strlen(username), strlen(domain), BUFSIZ); - - return addr; -} - - #define W_NIL 0x0000 #define W_MBEG 0x0001 #define W_MEND 0x0002 @@ -371,36 +230,36 @@ adrsprintf (char *username, char *domain) #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND" /* - * Check if this is my address - */ +** Check if this is my address +*/ int -ismymbox (struct mailname *np) +ismymbox(struct mailname *np) { int oops; - register int len, i; - register char *cp; - register char *pp; + int len, i; + char *cp; + char *pp; char buffer[BUFSIZ]; struct mailname *mp; static char *am = NULL; - static struct mailname mq={NULL}; + static struct mailname mq; /* - * If this is the first call, initialize - * list of alternate mailboxes. - */ + ** If this is the first call, initialize + ** list of alternate mailboxes. + */ if (am == NULL) { mq.m_next = NULL; - mq.m_mbox = getusername (); - if ((am = context_find ("alternate-mailboxes")) == NULL) + mq.m_mbox = getusername(); + mp = &mq; + if ((am = context_find("alternate-mailboxes")) == NULL) { am = getusername(); - else { - mp = &mq; + } else { oops = 0; - while ((cp = getname (am))) { - if ((mp->m_next = getm (cp, NULL, 0, AD_NAME, NULL)) == NULL) { - admonish (NULL, "illegal address: %s", cp); + while ((cp = getname(am))) { + if ((mp->m_next = getm(cp, NULL, 0, AD_NAME, NULL)) == NULL) { + admonish(NULL, "illegal address: %s", cp); oops++; } else { mp = mp->m_next; @@ -409,7 +268,7 @@ ismymbox (struct mailname *np) mp->m_type |= W_MBEG; mp->m_mbox++; } - if (*(cp = mp->m_mbox + strlen (mp->m_mbox) - 1) == '*') { + if (*(cp = mp->m_mbox + strlen(mp->m_mbox) - 1) == '*') { mp->m_type |= W_MEND; *cp = '\0'; } @@ -418,20 +277,50 @@ ismymbox (struct mailname *np) mp->m_type |= W_HBEG; mp->m_host++; } - if (*(cp = mp->m_host + strlen (mp->m_host) - 1) == '*') { + if (*(cp = mp->m_host + strlen(mp->m_host) - 1) == '*') { mp->m_type |= W_HEND; *cp = '\0'; } } - if ((cp = getenv ("MHWDEBUG")) && *cp) - fprintf (stderr, "mbox=\"%s\" host=\"%s\" %s\n", + if ((cp = getenv("MHWDEBUG")) && *cp) { + fprintf(stderr, "mbox=\"%s\" host=\"%s\" %s\n", + mp->m_mbox, mp->m_host, + snprintb(buffer, sizeof(buffer), (unsigned) mp->m_type, WBITS)); + } + } + } + if (oops != 0) { + advise(NULL, "please fix the profile entry %s", + "alternate-mailboxes"); + } + } + + if ((cp = context_find("Default-From")) != NULL) { + int i = 0; + char *cp2; + oops = 0; + + while ((cp2 = getname(cp)) != NULL) { + i++; + if ((mp->m_next = getm(cp2, NULL, 0, AD_NAME, NULL)) == NULL) { + admonish(NULL, "illegal address: %s", cp); + oops++; + } else { + mp = mp->m_next; + if ((cp = getenv("MHWDEBUG")) && *cp) { + fprintf(stderr, "mbox=\"%s\" host=\"%s\" %s\n", mp->m_mbox, mp->m_host, - snprintb (buffer, sizeof(buffer), (unsigned) mp->m_type, WBITS)); + snprintb(buffer, sizeof(buffer), (unsigned) mp->m_type, WBITS)); + } } + } - if (oops) - advise (NULL, "please fix the %s: entry in your %s file", - "alternate-mailboxes", mh_profile); + + if (oops != 0 || i < 1) { + advise(NULL, "please fix the profile entry %s", + "Default-From"); + } + } } @@ -439,79 +328,76 @@ ismymbox (struct mailname *np) return 0; switch (np->m_type) { - case NETHOST: - len = strlen (cp = LocalName ()); - if (!uprf (np->m_host, cp) || np->m_host[len] != '.') - break; - goto local_test; - - case UUCPHOST: - if (mh_strcasecmp (np->m_host, SystemName())) - break; /* fall */ - case LOCALHOST: -local_test: ; - if (!mh_strcasecmp (np->m_mbox, mq.m_mbox)) - return 1; + case NETHOST: + len = strlen(cp = LocalName()); + if (!uprf(np->m_host, cp) || np->m_host[len] != '.') break; + goto local_test; - default: - break; + case LOCALHOST: +local_test: ; + if (!mh_strcasecmp(np->m_mbox, mq.m_mbox)) + return 1; + break; + + default: + break; } /* - * Now scan through list of alternate - * mailboxes, and check for a match. - */ + ** Now scan through list of alternate + ** mailboxes, and check for a match. + */ for (mp = &mq; mp->m_next;) { mp = mp->m_next; if (!np->m_mbox) continue; - if ((len = strlen (cp = np->m_mbox)) - < (i = strlen (pp = mp->m_mbox))) + if ((len = strlen(cp = np->m_mbox)) + < (i = strlen(pp = mp->m_mbox))) continue; switch (mp->m_type & W_MBOX) { - case W_NIL: - if (mh_strcasecmp (cp, pp)) - continue; - break; - case W_MBEG: - if (mh_strcasecmp (cp + len - i, pp)) - continue; - break; - case W_MEND: - if (!uprf (cp, pp)) - continue; - break; - case W_MBEG | W_MEND: - if (stringdex (pp, cp) < 0) - continue; - break; + case W_NIL: + if (mh_strcasecmp(cp, pp)) + continue; + break; + case W_MBEG: + if (mh_strcasecmp(cp + len - i, pp)) + continue; + break; + case W_MEND: + if (!uprf(cp, pp)) + continue; + break; + case W_MBEG | W_MEND: + if (stringdex(pp, cp) < 0) + continue; + break; } if (mp->m_nohost) return 1; if (np->m_host == NULL) continue; - if ((len = strlen (cp = np->m_host)) - < (i = strlen (pp = mp->m_host))) + if ((len = strlen(cp = np->m_host)) + < (i = strlen(pp = mp->m_host))) continue; switch (mp->m_type & W_HOST) { - case W_NIL: - if (mh_strcasecmp (cp, pp)) - continue; - break; - case W_HBEG: - if (mh_strcasecmp (cp + len - i, pp)) - continue; - break; - case W_HEND: - if (!uprf (cp, pp)) - continue; - break; - case W_HBEG | W_HEND: - if (stringdex (pp, cp) < 0) - continue; - break; + case W_NIL: + if (mh_strcasecmp(cp, pp)) + continue; + break; + case W_HBEG: + if (mh_strcasecmp (cp + len - i, pp)) + continue; + break; + case W_HEND: + if (!uprf(cp, pp)) + continue; + break; + case W_HBEG | W_HEND: + if (stringdex(pp, cp) < 0) + continue; + break; } return 1; } @@ -519,50 +405,39 @@ local_test: ; return 0; } - /* - * Moved from hosts.c -- find out the official name of a host + * Insert mailname after element and returns the + * number of parsed addresses. element is set to + * the last parsed addresse. */ - -/* - * In the SendMail world, we really don't know what the valid - * hosts are. We could poke around in the sendmail.cf file, but - * that still isn't a guarantee. As a result, we'll say that - * everything is a valid host, and let SendMail worry about it. - */ - -#include -#include - - -char * -OfficialName (char *name) +ssize_t +getmboxes(char *line, struct mailname **element) { - unsigned char *p; - char *q, site[BUFSIZ]; - struct addrinfo hints, *res; - - static char buffer[BUFSIZ]; + struct mailname *mp, *next, *first; + char *cp; + size_t i = 0; - for (p = name, q = site; *p && (q - site < sizeof(site) - 1); p++, q++) - *q = isupper (*p) ? tolower (*p) : *p; - *q = '\0'; - q = site; + first = *element; + next = first->m_next; - if (!mh_strcasecmp (LocalName(), site)) - return LocalName(); - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - - if (getaddrinfo(q, NULL, &hints, &res) == 0) { - strncpy (buffer, res->ai_canonname, sizeof(buffer)); - buffer[sizeof(buffer) - 1] = '\0'; - freeaddrinfo(res); - return buffer; + while ((cp = getname(line))) { + mp = getm(cp, NULL, 0, AD_HOST, NULL); + if (mp == NULL) { + goto error; + } + (*element)->m_next = mp; + *element = mp; + i++; } - strncpy (buffer, site, sizeof(buffer)); - return buffer; + (*element)->m_next = next; + return i; +error: + while (first->m_next != NULL && first->m_next != next) { + mp = first->m_next; + first->m_next = mp->m_next; + mh_free0(&mp); + } + first->m_next = next; + return -1; }