improve error returns throughout complete save and remove user warnings

This commit is contained in:
Vincent Sanders 2019-11-04 23:39:13 +00:00
parent 44574d800f
commit 7c63f5f66b
2 changed files with 123 additions and 101 deletions

View File

@ -75,9 +75,8 @@ typedef enum {
} save_complete_event_type; } save_complete_event_type;
static bool save_complete_save_html(save_complete_ctx *ctx, struct hlcache_handle *c, static nserror save_complete_save_html(save_complete_ctx *ctx, struct hlcache_handle *c, bool index);
bool index); static nserror save_complete_save_imported_sheets(save_complete_ctx *ctx,
static bool save_complete_save_imported_sheets(save_complete_ctx *ctx,
struct nscss_import *imports, uint32_t import_count); struct nscss_import *imports, uint32_t import_count);
@ -100,20 +99,22 @@ static void save_complete_ctx_finalise(save_complete_ctx *ctx)
} }
} }
static bool save_complete_ctx_add_content(save_complete_ctx *ctx, static nserror
save_complete_ctx_add_content(save_complete_ctx *ctx,
struct hlcache_handle *content) struct hlcache_handle *content)
{ {
save_complete_entry *entry; save_complete_entry *entry;
entry = malloc(sizeof (*entry)); entry = malloc(sizeof (*entry));
if (entry == NULL) if (entry == NULL) {
return false; return NSERROR_NOMEM;
}
entry->content = content; entry->content = content;
entry->next = ctx->list; entry->next = ctx->list;
ctx->list = entry; ctx->list = entry;
return true; return NSERROR_OK;
} }
/** /**
@ -155,7 +156,7 @@ save_complete_ctx_has_content(save_complete_ctx *ctx,
return false; return false;
} }
static bool static nserror
save_complete_save_buffer(save_complete_ctx *ctx, save_complete_save_buffer(save_complete_ctx *ctx,
const char *leafname, const char *leafname,
const uint8_t *data, const uint8_t *data,
@ -168,16 +169,14 @@ save_complete_save_buffer(save_complete_ctx *ctx,
ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, leafname); ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, leafname);
if (ret != NSERROR_OK) { if (ret != NSERROR_OK) {
guit->misc->warning(messages_get_errorcode(ret), 0); return ret;
return false;
} }
fp = fopen(fname, "wb"); fp = fopen(fname, "wb");
if (fp == NULL) { if (fp == NULL) {
free(fname); free(fname);
NSLOG(netsurf, INFO, "fopen(): errno = %i", errno); NSLOG(netsurf, INFO, "fopen(): %s", strerror(errno));
guit->misc->warning("SaveError", strerror(errno)); return NSERROR_SAVE_FAILED;
return false;
} }
fwrite(data, sizeof(*data), data_len, fp); fwrite(data, sizeof(*data), data_len, fp);
@ -189,7 +188,7 @@ save_complete_save_buffer(save_complete_ctx *ctx,
} }
free(fname); free(fname);
return true; return NSERROR_OK;
} }
@ -357,7 +356,7 @@ save_complete_rewrite_stylesheet_urls(save_complete_ctx *ctx,
return rewritten; return rewritten;
} }
static bool static nserror
save_complete_save_stylesheet(save_complete_ctx *ctx, hlcache_handle *css) save_complete_save_stylesheet(save_complete_ctx *ctx, hlcache_handle *css)
{ {
const uint8_t *css_data; const uint8_t *css_data;
@ -368,22 +367,25 @@ save_complete_save_stylesheet(save_complete_ctx *ctx, hlcache_handle *css)
uint32_t import_count; uint32_t import_count;
lwc_string *type; lwc_string *type;
char filename[32]; char filename[32];
bool result; nserror result;
if (save_complete_ctx_find_content(ctx, if (save_complete_ctx_find_content(ctx,
hlcache_handle_get_url(css)) != NULL) { hlcache_handle_get_url(css)) != NULL) {
return true; return NSERROR_OK;
} }
if (save_complete_ctx_add_content(ctx, css) == false) { result = save_complete_ctx_add_content(ctx, css);
guit->misc->warning("NoMemory", 0); if (result != NSERROR_OK) {
return false; return result;
} }
imports = nscss_get_imports(css, &import_count); imports = nscss_get_imports(css, &import_count);
if (save_complete_save_imported_sheets(ctx, result = save_complete_save_imported_sheets(ctx,
imports, import_count) == false) imports,
return false; import_count);
if (result != NSERROR_OK) {
return result;
}
css_data = content_get_source_data(css, &css_size); css_data = content_get_source_data(css, &css_size);
source = save_complete_rewrite_stylesheet_urls( source = save_complete_rewrite_stylesheet_urls(
@ -393,14 +395,13 @@ save_complete_save_stylesheet(save_complete_ctx *ctx, hlcache_handle *css)
hlcache_handle_get_url(css), hlcache_handle_get_url(css),
&source_len); &source_len);
if (source == NULL) { if (source == NULL) {
guit->misc->warning("NoMemory", 0); return NSERROR_NOMEM;
return false;
} }
type = content_get_mime_type(css); type = content_get_mime_type(css);
if (type == NULL) { if (type == NULL) {
free(source); free(source);
return false; return NSERROR_NOMEM;
} }
snprintf(filename, sizeof filename, "%p", css); snprintf(filename, sizeof filename, "%p", css);
@ -414,75 +415,84 @@ save_complete_save_stylesheet(save_complete_ctx *ctx, hlcache_handle *css)
return result; return result;
} }
static bool static nserror
save_complete_save_imported_sheets(save_complete_ctx *ctx, save_complete_save_imported_sheets(save_complete_ctx *ctx,
struct nscss_import *imports, struct nscss_import *imports,
uint32_t import_count) uint32_t import_count)
{ {
nserror res;
uint32_t i; uint32_t i;
for (i = 0; i < import_count; i++) { for (i = 0; i < import_count; i++) {
/* treat a valid content as a stylesheet to save */ /* treat a valid content as a stylesheet to save */
if ((imports[i].c != NULL) && if (imports[i].c != NULL) {
(save_complete_save_stylesheet(ctx, imports[i].c) == false)) { res = save_complete_save_stylesheet(ctx, imports[i].c);
return false; if (res != NSERROR_OK) {
return res;
}
} }
} }
return true; return res;
} }
static bool static nserror
save_complete_save_html_stylesheet(save_complete_ctx *ctx, save_complete_save_html_stylesheet(save_complete_ctx *ctx,
struct html_stylesheet *sheet) struct html_stylesheet *sheet)
{ {
if (sheet->sheet == NULL) if (sheet->sheet == NULL) {
return true; return NSERROR_OK;
}
return save_complete_save_stylesheet(ctx, sheet->sheet); return save_complete_save_stylesheet(ctx, sheet->sheet);
} }
static bool save_complete_save_html_stylesheets(save_complete_ctx *ctx, static nserror
save_complete_save_html_stylesheets(save_complete_ctx *ctx,
hlcache_handle *c) hlcache_handle *c)
{ {
struct html_stylesheet *sheets; struct html_stylesheet *sheets;
unsigned int i, count; unsigned int i, count;
nserror res;
sheets = html_get_stylesheets(c, &count); sheets = html_get_stylesheets(c, &count);
for (i = STYLESHEET_START; i != count; i++) { for (i = STYLESHEET_START; i != count; i++) {
if (save_complete_save_html_stylesheet(ctx, res = save_complete_save_html_stylesheet(ctx, &sheets[i]);
&sheets[i]) == false) if (res != NSERROR_OK) {
return false; return res;
}
} }
return true; return NSERROR_OK;
} }
static bool static nserror
save_complete_save_html_object(save_complete_ctx *ctx, hlcache_handle *obj) save_complete_save_html_object(save_complete_ctx *ctx, hlcache_handle *obj)
{ {
const uint8_t *obj_data; const uint8_t *obj_data;
size_t obj_size; size_t obj_size;
lwc_string *type; lwc_string *type;
bool result; nserror result;
char filename[32]; char filename[32];
if (content_get_type(obj) == CONTENT_NONE) if (content_get_type(obj) == CONTENT_NONE) {
return true; return NSERROR_OK;
}
obj_data = content_get_source_data(obj, &obj_size); obj_data = content_get_source_data(obj, &obj_size);
if (obj_data == NULL) if (obj_data == NULL) {
return true; return NSERROR_OK;
}
if (save_complete_ctx_find_content(ctx, if (save_complete_ctx_find_content(ctx,
hlcache_handle_get_url(obj)) != NULL) { hlcache_handle_get_url(obj)) != NULL) {
return true; return NSERROR_OK;
} }
if (save_complete_ctx_add_content(ctx, obj) == false) { result = save_complete_ctx_add_content(ctx, obj);
guit->misc->warning("NoMemory", 0); if (result != NSERROR_OK) {
return false; return result;
} }
if (content_get_type(obj) == CONTENT_HTML) { if (content_get_type(obj) == CONTENT_HTML) {
@ -492,39 +502,45 @@ save_complete_save_html_object(save_complete_ctx *ctx, hlcache_handle *obj)
snprintf(filename, sizeof filename, "%p", obj); snprintf(filename, sizeof filename, "%p", obj);
type = content_get_mime_type(obj); type = content_get_mime_type(obj);
if (type == NULL) if (type == NULL) {
return false; return NSERROR_NOMEM;
}
result = save_complete_save_buffer(ctx, filename, result = save_complete_save_buffer(ctx, filename, obj_data, obj_size, type);
obj_data, obj_size, type);
lwc_string_unref(type); lwc_string_unref(type);
return result; return result;
} }
static bool save_complete_save_html_objects(save_complete_ctx *ctx, static nserror
save_complete_save_html_objects(save_complete_ctx *ctx,
hlcache_handle *c) hlcache_handle *c)
{ {
struct content_html_object *object; struct content_html_object *object;
unsigned int count; unsigned int count;
nserror res;
object = html_get_objects(c, &count); object = html_get_objects(c, &count);
for (; object != NULL; object = object->next) { for (; object != NULL; object = object->next) {
if ((object->content != NULL) && (object->box != NULL)) { if ((object->content != NULL) &&
if (save_complete_save_html_object(ctx, (object->box != NULL)) {
object->content) == false) res = save_complete_save_html_object(ctx, object->content);
return false; if (res != NSERROR_OK) {
return res;
}
} }
} }
return true; return NSERROR_OK;
} }
static bool save_complete_libdom_treewalk(dom_node *root, static bool
save_complete_libdom_treewalk(dom_node *root,
bool (*callback)(dom_node *node, bool (*callback)(dom_node *node,
save_complete_event_type event_type, void *ctx), save_complete_event_type event_type,
void *ctx),
void *ctx) void *ctx)
{ {
dom_node *node; dom_node *node;
@ -1118,7 +1134,7 @@ save_complete_node_handler(dom_node *node,
return true; return true;
} }
static bool static nserror
save_complete_save_html_document(save_complete_ctx *ctx, save_complete_save_html_document(save_complete_ctx *ctx,
hlcache_handle *c, hlcache_handle *c,
bool index) bool index)
@ -1138,16 +1154,14 @@ save_complete_save_html_document(save_complete_ctx *ctx,
ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, filename); ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, filename);
if (ret != NSERROR_OK) { if (ret != NSERROR_OK) {
guit->misc->warning(messages_get_errorcode(ret), NULL); return ret;
return false;
} }
fp = fopen(fname, "wb"); fp = fopen(fname, "wb");
if (fp == NULL) { if (fp == NULL) {
free(fname); free(fname);
NSLOG(netsurf, INFO, "fopen(): errno = %i", errno); NSLOG(netsurf, INFO, "fopen(): %s", strerror(errno));
guit->misc->warning("SaveError", strerror(errno)); return NSERROR_SAVE_FAILED;
return false;
} }
ctx->base = html_get_base_url(c); ctx->base = html_get_base_url(c);
@ -1160,23 +1174,23 @@ save_complete_save_html_document(save_complete_ctx *ctx,
save_complete_node_handler, save_complete_node_handler,
ctx) == false) { ctx) == false) {
free(fname); free(fname);
guit->misc->warning("NoMemory", 0);
fclose(fp); fclose(fp);
return false; return NSERROR_NOMEM;
} }
fclose(fp); fclose(fp);
mime_type = content_get_mime_type(c); mime_type = content_get_mime_type(c);
if (mime_type != NULL) { if (mime_type != NULL) {
if (ctx->set_type != NULL) if (ctx->set_type != NULL) {
ctx->set_type(fname, mime_type); ctx->set_type(fname, mime_type);
}
lwc_string_unref(mime_type); lwc_string_unref(mime_type);
} }
free(fname); free(fname);
return true; return NSERROR_OK;
} }
/** /**
@ -1187,22 +1201,30 @@ save_complete_save_html_document(save_complete_ctx *ctx,
* \param index true to save as "index" * \param index true to save as "index"
* \return true on success, false on error and error reported * \return true on success, false on error and error reported
*/ */
static bool static nserror
save_complete_save_html(save_complete_ctx *ctx, save_complete_save_html(save_complete_ctx *ctx,
hlcache_handle *c, hlcache_handle *c,
bool index) bool index)
{ {
if (content_get_type(c) != CONTENT_HTML) nserror res;
return false;
if (save_complete_ctx_has_content(ctx, c)) if (content_get_type(c) != CONTENT_HTML) {
return true; return NSERROR_INVALID;
}
if (save_complete_save_html_stylesheets(ctx, c) == false) if (save_complete_ctx_has_content(ctx, c)) {
return false; return NSERROR_OK;
}
if (save_complete_save_html_objects(ctx, c) == false) res = save_complete_save_html_stylesheets(ctx, c);
return false; if (res != NSERROR_OK) {
return res;
}
res = save_complete_save_html_objects(ctx, c);
if (res != NSERROR_OK) {
return res;
}
return save_complete_save_html_document(ctx, c, index); return save_complete_save_html_document(ctx, c, index);
} }
@ -1212,7 +1234,7 @@ save_complete_save_html(save_complete_ctx *ctx,
* Create the inventory file listing original URLs. * Create the inventory file listing original URLs.
*/ */
static bool save_complete_inventory(save_complete_ctx *ctx) static nserror save_complete_inventory(save_complete_ctx *ctx)
{ {
nserror ret; nserror ret;
FILE *fp; FILE *fp;
@ -1221,26 +1243,26 @@ static bool save_complete_inventory(save_complete_ctx *ctx)
ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, "Inventory"); ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, "Inventory");
if (ret != NSERROR_OK) { if (ret != NSERROR_OK) {
return false; return ret;
} }
fp = fopen(fname, "w"); fp = fopen(fname, "w");
free(fname); free(fname);
if (fp == NULL) { if (fp == NULL) {
NSLOG(netsurf, INFO, "fopen(): errno = %i", errno); NSLOG(netsurf, INFO, "fopen(): %s", strerror(errno));
guit->misc->warning("SaveError", strerror(errno)); return NSERROR_SAVE_FAILED;
return false;
} }
for (entry = ctx->list; entry != NULL; entry = entry->next) { for (entry = ctx->list; entry != NULL; entry = entry->next) {
fprintf(fp, "%p %s\n", entry->content, fprintf(fp, "%p %s\n",
entry->content,
nsurl_access(hlcache_handle_get_url( nsurl_access(hlcache_handle_get_url(
entry->content))); entry->content)));
} }
fclose(fp); fclose(fp);
return true; return NSERROR_OK;
} }
/** /**
@ -1304,19 +1326,19 @@ nserror save_complete_finalise(void)
} }
/* Documented in save_complete.h */ /* Documented in save_complete.h */
bool nserror
save_complete(hlcache_handle *c, save_complete(hlcache_handle *c,
const char *path, const char *path,
save_complete_set_type_cb set_type) save_complete_set_type_cb set_type)
{ {
bool result; nserror result;
save_complete_ctx ctx; save_complete_ctx ctx;
save_complete_ctx_initialise(&ctx, path, set_type); save_complete_ctx_initialise(&ctx, path, set_type);
result = save_complete_save_html(&ctx, c, true); result = save_complete_save_html(&ctx, c, true);
if (result) { if (result == NSERROR_OK) {
result = save_complete_inventory(&ctx); result = save_complete_inventory(&ctx);
} }

View File

@ -21,8 +21,8 @@
* Save HTML document with dependencies (interface). * Save HTML document with dependencies (interface).
*/ */
#ifndef _NETSURF_DESKTOP_SAVE_COMPLETE_H_ #ifndef NETSURF_DESKTOP_SAVE_COMPLETE_H_
#define _NETSURF_DESKTOP_SAVE_COMPLETE_H_ #define NETSURF_DESKTOP_SAVE_COMPLETE_H_
#include <stdbool.h> #include <stdbool.h>
@ -56,9 +56,9 @@ nserror save_complete_finalise(void);
* \param c CONTENT_HTML to save * \param c CONTENT_HTML to save
* \param path Native path to directory to save in to (must exist) * \param path Native path to directory to save in to (must exist)
* \param set_type Callback to set type of a file, or NULL * \param set_type Callback to set type of a file, or NULL
* \return true on success, false on error and error reported * \return NSERROR_OK on success else error code
*/ */
bool save_complete(struct hlcache_handle *c, const char *path, nserror save_complete(struct hlcache_handle *c, const char *path,
save_complete_set_type_cb set_type); save_complete_set_type_cb set_type);
#endif #endif