X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=query.c;h=398f3b4b9390d4210ee3aca1ceef3f97dc703087;hp=90dc614178eb0ca3759ebb3e0446ebe01932bd8a;hb=61fec8f6b3bff64d96d016a14729ab1ea2c4a2e8;hpb=f404a0ca916be07049af51a3022baaaaab94def6 diff --git a/query.c b/query.c index 90dc614..398f3b4 100644 --- a/query.c +++ b/query.c @@ -1,74 +1,71 @@ /* + * Copyright notice from original mutt: * Copyright (C) 1996-2000 Michael R. Elkins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - */ + * + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. + */ #if HAVE_CONFIG_H # include "config.h" #endif +#include +#include +#include +#include +#include + #include "mutt.h" #include "mutt_menu.h" #include "mutt_idna.h" -#include "mapping.h" #include "sort.h" +#include "lib/debug.h" + #include #include #include -typedef struct query -{ - ADDRESS *addr; +typedef struct query { + address_t *addr; char *name; char *other; struct query *next; } QUERY; -typedef struct entry -{ +typedef struct entry { int tagged; QUERY *data; } ENTRY; static struct mapping_t QueryHelp[] = { - { N_("Exit"), OP_EXIT }, - { N_("Mail"), OP_MAIL }, - { N_("New Query"), OP_QUERY }, - { N_("Make Alias"), OP_CREATE_ALIAS }, - { N_("Search"), OP_SEARCH }, - { N_("Help"), OP_HELP }, - { NULL } + {N_("Exit"), OP_EXIT}, + {N_("Mail"), OP_MAIL}, + {N_("New Query"), OP_QUERY}, + {N_("Make Alias"), OP_CREATE_ALIAS}, + {N_("Search"), OP_SEARCH}, + {N_("Help"), OP_HELP}, + {NULL, OP_NULL} }; /* Variables for outsizing output format */ static int FirstColumn; static int SecondColumn; -static void query_menu (char *buf, size_t buflen, QUERY *results, int retbuf); +static void query_menu (char *buf, size_t buflen, QUERY * results, + int retbuf); -static ADDRESS *result_to_addr (QUERY *r) +static address_t *result_to_addr (QUERY * r) { - static ADDRESS *tmp; - - tmp = rfc822_cpy_adr (r->addr); - - if(!tmp->next && !tmp->personal) - tmp->personal = safe_strdup (r->name); - + static address_t *tmp; + + tmp = address_list_dup (r->addr); + + if (!tmp->next && !tmp->personal) + tmp->personal = m_strdup(r->name); + mutt_addrlist_to_idna (tmp, NULL); return tmp; } @@ -88,72 +85,65 @@ static QUERY *run_query (char *s, int quiet) int l; - mutt_expand_file_fmt (cmd, sizeof(cmd), QueryCmd, s); + mutt_expand_file_fmt (cmd, sizeof (cmd), QueryCmd, s); - if ((thepid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0) - { - dprint (1, (debugfile, "unable to fork command: %s", cmd)); + if ((thepid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0) { + debug_print (1, ("unable to fork command: %s\n", cmd)); return 0; } if (!quiet) mutt_message _("Waiting for response..."); + fgets (msg, sizeof (msg), fp); if ((p = strrchr (msg, '\n'))) *p = '\0'; - while ((buf = mutt_read_line (buf, &buflen, fp, &dummy)) != NULL) - { - if ((p = strtok(buf, "\t\n"))) - { - if (first == NULL) - { - FirstColumn = 0; - SecondColumn = 0; - first = (QUERY *) safe_calloc (1, sizeof (QUERY)); - cur = first; + while ((buf = mutt_read_line (buf, &buflen, fp, &dummy)) != NULL) { + if ((p = strtok (buf, "\t\n"))) { + if (first == NULL) { + FirstColumn = 0; + SecondColumn = 0; + first = p_new(QUERY, 1); + cur = first; } - else - { - cur->next = (QUERY *) safe_calloc (1, sizeof (QUERY)); - cur = cur->next; + else { + cur->next = p_new(QUERY, 1); + cur = cur->next; } l = mutt_strwidth (p); if (l > SecondColumn) - SecondColumn = l; - + SecondColumn = l; + cur->addr = rfc822_parse_adrlist (cur->addr, p); - p = strtok(NULL, "\t\n"); - if (p) - { - l = mutt_strwidth (p); - if (l > FirstColumn) - FirstColumn = l; - cur->name = safe_strdup (p); - p = strtok(NULL, "\t\n"); - if (p) - { - cur->other = safe_strdup (p); - } + p = strtok (NULL, "\t\n"); + if (p) { + l = mutt_strwidth (p); + if (l > FirstColumn) + FirstColumn = l; + cur->name = m_strdup(p); + p = strtok (NULL, "\t\n"); + if (p) { + cur->other = m_strdup(p); + } } } } - FREE (&buf); + p_delete(&buf); fclose (fp); - if (mutt_wait_filter (thepid)) - { - dprint (1, (debugfile, "Error: %s\n", msg)); - if (!quiet) mutt_error ("%s", msg); + if (mutt_wait_filter (thepid)) { + debug_print (1, ("Error: %s\n", msg)); + if (!quiet) + mutt_error ("%s", msg); } - else - { + else { if (!quiet) mutt_message ("%s", msg); } - + return first; } -static int query_search (MUTTMENU *m, regex_t *re, int n) +static int query_search (MUTTMENU * m, regex_t * re, int n) { ENTRY *table = (ENTRY *) m->data; @@ -161,36 +151,29 @@ static int query_search (MUTTMENU *m, regex_t *re, int n) return 0; if (table[n].data->other && !regexec (re, table[n].data->other, 0, NULL, 0)) return 0; - if (table[n].data->addr) - { - if (table[n].data->addr->personal && - !regexec (re, table[n].data->addr->personal, 0, NULL, 0)) + if (table[n].data->addr) { + if (table[n].data->addr->personal && + !regexec (re, table[n].data->addr->personal, 0, NULL, 0)) return 0; if (table[n].data->addr->mailbox && - !regexec (re, table[n].data->addr->mailbox, 0, NULL, 0)) - return 0; -#ifdef EXACT_ADDRESS - if (table[n].data->addr->val && - !regexec (re, table[n].data->addr->val, 0, NULL, 0)) + !regexec (re, table[n].data->addr->mailbox, 0, NULL, 0)) return 0; -#endif } - + return REG_NOMATCH; } /* This is the callback routine from mutt_menuLoop() which is used to generate * a menu entry for the requested item number. */ -#define QUERY_MIN_COLUMN_LENGHT 20 /* Must be < 70/2 */ -static void query_entry (char *s, size_t slen, MUTTMENU *m, int num) +#define QUERY_MIN_COLUMN_LENGHT 20 /* Must be < 70/2 */ +static void query_entry (char *s, size_t slen, MUTTMENU * m, int num) { ENTRY *table = (ENTRY *) m->data; char buf2[SHORT_STRING], buf[SHORT_STRING] = ""; /* need a query format ... hard coded constants are not good */ - while (FirstColumn + SecondColumn > 70) - { + while (FirstColumn + SecondColumn > 70) { FirstColumn = FirstColumn * 3 / 4; SecondColumn = SecondColumn * 3 / 4; if (FirstColumn < QUERY_MIN_COLUMN_LENGHT) @@ -202,25 +185,23 @@ static void query_entry (char *s, size_t slen, MUTTMENU *m, int num) rfc822_write_address (buf, sizeof (buf), table[num].data->addr, 1); mutt_format_string (buf2, sizeof (buf2), - FirstColumn + 2, FirstColumn + 2, - 0, ' ', table[num].data->name, - mutt_strlen (table[num].data->name), 0); - - snprintf (s, slen, " %c %3d %s %-*.*s %s", - table[num].tagged ? '*':' ', - num+1, - buf2, - SecondColumn+2, - SecondColumn+2, - buf, - NONULL (table[num].data->other)); + FirstColumn + 2, FirstColumn + 2, + 0, ' ', table[num].data->name, + m_strlen(table[num].data->name), 0); + + snprintf (s, slen, " %c %3d %s %-*.*s %s", + table[num].tagged ? '*' : ' ', + num + 1, + buf2, + SecondColumn + 2, + SecondColumn + 2, buf, NONULL (table[num].data->other)); } -static int query_tag (MUTTMENU *menu, int n, int m) +static int query_tag (MUTTMENU * menu, int n, int m) { ENTRY *cur = &((ENTRY *) menu->data)[n]; int ot = cur->tagged; - + cur->tagged = m >= 0 ? m : !cur->tagged; return cur->tagged - ot; } @@ -228,25 +209,23 @@ static int query_tag (MUTTMENU *menu, int n, int m) int mutt_query_complete (char *buf, size_t buflen) { QUERY *results = NULL; - ADDRESS *tmpa; + address_t *tmpa; - if (!QueryCmd) - { + if (!QueryCmd) { mutt_error _("Query command not defined."); + return 0; } results = run_query (buf, 1); - if (results) - { + if (results) { /* only one response? */ - if (results->next == NULL) - { + if (results->next == NULL) { tmpa = result_to_addr (results); mutt_addrlist_to_local (tmpa); buf[0] = '\0'; rfc822_write_address (buf, buflen, tmpa, 0); - rfc822_free_address (&tmpa); + address_delete (&tmpa); mutt_clear_error (); return (0); } @@ -258,25 +237,23 @@ int mutt_query_complete (char *buf, size_t buflen) void mutt_query_menu (char *buf, size_t buflen) { - if (!QueryCmd) - { + if (!QueryCmd) { mutt_error _("Query command not defined."); + return; } - if (buf == NULL) - { + if (buf == NULL) { char buffer[STRING] = ""; query_menu (buffer, sizeof (buffer), NULL, 0); } - else - { + else { query_menu (buf, buflen, NULL, 1); } } -static void query_menu (char *buf, size_t buflen, QUERY *results, int retbuf) +static void query_menu (char *buf, size_t buflen, QUERY * results, int retbuf) { MUTTMENU *menu; HEADER *msg = NULL; @@ -295,234 +272,209 @@ static void query_menu (char *buf, size_t buflen, QUERY *results, int retbuf) menu->tag = query_tag; menu->menu = MENU_QUERY; menu->title = title; - menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_QUERY, QueryHelp); + menu->help = + mutt_compile_help (helpstr, sizeof (helpstr), MENU_QUERY, QueryHelp); - if (results == NULL) - { + if (results == NULL) { /* Prompt for Query */ - if (mutt_get_field (_("Query: "), buf, buflen, 0) == 0 && buf[0]) - { + if (mutt_get_field (_("Query: "), buf, buflen, 0) == 0 && buf[0]) { results = run_query (buf, 0); } } - if (results) - { + if (results) { snprintf (title, sizeof (title), _("Query '%s'"), buf); /* count the number of results */ for (queryp = results; queryp; queryp = queryp->next) menu->max++; - menu->data = QueryTable = (ENTRY *) safe_calloc (menu->max, sizeof (ENTRY)); + menu->data = QueryTable = p_new(ENTRY, menu->max); for (i = 0, queryp = results; queryp; queryp = queryp->next, i++) QueryTable[i].data = queryp; - while (!done) - { - switch ((op = mutt_menuLoop (menu))) - { - case OP_QUERY_APPEND: - case OP_QUERY: - if (mutt_get_field (_("Query: "), buf, buflen, 0) == 0 && buf[0]) - { - QUERY *newresults = NULL; - - newresults = run_query (buf, 0); - - menu->redraw = REDRAW_FULL; - if (newresults) - { - snprintf (title, sizeof (title), _("Query '%s'"), buf); - - if (op == OP_QUERY) - { - queryp = results; - while (queryp) - { - rfc822_free_address (&queryp->addr); - FREE (&queryp->name); - FREE (&queryp->other); - results = queryp->next; - FREE (&queryp); - queryp = results; - } - results = newresults; - FREE (&QueryTable); - } - else - { - /* append */ - for (queryp = results; queryp->next; queryp = queryp->next); - - queryp->next = newresults; - } - - - menu->current = 0; - mutt_menuDestroy (&menu); - menu = mutt_new_menu (); - menu->make_entry = query_entry; - menu->search = query_search; - menu->tag = query_tag; - menu->menu = MENU_QUERY; - menu->title = title; - menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_QUERY, QueryHelp); - - /* count the number of results */ - for (queryp = results; queryp; queryp = queryp->next) - menu->max++; - - if (op == OP_QUERY) - { - menu->data = QueryTable = - (ENTRY *) safe_calloc (menu->max, sizeof (ENTRY)); - - for (i = 0, queryp = results; queryp; - queryp = queryp->next, i++) - QueryTable[i].data = queryp; - } - else - { - int clear = 0; - - /* append */ - safe_realloc (&QueryTable, menu->max * sizeof (ENTRY)); - - menu->data = QueryTable; - - for (i = 0, queryp = results; queryp; - queryp = queryp->next, i++) - { - /* once we hit new entries, clear/init the tag */ - if (queryp == newresults) - clear = 1; - - QueryTable[i].data = queryp; - if (clear) - QueryTable[i].tagged = 0; - } - } - } - } - break; - - case OP_CREATE_ALIAS: - if (menu->tagprefix) - { - ADDRESS *naddr = NULL; - - for (i = 0; i < menu->max; i++) - if (QueryTable[i].tagged) - { - ADDRESS *a = result_to_addr(QueryTable[i].data); - rfc822_append (&naddr, a); - rfc822_free_address (&a); - } - - mutt_create_alias (NULL, naddr); - } - else - { - ADDRESS *a = result_to_addr(QueryTable[menu->current].data); - mutt_create_alias (NULL, a); - rfc822_free_address (&a); - } - break; - - case OP_GENERIC_SELECT_ENTRY: - if (retbuf) - { - done = 2; - break; - } - /* fall through to OP_MAIL */ - - case OP_MAIL: - msg = mutt_new_header (); - msg->env = mutt_new_envelope (); - if (!menu->tagprefix) - { - msg->env->to = result_to_addr(QueryTable[menu->current].data); - } - else - { - for (i = 0; i < menu->max; i++) - if (QueryTable[i].tagged) - { - ADDRESS *a = result_to_addr(QueryTable[i].data); - rfc822_append (&msg->env->to, a); - rfc822_free_address (&a); - } - } - ci_send_message (0, msg, NULL, Context, NULL); - menu->redraw = REDRAW_FULL; - break; - - case OP_EXIT: - done = 1; - break; + while (!done) { + switch ((op = mutt_menuLoop (menu))) { + case OP_QUERY_APPEND: + case OP_QUERY: + if (mutt_get_field (_("Query: "), buf, buflen, 0) == 0 && buf[0]) { + QUERY *newresults = NULL; + + newresults = run_query (buf, 0); + + menu->redraw = REDRAW_FULL; + if (newresults) { + snprintf (title, sizeof (title), _("Query '%s'"), buf); + + if (op == OP_QUERY) { + queryp = results; + while (queryp) { + address_delete (&queryp->addr); + p_delete(&queryp->name); + p_delete(&queryp->other); + results = queryp->next; + p_delete(&queryp); + queryp = results; + } + results = newresults; + p_delete(&QueryTable); + } + else { + /* append */ + for (queryp = results; queryp->next; queryp = queryp->next); + + queryp->next = newresults; + } + + + menu->current = 0; + mutt_menuDestroy (&menu); + menu = mutt_new_menu (); + menu->make_entry = query_entry; + menu->search = query_search; + menu->tag = query_tag; + menu->menu = MENU_QUERY; + menu->title = title; + menu->help = + mutt_compile_help (helpstr, sizeof (helpstr), MENU_QUERY, + QueryHelp); + + /* count the number of results */ + for (queryp = results; queryp; queryp = queryp->next) + menu->max++; + + if (op == OP_QUERY) { + menu->data = QueryTable = p_new(ENTRY, menu->max); + + for (i = 0, queryp = results; queryp; + queryp = queryp->next, i++) + QueryTable[i].data = queryp; + } + else { + int clear = 0; + + /* append */ + p_realloc(&QueryTable, menu->max); + + menu->data = QueryTable; + + for (i = 0, queryp = results; queryp; + queryp = queryp->next, i++) { + /* once we hit new entries, clear/init the tag */ + if (queryp == newresults) + clear = 1; + + QueryTable[i].data = queryp; + if (clear) + QueryTable[i].tagged = 0; + } + } + } + } + break; + + case OP_CREATE_ALIAS: + if (menu->tagprefix) { + address_t *naddr = NULL; + + for (i = 0; i < menu->max; i++) + if (QueryTable[i].tagged) { + address_list_append(&naddr, result_to_addr(QueryTable[i].data)); + } + + mutt_create_alias (NULL, naddr); + } + else { + address_t *a = result_to_addr (QueryTable[menu->current].data); + + mutt_create_alias (NULL, a); + address_delete (&a); + } + break; + + case OP_GENERIC_SELECT_ENTRY: + if (retbuf) { + done = 2; + break; + } + /* fall through to OP_MAIL */ + + case OP_MAIL: + msg = mutt_new_header (); + msg->env = mutt_new_envelope (); + if (!menu->tagprefix) { + msg->env->to = result_to_addr (QueryTable[menu->current].data); + } + else { + for (i = 0; i < menu->max; i++) + if (QueryTable[i].tagged) { + address_list_append(&msg->env->to, result_to_addr(QueryTable[i].data)); + } + } + ci_send_message (0, msg, NULL, Context, NULL); + menu->redraw = REDRAW_FULL; + break; + + case OP_EXIT: + done = 1; + break; } } /* if we need to return the selected entries */ - if (retbuf && (done == 2)) - { + if (retbuf && (done == 2)) { int tagged = 0; size_t curpos = 0; - memset (buf, 0, buflen); + p_clear(buf, buflen); /* check for tagged entries */ - for (i = 0; i < menu->max; i++) - { - if (QueryTable[i].tagged) - { - if (curpos == 0) - { - ADDRESS *tmpa = result_to_addr (QueryTable[i].data); - mutt_addrlist_to_local (tmpa); - tagged = 1; - rfc822_write_address (buf, buflen, tmpa, 0); - curpos = mutt_strlen (buf); - rfc822_free_address (&tmpa); - } - else if (curpos + 2 < buflen) - { - ADDRESS *tmpa = result_to_addr (QueryTable[i].data); - mutt_addrlist_to_local (tmpa); - strcat (buf, ", "); /* __STRCAT_CHECKED__ */ - rfc822_write_address ((char *) buf + curpos + 1, buflen - curpos - 1, - tmpa, 0); - curpos = mutt_strlen (buf); - rfc822_free_address (&tmpa); - } - } + for (i = 0; i < menu->max; i++) { + if (QueryTable[i].tagged) { + if (curpos == 0) { + address_t *tmpa = result_to_addr (QueryTable[i].data); + + mutt_addrlist_to_local (tmpa); + tagged = 1; + rfc822_write_address (buf, buflen, tmpa, 0); + curpos = m_strlen(buf); + address_delete (&tmpa); + } + else if (curpos + 2 < buflen) { + address_t *tmpa = result_to_addr (QueryTable[i].data); + + mutt_addrlist_to_local (tmpa); + strcat (buf, ", "); /* __STRCAT_CHECKED__ */ + rfc822_write_address ((char *) buf + curpos + 1, + buflen - curpos - 1, tmpa, 0); + curpos = m_strlen(buf); + address_delete (&tmpa); + } + } } /* then enter current message */ - if (!tagged) - { - ADDRESS *tmpa = result_to_addr (QueryTable[menu->current].data); - mutt_addrlist_to_local (tmpa); - rfc822_write_address (buf, buflen, tmpa, 0); - rfc822_free_address (&tmpa); + if (!tagged) { + address_t *tmpa = result_to_addr (QueryTable[menu->current].data); + + mutt_addrlist_to_local (tmpa); + rfc822_write_address (buf, buflen, tmpa, 0); + address_delete (&tmpa); } - + } queryp = results; - while (queryp) - { - rfc822_free_address (&queryp->addr); - FREE (&queryp->name); - FREE (&queryp->other); + while (queryp) { + address_delete (&queryp->addr); + p_delete(&queryp->name); + p_delete(&queryp->other); results = queryp->next; - FREE (&queryp); + p_delete(&queryp); queryp = results; } - FREE (&QueryTable); - + p_delete(&QueryTable); + /* tell whoever called me to redraw the screen when I return */ set_option (OPTNEEDREDRAW); }