+ address_t *pop, *head = NULL;
+ address_t **last = &head;
+
+ while ((pop = address_list_pop(&a))) {
+ if (!pop->group && !pop->personal
+ && pop->mailbox && !strchr(pop->mailbox, '@'))
+ {
+ const address_t *t = alias_lookup(Aliases, pop->mailbox);
+
+ if (t) {
+ LIST *u;
+
+ for (u = *expn; u; u = u->next) {
+ if (!m_strcmp(pop->mailbox, u->data)) { /* alias already found */
+ address_delete(&pop);
+ continue;
+ }
+ }
+
+ /* save the fact we saw it */
+ u = mutt_new_list();
+ u->data = m_strdup(pop->mailbox);
+ u->next = *expn;
+ *expn = u;
+ address_delete(&pop);
+
+ /* recurse */
+ last = address_list_last(last);
+ *last = mutt_expand_aliases_r(address_list_dup(t), expn);
+ continue;
+ } else {
+ struct passwd *pw = getpwnam(pop->mailbox);
+
+ if (pw) {
+ char namebuf[STRING];
+ mutt_gecos_name(namebuf, sizeof(namebuf), pw, GecosMask.rx);
+ m_strreplace(&pop->personal, namebuf);
+ }
+ }
+ }
+
+ last = address_list_append(last, pop);
+ }
+
+ if (option(OPTUSEDOMAIN)) {
+ /* now qualify all local addresses */
+ const char *fqdn = mutt_fqdn(1);
+ if (fqdn)
+ rfc822_qualify(head, fqdn);
+ }
+
+ return head;