From a41c8d168ec2c9c941d7d9b9b6da489115d6b255 Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Fri, 7 May 2010 21:12:49 -0400 Subject: [PATCH 1/4] owl_function_zuserfilt: Don't leak the filter name. --- functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions.c b/functions.c index 973f84ca6..8a58638be 100644 --- a/functions.c +++ b/functions.c @@ -2388,7 +2388,7 @@ char *owl_function_zuserfilt(const char *user) /* if it already exists then go with it. This lets users override */ if (owl_global_get_filter(&g, filtname)) { - return(owl_strdup(filtname)); + return filtname; } /* create the new-internal filter */ From 839697d886ff0c8987d4f6233e92a81a5157faed Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Fri, 7 May 2010 20:31:20 -0400 Subject: [PATCH 2/4] Make owl_message_get_cc_without_recipient return a GList. Signed-off-by: Nelson Elhage --- logging.c | 41 ++++++++++++++++++++--------------------- message.c | 17 ++++------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/logging.c b/logging.c index d9a61721b..8738ef797 100644 --- a/logging.c +++ b/logging.c @@ -127,6 +127,7 @@ void owl_log_outgoing(const owl_message *m) { char filename[MAXPATHLEN], *logpath; char *to, *temp; + GList *cc; /* expand ~ in path names */ logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g)); @@ -134,17 +135,16 @@ void owl_log_outgoing(const owl_message *m) /* Figure out what path to log to */ if (owl_message_is_type_zephyr(m)) { /* If this has CC's, do all but the "recipient" which we'll do below */ - to = owl_message_get_cc_without_recipient(m); - if (to != NULL) { - temp = strtok(to, " "); - while (temp != NULL) { - temp = short_zuser(temp); - snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp); - owl_log_append(m, filename); - temp = strtok(NULL, " "); - } - owl_free(to); + cc = owl_message_get_cc_without_recipient(m); + while (cc != NULL) { + temp = short_zuser(cc->data); + snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp); + owl_log_append(m, filename); + + owl_free(cc->data); + cc = g_list_delete_link(cc, cc); } + to = short_zuser(owl_message_get_recipient(m)); } else if (owl_message_is_type_jabber(m)) { to = owl_sprintf("jabber:%s", owl_message_get_recipient(m)); @@ -324,19 +324,18 @@ void owl_log_incoming(const owl_message *m) /* We want to log to all of the CC'd people who were not us, or * the sender, as well. */ - char *cc, *temp; + char *temp; + GList *cc; cc = owl_message_get_cc_without_recipient(m); - if (cc != NULL) { - temp = strtok(cc, " "); - while (temp != NULL) { - temp = short_zuser(temp); - if (strcasecmp(temp, frombuff) != 0) { - snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp); - owl_log_append(m, filename); - } - temp = strtok(NULL, " "); + while (cc != NULL) { + temp = short_zuser(cc->data); + if (strcasecmp(temp, frombuff) != 0) { + snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp); + owl_log_append(m, filename); } - owl_free(cc); + + owl_free(cc->data); + cc = g_list_delete_link(cc, cc); } } diff --git a/message.c b/message.c index 9506afaa7..69a7a75cc 100644 --- a/message.c +++ b/message.c @@ -583,40 +583,31 @@ char *owl_message_get_cc(const owl_message *m) } /* caller must free return value */ -char *owl_message_get_cc_without_recipient(const owl_message *m) +GList *owl_message_get_cc_without_recipient(const owl_message *m) { - char *cc, *out, *end, *shortuser, *recip; + char *cc, *shortuser, *recip; const char *user; + GList *out = NULL; cc = owl_message_get_cc(m); if (cc == NULL) return NULL; recip = short_zuser(owl_message_get_recipient(m)); - out = owl_malloc(strlen(cc) + 2); - end = out; user = strtok(cc, " "); while (user != NULL) { shortuser = short_zuser(user); if (strcasecmp(shortuser, recip) != 0) { - strcpy(end, user); - end[strlen(user)] = ' '; - end += strlen(user) + 1; + out = g_list_prepend(out, owl_strdup(user)); } owl_free(shortuser); user = strtok(NULL, " "); } - end[0] = '\0'; owl_free(recip); owl_free(cc); - if (strlen(out) == 0) { - owl_free(out); - out = NULL; - } - return(out); } From 4727d311dfe0434995c547f09b2c108b7c3371fe Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Fri, 7 May 2010 20:44:07 -0400 Subject: [PATCH 3/4] Cache Zephyr CCs into an attribute on the message object. --- message.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/message.c b/message.c index 69a7a75cc..c01ab8bd8 100644 --- a/message.c +++ b/message.c @@ -724,6 +724,41 @@ void owl_message_create_loopback(owl_message *m, const char *text) owl_message_set_isprivate(m); } +void owl_message_save_ccs(owl_message *m) { + GList *cc; + char *tmp; + + cc = owl_message_get_cc_without_recipient(m); + + if (cc != NULL) { + GString *recips = g_string_new(""); + cc = g_list_prepend(cc, short_zuser(owl_message_get_sender(m))); + cc = g_list_prepend(cc, short_zuser(owl_message_get_recipient(m))); + cc = g_list_sort(cc, (GCompareFunc)strcasecmp); + + while(cc != NULL) { + /* Collapse any identical entries */ + while (cc->next && strcasecmp(cc->data, cc->next->data) == 0) { + owl_free(cc->data); + cc = g_list_delete_link(cc, cc); + } + + tmp = short_zuser(cc->data); + g_string_append(recips, tmp); + + owl_free(tmp); + owl_free(cc->data); + cc = g_list_delete_link(cc, cc); + + if (cc) + g_string_append_c(recips, ' '); + } + + owl_message_set_attribute(m, "zephyr_ccs", recips->str); + g_string_free(recips, true); + } +} + #ifdef HAVE_LIBZEPHYR void owl_message_create_from_znotice(owl_message *m, const ZNotice_t *n) { @@ -859,6 +894,8 @@ void owl_message_create_from_znotice(owl_message *m, const ZNotice_t *n) owl_free(out); } } + + owl_message_save_ccs(m); } #else void owl_message_create_from_znotice(owl_message *m, const void *n) @@ -953,6 +990,8 @@ void owl_message_create_from_zwrite(owl_message *m, const owl_zwrite *z, const c if (owl_zwrite_is_personal(z)) { owl_message_set_isprivate(m); } + + owl_message_save_ccs(m); } void owl_message_cleanup(owl_message *m) From ecaec2163c1c65f306cb1ce7b5c56c3d2c3096ca Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Fri, 7 May 2010 21:19:09 -0400 Subject: [PATCH 4/4] Make smartnarrow work better on CC:'d personals --- functions.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/functions.c b/functions.c index 8a58638be..2e126403a 100644 --- a/functions.c +++ b/functions.c @@ -2505,6 +2505,34 @@ void owl_function_delete_curview_msgs(int flag) owl_mainwin_redisplay(owl_global_get_mainwin(&g)); } +static char *owl_function_smartfilter_cc(const owl_message *m) { + const char *ccs; + char *filtname; + char *text; + owl_filter *f; + + ccs = owl_message_get_attribute_value(m, "zephyr_ccs"); + + filtname = owl_sprintf("conversation-%s", ccs); + owl_text_tr(filtname, ' ', '-'); + + if (owl_global_get_filter(&g, filtname)) { + return filtname; + } + + text = owl_sprintf("type ^zephyr$ and filter personal and " + "zephyr_ccs ^%s%s%s$", + owl_getquoting(ccs), ccs, owl_getquoting(ccs)); + + f = owl_filter_new_fromstring(filtname, text); + + owl_global_add_filter(&g, f); + + owl_free(text); + + return filtname; +} + /* Create a filter based on the current message. Returns the name of * a filter or null. The caller must free this name. * @@ -2558,6 +2586,10 @@ char *owl_function_smartfilter(int type, int invert_related) /* narrow personal and login messages to the sender or recip as appropriate */ if (owl_message_is_type_zephyr(m)) { if (owl_message_is_personal(m) || owl_message_is_loginout(m)) { + if (owl_message_get_attribute_value(m, "zephyr_ccs") != NULL) { + return owl_function_smartfilter_cc(m); + } + if (owl_message_is_direction_in(m)) { zperson=short_zuser(owl_message_get_sender(m)); } else {