return;
}
+ alias_add_reverse (new);
+
if ((t = Aliases))
{
while (t->next)
*/
ADDRESS *alias_reverse_lookup (ADDRESS *a)
{
- ALIAS *t = Aliases;
- ADDRESS *ap;
-
if (!a || !a->mailbox)
- return NULL;
+ return NULL;
+
+ return hash_find (ReverseAlias, a->mailbox);
+}
- for (; t; t = t->next)
+void alias_add_reverse (ALIAS *t)
+{
+ ADDRESS *ap;
+ if (!t)
+ return;
+
+ for (ap = t->addr; ap; ap = ap->next)
{
- /* cycle through all addresses if this is a group alias */
- for (ap = t->addr; ap; ap = ap->next)
- {
- if (!ap->group && ap->mailbox &&
- ascii_strcasecmp (ap->mailbox, a->mailbox) == 0)
- return ap;
- }
+ if (!ap->group && ap->mailbox)
+ hash_insert (ReverseAlias, ap->mailbox, ap, 1);
+ }
+}
+
+void alias_delete_reverse (ALIAS *t)
+{
+ ADDRESS *ap;
+ if (!t)
+ return;
+
+ for (ap = t->addr; ap; ap = ap->next)
+ {
+ if (!ap->group && ap->mailbox)
+ hash_delete (ReverseAlias, ap->mailbox, ap, NULL);
}
- return 0;
}
/* alias_complete() -- alias completion routine
WHERE const char *ReleaseDate;
WHERE HASH *Groups;
+WHERE HASH *ReverseAlias;
WHERE LIST *AutoViewList INITVAL(0);
WHERE LIST *AlternativeOrderList INITVAL(0);
{
if (CurrentMenu == MENU_ALIAS)
{
- for (tmp = Aliases; tmp ; tmp = tmp->next)
+ for (tmp = Aliases; tmp ; tmp = tmp->next)
tmp->del = 1;
set_option (OPTFORCEREDRAWINDEX);
}
}
else
{
+ alias_delete_reverse (tmp);
/* override the previous value */
rfc822_free_address (&tmp->addr);
if (CurrentMenu == MENU_ALIAS)
}
mutt_group_context_add_adrlist (gc, tmp->addr);
-
+ alias_add_reverse (tmp);
#ifdef DEBUG
if (debuglevel >= 2)
err.dsize = sizeof (error);
Groups = hash_create (1031);
+ ReverseAlias = hash_create (1031);
/*
* XXX - use something even more difficult to predict?
#else
+/* check whether an address is an IDN */
+
+static int check_idn (ADDRESS *ap)
+{
+ char *p = 0;
+
+ if (!ap || !ap->mailbox)
+ return 0;
+
+ if (!ap->idn_checked)
+ {
+ ap->idn_checked = 1;
+ for (p = strchr (ap->mailbox, '@'); p && *p; p = strchr (p, '.'))
+ if (ascii_strncasecmp (++p, "xn--", 4) == 0)
+ {
+ ap->is_idn = 1;
+ break;
+ }
+ }
+
+ return ap->is_idn;
+}
+
int mutt_idna_to_local (const char *in, char **out, int flags)
{
*out = NULL;
if (!in)
goto notrans;
-
+
/* Is this the right function? Interesting effects with some bad identifiers! */
if (idna_to_unicode_8z8z (in, out, 1) != IDNA_SUCCESS)
goto notrans;
static int mbox_to_udomain (const char *mbx, char **user, char **domain)
{
+ static char *buff = NULL;
char *p;
- *user = NULL;
- *domain = NULL;
- p = strchr (mbx, '@');
+ mutt_str_replace (&buff, mbx);
+
+ p = strchr (buff, '@');
if (!p || !p[1])
return -1;
- *user = safe_calloc((p - mbx + 1), sizeof(mbx[0]));
- strfcpy (*user, mbx, (p - mbx + 1));
- *domain = safe_strdup(p + 1);
+ *p = '\0';
+ *user = buff;
+ *domain = p + 1;
return 0;
}
{
safe_realloc (&a->mailbox, mutt_strlen (user) + mutt_strlen (tmp) + 2);
sprintf (a->mailbox, "%s@%s", NONULL(user), NONULL(tmp)); /* __SPRINTF_CHECKED__ */
+ a->idn_checked = 0;
}
- FREE (&domain);
- FREE (&user);
FREE (&tmp);
if (e)
{
if (!a->mailbox)
continue;
+ if (!check_idn (a))
+ continue;
if (mbox_to_udomain (a->mailbox, &user, &domain) == -1)
continue;
-
if (mutt_idna_to_local (domain, &tmp, 0) == 0)
{
safe_realloc (&a->mailbox, mutt_strlen (user) + mutt_strlen (tmp) + 2);
sprintf (a->mailbox, "%s@%s", NONULL (user), NONULL (tmp)); /* __SPRINTF_CHECKED__ */
+ a->idn_checked = 0;
}
- FREE (&domain);
- FREE (&user);
FREE (&tmp);
}
char *user = NULL;
FREE (&buff);
-
+
+ if (!check_idn (a))
+ return a->mailbox;
if (mbox_to_udomain (a->mailbox, &user, &domain) != 0)
return a->mailbox;
if (mutt_idna_to_local (domain, &tmp, MI_MAY_BE_IRREVERSIBLE) != 0)
{
- FREE (&user);
- FREE (&domain);
FREE (&tmp);
return a->mailbox;
}
safe_realloc (&buff, mutt_strlen (tmp) + mutt_strlen (user) + 2);
sprintf (buff, "%s@%s", NONULL(user), NONULL(tmp)); /* __SPRINTF_CHECKED__ */
FREE (&tmp);
- FREE (&user);
- FREE (&domain);
return buff;
}
{
t = *p;
*p = (*p)->next;
+ alias_delete_reverse (t);
FREE (&t->name);
rfc822_free_address (&t->addr);
FREE (&t);
char *mailbox; /* mailbox and host address */
int group; /* group mailbox? */
struct address_t *next;
+ unsigned is_idn : 1;
+ unsigned idn_checked : 1;
}
ADDRESS;
{
HEADER **ppa = (HEADER **) a;
HEADER **ppb = (HEADER **) b;
- const char *fa, *fb;
+ char fa[SHORT_STRING];
+ const char *fb;
int result;
- fa = safe_strdup (mutt_get_name ((*ppa)->env->to));
+ strfcpy (fa, mutt_get_name ((*ppa)->env->to), SHORT_STRING);
fb = mutt_get_name ((*ppb)->env->to);
- result = mutt_strcasecmp (fa, fb);
- FREE(&fa);
+ result = mutt_strncasecmp (fa, fb, SHORT_STRING);
AUXSORT(result,a,b);
return (SORTCODE (result));
}
{
HEADER **ppa = (HEADER **) a;
HEADER **ppb = (HEADER **) b;
- const char *fa, *fb;
+ char fa[SHORT_STRING];
+ const char *fb;
int result;
- fa = safe_strdup (mutt_get_name ((*ppa)->env->from));
+ strfcpy (fa, mutt_get_name ((*ppa)->env->from), SHORT_STRING);
fb = mutt_get_name ((*ppb)->env->from);
- result = mutt_strcasecmp (fa, fb);
- FREE(&fa);
+ result = mutt_strncasecmp (fa, fb, SHORT_STRING);
AUXSORT(result,a,b);
return (SORTCODE (result));
}