Fix blind list alias expansion
[mmh] / uip / aliasbr.c
index 1ed527f..3faa373 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <h/mh.h>
 #include <h/aliasbr.h>
+#include <h/addrsbr.h>
 #include <h/utils.h>
 #include <grp.h>
 #include <pwd.h>
@@ -76,7 +77,7 @@ akresult(struct aka *ak)
 
        for (ad = ak->ak_addr; ad; ad = ad->ad_next) {
                pp = ad->ad_local ? akval(ak->ak_next, ad->ad_text)
-                       : getcpy(ad->ad_text);
+                       : mh_xstrdup(ad->ad_text);
 
                if (cp) {
                        dp = cp;
@@ -99,11 +100,49 @@ akval(struct aka *ak, char *s)
        if (!s)
                return s;  /* XXX */
 
-       for (; ak; ak = ak->ak_next)
-               if (aleq(s, ak->ak_name))
-                       return akresult(ak);
+       for (; ak; ak = ak->ak_next) {
+               if (aleq (s, ak->ak_name)) {
+                       return akresult (ak);
+               } else if (strchr (s, ':')) {
+                       /*
+                       ** The first address in a blind list will contain the
+                       ** alias name, so try to match, but just with just the
+                       ** address (not including the list name).  If there's a
+                       ** match, then replace the alias part with its
+                       ** expansion.
+                       */
+
+                       char *name = getname(s);
+                       char *cp = NULL;
+
+                       if (name) {
+                               /*
+                               ** s is of the form "Blind list: address".  If address
+                               ** is an alias, expand it.
+                               */
+                               struct mailname *mp = getm(name, NULL, 0, AD_NAME, NULL);
+
+                               if (mp  &&  mp->m_ingrp) {
+                                       char *gname = add (mp->m_gname, NULL);
+
+                                       if (gname  &&  aleq(name, ak->ak_name)) {
+                                               /* Will leak cp. */
+                                               cp = concat (gname, akresult (ak), NULL);
+                                               free(gname);
+                                       }
+                               }
+                       mnfree(mp);
+                       }
+                       /* Need to flush getname after use. */
+                       while (getname("")) continue;
+
+                       if (cp) {
+                               return cp;
+                       }
+               }
+       }
 
-       return getcpy(s);
+       return mh_xstrdup(s);
 }
 
 
@@ -432,7 +471,7 @@ add_aka(struct aka *ak, char *pp)
                        return;
 
        ad = mh_xcalloc(1, sizeof(*ad));
-       ad->ad_text = getcpy(pp);
+       ad->ad_text = mh_xstrdup(pp);
        ad->ad_local = strchr(pp, '@') == NULL;
        ad->ad_next = NULL;
        if (ak->ak_addr)
@@ -470,7 +509,7 @@ akalloc(char *id)
 
        p = mh_xcalloc(1, sizeof(*p));
 
-       p->ak_name = getcpy(id);
+       p->ak_name = mh_xstrdup(id);
        p->ak_visible = 0;
        p->ak_addr = NULL;
        p->ak_next = NULL;
@@ -491,11 +530,11 @@ hmalloc(struct passwd *pw)
 
        p = mh_xcalloc(1, sizeof(*p));
 
-       p->h_name = getcpy(pw->pw_name);
+       p->h_name = mh_xstrdup(pw->pw_name);
        p->h_uid = pw->pw_uid;
        p->h_gid = pw->pw_gid;
-       p->h_home = getcpy(pw->pw_dir);
-       p->h_shell = getcpy(pw->pw_shell);
+       p->h_home = mh_xstrdup(pw->pw_dir);
+       p->h_shell = mh_xstrdup(pw->pw_shell);
        p->h_ngrps = 0;
        p->h_next = NULL;
        /* append to end */