From: Lars Hjemli Date: Sun, 18 Mar 2012 21:01:28 +0000 (+0000) Subject: Merge branch 'fh/mimetypes' X-Git-Url: https://gitweb.ps.run/ps-cgit/commitdiff_plain/ae90a0b2d18d66e7b1cb98b2e34fd697f8b5311a?hp=-c Merge branch 'fh/mimetypes' --- ae90a0b2d18d66e7b1cb98b2e34fd697f8b5311a diff --combined cgit.c index 6a75f27,abb698b..b9b3a66 --- a/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")) @@@ -88,10 -86,7 +88,10 @@@ 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; @@@ -458,12 -444,10 +460,12 @@@ } 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) { @@@ -487,7 -471,6 +489,7 @@@ cgit_print_docend(); return 1; } + sort_string_list(&ctx->repo->submodules); cgit_prepare_repo_env(ctx->repo); return 0; } diff --combined cgit.h index b7c7ac9,db24941..6ee6769 --- a/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 fab0e0a,22a0dc3..a72241f --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@@ -226,11 -226,22 +226,22 @@@ mimetype.: 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." 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.". 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: +repo.module-link.:: + 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 2abd210,7fecc32..85877d7 --- a/ui-plain.c +++ b/ui-plain.c @@@ -6,6 -6,7 +6,7 @@@ * (see COPYING for full license text) */ + #include #include "cgit.h" #include "html.h" #include "ui-shared.h" @@@ -13,12 -14,53 +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 +75,16 @@@ } 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("
  • "); - 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("
  • \n"); match = 2; }