static void mimeview_drag_data_get(GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *selection_data, guint info, guint time, MimeView *mimeview) { gchar *filename, *uriname; MimeInfo *partinfo; if (!mimeview->opened) return; if (!mimeview->file) return; partinfo = mimeview_get_selected_part(mimeview); if (!partinfo) return; filename = g_basename(get_part_name(partinfo)); if (*filename == '\0') return; filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S, filename, NULL); if (procmime_get_part(filename, partinfo) < 0) alertpanel_error (_("Can't save the part of multipart message.")); uriname = g_strconcat("file://", filename, NULL); gtk_selection_data_set(selection_data, selection_data->target, 8, uriname, strlen(uriname)); g_free(uriname); g_free(filename); }
static MimeInfo *tnef_broken_mimeinfo(const gchar *reason) { MimeInfo *sub_info = NULL; gchar *tmpfilename = NULL; FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename); struct stat statbuf; if (!fp) { g_free(tmpfilename); return NULL; } sub_info = procmime_mimeinfo_new(); sub_info->content = MIMECONTENT_FILE; sub_info->data.filename = tmpfilename; sub_info->type = MIMETYPE_TEXT; sub_info->subtype = g_strdup("plain"); fprintf(fp, _("\n" "Claws Mail TNEF parser:\n\n" "%s\n"), reason?reason:_("Unknown error")); fclose(fp); g_stat(tmpfilename, &statbuf); sub_info->tmp = TRUE; sub_info->length = statbuf.st_size; sub_info->encoding_type = ENC_BINARY; return sub_info; }
MimeInfo *tnef_parse_vcard(TNEFStruct tnef) { MimeInfo *sub_info = NULL; gchar *tmpfilename = NULL; FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename); struct stat statbuf; gboolean result = FALSE; if (!fp) { g_free(tmpfilename); return NULL; } sub_info = procmime_mimeinfo_new(); sub_info->content = MIMECONTENT_FILE; sub_info->data.filename = tmpfilename; sub_info->type = MIMETYPE_TEXT; sub_info->subtype = g_strdup("x-vcard"); g_hash_table_insert(sub_info->typeparameters, g_strdup("filename"), g_strdup("contact.vcf")); result = SaveVCard(fp, tnef); fclose(fp); g_stat(tmpfilename, &statbuf); sub_info->tmp = TRUE; sub_info->length = statbuf.st_size; sub_info->encoding_type = ENC_BINARY; if (!result) { claws_unlink(tmpfilename); procmime_mimeinfo_free_all(sub_info); return tnef_broken_mimeinfo(_("Failed to parse VCard data.")); } return sub_info; }
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; g_return_if_fail(msginfo); if ((tmpfp = procmime_get_first_text_content(msginfo)) == 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 = fopen(prtmp, "wb")) == NULL) { FILE_OP_ERROR(prtmp, "fopen"); g_free(prtmp); fclose(tmpfp); return; } if (msginfo->date) fprintf(prfp, "Date: %s\n", msginfo->date); if (msginfo->from) fprintf(prfp, "From: %s\n", msginfo->from); if (msginfo->to) fprintf(prfp, "To: %s\n", msginfo->to); if (msginfo->cc) fprintf(prfp, "Cc: %s\n", msginfo->cc); if (msginfo->newsgroups) fprintf(prfp, "Newsgroups: %s\n", msginfo->newsgroups); if (msginfo->subject) fprintf(prfp, "Subject: %s\n", msginfo->subject); fputc('\n', prfp); while (fgets(buf, sizeof(buf), tmpfp) != NULL) 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] != '&') strcat(buf, "&"); system(buf); }
static MimeInfo *tnef_dump_file(const gchar *filename, char *data, size_t size) { MimeInfo *sub_info = NULL; gchar *tmpfilename = NULL; FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename); GStatBuf statbuf; gchar *content_type = NULL; if (!fp) { g_free(tmpfilename); return NULL; } sub_info = procmime_mimeinfo_new(); sub_info->content = MIMECONTENT_FILE; sub_info->data.filename = tmpfilename; sub_info->type = MIMETYPE_APPLICATION; sub_info->subtype = g_strdup("octet-stream"); if (filename) { g_hash_table_insert(sub_info->typeparameters, g_strdup("filename"), g_strdup(filename)); content_type = procmime_get_mime_type(filename); if (content_type && strchr(content_type, '/')) { g_free(sub_info->subtype); sub_info->subtype = g_strdup(strchr(content_type, '/')+1); *(strchr(content_type, '/')) = '\0'; sub_info->type = procmime_get_media_type(content_type); g_free(content_type); } } if (claws_fwrite(data, 1, size, fp) < size) { FILE_OP_ERROR(tmpfilename, "claws_fwrite"); claws_fclose(fp); claws_unlink(tmpfilename); procmime_mimeinfo_free_all(&sub_info); return tnef_broken_mimeinfo(_("Failed to write the part data.")); } claws_fclose(fp); if (g_stat(tmpfilename, &statbuf) < 0) { claws_unlink(tmpfilename); procmime_mimeinfo_free_all(&sub_info); return tnef_broken_mimeinfo(_("Failed to write the part data.")); } else { sub_info->tmp = TRUE; sub_info->length = statbuf.st_size; sub_info->encoding_type = ENC_BINARY; } return sub_info; }
gint syl_setup_rc_dir(void) { if (!is_dir_exist(get_rc_dir())) { if (make_dir_hier(get_rc_dir()) < 0) return -1; } MAKE_DIR_IF_NOT_EXIST(get_mail_base_dir()); CHDIR_RETURN_VAL_IF_FAIL(get_rc_dir(), -1); MAKE_DIR_IF_NOT_EXIST(get_imap_cache_dir()); MAKE_DIR_IF_NOT_EXIST(get_news_cache_dir()); MAKE_DIR_IF_NOT_EXIST(get_mime_tmp_dir()); MAKE_DIR_IF_NOT_EXIST(get_tmp_dir()); MAKE_DIR_IF_NOT_EXIST(UIDL_DIR); MAKE_DIR_IF_NOT_EXIST(PLUGIN_DIR); /* remove temporary files */ remove_all_files(get_tmp_dir()); remove_all_files(get_mime_tmp_dir()); return 0; }
void syl_cleanup(void) { /* remove temporary files */ remove_all_files(get_tmp_dir()); remove_all_files(get_mime_tmp_dir()); #if GLIB_CHECK_VERSION(2, 6, 0) g_log_set_default_handler(g_log_default_handler, NULL); #endif close_log_file(); sock_cleanup(); if (app) { g_object_unref(app); app = NULL; } }
MimeInfo *tnef_parse_vtask(TNEFStruct *tnef) { MimeInfo *sub_info = NULL; gchar *tmpfilename = NULL; FILE *fp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename); GStatBuf statbuf; gboolean result = FALSE; if (!fp) { g_free(tmpfilename); return NULL; } sub_info = procmime_mimeinfo_new(); sub_info->content = MIMECONTENT_FILE; sub_info->data.filename = tmpfilename; sub_info->type = MIMETYPE_TEXT; sub_info->subtype = g_strdup("calendar"); g_hash_table_insert(sub_info->typeparameters, g_strdup("filename"), g_strdup("task.ics")); result = SaveVTask(fp, tnef); claws_fclose(fp); if (g_stat(tmpfilename, &statbuf) < 0) { result = FALSE; } else { sub_info->tmp = TRUE; sub_info->length = statbuf.st_size; sub_info->encoding_type = ENC_BINARY; } if (!result) { claws_unlink(tmpfilename); procmime_mimeinfo_free_all(&sub_info); return tnef_broken_mimeinfo(_("Failed to parse VTask data.")); } return sub_info; }
static void mimeview_drag_begin(GtkWidget *widget, GdkDragContext *drag_context, MimeView *mimeview) { gchar *filename; gchar *bname = NULL; MimeInfo *partinfo; if (!mimeview->opened) return; if (!mimeview->messageview->file) return; partinfo = mimeview_get_selected_part(mimeview); if (!partinfo) return; filename = partinfo->filename ? partinfo->filename : partinfo->name; if (filename) { const gchar *bname_; bname_ = g_basename(filename); bname = conv_filename_from_utf8(bname_); subst_for_filename(bname); } if (!bname || *bname == '\0') filename = procmime_get_tmp_file_name(partinfo); else filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S, bname, NULL); if (procmime_get_part(filename, mimeview->messageview->file, partinfo) < 0) { g_warning(_("Can't save the part of multipart message.")); } else mimeview->drag_file = encode_uri(filename); g_free(filename); gtk_drag_set_icon_default(drag_context); }
static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo) { MimeInfo *decinfo, *parseinfo; gpgme_data_t cipher, plain; FILE *dstfp; gchar *fname; gchar *textdata = NULL; static gint id = 0; const gchar *src_codeset = NULL; gpgme_verify_result_t sigstat = 0; PrivacyDataPGP *data = NULL; gpgme_ctx_t ctx; gchar *chars; size_t len; const gchar *begin_indicator = "-----BEGIN PGP MESSAGE-----"; const gchar *end_indicator = "-----END PGP MESSAGE-----"; gchar *pos; if (gpgme_new(&ctx) != GPG_ERR_NO_ERROR) return NULL; gpgme_set_textmode(ctx, 1); gpgme_set_armor(ctx, 1); cm_return_val_if_fail(mimeinfo != NULL, NULL); cm_return_val_if_fail(pgpinline_is_encrypted(mimeinfo), NULL); if (procmime_mimeinfo_parent(mimeinfo) == NULL || mimeinfo->type != MIMETYPE_TEXT) { gpgme_release(ctx); privacy_set_error(_("Couldn't parse mime part.")); return NULL; } textdata = get_part_as_string(mimeinfo); if (!textdata) { gpgme_release(ctx); privacy_set_error(_("Couldn't get text data.")); return NULL; } debug_print("decrypting '%s'\n", textdata); gpgme_data_new_from_mem(&cipher, textdata, (size_t)strlen(textdata), 1); plain = sgpgme_decrypt_verify(cipher, &sigstat, ctx); if (sigstat && !sigstat->signatures) sigstat = NULL; gpgme_data_release(cipher); if (plain == NULL) { gpgme_release(ctx); return NULL; } fname = g_strdup_printf("%s%cplaintext.%08x", get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id); if ((dstfp = g_fopen(fname, "wb")) == NULL) { FILE_OP_ERROR(fname, "fopen"); privacy_set_error(_("Couldn't open decrypted file %s"), fname); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); return NULL; } src_codeset = procmime_mimeinfo_get_parameter(mimeinfo, "charset"); if (src_codeset == NULL) src_codeset = CS_ISO_8859_1; if (fprintf(dstfp, "MIME-Version: 1.0\r\n" "Content-Type: text/plain; charset=%s\r\n" "Content-Transfer-Encoding: 8bit\r\n" "\r\n", src_codeset) < 0) { FILE_OP_ERROR(fname, "fprintf"); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); goto FILE_ERROR; } /* Store any part before encrypted text */ pos = pgp_locate_armor_header(textdata, begin_indicator); if (pos != NULL && (pos - textdata) > 0) { if (fwrite(textdata, 1, pos - textdata, dstfp) < pos - textdata) { FILE_OP_ERROR(fname, "fwrite"); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); goto FILE_ERROR; } } if (fwrite(_("\n--- Start of PGP/Inline encrypted data ---\n"), 1, strlen(_("\n--- Start of PGP/Inline encrypted data ---\n")), dstfp) < strlen(_("\n--- Start of PGP/Inline encrypted data ---\n"))) { FILE_OP_ERROR(fname, "fwrite"); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); goto FILE_ERROR; } chars = sgpgme_data_release_and_get_mem(plain, &len); if (len > 0) { if (fwrite(chars, 1, len, dstfp) < len) { FILE_OP_ERROR(fname, "fwrite"); g_free(chars); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); goto FILE_ERROR; } } g_free(chars); /* Store any part after encrypted text */ if (fwrite(_("--- End of PGP/Inline encrypted data ---\n"), 1, strlen(_("--- End of PGP/Inline encrypted data ---\n")), dstfp) < strlen(_("--- End of PGP/Inline encrypted data ---\n"))) { FILE_OP_ERROR(fname, "fwrite"); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); goto FILE_ERROR; } if (pos != NULL) { pos = pgp_locate_armor_header(pos, end_indicator); if (pos != NULL && *pos != '\0') { pos += strlen(end_indicator); if (fwrite(pos, 1, strlen(pos), dstfp) < strlen(pos)) { FILE_OP_ERROR(fname, "fwrite"); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); goto FILE_ERROR; } } } if (fclose(dstfp) == EOF) { FILE_OP_ERROR(fname, "fclose"); privacy_set_error(_("Couldn't close decrypted file %s"), fname); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); return NULL; } parseinfo = procmime_scan_file(fname); g_free(fname); if (parseinfo == NULL) { gpgme_release(ctx); privacy_set_error(_("Couldn't scan decrypted file.")); return NULL; } decinfo = g_node_first_child(parseinfo->node) != NULL ? g_node_first_child(parseinfo->node)->data : NULL; if (decinfo == NULL) { gpgme_release(ctx); privacy_set_error(_("Couldn't scan decrypted file parts.")); return NULL; } g_node_unlink(decinfo->node); procmime_mimeinfo_free_all(parseinfo); decinfo->tmp = TRUE; if (sigstat != GPGME_SIG_STAT_NONE) { if (decinfo->privacy != NULL) { data = (PrivacyDataPGP *) decinfo->privacy; } else { data = pgpinline_new_privacydata(); decinfo->privacy = (PrivacyData *) data; } if (data != NULL) { data->done_sigtest = TRUE; data->is_signed = TRUE; data->sigstatus = sigstat; if (data->ctx) gpgme_release(data->ctx); data->ctx = ctx; } } else gpgme_release(ctx); return decinfo; FILE_ERROR: fclose(dstfp); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); return NULL; }
gint procmsg_send_message_queue(const gchar *file) { static HeaderEntry qentry[] = {{"S:", NULL, FALSE}, {"SSV:", NULL, FALSE}, {"R:", NULL, FALSE}, {"NG:", NULL, FALSE}, {"MAID:", NULL, FALSE}, {"NAID:", NULL, FALSE}, {"SCF:", NULL, FALSE}, {"RMID:", NULL, FALSE}, {"FMID:", NULL, FALSE}, {"X-Sylpheed-Privacy-System:", NULL, FALSE}, {"X-Sylpheed-Encrypt:", NULL, FALSE}, {"X-Sylpheed-Encrypt-Data:", NULL, FALSE}, {NULL, NULL, FALSE}}; FILE *fp; gint filepos; gint mailval = 0, newsval = 0; gchar *from = NULL; gchar *smtpserver = NULL; GSList *to_list = NULL; GSList *newsgroup_list = NULL; 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; int local = 0; g_return_val_if_fail(file != NULL, -1); if ((fp = fopen(file, "rb")) == NULL) { FILE_OP_ERROR(file, "fopen"); return -1; } while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, qentry)) != -1) { gchar *p = buf + strlen(qentry[hnum].name); switch (hnum) { case Q_SENDER: if (from == NULL) from = g_strdup(p); break; case Q_SMTPSERVER: if (smtpserver == NULL) smtpserver = g_strdup(p); break; case Q_RECIPIENTS: to_list = address_list_append(to_list, p); break; case Q_NEWSGROUPS: newsgroup_list = newsgroup_list_append(newsgroup_list, p); break; case Q_MAIL_ACCOUNT_ID: mailac = account_find_from_id(atoi(p)); break; case Q_NEWS_ACCOUNT_ID: newsac = account_find_from_id(atoi(p)); break; case Q_SAVE_COPY_FOLDER: if (savecopyfolder == NULL) savecopyfolder = g_strdup(p); break; case Q_REPLY_MESSAGE_ID: if (replymessageid == NULL) replymessageid = g_strdup(p); break; case Q_FWD_MESSAGE_ID: if (fwdmessageid == NULL) fwdmessageid = g_strdup(p); break; case Q_PRIVACY_SYSTEM: if (privacy_system == NULL) privacy_system = g_strdup(p); break; case Q_ENCRYPT: if (p[0] == '1') encrypt = TRUE; break; case Q_ENCRYPT_DATA: if (encrypt_data == NULL) encrypt_data = g_strdup(p); break; } } filepos = ftell(fp); if (encrypt) { MimeInfo *mimeinfo; save_clear_text = (mailac != NULL && mailac->save_encrypted_as_clear_text); 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); return -1; } 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; } if (to_list) { debug_print("Sending message by mail\n"); if (!from) { g_warning("Queued message header is broken.\n"); mailval = -1; } 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 (!mailac) { mailac = account_find_from_smtp_server(from, smtpserver); if (!mailac) { g_warning("Account not found. " "Using current account...\n"); mailac = cur_account; } } if (mailac) mailval = send_message_smtp(mailac, to_list, fp); else { PrefsAccount tmp_ac; g_warning("Account not found.\n"); memset(&tmp_ac, 0, sizeof(PrefsAccount)); tmp_ac.address = from; tmp_ac.smtp_server = smtpserver; tmp_ac.smtpport = SMTP_PORT; mailval = send_message_smtp(&tmp_ac, to_list, fp); } } } fseek(fp, filepos, SEEK_SET); if (newsgroup_list && (mailval == 0)) { Folder *folder; gchar *tmp = NULL; 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, "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); if (newsval == 0) { debug_print("Sending message by news\n"); 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); } fclose(fp); /* 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) { procmsg_save_to_outbox(outbox, file, TRUE); } else { procmsg_save_to_outbox(outbox, tmp_enc_file, FALSE); } } if (tmp_enc_file != NULL) { unlink(tmp_enc_file); free(tmp_enc_file); tmp_enc_file = NULL; } if (replymessageid != NULL || fwdmessageid != NULL) { gchar **tokens; FolderItem *item; if (replymessageid != NULL) tokens = g_strsplit(replymessageid, "\x7f", 0); else tokens = g_strsplit(fwdmessageid, "\x7f", 0); item = folder_find_item_from_identifier(tokens[0]); /* check if queued message has valid folder and message id */ if (item != NULL && tokens[2] != NULL) { MsgInfo *msginfo; msginfo = folder_item_get_msginfo(item, atoi(tokens[1])); /* check if referring message exists and has a message id */ if ((msginfo != NULL) && (msginfo->msgid != NULL) && (strcmp(msginfo->msgid, tokens[2]) != 0)) { procmsg_msginfo_free(msginfo); msginfo = NULL; } if (msginfo == NULL) { msginfo = folder_item_get_msginfo_by_msgid(item, tokens[2]); } if (msginfo != NULL) { if (replymessageid != NULL) { procmsg_msginfo_unset_flags(msginfo, MSG_FORWARDED, 0); procmsg_msginfo_set_flags(msginfo, MSG_REPLIED, 0); } else { procmsg_msginfo_unset_flags(msginfo, MSG_REPLIED, 0); procmsg_msginfo_set_flags(msginfo, MSG_FORWARDED, 0); } procmsg_msginfo_free(msginfo); } } g_strfreev(tokens); } 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); return (newsval != 0 ? newsval : mailval); }
static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo) { MimeInfo *encinfo, *decinfo, *parseinfo; gpgme_data_t cipher = NULL, plain = NULL; static gint id = 0; FILE *dstfp; gchar *fname; gpgme_verify_result_t sigstat = NULL; PrivacyDataPGP *data = NULL; gpgme_ctx_t ctx; gchar *chars; size_t len; gpgme_error_t err; if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s\n"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); return NULL; } cm_return_val_if_fail(pgpmime_is_encrypted(mimeinfo), NULL); encinfo = (MimeInfo *) g_node_nth_child(mimeinfo->node, 1)->data; cipher = sgpgme_data_from_mimeinfo(encinfo); plain = sgpgme_decrypt_verify(cipher, &sigstat, ctx); gpgme_data_release(cipher); if (plain == NULL) { debug_print("plain is null!\n"); gpgme_release(ctx); return NULL; } fname = g_strdup_printf("%s%cplaintext.%08x", get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id); if ((dstfp = claws_fopen(fname, "wb")) == NULL) { FILE_OP_ERROR(fname, "claws_fopen"); privacy_set_error(_("Couldn't open decrypted file %s"), fname); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); debug_print("can't open!\n"); return NULL; } if (fprintf(dstfp, "MIME-Version: 1.0\n") < 0) { FILE_OP_ERROR(fname, "fprintf"); claws_fclose(dstfp); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); debug_print("can't open!\n"); return NULL; } chars = sgpgme_data_release_and_get_mem(plain, &len); if (len > 0) { if (claws_fwrite(chars, 1, len, dstfp) < len) { FILE_OP_ERROR(fname, "claws_fwrite"); g_free(chars); claws_fclose(dstfp); privacy_set_error(_("Couldn't write to decrypted file %s"), fname); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); debug_print("can't open!\n"); return NULL; } } g_free(chars); if (claws_safe_fclose(dstfp) == EOF) { FILE_OP_ERROR(fname, "claws_fclose"); privacy_set_error(_("Couldn't close decrypted file %s"), fname); g_free(fname); gpgme_data_release(plain); gpgme_release(ctx); debug_print("can't open!\n"); return NULL; } parseinfo = procmime_scan_file(fname); g_free(fname); if (parseinfo == NULL) { gpgme_release(ctx); privacy_set_error(_("Couldn't parse decrypted file.")); return NULL; } decinfo = g_node_first_child(parseinfo->node) != NULL ? g_node_first_child(parseinfo->node)->data : NULL; if (decinfo == NULL) { privacy_set_error(_("Couldn't parse decrypted file parts.")); gpgme_release(ctx); return NULL; } g_node_unlink(decinfo->node); procmime_mimeinfo_free_all(&parseinfo); decinfo->tmp = TRUE; if (sigstat != NULL && sigstat->signatures != NULL) { if (decinfo->privacy != NULL) { data = (PrivacyDataPGP *) decinfo->privacy; } else { data = pgpmime_new_privacydata(); decinfo->privacy = (PrivacyData *) data; } if (data != NULL) { data->done_sigtest = TRUE; data->is_signed = TRUE; data->sigstatus = sigstat; if (data->ctx) gpgme_release(data->ctx); data->ctx = ctx; } } else gpgme_release(ctx); return decinfo; }