summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.c13
-rw-r--r--cgit.h3
-rw-r--r--cgitrc.5.txt21
-rw-r--r--ui-atom.c2
-rw-r--r--ui-commit.c4
-rw-r--r--ui-patch.c6
-rw-r--r--ui-plain.c12
-rw-r--r--ui-tag.c2
-rw-r--r--ui-tree.c8
9 files changed, 66 insertions, 5 deletions
diff --git a/cgit.c b/cgit.c
index cb1149d..7b228af 100644
--- a/cgit.c
+++ b/cgit.c
@@ -8,24 +8,32 @@
#include "cgit.h"
#include "cache.h"
#include "cmd.h"
#include "configfile.h"
#include "html.h"
#include "ui-shared.h"
#include "ui-stats.h"
#include "scan-tree.h"
const char *cgit_version = CGIT_VERSION;
+void add_mimetype(const char *name, const char *value)
+{
+ struct string_list_item *item;
+
+ item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes);
+ item->util = xstrdup(value);
+}
+
struct cgit_filter *new_filter(const char *cmd, int extra_args)
{
struct cgit_filter *f;
if (!cmd || !cmd[0])
return NULL;
f = xmalloc(sizeof(struct cgit_filter));
f->cmd = xstrdup(cmd);
f->argv = xmalloc((2 + extra_args) * sizeof(char *));
f->argv[0] = f->cmd;
f->argv[1] = NULL;
@@ -57,24 +65,26 @@ void config_cb(const char *name, const char *value)
else if (!strcmp(name, "index-info"))
ctx.cfg.index_info = xstrdup(value);
else if (!strcmp(name, "logo-link"))
ctx.cfg.logo_link = xstrdup(value);
else if (!strcmp(name, "module-link"))
ctx.cfg.module_link = xstrdup(value);
else if (!strcmp(name, "virtual-root")) {
ctx.cfg.virtual_root = trim_end(value, '/');
if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
ctx.cfg.virtual_root = "";
} else if (!strcmp(name, "nocache"))
ctx.cfg.nocache = atoi(value);
+ else if (!strcmp(name, "noplainemail"))
+ ctx.cfg.noplainemail = atoi(value);
else if (!strcmp(name, "noheader"))
ctx.cfg.noheader = atoi(value);
else if (!strcmp(name, "snapshots"))
ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
else if (!strcmp(name, "enable-index-links"))
ctx.cfg.enable_index_links = atoi(value);
else if (!strcmp(name, "enable-log-filecount"))
ctx.cfg.enable_log_filecount = atoi(value);
else if (!strcmp(name, "enable-log-linecount"))
ctx.cfg.enable_log_linecount = atoi(value);
else if (!strcmp(name, "max-stats"))
ctx.cfg.max_stats = cgit_find_stats_period(value, NULL);
@@ -113,24 +123,26 @@ void config_cb(const char *name, const char *value)
else if (!strcmp(name, "summary-tags"))
ctx.cfg.summary_tags = atoi(value);
else if (!strcmp(name, "agefile"))
ctx.cfg.agefile = xstrdup(value);
else if (!strcmp(name, "renamelimit"))
ctx.cfg.renamelimit = atoi(value);
else if (!strcmp(name, "robots"))
ctx.cfg.robots = xstrdup(value);
else if (!strcmp(name, "clone-prefix"))
ctx.cfg.clone_prefix = xstrdup(value);
else if (!strcmp(name, "local-time"))
ctx.cfg.local_time = atoi(value);
+ else if (!prefixcmp(name, "mimetype."))
+ add_mimetype(name + 9, value);
else if (!strcmp(name, "repo.group"))
ctx.cfg.repo_group = xstrdup(value);
else if (!strcmp(name, "repo.url"))
ctx.repo = cgit_add_repo(value);
else if (!strcmp(name, "repo.name"))
ctx.repo->name = xstrdup(value);
else if (ctx.repo && !strcmp(name, "repo.path"))
ctx.repo->path = trim_end(value, '/');
else if (ctx.repo && !strcmp(name, "repo.clone-url"))
ctx.repo->clone_url = xstrdup(value);
else if (ctx.repo && !strcmp(name, "repo.desc"))
ctx.repo->desc = xstrdup(value);
@@ -231,24 +243,25 @@ static void prepare_context(struct cgit_context *ctx)
ctx->cfg.root_desc = "a fast webinterface for the git dscm";
ctx->cfg.script_name = CGIT_SCRIPT_NAME;
ctx->cfg.summary_branches = 10;
ctx->cfg.summary_log = 10;
ctx->cfg.summary_tags = 10;
ctx->page.mimetype = "text/html";
ctx->page.charset = PAGE_ENCODING;
ctx->page.filename = NULL;
ctx->page.size = 0;
ctx->page.modified = time(NULL);
ctx->page.expires = ctx->page.modified;
ctx->page.etag = NULL;
+ memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list));
}
struct refmatch {
char *req_ref;
char *first_ref;
int match;
};
int find_current_ref(const char *refname, const unsigned char *sha1,
int flags, void *cb_data)
{
struct refmatch *info;
diff --git a/cgit.h b/cgit.h
index b8f4850..4c854ea 100644
--- a/cgit.h
+++ b/cgit.h
@@ -6,24 +6,25 @@
#include <cache.h>
#include <grep.h>
#include <object.h>
#include <tree.h>
#include <commit.h>
#include <tag.h>
#include <diff.h>
#include <diffcore.h>
#include <refs.h>
#include <revision.h>
#include <log-tree.h>
#include <archive.h>
+#include <string-list.h>
#include <xdiff-interface.h>
#include <xdiff/xdiff.h>
#include <utf8.h>
/*
* Dateformats used on misc. pages
*/
#define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)"
#define FMT_SHORTDATE "%Y-%m-%d"
#define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ"
@@ -171,30 +172,32 @@ struct cgit_config {
int embedded;
int enable_index_links;
int enable_log_filecount;
int enable_log_linecount;
int local_time;
int max_repo_count;
int max_commit_count;
int max_lock_attempts;
int max_msg_len;
int max_repodesc_len;
int max_stats;
int nocache;
+ int noplainemail;
int noheader;
int renamelimit;
int snapshots;
int summary_branches;
int summary_log;
int summary_tags;
+ struct string_list mimetypes;
struct cgit_filter *about_filter;
struct cgit_filter *commit_filter;
struct cgit_filter *source_filter;
};
struct cgit_page {
time_t modified;
time_t expires;
size_t size;
char *mimetype;
char *charset;
char *filename;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index d8e4b97..4d656fe 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -151,35 +151,43 @@ max-repo-count::
Specifies the number of entries to list per page on the repository
index page. Default value: "50".
max-repodesc-length::
Specifies the maximum number of repo description characters to display
on the repository index page. Default value: "80".
max-stats::
Set the default maximum statistics period. Valid values are "week",
"month", "quarter" and "year". If unspecified, statistics are
disabled. Default value: none. See also: "repo.max-stats".
+mimetype.<ext>::
+ Set the mimetype for the specified filename extension. This is used
+ by the `plain` command when returning blob content.
+
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"
nocache::
If set to the value "1" caching will be disabled. This settings is
deprecated, and will not be honored starting with cgit-1.0. Default
value: "0".
+noplainemail::
+ If set to "1" showing full author email adresses will be disabled.
+ Default value: "0".
+
noheader::
Flag which, when set to "1", will make cgit omit the standard header
on all pages. Default value: none. See also: "embedded".
renamelimit::
Maximum number of files to consider when detecting renames. The value
"-1" uses the compiletime value in git (for further info, look at
`man git-diff`). Default value: "-1".
repo.group::
A value for the current repository group, which all repositories
specified after this setting will inherit. Default value: none.
@@ -346,24 +354,37 @@ root-title=foobar.com git repositories
root-desc=tracking the foobar development
# Include some more info about foobar.com on the index page
root-readme=/var/www/htdocs/about.html
# Allow download of tar.gz, tar.bz2 and zip-files
snapshots=tar.gz tar.bz2 zip
##
+## List of common mimetypes
+##
+
+mimetype.git=image/git
+mimetype.html=text/html
+mimetype.jpg=image/jpeg
+mimetype.jpeg=image/jpeg
+mimetype.pdf=application/pdf
+mimetype.png=image/png
+mimetype.svg=image/svg+xml
+
+
+##
## List of repositories.
## PS: Any repositories listed when repo.group is unset will not be
## displayed under a group heading
## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos')
## and included like this:
## include=/etc/cgitrepos
##
repo.url=foo
repo.path=/pub/git/foo.git
repo.desc=the master foo repository
diff --git a/ui-atom.c b/ui-atom.c
index e5c31d9..808b2d0 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -23,25 +23,25 @@ void add_entry(struct commit *commit, char *host)
html("<title>");
html_txt(info->subject);
html("</title>\n");
html("<updated>");
cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time);
html("</updated>\n");
html("<author>\n");
if (info->author) {
html("<name>");
html_txt(info->author);
html("</name>\n");
}
- if (info->author_email) {
+ if (info->author_email && !ctx.cfg.noplainemail) {
mail = xstrdup(info->author_email);
t = strchr(mail, '<');
if (t)
t++;
else
t = mail;
t2 = strchr(t, '>');
if (t2)
*t2 = '\0';
html("<email>");
html_txt(t);
html("</email>\n");
diff --git a/ui-commit.c b/ui-commit.c
index 5815b58..d6b73ee 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -31,33 +31,37 @@ void cgit_print_commit(char *hex)
commit = lookup_commit_reference(sha1);
if (!commit) {
cgit_print_error(fmt("Bad commit reference: %s", hex));
return;
}
info = cgit_parse_commit(commit);
load_ref_decorations();
html("<table summary='commit info' class='commit-info'>\n");
html("<tr><th>author</th><td>");
html_txt(info->author);
+ if (!ctx.cfg.noplainemail) {
html(" ");
html_txt(info->author_email);
+ }
html("</td><td class='right'>");
cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
html("</td></tr>\n");
html("<tr><th>committer</th><td>");
html_txt(info->committer);
+ if (!ctx.cfg.noplainemail) {
html(" ");
html_txt(info->committer_email);
+ }
html("</td><td class='right'>");
cgit_print_date(info->committer_date, FMT_LONGDATE, ctx.cfg.local_time);
html("</td></tr>\n");
html("<tr><th>commit</th><td colspan='2' class='sha1'>");
tmp = sha1_to_hex(commit->object.sha1);
cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp);
html(" (");
cgit_patch_link("patch", NULL, NULL, NULL, tmp);
html(")</td></tr>\n");
html("<tr><th>tree</th><td colspan='2' class='sha1'>");
tmp = xstrdup(hex);
cgit_tree_link(sha1_to_hex(commit->tree->object.sha1), NULL, NULL,
diff --git a/ui-patch.c b/ui-patch.c
index 5d665d3..2a8f7a5 100644
--- a/ui-patch.c
+++ b/ui-patch.c
@@ -99,25 +99,29 @@ void cgit_print_patch(char *hex)
info = cgit_parse_commit(commit);
if (commit->parents && commit->parents->item)
hashcpy(old_sha1, commit->parents->item->object.sha1);
else
hashclr(old_sha1);
patchname = fmt("%s.patch", sha1_to_hex(sha1));
ctx.page.mimetype = "text/plain";
ctx.page.filename = patchname;
cgit_print_http_headers(&ctx);
htmlf("From %s Mon Sep 17 00:00:00 2001\n", sha1_to_hex(sha1));
- htmlf("From: %s %s\n", info->author, info->author_email);
+ htmlf("From: %s", info->author);
+ if (!ctx.cfg.noplainemail) {
+ htmlf(" %s", info->author_email);
+ }
+ html("\n");
html("Date: ");
cgit_print_date(info->author_date, "%a, %d %b %Y %H:%M:%S %z%n", ctx.cfg.local_time);
htmlf("Subject: %s\n\n", info->subject);
if (info->msg && *info->msg) {
htmlf("%s", info->msg);
if (info->msg[strlen(info->msg) - 1] != '\n')
html("\n");
}
html("---\n");
cgit_diff_tree(old_sha1, sha1, filepair_cb, NULL);
html("--\n");
htmlf("cgit %s\n", CGIT_VERSION);
diff --git a/ui-plain.c b/ui-plain.c
index 93a3a05..27c6dae 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -8,42 +8,52 @@
#include "cgit.h"
#include "html.h"
#include "ui-shared.h"
char *curr_rev;
char *match_path;
int match;
static void print_object(const unsigned char *sha1, const char *path)
{
enum object_type type;
- char *buf;
+ char *buf, *ext;
unsigned long size;
+ struct string_list_item *mime;
type = sha1_object_info(sha1, &size);
if (type == OBJ_BAD) {
html_status(404, "Not found", 0);
return;
}
buf = read_sha1_file(sha1, &type, &size);
if (!buf) {
html_status(404, "Not found", 0);
return;
}
+ ctx.page.mimetype = NULL;
+ ext = strrchr(path, '.');
+ if (ext && *(++ext)) {
+ mime = string_list_lookup(ext, &ctx.cfg.mimetypes);
+ if (mime)
+ ctx.page.mimetype = (char *)mime->util;
+ }
+ if (!ctx.page.mimetype) {
if (buffer_is_binary(buf, size))
ctx.page.mimetype = "application/octet-stream";
else
ctx.page.mimetype = "text/plain";
+ }
ctx.page.filename = fmt("%s", path);
ctx.page.size = size;
ctx.page.etag = sha1_to_hex(sha1);
cgit_print_http_headers(&ctx);
html_raw(buf, size);
match = 1;
}
static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
const char *pathname, unsigned mode, int stage,
void *cbdata)
{
diff --git a/ui-tag.c b/ui-tag.c
index 0e056e0..a9c8670 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -55,25 +55,25 @@ void cgit_print_tag(char *revname)
html("<table class='commit-info'>\n");
htmlf("<tr><td>Tag name</td><td>");
html_txt(revname);
htmlf(" (%s)</td></tr>\n", sha1_to_hex(sha1));
if (info->tagger_date > 0) {
html("<tr><td>Tag date</td><td>");
cgit_print_date(info->tagger_date, FMT_LONGDATE, ctx.cfg.local_time);
html("</td></tr>\n");
}
if (info->tagger) {
html("<tr><td>Tagged by</td><td>");
html_txt(info->tagger);
- if (info->tagger_email) {
+ if (info->tagger_email && !ctx.cfg.noplainemail) {
html(" ");
html_txt(info->tagger_email);
}
html("</td></tr>\n");
}
html("<tr><td>Tagged object</td><td>");
cgit_object_link(tag->tagged);
html("</td></tr>\n");
html("</table>\n");
print_tag_content(info->msg);
} else {
html("<table class='commit-info'>\n");
diff --git a/ui-tree.c b/ui-tree.c
index caf6a9e..c608754 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -104,24 +104,25 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
print_binary_buffer(buf, size);
else
print_text_buffer(basename, buf, size);
}
static int ls_item(const unsigned char *sha1, const char *base, int baselen,
const char *pathname, unsigned int mode, int stage,
void *cbdata)
{
char *name;
char *fullpath;
+ char *class;
enum object_type type;
unsigned long size = 0;
name = xstrdup(pathname);
fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "",
ctx.qry.path ? "/" : "", name);
if (!S_ISGITLINK(mode)) {
type = sha1_object_info(sha1, &size);
if (type == OBJ_BAD) {
htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>",
name,
@@ -136,25 +137,30 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen,
if (S_ISGITLINK(mode)) {
htmlf("<a class='ls-mod' href='");
html_attr(fmt(ctx.repo->module_link,
name,
sha1_to_hex(sha1)));
html("'>");
html_txt(name);
html("</a>");
} else if (S_ISDIR(mode)) {
cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
curr_rev, fullpath);
} else {
- cgit_tree_link(name, NULL, "ls-blob", ctx.qry.head,
+ class = strrchr(name, '.');
+ if (class != NULL) {
+ class = fmt("ls-blob %s", class + 1);
+ } else
+ class = "ls-blob";
+ cgit_tree_link(name, NULL, class, ctx.qry.head,
curr_rev, fullpath);
}
htmlf("</td><td class='ls-size'>%li</td>", size);
html("<td>");
cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev,
fullpath, 0, NULL, NULL, ctx.qry.showmsg);
if (ctx.repo->max_stats)
cgit_stats_link("stats", NULL, "button", ctx.qry.head,
fullpath);
html("</td></tr>\n");
free(name);