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 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; }
static gint mh_remove_msg(Folder *folder, FolderItem *item, gint num) { gboolean need_scan = FALSE; time_t last_mtime = (time_t)0; gchar *file; cm_return_val_if_fail(item != NULL, -1); file = mh_fetch_msg(folder, item, num); cm_return_val_if_fail(file != NULL, -1); need_scan = mh_scan_required(folder, item); last_mtime = item->mtime; if (claws_unlink(file) < 0) { FILE_OP_ERROR(file, "unlink"); g_free(file); return -1; } if (item->mtime == last_mtime && !need_scan) { mh_set_mtime(folder, item); } g_free(file); return 0; }
gpgme_data_t sgpgme_data_from_mimeinfo(MimeInfo *mimeinfo) { gpgme_data_t data = NULL; gpgme_error_t err; FILE *fp = g_fopen(mimeinfo->data.filename, "rb"); gchar *tmp_file = NULL; if (!fp) return NULL; tmp_file = get_tmp_file(); copy_file_part(fp, mimeinfo->offset, mimeinfo->length, tmp_file); fclose(fp); fp = NULL; debug_print("tmp file %s\n", tmp_file); err = gpgme_data_new_from_file(&data, tmp_file, 1); claws_unlink(tmp_file); g_free(tmp_file); debug_print("data %p (%d %d)\n", (void *)&data, mimeinfo->offset, mimeinfo->length); if (err) { debug_print ("gpgme_data_new_from_file failed: %s\n", gpgme_strerror (err)); privacy_set_error(_("Couldn't get data from message, %s"), gpgme_strerror(err)); return NULL; } return data; }
void set_log_file(LogInstance instance, const gchar *filename) { gchar *fullname = NULL; if (log_fp[instance]) return; if (!g_path_is_absolute(filename)) { fullname = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, filename, NULL); } else { fullname = g_strdup(filename); } /* backup old logfile if existing */ if (is_file_exist(fullname)) { gchar *backupname; backupname = g_strconcat(fullname, ".bak", NULL); claws_unlink(backupname); if (g_rename(fullname, backupname) < 0) FILE_OP_ERROR(fullname, "rename"); g_free(backupname); } log_fp[instance] = g_fopen(fullname, "wb"); if (!log_fp[instance]) { FILE_OP_ERROR(fullname, "fopen"); log_filename[instance] = NULL; g_free(fullname); return; } log_filename[instance] = g_strdup(fullname); log_size[instance] = 0; g_free(fullname); }
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; }
static gint mh_remove_msgs(Folder *folder, FolderItem *item, MsgInfoList *msglist, GHashTable *relation) { gboolean need_scan = FALSE; gchar *path, *file; time_t last_mtime = (time_t)0; MsgInfoList *cur; gint total = 0, curnum = 0; cm_return_val_if_fail(item != NULL, -1); path = folder_item_get_path(item); need_scan = mh_scan_required(folder, item); last_mtime = item->mtime; total = g_slist_length(msglist); if (total > 100) { statusbar_print_all(_("Deleting messages...")); } for (cur = msglist; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; if (msginfo == NULL) continue; if (MSG_IS_MOVE(msginfo->flags) && MSG_IS_MOVE_DONE(msginfo->flags)) { msginfo->flags.tmp_flags &= ~MSG_MOVE_DONE; continue; } if (total > 100) { statusbar_progress_all(curnum, total, 100); if (curnum % 100 == 0) GTK_EVENTS_FLUSH(); curnum++; } file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL); if (file == NULL) continue; if (claws_unlink(file) < 0) { g_free(file); continue; } g_free(file); } if (total > 100) { statusbar_progress_all(0,0,0); statusbar_pop_all(); } if (item->mtime == last_mtime && !need_scan) { mh_set_mtime(folder, item); } g_free(path); return 0; }
static void cache_delete_item(gpointer filename, gpointer errors) { const gchar *fname = (const gchar *) filename; AvatarCleanupResult *acr = (AvatarCleanupResult *) errors; if (!is_dir_exist(fname)) { if (claws_unlink(fname) < 0) { g_warning("couldn't delete file %s\n", fname); (acr->e_unlink)++; } else { (acr->removed)++; } } }
void news_remove_group_list_cache(Folder *folder) { gchar *path, *filename; cm_return_if_fail(folder != NULL); cm_return_if_fail(FOLDER_CLASS(folder) == &news_class); path = folder_item_get_path(FOLDER_ITEM(folder->node->data)); filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL); g_free(path); if (is_file_exist(filename)) { if (claws_unlink(filename) < 0) FILE_OP_ERROR(filename, "remove"); } g_free(filename); }
static void news_remove_cached_msg(Folder *folder, FolderItem *item, MsgInfo *msginfo) { gchar *path, *filename; path = folder_item_get_path(item); if (!is_dir_exist(path)) { g_free(path); return; } filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL); g_free(path); if (is_file_exist(filename)) { claws_unlink(filename); } g_free(filename); }
static int news_remove_msg (Folder *folder, FolderItem *item, gint msgnum) { gchar *path, *filename; cm_return_val_if_fail(folder != NULL, -1); cm_return_val_if_fail(item != NULL, -1); path = folder_item_get_path(item); if (!is_dir_exist(path)) make_dir_hier(path); filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msgnum), NULL); g_free(path); claws_unlink(filename); g_free(filename); return 0; }
static void prefs_themes_file_remove(const gchar *filename, gpointer data) { gchar **status = (gchar **)data; gchar *base; if ((*status) != NULL) return; base = g_path_get_basename(filename); if (TRUE == is_dir_exist(filename)) { if (strcmp(base, ".") != 0 && strcmp(base, "..") != 0) g_warning("prefs_themes_file_remove(): subdir in theme dir skipped: '%s'.", base); } else if (0 != claws_unlink(filename)) { (*status) = g_strdup(filename); } g_free(base); }
/*! *\brief Close and free preferences file, delete temp file * *\param pfile Preferences file struct */ gint prefs_file_close_revert(PrefFile *pfile) { gchar *tmppath = NULL; cm_return_val_if_fail(pfile != NULL, -1); if (pfile->orig_fp) fclose(pfile->orig_fp); if (pfile->writing) tmppath = g_strconcat(pfile->path, ".tmp", NULL); fclose(pfile->fp); if (pfile->writing) { if (claws_unlink(tmppath) < 0) FILE_OP_ERROR(tmppath, "unlink"); g_free(tmppath); } g_free(pfile->path); g_free(pfile); return 0; }
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 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); GStatBuf 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")); claws_fclose(fp); if (g_stat(tmpfilename, &statbuf) < 0) { claws_unlink(tmpfilename); procmime_mimeinfo_free_all(&sub_info); return NULL; } sub_info->tmp = TRUE; sub_info->length = statbuf.st_size; sub_info->encoding_type = ENC_BINARY; return sub_info; }
/*! *\brief put all the things here we can do before * letting the program die */ static void crash_cleanup_exit(void) { const char *filename = claws_get_socket_name(); claws_unlink(filename); }
gint pop3_write_uidl_list(Pop3Session *session) { gchar *path, *tmp_path; FILE *fp; Pop3MsgInfo *msg; gint n; gchar *sanitized_uid = g_strdup(session->ac_prefs->userid); subst_for_filename(sanitized_uid); if (!session->uidl_is_valid) { g_free(sanitized_uid); return 0; } path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "uidl", G_DIR_SEPARATOR_S, session->ac_prefs->recv_server, "-", sanitized_uid, NULL); tmp_path = g_strconcat(path, ".tmp", NULL); g_free(sanitized_uid); if ((fp = g_fopen(tmp_path, "wb")) == NULL) { FILE_OP_ERROR(tmp_path, "fopen"); goto err_write; } for (n = 1; n <= session->count; n++) { msg = &session->msg[n]; if (msg->uidl && msg->received && (!msg->deleted || session->state != POP3_DONE)) TRY(fprintf(fp, "%s\t%ld\t%d\n", msg->uidl, (long int) msg->recv_time, msg->partial_recv) > 0); } if (fclose(fp) == EOF) { FILE_OP_ERROR(tmp_path, "fclose"); fp = NULL; goto err_write; } fp = NULL; #ifdef G_OS_WIN32 claws_unlink(path); #endif if (g_rename(tmp_path, path) < 0) { FILE_OP_ERROR(path, "rename"); goto err_write; } g_free(path); g_free(tmp_path); return 0; err_write: if (fp) fclose(fp); g_free(path); g_free(tmp_path); return -1; }
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; }
static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data) { MimeInfo *msgcontent; FILE *fp; gchar *enccontent; size_t len; gchar *textstr, *tmp; gpgme_data_t gpgtext, gpgenc; gpgme_ctx_t ctx; gpgme_key_t *kset = NULL; gchar **fprs = g_strsplit(encrypt_data, " ", -1); gpgme_error_t err; gint i = 0; while (fprs[i] && strlen(fprs[i])) { i++; } kset = g_malloc(sizeof(gpgme_key_t)*(i+1)); memset(kset, 0, sizeof(gpgme_key_t)*(i+1)); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); g_free(kset); return FALSE; } i = 0; while (fprs[i] && strlen(fprs[i])) { gpgme_key_t key; err = gpgme_get_key(ctx, fprs[i], &key, 0); if (err) { debug_print("can't add key '%s'[%d] (%s)\n", fprs[i],i, gpgme_strerror(err)); privacy_set_error(_("Couldn't add GPG key %s, %s"), fprs[i], gpgme_strerror(err)); g_free(kset); return FALSE; } debug_print("found %s at %d\n", fprs[i], i); kset[i] = key; i++; } debug_print("Encrypting message content\n"); /* get content node from message */ msgcontent = (MimeInfo *) mimeinfo->node->children->data; if (msgcontent->type == MIMETYPE_MULTIPART) { if (!msgcontent->node->children) { debug_print("msgcontent->node->children NULL, bailing\n"); privacy_set_error(_("Malformed message")); g_free(kset); return FALSE; } msgcontent = (MimeInfo *) msgcontent->node->children->data; } /* get rid of quoted-printable or anything */ procmime_decode_content(msgcontent); fp = my_tmpfile(); if (fp == NULL) { privacy_set_error(_("Couldn't create temporary file, %s"), g_strerror(errno)); perror("my_tmpfile"); g_free(kset); return FALSE; } procmime_write_mimeinfo(msgcontent, fp); rewind(fp); /* read temporary file into memory */ textstr = fp_read_noconv(fp); fclose(fp); /* encrypt data */ gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgenc); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); g_free(kset); return FALSE; } gpgme_set_armor(ctx, 1); err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc); enccontent = sgpgme_data_release_and_get_mem(gpgenc, &len); g_free(kset); if (enccontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Encryption failed, %s"), gpgme_strerror(err)); gpgme_data_release(gpgtext); g_free(textstr); gpgme_release(ctx); g_free(enccontent); return FALSE; } tmp = g_malloc(len+1); g_memmove(tmp, enccontent, len+1); tmp[len] = '\0'; g_free(enccontent); gpgme_data_release(gpgtext); g_free(textstr); if (msgcontent->content == MIMECONTENT_FILE && msgcontent->data.filename != NULL) { if (msgcontent->tmp == TRUE) claws_unlink(msgcontent->data.filename); g_free(msgcontent->data.filename); } msgcontent->data.mem = g_strdup(tmp); msgcontent->content = MIMECONTENT_MEM; g_free(tmp); gpgme_release(ctx); return TRUE; }
static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account, const gchar *from_addr) { MimeInfo *msgcontent; gchar *textstr, *tmp; FILE *fp; gchar *sigcontent; gpgme_ctx_t ctx; gpgme_data_t gpgtext, gpgsig; size_t len; gpgme_error_t err; struct passphrase_cb_info_s info; gpgme_sign_result_t result = NULL; memset (&info, 0, sizeof info); /* get content node from message */ msgcontent = (MimeInfo *) mimeinfo->node->children->data; if (msgcontent->type == MIMETYPE_MULTIPART) { if (!msgcontent->node->children) { debug_print("msgcontent->node->children NULL, bailing\n"); privacy_set_error(_("Malformed message")); return FALSE; } msgcontent = (MimeInfo *) msgcontent->node->children->data; } /* get rid of quoted-printable or anything */ procmime_decode_content(msgcontent); fp = my_tmpfile(); if (fp == NULL) { perror("my_tmpfile"); privacy_set_error(_("Couldn't create temporary file.")); return FALSE; } procmime_write_mimeinfo(msgcontent, fp); rewind(fp); /* read temporary file into memory */ textstr = fp_read_noconv(fp); fclose(fp); gpgme_data_new_from_mem(&gpgtext, textstr, (size_t)strlen(textstr), 0); gpgme_data_new(&gpgsig); if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) { debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err)); return FALSE; } gpgme_set_textmode(ctx, 1); gpgme_set_armor(ctx, 1); if (!sgpgme_setup_signers(ctx, account, from_addr)) { gpgme_release(ctx); return FALSE; } prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent); if (!getenv("GPG_AGENT_INFO") || !prefs_gpg_get_config()->use_gpg_agent) { info.c = ctx; gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info); } err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_CLEAR); if (err != GPG_ERR_NO_ERROR) { if (err == GPG_ERR_CANCELED) { /* ignore cancelled signing */ privacy_reset_error(); debug_print("gpgme_op_sign cancelled\n"); } else { privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err)); debug_print("gpgme_op_sign error : %x\n", err); } gpgme_release(ctx); return FALSE; } result = gpgme_op_sign_result(ctx); if (result && result->signatures) { gpgme_new_signature_t sig = result->signatures; while (sig) { debug_print("valid signature: %s\n", sig->fpr); sig = sig->next; } } else if (result && result->invalid_signers) { gpgme_invalid_key_t invalid = result->invalid_signers; while (invalid) { g_warning("invalid signer: %s (%s)", invalid->fpr, gpgme_strerror(invalid->reason)); privacy_set_error(_("Data signing failed due to invalid signer: %s"), gpgme_strerror(invalid->reason)); invalid = invalid->next; } gpgme_release(ctx); return FALSE; } else { /* can't get result (maybe no signing key?) */ debug_print("gpgme_op_sign_result error\n"); privacy_set_error(_("Data signing failed, no results.")); gpgme_release(ctx); return FALSE; } sigcontent = sgpgme_data_release_and_get_mem(gpgsig, &len); if (sigcontent == NULL || len <= 0) { g_warning("sgpgme_data_release_and_get_mem failed"); privacy_set_error(_("Data signing failed, no contents.")); gpgme_data_release(gpgtext); g_free(textstr); g_free(sigcontent); gpgme_release(ctx); return FALSE; } tmp = g_malloc(len+1); g_memmove(tmp, sigcontent, len+1); tmp[len] = '\0'; gpgme_data_release(gpgtext); g_free(textstr); g_free(sigcontent); if (msgcontent->content == MIMECONTENT_FILE && msgcontent->data.filename != NULL) { if (msgcontent->tmp == TRUE) claws_unlink(msgcontent->data.filename); g_free(msgcontent->data.filename); } msgcontent->data.mem = g_strdup(tmp); msgcontent->content = MIMECONTENT_MEM; g_free(tmp); /* avoid all sorts of clear-signing problems with non ascii * chars */ procmime_encode_content(msgcontent, ENC_BASE64); gpgme_release(ctx); return TRUE; }
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 prefs_file_close(PrefFile *pfile) { FILE *fp, *orig_fp; gchar *path; gchar *tmppath; gchar *bakpath = NULL; gchar buf[BUFFSIZE]; cm_return_val_if_fail(pfile != NULL, -1); fp = pfile->fp; orig_fp = pfile->orig_fp; path = pfile->path; if (!pfile->writing) { fclose(fp); g_free(pfile); g_free(path); return 0; } if (orig_fp) { while (fgets(buf, sizeof(buf), orig_fp) != NULL) { /* next block */ if (buf[0] == '[') { if (fputs(buf, fp) == EOF) { g_warning("failed to write configuration to file\n"); prefs_file_close_revert(pfile); return -1; } break; } } while (fgets(buf, sizeof(buf), orig_fp) != NULL) if (fputs(buf, fp) == EOF) { g_warning("failed to write configuration to file\n"); prefs_file_close_revert(pfile); return -1; } fclose(orig_fp); } tmppath = g_strconcat(path, ".tmp", NULL); if (prefs_common_get_flush_metadata() && fsync(fileno(fp)) < 0) { FILE_OP_ERROR(tmppath, "fsync"); fclose(fp); claws_unlink(tmppath); g_free(path); g_free(tmppath); return -1; } if (fclose(fp) == EOF) { FILE_OP_ERROR(tmppath, "fclose"); claws_unlink(tmppath); g_free(path); g_free(tmppath); return -1; } if (is_file_exist(path)) { bakpath = g_strconcat(path, ".bak", NULL); #ifdef G_OS_WIN32 claws_unlink(bakpath); #endif if (g_rename(path, bakpath) < 0) { FILE_OP_ERROR(path, "rename"); claws_unlink(tmppath); g_free(path); g_free(tmppath); g_free(bakpath); return -1; } } #ifdef G_OS_WIN32 claws_unlink(path); #endif if (g_rename(tmppath, path) < 0) { FILE_OP_ERROR(tmppath, "rename"); claws_unlink(tmppath); g_free(path); g_free(tmppath); g_free(bakpath); return -1; } g_free(pfile); g_free(path); g_free(tmppath); g_free(bakpath); return 0; }