summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2006-07-06 00:07:11 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2006-07-06 00:07:11 +0000
commitbadad073ec99b49288421e99a701f3a61f1fac55 (patch)
tree1ff96c8f43de077f8e40cac272cc587f43f3e834
parent55389c543be402eeca097cde75a68d8b1315b980 (diff)
downloadnetsurf-badad073ec99b49288421e99a701f3a61f1fac55.tar.gz
netsurf-badad073ec99b49288421e99a701f3a61f1fac55.tar.bz2
Generate directory listings (fix 1397934)
svn path=/trunk/netsurf/; revision=2719
-rw-r--r--content/content.c7
-rw-r--r--content/content_type.h1
-rw-r--r--makefile4
-rw-r--r--render/directory.c117
-rw-r--r--render/directory.h24
-rw-r--r--riscos/filetype.c18
-rw-r--r--riscos/gui.c13
7 files changed, 174 insertions, 10 deletions
diff --git a/content/content.c b/content/content.c
index e29990461..68c90a7f0 100644
--- a/content/content.c
+++ b/content/content.c
@@ -25,6 +25,7 @@
#include "netsurf/css/css.h"
#include "netsurf/image/bitmap.h"
#include "netsurf/desktop/options.h"
+#include "netsurf/render/directory.h"
#include "netsurf/render/html.h"
#include "netsurf/render/textplain.h"
#ifdef WITH_JPEG
@@ -89,6 +90,7 @@ static const struct mime_entry mime_map[] = {
#ifdef WITH_BMP
{"application/x-ico", CONTENT_ICO},
#endif
+ {"application/x-netsurf-directory", CONTENT_DIRECTORY},
#ifdef WITH_THEME_INSTALL
{"application/x-netsurf-theme", CONTENT_THEME},
#endif
@@ -192,6 +194,7 @@ const char *content_type_name[] = {
#ifdef WITH_PLUGIN
"PLUGIN",
#endif
+ "DIRECTORY",
#ifdef WITH_THEME_INSTALL
"THEME",
#endif
@@ -285,6 +288,10 @@ static const struct handler_entry handler_map[] = {
plugin_open, plugin_close,
true},
#endif
+ {directory_create, 0, directory_convert,
+ html_reformat, html_destroy, html_stop, html_redraw, 0,
+ html_open, html_close,
+ true},
#ifdef WITH_THEME_INSTALL
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false},
#endif
diff --git a/content/content_type.h b/content/content_type.h
index b8b891514..388cbfb38 100644
--- a/content/content_type.h
+++ b/content/content_type.h
@@ -46,6 +46,7 @@ typedef enum {
#ifdef WITH_PLUGIN
CONTENT_PLUGIN,
#endif
+ CONTENT_DIRECTORY,
#ifdef WITH_THEME_INSTALL
CONTENT_THEME,
#endif
diff --git a/makefile b/makefile
index 05619b9d9..de781540b 100644
--- a/makefile
+++ b/makefile
@@ -19,8 +19,8 @@
OBJECTS_COMMON = content.o fetch.o fetchcache.o urldb.o # content/
OBJECTS_COMMON += css.o css_enum.o parser.o ruleset.o scanner.o # css/
-OBJECTS_COMMON += box.o box_construct.o box_normalise.o form.o \
- html.o html_redraw.o imagemap.o layout.o list.o \
+OBJECTS_COMMON += box.o box_construct.o box_normalise.o directory.o \
+ form.o html.o html_redraw.o imagemap.o layout.o list.o \
table.o textplain.o # render/
OBJECTS_COMMON += filename.o messages.o talloc.o url.o utf8.o \
utils.o # utils/
diff --git a/render/directory.c b/render/directory.c
new file mode 100644
index 000000000..eaaea35c6
--- /dev/null
+++ b/render/directory.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 Richard Wilson <info@tinct.net>
+ */
+
+/** \file
+ * Content for directory listings (implementation).
+ */
+
+#include <dirent.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <time.h>
+#include "libxml/HTMLparser.h"
+#include "netsurf/content/content.h"
+#include "netsurf/render/directory.h"
+#include "netsurf/render/html.h"
+#include "netsurf/utils/messages.h"
+#include "netsurf/utils/url.h"
+
+#define MAX_LENGTH 2048
+
+static const char header[] = "<html>\n<head>\n<title>\n";
+static const char footer[] = "</pre>\n</body>\n</html>\n";
+
+
+bool directory_create(struct content *c, const char *params[]) {
+ if (!html_create(c, params))
+ /* html_create() must have broadcast MSG_ERROR already, so we
+ * don't need to. */
+ return false;
+ htmlParseChunk(c->data.html.parser, header, sizeof(header) - 1, 0);
+ return true;
+}
+
+bool directory_convert(struct content *c, int width, int height) {
+ char *path;
+ DIR *parent;
+ struct dirent *entry;
+ union content_msg_data msg_data;
+ char buffer[MAX_LENGTH];
+ char *nice_path, *cnv, *tmp;
+ url_func_result res;
+ bool compare;
+ char *up;
+
+ path = url_to_path(c->url);
+ if (!path) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+ nice_path = malloc(strlen(path) * 4 + 1);
+ if (!nice_path) {
+ msg_data.error = messages_get("MiscErr");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+ for (cnv = nice_path, tmp = path; *tmp != '\0'; *tmp++) {
+ if (*tmp == '<') {
+ *cnv++ = '&';
+ *cnv++ = 'l';
+ *cnv++ = 't';
+ *cnv++ = ';';
+ } else if (*tmp == '>') {
+ *cnv++ = '&';
+ *cnv++ = 'g';
+ *cnv++ = 't';
+ *cnv++ = ';';
+ } else {
+ *cnv++ = *tmp;
+ }
+ }
+ *cnv++ = '\0';
+ snprintf(buffer, sizeof(buffer), "Index of %s</title>\n</head>\n"
+ "<body>\n<h1>\nIndex of %s</h1>\n<hr><pre>",
+ nice_path, nice_path);
+ free(nice_path);
+ htmlParseChunk(c->data.html.parser, buffer, strlen(buffer), 0);
+
+ res = url_parent(c->url, &up);
+ if (res == URL_FUNC_OK) {
+ res = url_compare(c->url, up, &compare);
+ if (!compare) {
+ snprintf(buffer, sizeof(buffer),
+ "<a href=\"..\">[..]</a>\n");
+ htmlParseChunk(c->data.html.parser, buffer,
+ strlen(buffer), 0);
+ }
+ free(up);
+ }
+
+ if ((parent = opendir(path)) == NULL) {
+ msg_data.error = messages_get("EmptyErr");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+ while ((entry = readdir(parent)) != NULL) {
+ if ((entry->d_ino == 0) || (!strcmp(entry->d_name, ".")) ||
+ (!strcmp(entry->d_name, "..")))
+ continue;
+
+ snprintf(buffer, sizeof(buffer), "<a href=\"%s/%s\">%s</a>\n",
+ c->url, entry->d_name, entry->d_name);
+ htmlParseChunk(c->data.html.parser, buffer, strlen(buffer), 0);
+ }
+ closedir(parent);
+
+ htmlParseChunk(c->data.html.parser, footer, sizeof(footer) - 1, 0);
+ c->type = CONTENT_HTML;
+ return html_convert(c, width, height);
+}
diff --git a/render/directory.h b/render/directory.h
new file mode 100644
index 000000000..93193fbad
--- /dev/null
+++ b/render/directory.h
@@ -0,0 +1,24 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 Richard Wilson <info@tinct.net>
+ */
+
+/** \file
+ * Content for directory listings (interface).
+ *
+ * These functions should in general be called via the content interface.
+ */
+
+#ifndef _NETSURF_RENDER_DIRECTORY_H_
+#define _NETSURF_RENDER_DIRECTORY_H_
+
+#include <stdbool.h>
+#include "netsurf/content/content_type.h"
+
+
+bool directory_create(struct content *c, const char *params[]);
+bool directory_convert(struct content *c, int width, int height);
+
+#endif
diff --git a/riscos/filetype.c b/riscos/filetype.c
index a763e46f8..9a26dad8d 100644
--- a/riscos/filetype.c
+++ b/riscos/filetype.c
@@ -1,7 +1,7 @@
/*
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
+ * http://www.opensource.org/licenses/gpl-license
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
*/
@@ -23,8 +23,8 @@ struct type_entry {
char mime_type[40];
};
static const struct type_entry type_map[] = {
- {0x132, "image/ico"},
- {0x188, "application/x-shockwave-flash"},
+ {0x132, "image/ico"},
+ {0x188, "application/x-shockwave-flash"},
{0x695, "image/gif"},
{0x69c, "image/x-ms-bmp"},
{0xaff, "image/x-drawfile"},
@@ -51,7 +51,7 @@ static int cmp_type(const void *x, const void *y);
*
* \param unix_path Unix style path to file on disk
* \return Pointer to MIME type string (should not be freed) - invalidated
- * on next call to fetch_filetype.
+ * on next call to fetch_filetype.
*/
const char *fetch_filetype(const char *unix_path)
{
@@ -61,6 +61,7 @@ const char *fetch_filetype(const char *unix_path)
char *r, *slash;
os_error *error;
bits file_type, temp;
+ int objtype;
if (!path) {
LOG(("Insufficient memory for calloc"));
@@ -78,7 +79,8 @@ const char *fetch_filetype(const char *unix_path)
}
LOG(("riscos path '%s'", path));
- error = xosfile_read_stamped_no_path(path, 0, 0, 0, 0, 0, &file_type);
+ error = xosfile_read_stamped_no_path(path, &objtype, 0, 0, 0, 0,
+ &file_type);
if (error) {
LOG(("xosfile_read_stamped_no_path failed: %s",
error->errmess));
@@ -86,6 +88,11 @@ const char *fetch_filetype(const char *unix_path)
return "application/riscos";
}
+ if (objtype == osfile_IS_DIR) {
+ sprintf(type_buf, "application/x-netsurf-directory");
+ return (const char *)type_buf;
+ }
+
/* If filetype is text and the file has an extension, try to map the
* extension to a filetype via the MimeMap file. */
if (file_type == osfile_TYPE_TEXT) {
@@ -157,6 +164,7 @@ char *fetch_mimetype(const char *ro_path)
return 0;
if (objtype == osfile_IS_DIR)
+ sprintf(mime, "application/x-netsurf-directory");
return 0; /* directories are pointless */
if ((load >> 20) & 0xFFF) {
diff --git a/riscos/gui.c b/riscos/gui.c
index 5abddac3d..53fd4ea74 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -2157,6 +2157,8 @@ void ro_gui_view_source(struct content *content)
char full_name[256];
char *temp_name, *r;
wimp_full_message_data_xfer message;
+ int objtype;
+ bool done = false;
if (!content || !content->source_data) {
warn_user("MiscError", "No document source");
@@ -2166,10 +2168,15 @@ void ro_gui_view_source(struct content *content)
/* try to load local files directly. */
temp_name = url_to_path(content->url);
if (temp_name) {
- snprintf(message.file_name, 212, "%s", temp_name);
- message.file_name[211] = '\0';
+ error = xosfile_read_no_path(temp_name, &objtype, 0, 0, 0, 0);
+ if ((!error) && (objtype == osfile_IS_FILE)) {
+ snprintf(message.file_name, 212, "%s", temp_name);
+ message.file_name[211] = '\0';
+ done = true;
+ }
free(temp_name);
- } else {
+ }
+ if (!done) {
/* We cannot release the requested filename until after it
* has finished being used. As we can't easily find out when
* this is, we simply don't bother releasing it and simply