diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2015-01-02 12:43:46 +0000 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2015-01-02 12:48:18 +0000 |
commit | e31ae2c5a12df0e14d93adca2b83adfe6939bb0b (patch) | |
tree | 681425008e78fc6a73a97116140d4b4d67d167f1 /desktop/hotlist.c | |
parent | 8df033357721f62064e4f80850d37d44070530e1 (diff) | |
download | netsurf-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/hotlist.c')
-rw-r--r-- | desktop/hotlist.c | 80 |
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); } |