Fix blind list alias expansion
[mmh] / uip / aliasbr.c
index 744d3bf..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,13 +77,13 @@ 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;
                        cp = concat(cp, ",", pp, NULL);
-                       free(dp);
-                       free(pp);
+                       mh_free0(&dp);
+                       mh_free0(&pp);
                } else
                        cp = pp;
        }
@@ -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);
 }
 
 
@@ -431,8 +470,8 @@ add_aka(struct aka *ak, char *pp)
                if (strcmp(pp, ad->ad_text)==0)
                        return;
 
-       ad = (struct adr *) mh_xcalloc(1, sizeof(*ad));
-       ad->ad_text = getcpy(pp);
+       ad = mh_xcalloc(1, sizeof(*ad));
+       ad->ad_text = mh_xstrdup(pp);
        ad->ad_local = strchr(pp, '@') == NULL;
        ad->ad_next = NULL;
        if (ak->ak_addr)
@@ -468,9 +507,9 @@ akalloc(char *id)
 {
        struct aka *p;
 
-       p = (struct aka *) mh_xcalloc(1, sizeof(*p));
+       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;
@@ -489,13 +528,13 @@ hmalloc(struct passwd *pw)
 {
        struct home *p;
 
-       p = (struct home *) mh_xcalloc(1, sizeof(*p));
+       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 */