X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fprocmsg.c;h=461c0c9d89aa7d7b40c602bb381eab62d8e26100;hp=b9881cfdf053d2d6f7596b4bbdc5c58d2428874e;hb=8bd1d905d643bdb7b71dd9db298bae35399c05fc;hpb=7fa02a7aa4fd6b1cf1a71a953d0a655a3f26810a diff --git a/src/procmsg.c b/src/procmsg.c index b9881cfdf..461c0c9d8 100644 --- a/src/procmsg.c +++ b/src/procmsg.c @@ -37,6 +37,9 @@ #if USE_GPGME # include "rfc2015.h" #endif +#include "alertpanel.h" +#include "news.h" +#include "imap.h" typedef struct _FlagInfo FlagInfo; @@ -46,15 +49,8 @@ struct _FlagInfo MsgFlags flags; }; -static void mark_sum_func (gpointer key, - gpointer value, - gpointer data); - static GHashTable *procmsg_read_mark_file (const gchar *folder); -static gint procmsg_cmp_msgnum (gconstpointer a, - gconstpointer b); -static gint procmsg_cmp_flag_msgnum (gconstpointer a, - gconstpointer b); +void procmsg_msginfo_write_flags (MsgInfo *msginfo); GHashTable *procmsg_msg_hash_table_create(GSList *mlist) @@ -181,13 +177,14 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) default_flags.perm_flags = MSG_NEW|MSG_UNREAD; default_flags.tmp_flags = MSG_CACHED; - if (type == F_MH) { + if (type == F_MH || type == F_IMAP) { if (item->stype == F_QUEUE) { MSG_SET_TMP_FLAGS(default_flags, MSG_QUEUED); } else if (item->stype == F_DRAFT) { MSG_SET_TMP_FLAGS(default_flags, MSG_DRAFT); } - } else if (type == F_IMAP) { + } + if (type == F_IMAP) { MSG_SET_TMP_FLAGS(default_flags, MSG_IMAP); } else if (type == F_NEWS) { MSG_SET_TMP_FLAGS(default_flags, MSG_NEWS); @@ -204,7 +201,7 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) g_free(path); } cache_file = folder_item_get_cache_file(item); - if ((fp = fopen(cache_file, "r")) == NULL) { + if ((fp = fopen(cache_file, "rb")) == NULL) { debug_print(_("\tNo cache file\n")); g_free(cache_file); return NULL; @@ -223,7 +220,7 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) } while (fread(&num, sizeof(num), 1, fp) == 1) { - msginfo = g_new0(MsgInfo, 1); + msginfo = procmsg_msginfo_new(); msginfo->msgnum = num; READ_CACHE_DATA_INT(msginfo->size, fp); READ_CACHE_DATA_INT(msginfo->mtime, fp); @@ -241,6 +238,8 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) READ_CACHE_DATA(msginfo->msgid, fp); READ_CACHE_DATA(msginfo->inreplyto, fp); READ_CACHE_DATA(msginfo->references, fp); + READ_CACHE_DATA(msginfo->xref, fp); + MSG_SET_PERM_FLAGS(msginfo->flags, default_flags.perm_flags); MSG_SET_TMP_FLAGS(msginfo->flags, default_flags.tmp_flags); @@ -335,14 +334,12 @@ void procmsg_set_flags(GSList *mlist, FolderItem *item) g_hash_table_destroy(mark_table); } -gint procmsg_get_last_num_in_cache(GSList *mlist) +gint procmsg_get_last_num_in_msg_list(GSList *mlist) { GSList *cur; MsgInfo *msginfo; gint last = 0; - if (mlist == NULL) return 0; - for (cur = mlist; cur != NULL; cur = cur->next) { msginfo = (MsgInfo *)cur->data; if (msginfo && msginfo->msgnum > last) @@ -385,6 +382,8 @@ void procmsg_write_cache(MsgInfo *msginfo, FILE *fp) WRITE_CACHE_DATA(msginfo->msgid, fp); WRITE_CACHE_DATA(msginfo->inreplyto, fp); WRITE_CACHE_DATA(msginfo->references, fp); + WRITE_CACHE_DATA(msginfo->xref, fp); + } void procmsg_write_flags(MsgInfo *msginfo, FILE *fp) @@ -395,58 +394,66 @@ void procmsg_write_flags(MsgInfo *msginfo, FILE *fp) WRITE_CACHE_DATA_INT(flags, fp); } -struct MarkSum { - gint *new; - gint *unread; - gint *total; - gint *min; - gint *max; - gint first; -}; - -static void mark_sum_func(gpointer key, gpointer value, gpointer data) +void procmsg_flush_mark_queue(FolderItem *item, FILE *fp) { - MsgFlags *flags = value; - gint num = GPOINTER_TO_INT(key); - struct MarkSum *marksum = data; - - if (marksum->first <= num) { - if (MSG_IS_NEW(*flags) && !MSG_IS_IGNORE_THREAD(*flags)) (*marksum->new)++; - if (MSG_IS_UNREAD(*flags) && !MSG_IS_IGNORE_THREAD(*flags)) (*marksum->unread)++; - if (num > *marksum->max) *marksum->max = num; - if (num < *marksum->min || *marksum->min == 0) *marksum->min = num; - (*marksum->total)++; - } + MsgInfo *flaginfo; - g_free(flags); + g_return_if_fail(item != NULL); + g_return_if_fail(fp != NULL); + + while (item->mark_queue != NULL) { + flaginfo = (MsgInfo *)item->mark_queue->data; + procmsg_write_flags(flaginfo, fp); + procmsg_msginfo_free(flaginfo); + item->mark_queue = g_slist_remove(item->mark_queue, flaginfo); + } } -void procmsg_get_mark_sum(const gchar *folder, - gint *new, gint *unread, gint *total, - gint *min, gint *max, - gint first) +void procmsg_add_flags(FolderItem *item, gint num, MsgFlags flags) { - GHashTable *mark_table; - struct MarkSum marksum; + FILE *fp; + gchar *path; + MsgInfo msginfo; - *new = *unread = *total = *min = *max = 0; - marksum.new = new; - marksum.unread = unread; - marksum.total = total; - marksum.min = min; - marksum.max = max; - marksum.first = first; + g_return_if_fail(item != NULL); - mark_table = procmsg_read_mark_file(folder); + if (item->opened) { + MsgInfo *queue_msginfo; - if (mark_table) { - g_hash_table_foreach(mark_table, mark_sum_func, &marksum); - g_hash_table_destroy(mark_table); + queue_msginfo = g_new0(MsgInfo, 1); + queue_msginfo->msgnum = num; + queue_msginfo->flags = flags; + item->mark_queue = g_slist_append + (item->mark_queue, queue_msginfo); + return; } - debug_print("mark->new = %d, mark->unread = %d, mark->total = %d\n", - *(marksum.new), *(marksum.unread), *(marksum.total)); + + path = folder_item_get_path(item); + g_return_if_fail(path != NULL); + + if ((fp = procmsg_open_mark_file(path, TRUE)) == NULL) { + g_warning(_("can't open mark file\n")); + g_free(path); + return; + } + g_free(path); + + msginfo.msgnum = num; + msginfo.flags = flags; + + procmsg_write_flags(&msginfo, fp); + fclose(fp); } +struct MarkSum { + gint *new; + gint *unread; + gint *total; + gint *min; + gint *max; + gint first; +}; + static GHashTable *procmsg_read_mark_file(const gchar *folder) { FILE *fp; @@ -463,10 +470,18 @@ static GHashTable *procmsg_read_mark_file(const gchar *folder) while (fread(&num, sizeof(num), 1, fp) == 1) { if (fread(&perm_flags, sizeof(perm_flags), 1, fp) != 1) break; + flags = g_hash_table_lookup(mark_table, GUINT_TO_POINTER(num)); + if (flags != NULL) + g_free(flags); + flags = g_new0(MsgFlags, 1); flags->perm_flags = perm_flags; - - g_hash_table_insert(mark_table, GUINT_TO_POINTER(num), flags); + + if(!MSG_IS_REALLY_DELETED(*flags)) { + g_hash_table_insert(mark_table, GUINT_TO_POINTER(num), flags); + } else { + g_hash_table_remove(mark_table, GUINT_TO_POINTER(num)); + } } fclose(fp); @@ -481,7 +496,7 @@ FILE *procmsg_open_mark_file(const gchar *folder, gboolean append) markfile = g_strconcat(folder, G_DIR_SEPARATOR_S, MARK_FILE, NULL); - if ((fp = fopen(markfile, "r")) == NULL) + if ((fp = fopen(markfile, "rb")) == NULL) debug_print(_("Mark file not found.\n")); else if (fread(&ver, sizeof(ver), 1, fp) != 1 || MARK_VERSION != ver) { debug_print(_("Mark version is different (%d != %d). " @@ -499,12 +514,12 @@ FILE *procmsg_open_mark_file(const gchar *folder, gboolean append) if (fp) { /* reopen with append mode */ fclose(fp); - if ((fp = fopen(markfile, "a")) == NULL) + if ((fp = fopen(markfile, "ab")) == NULL) g_warning(_("Can't open mark file with append mode.\n")); } else { /* open with overwrite mode if mark file doesn't exist or version is different */ - if ((fp = fopen(markfile, "w")) == NULL) + if ((fp = fopen(markfile, "wb")) == NULL) g_warning(_("Can't open mark file with write mode.\n")); else { ver = MARK_VERSION; @@ -525,6 +540,7 @@ GNode *procmsg_get_thread_tree(GSList *mlist) MsgInfo *msginfo; const gchar *msgid; const gchar *subject; + GNode *found_subject; root = g_node_new(NULL); msgid_table = g_hash_table_new(g_str_hash, g_str_equal); @@ -539,8 +555,8 @@ GNode *procmsg_get_thread_tree(GSList *mlist) if (parent == NULL) { parent = root; } else { - if(MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags)) { - MSG_SET_PERM_FLAGS(msginfo->flags, MSG_IGNORE_THREAD); + if(MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0); } } } @@ -552,10 +568,20 @@ GNode *procmsg_get_thread_tree(GSList *mlist) g_hash_table_insert(msgid_table, (gchar *)msgid, node); subject = msginfo->subject; - if (subject_table_lookup(subject_table, - (gchar *) subject) == NULL) - subject_table_insert(subject_table, (gchar *)subject, + found_subject = subject_table_lookup(subject_table, + (gchar *) subject); + if (found_subject == NULL) + subject_table_insert(subject_table, (gchar *) subject, node); + else { + /* replace if msg in table is older than current one + * can add here more stuff. */ + if ( ((MsgInfo*)(found_subject->data))->date_t > + ((MsgInfo*)(node->data))->date_t ) { + subject_table_remove(subject_table, (gchar *) subject); + subject_table_insert(subject_table, (gchar *) subject, node); + } + } } /* complete the unfinished threads */ @@ -570,8 +596,8 @@ GNode *procmsg_get_thread_tree(GSList *mlist) g_node_insert_before (parent, parent->children, node); /* CLAWS: ignore thread */ - if(MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags)) { - MSG_SET_PERM_FLAGS(msginfo->flags, MSG_IGNORE_THREAD); + if(MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0); } } node = next; @@ -601,8 +627,8 @@ GNode *procmsg_get_thread_tree(GSList *mlist) g_node_unlink(node); g_node_append(parent, node); /* CLAWS: ignore thread */ - if(MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags)) { - MSG_SET_PERM_FLAGS(msginfo->flags, MSG_IGNORE_THREAD); + if(MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0); } } } @@ -620,14 +646,9 @@ void procmsg_move_messages(GSList *mlist) GSList *cur, *movelist = NULL; MsgInfo *msginfo; FolderItem *dest = NULL; - GHashTable *hash; if (!mlist) return; - hash = procmsg_to_folder_hash_table_create(mlist); - folder_item_scan_foreach(hash); - g_hash_table_destroy(hash); - for (cur = mlist; cur != NULL; cur = cur->next) { msginfo = (MsgInfo *)cur->data; if (!dest) { @@ -655,13 +676,17 @@ void procmsg_copy_messages(GSList *mlist) GSList *cur, *copylist = NULL; MsgInfo *msginfo; FolderItem *dest = NULL; - GHashTable *hash; if (!mlist) return; + /* + + Horrible: Scanning 2 times for every copy! + hash = procmsg_to_folder_hash_table_create(mlist); folder_item_scan_foreach(hash); g_hash_table_destroy(hash); + */ for (cur = mlist; cur != NULL; cur = cur->next) { msginfo = (MsgInfo *)cur->data; @@ -732,7 +757,7 @@ FILE *procmsg_open_message(MsgInfo *msginfo) g_return_val_if_fail(file != NULL, NULL); } - if ((fp = fopen(file, "r")) == NULL) { + if ((fp = fopen(file, "rb")) == NULL) { FILE_OP_ERROR(file, "fopen"); g_free(file); return NULL; @@ -823,35 +848,117 @@ void procmsg_empty_trash(void) } } -gint procmsg_send_queue(void) +gint procmsg_send_queue(FolderItem *queue, gboolean save_msgs) { - FolderItem *queue; - gint i; gint ret = 0; + GSList *list, *elem; - queue = folder_get_default_queue(); + if (!queue) + queue = folder_get_default_queue(); g_return_val_if_fail(queue != NULL, -1); + folder_item_scan(queue); - if (queue->last_num < 0) return -1; - else if (queue->last_num == 0) return 0; + list = folder_item_get_msg_list(queue); + - for (i = 1; i <= queue->last_num; i++) { + for(elem = list; elem != NULL; elem = elem->next) { gchar *file; + MsgInfo *msginfo; + + msginfo = (MsgInfo *)(elem->data); - file = folder_item_fetch_msg(queue, i); + file = folder_item_fetch_msg(queue, msginfo->msgnum); if (file) { if (procmsg_send_message_queue(file) < 0) { - g_warning(_("Sending queued message %d failed.\n"), i); + g_warning(_("Sending queued message %d failed.\n"), msginfo->msgnum); ret = -1; - } else - folder_item_remove_msg(queue, i); + } else { + /* CLAWS: + * We save in procmsg_send_message_queue because + * we need the destination folder from the queue + * header + + if (save_msgs) + procmsg_save_to_outbox + (queue->folder->outbox, + file, TRUE); +*/ + folder_item_remove_msg(queue, msginfo->msgnum); + } g_free(file); } + procmsg_msginfo_free(msginfo); } + folderview_update_item(queue, FALSE); + return ret; } +gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file, + gboolean is_queued) +{ + gint num; + FILE *fp; + MsgInfo *msginfo; + + debug_print("saving sent message...\n"); + + if (!outbox) + outbox = folder_get_default_outbox(); + g_return_val_if_fail(outbox != NULL, -1); + + /* remove queueing headers */ + if (is_queued) { + gchar tmp[MAXPATHLEN + 1]; + gchar buf[BUFFSIZE]; + FILE *outfp; + + g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg.out.%08x", + get_rc_dir(), G_DIR_SEPARATOR, (guint)random()); + if ((fp = fopen(file, "rb")) == NULL) { + FILE_OP_ERROR(file, "fopen"); + return -1; + } + if ((outfp = fopen(tmp, "wb")) == NULL) { + FILE_OP_ERROR(tmp, "fopen"); + fclose(fp); + return -1; + } + while (fgets(buf, sizeof(buf), fp) != NULL) + if (buf[0] == '\r' || buf[0] == '\n') break; + while (fgets(buf, sizeof(buf), fp) != NULL) + fputs(buf, outfp); + fclose(outfp); + fclose(fp); + + folder_item_scan(outbox); + if ((num = folder_item_add_msg(outbox, tmp, TRUE)) < 0) { + g_warning("can't save message\n"); + unlink(tmp); + return -1; + } + } else { + folder_item_scan(outbox); + if ((num = folder_item_add_msg(outbox, file, FALSE)) < 0) { + g_warning("can't save message\n"); + return -1; + } + return -1; + } + msginfo = folder_item_fetch_msginfo(outbox, num); + if(msginfo != NULL) { + procmsg_msginfo_unset_flags(msginfo, ~0, ~0); + procmsg_msginfo_free(msginfo); + } + + if(is_queued) { + unlink(file); + } + + return 0; +} + void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline) { static const gchar *def_cmd = "lpr %s"; @@ -871,7 +978,7 @@ void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline) prtmp = g_strdup_printf("%s%cprinttmp.%08x", get_mime_tmp_dir(), G_DIR_SEPARATOR, id++); - if ((prfp = fopen(prtmp, "w")) == NULL) { + if ((prfp = fopen(prtmp, "wb")) == NULL) { FILE_OP_ERROR(prtmp, "fopen"); g_free(prtmp); fclose(tmpfp); @@ -910,6 +1017,23 @@ void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline) system(buf); } +MsgInfo *procmsg_msginfo_new_ref(MsgInfo *msginfo) +{ + msginfo->refcnt++; + + return msginfo; +} + +MsgInfo *procmsg_msginfo_new() +{ + MsgInfo *newmsginfo; + + newmsginfo = g_new0(MsgInfo, 1); + newmsginfo->refcnt = 1; + + return newmsginfo; +} + MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo) { MsgInfo *newmsginfo; @@ -918,6 +1042,8 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo) newmsginfo = g_new0(MsgInfo, 1); + newmsginfo->refcnt = 1; + #define MEMBCOPY(mmb) newmsginfo->mmb = msginfo->mmb #define MEMBDUP(mmb) newmsginfo->mmb = msginfo->mmb ? \ g_strdup(msginfo->mmb) : NULL @@ -938,6 +1064,7 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo) MEMBDUP(subject); MEMBDUP(msgid); MEMBDUP(inreplyto); + MEMBDUP(xref); MEMBCOPY(folder); MEMBCOPY(to_folder); @@ -957,6 +1084,10 @@ void procmsg_msginfo_free(MsgInfo *msginfo) { if (msginfo == NULL) return; + msginfo->refcnt--; + if(msginfo->refcnt > 0) + return; + g_free(msginfo->fromspace); g_free(msginfo->references); g_free(msginfo->returnreceiptto); @@ -973,19 +1104,46 @@ void procmsg_msginfo_free(MsgInfo *msginfo) g_free(msginfo->subject); g_free(msginfo->msgid); g_free(msginfo->inreplyto); + g_free(msginfo->xref); g_free(msginfo); } -static gint procmsg_cmp_msgnum(gconstpointer a, gconstpointer b) +guint procmsg_msginfo_memusage(MsgInfo *msginfo) { - const MsgInfo *msginfo = a; - const guint msgnum = GPOINTER_TO_UINT(b); - - if (!msginfo) - return -1; - - return msginfo->msgnum - msgnum; + guint memusage = 0; + + memusage += sizeof(MsgInfo); + if(msginfo->fromname) + memusage += strlen(msginfo->fromname); + if(msginfo->date) + memusage += strlen(msginfo->date); + if(msginfo->from) + memusage += strlen(msginfo->from); + if(msginfo->to) + memusage += strlen(msginfo->to); + if(msginfo->cc) + memusage += strlen(msginfo->cc); + if(msginfo->newsgroups) + memusage += strlen(msginfo->newsgroups); + if(msginfo->subject) + memusage += strlen(msginfo->subject); + if(msginfo->msgid) + memusage += strlen(msginfo->msgid); + if(msginfo->inreplyto) + memusage += strlen(msginfo->inreplyto); + if(msginfo->xface) + memusage += strlen(msginfo->xface); + if(msginfo->dispositionnotificationto) + memusage += strlen(msginfo->dispositionnotificationto); + if(msginfo->returnreceiptto) + memusage += strlen(msginfo->returnreceiptto); + if(msginfo->references) + memusage += strlen(msginfo->references); + if(msginfo->fromspace) + memusage += strlen(msginfo->fromspace); + + return memusage; } gint procmsg_cmp_msgnum_for_sort(gconstpointer a, gconstpointer b) @@ -1001,17 +1159,6 @@ gint procmsg_cmp_msgnum_for_sort(gconstpointer a, gconstpointer b) return msginfo1->msgnum - msginfo2->msgnum; } -static gint procmsg_cmp_flag_msgnum(gconstpointer a, gconstpointer b) -{ - const FlagInfo *finfo = a; - const guint msgnum = GPOINTER_TO_UINT(b); - - if (!finfo) - return -1; - - return finfo->msgnum - msgnum; -} - enum { Q_SENDER = 0, @@ -1020,7 +1167,8 @@ enum Q_NEWSGROUPS = 3, Q_MAIL_ACCOUNT_ID = 4, Q_NEWS_ACCOUNT_ID = 5, - Q_SAVE_COPY_FOLDER = 6 + Q_SAVE_COPY_FOLDER = 6, + Q_REPLY_MESSAGE_ID = 7, }; gint procmsg_send_message_queue(const gchar *file) @@ -1032,6 +1180,7 @@ gint procmsg_send_message_queue(const gchar *file) {"MAID:", NULL, FALSE}, {"NAID:", NULL, FALSE}, {"SCF:", NULL, FALSE}, + {"RMID:", NULL, FALSE}, {NULL, NULL, FALSE}}; FILE *fp; gint filepos; @@ -1041,14 +1190,15 @@ gint procmsg_send_message_queue(const gchar *file) GSList *to_list = NULL; GSList *newsgroup_list = NULL; gchar *savecopyfolder = NULL; + gchar *replymessageid = NULL; gchar buf[BUFFSIZE]; gint hnum; PrefsAccount *mailac = NULL, *newsac = NULL; - gchar *tmp = NULL; + int local = 0; g_return_val_if_fail(file != NULL, -1); - if ((fp = fopen(file, "r")) == NULL) { + if ((fp = fopen(file, "rb")) == NULL) { FILE_OP_ERROR(file, "fopen"); return -1; } @@ -1079,35 +1229,13 @@ gint procmsg_send_message_queue(const gchar *file) case Q_SAVE_COPY_FOLDER: if (!savecopyfolder) savecopyfolder = g_strdup(p); break; - default: + case Q_REPLY_MESSAGE_ID: + if (!replymessageid) replymessageid = g_strdup(p); + break; } } filepos = ftell(fp); - if(newsgroup_list || prefs_common.savemsg) { - FILE *tmpfp; - - /* write to temporary file */ - tmp = g_strdup_printf("%s%ctmp%d", g_get_tmp_dir(), - G_DIR_SEPARATOR, (gint)file); - if ((tmpfp = fopen(tmp, "w")) == NULL) { - FILE_OP_ERROR(tmp, "fopen"); - newsval = -1; - } - if (change_file_mode_rw(tmpfp, tmp) < 0) { - FILE_OP_ERROR(tmp, "chmod"); - g_warning(_("can't change file mode\n")); - } - - while ((newsval == 0) && fgets(buf, sizeof(buf), fp) != NULL) { - if (fputs(buf, tmpfp) == EOF) { - FILE_OP_ERROR(tmp, "fputs"); - newsval = -1; - } - } - fclose(tmpfp); - } - fseek(fp, filepos, SEEK_SET); if (to_list) { debug_print(_("Sending message by mail\n")); @@ -1117,8 +1245,10 @@ gint procmsg_send_message_queue(const gchar *file) } else if (mailac && mailac->use_mail_command && mailac->mail_command && (* mailac->mail_command)) { mailval = send_message_local(mailac->mail_command, fp); + local = 1; } else if (prefs_common.use_extsend && prefs_common.extsend_cmd) { mailval = send_message_local(prefs_common.extsend_cmd, fp); + local = 1; } else { if (!mailac) { mailac = account_find_from_smtp_server(from, smtpserver); @@ -1144,73 +1274,233 @@ gint procmsg_send_message_queue(const gchar *file) } } if (mailval < 0) { - alertpanel_error(_("Error occurred while sending the message to %s ."), - mailac ? mailac->smtp_server : smtpserver); + if (!local) + alertpanel_error( + _("Error occurred while sending the message to `%s'."), + mailac ? mailac->smtp_server : smtpserver); + else + alertpanel_error( + _("Error occurred while sending the message with command `%s'."), + (mailac && mailac->use_mail_command && + mailac->mail_command && (*mailac->mail_command)) ? + mailac->mail_command : prefs_common.extsend_cmd); } } if(newsgroup_list && (newsval == 0)) { Folder *folder; + gchar *tmp = NULL; + FILE *tmpfp; - debug_print(_("Sending message by news\n")); + /* write to temporary file */ + tmp = g_strdup_printf("%s%ctmp%d", g_get_tmp_dir(), + G_DIR_SEPARATOR, (gint)file); + if ((tmpfp = fopen(tmp, "wb")) == NULL) { + FILE_OP_ERROR(tmp, "fopen"); + newsval = -1; + alertpanel_error(_("Could not create temporary file for news sending.")); + } else { + if (change_file_mode_rw(tmpfp, tmp) < 0) { + FILE_OP_ERROR(tmp, "chmod"); + g_warning(_("can't change file mode\n")); + } + + while ((newsval == 0) && fgets(buf, sizeof(buf), fp) != NULL) { + if (fputs(buf, tmpfp) == EOF) { + FILE_OP_ERROR(tmp, "fputs"); + newsval = -1; + alertpanel_error(_("Error when writing temporary file for news sending.")); + } + } + fclose(tmpfp); - folder = FOLDER(newsac->folder); + if(newsval == 0) { + debug_print(_("Sending message by news\n")); - newsval = news_post(folder, tmp); - if (newsval < 0) { - alertpanel_error(_("Error occurred while posting the message to %s ."), - newsac->nntp_server); - } + folder = FOLDER(newsac->folder); + + newsval = news_post(folder, tmp); + if (newsval < 0) { + alertpanel_error(_("Error occurred while posting the message to %s ."), + newsac->nntp_server); + } + } + unlink(tmp); + } + g_free(tmp); } + slist_free_strings(to_list); + g_slist_free(to_list); + slist_free_strings(newsgroup_list); + g_slist_free(newsgroup_list); + g_free(from); + g_free(smtpserver); + fclose(fp); + /* save message to outbox */ if (mailval == 0 && newsval == 0 && savecopyfolder) { - FolderItem *folder; - gchar *path; - gint num; - FILE *fp; + FolderItem *outbox; debug_print(_("saving sent message...\n")); - folder = folder_find_item_from_identifier(savecopyfolder); - if(!folder) - folder = folder_get_default_outbox(); - path = folder_item_get_path(folder); - if (!is_dir_exist(path)) - make_dir_hier(path); + outbox = folder_find_item_from_identifier(savecopyfolder); + if(!outbox) + outbox = folder_get_default_outbox(); - folder_item_scan(folder); - if ((num = folder_item_add_msg(folder, tmp, FALSE)) < 0) { - g_warning(_("can't save message\n")); - } + procmsg_save_to_outbox(outbox, file, TRUE); + } - if(num) { - if ((fp = procmsg_open_mark_file(path, TRUE)) == NULL) - g_warning(_("can't open mark file\n")); - else { - MsgInfo newmsginfo; + if(replymessageid != NULL) { + gchar **tokens; + FolderItem *item; + + tokens = g_strsplit(replymessageid, "\x7f", 0); + item = folder_find_item_from_identifier(tokens[0]); + if(item != NULL) { + MsgInfo *msginfo; + + msginfo = folder_item_fetch_msginfo(item, atoi(tokens[1])); + if((msginfo != NULL) && (strcmp(msginfo->msgid, tokens[2]) != 0)) { + procmsg_msginfo_free(msginfo); + msginfo = NULL; + } + + if(msginfo == NULL) { + msginfo = folder_item_fetch_msginfo_by_id(item, tokens[2]); + } + + if(msginfo != NULL) { + procmsg_msginfo_unset_flags(msginfo, MSG_FORWARDED, 0); + procmsg_msginfo_set_flags(msginfo, MSG_REPLIED, 0); - newmsginfo.msgnum = num; - newmsginfo.flags.perm_flags = 0; - newmsginfo.flags.tmp_flags = 0; - procmsg_write_flags(&newmsginfo, fp); - fclose(fp); + procmsg_msginfo_free(msginfo); } } - g_free(path); + g_strfreev(tokens); } - slist_free_strings(to_list); - g_slist_free(to_list); - slist_free_strings(newsgroup_list); - g_slist_free(newsgroup_list); - g_free(from); - g_free(smtpserver); - fclose(fp); - if(tmp) { - unlink(tmp); - g_free(tmp); + g_free(savecopyfolder); + g_free(replymessageid); + + return (newsval != 0 ? newsval : mailval); +} + +#define CHANGE_FLAGS(msginfo) \ +{ \ +if (msginfo->folder->folder->change_flags != NULL) \ +msginfo->folder->folder->change_flags(msginfo->folder->folder, \ + msginfo->folder, \ + msginfo); \ +} + +void procmsg_msginfo_set_flags(MsgInfo *msginfo, MsgPermFlags perm_flags, MsgTmpFlags tmp_flags) +{ + gboolean changed = FALSE; + FolderItem *item = msginfo->folder; + + debug_print(_("Setting flags for message %d in folder %s\n"), msginfo->msgnum, item->path); + + /* if new flag is set */ + if((perm_flags & MSG_NEW) && !MSG_IS_NEW(msginfo->flags) && + !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + item->new++; + changed = TRUE; } - return (newsval != 0 ? newsval : mailval); + /* if unread flag is set */ + if((perm_flags & MSG_UNREAD) && !MSG_IS_UNREAD(msginfo->flags) && + !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + item->unread++; + changed = TRUE; + } + + /* if ignore thread flag is set */ + if((perm_flags & MSG_IGNORE_THREAD) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + if(MSG_IS_NEW(msginfo->flags) || (perm_flags & MSG_NEW)) { + item->new--; + changed = TRUE; + } + if(MSG_IS_UNREAD(msginfo->flags) || (perm_flags & MSG_UNREAD)) { + item->unread--; + changed = TRUE; + } + } + + if (MSG_IS_IMAP(msginfo->flags)) + imap_msg_set_perm_flags(msginfo, perm_flags); + + msginfo->flags.perm_flags |= perm_flags; + msginfo->flags.tmp_flags |= tmp_flags; + + if(changed) { + folderview_update_item(item, FALSE); + } + CHANGE_FLAGS(msginfo); + procmsg_msginfo_write_flags(msginfo); +} + +void procmsg_msginfo_unset_flags(MsgInfo *msginfo, MsgPermFlags perm_flags, MsgTmpFlags tmp_flags) +{ + gboolean changed = FALSE; + FolderItem *item = msginfo->folder; + + debug_print(_("Unsetting flags for message %d in folder %s\n"), msginfo->msgnum, item->path); + + /* if new flag is unset */ + if((perm_flags & MSG_NEW) && MSG_IS_NEW(msginfo->flags) && + !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + item->new--; + changed = TRUE; + } + + /* if unread flag is unset */ + if((perm_flags & MSG_UNREAD) && MSG_IS_UNREAD(msginfo->flags) && + !MSG_IS_IGNORE_THREAD(msginfo->flags)) { + item->unread--; + changed = TRUE; + } + + /* if ignore thread flag is unset */ + if((perm_flags & MSG_IGNORE_THREAD) && MSG_IS_IGNORE_THREAD(msginfo->flags)) { + if(MSG_IS_NEW(msginfo->flags) && !(perm_flags & MSG_NEW)) { + item->new++; + changed = TRUE; + } + if(MSG_IS_UNREAD(msginfo->flags) && !(perm_flags & MSG_UNREAD)) { + item->unread++; + changed = TRUE; + } + } + + if (MSG_IS_IMAP(msginfo->flags)) + imap_msg_unset_perm_flags(msginfo, perm_flags); + + msginfo->flags.perm_flags &= ~perm_flags; + msginfo->flags.tmp_flags &= ~tmp_flags; + + if(changed) { + folderview_update_item(item, FALSE); + } + CHANGE_FLAGS(msginfo); + procmsg_msginfo_write_flags(msginfo); +} + +void procmsg_msginfo_write_flags(MsgInfo *msginfo) +{ + gchar *destdir; + FILE *fp; + + destdir = folder_item_get_path(msginfo->folder); + if (!is_dir_exist(destdir)) + make_dir_hier(destdir); + + if ((fp = procmsg_open_mark_file(destdir, TRUE))) { + procmsg_write_flags(msginfo, fp); + fclose(fp); + } else { + g_warning(_("Can't open mark file.\n")); + } + + g_free(destdir); }