]> diplodocus.org Git - nmh/blobdiff - sbr/addrsbr.c
Escape literal leading full stop in man/new.man.
[nmh] / sbr / addrsbr.c
index 07bc810fab4e52133cd0b71f248cc602475b943b..49953f61de73f9b0ee68a4bab790b6c7ad7cbddd 100644 (file)
@@ -10,6 +10,8 @@
 #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:
 
@@ -47,7 +49,7 @@
 
    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
@@ -74,27 +76,24 @@ static char *grp = NULL;
 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;
@@ -112,57 +111,45 @@ getname (char *addrs)
 
 
 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;
     }
 
     if (dfhost == NULL) {
-       dfhost = LocalName ();
+       dfhost = LocalName (0);
        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;
@@ -170,51 +157,44 @@ getm (char *str, char *dfhost, int dftype, int wanthost, char *eresult)
        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 (), mp->m_host)
-           ? LOCALHOST : NETHOST;
-    else
-       mp->m_type = mh_strcasecmp (LocalName(), 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;
 }
@@ -226,22 +206,15 @@ 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);
+    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);
 }
 
 
@@ -257,10 +230,13 @@ auxformat (struct mailname *mp, int extras)
            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)
@@ -286,60 +262,6 @@ auxformat (struct mailname *mp, int 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();
-
-    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
@@ -357,13 +279,14 @@ int
 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
@@ -372,13 +295,37 @@ ismymbox (struct mailname *np)
     if (am == NULL) {
        mq.m_next = NULL;
        mq.m_mbox = getusername ();
+
+       if ((am = context_find ("local-mailbox"))) {
+
+           localmailbox++;
+
+           if ((cp = getname(am)) == NULL) {
+               admonish (NULL, "Unable to find address in local-mailbox");
+               return 0;
+           }
+
+           if ((mq.m_next = getm (cp, NULL, 0, NULL, 0)) == NULL) {
+               admonish (NULL, "invalid entry in local-mailbox: %s", cp);
+               return 0;
+           }
+
+           /*
+            * 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)
+               ;
+       }
+
        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 {
@@ -402,40 +349,53 @@ ismymbox (struct mailname *np)
                            *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 ());
-           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;
+                   /* FALLTHRU */
+           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
@@ -445,16 +405,16 @@ local_test: ;
        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: 
@@ -469,18 +429,18 @@ local_test: ;
 
        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: