Coverity fixes
[claws.git] / src / partial_download.c
index 95fde101dd6858183a717b5dd337c9560baf6ad5..d7b0ce695921b78c83992b9c81da238ed5144e3d 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 Hiroyuki Yamamoto
- * This file (C) 2004 Colin Leroy
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2012 Colin Leroy <colin@colino.net> 
+ * and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -14,8 +14,8 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 
  */
 
 /* Partial download:
@@ -44,6 +44,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
+#include "claws-features.h"
 #endif
 
 #include <glib.h>
@@ -71,24 +72,28 @@ int partial_msg_in_uidl_list(MsgInfo *msginfo)
        gchar uidl[POPBUFSIZE];
        time_t recv_time;
        time_t now;
-       gint partial_recv;
-       gchar *sanitized_uid = g_strdup(msginfo->account_login);
+       gchar *sanitized_uid = NULL;
+       
+       if (!msginfo->extradata)
+               return FALSE;
+
+       sanitized_uid = g_strdup(msginfo->extradata->account_login);
        
        subst_for_filename(sanitized_uid);
 
-       if (!msginfo->account_server
-       ||  !msginfo->account_login
-       ||  !msginfo->partial_recv)
+       if (!msginfo->extradata->account_server
+       ||  !msginfo->extradata->account_login
+       ||  !msginfo->extradata->partial_recv)
                return FALSE;
        
        path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
-                          "uidl", G_DIR_SEPARATOR_S, msginfo->account_server,
-                          "-", msginfo->account_login, NULL);
+                          "uidl", G_DIR_SEPARATOR_S, msginfo->extradata->account_server,
+                          "-", msginfo->extradata->account_login, NULL);
        if ((fp = g_fopen(path, "rb")) == NULL) {
                if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
                g_free(path);
                path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
-                                  "uidl-", msginfo->account_server,
+                                  "uidl-", msginfo->extradata->account_server,
                                   "-", sanitized_uid, NULL);
                if ((fp = g_fopen(path, "rb")) == NULL) {
                        if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
@@ -106,7 +111,6 @@ int partial_msg_in_uidl_list(MsgInfo *msginfo)
                gchar tmp[POPBUFSIZE];
                strretchomp(buf);
                recv_time = RECV_TIME_NONE;
-               partial_recv = POP3_TOTALLY_RECEIVED;
                
                if (sscanf(buf, "%s\t%ld\t%s", uidl, (long int *) &recv_time, 
                           tmp) < 2) {
@@ -116,7 +120,7 @@ int partial_msg_in_uidl_list(MsgInfo *msginfo)
                                recv_time = now;
                        }
                }
-               if (!strcmp(uidl, msginfo->partial_recv)) {
+               if (!strcmp(uidl, msginfo->extradata->partial_recv)) {
                        fclose(fp);
                        return TRUE;
                }
@@ -136,8 +140,6 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
        gchar uidl[POPBUFSIZE];
        time_t recv_time;
        time_t now;
-       int len;
-       int start = TRUE;
        gchar partial_recv[POPBUFSIZE];
        int err = -1;
        gchar *filename;
@@ -150,17 +152,22 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                return err;
        }
        tinfo = procheader_parse_file(filename, msginfo->flags, TRUE, TRUE);
+       
+       if (!tinfo->extradata) {
+               g_free(filename);
+               return err;
+       }
 
-       sanitized_uid = g_strdup(tinfo->account_login);
+       sanitized_uid = g_strdup(tinfo->extradata->account_login);
        subst_for_filename(sanitized_uid);
 
-       if (!tinfo->account_server
-       ||  !tinfo->account_login
-       ||  !tinfo->partial_recv) {
+       if (!tinfo->extradata->account_server
+       ||  !tinfo->extradata->account_login
+       ||  !tinfo->extradata->partial_recv) {
                goto bail;
        }
        path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
-                          "uidl", G_DIR_SEPARATOR_S, tinfo->account_server,
+                          "uidl", G_DIR_SEPARATOR_S, tinfo->extradata->account_server,
                           "-", sanitized_uid, NULL);
 
        if ((fp = g_fopen(path, "rb")) == NULL) {
@@ -168,8 +175,8 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
                g_free(path);
                path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
-                                  "uidl-", tinfo->account_server,
-                                  "-", tinfo->account_login, NULL);
+                                  "uidl-", tinfo->extradata->account_server,
+                                  "-", tinfo->extradata->account_login, NULL);
                if ((fp = g_fopen(path, "rb")) == NULL) {
                        if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
                        g_free(path);
@@ -178,7 +185,7 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
        }
 
        pathnew = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
-                          "uidl", G_DIR_SEPARATOR_S, tinfo->account_server,
+                          "uidl", G_DIR_SEPARATOR_S, tinfo->extradata->account_server,
                           "-", sanitized_uid, ".new", NULL);
        
        g_free(sanitized_uid);
@@ -205,9 +212,16 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                                recv_time = now;
                        }
                }
-               if (strcmp(tinfo->partial_recv, uidl)) {
-                       fprintf(fpnew, "%s\t%ld\t%s\n", 
-                               uidl, (long int) recv_time, partial_recv);
+               if (strcmp(tinfo->extradata->partial_recv, uidl)) {
+                       if (fprintf(fpnew, "%s\t%ld\t%s\n", 
+                               uidl, (long int) recv_time, partial_recv) < 0) {
+                               FILE_OP_ERROR(pathnew, "fprintf");
+                               fclose(fpnew);
+                               fclose(fp);
+                               g_free(path);
+                               g_free(pathnew);
+                               goto bail;
+                       }
                } else {
                        gchar *stat = NULL;
                        if (download == POP3_PARTIAL_DLOAD_DLOAD) {
@@ -222,12 +236,25 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                        else if (download == POP3_PARTIAL_DLOAD_DELE)
                                stat = g_strdup("0");
                        
-                       fprintf(fpnew, "%s\t%ld\t%s\n", 
-                               uidl, (long int) recv_time, stat);
+                       if (fprintf(fpnew, "%s\t%ld\t%s\n", 
+                               uidl, (long int) recv_time, stat) < 0) {
+                               FILE_OP_ERROR(pathnew, "fprintf");
+                               fclose(fpnew);
+                               fclose(fp);
+                               g_free(path);
+                               g_free(pathnew);
+                               goto bail;
+                       }
                        g_free(stat);
                }
        }
-       fclose(fpnew);
+       if (fclose(fpnew) == EOF) {
+               FILE_OP_ERROR(pathnew, "fclose");
+               fclose(fp);
+               g_free(path);
+               g_free(pathnew);
+               goto bail;
+       }
        fclose(fp);
 
        move_file(pathnew, path, TRUE);
@@ -247,27 +274,49 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                goto bail;
        }
        
-       while ((len = fread(buf, sizeof(gchar), sizeof(buf)-1, fp)) > 0) {
-               buf[len]='\0';
-               if (start) {
-                       start = FALSE;
-                       fprintf(fpnew, "SC-Marked-For-Download: %d\n", 
-                                       download);
-                       
-                       if(strlen(buf) > strlen("SC-Marked-For-Download: x\n")
-                       && !strncmp(buf, "SC-Marked-For-Download:", 
-                                   strlen("SC-Marked-For-Download:"))) {
-                               fprintf(fpnew, "%s", 
-                                buf+strlen("SC-Marked-For-Download: x\n"));
-                               continue;
+       if (fprintf(fpnew, "SC-Marked-For-Download: %d\n", 
+                       download) < 0) {
+               FILE_OP_ERROR(pathnew, "fprintf");
+               fclose(fpnew);
+               fclose(fp);
+               g_free(pathnew);
+               goto bail;
+       }
+       while (fgets(buf, sizeof(buf)-1, fp) != NULL) {
+               if(strlen(buf) > strlen("SC-Marked-For-Download: x\n")
+               && !strncmp(buf, "SC-Marked-For-Download:", 
+                           strlen("SC-Marked-For-Download:"))) {
+                       if (fprintf(fpnew, "%s", 
+                        buf+strlen("SC-Marked-For-Download: x\n")) < 0) {
+                               FILE_OP_ERROR(pathnew, "fprintf");
+                               fclose(fpnew);
+                               fclose(fp);
+                               g_free(pathnew);
+                               goto bail;
                        }
+                       continue;
+               } else if (strlen(buf) == strlen("SC-Marked-For-Download: x\n")
+               && !strncmp(buf, "SC-Marked-For-Download:", 
+                           strlen("SC-Marked-For-Download:"))) {
+                       continue;
                }
-               fprintf(fpnew, "%s", buf);
+               if (fprintf(fpnew, "%s", buf) < 0) {
+                       FILE_OP_ERROR(pathnew, "fprintf");
+                       fclose(fpnew);
+                       fclose(fp);
+                       g_free(pathnew);
+                       goto bail;
+               }
+       }
+       if (fclose(fpnew) == EOF) {
+               FILE_OP_ERROR(pathnew, "fclose");
+               fclose(fp);
+               g_free(pathnew);
+               goto bail;
        }
-       fclose(fpnew);
+
        fclose(fp);
-       g_unlink(filename);
-       rename(pathnew, filename);
+       rename_force(pathnew, filename);
        g_free(pathnew);
        msginfo->planned_download = download;
        msgcache_update_msg(msginfo->folder->cache, msginfo);
@@ -302,7 +351,7 @@ void partial_delete_old(const gchar *file)
        int num = 0;
        FolderItem *item = NULL;
 
-       debug_print("too big message updated,should remove %s\n", file);
+       debug_print("too big message updated, should remove %s\n", file?file:"(null)");
 
        if (snum) {
                snum++;
@@ -334,7 +383,6 @@ gchar *partial_get_filename(const gchar *server, const gchar *login,
        gchar uidl[POPBUFSIZE];
        time_t recv_time;
        time_t now;
-       gint partial_recv;
        gchar *sanitized_uid = g_strdup(login); 
 
        subst_for_filename(sanitized_uid);
@@ -364,7 +412,6 @@ gchar *partial_get_filename(const gchar *server, const gchar *login,
                gchar tmp[POPBUFSIZE];
                strretchomp(buf);
                recv_time = RECV_TIME_NONE;
-               partial_recv = POP3_TOTALLY_RECEIVED;
                
                if (sscanf(buf, "%s\t%ld\t%s", uidl, (long int *) &recv_time, 
                           tmp) < 2) {