#include <h/mh.h>
#include <h/addrsbr.h>
#include <h/mf.h>
+#include <h/mts.h>
+#include <h/utils.h>
/* High level parsing of addresses:
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
+ defaulted, typically to the local host. The lack of an explicit host is
also noted.
If an explicit 822-style host is present, then MH checks to see if it
static char *note = NULL;
static char err[BUFSIZ];
static char adr[BUFSIZ];
+static int eai = 0;
-
-extern boolean username_extension_masquerading; /* defined in mts.c */
-
-
-/*
- * external prototypes
- */
-char *getusername (void);
+void
+enable_eai() {
+ eai = 1;
+}
char *
-getname (char *addrs)
+getname (const 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 : "", eai)) == NULL) {
return NULL;
+ }
strncpy (adr, ap->text, sizeof(adr));
pers = ap->pers;
struct mailname *
-getm (char *str, char *dfhost, int dftype, int wanthost, char *eresult)
+getm (char *str, char *dfhost, int dftype, char *eresult, size_t eresultsize)
{
char *pp;
struct mailname *mp;
if (err[0]) {
- if (eresult)
- strcpy (eresult, err);
- else
- if (wanthost == AD_HOST)
- admonish (NULL, "bad address '%s' - %s", str, err);
+ if (eresult) {
+ strncpy (eresult, err, eresultsize);
+ eresult[eresultsize - 1] = '\0';
+ }
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);
+ if (eresult) {
+ strncpy (eresult, "null address", eresultsize);
+ eresult[eresultsize - 1] = '\0';
+ }
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);
+ if (eresult) {
+ strncpy (eresult, "no mailbox in address", eresultsize);
+ eresult[eresultsize - 1] = '\0';
+ }
return NULL;
}
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;
- }
-
+ NEW0(mp);
mp->m_next = NULL;
mp->m_text = getcpy (str);
if (pers)
- mp->m_pers = getcpy (pers);
+ mp->m_pers = mh_xstrdup(pers);
if (mbox == NULL) {
mp->m_type = BADHOST;
mp->m_ingrp = ingrp;
mp->m_gname = getcpy (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);
- }
- else {
+ mp->m_host = mh_xstrdup(host);
+ mp->m_type =
+ strcasecmp (LocalName(0), mp->m_host) ? NETHOST : LOCALHOST;
+ } else {
if ((pp = strchr(mbox, '!'))) {
*pp++ = '\0';
- mp->m_mbox = getcpy (pp);
+ mp->m_mbox = mh_xstrdup(pp);
mp->m_host = getcpy (mbox);
mp->m_type = UUCPHOST;
- }
- else {
+ } else {
mp->m_nohost = 1;
mp->m_mbox = getcpy (mbox);
if (route == NULL && dftype == LOCALHOST) {
mp->m_host = NULL;
mp->m_type = dftype;
- }
- else
- {
+ } else {
mp->m_host = route ? NULL : getcpy (dfhost);
mp->m_type = route ? NETHOST : dftype;
}
}
- goto got_host;
}
- if (wanthost == AD_NHST)
- mp->m_type = !mh_strcasecmp (LocalName (0), mp->m_host)
- ? LOCALHOST : NETHOST;
- else
- mp->m_type = mh_strcasecmp (LocalName(0), mp->m_host) ? NETHOST : LOCALHOST;
+ /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
+ to support wild-card matching. */
-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;
}
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);
+ mh_xfree(mp->m_text);
+ mh_xfree(mp->m_pers);
+ mh_xfree(mp->m_mbox);
+ mh_xfree(mp->m_host);
+ mh_xfree(mp->m_path);
+ mh_xfree(mp->m_gname);
+ mh_xfree(mp->m_note);
+
+ free(mp);
}
strncpy (addr, mp->m_mbox ? mp->m_mbox : "", sizeof(addr));
else
- 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);
- else
+ if (mp->m_type != UUCPHOST) {
+ if (mp->m_host)
+ snprintf (addr, sizeof(addr), "%s%s@%s", empty(mp->m_path),
+ empty(mp->m_mbox), mp->m_host);
+ else snprintf (addr, sizeof(addr), "%s%s", empty(mp->m_path),
+ empty(mp->m_mbox));
+ } else
snprintf (addr, sizeof(addr), "%s!%s", mp->m_host, mp->m_mbox);
if (!extras)
}
-/*
- * This used to be adrsprintf() (where it would format an address for you
- * given a username and a domain). But somewhere we got to the point where
- * the only caller was post, and it only called it with both arguments NULL.
- * So the function was renamed with a more sensible name.
- */
-
-char *
-getlocaladdr(void)
-{
- int snprintf_return;
- char *username, *domain;
- static char addr[BUFSIZ];
-
- 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 >= (int) 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;
- }
- }
-
- return username;
-
- domain = LocalName(0);
-
- snprintf_return = snprintf (addr, sizeof(addr), "%s@%s", username, domain);
-
- if (snprintf_return < 0 || snprintf_return >= (int) 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
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;
+ static int localmailbox = 0;
/*
* 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 ("local-mailbox"))) {
- struct mailname *mptr;
+
+ localmailbox++;
if ((cp = getname(am)) == NULL) {
admonish (NULL, "Unable to find address in local-mailbox");
return 0;
}
- if ((mptr = getm (cp, NULL, 0, AD_NAME, NULL)) == NULL) {
+ if ((mq.m_next = getm (cp, NULL, 0, NULL, 0)) == NULL) {
admonish (NULL, "invalid entry in local-mailbox: %s", cp);
return 0;
}
- /*
- * Yes, we're not freeing the whole entry, because all of those
- * elements contain allocated pointers that we need; maybe
- * later ...
- */
-
- mq = *mptr;
-
- free(mptr);
-
/*
* Sigh, it turns out that the address parser gets messed up
* if you don't call getname() until it returns NULL.
while ((cp = getname(am)) != NULL)
;
- } else {
- mq.m_mbox = getusername ();
}
- mq.m_next = NULL;
-
if ((am = context_find ("alternate-mailboxes")) == NULL)
am = getusername();
else {
- mp = &mq;
+ mp = mq.m_next ? mq.m_next : &mq;
oops = 0;
while ((cp = getname (am))) {
- if ((mp->m_next = getm (cp, NULL, 0, AD_NAME, NULL)) == NULL) {
+ if ((mp->m_next = getm (cp, NULL, 0, NULL, 0)) == NULL) {
admonish (NULL, "illegal address: %s", cp);
oops++;
} else {
*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 (oops)
advise (NULL, "please fix the %s: entry in your %s file",
"alternate-mailboxes", mh_profile);
}
+
+ if ((cp = getenv ("MHWDEBUG")) && *cp) {
+ for (mp = &mq; mp; mp = mp->m_next) {
+ fprintf (stderr, "Local- or Alternate-Mailbox: text=\"%s\" "
+ "mbox=\"%s\" host=\"%s\" %s\n",
+ mp->m_text ? mp->m_text : "", mp->m_mbox,
+ mp->m_host ? mp->m_host : "",
+ snprintb (buffer, sizeof(buffer), (unsigned) mp->m_type,
+ WBITS));
+ }
+ }
}
if (np == NULL) /* XXX */
return 0;
- switch (np->m_type) {
- case NETHOST:
- len = strlen (cp = LocalName (0));
- if (!uprf (np->m_host, cp) || np->m_host[len] != '.')
- break;
- goto local_test;
+ /*
+ * Don't perform this "local" test if we have a Local-Mailbox set
+ */
- case UUCPHOST:
- if (mh_strcasecmp (np->m_host, SystemName()))
- break; /* fall */
- case LOCALHOST:
+ if (! localmailbox)
+ switch (np->m_type) {
+ case NETHOST:
+ len = strlen (cp = LocalName (0));
+ 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 (!mh_strcasecmp (np->m_mbox, mq.m_mbox))
- return 1;
- break;
+ if (!strcasecmp (np->m_mbox, mq.m_mbox))
+ return 1;
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
/*
* Now scan through list of alternate
mp = mp->m_next;
if (!np->m_mbox)
continue;
- if ((len = strlen (cp = np->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))
+ if (strcasecmp (cp, pp))
continue;
break;
case W_MBEG:
- if (mh_strcasecmp (cp + len - i, pp))
+ if (strcasecmp (cp + len - i, pp))
continue;
break;
case W_MEND:
if (mp->m_nohost)
return 1;
- if (np->m_host == NULL)
+ if (np->m_host == NULL || mp->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))
+ if (strcasecmp (cp, pp))
continue;
break;
case W_HBEG:
- if (mh_strcasecmp (cp + len - i, pp))
+ if (strcasecmp (cp + len - i, pp))
continue;
break;
case W_HEND: