about summary refs log tree commit diff stats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/aesgcm_download.c81
-rw-r--r--src/tools/aesgcm_download.h2
-rw-r--r--src/tools/http_download.c52
-rw-r--r--src/tools/http_download.h3
4 files changed, 87 insertions, 51 deletions
diff --git a/src/tools/aesgcm_download.c b/src/tools/aesgcm_download.c
index 693eabe7..6e8b89c5 100644
--- a/src/tools/aesgcm_download.c
+++ b/src/tools/aesgcm_download.c
@@ -67,56 +67,87 @@ aesgcm_file_get(void* userdata)
     char* https_url = NULL;
     char* fragment = NULL;
 
+    const size_t err_len = 100;
+    char err_buf[err_len];
+
     if (omemo_parse_aesgcm_url(aesgcm_dl->url, &https_url, &fragment) != 0) {
         http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
-                                   "Download failed: Cannot parse URL.");
+                                   "Download failed: Cannot parse URL '%s'.",
+                                   aesgcm_dl->url);
         return NULL;
     }
 
-    int tmpfd;
     char* tmpname = NULL;
-    if ((tmpfd = g_file_open_tmp("profanity.XXXXXX", &tmpname, NULL)) == -1) {
+    if (g_file_open_tmp("profanity.XXXXXX", &tmpname, NULL) == -1) {
+        strerror_r(errno, err_buf, err_len);
         http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
                                    "Downloading '%s' failed: Unable to create "
-                                   "temporary ciphertext file for writing.",
-                                   https_url);
+                                   "temporary ciphertext file for writing "
+                                   "(%s).",
+                                   https_url, err_buf);
         return NULL;
     }
-    FILE* tmpfh = fdopen(tmpfd, "wb");
 
-    // Remove the file once it is closed.
-    remove(tmpname);
-    free(tmpname);
+    FILE* outfh = fopen(aesgcm_dl->filename, "wb");
+    if (outfh == NULL) {
+        strerror_r(errno, err_buf, err_len);
+        http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
+                                   "Downloading '%s' failed: Unable to open "
+                                   "output file at '%s' for writing (%s).",
+                                   https_url, aesgcm_dl->filename, err_buf);
+        return NULL;
+    }
 
     HTTPDownload* http_dl = malloc(sizeof(HTTPDownload));
     http_dl->window = aesgcm_dl->window;
     http_dl->worker = aesgcm_dl->worker;
-    http_dl->url = https_url;
-    http_dl->filehandle = tmpfh;
-    http_dl->close = 0;
+    http_dl->url = strdup(https_url);
+    http_dl->filename = strdup(tmpname);
 
     aesgcm_dl->http_dl = http_dl;
 
-    // TODO: Verify result.
-    http_file_get(http_dl);
+    http_file_get(http_dl); // TODO(wstrm): Verify result.
+
+    FILE* tmpfh = fopen(tmpname, "rb");
+    if (tmpfh == NULL) {
+        strerror_r(errno, err_buf, err_len);
+        http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
+                                   "Downloading '%s' failed: Unable to open "
+                                   "temporary file at '%s' for reading (%s).",
+                                   aesgcm_dl->url, aesgcm_dl->filename, err_buf);
+        return NULL;
+    }
 
-    // Force flush as the decrypt function will read from the same stream.
-    fflush(tmpfh);
-    rewind(tmpfh);
+    gcry_error_t crypt_res;
+    crypt_res = omemo_decrypt_file(tmpfh, outfh,
+                                   http_dl->bytes_received, fragment);
 
-    int crypt_res = omemo_decrypt_file(tmpfh, aesgcm_dl->filehandle,
-                                       http_dl->bytes_received, fragment);
+    if (fclose(tmpfh) == EOF) {
+        strerror_r(errno, err_buf, err_len);
+        cons_show_error(err_buf);
+    }
 
-    fclose(tmpfh);
+    remove(tmpname);
+    free(tmpname);
 
-    if (crypt_res != 0) {
+    if (crypt_res != GPG_ERR_NO_ERROR) {
         http_print_transfer_update(aesgcm_dl->window, aesgcm_dl->url,
-                                   "Downloading '%s' failed: Failed to decrypt"
-                                   "file.",
-                                   https_url);
+                                   "Downloading '%s' failed: Failed to decrypt "
+                                   "file (%s).",
+                                   https_url, gcry_strerror(crypt_res));
+    }
+
+    if (fclose(outfh) == EOF) {
+        strerror_r(errno, err_buf, err_len);
+        cons_show_error(err_buf);
     }
 
-    fclose(aesgcm_dl->filehandle);
+    free(https_url);
+    free(fragment);
+
+    free(aesgcm_dl->filename);
+    free(aesgcm_dl->url);
+    free(aesgcm_dl);
 
     return NULL;
 }
diff --git a/src/tools/aesgcm_download.h b/src/tools/aesgcm_download.h
index fc29a99e..ebc8a5f9 100644
--- a/src/tools/aesgcm_download.h
+++ b/src/tools/aesgcm_download.h
@@ -50,7 +50,7 @@
 typedef struct aesgcm_download_t
 {
     char* url;
-    FILE* filehandle;
+    char* filename;
     ProfWin* window;
     pthread_t worker;
     HTTPDownload* http_dl;
diff --git a/src/tools/http_download.c b/src/tools/http_download.c
index a86af172..5859dc70 100644
--- a/src/tools/http_download.c
+++ b/src/tools/http_download.c
@@ -109,6 +109,9 @@ http_file_get(void* userdata)
 {
     HTTPDownload* download = (HTTPDownload*)userdata;
 
+    const size_t err_len = 100;
+    char err_buf[err_len];
+
     char* err = NULL;
 
     CURL* curl;
@@ -118,12 +121,18 @@ http_file_get(void* userdata)
     download->bytes_received = 0;
 
     pthread_mutex_lock(&lock);
-    char* msg;
-    if (asprintf(&msg, "Downloading '%s': 0%%", download->url) == -1) {
-        msg = strdup(FALLBACK_MSG);
+    http_print_transfer_update(download->window, download->url,
+                               "Downloading '%s': 0%%", download->url);
+
+    FILE* outfh = fopen(download->filename, "wb");
+    if (outfh == NULL) {
+        strerror_r(errno, err_buf, err_len);
+        http_print_transfer_update(download->window, download->url,
+                                   "Downloading '%s' failed: Unable to open "
+                                   "output file at '%s' for writing (%s).",
+                                   download->url, download->filename, err_buf);
+        return NULL;
     }
-    win_print_http_transfer(download->window, msg, download->url);
-    free(msg);
 
     char* cert_path = prefs_get_string(PREF_TLS_CERTPATH);
     pthread_mutex_unlock(&lock);
@@ -142,7 +151,7 @@ http_file_get(void* userdata)
 #endif
     curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
 
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)download->filehandle);
+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)outfh);
 
     curl_easy_setopt(curl, CURLOPT_USERAGENT, "profanity");
 
@@ -157,35 +166,31 @@ http_file_get(void* userdata)
     curl_easy_cleanup(curl);
     curl_global_cleanup();
 
-    if (download->filehandle && download->close) {
-        fclose(download->filehandle);
+    if (fclose(outfh) == EOF) {
+        strerror_r(errno, err_buf, err_len);
+        err = strdup(err_buf);
     }
 
     pthread_mutex_lock(&lock);
     g_free(cert_path);
     if (err) {
-        char* msg;
         if (download->cancel) {
-            if (asprintf(&msg, "Downloading '%s' failed: Download was canceled", download->url) == -1) {
-                msg = strdup(FALLBACK_MSG);
-            }
+            http_print_transfer_update(download->window, download->url,
+                                       "Downloading '%s' failed: "
+                                       "Download was canceled",
+                                       download->url);
         } else {
-            if (asprintf(&msg, "Downloading '%s' failed: %s", download->url, err) == -1) {
-                msg = strdup(FALLBACK_MSG);
-            }
-            win_update_entry_message(download->window, download->url, msg);
+            http_print_transfer_update(download->window, download->url,
+                                       "Downloading '%s' failed: %s",
+                                       download->url, err);
         }
-        cons_show_error(msg);
-        free(msg);
         free(err);
     } else {
         if (!download->cancel) {
-            if (asprintf(&msg, "Downloading '%s': 100%%", download->url) == -1) {
-                msg = strdup(FALLBACK_MSG);
-            }
-            win_update_entry_message(download->window, download->url, msg);
+            http_print_transfer_update(download->window, download->url,
+                                       "Downloading '%s': 100%%",
+                                       download->url);
             win_mark_received(download->window, download->url);
-            free(msg);
         }
     }
 
@@ -193,6 +198,7 @@ http_file_get(void* userdata)
     pthread_mutex_unlock(&lock);
 
     free(download->url);
+    free(download->filename);
     free(download);
 
     return NULL;
diff --git a/src/tools/http_download.h b/src/tools/http_download.h
index 797e1603..077e3e3d 100644
--- a/src/tools/http_download.h
+++ b/src/tools/http_download.h
@@ -49,12 +49,11 @@
 typedef struct http_download_t
 {
     char* url;
-    FILE* filehandle;
+    char* filename;
     curl_off_t bytes_received;
     ProfWin* window;
     pthread_t worker;
     int cancel;
-    int close;
 } HTTPDownload;
 
 void* http_file_get(void* userdata);