/* * Copyright 2004 John M Bell * Copyright 2004-2007 James Bursa * * This file is part of NetSurf, http://www.netsurf-browser.org/ * * NetSurf is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * NetSurf is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** \file * Save HTML document with dependencies (implementation). */ #include "utils/config.h" #define _GNU_SOURCE /* for strndup */ #include #include #include #include #include #include #include #include #include #include "oslib/osfile.h" #include "utils/config.h" #include "content/content.h" #include "css/css.h" #include "render/box.h" #include "riscos/gui.h" #include "riscos/save_complete.h" #include "utils/log.h" #include "utils/url.h" #include "utils/utils.h" regex_t save_complete_import_re; /** An entry in save_complete_list. */ struct save_complete_entry { struct content *content; struct save_complete_entry *next; /**< Next entry in list */ }; /** List of urls seen and saved so far. */ static struct save_complete_entry *save_complete_list = 0; static bool save_complete_html(struct content *c, const char *path, bool index); static bool save_imported_sheets(struct content *c, const char *path); static char * rewrite_stylesheet_urls(const char *source, unsigned int size, int *osize, const char *base); static bool rewrite_document_urls(xmlDoc *doc, const char *base); static bool rewrite_urls(xmlNode *n, const char *base); static bool rewrite_url(xmlNode *n, const char *attr, const char *base); static bool save_complete_list_add(struct content *content); static struct content * save_complete_list_find(const char *url); static bool save_complete_list_check(struct content *content); /* static void save_complete_list_dump(void); */ static bool save_complete_inventory(const char *path); /** * Save an HTML page with all dependencies. * * \param c CONTENT_HTML to save * \param path directory to save to (must exist) * \return true on success, false on error and error reported */ bool save_complete(struct content *c, const char *path) { bool result; result = save_complete_html(c, path, true); if (result) result = save_complete_inventory(path); /* free save_complete_list */ while (save_complete_list) { struct save_complete_entry *next = save_complete_list->next; free(save_complete_list); save_complete_list = next; } return result; } /** * Save an HTML page with all dependencies, recursing through imported pages. * * \param c CONTENT_HTML to save * \param path directory to save to (must exist) * \param index true to save as "index" * \return true on success, false on error and error reported */ bool save_complete_html(struct content *c, const char *path, bool index) { char spath[256]; unsigned int i; xmlDocPtr doc; os_error *error; if (c->type != CONTENT_HTML) return false; if (save_complete_list_check(c)) return true; /* save stylesheets, ignoring the base and adblocking sheets */ for (i = STYLESHEET_STYLE; i != c->data.html.stylesheet_count; i++) { struct content *css = c->data.html.stylesheet_content[i]; char *source; int source_len; if (!css) continue; if (save_complete_list_check(css)) continue; if (i != STYLESHEET_STYLE) { if (!save_complete_list_add(css)) { warn_user("NoMemory", 0); return false; } } if (!save_imported_sheets(css, path)) return false; if (i == STYLESHEET_STYLE) continue; /* don't save