/soc/2015/mmcc/rand: 44944d650a24: Revert file-reading function ...

Michael McConville mmcconville at mykolab.com
Wed Aug 12 18:23:39 EDT 2015


Changeset: 44944d650a2480cc49db0e40ffa7b9a26507af1a
Author:	 Michael McConville <mmcconville at mykolab.com>
Date:	 2015-08-12 18:23 -0400
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/mmcc/rand/rev/44944d650a24

Description:

Revert file-reading function change. That's meant for my main repo - this one is only for the random data API.

diffstat:

 libpurple/image.c                       |    9 +-
 libpurple/plugins/ssl/ssl-gnutls.c      |    9 +-
 libpurple/plugins/ssl/ssl-nss.c         |   11 +-
 libpurple/protocols/gg/gg.c             |    5 +-
 libpurple/protocols/msn/slplink.c       |    5 +-
 libpurple/protocols/mxit/formcmds.c     |   18 +--
 libpurple/protocols/mxit/splashscreen.c |    8 +-
 libpurple/util.c                        |  159 ++++++++++++++++++++++++++++++-
 libpurple/util.h                        |   20 ++++
 libpurple/xmlnode.c                     |    4 +-
 10 files changed, 202 insertions(+), 46 deletions(-)

diffs (truncated from 445 to 300 lines):

diff --git a/libpurple/image.c b/libpurple/image.c
--- a/libpurple/image.c
+++ b/libpurple/image.c
@@ -197,14 +197,13 @@ purple_image_new_from_data(gpointer data
 	return img;
 }
 
-/* TODO: Should this now return a GError* instead? */
 gboolean
 purple_image_save(PurpleImage *image, const gchar *path)
 {
 	PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image);
 	gconstpointer data;
 	gsize len;
-	GError *err = NULL;
+	gboolean succ;
 
 	g_return_val_if_fail(priv != NULL, FALSE);
 	g_return_val_if_fail(path != NULL, FALSE);
@@ -216,11 +215,11 @@ purple_image_save(PurpleImage *image, co
 	g_return_val_if_fail(data != NULL, FALSE);
 	g_return_val_if_fail(len > 0, FALSE);
 
-	g_file_set_contents(path, data, len, &err);
-	if (err == NULL && priv->path == NULL)
+	succ = purple_util_write_data_to_file_absolute(path, data, len);
+	if (succ && priv->path == NULL)
 		priv->path = g_strdup(path);
 
-	return err == NULL;
+	return succ;
 }
 
 const gchar *
diff --git a/libpurple/plugins/ssl/ssl-gnutls.c b/libpurple/plugins/ssl/ssl-gnutls.c
--- a/libpurple/plugins/ssl/ssl-gnutls.c
+++ b/libpurple/plugins/ssl/ssl-gnutls.c
@@ -884,8 +884,6 @@ x509_importcerts_from_file(const gchar *
  * @param crt      Certificate to export
  *
  * @return TRUE if success, otherwise FALSE
- *
- * TODO: should this now return a GError* instead?
  */
 static gboolean
 x509_export_certificate(const gchar *filename, PurpleCertificate *crt)
@@ -894,7 +892,7 @@ x509_export_certificate(const gchar *fil
 	int ret;
 	gchar * out_buf; /* Data to output */
 	size_t out_size; /* Output size */
-	GError *err = NULL;
+	gboolean success = FALSE;
 
 	/* Paranoia paranoia paranoia! */
 	g_return_val_if_fail(filename, FALSE);
@@ -927,10 +925,11 @@ x509_export_certificate(const gchar *fil
 	}
 
 	/* Write it out to an actual file */
-	g_file_set_contents(filename, out_buf, out_size, &err);
+	success = purple_util_write_data_to_file_absolute(filename,
+							  out_buf, out_size);
 
 	g_free(out_buf);
-	return err == NULL;
+	return success;
 }
 
 static PurpleCertificate *
diff --git a/libpurple/plugins/ssl/ssl-nss.c b/libpurple/plugins/ssl/ssl-nss.c
--- a/libpurple/plugins/ssl/ssl-nss.c
+++ b/libpurple/plugins/ssl/ssl-nss.c
@@ -762,10 +762,7 @@ x509_importcerts_from_file(const gchar *
  * @return TRUE if success, otherwise FALSE
  */
 /* This function should not be so complicated, but NSS doesn't seem to have a
-   "convert yon certificate to PEM format" function.
-
-   TODO: Should this now return GError* instead?
- */
+   "convert yon certificate to PEM format" function. */
 static gboolean
 x509_export_certificate(const gchar *filename, PurpleCertificate *crt)
 {
@@ -773,7 +770,7 @@ x509_export_certificate(const gchar *fil
 	SECItem *dercrt;
 	gchar *b64crt;
 	gchar *pemcrt;
-	GError *err = NULL;
+	gboolean ret = FALSE;
 
 	g_return_val_if_fail(filename, FALSE);
 	g_return_val_if_fail(crt, FALSE);
@@ -801,11 +798,11 @@ x509_export_certificate(const gchar *fil
 			      function; hence, we'll let NSPR free it. */
 
 	/* Finally, dump the silly thing to a file. */
-	g_file_set_contents(filename, pemcrt, -1, &err);
+	ret =  purple_util_write_data_to_file_absolute(filename, pemcrt, -1);
 
 	g_free(pemcrt);
 
-	return err == NULL;
+	return ret;
 }
 
 static PurpleCertificate *
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -114,8 +114,8 @@ uin_t ggp_own_uin(PurpleConnection *gc)
 static void ggp_callback_buddylist_save_ok(PurpleConnection *gc, const char *filename)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
+
 	char *buddylist = ggp_buddylist_dump(account);
-	GError *err = NULL;
 
 	purple_debug_info("gg", "Saving...\n");
 	purple_debug_info("gg", "file = %s\n", filename);
@@ -127,8 +127,7 @@ static void ggp_callback_buddylist_save_
 		return;
 	}
 
-	g_file_set_contents(filename, buddylist, -1, &err);
-	if (err == NULL) {
+	if (purple_util_write_data_to_file_absolute(filename, buddylist, -1)) {
 		purple_notify_info(account, _("Save Buddylist..."),
 			_("Buddylist saved successfully!"), NULL,
 			purple_request_cpar_from_connection(gc));
diff --git a/libpurple/protocols/msn/slplink.c b/libpurple/protocols/msn/slplink.c
--- a/libpurple/protocols/msn/slplink.c
+++ b/libpurple/protocols/msn/slplink.c
@@ -46,14 +46,13 @@ debug_part_to_file(MsnSlpMessage *msg, g
 	char *data;
 	int c;
 	gsize data_size;
-	GError *err = NULL;
 
 	dir = send ? "send" : "recv";
 	c = send ? m_sc++ : m_rc++;
 	tmp = g_strdup_printf("%s/msntest/%s/%03d", purple_user_dir(), dir, c);
 	data = msn_slpmsg_serialize(msg, &data_size);
-	g_file_set_contents(tmp, data, data_size, &err);
-	if (err != NULL) {
+	if (!purple_util_write_data_to_file_absolute(tmp, data, data_size))
+	{
 		purple_debug_error("msn", "could not save debug file\n");
 	}
 	g_free(tmp);
diff --git a/libpurple/protocols/mxit/formcmds.c b/libpurple/protocols/mxit/formcmds.c
--- a/libpurple/protocols/mxit/formcmds.c
+++ b/libpurple/protocols/mxit/formcmds.c
@@ -397,14 +397,13 @@ static void command_imagestrip(struct MX
 	/* image data */
 	tmp = g_hash_table_lookup(hash, "dat");
 	if (tmp) {
-		guchar *rawimg;
-		gsize rawimglen;
-		char *dir;
-		char *escfrom;
-		char *escname;
-		char *escvalidator;
-		char *filename;
-		GError *err = NULL;
+		guchar*		rawimg;
+		gsize		rawimglen;
+		char*		dir;
+		char*		escfrom;
+		char*		escname;
+		char*		escvalidator;
+		char*		filename;
 
 		/* base64 decode the image data */
 		rawimg = purple_base64_decode(tmp, &rawimglen);
@@ -420,8 +419,7 @@ static void command_imagestrip(struct MX
 		escvalidator = g_strdup(purple_escape_filename(validator));
 		filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s-%s-%s.png", dir, escfrom, escname, escvalidator);
 
-		/* XXX: we never check whether this write succeeds */
-		g_file_set_contents(filename, (char*) rawimg, rawimglen, &err);
+		purple_util_write_data_to_file_absolute(filename, (char*) rawimg, rawimglen);
 
 		g_free(dir);
 		g_free(escfrom);
diff --git a/libpurple/protocols/mxit/splashscreen.c b/libpurple/protocols/mxit/splashscreen.c
--- a/libpurple/protocols/mxit/splashscreen.c
+++ b/libpurple/protocols/mxit/splashscreen.c
@@ -113,9 +113,8 @@ void splash_remove(struct MXitSession* s
  */
 void splash_update(struct MXitSession* session, const char* splashId, const char* data, int datalen, gboolean clickable)
 {
-	char *dir;
-	char *filename;
-	GError *err = NULL;
+	char* dir;
+	char* filename;
 
 	/* Remove the current splash-screen */
 	splash_remove(session);
@@ -125,8 +124,7 @@ void splash_update(struct MXitSession* s
 	purple_build_dir(dir, S_IRUSR | S_IWUSR | S_IXUSR);		/* ensure directory exists */
 
 	filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.png", dir, purple_escape_filename(splashId));
-	g_file_set_contents(filename, data, datalen, &err);
-	if (err == NULL) {
+	if (purple_util_write_data_to_file_absolute(filename, data, datalen)) {
 		/* Store new splash-screen ID to settings */
 		purple_account_set_string(session->acc, MXIT_CONFIG_SPLASHID, splashId);
 		purple_account_set_bool(session->acc, MXIT_CONFIG_SPLASHCLICK, clickable );
diff --git a/libpurple/util.c b/libpurple/util.c
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -2943,15 +2943,13 @@ int purple_build_dir (const char *path, 
  * This function is long and beautiful, like my--um, yeah.  Anyway,
  * it includes lots of error checking so as we don't overwrite
  * people's settings if there is a problem writing the new values.
- *
- * TODO: We should probably find a glib function to replace this with.
  */
 gboolean
 purple_util_write_data_to_file(const char *filename, const char *data, gssize size)
 {
 	const char *user_dir = purple_user_dir();
 	gchar *filename_full;
-	GError *err = NULL;
+	gboolean ret = FALSE;
 
 	g_return_val_if_fail(user_dir != NULL, FALSE);
 
@@ -2971,10 +2969,161 @@ purple_util_write_data_to_file(const cha
 
 	filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename);
 
-	g_file_set_contents(filename_full, data, size, &err);
+	ret = purple_util_write_data_to_file_absolute(filename_full, data, size);
 
 	g_free(filename_full);
-	return err == NULL;
+	return ret;
+}
+
+gboolean
+purple_util_write_data_to_file_absolute(const char *filename_full, const char *data, gssize size)
+{
+	gchar *filename_temp;
+	FILE *file;
+	gsize real_size, byteswritten;
+	GStatBuf st;
+#ifndef HAVE_FILENO
+	int fd;
+#endif
+
+	purple_debug_misc("util", "Writing file %s",
+					filename_full);
+
+	g_return_val_if_fail((size >= -1), FALSE);
+
+	filename_temp = g_strdup_printf("%s.save", filename_full);
+
+	/* Remove an old temporary file, if one exists */
+	if (g_file_test(filename_temp, G_FILE_TEST_EXISTS))
+	{
+		if (g_unlink(filename_temp) == -1)
+		{
+			purple_debug_error("util", "Error removing old file "
+					   "%s: %s\n",
+					   filename_temp, g_strerror(errno));
+		}
+	}
+
+	/* Open file */
+	file = g_fopen(filename_temp, "wb");
+	if (file == NULL)
+	{
+		purple_debug_error("util", "Error opening file %s for "
+				   "writing: %s\n",
+				   filename_temp, g_strerror(errno));
+		g_free(filename_temp);
+		return FALSE;
+	}
+
+	/* Write to file */
+	real_size = (size == -1) ? strlen(data) : (size_t) size;
+	byteswritten = fwrite(data, 1, real_size, file);
+
+#ifdef HAVE_FILENO
+#ifndef _WIN32
+	/* Set file permissions */
+	if (fchmod(fileno(file), S_IRUSR | S_IWUSR) == -1) {
+		purple_debug_error("util", "Error setting permissions of "
+			"file %s: %s\n", filename_temp, g_strerror(errno));
+	}
+#endif
+
+	/* Apparently XFS (and possibly other filesystems) do not
+	 * guarantee that file data is flushed before file metadata,
+	 * so this procedure is insufficient without some flushage. */
+	if (fflush(file) < 0) {
+		purple_debug_error("util", "Error flushing %s: %s\n",



More information about the Commits mailing list