about summary refs log tree commit
path: root/ui-plain.c
diff options
context:
space:
mode:
authorFerry Huberts <ferry.huberts@pelagic.nl>2011-07-19 10:51:58 +0200
committerLars Hjemli <hjemli@gmail.com>2011-07-19 09:30:07 +0000
commitd01c600c179593a53162a9d4e3040ecfc5078fdc (patch)
tree487f8afaefe7b5f09f05d0d3e3796aaff86b931a /ui-plain.c
parent96f05018c9dbdf8131f18c87ee3bbbac40e0f729 (diff)
downloadcgit-d01c600c179593a53162a9d4e3040ecfc5078fdc.tar.gz
ui_plain: automatically lookup mimetype when mimetype-file is set
For sites that do not want to configure mime types by hand but
still want the correct mime type for 'plain' blobs, configuring
a mime type file is made possible. This is handy since such a
file is normally already provided (at least on Linux systems).

Also, this reflects the gitweb option '$mimetypes_file'

Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'ui-plain.c')
-rw-r--r--ui-plain.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/ui-plain.c b/ui-plain.c
index 733db4d..7fecc32 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -6,6 +6,7 @@
  *   (see COPYING for full license text)
  */
 
+#include <stdio.h>
 #include "cgit.h"
 #include "html.h"
 #include "ui-shared.h"
@@ -13,12 +14,53 @@
 int match_baselen;
 int match;
 
+static char *get_mimetype_from_file(const char *filename, const char *ext)
+{
+        static const char *delimiters;
+        char *result;
+        FILE *fd;
+        char line[1024];
+        char *mimetype;
+        char *token;
+
+        if (!filename)
+                return NULL;
+
+        fd = fopen(filename, "r");
+        if (!fd)
+                return NULL;
+
+        delimiters = " \t\r\n";
+        result = NULL;
+
+        /* loop over all lines in the file */
+        while (!result && fgets(line, sizeof(line), fd)) {
+                mimetype = strtok(line, delimiters);
+
+                /* skip empty lines and comment lines */
+                if (!mimetype || (mimetype[0] == '#'))
+                        continue;
+
+                /* loop over all extensions of mimetype */
+                while ((token = strtok(NULL, delimiters))) {
+                        if (!strcasecmp(ext, token)) {
+                                result = xstrdup(mimetype);
+                                break;
+                        }
+                }
+        }
+        fclose(fd);
+
+        return result;
+}
+
 static void print_object(const unsigned char *sha1, const char *path)
 {
         enum object_type type;
         char *buf, *ext;
         unsigned long size;
         struct string_list_item *mime;
+        int freemime;
 
         type = sha1_object_info(sha1, &size);
         if (type == OBJ_BAD) {
@@ -33,10 +75,16 @@ static void print_object(const unsigned char *sha1, const char *path)
         }
         ctx.page.mimetype = NULL;
         ext = strrchr(path, '.');
+        freemime = 0;
         if (ext && *(++ext)) {
                 mime = string_list_lookup(&ctx.cfg.mimetypes, ext);
-                if (mime)
+                if (mime) {
                         ctx.page.mimetype = (char *)mime->util;
+                } else {
+                        ctx.page.mimetype = get_mimetype_from_file(ctx.cfg.mimetype_file, ext);
+                        if (ctx.page.mimetype)
+                                freemime = 1;
+                }
         }
         if (!ctx.page.mimetype) {
                 if (buffer_is_binary(buf, size))
@@ -50,6 +98,8 @@ static void print_object(const unsigned char *sha1, const char *path)
         cgit_print_http_headers(&ctx);
         html_raw(buf, size);
         match = 1;
+        if (freemime)
+                free(ctx.page.mimetype);
 }
 
 static char *buildpath(const char *base, int baselen, const char *path)