From 6bd367602d03b94be863c6c8eda932130c918888 Mon Sep 17 00:00:00 2001 From: Melvin Hadasht Date: Mon, 5 Aug 2002 23:50:37 +0000 Subject: [PATCH] src/account.[ch] account_find_all_from_address(): new function that returns the list of all accounts that are matched in an address. src/alertpanel.[ch] alertpanel() now accepts a custom widget alertpanel_with_widget(): new function that pops up a panel with a custom widget in it src/gtkutils.[ch] gtkut_account_menu_new(): new function that allows the selection of an account from a list of accounts. src/messageview.c Extended Return Receipt notification to select the correct account and to make a security test on the Delivery-Notification address which should be the same as the Return-Path --- ChangeLog.claws | 17 +++++++ configure.in | 2 +- src/account.c | 27 +++++++++++ src/account.h | 2 + src/alertpanel.c | 45 ++++++++++++++--- src/alertpanel.h | 7 +++ src/gtkutils.c | 38 +++++++++++++++ src/gtkutils.h | 4 ++ src/messageview.c | 120 ++++++++++++++++++++++++++++++++++++++++------ 9 files changed, 240 insertions(+), 22 deletions(-) diff --git a/ChangeLog.claws b/ChangeLog.claws index daf192fa7..96a1f5910 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,20 @@ +2002-08-06 [melvin] 0.8.0claws19 + + * src/account.[ch] + account_find_all_from_address(): new function that returns the + list of all accounts that are matched in an address. + * src/alertpanel.[ch] + alertpanel() now accepts a custom widget + alertpanel_with_widget(): new function that pops up a panel with + a custom widget in it + * src/gtkutils.[ch] + gtkut_account_menu_new(): new function that allows the selection + of an account from a list of accounts. + * src/messageview.c + Extended Return Receipt notification to select the correct + account and to make a security test on the Delivery-Notification + address which should be the same as the Return-Path. + 2002-08-06 [thorsten] 0.8.0claws18 * src/mimeview.c diff --git a/configure.in b/configure.in index a367075b7..39e6acd1c 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ MINOR_VERSION=8 MICRO_VERSION=1 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=claws18 +EXTRA_VERSION=claws19 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION dnl set $target diff --git a/src/account.c b/src/account.c index 54a75f836..0bc5e8375 100644 --- a/src/account.c +++ b/src/account.c @@ -227,6 +227,33 @@ PrefsAccount *account_find_from_id(gint id) return NULL; } +/* + * account_find_all_from_address: + * @ac_list: initial list of accounts. NULL to create a new one. + * Accounts found in the @address will be appended to this list. + * @address: Email address string. + * + * Find all the mail (not news) accounts within the specified address. + * + * Return value: the original accounts list with the found accounts appended. + */ +GList *account_find_all_from_address(GList *ac_list, const gchar *address) +{ + GList *cur; + PrefsAccount *ac; + + if (address == NULL) + return ac_list; + + for (cur = account_list; cur != NULL; cur = cur->next) { + ac = (PrefsAccount *)cur->data; + if (ac->protocol != A_NNTP && ac->address && + strcasestr(address, ac->address) != NULL) + ac_list = g_list_append(ac_list, ac); + } + return ac_list; +} + void account_set_menu(void) { main_window_set_account_menu(account_list); diff --git a/src/account.h b/src/account.h index c77aff397..9c3d8f41c 100644 --- a/src/account.h +++ b/src/account.h @@ -38,6 +38,8 @@ PrefsAccount *account_find_from_smtp_server (const gchar *address, const gchar *smtp_server); PrefsAccount *account_find_from_address (const gchar *address); PrefsAccount *account_find_from_id (gint id); +GList *account_find_all_from_address (GList *ac_list, + const gchar *address); void account_set_menu (void); diff --git a/src/alertpanel.c b/src/alertpanel.c index 2b93d8a70..4e32da385 100644 --- a/src/alertpanel.c +++ b/src/alertpanel.c @@ -50,7 +50,8 @@ static void alertpanel_create (const gchar *title, const gchar *button1_label, const gchar *button2_label, const gchar *button3_label, - gboolean can_disable); + gboolean can_disable, + GtkWidget *custom_widget); static void alertpanel_button_toggled (GtkToggleButton *button, gpointer data); @@ -75,13 +76,31 @@ AlertValue alertpanel(const gchar *title, alertpanel_is_open = TRUE; alertpanel_create(title, message, button1_label, button2_label, - button3_label, FALSE); + button3_label, FALSE, NULL); alertpanel_show(); debug_print("return value = %d\n", value); return value; } +AlertValue alertpanel_with_widget(const gchar *title, + const gchar *message, + const gchar *button1_label, + const gchar *button2_label, + const gchar *button3_label, + GtkWidget *widget) +{ + if (alertpanel_is_open) + return -1; + else + alertpanel_is_open = TRUE; + alertpanel_create(title, message, button1_label, button2_label, + button3_label, FALSE, widget); + alertpanel_show(); + + debug_print("return value = %d\n", value); + return value; +} void alertpanel_message(const gchar *title, const gchar *message) { if (alertpanel_is_open) @@ -89,7 +108,7 @@ void alertpanel_message(const gchar *title, const gchar *message) else alertpanel_is_open = TRUE; - alertpanel_create(title, message, NULL, NULL, NULL, FALSE); + alertpanel_create(title, message, NULL, NULL, NULL, FALSE, NULL); alertpanel_show(); } @@ -101,7 +120,7 @@ AlertValue alertpanel_message_with_disable(const gchar *title, else alertpanel_is_open = TRUE; - alertpanel_create(title, message, NULL, NULL, NULL, TRUE); + alertpanel_create(title, message, NULL, NULL, NULL, TRUE, NULL); alertpanel_show(); return value; @@ -170,13 +189,15 @@ static void alertpanel_create(const gchar *title, const gchar *button1_label, const gchar *button2_label, const gchar *button3_label, - gboolean can_disable) + gboolean can_disable, + GtkWidget *custom_widget) { static GdkFont *titlefont; GtkStyle *style; GtkWidget *label; GtkWidget *hbox; GtkWidget *vbox; + GtkWidget *vbox2; GtkWidget *disable_chkbtn; GtkWidget *confirm_area; GtkWidget *button1; @@ -223,17 +244,27 @@ static void alertpanel_create(const gchar *title, vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), vbox); + vbox2 = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox2), 20); + gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0); /* for message label */ hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 20); + gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0); /* message label */ label = gtk_label_new(message); - gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 32); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 12); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); + /* custom widget */ + if (custom_widget) { + GtkWidget *hbox2 = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox2), custom_widget, FALSE, FALSE, + 12); + } /* for button(s) */ if (!button1_label) button1_label = _("OK"); diff --git a/src/alertpanel.h b/src/alertpanel.h index 956f992c5..01fbcc501 100644 --- a/src/alertpanel.h +++ b/src/alertpanel.h @@ -41,6 +41,13 @@ AlertValue alertpanel (const gchar *title, const gchar *button2_label, const gchar *button3_label); +AlertValue alertpanel_with_widget (const gchar *title, + const gchar *message, + const gchar *button1_label, + const gchar *button2_label, + const gchar *button3_label, + GtkWidget *widget); + void alertpanel_message (const gchar *title, const gchar *message); diff --git a/src/gtkutils.c b/src/gtkutils.c index 9e651ef35..2bcc4b1c4 100644 --- a/src/gtkutils.c +++ b/src/gtkutils.c @@ -45,6 +45,8 @@ #include "gtksctree.h" #include "codeconv.h" #include "stock_pixmap.h" +#include "menu.h" +#include "prefs_account.h" gint gtkut_get_font_width(GdkFont *font) { @@ -509,3 +511,39 @@ void gtkut_widget_set_composer_icon(GtkWidget *widget) } gdk_window_set_icon(widget->window, NULL, xpm, bmp); } + +GtkWidget *gtkut_account_menu_new(GList *ac_list, + GtkSignalFunc callback, + gpointer data) +{ + GList *cur_ac; + GtkWidget *menu; + + g_return_val_if_fail(ac_list != NULL, NULL); + + menu = gtk_menu_new(); + + for (cur_ac = ac_list; cur_ac != NULL; cur_ac = cur_ac->next) { + gchar *name; + GtkWidget *menuitem; + PrefsAccount *account; + + account = (PrefsAccount *) cur_ac->data; + if (account->name) + name = g_strdup_printf("%s: %s <%s>", + account->account_name, + account->name, + account->address); + else + name = g_strdup_printf("%s: %s", + account->account_name, + account->address); + MENUITEM_ADD(menu, menuitem, name, account->account_id); + g_free(name); + if (callback != NULL) + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", + callback, + data); + } + return menu; +} diff --git a/src/gtkutils.h b/src/gtkutils.h index a30f78a5f..c464b6785 100644 --- a/src/gtkutils.h +++ b/src/gtkutils.h @@ -145,4 +145,8 @@ void gtkut_widget_init (void); void gtkut_widget_set_app_icon (GtkWidget *widget); void gtkut_widget_set_composer_icon (GtkWidget *widget); + +GtkWidget *gtkut_account_menu_new (GList *ac_list, + GtkSignalFunc callback, + gpointer data); #endif /* __GTKUTILS_H__ */ diff --git a/src/messageview.c b/src/messageview.c index e31cb11c5..1e540c15d 100644 --- a/src/messageview.c +++ b/src/messageview.c @@ -65,6 +65,9 @@ static void return_receipt_show (NoticeView *noticeview, static void return_receipt_send_clicked (NoticeView *noticeview, MsgInfo *msginfo); +static PrefsAccount *select_account_from_list + (GList *ac_list); + MessageView *messageview_create(void) { MessageView *messageview; @@ -280,19 +283,79 @@ static gint disposition_notification_queue(PrefsAccount * account, return 0; } -static gint disposition_notification_send(MsgInfo * msginfo) +static gint disposition_notification_send(MsgInfo *msginfo) { gchar buf[BUFFSIZE]; gchar tmp[MAXPATHLEN + 1]; FILE *fp; - GSList * to_list; + GSList *to_list; + GList *ac_list; + PrefsAccount *account; gint ok; - gchar * to; + gchar *to; if ((!msginfo->returnreceiptto) && (!msginfo->dispositionnotificationto)) return -1; + /* RFC2298: Test for Return-Path */ + if (msginfo->dispositionnotificationto) + to = msginfo->dispositionnotificationto; + else + to = msginfo->returnreceiptto; + + ok = get_header_from_msginfo(msginfo, buf, sizeof(buf), + "Return-Path:"); + if (ok == 0) { + gchar *to_addr = g_strdup(to); + extract_address(to_addr); + extract_address(buf); + ok = strcmp(to_addr, buf); + g_free(to_addr); + } else { + strncpy(buf, _(""), + sizeof(buf)); + } + + if (ok != 0) { + AlertValue val; + gchar *message; + message = g_strdup_printf( + _("The notification address to which the " + "return receipt is to be sent\n" + "does not correspond to the return path:\n" + "Notification address: %s\n" + "Return path: %s\n" + "It is advised to not to send the return " + "receipt."), to, buf); + val = alertpanel(_("Warning"), message, _("Send"), + _("+Don't Send"), NULL); + if (val != G_ALERTDEFAULT) + return -1; + } + + ac_list = account_find_all_from_address(NULL, msginfo->to); + ac_list = account_find_all_from_address(ac_list, msginfo->cc); + + if (ac_list == NULL) { + alertpanel_error(_("This message is asking for a return " + "receipt notification\n" + "but according to its 'To:' and 'CC:' " + "headers it was not\nofficially addressed " + "to you.\n" + "Receipt notification cancelled.")); + return -1; + } + + if (g_list_length(ac_list) > 1) + account = select_account_from_list(ac_list); + else + account = (PrefsAccount *) ac_list->data; + g_list_free(ac_list); + + if (account == NULL) + return -1; + /* write to temporary file */ g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg%d", get_rc_dir(), G_DIR_SEPARATOR, (gint)msginfo); @@ -313,19 +376,14 @@ static gint disposition_notification_send(MsgInfo * msginfo) fprintf(fp, "Date: %s\n", buf); /* From */ - if (cur_account->name && *cur_account->name) { + if (account->name && *account->name) { notification_convert_header - (buf, sizeof(buf), cur_account->name, + (buf, sizeof(buf), account->name, strlen("From: ")); - fprintf(fp, "From: %s <%s>\n", buf, cur_account->address); + fprintf(fp, "From: %s <%s>\n", buf, account->address); } else - fprintf(fp, "From: %s\n", cur_account->address); + fprintf(fp, "From: %s\n", account->address); - /* To */ - if (msginfo->dispositionnotificationto) - to = msginfo->dispositionnotificationto; - else - to = msginfo->returnreceiptto; fprintf(fp, "To: %s\n", to); /* Subject */ @@ -340,7 +398,7 @@ static gint disposition_notification_send(MsgInfo * msginfo) } to_list = address_list_append(NULL, to); - ok = send_message(tmp, cur_account, to_list); + ok = send_message(tmp, account, to_list); if (ok < 0) { if (prefs_common.queue_msg) { @@ -352,7 +410,7 @@ static gint disposition_notification_send(MsgInfo * msginfo) "Put this notification into queue folder?"), _("OK"), _("Cancel"), NULL); if (G_ALERTDEFAULT == val) { - ok = disposition_notification_queue(cur_account, to, tmp); + ok = disposition_notification_queue(account, to, tmp); if (ok < 0) alertpanel_error(_("Can't queue the notification.")); } @@ -629,6 +687,9 @@ static void return_receipt_send_clicked(NoticeView *noticeview, MsgInfo *msginfo } tmpmsginfo = procheader_parse_file(file, msginfo->flags, TRUE, TRUE); + tmpmsginfo->folder = msginfo->folder; + tmpmsginfo->msgnum = msginfo->msgnum; + if (disposition_notification_send(tmpmsginfo) >= 0) { procmsg_msginfo_unset_flags(msginfo, MSG_RETRCPT_PENDING, 0); noticeview_hide(noticeview); @@ -638,4 +699,35 @@ static void return_receipt_send_clicked(NoticeView *noticeview, MsgInfo *msginfo g_free(file); } +static void select_account_cb(GtkWidget *w, gpointer data) +{ + *(gint*)data = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(w))); +} + +static PrefsAccount *select_account_from_list(GList *ac_list) +{ + GtkWidget *optmenu; + GtkWidget *menu; + gint account_id; + g_return_val_if_fail(ac_list != NULL, NULL); + g_return_val_if_fail(ac_list->data != NULL, NULL); + + optmenu = gtk_option_menu_new(); + menu = gtkut_account_menu_new(ac_list, select_account_cb, &account_id); + if (!menu) + return NULL; + gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu); + gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), 0); + account_id = ((PrefsAccount *) ac_list->data)->account_id; + if (alertpanel_with_widget( + _("Return Receipt Notification"), + _("The message was sent to several of your " + "accounts.\n" + "Please choose which account do you want to " + "use for sending the receipt notification:"), + _("Send Notification"), _("+Cancel"), NULL, + optmenu) != G_ALERTDEFAULT) + return NULL; + return account_find_from_id(account_id); +} -- 2.25.1