/*! *\brief Open preferences file for writing * Prefs are written to a temp file: Call prefs_write_close() * to rename this to the final filename * *\param path Filename with path of preferences file to write * *\return PrefFile * preferences file struct */ PrefFile *prefs_write_open(const gchar *path) { PrefFile *pfile; gchar *tmppath; FILE *fp; cm_return_val_if_fail(path != NULL, NULL); if (prefs_is_readonly(path)) { g_warning("no permission - %s\n", path); return NULL; } tmppath = g_strconcat(path, ".tmp", NULL); if ((fp = g_fopen(tmppath, "wb")) == NULL) { FILE_OP_ERROR(tmppath, "fopen"); g_free(tmppath); return NULL; } if (change_file_mode_rw(fp, tmppath) < 0) FILE_OP_ERROR(tmppath, "chmod"); g_free(tmppath); pfile = g_new(PrefFile, 1); pfile->fp = fp; pfile->orig_fp = NULL; pfile->path = g_strdup(path); pfile->writing = TRUE; return pfile; }
gint news_cancel_article(Folder * folder, MsgInfo * msginfo) { gchar * tmp; FILE * tmpfp; gchar buf[BUFFSIZE]; tmp = g_strdup_printf("%s%ccancel%p", get_tmp_dir(), G_DIR_SEPARATOR, msginfo); if (tmp == NULL) return -1; if ((tmpfp = g_fopen(tmp, "wb")) == NULL) { FILE_OP_ERROR(tmp, "fopen"); return -1; } if (change_file_mode_rw(tmpfp, tmp) < 0) { FILE_OP_ERROR(tmp, "chmod"); g_warning("can't change file mode"); } get_rfc822_date(buf, sizeof(buf)); if (fprintf(tmpfp, "From: %s\r\n" "Newsgroups: %s\r\n" "Subject: cmsg cancel <%s>\r\n" "Control: cancel <%s>\r\n" "Approved: %s\r\n" "X-Cancelled-by: %s\r\n" "Date: %s\r\n" "\r\n" "removed with Claws Mail\r\n", msginfo->from, msginfo->newsgroups, msginfo->msgid, msginfo->msgid, msginfo->from, msginfo->from, buf) < 0) { FILE_OP_ERROR(tmp, "fprintf"); fclose(tmpfp); claws_unlink(tmp); g_free(tmp); return -1; } if (fclose(tmpfp) == EOF) { FILE_OP_ERROR(tmp, "fclose"); claws_unlink(tmp); g_free(tmp); return -1; } news_post(folder, tmp); claws_unlink(tmp); g_free(tmp); return 0; }
static FILE *msgcache_open_data_file(const gchar *file, gint version, DataOpenMode mode, gchar *buf, size_t buf_size) { FILE *fp; gint data_ver; g_return_val_if_fail(file != NULL, NULL); if (mode == DATA_WRITE) { if ((fp = fopen(file, "wb")) == NULL) { FILE_OP_ERROR(file, "fopen"); return NULL; } if (change_file_mode_rw(fp, file) < 0) FILE_OP_ERROR(file, "chmod"); WRITE_CACHE_DATA_INT(version, fp); return fp; } /* check version */ if ((fp = fopen(file, "rb")) == NULL) debug_print("Mark/Cache file not found\n"); else { if (buf && buf_size > 0) setvbuf(fp, buf, _IOFBF, buf_size); if (fread(&data_ver, sizeof(data_ver), 1, fp) != 1 || version != data_ver) { debug_print("Mark/Cache version is different (%d != %d). " "Discarding it.\n", data_ver, version); fclose(fp); fp = NULL; } } if (mode == DATA_READ) return fp; if (fp) { /* reopen with append mode */ fclose(fp); if ((fp = fopen(file, "ab")) == NULL) FILE_OP_ERROR(file, "fopen"); } else { /* open with overwrite mode if mark file doesn't exist or version is different */ fp = msgcache_open_data_file(file, version, DATA_WRITE, buf, buf_size); } return fp; }
gint msgcache_write(const gchar *cache_file, const gchar *mark_file, MsgCache *cache) { struct write_fps write_fps; g_return_val_if_fail(cache_file != NULL, -1); g_return_val_if_fail(mark_file != NULL, -1); g_return_val_if_fail(cache != NULL, -1); write_fps.cache_fp = msgcache_open_data_file(cache_file, CACHE_VERSION, DATA_WRITE, NULL, 0); if (write_fps.cache_fp == NULL) return -1; WRITE_CACHE_DATA(conv_get_current_charset_str(), write_fps.cache_fp); write_fps.mark_fp = msgcache_open_data_file(mark_file, MARK_VERSION, DATA_WRITE, NULL, 0); if (write_fps.mark_fp == NULL) { fclose(write_fps.cache_fp); return -1; } debug_print("\tWriting message cache to %s and %s...\n", cache_file, mark_file); if (change_file_mode_rw(write_fps.cache_fp, cache_file) < 0) FILE_OP_ERROR(cache_file, "chmod"); g_hash_table_foreach(cache->msgnum_table, msgcache_write_func, (gpointer)&write_fps); fclose(write_fps.cache_fp); fclose(write_fps.mark_fp); cache->last_access = time(NULL); debug_print("done.\n"); return 0; }
static gint pop3_write_msg_to_file(const gchar *file, const gchar *data, guint len, const gchar *prefix) { FILE *fp; const gchar *prev, *cur; cm_return_val_if_fail(file != NULL, -1); if ((fp = g_fopen(file, "wb")) == NULL) { FILE_OP_ERROR(file, "fopen"); return -1; } if (change_file_mode_rw(fp, file) < 0) FILE_OP_ERROR(file, "chmod"); if (prefix != NULL) { if (fprintf(fp, "%s\n", prefix) < 0) { FILE_OP_ERROR(file, "fprintf"); fclose(fp); claws_unlink(file); return -1; } } /* +------------------+----------------+--------------------------+ * * ^data ^prev ^cur data+len-1^ */ prev = data; while ((cur = (gchar *)my_memmem(prev, len - (prev - data), "\r\n", 2)) != NULL) { if ((cur > prev && fwrite(prev, 1, cur - prev, fp) < 1) || fputc('\n', fp) == EOF) { FILE_OP_ERROR(file, "fwrite"); g_warning("can't write to file: %s\n", file); fclose(fp); claws_unlink(file); return -1; } if (cur == data + len - 1) { prev = cur + 1; break; } if (*(cur + 1) == '\n') prev = cur + 2; else prev = cur + 1; if (prev - data < len - 1 && *prev == '.' && *(prev + 1) == '.') prev++; if (prev - data >= len) break; } if (prev - data < len && fwrite(prev, 1, len - (prev - data), fp) < 1) { FILE_OP_ERROR(file, "fwrite"); g_warning("can't write to file: %s\n", file); fclose(fp); claws_unlink(file); return -1; } if (data[len - 1] != '\r' && data[len - 1] != '\n') { if (fputc('\n', fp) == EOF) { FILE_OP_ERROR(file, "fputc"); g_warning("can't write to file: %s\n", file); fclose(fp); claws_unlink(file); return -1; } } if (fclose(fp) == EOF) { FILE_OP_ERROR(file, "fclose"); claws_unlink(file); return -1; } return 0; }
gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter, PrefsAccount *account) /* return values: -1 error, >=0 number of msgs added */ { FILE *mbox_fp; gchar buf[MESSAGEBUFSIZE]; gchar *tmp_file; gint msgs = 0; gint lines; MsgInfo *msginfo; gboolean more; GSList *to_filter = NULL, *filtered = NULL, *unfiltered = NULL, *cur, *to_add = NULL; gboolean printed = FALSE; FolderItem *dropfolder; cm_return_val_if_fail(dest != NULL, -1); cm_return_val_if_fail(mbox != NULL, -1); debug_print("Getting messages from %s into %s...\n", mbox, dest->path); if ((mbox_fp = g_fopen(mbox, "rb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); alertpanel_error(_("Could not open mbox file:\n%s\n"), mbox); return -1; } /* ignore empty lines on the head */ do { if (fgets(buf, sizeof(buf), mbox_fp) == NULL) { g_warning("can't read mbox file.\n"); fclose(mbox_fp); return -1; } } while (buf[0] == '\n' || buf[0] == '\r'); if (strncmp(buf, "From ", 5) != 0) { g_warning("invalid mbox format: %s\n", mbox); fclose(mbox_fp); return -1; } tmp_file = get_tmp_file(); folder_item_update_freeze(); if (apply_filter) dropfolder = folder_get_default_processing(); else dropfolder = dest; do { FILE *tmp_fp; gint empty_lines; gint msgnum; if (msgs > 0 && msgs%500 == 0) { if (printed) statusbar_pop_all(); statusbar_print_all( ngettext("Importing from mbox... (%d mail imported)", "Importing from mbox... (%d mails imported)", msgs), msgs); printed=TRUE; GTK_EVENTS_FLUSH(); } if ((tmp_fp = g_fopen(tmp_file, "wb")) == NULL) { FILE_OP_ERROR(tmp_file, "fopen"); g_warning("can't open temporary file\n"); fclose(mbox_fp); g_free(tmp_file); return -1; } if (change_file_mode_rw(tmp_fp, tmp_file) < 0) { FILE_OP_ERROR(tmp_file, "chmod"); } empty_lines = 0; lines = 0; /* process all lines from mboxrc file */ while (fgets(buf, sizeof(buf), mbox_fp) != NULL) { int offset; /* eat empty lines */ if (buf[0] == '\n' || buf[0] == '\r') { empty_lines++; continue; } /* From separator or quoted From */ offset = 0; /* detect leading '>' char(s) */ while ((buf[offset] == '>')) { offset++; } if (!strncmp(buf+offset, "From ", 5)) { /* From separator: */ if (offset == 0) { /* expect next mbox item */ break; } /* quoted From: */ /* flush any eaten empty line */ if (empty_lines > 0) { while (empty_lines-- > 0) { FPUTS_TO_TMP_ABORT_IF_FAIL("\n"); } empty_lines = 0; } /* store the unquoted line */ FPUTS_TO_TMP_ABORT_IF_FAIL(buf + 1); continue; } /* other line */ /* flush any eaten empty line */ if (empty_lines > 0) { while (empty_lines-- > 0) { FPUTS_TO_TMP_ABORT_IF_FAIL("\n"); } empty_lines = 0; } /* store the line itself */ FPUTS_TO_TMP_ABORT_IF_FAIL(buf); } /* end of mbox item or end of mbox */ /* flush any eaten empty line (but the last one) */ if (empty_lines > 0) { while (--empty_lines > 0) { FPUTS_TO_TMP_ABORT_IF_FAIL("\n"); } } /* more emails to expect? */ more = !feof(mbox_fp); /* warn if email part is empty (it's the minimum check we can do */ if (lines == 0) { g_warning("malformed mbox: %s: message %d is empty\n", mbox, msgs); fclose(tmp_fp); fclose(mbox_fp); claws_unlink(tmp_file); return -1; } if (fclose(tmp_fp) == EOF) { FILE_OP_ERROR(tmp_file, "fclose"); g_warning("can't write to temporary file\n"); fclose(mbox_fp); claws_unlink(tmp_file); g_free(tmp_file); return -1; } if (apply_filter) { if ((msgnum = folder_item_add_msg(dropfolder, tmp_file, NULL, TRUE)) < 0) { fclose(mbox_fp); claws_unlink(tmp_file); g_free(tmp_file); return -1; } msginfo = folder_item_get_msginfo(dropfolder, msgnum); to_filter = g_slist_prepend(to_filter, msginfo); } else { MsgFileInfo *finfo = g_new0(MsgFileInfo, 1); finfo->file = tmp_file; to_add = g_slist_prepend(to_add, finfo); tmp_file = get_tmp_file(); /* flush every 500 */ if (msgs > 0 && msgs % 500 == 0) { folder_item_add_msgs(dropfolder, to_add, TRUE); procmsg_message_file_list_free(to_add); to_add = NULL; } } msgs++; } while (more); if (printed) statusbar_pop_all(); if (apply_filter) { folder_item_set_batch(dropfolder, FALSE); procmsg_msglist_filter(to_filter, account, &filtered, &unfiltered, TRUE); folder_item_set_batch(dropfolder, TRUE); filtering_move_and_copy_msgs(to_filter); for (cur = filtered; cur; cur = g_slist_next(cur)) { MsgInfo *info = (MsgInfo *)cur->data; procmsg_msginfo_free(info); } unfiltered = g_slist_reverse(unfiltered); if (unfiltered) { folder_item_move_msgs(dest, unfiltered); for (cur = unfiltered; cur; cur = g_slist_next(cur)) { MsgInfo *info = (MsgInfo *)cur->data; procmsg_msginfo_free(info); } } g_slist_free(unfiltered); g_slist_free(filtered); g_slist_free(to_filter); } else if (to_add) { folder_item_add_msgs(dropfolder, to_add, TRUE); procmsg_message_file_list_free(to_add); to_add = NULL; } folder_item_update_thaw(); g_free(tmp_file); fclose(mbox_fp); debug_print("%d messages found.\n", msgs); return msgs; }
gint lock_mbox(const gchar *base, LockType type) { #ifdef G_OS_UNIX gint retval = 0; if (type == LOCK_FILE) { gchar *lockfile, *locklink; gint retry = 0; FILE *lockfp; lockfile = g_strdup_printf("%s.%d", base, getpid()); if ((lockfp = g_fopen(lockfile, "wb")) == NULL) { FILE_OP_ERROR(lockfile, "fopen"); g_warning("can't create lock file %s\n", lockfile); g_warning("use 'flock' instead of 'file' if possible.\n"); g_free(lockfile); return -1; } if (fprintf(lockfp, "%d\n", getpid()) < 0) { FILE_OP_ERROR(lockfile, "fprintf"); g_free(lockfile); fclose(lockfp); return -1; } if (fclose(lockfp) == EOF) { FILE_OP_ERROR(lockfile, "fclose"); g_free(lockfile); return -1; } locklink = g_strconcat(base, ".lock", NULL); while (link(lockfile, locklink) < 0) { FILE_OP_ERROR(lockfile, "link"); if (retry >= 5) { g_warning("can't create %s\n", lockfile); claws_unlink(lockfile); g_free(lockfile); return -1; } if (retry == 0) g_warning("mailbox is owned by another" " process, waiting...\n"); retry++; sleep(5); } claws_unlink(lockfile); g_free(lockfile); } else if (type == LOCK_FLOCK) { gint lockfd; gboolean fcntled = FALSE; #if HAVE_FCNTL_H && !defined(G_OS_WIN32) struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; #endif #if HAVE_FLOCK if ((lockfd = g_open(base, O_RDWR, 0)) < 0) { #else if ((lockfd = g_open(base, O_RDWR, 0)) < 0) { #endif FILE_OP_ERROR(base, "open"); return -1; } #if HAVE_FCNTL_H && !defined(G_OS_WIN32) if (fcntl(lockfd, F_SETLK, &fl) == -1) { g_warning("can't fnctl %s (%s)", base, strerror(errno)); return -1; } else { fcntled = TRUE; } #endif #if HAVE_FLOCK if (flock(lockfd, LOCK_EX|LOCK_NB) < 0 && !fcntled) { perror("flock"); #else #if HAVE_LOCKF if (lockf(lockfd, F_TLOCK, 0) < 0 && !fcntled) { perror("lockf"); #else { #endif #endif /* HAVE_FLOCK */ g_warning("can't lock %s\n", base); if (close(lockfd) < 0) perror("close"); return -1; } retval = lockfd; } else { g_warning("invalid lock type\n"); return -1; } return retval; #else return -1; #endif /* G_OS_UNIX */ } gint unlock_mbox(const gchar *base, gint fd, LockType type) { if (type == LOCK_FILE) { gchar *lockfile; lockfile = g_strconcat(base, ".lock", NULL); if (claws_unlink(lockfile) < 0) { FILE_OP_ERROR(lockfile, "unlink"); g_free(lockfile); return -1; } g_free(lockfile); return 0; } else if (type == LOCK_FLOCK) { gboolean fcntled = FALSE; #if HAVE_FCNTL_H && !defined(G_OS_WIN32) struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; if (fcntl(fd, F_SETLK, &fl) == -1) { g_warning("can't fnctl %s", base); } else { fcntled = TRUE; } #endif #if HAVE_FLOCK if (flock(fd, LOCK_UN) < 0 && !fcntled) { perror("flock"); #else #if HAVE_LOCKF if (lockf(fd, F_ULOCK, 0) < 0 && !fcntled) { perror("lockf"); #else { #endif #endif /* HAVE_FLOCK */ g_warning("can't unlock %s\n", base); if (close(fd) < 0) perror("close"); return -1; } if (close(fd) < 0) { perror("close"); return -1; } return 0; } g_warning("invalid lock type\n"); return -1; } gint copy_mbox(gint srcfd, const gchar *dest) { FILE *dest_fp; ssize_t n_read; gchar buf[BUFSIZ]; gboolean err = FALSE; int save_errno = 0; if (srcfd < 0) { return -1; } if ((dest_fp = g_fopen(dest, "wb")) == NULL) { FILE_OP_ERROR(dest, "fopen"); return -1; } if (change_file_mode_rw(dest_fp, dest) < 0) { FILE_OP_ERROR(dest, "chmod"); g_warning("can't change file mode\n"); } while ((n_read = read(srcfd, buf, sizeof(buf))) > 0) { if (n_read == -1 && errno != 0) { save_errno = errno; break; } if (fwrite(buf, 1, n_read, dest_fp) < n_read) { g_warning("writing to %s failed.\n", dest); fclose(dest_fp); claws_unlink(dest); return -1; } } if (save_errno != 0) { g_warning("error %d reading mbox: %s\n", save_errno, strerror(save_errno)); err = TRUE; } if (fclose(dest_fp) == EOF) { FILE_OP_ERROR(dest, "fclose"); err = TRUE; } if (err) { claws_unlink(dest); return -1; } return 0; } void empty_mbox(const gchar *mbox) { FILE *fp; if ((fp = g_fopen(mbox, "wb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); g_warning("can't truncate mailbox to zero.\n"); return; } fclose(fp); } gint export_list_to_mbox(GSList *mlist, const gchar *mbox) /* return values: -2 skipped, -1 error, 0 OK */ { GSList *cur; MsgInfo *msginfo; FILE *msg_fp; FILE *mbox_fp; gchar buf[BUFFSIZE]; int err = 0; gint msgs = 1, total = g_slist_length(mlist); if (g_file_test(mbox, G_FILE_TEST_EXISTS) == TRUE) { if (alertpanel_full(_("Overwrite mbox file"), _("This file already exists. Do you want to overwrite it?"), GTK_STOCK_CANCEL, _("Overwrite"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) { return -2; } } if ((mbox_fp = g_fopen(mbox, "wb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); alertpanel_error(_("Could not create mbox file:\n%s\n"), mbox); return -1; } #ifdef HAVE_FGETS_UNLOCKED flockfile(mbox_fp); #endif statuswindow_print_all(_("Exporting to mbox...")); for (cur = mlist; cur != NULL; cur = cur->next) { int len; gchar buft[BUFFSIZE]; msginfo = (MsgInfo *)cur->data; msg_fp = procmsg_open_message(msginfo); if (!msg_fp) { continue; } #ifdef HAVE_FGETS_UNLOCKED flockfile(msg_fp); #endif strncpy2(buf, msginfo->from ? msginfo->from : cur_account && cur_account->address ? cur_account->address : "unknown", sizeof(buf)); extract_address(buf); if (fprintf(mbox_fp, "From %s %s", buf, ctime_r(&msginfo->date_t, buft)) < 0) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } buf[0] = '\0'; /* write email to mboxrc */ while (SC_FGETS(buf, sizeof(buf), msg_fp) != NULL) { /* quote any From, >From, >>From, etc., according to mbox format specs */ int offset; offset = 0; /* detect leading '>' char(s) */ while ((buf[offset] == '>')) { offset++; } if (!strncmp(buf+offset, "From ", 5)) { if (SC_FPUTC('>', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } if (SC_FPUTS(buf, mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } /* force last line to end w/ a newline */ len = strlen(buf); if (len > 0) { len--; if ((buf[len] != '\n') && (buf[len] != '\r')) { if (SC_FPUTC('\n', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } } /* add a trailing empty line */ if (SC_FPUTC('\n', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); statusbar_progress_all(msgs++,total, 500); if (msgs%500 == 0) GTK_EVENTS_FLUSH(); } out: statusbar_progress_all(0,0,0); statuswindow_pop_all(); #ifdef HAVE_FGETS_UNLOCKED funlockfile(mbox_fp); #endif fclose(mbox_fp); return err; }
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); }