X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=alias.c;h=65fa6344133c43e3820ae098e43665a56e02055b;hp=f092a8caa04eea7cce8693324982b89d30c0906b;hb=7ff4900e87f7b836b9b5904b420f2818e390a073;hpb=fa7f733a61a6fe3143198791ab470ddf4d08fdbe diff --git a/alias.c b/alias.c index f092a8c..65fa634 100644 --- a/alias.c +++ b/alias.c @@ -11,24 +11,41 @@ # include "config.h" #endif -#include "mutt.h" -#include "mutt_curses.h" -#include "mutt_idna.h" +#include +#include #include "lib/mem.h" #include "lib/intl.h" #include "lib/str.h" #include "lib/rx.h" +#include "lib/debug.h" -#include -#include +#include "mutt.h" +#include "enter.h" +#include "ascii.h" +#include "mutt_curses.h" +#include "mutt_idna.h" +#include "mutt_menu.h" +#include "mapping.h" +#include "sort.h" + +#define RSORT(x) (SortAlias & SORT_REVERSE) ? -x : x + +static struct mapping_t AliasHelp[] = { + {N_("Exit"), OP_EXIT}, + {N_("Del"), OP_DELETE}, + {N_("Undel"), OP_UNDELETE}, + {N_("Select"), OP_GENERIC_SELECT_ENTRY}, + {N_("Help"), OP_HELP}, + {NULL} +}; ADDRESS *mutt_lookup_alias (const char *s) { ALIAS *t = Aliases; for (; t; t = t->next) - if (!mutt_strcasecmp (s, t->name)) + if (!str_casecmp (s, t->name)) return (t->addr); return (NULL); /* no such alias */ } @@ -48,19 +65,16 @@ static ADDRESS *mutt_expand_aliases_r (ADDRESS * a, LIST ** expn) if (t) { i = 0; for (u = *expn; u; u = u->next) { - if (mutt_strcmp (a->mailbox, u->data) == 0) { /* alias already found */ - dprint (1, - (debugfile, - "mutt_expand_aliases_r(): loop in alias found for '%s'\n", - a->mailbox)); + if (str_cmp (a->mailbox, u->data) == 0) { /* alias already found */ + debug_print(1, ("loop in alias found for '%s'\n", a->mailbox)); i = 1; break; } } if (!i) { - u = safe_malloc (sizeof (LIST)); - u->data = safe_strdup (a->mailbox); + u = mem_malloc (sizeof (LIST)); + u->data = str_dup (a->mailbox); u->next = *expn; *expn = u; w = rfc822_cpy_adr (t); @@ -85,11 +99,7 @@ static ADDRESS *mutt_expand_aliases_r (ADDRESS * a, LIST ** expn) char namebuf[STRING]; mutt_gecos_name (namebuf, sizeof (namebuf), pw); - mutt_str_replace (&a->personal, namebuf); - -#ifdef EXACT_ADDRESS - FREE (&a->val); -#endif + str_replace (&a->personal, namebuf); } } } @@ -244,9 +254,9 @@ retry_name: } } - new = safe_calloc (1, sizeof (ALIAS)); + new = mem_calloc (1, sizeof (ALIAS)); new->self = new; - new->name = safe_strdup (buf); + new->name = str_dup (buf); mutt_addrlist_to_local (adr); @@ -282,7 +292,7 @@ retry_name: mutt_free_alias (&new); return; } - new->addr->personal = safe_strdup (buf); + new->addr->personal = str_dup (buf); buf[0] = 0; rfc822_write_address (buf, sizeof (buf), new->addr, 1); @@ -398,7 +408,7 @@ int mutt_alias_complete (char *s, size_t buflen) if (a->name && strstr (a->name, s) == a->name) { if (!bestname[0]) /* init */ strfcpy (bestname, a->name, - min (mutt_strlen (a->name) + 1, sizeof (bestname))); + min (str_len (a->name) + 1, sizeof (bestname))); else { for (i = 0; a->name[i] && a->name[i] == bestname[i]; i++); bestname[i] = 0; @@ -408,9 +418,9 @@ int mutt_alias_complete (char *s, size_t buflen) } if (bestname[0] != 0) { - if (mutt_strcmp (bestname, s) != 0) { + if (str_cmp (bestname, s) != 0) { /* we are adding something to the completion */ - strfcpy (s, bestname, mutt_strlen (bestname) + 1); + strfcpy (s, bestname, str_len (bestname) + 1); return 1; } @@ -420,9 +430,9 @@ int mutt_alias_complete (char *s, size_t buflen) while (a) { if (a->name && (strstr (a->name, s) == a->name)) { if (!a_list) /* init */ - a_cur = a_list = (ALIAS *) safe_malloc (sizeof (ALIAS)); + a_cur = a_list = (ALIAS *) mem_malloc (sizeof (ALIAS)); else { - a_cur->next = (ALIAS *) safe_malloc (sizeof (ALIAS)); + a_cur->next = (ALIAS *) mem_malloc (sizeof (ALIAS)); a_cur = a_cur->next; } memcpy (a_cur, a, sizeof (ALIAS)); @@ -442,7 +452,7 @@ int mutt_alias_complete (char *s, size_t buflen) while (a_list) { a_cur = a_list; a_list = a_list->next; - FREE (&a_cur); + mem_free (&a_cur); } /* remove any aliases marked for deletion */ @@ -487,59 +497,239 @@ int mutt_addr_is_user (ADDRESS * addr) { /* NULL address is assumed to be the user. */ if (!addr) { - dprint (5, (debugfile, "mail_addr_is_user: yes, NULL address\n")); + debug_print(5, ("yes, NULL address\n")); return 1; } if (!addr->mailbox) { - dprint (5, (debugfile, "mail_addr_is_user: no, no mailbox\n")); + debug_print(5, ("no, no mailbox\n")); return 0; } if (ascii_strcasecmp (addr->mailbox, Username) == 0) { - dprint (5, - (debugfile, "mail_addr_is_user: yes, %s = %s\n", addr->mailbox, - Username)); + debug_print(5, ("yes, %s = %s\n", addr->mailbox, Username)); return 1; } if (string_is_address (addr->mailbox, Username, Hostname)) { - dprint (5, - (debugfile, "mail_addr_is_user: yes, %s = %s @ %s \n", - addr->mailbox, Username, Hostname)); + debug_print(5, ("yes, %s = %s @ %s \n", addr->mailbox, Username, Hostname)); return 1; } if (string_is_address (addr->mailbox, Username, mutt_fqdn (0))) { - dprint (5, - (debugfile, "mail_addr_is_user: yes, %s = %s @ %s \n", - addr->mailbox, Username, mutt_fqdn (0))); + debug_print(5, ("yes, %s = %s @ %s \n", addr->mailbox, Username, mutt_fqdn (0))); return 1; } if (string_is_address (addr->mailbox, Username, mutt_fqdn (1))) { - dprint (5, - (debugfile, "mail_addr_is_user: yes, %s = %s @ %s \n", - addr->mailbox, Username, mutt_fqdn (1))); + debug_print(5, ("yes, %s = %s @ %s \n", addr->mailbox, Username, mutt_fqdn (1))); return 1; } if (From && !ascii_strcasecmp (From->mailbox, addr->mailbox)) { - dprint (5, - (debugfile, "mail_addr_is_user: yes, %s = %s\n", addr->mailbox, - From->mailbox)); + debug_print(5, ("yes, %s = %s\n", addr->mailbox, From->mailbox)); return 1; } if (rx_list_match (Alternates, addr->mailbox)) { - dprint (5, - (debugfile, "mail_addr_is_user: yes, %s matched by alternates.\n", - addr->mailbox)); + debug_print(5, ("yes, %s matched by alternates.\n", addr->mailbox)); if (rx_list_match (UnAlternates, addr->mailbox)) - dprint (5, - (debugfile, - "mail_addr_is_user: but, %s matched by unalternates.\n", - addr->mailbox)); + debug_print(5, ("but, %s matched by unalternates.\n", addr->mailbox)); else return 1; } - dprint (5, (debugfile, "mail_addr_is_user: no, all failed.\n")); + debug_print(5, ("no, all failed.\n")); return 0; } + +static const char *alias_format_str (char *dest, size_t destlen, char op, + const char *src, const char *fmt, + const char *ifstring, + const char *elsestring, + unsigned long data, format_flag flags) +{ + char tmp[SHORT_STRING], adr[SHORT_STRING]; + ALIAS *alias = (ALIAS *) data; + + switch (op) { + case 'f': + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, alias->del ? "D" : " "); + break; + case 'a': + mutt_format_s (dest, destlen, fmt, alias->name); + break; + case 'r': + adr[0] = 0; + rfc822_write_address (adr, sizeof (adr), alias->addr, 1); + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, adr); + break; + case 'n': + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, alias->num + 1); + break; + case 't': + dest[0] = alias->tagged ? '*' : ' '; + dest[1] = 0; + break; + } + + return (src); +} + +static void alias_entry (char *s, size_t slen, MUTTMENU * m, int num) +{ + mutt_FormatString (s, slen, NONULL (AliasFmt), alias_format_str, + (unsigned long) ((ALIAS **) m->data)[num], + M_FORMAT_ARROWCURSOR); +} + +static int alias_tag (MUTTMENU * menu, int n, int m) +{ + ALIAS *cur = ((ALIAS **) menu->data)[n]; + int ot = cur->tagged; + + cur->tagged = (m >= 0 ? m : !cur->tagged); + + return cur->tagged - ot; +} + +static int alias_SortAlias (const void *a, const void *b) +{ + ALIAS *pa = *(ALIAS **) a; + ALIAS *pb = *(ALIAS **) b; + int r = str_casecmp (pa->name, pb->name); + + return (RSORT (r)); +} + +static int alias_SortAddress (const void *a, const void *b) +{ + ADDRESS *pa = (*(ALIAS **) a)->addr; + ADDRESS *pb = (*(ALIAS **) b)->addr; + int r; + + if (pa == pb) + r = 0; + else if (pa == NULL) + r = -1; + else if (pb == NULL) + r = 1; + else if (pa->personal) { + if (pb->personal) + r = str_casecmp (pa->personal, pb->personal); + else + r = 1; + } + else if (pb->personal) + r = -1; + else + r = ascii_strcasecmp (pa->mailbox, pb->mailbox); + return (RSORT (r)); +} + +void mutt_alias_menu (char *buf, size_t buflen, ALIAS * aliases) +{ + ALIAS *aliasp; + MUTTMENU *menu; + ALIAS **AliasTable = NULL; + int t = -1; + int i, done = 0; + int op; + char helpstr[SHORT_STRING]; + + int omax; + + if (!aliases) { + mutt_error _("You have no aliases!"); + + return; + } + + /* tell whoever called me to redraw the screen when I return */ + set_option (OPTNEEDREDRAW); + + menu = mutt_new_menu (); + menu->make_entry = alias_entry; + menu->tag = alias_tag; + menu->menu = MENU_ALIAS; + menu->title = _("Aliases"); + menu->help = + mutt_compile_help (helpstr, sizeof (helpstr), MENU_ALIAS, AliasHelp); + +new_aliases: + + omax = menu->max; + + /* count the number of aliases */ + for (aliasp = aliases; aliasp; aliasp = aliasp->next) { + aliasp->self->del = 0; + aliasp->self->tagged = 0; + menu->max++; + } + + mem_realloc (&AliasTable, menu->max * sizeof (ALIAS *)); + menu->data = AliasTable; + + for (i = omax, aliasp = aliases; aliasp; aliasp = aliasp->next, i++) { + AliasTable[i] = aliasp->self; + aliases = aliasp; + } + + if ((SortAlias & SORT_MASK) != SORT_ORDER) { + qsort (AliasTable, i, sizeof (ALIAS *), + (SortAlias & SORT_MASK) == + SORT_ADDRESS ? alias_SortAddress : alias_SortAlias); + } + + for (i = 0; i < menu->max; i++) + AliasTable[i]->num = i; + + while (!done) { + if (aliases->next) { + menu->redraw |= REDRAW_FULL; + aliases = aliases->next; + goto new_aliases; + } + + switch ((op = mutt_menuLoop (menu))) { + case OP_DELETE: + case OP_UNDELETE: + if (menu->tagprefix) { + for (i = 0; i < menu->max; i++) + if (AliasTable[i]->tagged) + AliasTable[i]->del = (op == OP_DELETE) ? 1 : 0; + menu->redraw |= REDRAW_INDEX; + } + else { + AliasTable[menu->current]->self->del = (op == OP_DELETE) ? 1 : 0; + menu->redraw |= REDRAW_CURRENT; + if (option (OPTRESOLVE) && menu->current < menu->max - 1) { + menu->current++; + menu->redraw |= REDRAW_INDEX; + } + } + break; + case OP_GENERIC_SELECT_ENTRY: + t = menu->current; + case OP_EXIT: + done = 1; + break; + } + } + + for (i = 0; i < menu->max; i++) { + if (AliasTable[i]->tagged) { + mutt_addrlist_to_local (AliasTable[i]->addr); + rfc822_write_address (buf, buflen, AliasTable[i]->addr, 0); + t = -1; + } + } + + if (t != -1) { + mutt_addrlist_to_local (AliasTable[t]->addr); + rfc822_write_address (buf, buflen, AliasTable[t]->addr, 0); + } + + mutt_menuDestroy (&menu); + mem_free (&AliasTable); + +}