summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.defaults22
-rw-r--r--Makefile.sources4
-rwxr-xr-xamiga/gui.c6
-rwxr-xr-xatari/gui.c6
-rw-r--r--beos/beos_gui.cpp6
-rw-r--r--cocoa/gui.m6
-rw-r--r--content/fetch.c2
-rw-r--r--content/fetchers/about.c44
-rw-r--r--content/fetchers/resource.c277
-rw-r--r--content/fetchers/resource.h38
-rw-r--r--content/llcache.c25
-rw-r--r--framebuffer/Makefile.target1
-rw-r--r--framebuffer/filetype.c2
-rw-r--r--framebuffer/findfile.c97
-rw-r--r--framebuffer/findfile.h10
-rw-r--r--framebuffer/font_freetype.c7
-rw-r--r--framebuffer/gui.c38
-rw-r--r--gtk/filetype.c6
-rw-r--r--gtk/gui.c183
-rw-r--r--riscos/gui.c6
-rw-r--r--utils/resource.c (renamed from utils/findresource.c)136
-rw-r--r--utils/resource.h (renamed from utils/findresource.h)41
-rw-r--r--windows/gui.c6
23 files changed, 663 insertions, 306 deletions
diff --git a/Makefile.defaults b/Makefile.defaults
index 44ad6fbf8..6722494d1 100644
--- a/Makefile.defaults
+++ b/Makefile.defaults
@@ -253,16 +253,18 @@ ifeq ($(TARGET),framebuffer)
NETSURF_FB_FONTLIB := internal
# freetype compiled in font locations
- NETSURF_FB_FONT_SANS_SERIF := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf
- NETSURF_FB_FONT_SANS_SERIF_BOLD := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf
- NETSURF_FB_FONT_SANS_SERIF_ITALIC := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Oblique.ttf
- NETSURF_FB_FONT_SANS_SERIF_ITALIC_BOLD := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-BoldOblique.ttf
- NETSURF_FB_FONT_SERIF := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf
- NETSURF_FB_FONT_SERIF_BOLD := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf
- NETSURF_FB_FONT_MONOSPACE := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf
- NETSURF_FB_FONT_MONOSPACE_BOLD := /usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono-Bold.ttf
- NETSURF_FB_FONT_CURSIVE := /usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf
- NETSURF_FB_FONT_FANTASY := /usr/share/fonts/truetype/msttcorefonts/Impact.ttf
+ NETSURF_FB_FONTPATH := /usr/share/fonts/truetype/ttf-dejavu:/usr/share/fonts/truetype/msttcorefonts
+
+ NETSURF_FB_FONT_SANS_SERIF := DejaVuSans.ttf
+ NETSURF_FB_FONT_SANS_SERIF_BOLD := DejaVuSans-Bold.ttf
+ NETSURF_FB_FONT_SANS_SERIF_ITALIC := DejaVuSans-Oblique.ttf
+ NETSURF_FB_FONT_SANS_SERIF_ITALIC_BOLD := DejaVuSans-BoldOblique.ttf
+ NETSURF_FB_FONT_SERIF := DejaVuSerif.ttf
+ NETSURF_FB_FONT_SERIF_BOLD := DejaVuSerif-Bold.ttf
+ NETSURF_FB_FONT_MONOSPACE := DejaVuSansMono.ttf
+ NETSURF_FB_FONT_MONOSPACE_BOLD := DejaVuSansMono-Bold.ttf
+ NETSURF_FB_FONT_CURSIVE := Comic_Sans_MS.ttf
+ NETSURF_FB_FONT_FANTASY := Impact.ttf
# Framebuffer frontends may have differing root paths for resources
# As such, these specify the resource path and config path.
diff --git a/Makefile.sources b/Makefile.sources
index 6ca7cfcab..3b9e11368 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -6,7 +6,7 @@
S_CONTENT := content.c dirlist.c fetch.c hlcache.c llcache.c urldb.c
-S_FETCHERS := curl.c data.c file.c about.c
+S_FETCHERS := curl.c data.c file.c about.c resource.c
S_CSS := css.c dump.c internal.c select.c utils.c
@@ -15,7 +15,7 @@ S_RENDER := box.c box_construct.c box_normalise.c favicon.c \
hubbub_binding.c imagemap.c layout.c list.c table.c textplain.c
S_UTILS := base64.c filename.c hashtable.c http.c locale.c messages.c \
- talloc.c url.c utf8.c utils.c useragent.c findresource.c log.c
+ talloc.c url.c utf8.c utils.c useragent.c resource.c log.c
S_DESKTOP := cookies.c history_global_core.c hotlist.c knockout.c \
mouse.c options.c plot_style.c print.c search.c searchweb.c \
diff --git a/amiga/gui.c b/amiga/gui.c
index c3d1d8647..f95e2b981 100755
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -34,6 +34,7 @@
#include "utils/utf8.h"
#include "utils/utils.h"
#include "utils/url.h"
+#include "content/fetchers/resource.h"
/* NetSurf Amiga platform includes */
#include "amiga/arexx.h"
@@ -412,6 +413,11 @@ void ami_amiupdate(void)
/* end Amiupdate */
}
+char* gui_find_resource(const char *filename)
+{
+ return NULL;
+}
+
void gui_init(int argc, char** argv)
{
BPTR lock = 0;
diff --git a/atari/gui.c b/atari/gui.c
index b8cfdbe0e..e52965ffb 100755
--- a/atari/gui.c
+++ b/atari/gui.c
@@ -34,6 +34,7 @@
#include "content/urldb.h"
#include "content/fetch.h"
+#include "content/fetchers/resource.h"
#include "css/utils.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
@@ -1056,6 +1057,11 @@ static inline void create_cursor(int flags, short mode, void * form, MFORM_EX *
}
}
+char* gui_find_resource(const char *filename)
+{
+ return NULL;
+}
+
static void gui_init(int argc, char** argv)
{
char buf[PATH_MAX], sbuf[PATH_MAX];
diff --git a/beos/beos_gui.cpp b/beos/beos_gui.cpp
index b757c9790..2317b0b0d 100644
--- a/beos/beos_gui.cpp
+++ b/beos/beos_gui.cpp
@@ -46,6 +46,7 @@ extern "C" {
#include "content/content_protected.h"
#include "content/fetch.h"
#include "content/fetchers/curl.h"
+#include "content/fetchers/resource.h"
#include "content/urldb.h"
#include "desktop/401login.h"
#include "desktop/browser.h"
@@ -421,6 +422,11 @@ static int32 bapp_thread(void *arg)
return 0;
}
+char* gui_find_resource(const char *filename)
+{
+ return NULL;
+}
+
static void gui_init2(int argc, char** argv)
{
CALLED();
diff --git a/cocoa/gui.m b/cocoa/gui.m
index 0acd6bcc4..3a10b9143 100644
--- a/cocoa/gui.m
+++ b/cocoa/gui.m
@@ -34,6 +34,7 @@
#import "desktop/401login.h"
#import "utils/utils.h"
#import "image/ico.h"
+#import "content/fetchers/resource.h"
char *default_stylesheet_url;
char *adblock_stylesheet_url;
@@ -49,6 +50,11 @@ NSString * const kAlwaysCloseMultipleTabs = @"AlwaysCloseMultipleTabs";
#define UNIMPL() NSLog( @"Function '%s' unimplemented", __func__ )
+char* gui_find_resource(const char *filename)
+{
+ return NULL;
+}
+
void gui_multitask(void)
{
// nothing to do
diff --git a/content/fetch.c b/content/fetch.c
index a848e17fa..e521ca2fc 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -38,6 +38,7 @@
#include "utils/config.h"
#include "content/fetch.h"
+#include "content/fetchers/resource.h"
#include "content/fetchers/about.h"
#include "content/fetchers/curl.h"
#include "content/fetchers/data.h"
@@ -112,6 +113,7 @@ void fetch_init(void)
fetch_curl_register();
fetch_data_register();
fetch_file_register();
+ fetch_resource_register();
fetch_about_register();
fetch_active = false;
}
diff --git a/content/fetchers/about.c b/content/fetchers/about.c
index 8ed112200..c4a376a29 100644
--- a/content/fetchers/about.c
+++ b/content/fetchers/about.c
@@ -127,52 +127,16 @@ fetch_about_blank_handler_aborted:
return false;
}
-static const char *authors[] = {
- "John-Mark Bell", "James Bursa", "Michael Drake",
- "Rob Kendrick", "Adrian Lees", "Vincent Sanders",
- "Daniel Silverstone", "Richard Wilson", NULL
-};
static bool fetch_about_credits_handler(struct fetch_about_context *ctx)
{
- char buffer[4096];
- int code = 200;
- int slen;
- int auth_loop = 0;
-
- /* content is going to return ok */
- fetch_set_http_code(ctx->fetchh, code);
+ /* content is going to return redirect */
+ fetch_set_http_code(ctx->fetchh, 302);
- /* content type */
- if (fetch_about_send_header(ctx, "Content-Type: text/html"))
- goto fetch_about_credits_handler_aborted;
-
- slen = snprintf(buffer, sizeof buffer,
- "<html><head><title>NetSurf Browser Credits</title></head>"
- "<body><h1>NetSurf Browser Credits</h1>"
- "<p>Authors</p>"
- "<ul>");
-
- while (authors[auth_loop] != NULL) {
- slen += snprintf(buffer + slen, sizeof buffer - slen,
- "<li>%s</li>", authors[auth_loop]);
- auth_loop++;
- }
-
- slen += snprintf(buffer + slen, sizeof buffer - slen,
- "</ul></body></html>");
-
- if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
- FETCH_ERROR_NO_ERROR))
- goto fetch_about_credits_handler_aborted;
-
- fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
- FETCH_ERROR_NO_ERROR);
+ fetch_about_send_callback(FETCH_REDIRECT, ctx, "resource:credits.html",
+ 0, FETCH_ERROR_NO_ERROR);
return true;
-
-fetch_about_credits_handler_aborted:
- return false;
}
static bool fetch_about_config_handler(struct fetch_about_context *ctx)
diff --git a/content/fetchers/resource.c b/content/fetchers/resource.c
new file mode 100644
index 000000000..2818305d0
--- /dev/null
+++ b/content/fetchers/resource.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2011 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* resource: URL handling. Based on the data fetcher by Rob Kendrick */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#include "utils/config.h"
+#include "content/dirlist.h"
+#include "content/fetch.h"
+#include "content/fetchers/resource.h"
+#include "content/urldb.h"
+#include "desktop/netsurf.h"
+#include "desktop/options.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/url.h"
+#include "utils/utils.h"
+#include "utils/ring.h"
+
+struct fetch_resource_context;
+
+typedef bool (*fetch_resource_handler)(struct fetch_resource_context *);
+
+/** Context for an resource fetch */
+struct fetch_resource_context {
+ struct fetch_resource_context *r_next, *r_prev;
+
+ struct fetch *fetchh; /**< Handle for this fetch */
+
+ bool aborted; /**< Flag indicating fetch has been aborted */
+ bool locked; /**< Flag indicating entry is already entered */
+
+ char *url;
+ char *redirect_url; /**< The url the fetch redirects to */
+
+ fetch_resource_handler handler;
+};
+
+static struct fetch_resource_context *ring = NULL;
+
+/** issue fetch callbacks with locking */
+static inline bool fetch_resource_send_callback(fetch_msg msg,
+ struct fetch_resource_context *ctx, const void *data,
+ unsigned long size, fetch_error_code errorcode)
+{
+ ctx->locked = true;
+ fetch_send_callback(msg, ctx->fetchh, data, size, errorcode);
+ ctx->locked = false;
+
+ return ctx->aborted;
+}
+
+static bool fetch_resource_send_header(struct fetch_resource_context *ctx,
+ const char *fmt, ...)
+{
+ char header[64];
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ vsnprintf(header, sizeof header, fmt, ap);
+
+ va_end(ap);
+
+ fetch_resource_send_callback(FETCH_HEADER, ctx, header, strlen(header),
+ FETCH_ERROR_NO_ERROR);
+
+ return ctx->aborted;
+}
+
+
+
+
+static bool fetch_resource_redirect_handler(struct fetch_resource_context *ctx)
+{
+ /* content is going to return redirect */
+ fetch_set_http_code(ctx->fetchh, 302);
+
+ fetch_resource_send_callback(FETCH_REDIRECT, ctx, ctx->redirect_url, 0,
+ FETCH_ERROR_NO_ERROR);
+
+ return true;
+}
+
+
+static bool fetch_resource_notfound_handler(struct fetch_resource_context *ctx)
+{
+ int code = 404;
+ char buffer[1024];
+ const char *title;
+ char key[8];
+
+ /* content is going to return error code */
+ fetch_set_http_code(ctx->fetchh, code);
+
+ /* content type */
+ if (fetch_resource_send_header(ctx, "Content-Type: text/html"))
+ goto fetch_resource_notfound_handler_aborted;
+
+ snprintf(key, sizeof key, "HTTP%03d", code);
+ title = messages_get(key);
+
+ snprintf(buffer, sizeof buffer, "<html><head><title>%s</title></head>"
+ "<body><h1>%s</h1>"
+ "<p>Error %d while fetching file %s</p></body></html>",
+ title, title, code, ctx->url);
+
+ if (fetch_resource_send_callback(FETCH_DATA, ctx, buffer, strlen(buffer),
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_resource_notfound_handler_aborted;
+
+ fetch_resource_send_callback(FETCH_FINISHED, ctx, 0, 0,
+ FETCH_ERROR_NO_ERROR);
+
+fetch_resource_notfound_handler_aborted:
+ return false;
+}
+
+
+
+/** callback to initialise the resource fetcher. */
+static bool fetch_resource_initialise(const char *scheme)
+{
+ return true;
+}
+
+/** callback to initialise the resource fetcher. */
+static void fetch_resource_finalise(const char *scheme)
+{
+}
+
+/** callback to set up a resource fetch context. */
+static void *
+fetch_resource_setup(struct fetch *fetchh,
+ const char *url,
+ bool only_2xx,
+ const char *post_urlenc,
+ const struct fetch_multipart_data *post_multipart,
+ const char **headers)
+{
+ struct fetch_resource_context *ctx;
+ struct url_components urlcomp;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ return NULL;
+
+ url_get_components(url, &urlcomp);
+
+ ctx->redirect_url = gui_find_resource(urlcomp.path);
+ if (ctx->redirect_url == NULL) {
+ ctx->handler = fetch_resource_notfound_handler;
+ } else {
+ ctx->handler = fetch_resource_redirect_handler;
+ }
+
+ ctx->url = strdup(url);
+
+ url_destroy_components(&urlcomp);
+
+ ctx->fetchh = fetchh;
+
+ RING_INSERT(ring, ctx);
+
+ return ctx;
+}
+
+/** callback to free a resource fetch */
+static void fetch_resource_free(void *ctx)
+{
+ struct fetch_resource_context *c = ctx;
+ free(c->redirect_url);
+ free(c->url);
+ RING_REMOVE(ring, c);
+ free(ctx);
+}
+
+/** callback to start a resource fetch */
+static bool fetch_resource_start(void *ctx)
+{
+ return true;
+}
+
+/** callback to abort a resource fetch */
+static void fetch_resource_abort(void *ctx)
+{
+ struct fetch_resource_context *c = ctx;
+
+ /* To avoid the poll loop having to deal with the fetch context
+ * disappearing from under it, we simply flag the abort here.
+ * The poll loop itself will perform the appropriate cleanup.
+ */
+ c->aborted = true;
+}
+
+
+/** callback to poll for additional resource fetch contents */
+static void fetch_resource_poll(const char *scheme)
+{
+ struct fetch_resource_context *c, *next;
+
+ if (ring == NULL) return;
+
+ /* Iterate over ring, processing each pending fetch */
+ c = ring;
+ do {
+ /* Take a copy of the next pointer as we may destroy
+ * the ring item we're currently processing */
+ next = c->r_next;
+
+ /* Ignore fetches that have been flagged as locked.
+ * This allows safe re-entrant calls to this function.
+ * Re-entrancy can occur if, as a result of a callback,
+ * the interested party causes fetch_poll() to be called
+ * again.
+ */
+ if (c->locked == true) {
+ continue;
+ }
+
+ /* Only process non-aborted fetches */
+ if (c->aborted == false) {
+ /* resource fetches can be processed in one go */
+ c->handler(c);
+ }
+
+
+ fetch_remove_from_queues(c->fetchh);
+ fetch_free(c->fetchh);
+
+ /* Advance to next ring entry, exiting if we've reached
+ * the start of the ring or the ring has become empty
+ */
+ } while ( (c = next) != ring && ring != NULL);
+}
+
+void fetch_resource_register(void)
+{
+ fetch_add_fetcher("resource",
+ fetch_resource_initialise,
+ fetch_resource_setup,
+ fetch_resource_start,
+ fetch_resource_abort,
+ fetch_resource_free,
+ fetch_resource_poll,
+ fetch_resource_finalise);
+}
diff --git a/content/fetchers/resource.h b/content/fetchers/resource.h
new file mode 100644
index 000000000..6c590d390
--- /dev/null
+++ b/content/fetchers/resource.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * resource: URL method handler
+ */
+
+#ifndef NETSURF_CONTENT_FETCHERS_FETCH_RESOURCE_H
+#define NETSURF_CONTENT_FETCHERS_FETCH_RESOURCE_H
+
+/**
+ * register the resource scheme.
+ *
+ * should only be called from the fetch initialise
+ */
+void fetch_resource_register(void);
+
+/**
+ * callback to translate resource to full url
+ */
+char* gui_find_resource(const char *filename);
+
+#endif
diff --git a/content/llcache.c b/content/llcache.c
index 64e37915a..a7c8cbe06 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1952,6 +1952,7 @@ nserror llcache_fetch_redirect(llcache_object *object, const char *target,
const llcache_post_data *post = object->fetch.post;
char *url, *absurl;
char *scheme;
+ char *object_scheme;
url_func_result result;
/* Extract HTTP response code from the fetch object */
long http_code = fetch_http_code(object->fetch.fetch);
@@ -1999,20 +2000,34 @@ nserror llcache_fetch_redirect(llcache_object *object, const char *target,
return NSERROR_NOMEM;
}
- /* Ensure that redirects to file:/// don't happen */
- result = url_scheme(url, &scheme);
+ /* Ensure that redirects to file:/// only happen for valid schemes */
+ result = url_scheme(object->url, &object_scheme);
if (result != URL_FUNC_OK) {
free(url);
return NSERROR_NOMEM;
}
- if (strcasecmp(scheme, "file") == 0) {
- free(scheme);
+ result = url_scheme(url, &scheme);
+ if (result != URL_FUNC_OK) {
free(url);
- return NSERROR_OK;
+ return NSERROR_NOMEM;
+ }
+
+ /* resource is allowed to redirect anywhere */
+ if ((strcasecmp(object_scheme, "resource") != 0) &&
+ (strcasecmp(object_scheme, "about") != 0)) {
+ /* file, about and resource are not valid redirect targets */
+ if ((strcasecmp(scheme, "file") == 0) ||
+ (strcasecmp(scheme, "about") == 0) ||
+ (strcasecmp(scheme, "resource") == 0)) {
+ free(scheme);
+ free(url);
+ return NSERROR_OK;
+ }
}
free(scheme);
+ free(object_scheme);
/* Bail out if we've no way of handling this URL */
if (fetch_can_fetch(url) == false) {
diff --git a/framebuffer/Makefile.target b/framebuffer/Makefile.target
index e9dd8a883..98c6427df 100644
--- a/framebuffer/Makefile.target
+++ b/framebuffer/Makefile.target
@@ -24,6 +24,7 @@ CFLAGS += -Dnsframebuffer
CFLAGS += '-DNETSURF_FB_RESPATH="$(NETSURF_FB_RESPATH_$(NETSURF_FB_FRONTEND))"'
# compile time font locations
+CFLAGS += '-DNETSURF_FB_FONTPATH="$(NETSURF_FB_FONTPATH)"'
CFLAGS += '-DNETSURF_FB_FONT_SANS_SERIF="$(NETSURF_FB_FONT_SANS_SERIF)"'
CFLAGS += '-DNETSURF_FB_FONT_SANS_SERIF_BOLD="$(NETSURF_FB_FONT_SANS_SERIF_BOLD)"'
CFLAGS += '-DNETSURF_FB_FONT_SANS_SERIF_ITALIC="$(NETSURF_FB_FONT_SANS_SERIF_ITALIC)"'
diff --git a/framebuffer/filetype.c b/framebuffer/filetype.c
index d15890ce4..4b303e5f1 100644
--- a/framebuffer/filetype.c
+++ b/framebuffer/filetype.c
@@ -33,6 +33,8 @@ const char *fetch_filetype(const char *unix_path)
l = strlen(unix_path);
if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0)
return "text/css";
+ if (2 < l && strcasecmp(unix_path + l - 3, "f79") == 0)
+ return "text/css";
if (2 < l && strcasecmp(unix_path + l - 3, "jpg") == 0)
return "image/jpeg";
if (3 < l && strcasecmp(unix_path + l - 4, "jpeg") == 0)
diff --git a/framebuffer/findfile.c b/framebuffer/findfile.c
index caa910005..130804eed 100644
--- a/framebuffer/findfile.c
+++ b/framebuffer/findfile.c
@@ -27,9 +27,45 @@
#include "utils/log.h"
#include "utils/url.h"
+#include "utils/resource.h"
+#include "content/fetchers/resource.h"
#include "framebuffer/findfile.h"
+char **respaths; /** resource search path vector */
+
+/** Create an array of valid paths to search for resources.
+ *
+ * The idea is that all the complex path computation to find resources
+ * is performed here, once, rather than every time a resource is
+ * searched for.
+ */
+char **
+fb_init_resource(const char *resource_path)
+{
+ char **pathv; /* resource path string vector */
+ char **respath; /* resource paths vector */
+ const char *lang = NULL;
+ char *foo;
+ int bar=0;
+ fprintf(stderr, "fb_init_resource:%s\n",resource_path);
+
+ pathv = resource_path_to_strvec(resource_path);
+
+ respath = resource_generate(pathv, &lang);
+
+ resource_free_strvec(pathv);
+
+ foo = respath[bar];
+ while (foo != NULL) {
+ fprintf(stderr, "%s\n",foo);
+ bar++;
+ foo = respath[bar];
+ }
+ return respath;
+}
+
+
char *path_to_url(const char *path)
{
int urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1;
@@ -65,67 +101,12 @@ char *url_to_path(const char *url)
return respath;
}
-/**
- * Locate a shared resource file by searching known places in order.
- *
- * \param buf buffer to write to. must be at least PATH_MAX chars
- * \param filename file to look for
- * \param def default to return if file not found
- * \return buf
- *
- * Search order is: ~/.netsurf/, $NETSURFRES/ (where NETSURFRES is an
- * environment variable), and finally the path specified by NETSURF_FB_RESPATH
- * from the Makefile
- */
-
-char *fb_find_resource(char *buf, const char *filename, const char *def)
+char* gui_find_resource(const char *filename)
{
- char *cdir = getenv("HOME");
- char t[PATH_MAX];
-
- if (cdir != NULL) {
- strcpy(t, cdir);
- strcat(t, "/.netsurf/");
- strcat(t, filename);
- if (realpath(t, buf) != NULL) {
- if (access(buf, R_OK) == 0)
- return buf;
- }
- }
-
- cdir = getenv("NETSURFRES");
-
- if (cdir != NULL) {
- if (realpath(cdir, buf) != NULL) {
- strcat(buf, "/");
- strcat(buf, filename);
- if (access(buf, R_OK) == 0)
- return buf;
- }
- }
-
- strcpy(t, NETSURF_FB_RESPATH);
- strcat(t, filename);
- if (realpath(t, buf) != NULL) {
- if (access(buf, R_OK) == 0)
- return buf;
- }
-
- if (def[0] == '~') {
- snprintf(t, PATH_MAX, "%s%s", getenv("HOME"), def + 1);
- if (realpath(t, buf) == NULL) {
- strcpy(buf, t);
- }
- } else {
- if (realpath(def, buf) == NULL) {
- strcpy(buf, def);
- }
- }
-
- return buf;
+ char buf[PATH_MAX];
+ return path_to_url(resource_sfind(respaths, buf, filename));
}
-
/*
* Local Variables:
* c-basic-offset: 8
diff --git a/framebuffer/findfile.h b/framebuffer/findfile.h
index 85a2f7074..1f3db6eb1 100644
--- a/framebuffer/findfile.h
+++ b/framebuffer/findfile.h
@@ -19,6 +19,14 @@
#ifndef NETSURF_FB_FINDFILE_H
#define NETSURF_FB_FINDFILE_H
-extern char *fb_find_resource(char *buf, const char *filename, const char *def);
+extern char **respaths;
+
+/** Create an array of valid paths to search for resources.
+ *
+ * The idea is that all the complex path computation to find resources
+ * is performed here, once, rather than every time a resource is
+ * searched for.
+ */
+char **fb_init_resource(const char *resource_path);
#endif /* NETSURF_FB_FINDFILE_H */
diff --git a/framebuffer/font_freetype.c b/framebuffer/font_freetype.c
index ea183ea4b..44d6701dc 100644
--- a/framebuffer/font_freetype.c
+++ b/framebuffer/font_freetype.c
@@ -27,6 +27,7 @@
#include "render/font.h"
#include "utils/utf8.h"
#include "utils/log.h"
+#include "utils/resource.h"
#include "desktop/options.h"
#include "framebuffer/gui.h"
@@ -112,7 +113,7 @@ static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Po
/* create new framebuffer face and cause it to be loaded to check its ok */
static fb_faceid_t *
-fb_new_face(const char *option, const char *resname, const char *fontfile)
+fb_new_face(const char *option, const char *resname, const char *fontname)
{
fb_faceid_t *newf;
FT_Error error;
@@ -124,13 +125,13 @@ fb_new_face(const char *option, const char *resname, const char *fontfile)
if (option != NULL) {
newf->fontfile = strdup(option);
} else {
- fb_find_resource(buf, resname, fontfile);
+ resource_sfind(respaths, buf, fontname);
newf->fontfile = strdup(buf);
}
error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface);
if (error) {
- LOG(("Could not find font face %s (code %d)\n", fontfile, error));
+ LOG(("Could not find font face %s (code %d)\n", fontname, error));
free(newf);
newf = NULL;
}
diff --git a/framebuffer/gui.c b/framebuffer/gui.c
index 6cec4e7fa..abdb0ed9e 100644
--- a/framebuffer/gui.c
+++ b/framebuffer/gui.c
@@ -37,6 +37,7 @@
#include "desktop/netsurf.h"
#include "desktop/options.h"
#include "desktop/shape.h"
+#include "utils/resource.h"
#include "utils/log.h"
#include "utils/url.h"
#include "utils/messages.h"
@@ -63,7 +64,6 @@
char *default_stylesheet_url;
char *quirks_stylesheet_url;
char *adblock_stylesheet_url;
-char *options_file_location;
fbtk_widget_t *fbtk;
@@ -435,33 +435,31 @@ process_cmdline(int argc, char** argv)
return true;
}
-
static void
gui_init(int argc, char** argv)
{
- char buf[PATH_MAX];
nsfb_t *nsfb;
option_core_select_menu = true;
/* set up stylesheet urls */
- fb_find_resource(buf, "default.css", "./framebuffer/res/default.css");
- default_stylesheet_url = path_to_url(buf);
+ default_stylesheet_url = strdup("resource:default.css");
LOG(("Using '%s' as Default CSS URL", default_stylesheet_url));
- fb_find_resource(buf, "quirks.css", "./framebuffer/res/quirks.css");
- quirks_stylesheet_url = path_to_url(buf);
+ quirks_stylesheet_url = strdup("resource:quirks.css");
+ LOG(("Using '%s' as quirks CSS URL", quirks_stylesheet_url));
+
+ adblock_stylesheet_url = strdup("resource:adblock.css");
+ LOG(("Using '%s' as AdBlock CSS URL", adblock_stylesheet_url));
if (option_cookie_file == NULL) {
- fb_find_resource(buf, "Cookies", "~/.netsurf/Cookies");
- LOG(("Using '%s' as Cookies file", buf));
- option_cookie_file = strdup(buf);
+ option_cookie_file = resource_find(respaths, "Cookies");
+ LOG(("Using '%s' as Cookies file", option_cookie_file));
}
if (option_cookie_jar == NULL) {
- fb_find_resource(buf, "Cookies", "~/.netsurf/Cookies");
- LOG(("Using '%s' as Cookie Jar file", buf));
- option_cookie_jar = strdup(buf);
+ option_cookie_jar = resource_find(respaths, "Cookies");
+ LOG(("Using '%s' as Cookie Jar file", option_cookie_jar));
}
if (option_cookie_file == NULL || option_cookie_jar == NULL)
@@ -496,17 +494,21 @@ int
main(int argc, char** argv)
{
struct browser_window *bw;
- char options[PATH_MAX];
- char messages[PATH_MAX];
+ char *options;
+ char *messages;
setbuf(stderr, NULL);
- fb_find_resource(messages, "messages", "./framebuffer/res/messages");
- fb_find_resource(options, "Choices-fb", "~/.netsurf/Choices-fb");
- options_file_location = strdup(options);
+ respaths = fb_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"NETSURF_FB_RESPATH":./framebuffer/res:"NETSURF_FB_FONTPATH);
+
+ options = resource_find(respaths, "Choices");
+ messages = resource_find(respaths, "messages");
netsurf_init(&argc, &argv, options, messages);
+ free(messages);
+ free(options);
+
gui_init(argc, argv);
LOG(("calling browser_window_create"));
diff --git a/gtk/filetype.c b/gtk/filetype.c
index b172f5191..f89f2358c 100644
--- a/gtk/filetype.c
+++ b/gtk/filetype.c
@@ -155,11 +155,17 @@ const char *fetch_filetype(const char *unix_path)
const char *ptr;
char *lowerchar;
const char *type;
+ int l;
stat(unix_path, &statbuf);
if (S_ISDIR(statbuf.st_mode))
return "application/x-netsurf-directory";
+ l = strlen(unix_path);
+ if ((3 < l) && (strcasecmp(unix_path + l - 4, ",f79") == 0)) {
+ return "text/css";
+ }
+
if (strchr(unix_path, '.') == NULL) {
/* no extension anywhere! */
return "text/plain";
diff --git a/gtk/gui.c b/gtk/gui.c
index fd2116f21..ce2b4f3bd 100644
--- a/gtk/gui.c
+++ b/gtk/gui.c
@@ -43,6 +43,7 @@
#include "content/content.h"
#include "content/fetch.h"
#include "content/fetchers/curl.h"
+#include "content/fetchers/resource.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "desktop/browser.h"
@@ -78,7 +79,7 @@
#include "utils/url.h"
#include "utils/utf8.h"
#include "utils/utils.h"
-#include "utils/findresource.h"
+#include "utils/resource.h"
char *default_stylesheet_url;
char *quirks_stylesheet_url;
@@ -122,101 +123,7 @@ static void nsgtk_PDF_no_pass(GtkButton *w, gpointer data);
#define THROBBER_FRAMES 9
-#define MAX_RESPATH 128 /* maximum number of elements in the resource vector */
-
-/* expand ${} in a string into environment variables */
-static char *
-expand_path(const char *path)
-{
- char *exp = strdup(path);
- int explen;
- int cstart = -1;
- int cloop = 0;
- char *envv;
- int envlen;
- int replen; /* length of replacement */
-
- if (exp == NULL)
- return NULL;
-
- explen = strlen(exp) + 1;
-
- while (exp[cloop] != 0) {
- if ((exp[cloop] == '$') &&
- (exp[cloop + 1] == '{')) {
- cstart = cloop;
- cloop++;
- }
-
- if ((cstart != -1) &&
- (exp[cloop] == '}')) {
- replen = cloop - cstart;
- exp[cloop] = 0;
- envv = getenv(exp + cstart + 2);
- if (envv == NULL) {
- memmove(exp + cstart,
- exp + cloop + 1,
- explen - cloop - 1);
- explen -= replen;
- } else {
- envlen = strlen(envv);
- exp = realloc(exp, explen + envlen - replen);
- memmove(exp + cstart + envlen,
- exp + cloop + 1,
- explen - cloop - 1);
- memmove(exp + cstart, envv, envlen);
- explen += envlen - replen;
- }
- cloop -= replen;
- cstart = -1;
- }
-
- cloop++;
- }
-
- return exp;
-}
-
-/* convert a colon separated list of path elements into a string vector */
-static char **
-path_to_strvec(const char *path)
-{
- char **strvec;
- int strc = 0;
-
- strvec = calloc(MAX_RESPATH, sizeof(char *));
- if (strvec == NULL)
- return NULL;
-
- strvec[strc] = expand_path(path);
- if (strvec[strc] == NULL) {
- free(strvec);
- return NULL;
- }
- strc++;
-
- strvec[strc] = strchr(strvec[0], ':');
- while ((strc < (MAX_RESPATH - 2)) &&
- (strvec[strc] != NULL)) {
- /* null terminate previous entry */
- *strvec[strc] = 0;
- strvec[strc]++;
-
- /* skip colons */
- while (*strvec[strc] == ':')
- strvec[strc]++;
-
- if (*strvec[strc] == 0)
- break; /* string is terminated */
-
- strc++;
-
- strvec[strc] = strchr(strvec[strc - 1], ':');
- }
-
- return strvec;
-}
-
+char **respaths; /** resource search path vector */
/** Create an array of valid paths to search for resources.
*
@@ -231,14 +138,13 @@ nsgtk_init_resource(const char *resource_path)
char **pathv; /* resource path string vector */
char **respath; /* resource paths vector */
- pathv = path_to_strvec(resource_path);
+ pathv = resource_path_to_strvec(resource_path);
langv = g_get_language_names();
- respath = findresource_generate(pathv, langv);
+ respath = resource_generate(pathv, langv);
- free(pathv[0]);
- free(pathv);
+ resource_free_strvec(pathv);
return respath;
}
@@ -259,7 +165,7 @@ static bool nsgtk_throbber_init(char **respath, int framec)
for (frame_num = 0; frame_num < framec; frame_num++) {
snprintf(targetname, PATH_MAX, "throbber/throbber%d.png", frame_num);
- filenames[frame_num] = findresource(respath, targetname);
+ filenames[frame_num] = resource_find(respath, targetname);
}
ret = nsgtk_throbber_initialise_from_png(frame_num, filenames);
@@ -285,7 +191,7 @@ nsgtk_new_glade(char **respath, const char *name, GladeXML **pglade)
snprintf(resname, PATH_MAX, "%s.glade", name);
- filepath = findresource(respath, resname);
+ filepath = resource_find(respath, resname);
if (filepath == NULL) {
snprintf(errorstr, NEW_GLADE_ERROR_SIZE,
"Unable to locate %s glade template file.\n", name);
@@ -362,12 +268,12 @@ static void check_options(char **respath)
* values!
*/
if (!option_cookie_file) {
- sfindresourcedef(respath, buf, "Cookies", "~/.netsurf/");
+ resource_sfinddef(respath, buf, "Cookies", "~/.netsurf/");
LOG(("Using '%s' as Cookies file", buf));
option_cookie_file = strdup(buf);
}
if (!option_cookie_jar) {
- sfindresourcedef(respath, buf, "Cookies", "~/.netsurf/");
+ resource_sfinddef(respath, buf, "Cookies", "~/.netsurf/");
LOG(("Using '%s' as Cookie Jar file", buf));
option_cookie_jar = strdup(buf);
}
@@ -375,13 +281,13 @@ static void check_options(char **respath)
die("Failed initialising cookie options");
if (!option_url_file) {
- sfindresourcedef(respath, buf, "URLs", "~/.netsurf/");
+ resource_sfinddef(respath, buf, "URLs", "~/.netsurf/");
LOG(("Using '%s' as URL file", buf));
option_url_file = strdup(buf);
}
if (!option_ca_path) {
- sfindresourcedef(respath, buf, "certs", "/etc/ssl/");
+ resource_sfinddef(respath, buf, "certs", "/etc/ssl/");
LOG(("Using '%s' as certificate path", buf));
option_ca_path = strdup(buf);
}
@@ -391,12 +297,12 @@ static void check_options(char **respath)
option_downloads_directory = hdir;
}
- sfindresourcedef(respath, buf, "icons/", "~/.netsurf/");
+ resource_sfinddef(respath, buf, "icons/", "~/.netsurf/");
LOG(("Using '%s' as Tree icons dir", buf));
tree_set_icon_dir(strdup(buf));
if (!option_hotlist_path) {
- sfindresourcedef(respath, buf, "Hotlist", "~/.netsurf/");
+ resource_sfinddef(respath, buf, "Hotlist", "~/.netsurf/");
LOG(("Using '%s' as Hotlist file", buf));
option_hotlist_path = strdup(buf);
}
@@ -404,7 +310,7 @@ static void check_options(char **respath)
die("Failed initialising hotlist option");
- sfindresourcedef(respath, buf, "Print", "~/.netsurf/");
+ resource_sfinddef(respath, buf, "Print", "~/.netsurf/");
LOG(("Using '%s' as Print Settings file", buf));
print_options_file_location = strdup(buf);
@@ -420,6 +326,13 @@ static void check_options(char **respath)
}
+char* gui_find_resource(const char *filename)
+{
+ char buf[PATH_MAX];
+ return path_to_url(resource_sfind(respaths, buf, filename));
+}
+
+
/**
* Initialize GTK interface.
*/
@@ -440,33 +353,33 @@ static void gui_init(int argc, char** argv, char **respath)
* however these may be translated which breaks things
* relying on res_dir_location.
*/
- resource_filename = findresource(respath, "languages");
+ resource_filename = resource_find(respath, "languages");
resource_filename[strlen(resource_filename) - 9] = 0;
res_dir_location = resource_filename;
/* languages file */
- languages_file_location = findresource(respath, "languages");
+ languages_file_location = resource_find(respath, "languages");
/* initialise the glade templates */
nsgtk_init_glade(respath);
/* set default icon if its available */
- resource_filename = findresource(respath, "netsurf.xpm");
+ resource_filename = resource_find(respath, "netsurf.xpm");
if (resource_filename != NULL) {
gtk_window_set_default_icon_from_file(resource_filename, NULL);
free(resource_filename);
}
/* Search engine sources */
- search_engines_file_location = findresource(respath, "SearchEngines");
+ search_engines_file_location = resource_find(respath, "SearchEngines");
LOG(("Using '%s' as Search Engines file", search_engines_file_location));
/* Default Icon */
- search_default_ico_location = findresource(respath, "default.ico");
+ search_default_ico_location = resource_find(respath, "default.ico");
LOG(("Using '%s' as default search ico", search_default_ico_location));
/* Toolbar inicies file */
- toolbar_indices_file_location = findresource(respath, "toolbarIndices");
+ toolbar_indices_file_location = resource_find(respath, "toolbarIndices");
LOG(("Using '%s' as custom toolbar settings file", toolbar_indices_file_location));
/* load throbber images */
@@ -476,19 +389,17 @@ static void gui_init(int argc, char** argv, char **respath)
/* Initialise completions - cannot fail */
nsgtk_completion_init();
- sfindresourcedef(respath, buf, "mime.types", "/etc/");
+ resource_sfinddef(respath, buf, "mime.types", "/etc/");
gtk_fetch_filetype_init(buf);
/* set up stylesheet urls */
- sfindresourcedef(respath, buf, "gtkdefault.css", "./gtk/res/");
- default_stylesheet_url = path_to_url(buf);
+ default_stylesheet_url = strdup("resource:gtkdefault.css");
LOG(("Using '%s' as Default CSS URL", default_stylesheet_url));
- sfindresourcedef(respath, buf, "quirks.css", "./gtk/res/");
- quirks_stylesheet_url = path_to_url(buf);
+ quirks_stylesheet_url = strdup("resource:quirks.css");
+ LOG(("Using '%s' as quirks CSS URL", quirks_stylesheet_url));
- sfindresourcedef(respath, buf, "adblock.css", "./gtk/res/");
- adblock_stylesheet_url = path_to_url(buf);
+ adblock_stylesheet_url = strdup("resource:adblock.css");
LOG(("Using '%s' as AdBlock CSS URL", adblock_stylesheet_url));
urldb_load(option_url_file);
@@ -560,32 +471,19 @@ int main(int argc, char** argv)
{
char *messages;
char *options;
- char **respaths;
/* check home directory is available */
nsgtk_check_homedir();
respaths = nsgtk_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"GTK_RESPATH":./gtk/res");
- /* Some modern distributions can set ALL_PROXY/all_proxy if configured
- * to by the user. Due to a bug in many versions of libcurl
- * (including the one shipped in Ubuntu 10.04 LTS), this also takes
- * effect on file:// URLs, meaning that NetSurf cannot load its
- * default CSS file. Given all examples of distributions I've checked
- * also set http_proxy and friends, we can safely unset these.
- */
-
- unsetenv("ALL_PROXY");
- unsetenv("all_proxy");
-
gtk_init(&argc, &argv);
/* set standard error to be non-buffering */
setbuf(stderr, NULL);
- options = findresource(respaths, "Choices");
-
- messages = findresource(respaths, "Messages");
+ options = resource_find(respaths, "Choices");
+ messages = resource_find(respaths, "Messages");
netsurf_init(&argc, &argv, options, messages);
@@ -896,9 +794,16 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len,
char *path_to_url(const char *path)
{
- int urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1;
- char *url = malloc(urllen);
+ int urllen;
+ char *url;
+
+ if (path == NULL) {
+ return NULL;
+ }
+
+ urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1;
+ url = malloc(urllen);
if (url == NULL) {
return NULL;
}
diff --git a/riscos/gui.c b/riscos/gui.c
index 8ebbc4fe6..e7ca63741 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -54,6 +54,7 @@
#include "content/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
+#include "content/fetchers/resource.h"
#include "desktop/cookies.h"
#include "desktop/gui.h"
#include "desktop/history_global_core.h"
@@ -278,6 +279,11 @@ static void ro_msg_save_desktop(wimp_message *message);
static void ro_msg_window_info(wimp_message *message);
static void ro_gui_view_source_bounce(wimp_message *message);
+char* gui_find_resource(const char *filename)
+{
+ return NULL;
+}
+
/**
* Initialise the gui (RISC OS specific part).
*/
diff --git a/utils/findresource.c b/utils/resource.c
index cc782682a..80b1c8280 100644
--- a/utils/findresource.c
+++ b/utils/resource.c
@@ -32,12 +32,13 @@
#include <string.h>
#include "utils/config.h"
-#include "utils/findresource.h"
+#include "utils/resource.h"
-#define MAX_RESPATH 128 /* maximum number of elements in the resource vector */
+/** maximum number of elements in the resource vector */
+#define MAX_RESPATH 128
/* exported interface documented in findresource.h */
-char *vsfindfile(char *str, const char *format, va_list ap)
+char *resource_vsfindfile(char *str, const char *format, va_list ap)
{
char *realpathname;
char *pathname;
@@ -73,20 +74,20 @@ char *vsfindfile(char *str, const char *format, va_list ap)
}
/* exported interface documented in findresource.h */
-char *sfindfile(char *str, const char *format, ...)
+char *resource_sfindfile(char *str, const char *format, ...)
{
va_list ap;
char *ret;
va_start(ap, format);
- ret = vsfindfile(str, format, ap);
+ ret = resource_vsfindfile(str, format, ap);
va_end(ap);
return ret;
}
/* exported interface documented in findresource.h */
-char *findfile(const char *format, ...)
+char *resource_findfile(const char *format, ...)
{
char *str;
char *ret;
@@ -97,7 +98,7 @@ char *findfile(const char *format, ...)
return NULL; /* unable to allocate memory */
va_start(ap, format);
- ret = vsfindfile(str, format, ap);
+ ret = resource_vsfindfile(str, format, ap);
va_end(ap);
if (ret == NULL)
@@ -107,7 +108,7 @@ char *findfile(const char *format, ...)
}
/* exported interface documented in findresource.h */
-char *sfindresource(char **respathv, char *filepath, const char *filename)
+char *resource_sfind(char **respathv, char *filepath, const char *filename)
{
int respathc = 0;
@@ -115,7 +116,7 @@ char *sfindresource(char **respathv, char *filepath, const char *filename)
return NULL;
while (respathv[respathc] != NULL) {
- if (sfindfile(filepath, "%s/%s", respathv[respathc], filename) != NULL)
+ if (resource_sfindfile(filepath, "%s/%s", respathv[respathc], filename) != NULL)
return filepath;
respathc++;
@@ -125,7 +126,7 @@ char *sfindresource(char **respathv, char *filepath, const char *filename)
}
/* exported interface documented in findresource.h */
-char *findresource(char **respathv, const char *filename)
+char *resource_find(char **respathv, const char *filename)
{
char *ret;
char *filepath;
@@ -137,7 +138,7 @@ char *findresource(char **respathv, const char *filename)
if (filepath == NULL)
return NULL;
- ret = sfindresource(respathv, filepath, filename);
+ ret = resource_sfind(respathv, filepath, filename);
if (ret == NULL)
free(filepath);
@@ -146,7 +147,7 @@ char *findresource(char **respathv, const char *filename)
}
/* exported interface documented in findresource.h */
-char *sfindresourcedef(char **respathv, char *filepath, const char *filename, const char *def)
+char *resource_sfinddef(char **respathv, char *filepath, const char *filename, const char *def)
{
char t[PATH_MAX];
char *ret;
@@ -154,10 +155,9 @@ char *sfindresourcedef(char **respathv, char *filepath, const char *filename, co
if ((respathv == NULL) || (respathv[0] == NULL) || (filepath == NULL))
return NULL;
- ret = sfindresource(respathv, filepath, filename);
+ ret = resource_sfind(respathv, filepath, filename);
- if ((ret == NULL) &&
- (def != NULL)) {
+ if ((ret == NULL) && (def != NULL)) {
/* search failed, return the path specified */
ret = filepath;
if (def[0] == '~') {
@@ -174,9 +174,9 @@ char *sfindresourcedef(char **respathv, char *filepath, const char *filename, co
}
-/* exported interface documented in findresource.h */
+/* exported interface documented in resource.h */
char **
-findresource_generate(char * const *pathv, const char * const *langv)
+resource_generate(char * const *pathv, const char * const *langv)
{
char **respath; /* resource paths vector */
int pathc = 0;
@@ -193,7 +193,7 @@ findresource_generate(char * const *pathv, const char * const *langv)
/* path element exists and is a directory */
langc = 0;
while (langv[langc] != NULL) {
- snprintf(tmppath, PATH_MAX,"%s/%s",pathv[pathc],langv[langc]);
+ snprintf(tmppath, sizeof tmppath, "%s/%s", pathv[pathc],langv[langc]);
if ((stat(tmppath, &dstat) == 0) &&
S_ISDIR(dstat.st_mode)) {
/* path element exists and is a directory */
@@ -208,3 +208,103 @@ findresource_generate(char * const *pathv, const char * const *langv)
return respath;
}
+
+/* expand ${} in a string into environment variables */
+static char *
+expand_path(const char *path)
+{
+ char *exp = strdup(path);
+ int explen;
+ int cstart = -1;
+ int cloop = 0;
+ char *envv;
+ int envlen;
+ int replen; /* length of replacement */
+
+ if (exp == NULL)
+ return NULL;
+
+ explen = strlen(exp) + 1;
+
+ while (exp[cloop] != 0) {
+ if ((exp[cloop] == '$') &&
+ (exp[cloop + 1] == '{')) {
+ cstart = cloop;
+ cloop++;
+ }
+
+ if ((cstart != -1) &&
+ (exp[cloop] == '}')) {
+ replen = cloop - cstart;
+ exp[cloop] = 0;
+ envv = getenv(exp + cstart + 2);
+ if (envv == NULL) {
+ memmove(exp + cstart,
+ exp + cloop + 1,
+ explen - cloop - 1);
+ explen -= replen;
+ } else {
+ envlen = strlen(envv);
+ exp = realloc(exp, explen + envlen - replen);
+ memmove(exp + cstart + envlen,
+ exp + cloop + 1,
+ explen - cloop - 1);
+ memmove(exp + cstart, envv, envlen);
+ explen += envlen - replen;
+ }
+ cloop -= replen;
+ cstart = -1;
+ }
+
+ cloop++;
+ }
+
+ return exp;
+}
+
+/* exported interface documented in resource.h */
+char **
+resource_path_to_strvec(const char *path)
+{
+ char **strvec;
+ int strc = 0;
+
+ strvec = calloc(MAX_RESPATH, sizeof(char *));
+ if (strvec == NULL)
+ return NULL;
+
+ strvec[strc] = expand_path(path);
+ if (strvec[strc] == NULL) {
+ free(strvec);
+ return NULL;
+ }
+ strc++;
+
+ strvec[strc] = strchr(strvec[0], ':');
+ while ((strc < (MAX_RESPATH - 2)) &&
+ (strvec[strc] != NULL)) {
+ /* null terminate previous entry */
+ *strvec[strc] = 0;
+ strvec[strc]++;
+
+ /* skip colons */
+ while (*strvec[strc] == ':')
+ strvec[strc]++;
+
+ if (*strvec[strc] == 0)
+ break; /* string is terminated */
+
+ strc++;
+
+ strvec[strc] = strchr(strvec[strc - 1], ':');
+ }
+
+ return strvec;
+}
+
+/* exported interface documented in resource.h */
+void resource_free_strvec(char **pathv)
+{
+ free(pathv[0]);
+ free(pathv);
+}
diff --git a/utils/findresource.h b/utils/resource.h
index 9e499f570..ba1ad1535 100644
--- a/utils/findresource.h
+++ b/utils/resource.h
@@ -16,8 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _NETSURF_UTILS_FINDRESOURCE_H_
-#define _NETSURF_UTILS_FINDRESOURCE_H_
+/** \file Utility routines to locate file resources. */
+
+#ifndef _NETSURF_UTILS_RESOURCE_H_
+#define _NETSURF_UTILS_RESOURCE_H_
/** Create a normalised file name.
*
@@ -32,20 +34,20 @@
* @return A pointer to the expanded filename or NULL if the file is
* not present or accessible.
*/
-char *vsfindfile(char *str, const char *format, va_list ap);
+char *resource_vsfindfile(char *str, const char *format, va_list ap);
/** Create a normalised file name.
*
* Similar to vsfindfile but takes variadic (printf like) parameters
*/
-char *sfindfile(char *str, const char *format, ...);
+char *resource_sfindfile(char *str, const char *format, ...);
/** Create a normalised file name.
*
* Similar to sfindfile but allocates its own storage for the
* returned string. The caller must free this sorage.
*/
-char *findfile(const char *format, ...);
+char *resource_findfile(const char *format, ...);
/** Searches an array of resource paths for a file.
*
@@ -58,23 +60,23 @@ char *findfile(const char *format, ...);
* @param filename The filename of the resource to search for.
* @return A pointer to filepath if a target is found or NULL if not.
*/
-char *sfindresource(char **respathv, char *filepath, const char *filename);
+char *resource_sfind(char **respathv, char *filepath, const char *filename);
/** Searches an array of resource paths for a file.
*
- * Similar to sfindresource except it allocates its own storage for
+ * Similar to resource_sfind except it allocates its own storage for
* the returned string. The caller must free this sorage.
*/
-char *findresource(char **respathv, const char *filename);
+char *resource_find(char **respathv, const char *filename);
/** Searches an array of resource paths for a file optionally forcing a default.
*
- * Similar to sfindresource except if no resource is found the default
+ * Similar to resource_sfind except if no resource is found the default
* is used as an additional path element to search, if that still
* fails the returned path is set to the concatination of the default
* path and the filename.
*/
-char *sfindresourcedef(char **respathv, char *filepath, const char *filename, const char *def);
+char *resource_sfinddef(char **respathv, char *filepath, const char *filename, const char *def);
/** Merge two string vectors into a resource search path vector.
*
@@ -83,6 +85,21 @@ char *sfindresourcedef(char **respathv, char *filepath, const char *filename, co
* @return A pointer to a NULL terminated string vector of valid
* resource directories.
*/
-char **findresource_generate(char * const *pathv, const char * const *langv);
+char **resource_generate(char * const *pathv, const char * const *langv);
+
+
+/** Convert a colon separated list of path elements into a string vector.
+ *
+ * @param path A colon separated path.
+ * @return A pointer to a NULL terminated string vector of valid
+ * resource directories.
+ */
+char **resource_path_to_strvec(const char *path);
+
+/** Free a string vector
+ *
+ * Free a string vector allocated by resource_path_to_strvec
+ */
+void resource_free_strvec(char **pathv);
-#endif
+#endif /* _NETSURF_UTILS_RESOURCE_H_ */
diff --git a/windows/gui.c b/windows/gui.c
index 81fb04e26..5a2163453 100644
--- a/windows/gui.c
+++ b/windows/gui.c
@@ -32,6 +32,7 @@
#include "content/urldb.h"
#include "content/fetch.h"
+#include "content/fetchers/resource.h"
#include "css/utils.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
@@ -2558,6 +2559,11 @@ void gui_quit(void)
LOG(("gui_quit"));
}
+char* gui_find_resource(const char *filename)
+{
+ return NULL;
+}
+
static void gui_init(int argc, char** argv)
{
char buf[PATH_MAX], sbuf[PATH_MAX];