]> gitweb.ps.run Git - ps-cgit/commitdiff
Merge branch 'fh/mimetypes'
authorLars Hjemli <hjemli@gmail.com>
Sun, 18 Mar 2012 21:01:28 +0000 (21:01 +0000)
committerLars Hjemli <hjemli@gmail.com>
Sun, 18 Mar 2012 21:01:28 +0000 (21:01 +0000)
1  2 
cgit.c
cgit.h
cgitrc.5.txt
ui-plain.c

diff --combined cgit.c
index 6a75f2706ff0c711e8c3f38ae20d3be867b858bd,abb698bb6dae8e675ebdf28f014e35e66be85565..b9b3a668b9755de93311b1700d8a79cfc31f754a
--- 1/cgit.c
--- 2/cgit.c
+++ b/cgit.c
@@@ -60,8 -60,6 +60,8 @@@ static void process_cached_repolist(con
  
  void repo_config(struct cgit_repo *repo, const char *name, const char *value)
  {
 +      struct string_list_item *item;
 +
        if (!strcmp(name, "name"))
                repo->name = xstrdup(value);
        else if (!strcmp(name, "clone-url"))
                repo->max_stats = cgit_find_stats_period(value, NULL);
        else if (!strcmp(name, "module-link"))
                repo->module_link= xstrdup(value);
 -      else if (!strcmp(name, "section"))
 +      else if (!prefixcmp(name, "module-link.")) {
 +              item = string_list_append(&repo->submodules, name + 12);
 +              item->util = xstrdup(value);
 +      } else if (!strcmp(name, "section"))
                repo->section = xstrdup(value);
        else if (!strcmp(name, "readme") && value != NULL)
                repo->readme = xstrdup(value);
@@@ -241,6 -236,8 +241,8 @@@ void config_cb(const char *name, const 
                ctx.cfg.ssdiff = atoi(value);
        else if (!strcmp(name, "agefile"))
                ctx.cfg.agefile = xstrdup(value);
+       else if (!strcmp(name, "mimetype-file"))
+               ctx.cfg.mimetype_file = xstrdup(value);
        else if (!strcmp(name, "renamelimit"))
                ctx.cfg.renamelimit = atoi(value);
        else if (!strcmp(name, "remove-suffix"))
@@@ -303,7 -300,6 +305,7 @@@ static void querystring_cb(const char *
                ctx.qry.period = xstrdup(value);
        } else if (!strcmp(name, "ss")) {
                ctx.qry.ssdiff = atoi(value);
 +              ctx.qry.has_ssdiff = 1;
        } else if (!strcmp(name, "all")) {
                ctx.qry.show_all = atoi(value);
        } else if (!strcmp(name, "context")) {
@@@ -344,6 -340,7 +346,6 @@@ static void prepare_context(struct cgit
        ctx->cfg.max_repodesc_len = 80;
        ctx->cfg.max_blob_size = 0;
        ctx->cfg.max_stats = 0;
 -      ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
        ctx->cfg.project_list = NULL;
        ctx->cfg.renamelimit = -1;
        ctx->cfg.remove_suffix = 0;
@@@ -421,17 -418,6 +423,17 @@@ char *find_default_branch(struct cgit_r
        return ref;
  }
  
 +static char *guess_defbranch(const char *repo_path)
 +{
 +      const char *ref;
 +      unsigned char sha1[20];
 +
 +      ref = resolve_ref("HEAD", sha1, 0, NULL);
 +      if (!ref || prefixcmp(ref, "refs/heads/"))
 +              return "master";
 +      return xstrdup(ref + 11);
 +}
 +
  static int prepare_repo_cmd(struct cgit_context *ctx)
  {
        char *tmp;
        }
        ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
  
 +      if (!ctx->repo->defbranch)
 +              ctx->repo->defbranch = guess_defbranch(ctx->repo->path);
 +
        if (!ctx->qry.head) {
                ctx->qry.nohead = 1;
                ctx->qry.head = find_default_branch(ctx->repo);
 -              ctx->repo->defbranch = ctx->qry.head;
        }
  
        if (!ctx->qry.head) {
                cgit_print_docend();
                return 1;
        }
 +      sort_string_list(&ctx->repo->submodules);
        cgit_prepare_repo_env(ctx->repo);
        return 0;
  }
diff --combined cgit.h
index b7c7ac949cbee102faf96de540129a273a4177c8,db24941c601dd7cf622e48639b7a8a55550b03cd..6ee6769cf2475a0119aa15539a134397cc28f329
--- 1/cgit.h
--- 2/cgit.h
+++ b/cgit.h
@@@ -88,7 -88,6 +88,7 @@@ struct cgit_repo 
        struct cgit_filter *about_filter;
        struct cgit_filter *commit_filter;
        struct cgit_filter *source_filter;
 +      struct string_list submodules;
  };
  
  typedef void (*repo_config_fn)(struct cgit_repo *repo, const char *name,
@@@ -138,7 -137,6 +138,7 @@@ struct reflist 
  struct cgit_query {
        int has_symref;
        int has_sha1;
 +      int has_ssdiff;
        char *raw;
        char *repo;
        char *page;
@@@ -177,6 -175,7 +177,7 @@@ struct cgit_config 
        char *index_info;
        char *logo;
        char *logo_link;
+       char *mimetype_file;
        char *module_link;
        char *project_list;
        char *readme;
diff --combined cgitrc.5.txt
index fab0e0a60e5f27d9e15e0b00680906b7fec6e6f8,22a0dc3beedcad637f7f71ad7bbe2bfd459eaa55..a72241ff6b38a1952884bbfcea1a686cad338b33
@@@ -226,11 -226,22 +226,22 @@@ mimetype.<ext>:
        Set the mimetype for the specified filename extension. This is used
        by the `plain` command when returning blob content.
  
+ mimetype-file::
+       Specifies the file to use for automatic mimetype lookup. If specified
+       then this field is used as a fallback when no "mimetype.<ext>" match is
+       found. If unspecified then no such lookup is performed. The typical file
+       to use on a Linux system is /etc/mime.types. Default value: none. See
+       also: "mimetype.<ext>". The format of the file must comply to:
+       - a comment line is an empty line or a line starting with a hash (#),
+         optionally preceded by whitespace
+       - a non-comment line starts with the mimetype (like image/png), followed
+         by one or more file extensions (like jpg), all separated by whitespace
  module-link::
        Text which will be used as the formatstring for a hyperlink when a
        submodule is printed in a directory listing. The arguments for the
        formatstring are the path and SHA1 of the submodule commit. Default
 -      value: "./?repo=%s&page=commit&id=%s"
 +      value: none.
  
  nocache::
        If set to the value "1" caching will be disabled. This settings is
@@@ -377,8 -388,7 +388,8 @@@ repo.commit-filter:
  repo.defbranch::
        The name of the default branch for this repository. If no such branch
        exists in the repository, the first branch name (when sorted) is used
 -      as default instead. Default value: "master".
 +      as default instead. Default value: branch pointed to by HEAD, or
 +      "master" if there is no suitable HEAD.
  
  repo.desc::
        The value to show as repository description. Default value: none.
@@@ -418,12 -428,6 +429,12 @@@ repo.module-link:
        formatstring are the path and SHA1 of the submodule commit. Default
        value: <module-link>
  
 +repo.module-link.<path>::
 +      Text which will be used as the formatstring for a hyperlink when a
 +      submodule with the specified subdirectory path is printed in a
 +      directory listing. The only argument for the formatstring is the SHA1
 +      of the submodule commit. Default value: none.
 +
  repo.max-stats::
        Override the default maximum statistics period. Valid values are equal
        to the values specified for the global "max-stats" setting. Default
@@@ -507,7 -511,7 +518,7 @@@ Also, all filters are handed the follow
  
  If a setting is not defined for a repository and the corresponding global
  setting is also not defined (if applicable), then the corresponding
 -environment variable will be an empty string.
 +environment variable will be unset.
  
  
  MACRO EXPANSION
diff --combined ui-plain.c
index 2abd210c0f5afd1871b00e6d53eaddb929b39ff0,7fecc32e1a970fdb3c51575e44072036222718d2..85877d774bfd40016b1b39267acb17b231569928
@@@ -6,6 -6,7 +6,7 @@@
   *   (see COPYING for full license text)
   */
  
+ #include <stdio.h>
  #include "cgit.h"
  #include "html.h"
  #include "ui-shared.h"
  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) {
        }
        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 +98,8 @@@
        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)
@@@ -97,14 -147,11 +147,14 @@@ static void print_dir_entry(const unsig
        char *fullpath;
  
        fullpath = buildpath(base, baselen, path);
 -      if (!S_ISDIR(mode))
 +      if (!S_ISDIR(mode) && !S_ISGITLINK(mode))
                fullpath[strlen(fullpath) - 1] = 0;
        html("  <li>");
 -      cgit_plain_link(path, NULL, NULL, ctx.qry.head, ctx.qry.sha1,
 -                      fullpath);
 +      if (S_ISGITLINK(mode)) {
 +              cgit_submodule_link(NULL, fullpath, sha1_to_hex(sha1));
 +      } else
 +              cgit_plain_link(path, NULL, NULL, ctx.qry.head, ctx.qry.sha1,
 +                              fullpath);
        html("</li>\n");
        match = 2;
  }