talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 7c0529df50f0f6a59fd45d1a62fe9f45f52215b8
parent 4de8e2182c447e4635fb977a2b95976b8f82e5d4
Author: Oliver Lowe <o@olowe.co>
Date:   Sun, 30 Nov 2025 11:40:54 +1100

Calm down on the chmod

All these files are under the user's own data directory which has mode
0700, so others won't normally able to read any files under these
directories anyway.

Diffstat:
Msrc/addressbook.c | 3++-
Msrc/common/file-utils.c | 110++++++-------------------------------------------------------------------------
Msrc/common/file-utils.h | 10----------
Msrc/common/log.c | 5-----
Msrc/common/prefs.c | 90+++++++++++++++----------------------------------------------------------------
Msrc/common/prefs.h | 3+--
Msrc/common/ssl_certificate.c | 2+-
Msrc/common/utils.c | 50+++++++-------------------------------------------
Msrc/common/utils.h | 1-
Msrc/compose.c | 21+++------------------
Msrc/folder.c | 4++--
Msrc/inc.c | 1+
Msrc/main.c | 53+++++++++++++++++++----------------------------------
Msrc/mbox.c | 44+++++++-------------------------------------
Msrc/mh.c | 50+++++++++++++++++++++++---------------------------
Msrc/msgcache.c | 13++-----------
Msrc/pop.c | 3---
Msrc/prefs_common.c | 5-----
Msrc/procheader.c | 8++++----
Msrc/procmime.c | 5-----
20 files changed, 97 insertions(+), 384 deletions(-)

diff --git a/src/addressbook.c b/src/addressbook.c @@ -22,6 +22,7 @@ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include <string.h> +#include <sys/stat.h> #include <sys/types.h> #include "main.h" @@ -3964,7 +3965,7 @@ void addressbook_read_file( void ) { /* Use new address book index. */ if ( !is_dir_exist(indexdir) ) { - if ( make_dir(indexdir) < 0 ) { + if (mkdir(indexdir, 0700) < 0 ) { addrindex_set_file_path( addrIndex, get_rc_dir() ); g_warning("couldn't create dir '%s'", indexdir); } else { diff --git a/src/common/file-utils.c b/src/common/file-utils.c @@ -62,8 +62,7 @@ gint file_strip_crs(const gchar *file) if (fclose(outfp) == EOF) { goto unlinkout; } - - if (move_file(out, file, TRUE) < 0) + if (rename(out, file) < 0) goto unlinkout; g_free(out); @@ -98,11 +97,6 @@ gint append_file(const gchar *src, const gchar *dest, gboolean keep_backup) return -1; } - if (change_file_mode_rw(dest_fp, dest) < 0) { - FILE_OP_ERROR(dest, "chmod"); - g_warning("can't change file mode: %s", dest); - } - while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) { if (n_read < sizeof(buf) && ferror(src_fp)) break; @@ -147,8 +141,8 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup) } if (is_file_exist(dest)) { dest_bak = g_strconcat(dest, ".bak", NULL); - if (rename_force(dest, dest_bak) < 0) { - FILE_OP_ERROR(dest, "rename"); + if (rename(dest, dest_bak) < 0) { + warn("rename %s to %s", dest, dest_bak); fclose(src_fp); g_free(dest_bak); return -1; @@ -159,18 +153,13 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup) FILE_OP_ERROR(dest, "g_fopen"); fclose(src_fp); if (dest_bak) { - if (rename_force(dest_bak, dest) < 0) + if (rename(dest_bak, dest) < 0) FILE_OP_ERROR(dest_bak, "rename"); g_free(dest_bak); } return -1; } - if (change_file_mode_rw(dest_fp, dest) < 0) { - FILE_OP_ERROR(dest, "chmod"); - g_warning("can't change file mode: %s", dest); - } - while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) { if (n_read < sizeof(buf) && ferror(src_fp)) break; @@ -181,7 +170,7 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup) if (unlink(dest) < 0) FILE_OP_ERROR(dest, "unlink"); if (dest_bak) { - if (rename_force(dest_bak, dest) < 0) + if (rename(dest_bak, dest) < 0) FILE_OP_ERROR(dest_bak, "rename"); g_free(dest_bak); } @@ -203,7 +192,7 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup) if (unlink(dest) < 0) FILE_OP_ERROR(dest, "unlink"); if (dest_bak) { - if (rename_force(dest_bak, dest) < 0) + if (rename(dest_bak, dest) < 0) FILE_OP_ERROR(dest_bak, "rename"); g_free(dest_bak); } @@ -219,27 +208,6 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup) return 0; } -gint move_file(const gchar *src, const gchar *dest, gboolean overwrite) -{ - if (overwrite == FALSE && is_file_exist(dest)) { - g_warning("move_file(): file %s already exists", dest); - return -1; - } - - if (rename_force(src, dest) == 0) return 0; - - if (EXDEV != errno) { - FILE_OP_ERROR(src, "rename"); - return -1; - } - - if (copy_file(src, dest, FALSE) < 0) return -1; - - unlink(src); - - return 0; -} - gint copy_file_part_to_fp(FILE *fp, off_t offset, size_t length, FILE *dest_fp) { gint n_read; @@ -284,11 +252,6 @@ gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest) return -1; } - if (change_file_mode_rw(dest_fp, dest) < 0) { - FILE_OP_ERROR(dest, "chmod"); - g_warning("can't change file mode: %s", dest); - } - if (copy_file_part_to_fp(fp, offset, length, dest_fp) < 0) err = TRUE; @@ -328,11 +291,6 @@ gint canonicalize_file(const gchar *src, const gchar *dest) return -1; } - if (change_file_mode_rw(dest_fp, dest) < 0) { - FILE_OP_ERROR(dest, "chmod"); - g_warning("can't change file mode: %s", dest); - } - while (fgets(buf, sizeof(buf), src_fp) != NULL) { gint r = 0; @@ -387,29 +345,6 @@ gint canonicalize_file(const gchar *src, const gchar *dest) return 0; } -gint canonicalize_file_replace(const gchar *file) -{ - gchar *tmp_file; - - tmp_file = get_tmp_file(); - - if (canonicalize_file(file, tmp_file) < 0) { - g_free(tmp_file); - return -1; - } - - if (move_file(tmp_file, file, TRUE) < 0) { - g_warning("can't replace file: %s", file); - unlink(tmp_file); - g_free(tmp_file); - return -1; - } - - g_free(tmp_file); - return 0; -} - - gint str_write_to_file(const gchar *str, char *file) { if (strlen(str) == 0) @@ -559,41 +494,17 @@ gchar *file_read_stream_to_str(FILE *fp) return file_read_stream_to_str_full(fp, TRUE); } -gchar *file_read_to_str_no_recode(const gchar *file) -{ - return file_read_to_str_full(file, FALSE); -} -gchar *file_read_stream_to_str_no_recode(FILE *fp) -{ - return file_read_stream_to_str_full(fp, FALSE); -} - -gint rename_force(const gchar *oldpath, const gchar *newpath) -{ -#ifndef G_OS_UNIX - if (!is_file_entry_exist(oldpath)) { - errno = ENOENT; - return -1; - } - if (is_file_exist(newpath)) { - if (unlink(newpath) < 0) - FILE_OP_ERROR(newpath, "unlink"); - } -#endif - return g_rename(oldpath, newpath); -} - gint copy_dir(const gchar *src, const gchar *dst) { GDir *dir; const gchar *name; if ((dir = g_dir_open(src, 0, NULL)) == NULL) { - g_warning("failed to open directory: %s", src); + warn("open %s", src); return -1; } - if (make_dir(dst) < 0) { + if (mkdir(dst, 0700) < 0) { g_dir_close(dir); return -1; } @@ -633,11 +544,6 @@ gint copy_dir(const gchar *src, const gchar *dst) return 0; } -gint change_file_mode_rw(FILE *fp, const gchar *file) -{ - return fchmod(fileno(fp), S_IRUSR|S_IWUSR); -} - FILE *my_tmpfile(void) { const gchar suffix[] = ".XXXXXX"; diff --git a/src/common/file-utils.h b/src/common/file-utils.h @@ -29,9 +29,6 @@ gint append_file (const gchar *src, gint copy_file (const gchar *src, const gchar *dest, gboolean keep_backup); -gint move_file (const gchar *src, - const gchar *dest, - gboolean overwrite); gint copy_file_part_to_fp (FILE *fp, off_t offset, size_t length, @@ -42,18 +39,11 @@ gint copy_file_part (FILE *fp, const gchar *dest); gint canonicalize_file (const gchar *src, const gchar *dest); -gint canonicalize_file_replace (const gchar *file); gchar *file_read_to_str (const gchar *file); -gchar *file_read_to_str_no_recode(const gchar *file); gchar *file_read_stream_to_str (FILE *fp); -gchar *file_read_stream_to_str_no_recode(FILE *fp); -gint rename_force (const gchar *oldpath, - const gchar *newpath); gint copy_dir (const gchar *src, const gchar *dest); -gint change_file_mode_rw (FILE *fp, - const gchar *file); FILE *my_tmpfile (void); FILE *get_tmpfile_in_dir (const gchar *dir, gchar **filename); diff --git a/src/common/log.c b/src/common/log.c @@ -115,11 +115,6 @@ void set_log_file(LogInstance instance, const gchar *filename) return; } - if (change_file_mode_rw(log_fp[instance], fullname) < 0) { - FILE_OP_ERROR(fullname, "chmod"); - g_warning("can't change file mode: %s", fullname); - } - log_filename[instance] = g_strdup(fullname); log_size[instance] = 0; g_free(fullname); diff --git a/src/common/prefs.c b/src/common/prefs.c @@ -18,6 +18,7 @@ */ #include <stdio.h> +#include <string.h> #include "defs.h" @@ -25,78 +26,32 @@ #include "prefs.h" #include "utils.h" -#include "file-utils.h" static gboolean prefs_is_readonly (const gchar *path); -/*! - *\brief Open preferences file for reading - * - *\param path Filename with path of preferences file to read - * - *\return PrefFile * preferences file struct - */ -PrefFile *prefs_read_open(const gchar *path) -{ - PrefFile *pfile; - FILE *fp; - - cm_return_val_if_fail(path != NULL, NULL); - - if ((fp = g_fopen(path, "rb")) == NULL) { - FILE_OP_ERROR(path, "g_fopen"); - return NULL; - } - - pfile = g_new(PrefFile, 1); - pfile->fp = fp; - pfile->orig_fp = NULL; - pfile->path = g_strdup(path); - pfile->writing = FALSE; - - return pfile; -} - -/*! - *\brief Open preferences file for writing - * Prefs are written to a temp file: Call prefs_file_close() - * to rename this to the final filename - * - *\param path Filename with path of preferences file to write - * - *\return PrefFile * preferences file struct +/* + * Open preferences file for writing + * Prefs are written to a temp file: Call prefs_file_close() + * to rename this to the final filename */ 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 write permission on '%s'", path); - return NULL; - } - - tmppath = g_strconcat(path, ".tmp", NULL); - if ((fp = g_fopen(tmppath, "wb")) == NULL) { - FILE_OP_ERROR(tmppath, "g_fopen"); - g_free(tmppath); + char tmp[PATH_MAX]; + strlcpy(tmp, path, sizeof(tmp)); + strlcat(tmp, ".tmp", sizeof(tmp)); + if ((fp = fopen(tmp, "w")) == NULL) { + char msg[PATH_MAX]; + snprintf(msg, sizeof(msg), "open %s", tmp); + perror(msg); return NULL; } - if (change_file_mode_rw(fp, tmppath) < 0) - FILE_OP_ERROR(tmppath, "chmod"); - - g_free(tmppath); - - pfile = g_new(PrefFile, 1); + PrefFile *pfile = g_new(PrefFile, 1); pfile->fp = fp; pfile->orig_fp = NULL; - pfile->path = g_strdup(path); + pfile->path = strdup(path); pfile->writing = TRUE; - return pfile; } @@ -228,22 +183,11 @@ static gboolean prefs_is_readonly(const gchar * path) return (access(path, W_OK) != 0 && access(path, F_OK) == 0); } -/*! - *\brief Check if "rcfile" is in rcdir, a file and read-only - */ gboolean prefs_rc_is_readonly(const gchar * rcfile) { - gboolean result; - gchar * rcpath; - - if (rcfile == NULL) - return TRUE; - - rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL); - result = prefs_is_readonly(rcpath); - g_free(rcpath); - - return result; + char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/%s", get_rc_dir(), rcfile); + return prefs_is_readonly(path); } /*! diff --git a/src/common/prefs.h b/src/common/prefs.h @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * */ #ifndef PREFS_H @@ -33,7 +33,6 @@ struct _PrefFile { gboolean writing; }; -PrefFile *prefs_read_open (const gchar *path); PrefFile *prefs_write_open (const gchar *path); gint prefs_file_close (PrefFile *pfile); gint prefs_file_close_revert (PrefFile *pfile); diff --git a/src/common/ssl_certificate.c b/src/common/ssl_certificate.c @@ -450,7 +450,7 @@ SSLCertificate *ssl_certificate_find (const gchar *host, gushort port, const gch gchar *old = get_certificate_path(host, buf, NULL); gchar *new = get_certificate_path(host, buf, fingerprint); if (strcmp(old, new)) - move_file(old, new, TRUE); + rename(old, new); g_free(old); g_free(new); } diff --git a/src/common/utils.c b/src/common/utils.c @@ -1654,18 +1654,6 @@ gint change_dir(const gchar *dir) return 0; } -gint make_dir(const gchar *dir) -{ - if (g_mkdir(dir, S_IRWXU) < 0) { - FILE_OP_ERROR(dir, "mkdir"); - return -1; - } - if (g_chmod(dir, S_IRWXU) < 0) - FILE_OP_ERROR(dir, "chmod"); - - return 0; -} - gint make_dir_hier(const gchar *dir) { gchar *parent_dir; @@ -1675,7 +1663,7 @@ gint make_dir_hier(const gchar *dir) parent_dir = g_strndup(dir, p - dir); if (*parent_dir != '\0') { if (!is_dir_exist(parent_dir)) { - if (make_dir(parent_dir) < 0) { + if (mkdir(parent_dir, 0700) < 0) { g_free(parent_dir); return -1; } @@ -1684,11 +1672,8 @@ gint make_dir_hier(const gchar *dir) g_free(parent_dir); } - if (!is_dir_exist(dir)) { - if (make_dir(dir) < 0) - return -1; - } - + if (mkdir(dir, 0700) < 0 && errno != EEXIST) + return -1; return 0; } @@ -2480,39 +2465,18 @@ gboolean debug_get_mode(void) return debug_mode; } -#ifdef HAVE_VA_OPT -void debug_print_real(const char *file, int line, const gchar *format, ...) -{ - va_list args; - gchar buf[BUFFSIZE]; - gint prefix_len; - - if (!debug_mode) return; - - prefix_len = g_snprintf(buf, sizeof(buf), "%s:%d:", debug_srcname(file), line); - - va_start(args, format); - g_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, format, args); - va_end(args); +void debug_print_real(const gchar *format, ...) { + if (!debug_mode) + return; - g_print("%s", buf); -} -#else -void debug_print_real(const gchar *format, ...) -{ va_list args; gchar buf[BUFFSIZE]; - if (!debug_mode) return; - va_start(args, format); g_vsnprintf(buf, sizeof(buf), format, args); va_end(args); - - g_print("%s", buf); + fprintf(stderr, "%s\n", buf); } -#endif - const char * debug_srcname(const char *file) { diff --git a/src/common/utils.h b/src/common/utils.h @@ -362,7 +362,6 @@ gboolean is_file_entry_regular(const gchar *file); #define is_file_or_fifo_exist(file) file_exist(file, TRUE) gint change_dir (const gchar *dir); -gint make_dir (const gchar *dir); gint make_dir_hier (const gchar *dir); gint remove_all_files (const gchar *dir); gint remove_numbered_files (const gchar *dir, diff --git a/src/compose.c b/src/compose.c @@ -4984,17 +4984,11 @@ static gint compose_write_body_to_file(Compose *compose, const gchar *file) size_t len; gchar *chars, *tmp; - if ((fp = g_fopen(file, "wb")) == NULL) { - FILE_OP_ERROR(file, "g_fopen"); + if ((fp = fopen(file, "wb")) == NULL) { + warn("open %s", file); return -1; } - /* chmod for security */ - if (change_file_mode_rw(fp, file) < 0) { - FILE_OP_ERROR(file, "chmod"); - g_warning("can't change file mode"); - } - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(compose->text)); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); @@ -5143,16 +5137,11 @@ static ComposeQueueResult compose_queue_sub(Compose *compose, gint *msgnum, Fold G_DIR_SEPARATOR, compose, (guint) rand()); debug_print("queuing to %s\n", tmp); if ((fp = g_fopen(tmp, "w+b")) == NULL) { - FILE_OP_ERROR(tmp, "g_fopen"); + warn("open %s", tmp); g_free(tmp); return COMPOSE_QUEUE_ERROR_WITH_ERRNO; } - if (change_file_mode_rw(fp, tmp) < 0) { - FILE_OP_ERROR(tmp, "chmod"); - g_warning("can't change file mode"); - } - /* queueing variables */ err |= (fprintf(fp, "AF:\n") < 0); err |= (fprintf(fp, "NF:0\n") < 0); @@ -8374,7 +8363,6 @@ gboolean compose_draft (gpointer data, guint action) goto warn_err; } - /* chmod for security unless folder chmod is set */ prefs = draft->prefs; if (prefs && prefs->enable_folder_chmod && prefs->folder_chmod) { filemode = prefs->folder_chmod; @@ -8382,9 +8370,6 @@ gboolean compose_draft (gpointer data, guint action) if (filemode & S_IROTH) filemode |= S_IWOTH; if (chmod(tmp, filemode) < 0) FILE_OP_ERROR(tmp, "chmod"); - } else if (change_file_mode_rw(fp, tmp) < 0) { - FILE_OP_ERROR(tmp, "chmod"); - g_warning("can't change file mode"); } /* Save draft infos */ diff --git a/src/folder.c b/src/folder.c @@ -1338,7 +1338,6 @@ gchar *folder_item_get_identifier(FolderItem *item) Folder *folder_find_from_identifier(const gchar *identifier) { - gchar *str; gchar *p; gchar *name; FolderClass *class; @@ -1348,7 +1347,8 @@ Folder *folder_find_from_identifier(const gchar *identifier) if (*identifier != '#') return NULL; - Xstrdup_a(str, identifier, return NULL); + char str[BUFSIZ]; + strlcpy(str, identifier, sizeof(str)); p = strchr(str, '/'); if (!p) diff --git a/src/inc.c b/src/inc.c @@ -1303,6 +1303,7 @@ static gint get_spool(FolderItem *dest, const gchar *mbox, PrefsAccount *account } debug_print("Getting new messages from %s into %s...\n", mbox, dest->path); if (copy_mbox(spool, tmp_mbox) < 0) { + perror("copy mbox"); flock(spool, LOCK_UN); close(spool); return -1; diff --git a/src/main.c b/src/main.c @@ -293,7 +293,6 @@ static void main_dump_features_list(gboolean show_debug_only) int main(int argc, char *argv[]) { - gchar *userrc; MainWindow *mainwin; FolderView *folderview; GdkPixbuf *icon; @@ -327,7 +326,7 @@ int main(int argc, char *argv[]) if (cmd.status || cmd.status_full || cmd.search || cmd.cancel_receiving || cmd.cancel_sending || cmd.debug) { - puts("0 Claws Mail not running."); + puts("Claws Mail not running"); lock_socket_remove(); return 0; } @@ -344,26 +343,20 @@ int main(int argc, char *argv[]) CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), 1); - if (!is_dir_exist(get_rc_dir())) { - if (copy_dir("/etc/skel/.claws-mail", get_rc_dir()) < 0) { - if (!is_dir_exist(get_rc_dir()) && make_dir(get_rc_dir()) < 0) { - exit(1); - } + if (mkdir(get_rc_dir(), 0700) == 0) { + char *skel = "/etc/skel/.claws-mail"; + if (copy_dir(skel, get_rc_dir()) < 0) { + err(1, "copy template config directory from %s to %s", skel, get_rc_dir()); } } - userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "gtkrc-2.0", NULL); - gtk_rc_parse(userrc); - g_free(userrc); - - userrc = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL); - + char userrc[PATH_MAX]; + snprintf(userrc, sizeof(userrc), "%s/%s", get_rc_dir, MENU_RC); if (copy_file(userrc, userrc, TRUE) < 0) { - g_warning("can't copy %s to %s.bak", userrc, userrc); + warn("backup %s to %s.bak", userrc, userrc); } gtk_accel_map_load (userrc); - g_free(userrc); CHDIR_RETURN_VAL_IF_FAIL(get_rc_dir(), 1); if (mkdir(get_mail_base_dir(), 0755) < 0 && errno != EEXIST) @@ -1178,22 +1171,15 @@ gboolean claws_is_starting(void) return sc_starting; } -gchar *claws_get_socket_name(void) +char *claws_get_socket_name(void) { - char *dir = g_strdup_printf("%s/claws-mail", g_get_user_runtime_dir()); - struct stat sb; - int ok = stat(dir, &sb); - if (ok < 0 && errno != ENOENT) { - g_print("stat %s: %s\n", dir, g_strerror(errno)); - } - if (!is_dir_exist(dir) && make_dir(dir) < 0) { - g_print("create %s: %s\n", dir, g_strerror(errno)); - } - char *filename = g_strdup_printf("%s/control.sock", dir); - g_free(dir); - - debug_print("Using control socket %s\n", filename); - return filename; + char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/claws-mail", g_get_user_runtime_dir()); + if (mkdir(path, 0755) < 0 && errno != EEXIST) + warn("mkdir %s", path); + strlcat(path, "/control.sock", sizeof(path)); + fprintf(stderr, "Using control socket %s\n", path); + return strdup(path); } static gint prohibit_duplicate_launch(int *argc, char ***argv) @@ -1548,13 +1534,12 @@ static void lock_socket_input_cb(gpointer data, static void open_compose_new(const gchar *address, GList *attach_files) { - gchar *addr = NULL; - + // 254 + mailto: + char addr[261]; if (address) { - Xstrdup_a(addr, address, return); + strlcpy(addr, address, sizeof(addr)); g_strstrip(addr); } - compose_new(NULL, addr, attach_files); } diff --git a/src/mbox.c b/src/mbox.c @@ -126,9 +126,6 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, PrefsAccount *account) 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; @@ -247,27 +244,17 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, PrefsAccount *account) return msgs; } -gint copy_mbox(gint srcfd, const gchar *dest) -{ - FILE *dest_fp; +int copy_mbox(gint srcfd, const gchar *dest) { ssize_t n_read; char 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, "g_fopen"); + FILE *dest_fp = fopen(dest, "w"); + if (dest_fp == NULL) { + warn("open %s", dest); return -1; } - - if (change_file_mode_rw(dest_fp, dest) < 0) { - FILE_OP_ERROR(dest, "chmod"); - g_warning("can't change file mode"); - } + if (chmod(dest, S_IRUSR|S_IWUSR) < 0) + warn("chmod %s", dest); while ((n_read = read(srcfd, buf, sizeof(buf))) > 0) { if (fwrite(buf, 1, n_read, dest_fp) < n_read) { @@ -277,24 +264,7 @@ gint copy_mbox(gint srcfd, const gchar *dest) return -1; } } - - if (save_errno != 0) { - g_warning("error %d reading mbox: %s", save_errno, - g_strerror(save_errno)); - err = TRUE; - } - - if (fclose(dest_fp) == EOF) { - FILE_OP_ERROR(dest, "fclose"); - err = TRUE; - } - - if (err) { - unlink(dest); - return -1; - } - - return 0; + return fclose(dest_fp); } gint export_list_to_mbox(GSList *mlist, const gchar *mbox) diff --git a/src/mh.c b/src/mh.c @@ -23,6 +23,7 @@ #include <sys/stat.h> #include <unistd.h> #include <string.h> +#include <err.h> #include <errno.h> #include <time.h> @@ -189,33 +190,19 @@ static void mh_folder_init(Folder *folder, const gchar *name, const gchar *path) gboolean mh_scan_required(Folder *folder, FolderItem *item) { - gchar *path; - GStatBuf s; - - path = folder_item_get_path(item); - cm_return_val_if_fail(path != NULL, FALSE); - - if (g_stat(path, &s) < 0) { - FILE_OP_ERROR(path, "stat"); - g_free(path); + char *path = folder_item_get_path(item); + if (path == NULL) + return FALSE; + struct stat sb; + if (stat(path, &sb) < 0) { + warn("stat %s", path); + free(path); return FALSE; } + free(path); - if ((s.st_mtime > item->mtime) && - (s.st_mtime - 3600 != item->mtime)) { - debug_print("MH scan required, folder updated: %s (%ld > %ld)\n", - path, - (long int) s.st_mtime, - (long int) item->mtime); - g_free(path); + if ((sb.st_mtime > item->mtime) && (sb.st_mtime - 3600 != item->mtime)) return TRUE; - } - - debug_print("MH scan not required: %s (%ld <= %ld)\n", - path, - (long int) s.st_mtime, - (long int) item->mtime); - g_free(path); return FALSE; } @@ -544,8 +531,8 @@ static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist, if (MSG_IS_MOVE(msginfo->flags)) { msginfo->flags.tmp_flags &= ~MSG_MOVE_DONE; - if (move_file(srcfile, destfile, TRUE) < 0) { - FILE_OP_ERROR(srcfile, "move"); + if (rename(srcfile, destfile) < 0) { + warn("rename %s to %s", srcfile, destfile); if (copy_file(srcfile, destfile, TRUE) < 0) { FILE_OP_ERROR(srcfile, "copy"); g_free(srcfile); @@ -890,7 +877,16 @@ static gboolean mh_renumber_msg(MsgInfo *info) dest = mh_get_new_msg_filename(info->folder); num = info->folder->last_num + 1; - if (move_file(src, dest, FALSE) == 0) { + // only renumber the file if dest doesn't already exist. + // TODO(otl): why? + struct stat sb; + if (stat(dest, &sb) && errno == ENOENT) { + if (rename(src, dest) < 0) { + warn("rename %s to %s", src, dest); + free(src); + free(dest); + return FALSE; + } msgcache_remove_msg(info->folder->cache, info->msgnum); info->msgnum = num; msgcache_add_msg(info->folder->cache, info); @@ -936,7 +932,7 @@ static FolderItem *mh_create_folder(Folder *folder, FolderItem *parent, } } - if (make_dir(fullpath) < 0) { + if (mkdir(fullpath, 0700) < 0) { g_free(fullpath); return NULL; } diff --git a/src/msgcache.c b/src/msgcache.c @@ -377,9 +377,6 @@ static FILE *msgcache_open_data_file(const gchar *file, guint version, FILE_OP_ERROR(file, "g_fopen"); return NULL; } - if (change_file_mode_rw(fp, file) < 0) - FILE_OP_ERROR(file, "chmod"); - WRITE_CACHE_DATA_INT(version, fp); if (w_err != 0) { g_warning("failed to write int"); @@ -958,12 +955,6 @@ gint msgcache_write(const gchar *cache_file, const gchar *mark_file, const gchar write_fps.tags_fp = NULL; - if (write_fps.cache_fp || write_fps.mark_fp) - debug_print("\tWriting message cache to %s and %s...\n", new_cache, new_mark); - - if (write_fps.cache_fp && change_file_mode_rw(write_fps.cache_fp, new_cache) < 0) - FILE_OP_ERROR(new_cache, "chmod"); - /* headers written, note file size */ if (write_fps.cache_fp) write_fps.cache_size = ftell(write_fps.cache_fp); @@ -989,9 +980,9 @@ gint msgcache_write(const gchar *cache_file, const gchar *mark_file, const gchar } else { /* switch files */ if (cache_file) - move_file(new_cache, cache_file, TRUE); + rename(new_cache, cache_file); if (mark_file) - move_file(new_mark, mark_file, TRUE); + rename(new_mark, mark_file); cache->last_access = time(NULL); } diff --git a/src/pop.c b/src/pop.c @@ -667,9 +667,6 @@ static gint pop3_write_msg_to_file(const gchar *file, const gchar *data, 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"); diff --git a/src/prefs_common.c b/src/prefs_common.c @@ -1008,11 +1008,6 @@ static void prefs_common_save_history_to_dir(const gchar *dirname, const gchar * goto out; } - if (change_file_mode_rw(fp, history) < 0) { - FILE_OP_ERROR(history, "chmod"); - g_warning("can't change file mode: %s", history); - } - for (cur = list; cur != NULL; cur = cur->next) { TRY(fputs((gchar *)cur->data, fp) != EOF && fputc('\n', fp) != EOF); diff --git a/src/procheader.c b/src/procheader.c @@ -982,10 +982,10 @@ static gint procheader_scan_date_string(const gchar *o_str, if (month_n >= 1 && month_n <= 12) { strncpy2(month, monthstr+((month_n-1)*3), 4); if (zonestr[0] == 'z' || zonestr[0] == 'Z') { - strcat(zone, "+00:00"); + strlcat(zone, "+00:00", sizeof(zone)); } else if (sscanf(zonestr, "%c%2d:%2d", &offset_sign, &zone1, &zone2) == 3) { - strcat(zone, zonestr); + strlcat(zone, zonestr, sizeof(zone)); } return 0; } @@ -999,10 +999,10 @@ static gint procheader_scan_date_string(const gchar *o_str, if (month_n >= 1 && month_n <= 12) { strncpy2(month, monthstr+((month_n-1)*3), 4); if (zonestr[0] == 'z' || zonestr[0] == 'Z') { - strcat(zone, "+00:00"); + strlcat(zone, "+00:00", sizeof(zone)); } else if (sscanf(zonestr, "%c%2d:%2d", &offset_sign, &zone1, &zone2) == 3) { - strcat(zone, zonestr); + strlcat(zone, zonestr, sizeof(zone)); } return 0; } diff --git a/src/procmime.c b/src/procmime.c @@ -693,11 +693,6 @@ gint procmime_get_part(const gchar *outfile, MimeInfo *mimeinfo) return -(saved_errno); } - if (change_file_mode_rw(outfp, outfile) < 0) { - FILE_OP_ERROR(outfile, "chmod"); - g_warning("can't change file mode: %s", outfile); - } - result = procmime_get_part_to_stream(outfp, mimeinfo); if (fclose(outfp) == EOF) {