summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2005-07-27 01:30:58 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2005-07-27 01:30:58 +0000
commit42b6a05ecec806035187e4f81d394e69638c9e62 (patch)
tree067aed9a950749641a49144723b309ee2fc9b696 /riscos
parent784ffb42e6dee010286d6ab61f190b3d29748818 (diff)
downloadnetsurf-42b6a05ecec806035187e4f81d394e69638c9e62.tar.gz
netsurf-42b6a05ecec806035187e4f81d394e69638c9e62.tar.bz2
[project @ 2005-07-27 01:30:58 by jmb]
Make fetch_filetype use MimeMap - works as follows: If the filetype is text and the filename has an extension, then use the extension to detect the MIME type. In all other cases, the filetype is used. Fix memory leak. svn path=/import/netsurf/; revision=1825
Diffstat (limited to 'riscos')
-rw-r--r--riscos/filetype.c169
1 files changed, 101 insertions, 68 deletions
diff --git a/riscos/filetype.c b/riscos/filetype.c
index 13b2f9aca..9ff9b0df2 100644
--- a/riscos/filetype.c
+++ b/riscos/filetype.c
@@ -17,47 +17,28 @@
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"
-/* type_map must be in sorted order by file_type */
-struct type_entry {
- bits file_type;
- char mime_type[40];
-};
-static const struct type_entry type_map[] = {
- {0x188, "application/x-shockwave-flash"},
- {0x695, "image/gif"},
- {0xaff, "image/x-drawfile"},
- {0xb60, "image/png"},
- {0xc85, "image/jpeg"},
- {0xf78, "image/jng"},
- {0xf79, "text/css"},
- {0xf83, "image/mng"},
- {0xfaf, "text/html"},
- {0xff9, "image/x-riscos-sprite"},
- {0xfff, "text/plain"},
-};
-#define TYPE_MAP_COUNT (sizeof(type_map) / sizeof(type_map[0]))
-
-
-static int cmp_type(const void *x, const void *y);
-
+#define BUF_SIZE (256)
+static char type_buf[BUF_SIZE];
/**
* Determine the MIME type of a local file.
+ *
+ * \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.
*/
-
const char *fetch_filetype(const char *unix_path)
{
- struct type_entry *t;
unsigned int len = strlen(unix_path) + 100;
char *path = calloc(len, 1);
- char *r;
+ char *r, *slash;
os_error *error;
- bits file_type;
+ bits file_type, temp;
if (!path) {
- LOG(("Insuficient memory for calloc"));
- warn_user("NoMemory", 0);
- return "application/riscos";
+ LOG(("Insufficient memory for calloc"));
+ warn_user("NoMemory", 0);
+ return "application/riscos";
}
LOG(("unix_path = '%s'", unix_path));
@@ -65,69 +46,121 @@ const char *fetch_filetype(const char *unix_path)
r = __riscosify(unix_path, 0, __RISCOSIFY_NO_SUFFIX, path, len, 0);
if (r == 0) {
LOG(("__riscosify failed"));
+ free(path);
return "application/riscos";
}
LOG(("riscos path '%s'", path));
error = xosfile_read_stamped_no_path(path, 0, 0, 0, 0, 0, &file_type);
- if (error != 0) {
- LOG(("xosfile_read_stamped_no_path failed: %s", error->errmess));
+ if (error) {
+ LOG(("xosfile_read_stamped_no_path failed: %s",
+ error->errmess));
+ free(path);
return "application/riscos";
}
- /* search for MIME type */
- t = bsearch(&file_type, type_map, TYPE_MAP_COUNT, sizeof(type_map[0]), cmp_type);
- if (t == 0)
+ /* 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) {
+ slash = strrchr(path, '/');
+ if (slash) {
+ error = xmimemaptranslate_extension_to_filetype(
+ slash+1, &temp);
+ if (error)
+ /* ignore error and leave file_type alone */
+ LOG(("0x%x %s",
+ error->errnum, error->errmess));
+ else
+ file_type = temp;
+ }
+ }
+
+ error = xmimemaptranslate_filetype_to_mime_type(file_type, type_buf);
+ if (error) {
+ LOG(("0x%x %s", error->errnum, error->errmess));
+ free(path);
return "application/riscos";
- LOG(("mime type '%s'", t->mime_type));
- return t->mime_type;
-}
+ }
+ /* make sure we're NULL terminated. If we're not, the MimeMap
+ * module's probably written past the end of the buffer from
+ * SVC mode. Short of rewriting MimeMap with an incompatible API,
+ * there's nothing we can do about it.
+ */
+ type_buf[BUF_SIZE - 1] = '\0';
+ free(path);
-char *fetch_mimetype(const char *ro_path) {
+ LOG(("mime type '%s'", type_buf));
+ return (const char *)type_buf;
- os_error *e;
- bits filetype = 0, load;
- int objtype;
- char *mime = calloc(256, sizeof(char));
+}
+
+/**
+ * Find a MIME type for a local file
+ *
+ * \param ro_path RISC OS style path to file on disk
+ * \return MIME type string (on heap, caller should free), or NULL
+ */
+char *fetch_mimetype(const char *ro_path)
+{
+ os_error *e;
+ bits filetype = 0, load;
+ int objtype;
+ char *mime = calloc(BUF_SIZE, sizeof(char));
+ char *slash;
if (!mime) {
- LOG(("Insuficient memory for calloc"));
- warn_user("NoMemory", 0);
- return 0;
+ LOG(("Insufficient memory for calloc"));
+ warn_user("NoMemory", 0);
+ return 0;
}
- e = xosfile_read_no_path(ro_path, &objtype, &load, 0, 0, 0);
- if (e) return 0;
-
- if (objtype == 0x2) return 0; /* directories are pointless */
-
- if ((load >> 20) & 0xFFF) {
- filetype = (load>>8) & 0x000FFF;
- }
- else {
- return 0; /* no idea */
- }
+ e = xosfile_read_no_path(ro_path, &objtype, &load, 0, 0, 0);
+ if (e)
+ return 0;
- e = xmimemaptranslate_filetype_to_mime_type(filetype, mime);
- if (e) return 0;
+ if (objtype == osfile_IS_DIR)
+ return 0; /* directories are pointless */
- return mime;
-}
+ if ((load >> 20) & 0xFFF) {
+ filetype = (load>>8) & 0x000FFF;
+ }
+ else {
+ return 0; /* no idea */
+ }
+ /* If filetype is text and the file has an extension, try to map the
+ * extension to a filetype via the MimeMap file. */
+ slash = strrchr(ro_path, '/');
+ if (slash && filetype == osfile_TYPE_TEXT) {
+ e = xmimemaptranslate_extension_to_filetype(slash+1, &load);
+ if (e)
+ /* if we get an error here, simply ignore it and
+ * leave filetype unchanged */
+ LOG(("0x%x %s", e->errnum, e->errmess));
+ else
+ filetype = load;
+ }
-int cmp_type(const void *x, const void *y)
-{
- const bits *p = x;
- const struct type_entry *q = y;
- return *p < q->file_type ? -1 : (*p == q->file_type ? 0 : +1);
+ e = xmimemaptranslate_filetype_to_mime_type(filetype, mime);
+ if (e)
+ return 0;
+ /* make sure we're NULL terminated. If we're not, the MimeMap
+ * module's probably written past the end of the buffer from
+ * SVC mode. Short of rewriting MimeMap with an incompatible API,
+ * there's nothing we can do about it.
+ */
+ mime[BUF_SIZE - 1] = '\0';
+
+ return mime;
}
-
/**
* Determine the RISC OS filetype for a content.
+ *
+ * \param content The content to examine.
+ * \return The RISC OS filetype corresponding to the content
*/
-
int ro_content_filetype(struct content *content)
{
int file_type;