[PATCH] DLD upload: Avoid using open_memstream() and non-portable functions

Lubomir I. Ivanov neolit123 at gmail.com
Tue Mar 12 13:40:02 PDT 2013


From: "Lubomir I. Ivanov" <neolit123 at gmail.com>

patch contains:
- replacement for open_memstream()
- storage of the temporary zip file in the OS temporary directory
- replacement usage of mktemp() with g_mkstemp()

patch based on work by Miika Turkia.

Signed-off-by: Lubomir I. Ivanov <neolit123 at gmail.com>
---
 divelist.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/divelist.c b/divelist.c
index a426d67..4d00c9f 100644
--- a/divelist.c
+++ b/divelist.c
@@ -10,6 +10,7 @@
  * void mark_divelist_changed(int changed)
  * int unsaved_changes()
  */
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -1977,7 +1978,7 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
 	int i;
 	struct dive *dive;
 	FILE *f;
-	char filename[PATH_MAX], *tempfile, *template;
+	char filename[PATH_MAX], *tempfile;
 	size_t streamsize;
 	char *membuf;
 	xmlDoc *doc;
@@ -1985,14 +1986,17 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
 	xmlDoc *transformed;
 	struct zip_source *s[dive_table.nr];
 	struct zip *zip;
+	const gchar *tmpdir = g_get_tmp_dir();
 
 	/*
 	 * Creating a temporary .DLD file to be eventually uploaded to
 	 * divelogs.de. I wonder if this could be done in-memory.
 	 */
 
-	template = strdup("/tmp/export.DLD-XXXXXX");
-	tempfile = mktemp(template);
+	tempfile = g_build_filename(tmpdir, "export.DLD-XXXXXX", NULL);
+	int fd = g_mkstemp(tempfile);
+	if (fd != -1)
+		close(fd);
 	zip = zip_open(tempfile, ZIP_CREATE, NULL);
 
 	if (!zip)
@@ -2010,14 +2014,17 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
 		if (!dive->selected)
 			continue;
 
-		/*
-		 * Saving the dive is done into a memory buffer
-		 */
-
-		f = open_memstream(&membuf, &streamsize);
+		f = tmpfile();
 		if (!f)
 			return;
 		save_dive(f, dive);
+		fseek(f, 0, SEEK_END);
+		streamsize = ftell(f);
+		rewind(f);
+		membuf = malloc(streamsize + 1);
+		if (!membuf || !fread(membuf, streamsize, 1, f))
+			return;
+		membuf[streamsize] = 0;
 		fclose(f);
 
 		/*
@@ -2030,7 +2037,10 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
 		if (!doc)
 			continue;
 
+		free((void *)membuf);
 		xslt = get_stylesheet("divelogs-export.xslt");
+		if (!xslt)
+			return;
 		transformed = xsltApplyStylesheet(xslt, doc, NULL);
 		xsltFreeStylesheet(xslt);
 		xmlDocDumpMemory(transformed, (xmlChar **) &membuf, (int *)&streamsize);
@@ -2044,7 +2054,8 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
 		snprintf(filename, PATH_MAX, "%d.xml", i + 1);
 		if ((s[i]=zip_source_buffer(zip, membuf, streamsize, 0)) == NULL || zip_add(zip, filename, s[i]) == -1)
 			fprintf(stderr, "failed to include dive %d\n", i);
-
+		if (membuf)
+			free((void *)membuf);
 	}
 	zip_close(zip);
 
@@ -2055,7 +2066,8 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path)
 	 */
 
 	fprintf(stderr, "Created .DLD file %s\n", tempfile);
-	free(template);
+	g_unlink(tempfile); /* temporary: file delete should be after the upload instead */
+	g_free(tempfile);
 }
 #endif
 
-- 
1.7.11.msysgit.0



More information about the subsurface mailing list