aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--e-util/e-xml-utils.c67
-rw-r--r--e-util/e-xml-utils.h2
2 files changed, 65 insertions, 4 deletions
diff --git a/e-util/e-xml-utils.c b/e-util/e-xml-utils.c
index 4bc1b9e7d7..b33fb74ca5 100644
--- a/e-util/e-xml-utils.c
+++ b/e-util/e-xml-utils.c
@@ -26,10 +26,6 @@
#include <config.h>
#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
#include "e-xml-utils.h"
#include <stdio.h>
@@ -441,3 +437,66 @@ e_xml_get_translated_string_prop_by_name (const xmlNode *parent, const xmlChar *
}
+int
+e_xml_save_file (const char *filename, xmlDocPtr doc)
+{
+ char *filesave, *slash, *xmlbuf;
+ size_t n, written = 0;
+ int ret, fd, size;
+ int errnosave;
+ ssize_t w;
+
+ filesave = alloca (strlen (filename) + 5);
+ slash = strrchr (filename, '/');
+ if (slash)
+ sprintf (filesave, "%.*s.#%s", slash - filename + 1, filename, slash + 1);
+ else
+ sprintf (filesave, ".#%s", filename);
+
+ fd = open (filesave, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd == -1)
+ return -1;
+
+ xmlDocDumpMemory (doc, (xmlChar **) &xmlbuf, &size);
+ if (size <= 0) {
+ close (fd);
+ unlink (filesave);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ n = (size_t) size;
+ do {
+ do {
+ w = write (fd, xmlbuf + written, n - written);
+ } while (w == -1 && errno == EINTR);
+
+ if (w > 0)
+ written += w;
+ } while (w != -1 && written < n);
+
+ xmlFree (xmlbuf);
+
+ if (written < n || fsync (fd) == -1) {
+ errnosave = errno;
+ close (fd);
+ unlink (filesave);
+ errno = errnosave;
+ return -1;
+ }
+
+ while ((ret = close (fd)) == -1 && errno == EINTR)
+ ;
+
+ if (ret == -1)
+ return -1;
+
+ if (rename (filesave, filename) == -1) {
+ errnosave = errno;
+ unlink (filesave);
+ errno = errnosave;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/e-util/e-xml-utils.h b/e-util/e-xml-utils.h
index ad16b10ea6..6c39ee6f79 100644
--- a/e-util/e-xml-utils.h
+++ b/e-util/e-xml-utils.h
@@ -94,6 +94,8 @@ void e_xml_set_string_prop_by_name (xmlNode *parent,
gchar *e_xml_get_translated_string_prop_by_name (const xmlNode *parent,
const xmlChar *prop_name);
+int e_xml_save_file (const char *filename, xmlDocPtr doc);
+
G_END_DECLS
#endif /* __E_XML_UTILS__ */