From: Thomas Roessler Date: Tue, 11 Sep 2001 11:20:34 +0000 (+0000) Subject: The addressbook used to crash when someone issued the alias and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=34a7399b2239f619dc20aabcc45b90f9ca8af110;p=neomutt The addressbook used to crash when someone issued the alias and unalias commands while on that menu. This patch has a basic fix for this behaviour, and adds delete and undelete functions to this menu. While I'm on it, I've also made sure that "apply-tag" untags everything on all menus. The original crash was noted by Oliver Kauss . --- diff --git a/addrbook.c b/addrbook.c index 99c973cda..7c738841e 100644 --- a/addrbook.c +++ b/addrbook.c @@ -44,6 +44,10 @@ alias_format_str (char *dest, size_t destlen, char op, const char *src, switch (op) { + case 'f': + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, alias->del ? "D" : " "); + break; case 'a': snprintf (tmp, sizeof (tmp), "%%%ss", fmt); snprintf (dest, destlen, tmp, alias->name); @@ -72,9 +76,14 @@ 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); } -int alias_tag (MUTTMENU *menu, int n) +int alias_tag (MUTTMENU *menu, int n, int m) { - return ((((ALIAS **) menu->data)[n]->tagged = !((ALIAS **) menu->data)[n]->tagged) ? 1 : -1); + 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) @@ -108,11 +117,12 @@ static int alias_SortAddress (const void *a, const void *b) void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) { - ALIAS *aliasp; + ALIAS *aliasp, *aliasl; MUTTMENU *menu; ALIAS **AliasTable = NULL; int t = -1; int i, done = 0; + int op; char helpstr[SHORT_STRING]; if (!aliases) @@ -124,6 +134,9 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) /* tell whoever called me to redraw the screen when I return */ set_option (OPTNEEDREDRAW); + /* tell mutt_alias and mutt_unalias that this menu is active */ + set_option (OPTALIASMENU); + menu = mutt_new_menu (); menu->make_entry = alias_entry; menu->tag = alias_tag; @@ -134,6 +147,7 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) /* count the number of aliases */ for (aliasp = aliases; aliasp; aliasp = aliasp->next) { + aliasp->del = 0; aliasp->tagged = 0; menu->max++; } @@ -153,8 +167,28 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) while (!done) { - switch (mutt_menuLoop (menu)) + 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]->del = (op == OP_DELETE) ? 1 : 0; + menu->redraw |= REDRAW_CURRENT; + if (option (OPTRESOLVE) && menu->current < menu->max - 1) + { + menu->current++; + menu->redraw |= REDRAW_MOTION; + } + } + break; case OP_GENERIC_SELECT_ENTRY: t = menu->current; case OP_EXIT: @@ -174,7 +208,33 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases) if(t != -1) rfc822_write_address (buf, buflen, AliasTable[t]->addr); - + mutt_menuDestroy (&menu); safe_free ((void **) &AliasTable); + + unset_option (OPTALIASMENU); + + /* remove aliases marked for deletion. */ + aliasl = NULL; + for (aliasp = Aliases; aliasp; aliasp = aliasp->next) + { + if (aliasp->del) + { + if (aliasl) + aliasl->next = aliasp->next; + else + Aliases = aliasp->next; + + aliasp->next = NULL; + mutt_free_alias (&aliasp); + + if (aliasl) + aliasp = aliasl; + else + aliasp = Aliases; + } + else + aliasl = aliasp; + } + } diff --git a/attach.h b/attach.h index 3e1cffdf7..5b84ac0c2 100644 --- a/attach.h +++ b/attach.h @@ -18,7 +18,7 @@ /* common protos for compose / attach menus */ -int mutt_tag_attach (MUTTMENU *menu, int n); +int mutt_tag_attach (MUTTMENU *menu, int n, int m); int mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr, BODY *cur, ATTACHPTR ***idxp, short *idxlen, short *idxmax, int recv); diff --git a/browser.c b/browser.c index 7d259dd70..a195299d8 100644 --- a/browser.c +++ b/browser.c @@ -507,16 +507,20 @@ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title, menu->redraw = REDRAW_FULL; } -int file_tag (MUTTMENU *menu, int n) +int file_tag (MUTTMENU *menu, int n, int m) { struct folder_file *ff = &(((struct folder_file *)menu->data)[n]); + int ot; if (S_ISDIR (ff->mode) || (S_ISLNK (ff->mode) && link_is_dir (LastDir, ff->name))) { mutt_error _("Can't attach a directory!"); return 0; } - return ((ff->tagged = !ff->tagged) ? 1 : -1); + ot = ff->tagged; + ff->tagged = (m >= 0 ? m : !ff->tagged); + + return ff->tagged - ot; } void _mutt_select_file (char *f, size_t flen, int flags, char ***files, int *numfiles) diff --git a/functions.h b/functions.h index f1f813b6a..aa54ed697 100644 --- a/functions.h +++ b/functions.h @@ -328,6 +328,13 @@ struct binding_t OpPost[] = { { NULL, 0, NULL } }; +struct binding_t OpAlias[] = { + { "delete-entry", OP_DELETE, "d" }, + { "undelete-entry", OP_UNDELETE, "u" }, + { NULL, 0, NULL } +}; + + /* The file browser */ struct binding_t OpBrowser[] = { { "change-dir", OP_CHANGE_DIRECTORY, "c" }, diff --git a/init.c b/init.c index 8f57ff5e9..46c4c5139 100644 --- a/init.c +++ b/init.c @@ -428,11 +428,17 @@ static int parse_unalias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *er { mutt_extract_token (buf, s, 0); - tmp = Aliases; for (tmp = Aliases; tmp; tmp = tmp->next) { if (mutt_strcasecmp (buf->data, tmp->name) == 0) { + if (option (OPTALIASMENU)) + { + tmp->del = 1; + set_option (OPTFORCEREDRAWINDEX); + break; + } + if (last) last->next = tmp->next; else @@ -483,6 +489,8 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { /* override the previous value */ rfc822_free_address (&tmp->addr); + if (option (OPTALIASMENU)) + set_option (OPTFORCEREDRAWINDEX); } s->dptr = p; diff --git a/init.h b/init.h index 20427ad6d..678b44e5d 100644 --- a/init.h +++ b/init.h @@ -127,7 +127,7 @@ struct option_t MuttVars[] = { ** \fBNote:\fP Mutt will not automatically source this file; you must ** explicitly use the ``$source'' command for it to be executed. */ - { "alias_format", DT_STR, R_NONE, UL &AliasFmt, UL "%4n %t %-10a %r" }, + { "alias_format", DT_STR, R_NONE, UL &AliasFmt, UL "%4n %2f %t %-10a %r" }, /* ** .pp ** Specifies the format of the data displayed for the `alias' menu. The @@ -135,6 +135,7 @@ struct option_t MuttVars[] = { ** .pp ** .dl ** .dt %a .dd alias name + ** .dt %f .dd flags - currently, a "d" for an alias marked for deletion ** .dt %n .dd index number ** .dt %r .dd address which alias expands to ** .dt %t .dd character which indicates if the alias is tagged for inclusion diff --git a/keymap.c b/keymap.c index 7b48e97ef..e7d90aa8d 100644 --- a/keymap.c +++ b/keymap.c @@ -526,7 +526,7 @@ void km_init (void) create_bindings (OpPager, MENU_PAGER); create_bindings (OpPost, MENU_POST); create_bindings (OpQuery, MENU_QUERY); - + create_bindings (OpAlias, MENU_ALIAS); #ifdef HAVE_PGP diff --git a/keymap.h b/keymap.h index 040e354dd..34937e755 100644 --- a/keymap.h +++ b/keymap.h @@ -100,6 +100,7 @@ extern struct binding_t OpCompose[]; extern struct binding_t OpBrowser[]; extern struct binding_t OpEditor[]; extern struct binding_t OpQuery[]; +extern struct binding_t OpAlias[]; #ifdef HAVE_PGP extern struct binding_t OpPgp[]; diff --git a/menu.c b/menu.c index 19d36a5e7..b0d9762c7 100644 --- a/menu.c +++ b/menu.c @@ -966,9 +966,15 @@ int mutt_menuLoop (MUTTMENU *menu) case OP_TAG: if (menu->tag && !menu->dialog) { - if (menu->max) + if (menu->tagprefix && !option (OPTAUTOTAG)) { - int i = menu->tag (menu, menu->current); + for (i = 0; i < menu->max; i++) + menu->tagged += menu->tag (menu, i, 0); + menu->redraw = REDRAW_INDEX; + } + else if (menu->max) + { + int i = menu->tag (menu, menu->current, -1); menu->tagged += i; if (i && option (OPTRESOLVE) && menu->current < menu->max - 1) { diff --git a/mutt.h b/mutt.h index dcf25df9b..acb179cde 100644 --- a/mutt.h +++ b/mutt.h @@ -442,6 +442,7 @@ enum * functions while we are executing an * external program. */ + OPTALIASMENU, /* (pseudo) alias menu active */ #ifdef HAVE_PGP OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */ OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */ @@ -489,6 +490,7 @@ typedef struct alias ADDRESS *addr; struct alias *next; short tagged; + short del; short num; } ALIAS; diff --git a/mutt_menu.h b/mutt_menu.h index 13e01b631..ee44248a5 100644 --- a/mutt_menu.h +++ b/mutt_menu.h @@ -62,7 +62,7 @@ typedef struct menu_t /* how to search the menu */ int (*search) (struct menu_t *, regex_t *re, int n); - int (*tag) (struct menu_t *, int i); + int (*tag) (struct menu_t *, int i, int m); /* color pair to be used for the requested element * (default function returns ColorDefs[MT_COLOR_NORMAL]) diff --git a/recvattach.c b/recvattach.c index c41fa2ce8..6039f48f5 100644 --- a/recvattach.c +++ b/recvattach.c @@ -354,9 +354,13 @@ void attach_entry (char *b, size_t blen, MUTTMENU *menu, int num) mutt_FormatString (b, blen, NONULL (AttachFormat), mutt_attach_fmt, (unsigned long) (((ATTACHPTR **)menu->data)[num]), M_FORMAT_ARROWCURSOR); } -int mutt_tag_attach (MUTTMENU *menu, int n) +int mutt_tag_attach (MUTTMENU *menu, int n, int m) { - return ((((ATTACHPTR **) menu->data)[n]->content->tagged = !((ATTACHPTR **) menu->data)[n]->content->tagged) ? 1 : -1); + BODY *cur = ((ATTACHPTR **) menu->data)[n]->content; + int ot = cur->tagged; + + cur->tagged = (m >= 0 ? m : !cur->tagged); + return cur->tagged - ot; } int mutt_is_message_type (int type, const char *subtype)