X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Faddrsbr.c;h=db5b42e67d33d35f2618c4c571e79f28bfc8410a;hp=4f734b444fba3ad4293a05ba8be664c9e1390b90;hb=ee8d01d64e8832304256de53db07228e2be67f6a;hpb=34ec62af8fc74c3c9d143328f485c82ef7aad327 diff --git a/sbr/addrsbr.c b/sbr/addrsbr.c index 4f734b4..db5b42e 100644 --- a/sbr/addrsbr.c +++ b/sbr/addrsbr.c @@ -1,63 +1,35 @@ - /* - * addrsbr.c -- parse addresses 822-style - * - * $Id$ - */ - +** 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 zotnet/mf/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 +#include - 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; @@ -71,456 +43,401 @@ 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) - return NULL; - - strncpy (adr, ap->text, sizeof(adr)); - pers = ap->pers; - mbox = ap->mbox; - host = ap->host; - route = ap->path; - grp = ap->grp; - ingrp = ap->ingrp; - note = ap->note; - if (ap->err && *ap->err) - strncpy (err, ap->err, sizeof(err)); - - return adr; + struct adrx *ap; + + pers = mbox = host = route = grp = note = NULL; + err[0] = '\0'; + + if ((ap = getadrx(addrs ? addrs : "")) == NULL) + return NULL; + + strncpy(adr, ap->text, sizeof(adr)); + pers = ap->pers; + mbox = ap->mbox; + host = ap->host; + route = ap->path; + grp = ap->grp; + ingrp = ap->ingrp; + note = ap->note; + if (ap->err && *ap->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 && err[0]) { - if (eresult) - strcpy (eresult, err); - else - if (wanthost == AD_HOST) - 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"); - else - if (wanthost == AD_HOST) - admonish (NULL, "null address '%s'", str); - return NULL; - } - if (mbox == NULL && grp == NULL) { - if (eresult) - strcpy (eresult, "no mailbox in address"); - else - if (wanthost == AD_HOST) - admonish (NULL, "no mailbox in address '%s'", str); - return NULL; - } - - if (dfhost == NULL) { - dfhost = LocalName (); - dftype = LOCALHOST; - } - - mp = (struct mailname *) calloc ((size_t) 1, sizeof(*mp)); - if (mp == NULL) { - if (eresult) - strcpy (eresult, "insufficient memory to represent address"); - else - if (wanthost == AD_HOST) - adios (NULL, "insufficient memory to represent address"); - return NULL; - } - - mp->m_next = NULL; - mp->m_text = getcpy (str); - if (pers) - mp->m_pers = getcpy (pers); - - if (mbox == NULL) { - mp->m_type = BADHOST; - mp->m_nohost = 1; - mp->m_ingrp = ingrp; - mp->m_gname = getcpy (grp); - if (note) - mp->m_note = getcpy (note); - return mp; - } - - if (host) { - mp->m_mbox = getcpy (mbox); - mp->m_host = getcpy (host); - } - else { - if ((pp = strchr(mbox, '!'))) { - *pp++ = '\0'; - mp->m_mbox = getcpy (pp); - mp->m_host = getcpy (mbox); - mp->m_type = UUCPHOST; + struct mailname *mp; + + if (err[0]) { + if (eresult) + strcpy(eresult, err); + else + if (wanthost == AD_HOST) + admonish(NULL, "bad address '%s' - %s", str, err); + return NULL; } - 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; - } + if (pers == NULL && mbox == NULL && host == NULL && route == NULL + && grp == NULL) { + if (eresult) + strcpy(eresult, "null address"); + else + if (wanthost == AD_HOST) + admonish(NULL, "null address '%s'", str); + return NULL; } - goto got_host; - } - - if (wanthost == AD_NHST) - mp->m_type = !strcasecmp (LocalName (), mp->m_host) - ? LOCALHOST : NETHOST; -#ifdef DUMB - else - mp->m_type = 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 = strcasecmp (LocalName(), mp->m_host) ? NETHOST : LOCALHOST; + if (mbox == NULL && grp == NULL) { + if (eresult) + strcpy(eresult, "no mailbox in address"); + else if (wanthost == AD_HOST) + admonish(NULL, "no mailbox in address '%s'", str); + return NULL; + } + + if (dfhost == NULL) { + dfhost = LocalName(); + dftype = LOCALHOST; + } + + mp = mh_xcalloc(1, sizeof(*mp)); + if (mp == NULL) { + if (eresult) + strcpy(eresult, "insufficient memory to represent address"); + else if (wanthost == AD_HOST) + adios(EX_OSERR, NULL, "insufficient memory to represent address"); + return NULL; + } + + mp->m_next = NULL; + mp->m_text = mh_xstrdup(str); + if (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 = mh_xstrdup(grp); + if (note) + mp->m_note = mh_xstrdup(note); + return mp; } - else { - if (dp = strchr(mp->m_host, '.')) { - *dp = NULL; - if (pp = OfficialName (mp->m_host)) - goto got_real_host; - *dp = '.'; - } - mp->m_type = BADHOST; + + if (host) { + mp->m_mbox = mh_xstrdup(mbox); + mp->m_host = mh_xstrdup(host); + } else { + 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_host = route ? NULL : mh_xstrdup(dfhost); + mp->m_type = route ? NETHOST : dftype; + } + goto got_host; } -#endif /* not DUMB */ + + if (wanthost == AD_NHST) + mp->m_type = !mh_strcasecmp(LocalName(), mp->m_host) + ? LOCALHOST : NETHOST; + else + mp->m_type = mh_strcasecmp(LocalName(), mp->m_host) ? NETHOST : LOCALHOST; got_host: ; - if (route) - mp->m_path = getcpy (route); - mp->m_ingrp = ingrp; - if (grp) - mp->m_gname = getcpy (grp); - if (note) - mp->m_note = getcpy (note); - - return mp; + if (route) + mp->m_path = mh_xstrdup(route); + mp->m_ingrp = ingrp; + if (grp) + mp->m_gname = mh_xstrdup(grp); + if (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); - if (mp->m_pers) - free (mp->m_pers); - if (mp->m_mbox) - free (mp->m_mbox); - if (mp->m_host) - free (mp->m_host); - if (mp->m_path) - free (mp->m_path); - if (mp->m_gname) - free (mp->m_gname); - if (mp->m_note) - free (mp->m_note); - - free ((char *) mp); + if (!mp) + return; + + if (mp->m_text) + mh_free0(&(mp->m_text)); + if (mp->m_pers) + mh_free0(&(mp->m_pers)); + if (mp->m_mbox) + mh_free0(&(mp->m_mbox)); + if (mp->m_host) + mh_free0(&(mp->m_host)); + if (mp->m_path) + mh_free0(&(mp->m_path)); + if (mp->m_gname) + mh_free0(&(mp->m_gname)); + if (mp->m_note) + mh_free0(&(mp->m_note)); + + 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]; + 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", - empty(mp->m_path), empty(mp->m_mbox), mp->m_host); + snprintf(addr, sizeof(addr), mp->m_host ? "%s%s@%s" : "%s%s", + empty(mp->m_path), empty(mp->m_mbox), mp->m_host); + + 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), + mp->m_note, addr); + else + 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); else -#endif /* not BANG */ - snprintf (addr, sizeof(addr), "%s!%s", mp->m_host, mp->m_mbox); - - if (!extras) - return addr; + strncpy(buffer, addr, sizeof(buffer)); - 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), - mp->m_note, addr); - else - 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); - else - 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; + return buffer; } -#define W_NIL 0x0000 -#define W_MBEG 0x0001 -#define W_MEND 0x0002 -#define W_MBOX (W_MBEG | W_MEND) -#define W_HBEG 0x0004 -#define W_HEND 0x0008 -#define W_HOST (W_HBEG | W_HEND) -#define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND" +#define W_NIL 0x0000 +#define W_MBEG 0x0001 +#define W_MEND 0x0002 +#define W_MBOX (W_MBEG | W_MEND) +#define W_HBEG 0x0004 +#define W_HEND 0x0008 +#define W_HOST (W_HBEG | W_HEND) +#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; - char buffer[BUFSIZ]; - struct mailname *mp; - static char *am = NULL; - static struct mailname mq={NULL}; - - /* - * 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) - am = getusername(); - else { - mp = &mq; - oops = 0; - while ((cp = getname (am))) { - if ((mp->m_next = getm (cp, NULL, 0, AD_NAME, NULL)) == NULL) { - admonish (NULL, "illegal address: %s", cp); - oops++; + int oops; + int len, i; + char *cp; + char *pp; + char buffer[BUFSIZ]; + struct mailname *mp; + static char *am = NULL; + static struct mailname mq; + + /* + ** If this is the first call, initialize + ** list of alternate mailboxes. + */ + if (am == NULL) { + mq.m_next = NULL; + mq.m_mbox = getusername(); + mp = &mq; + if ((am = context_find("alternate-mailboxes")) == NULL) { + am = getusername(); } else { - mp = mp->m_next; - mp->m_type = W_NIL; - if (*mp->m_mbox == '*') { - mp->m_type |= W_MBEG; - mp->m_mbox++; - } - if (*(cp = mp->m_mbox + strlen (mp->m_mbox) - 1) == '*') { - mp->m_type |= W_MEND; - *cp = '\0'; - } - if (mp->m_host) { - if (*mp->m_host == '*') { - mp->m_type |= W_HBEG; - mp->m_host++; + oops = 0; + 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; + mp->m_type = W_NIL; + if (*mp->m_mbox == '*') { + mp->m_type |= W_MBEG; + mp->m_mbox++; + } + if (*(cp = mp->m_mbox + strlen(mp->m_mbox) - 1) == '*') { + mp->m_type |= W_MEND; + *cp = '\0'; + } + if (mp->m_host) { + if (*mp->m_host == '*') { + mp->m_type |= W_HBEG; + mp->m_host++; + } + 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", + mp->m_mbox, mp->m_host, + snprintb(buffer, sizeof(buffer), (unsigned) mp->m_type, WBITS)); + } + } } - if (*(cp = mp->m_host + strlen (mp->m_host) - 1) == '*') { - mp->m_type |= W_HEND; - *cp = '\0'; + if (oops != 0) { + advise(NULL, "please fix the profile entry %s", + "alternate-mailboxes"); } - } - 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) - advise (NULL, "please fix the %s: entry in your %s file", - "alternate-mailboxes", mh_profile); + + 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)); + } + } + + } + + if (oops != 0 || i < 1) { + advise(NULL, "please fix the profile entry %s", + "Default-From"); + } + + } } - } - if (np == NULL) /* XXX */ - return 0; - - switch (np->m_type) { + if (np == NULL) /* XXX */ + 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; + len = strlen(cp = LocalName()); + if (!uprf(np->m_host, cp) || np->m_host[len] != '.') + break; + goto local_test; - case UUCPHOST: - if (strcasecmp (np->m_host, SystemName())) - break; /* fall */ case LOCALHOST: local_test: ; - if (!strcasecmp (np->m_mbox, mq.m_mbox)) - return 1; - break; + 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. - */ - 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))) - continue; - switch (mp->m_type & W_MBOX) { - case W_NIL: - if (strcasecmp (cp, pp)) - continue; - break; - case W_MBEG: - if (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))) - continue; - switch (mp->m_type & W_HOST) { - case W_NIL: - if (strcasecmp (cp, pp)) - continue; - break; - case W_HBEG: - if (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; + /* + ** 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))) + 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; + } + + 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))) + 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; + } + return 1; } - return 1; - } - return 0; + return 0; +} + +/* + * Insert mailname after element and returns the + * number of parsed addresses. element is set to + * the last parsed addresse. + */ +ssize_t +getmboxes(char *line, struct mailname **element) +{ + struct mailname *mp, *next, *first; + char *cp; + size_t i = 0; + + first = *element; + next = first->m_next; + + while ((cp = getname(line))) { + mp = getm(cp, NULL, 0, AD_HOST, NULL); + if (mp == NULL) { + goto error; + } + (*element)->m_next = mp; + *element = mp; + i++; + } + + (*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; }