Encrypt message just before writing it to queue dir.
[claws.git] / src / procmsg.c
index 4d17e4f908346be61788ff8a9e79e331ef6a1be0..5ff5f4d7d994b7c41de80a047c5038f4eac58a70 100644 (file)
@@ -89,6 +89,19 @@ void procmsg_msg_list_free(GSList *mlist)
        g_slist_free(mlist);
 }
 
+MsgNumberList *procmsg_get_number_list_for_msgs(MsgInfoList *msglist)
+{
+       GSList *cur = NULL;
+       GSList *nums = NULL;
+
+       for (cur = msglist; cur; cur = cur->next) {
+               MsgInfo *msg = (MsgInfo *)cur->data;
+               nums = g_slist_prepend(nums, GUINT_TO_POINTER(msg->msgnum));
+       }
+
+       return g_slist_reverse(nums);
+}
+
 struct MarkSum {
        gint *new_msgs;
        gint *unread_msgs;
@@ -759,6 +772,36 @@ static PrefsAccount *procmsg_get_account_from_file(const gchar *file)
        return mailac;
 }
 
+gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type)
+{
+       GSList *mia;
+
+       if (!msginfo || !msginfo->extradata || !msginfo->extradata->avatars)
+               return NULL;
+
+       for (mia = msginfo->extradata->avatars; mia; mia = mia->next) {
+               MsgInfoAvatar *avatar = (MsgInfoAvatar *)mia->data;
+               if (avatar->avatar_id == type)
+                       return avatar->avatar_src;
+       }
+
+       return NULL;
+}
+
+void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data)
+{
+       MsgInfoAvatar *av;
+
+       if (!msginfo->extradata)
+               msginfo->extradata = g_new0(MsgInfoExtraData, 1);
+
+       av = g_new0(MsgInfoAvatar, 1);
+       av->avatar_id = type;
+       av->avatar_src = g_strdup(data);
+
+       msginfo->extradata->avatars = g_slist_append(msginfo->extradata->avatars, av);
+}
+
 gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo)
 {
        gchar *folder_id;
@@ -847,7 +890,7 @@ parse_again:
                cur = cur->next;
        }
        
-       if (orig || g_slist_length(orig)) {
+       if (orig && g_slist_length(orig)) {
                if (!last_account && nothing_to_sort) {
                        /* can't find an account for the rest of the list */
                        cur = orig;
@@ -930,6 +973,7 @@ gint procmsg_send_queue(FolderItem *queue, gboolean save_msgs, gchar **errstr)
        GNode *node, *next;
        
        if (!procmsg_queue_lock(errstr)) {
+               main_window_set_menu_sensitive(mainwindow_get_mainwindow());
                toolbar_main_set_sensitive(mainwindow_get_mainwindow());
                return -1;
        }
@@ -943,6 +987,7 @@ gint procmsg_send_queue(FolderItem *queue, gboolean save_msgs, gchar **errstr)
                return -1;
        }
 
+       main_window_set_menu_sensitive(mainwindow_get_mainwindow());
        toolbar_main_set_sensitive(mainwindow_get_mainwindow());
 
        folder_item_scan(queue);
@@ -1000,6 +1045,7 @@ gint procmsg_send_queue(FolderItem *queue, gboolean save_msgs, gchar **errstr)
        }
        procmsg_queue_unlock();
        inc_unlock();
+       main_window_set_menu_sensitive(mainwindow_get_mainwindow());
        toolbar_main_set_sensitive(mainwindow_get_mainwindow());
 
        return (err != 0 ? -err : sent);
@@ -1077,14 +1123,20 @@ gint procmsg_remove_special_headers(const gchar *in, const gchar *out)
                        break;
                }
        }
-       while (fgets(buf, sizeof(buf), fp) != NULL)
-               fputs(buf, outfp);
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               if (fputs(buf, outfp) == EOF) {
+                       FILE_OP_ERROR(out, "fputs");
+                       fclose(outfp);
+                       fclose(fp);
+                       return -1;
+               }
+       }
        fclose(outfp);
        fclose(fp);
        return 0;
 }
 
-static gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file,
+gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file,
                            gboolean is_queued)
 {
        gint num;
@@ -1138,69 +1190,6 @@ static gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file,
        return 0;
 }
 
-void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline)
-{
-       static const gchar *def_cmd = "lpr %s";
-       static guint id = 0;
-       gchar *prtmp;
-       FILE *tmpfp, *prfp;
-       gchar buf[1024];
-       gchar *p;
-       int r;
-       cm_return_if_fail(msginfo);
-
-       if (procmime_msginfo_is_encrypted(msginfo))
-               tmpfp = procmime_get_first_encrypted_text_content(msginfo);
-       else
-               tmpfp = procmime_get_first_text_content(msginfo);
-       if (tmpfp == NULL) {
-               g_warning("Can't get text part\n");
-               return;
-       }
-
-       prtmp = g_strdup_printf("%s%cprinttmp.%08x",
-                               get_mime_tmp_dir(), G_DIR_SEPARATOR, id++);
-
-       if ((prfp = g_fopen(prtmp, "wb")) == NULL) {
-               FILE_OP_ERROR(prtmp, "fopen");
-               g_free(prtmp);
-               fclose(tmpfp);
-               return;
-       }
-
-       if (msginfo->date) r = fprintf(prfp, "Date: %s\n", msginfo->date);
-       if (msginfo->from) r = fprintf(prfp, "From: %s\n", msginfo->from);
-       if (msginfo->to)   r = fprintf(prfp, "To: %s\n", msginfo->to);
-       if (msginfo->cc)   r = fprintf(prfp, "Cc: %s\n", msginfo->cc);
-       if (msginfo->newsgroups)
-               r = fprintf(prfp, "Newsgroups: %s\n", msginfo->newsgroups);
-       if (msginfo->subject) r = fprintf(prfp, "Subject: %s\n", msginfo->subject);
-       fputc('\n', prfp);
-
-       while (fgets(buf, sizeof(buf), tmpfp) != NULL)
-               r = fputs(buf, prfp);
-
-       fclose(prfp);
-       fclose(tmpfp);
-
-       if (cmdline && (p = strchr(cmdline, '%')) && *(p + 1) == 's' &&
-           !strchr(p + 2, '%'))
-               g_snprintf(buf, sizeof(buf) - 1, cmdline, prtmp);
-       else {
-               if (cmdline)
-                       g_warning("Print command-line is invalid: '%s'\n",
-                                 cmdline);
-               g_snprintf(buf, sizeof(buf) - 1, def_cmd, prtmp);
-       }
-
-       g_free(prtmp);
-
-       g_strchomp(buf);
-       if (buf[strlen(buf) - 1] != '&')
-               strncat(buf, "&", sizeof(buf) - strlen(buf) - 1);
-       if (system(buf) == -1)
-               g_warning("system(%s) failed.", buf);
-}
 
 MsgInfo *procmsg_msginfo_new_ref(MsgInfo *msginfo)
 {
@@ -1219,6 +1208,28 @@ MsgInfo *procmsg_msginfo_new(void)
        return newmsginfo;
 }
 
+static MsgInfoAvatar *procmsg_msginfoavatar_copy(MsgInfoAvatar *avatar)
+{
+       MsgInfoAvatar *newavatar;
+
+       if (avatar == NULL) return NULL;
+
+       newavatar = g_new0(MsgInfoAvatar, 1);
+       newavatar->avatar_id = avatar->avatar_id;
+       newavatar->avatar_src = g_strdup(avatar->avatar_src);
+
+       return newavatar;
+}
+
+static void procmsg_msginfoavatar_free(MsgInfoAvatar *avatar)
+{
+       if (avatar != NULL) {
+               if (avatar->avatar_src != NULL)
+                       g_free(avatar->avatar_src);
+               g_free(avatar);
+       }
+}
+
 MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
 {
        MsgInfo *newmsginfo;
@@ -1258,8 +1269,10 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
 
        if (msginfo->extradata) {
                newmsginfo->extradata = g_new0(MsgInfoExtraData, 1);
-               MEMBDUP(extradata->face);
-               MEMBDUP(extradata->xface);
+               if (msginfo->extradata->avatars) {
+                       newmsginfo->extradata->avatars = slist_copy_deep(msginfo->extradata->avatars,
+                                                               (GCopyFunc) procmsg_msginfoavatar_copy);
+               }
                MEMBDUP(extradata->dispositionnotificationto);
                MEMBDUP(extradata->returnreceiptto);
                MEMBDUP(extradata->partial_recv);
@@ -1271,6 +1284,7 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
                MEMBDUP(extradata->list_help);
                MEMBDUP(extradata->list_archive);
                MEMBDUP(extradata->list_owner);
+               MEMBDUP(extradata->resent_from);
        }
 
         refs = msginfo->references;
@@ -1318,10 +1332,9 @@ MsgInfo *procmsg_msginfo_get_full_info_from_file(MsgInfo *msginfo, const gchar *
                        msginfo->extradata->list_archive= g_strdup(full_msginfo->extradata->list_archive);
                if (!msginfo->extradata->list_owner)
                        msginfo->extradata->list_owner = g_strdup(full_msginfo->extradata->list_owner);
-               if (!msginfo->extradata->xface)
-                       msginfo->extradata->xface = g_strdup(full_msginfo->extradata->xface);
-               if (!msginfo->extradata->face)
-                       msginfo->extradata->face = g_strdup(full_msginfo->extradata->face);
+               if (!msginfo->extradata->avatars)
+                       msginfo->extradata->avatars = slist_copy_deep(full_msginfo->extradata->avatars,
+                                                                       (GCopyFunc) procmsg_msginfoavatar_copy);
                if (!msginfo->extradata->dispositionnotificationto)
                        msginfo->extradata->dispositionnotificationto = 
                                g_strdup(full_msginfo->extradata->dispositionnotificationto);
@@ -1337,6 +1350,9 @@ MsgInfo *procmsg_msginfo_get_full_info_from_file(MsgInfo *msginfo, const gchar *
                if (!msginfo->extradata->account_login && full_msginfo->extradata->account_login)
                        msginfo->extradata->account_login = g_strdup
                                (full_msginfo->extradata->account_login);
+               if (!msginfo->extradata->resent_from && full_msginfo->extradata->resent_from)
+                       msginfo->extradata->resent_from = g_strdup
+                               (full_msginfo->extradata->resent_from);
        }
        procmsg_msginfo_free(full_msginfo);
 
@@ -1393,10 +1409,14 @@ void procmsg_msginfo_free(MsgInfo *msginfo)
        g_free(msginfo->xref);
 
        if (msginfo->extradata) {
+               if (msginfo->extradata->avatars) {
+                       g_slist_foreach(msginfo->extradata->avatars,
+                                       (GFunc)procmsg_msginfoavatar_free,
+                                       NULL);
+                       g_slist_free(msginfo->extradata->avatars);
+               }
                g_free(msginfo->extradata->returnreceiptto);
                g_free(msginfo->extradata->dispositionnotificationto);
-               g_free(msginfo->extradata->xface);
-               g_free(msginfo->extradata->face);
                g_free(msginfo->extradata->list_post);
                g_free(msginfo->extradata->list_subscribe);
                g_free(msginfo->extradata->list_unsubscribe);
@@ -1406,10 +1426,10 @@ void procmsg_msginfo_free(MsgInfo *msginfo)
                g_free(msginfo->extradata->partial_recv);
                g_free(msginfo->extradata->account_server);
                g_free(msginfo->extradata->account_login);
+               g_free(msginfo->extradata->resent_from);
                g_free(msginfo->extradata);
        }
-       slist_free_strings(msginfo->references);
-       g_slist_free(msginfo->references);
+       slist_free_strings_full(msginfo->references);
        g_slist_free(msginfo->tags);
 
        g_free(msginfo->plaintext_file);
@@ -1454,10 +1474,13 @@ guint procmsg_msginfo_memusage(MsgInfo *msginfo)
        }
        if (msginfo->extradata) {
                memusage += sizeof(MsgInfoExtraData);
-               if (msginfo->extradata->xface)
-                       memusage += strlen(msginfo->extradata->xface);
-               if (msginfo->extradata->face)
-                       memusage += strlen(msginfo->extradata->face);
+               if (msginfo->extradata->avatars) {
+                       for (tmp = msginfo->extradata->avatars; tmp; tmp = tmp->next) {
+                               MsgInfoAvatar *avt = (MsgInfoAvatar *)tmp->data;
+                               memusage += (avt->avatar_src)? strlen(avt->avatar_src): 0;
+                               memusage += sizeof(MsgInfoAvatar) + sizeof(GSList);
+                       }
+               }
                if (msginfo->extradata->dispositionnotificationto)
                        memusage += strlen(msginfo->extradata->dispositionnotificationto);
                if (msginfo->extradata->returnreceiptto)
@@ -1469,6 +1492,8 @@ guint procmsg_msginfo_memusage(MsgInfo *msginfo)
                        memusage += strlen(msginfo->extradata->account_server);
                if (msginfo->extradata->account_login)
                        memusage += strlen(msginfo->extradata->account_login);
+               if (msginfo->extradata->resent_from)
+                       memusage += strlen(msginfo->extradata->resent_from);
 
                if (msginfo->extradata->list_post)
                        memusage += strlen(msginfo->extradata->list_post);
@@ -1489,22 +1514,23 @@ guint procmsg_msginfo_memusage(MsgInfo *msginfo)
 static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_session, gchar **errstr,
                                            FolderItem *queue, gint msgnum, gboolean *queued_removed)
 {
-       static HeaderEntry qentry[] = {{"S:",    NULL, FALSE},
+       static HeaderEntry qentry[] = {
+                                      {"S:",    NULL, FALSE}, /* 0 */
                                       {"SSV:",  NULL, FALSE},
                                       {"R:",    NULL, FALSE},
                                       {"NG:",   NULL, FALSE},
                                       {"MAID:", NULL, FALSE},
-                                      {"NAID:", NULL, FALSE},
+                                      {"NAID:", NULL, FALSE}, /* 5 */
                                       {"SCF:",  NULL, FALSE},
                                       {"RMID:", NULL, FALSE},
                                       {"FMID:", NULL, FALSE},
                                       {"X-Claws-Privacy-System:", NULL, FALSE},
-                                      {"X-Claws-Encrypt:", NULL, FALSE},
+                                      {"X-Claws-Encrypt:", NULL, FALSE}, /* 10 */
                                       {"X-Claws-Encrypt-Data:", NULL, FALSE},
                                       {"X-Claws-End-Special-Headers:", NULL, FALSE},
                                       {"X-Sylpheed-Privacy-System:", NULL, FALSE},
                                       {"X-Sylpheed-Encrypt:", NULL, FALSE},
-                                      {"X-Sylpheed-Encrypt-Data:", NULL, FALSE},
+                                      {"X-Sylpheed-Encrypt-Data:", NULL, FALSE}, /* 15 */
                                       {"X-Sylpheed-End-Special-Headers:", NULL, FALSE},
                                       {NULL,    NULL, FALSE}};
        FILE *fp;
@@ -1517,14 +1543,11 @@ static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_ses
        gchar *savecopyfolder = NULL;
        gchar *replymessageid = NULL;
        gchar *fwdmessageid = NULL;
-       gchar *privacy_system = NULL;
-       gboolean encrypt = FALSE;
-       gchar *encrypt_data = NULL;
        gchar buf[BUFFSIZE];
        gint hnum;
        PrefsAccount *mailac = NULL, *newsac = NULL;
-       gboolean save_clear_text = TRUE;
-       gchar *tmp_enc_file = NULL;
+       gboolean encrypt = FALSE;
+       FolderItem *outbox;
 
        cm_return_val_if_fail(file != NULL, -1);
 
@@ -1574,21 +1597,11 @@ static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_ses
                        if (fwdmessageid == NULL) 
                                fwdmessageid = g_strdup(p);
                        break;
-               case Q_PRIVACY_SYSTEM:
-               case Q_PRIVACY_SYSTEM_OLD:
-                       if (privacy_system == NULL) 
-                               privacy_system = g_strdup(p);
-                       break;
                case Q_ENCRYPT:
                case Q_ENCRYPT_OLD:
                        if (p[0] == '1') 
                                encrypt = TRUE;
                        break;
-               case Q_ENCRYPT_DATA:
-               case Q_ENCRYPT_DATA_OLD:
-                       if (encrypt_data == NULL) 
-                               encrypt_data = g_strdup(p);
-                       break;
                case Q_CLAWS_HDRS:
                case Q_CLAWS_HDRS_OLD:
                        /* end of special headers reached */
@@ -1597,66 +1610,14 @@ static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_ses
        }
 send_mail:
        filepos = ftell(fp);
-
-       if (encrypt) {
-               MimeInfo *mimeinfo;
-
-               if (mailac && mailac->save_encrypted_as_clear_text 
-               &&  !mailac->encrypt_to_self)
-                       save_clear_text = TRUE;
-               else
-                       save_clear_text = FALSE;
-
-               fclose(fp);
-               fp = NULL;
-
-               mimeinfo = procmime_scan_queue_file(file);
-               if (!privacy_encrypt(privacy_system, mimeinfo, encrypt_data)
-               || (fp = my_tmpfile()) == NULL
-               ||  procmime_write_mimeinfo(mimeinfo, fp) < 0) {
-                       if (fp)
-                               fclose(fp);
-                       procmime_mimeinfo_free_all(mimeinfo);
-                       g_free(from);
-                       g_free(smtpserver);
-                       slist_free_strings(to_list);
-                       g_slist_free(to_list);
-                       slist_free_strings(newsgroup_list);
-                       g_slist_free(newsgroup_list);
-                       g_free(savecopyfolder);
-                       g_free(replymessageid);
-                       g_free(fwdmessageid);
-                       g_free(privacy_system);
-                       g_free(encrypt_data);
-                       if (errstr) {
-                               if (*errstr) g_free(*errstr);
-                               *errstr = g_strdup_printf(_("Couldn't encrypt the email: %s"),
-                                               privacy_get_error());
-                       }
-                       return -1;
+       if (filepos < 0) {
+               FILE_OP_ERROR(file, "ftell");
+               if (errstr) {
+                       if (*errstr) g_free(*errstr);
+                       *errstr = g_strdup_printf(_("Couldn't open file %s."), file);
                }
-               
-               rewind(fp);
-               if (!save_clear_text) {
-                       gchar *content = NULL;
-                       FILE *tmpfp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmp_enc_file);
-                       if (tmpfp) {
-                               fclose(tmpfp);
-
-                               content = file_read_stream_to_str(fp);
-                               rewind(fp);
-
-                               str_write_to_file(content, tmp_enc_file);
-                               g_free(content);
-                       } else {
-                               g_warning("couldn't get tempfile\n");
-                       }
-               } 
-               
-               procmime_mimeinfo_free_all(mimeinfo);
-               
-               filepos = 0;
-       }
+               return -1;
+       }
 
        if (to_list) {
                debug_print("Sending message by mail\n");
@@ -1705,13 +1666,17 @@ send_mail:
        } else if (!to_list && !newsgroup_list) {
                if (errstr) {
                        if (*errstr) g_free(*errstr);
-                       *errstr = g_strdup(_("Couldn't determine sending informations. "
+                       *errstr = g_strdup(_("Couldn't determine sending information. "
                                "Maybe the email hasn't been generated by Claws Mail."));
                }
                mailval = -1;
        }
 
-       fseek(fp, filepos, SEEK_SET);
+       if (fseek(fp, filepos, SEEK_SET) < 0) {
+               FILE_OP_ERROR(file, "fseek");
+               mailval = -1;
+       }
+
        if (newsgroup_list && newsac && (mailval == 0)) {
                Folder *folder;
                gchar *tmp = NULL;
@@ -1774,15 +1739,14 @@ send_mail:
 
        /* save message to outbox */
        if (mailval == 0 && newsval == 0 && savecopyfolder) {
-               FolderItem *outbox;
-
                debug_print("saving sent message...\n");
 
-               outbox = folder_find_item_from_identifier(savecopyfolder);
-               if (!outbox)
-                       outbox = folder_get_default_outbox();
-                       
-               if (save_clear_text || tmp_enc_file == NULL) {
+               if (!encrypt || !mailac->save_encrypted_as_clear_text) {
+                       outbox = folder_find_item_from_identifier(savecopyfolder);
+                       if (!outbox)
+                               outbox = folder_get_default_outbox();
+
+                       /* Mail was not saved to outbox before encrypting, save it now. */
                        gboolean saved = FALSE;
                        *queued_removed = FALSE;
                        if (queue && msgnum > 0) {
@@ -1798,21 +1762,12 @@ send_mail:
                                procmsg_msginfo_free(queued_mail);
                        }
                        if (!saved) {
-                               debug_print("resaving clear text queued mail to sent folder\n");
+                               debug_print("resaving queued mail to sent folder\n");
                                procmsg_save_to_outbox(outbox, file, TRUE);
                        }
-               } else {
-                       debug_print("saving encrpyted queued mail to sent folder\n");
-                       procmsg_save_to_outbox(outbox, tmp_enc_file, FALSE);
                }
        }
 
-       if (tmp_enc_file != NULL) {
-               claws_unlink(tmp_enc_file);
-               free(tmp_enc_file);
-               tmp_enc_file = NULL;
-       }
-
        if (replymessageid != NULL || fwdmessageid != NULL) {
                gchar **tokens;
                FolderItem *item;
@@ -1861,15 +1816,11 @@ send_mail:
 
        g_free(from);
        g_free(smtpserver);
-       slist_free_strings(to_list);
-       g_slist_free(to_list);
-       slist_free_strings(newsgroup_list);
-       g_slist_free(newsgroup_list);
+       slist_free_strings_full(to_list);
+       slist_free_strings_full(newsgroup_list);
        g_free(savecopyfolder);
        g_free(replymessageid);
        g_free(fwdmessageid);
-       g_free(privacy_system);
-       g_free(encrypt_data);
 
        return (newsval != 0 ? newsval : mailval);
 }
@@ -1877,6 +1828,7 @@ send_mail:
 gint procmsg_send_message_queue(const gchar *file, gchar **errstr, FolderItem *queue, gint msgnum, gboolean *queued_removed)
 {
        gint result = procmsg_send_message_queue_full(file, FALSE, errstr, queue, msgnum, queued_removed);
+       main_window_set_menu_sensitive(mainwindow_get_mainwindow());
        toolbar_main_set_sensitive(mainwindow_get_mainwindow());
        return result;
 }