summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2015-01-02 12:43:46 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2015-01-02 12:48:18 +0000
commite31ae2c5a12df0e14d93adca2b83adfe6939bb0b (patch)
tree681425008e78fc6a73a97116140d4b4d67d167f1 /desktop
parent8df033357721f62064e4f80850d37d44070530e1 (diff)
downloadnetsurf-e31ae2c5a12df0e14d93adca2b83adfe6939bb0b.tar.gz
netsurf-e31ae2c5a12df0e14d93adca2b83adfe6939bb0b.tar.bz2
Make saving hotlist safer.
If saving hotlist to "<path>", we now save to "<path>.bk", then remove the file at "<path>", and replace it with the one at "<path>.bk". This should prevent hotlist corruption when someone pulls the plug while the hotlist is being written.
Diffstat (limited to 'desktop')
-rw-r--r--desktop/hotlist.c80
1 files changed, 78 insertions, 2 deletions
diff --git a/desktop/hotlist.c b/desktop/hotlist.c
index d9f89f037..615146a72 100644
--- a/desktop/hotlist.c
+++ b/desktop/hotlist.c
@@ -724,6 +724,36 @@ nserror hotlist_load_directory_cb(dom_node *node, void *ctx)
/*
+ * Get path for writing hotlist to
+ *
+ * \param path The final path of the hotlist
+ * \param loaded Updated to the path to write the holist to
+ * \return NSERROR_OK on success, or appropriate error otherwise
+ */
+static nserror hotlist_get_temp_path(const char *path, char **temp_path)
+{
+ const char *extension = ".bk";
+ char *joined;
+ int len;
+
+ len = strlen(path) + strlen(extension);
+
+ joined = malloc(len + 1);
+ if (joined == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ if (snprintf(joined, len + 1, "%s%s", path, extension) != len) {
+ free(joined);
+ return NSERROR_UNKNOWN;
+ }
+
+ *temp_path = joined;
+ return NSERROR_OK;
+}
+
+
+/*
* Load the hotlist data from file
*
* \param path The path to load the hotlist file from, or NULL
@@ -735,6 +765,7 @@ static nserror hotlist_load(const char *path, bool *loaded)
dom_document *document;
dom_node *html, *body, *ul;
hotlist_load_ctx ctx;
+ char *temp_path;
nserror err;
*loaded = false;
@@ -745,10 +776,20 @@ static nserror hotlist_load(const char *path, bool *loaded)
return NSERROR_OK;
}
+ /* Get temp hotlist write path */
+ err = hotlist_get_temp_path(path, &temp_path);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
/* Load hotlist file */
err = libdom_parse_file(path, "iso-8859-1", &document);
+ free(temp_path);
if (err != NSERROR_OK) {
- return err;
+ err = libdom_parse_file(temp_path, "iso-8859-1", &document);
+ if (err != NSERROR_OK) {
+ return err;
+ }
}
/* Find HTML element */
@@ -871,9 +912,44 @@ static nserror hotlist_generate(void)
}
+
+/* Save the hotlist to to a file at the given path
+ *
+ * \param path Path to save hostlist file to.
+ * \return NSERROR_OK on success, or appropriate error otherwise
+ */
+static nserror hotlist_save(const char *path)
+{
+ nserror res = NSERROR_OK;
+ char *temp_path;
+
+ /* Get path to export to */
+ res = hotlist_get_temp_path(path, &temp_path);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ /* Export to temp path */
+ res = hotlist_export(temp_path, NULL);
+ if (res != NSERROR_OK) {
+ goto cleanup;
+ }
+
+ /* Remove old hotlist file, and replace */
+ remove(path);
+ rename(temp_path, path);
+
+cleanup:
+ free(temp_path);
+
+ return res;
+}
+
+
struct treeview_export_walk_ctx {
FILE *fp;
};
+
/** Callback for treeview_walk node entering */
static nserror hotlist_export_enter_cb(void *ctx, void *node_data,
enum treeview_node_type type, bool *abort)
@@ -1196,7 +1272,7 @@ nserror hotlist_fini(const char *path)
LOG(("Finalising hotlist"));
/* Save the hotlist */
- err = hotlist_export(path, NULL);
+ err = hotlist_save(path);
if (err != NSERROR_OK) {
warn_user("Couldn't save the hotlist.", 0);
}