summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--.gitignore1
-rw-r--r--Makefile29
-rw-r--r--cgit.c3
-rw-r--r--cgit.h2
-rwxr-xr-xgen-version.sh4
-rw-r--r--shared.c2
-rw-r--r--ui-shared.c2
7 files changed, 27 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
index c4c9ac3..5664962 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
1# Files I don't care to see in git-status/commit 1# Files I don't care to see in git-status/commit
2cgit 2cgit
3VERSION
3*.o 4*.o
4*~ 5*~
diff --git a/Makefile b/Makefile
index c2a5736..e69ad7e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,87 +1,94 @@
1CGIT_VERSION = 0.5
2
3prefix = /var/www/htdocs/cgit 1prefix = /var/www/htdocs/cgit
4
5SHA1_HEADER = <openssl/sha.h> 2SHA1_HEADER = <openssl/sha.h>
6CACHE_ROOT = /var/cache/cgit 3CACHE_ROOT = /var/cache/cgit
7CGIT_CONFIG = /etc/cgitrc 4CGIT_CONFIG = /etc/cgitrc
8CGIT_SCRIPT_NAME = cgit.cgi 5CGIT_SCRIPT_NAME = cgit.cgi
9 6
10# 7#
11# Let the user override the above settings. 8# Let the user override the above settings.
12# 9#
13-include cgit.conf 10-include cgit.conf
14 11
12
13CGIT_VERSION = 0.5
14
15all: cgit
16
17VERSION:
18 gen-version.sh
19
20-include VERSION
21
22
15EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto 23EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
16OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ 24OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
17 ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \ 25 ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \
18 ui-snapshot.o ui-blob.o 26 ui-snapshot.o ui-blob.o
19 27
20CFLAGS += -Wall 28CFLAGS += -Wall
21 29
22ifdef DEBUG 30ifdef DEBUG
23 CFLAGS += -g 31 CFLAGS += -g
24endif 32endif
25 33
26CFLAGS += -Igit 34CFLAGS += -Igit
27CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)' 35CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)'
28CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"' 36CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"'
29CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"' 37CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"'
30CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"' 38CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"'
31 39
32 40
33# 41#
34# If make is run on a nongit platform, get the git sources as a tarball. 42# If make is run on a nongit platform, get the git sources as a tarball.
35# 43#
36GITVER = $(shell git version 2>/dev/null || echo nogit) 44GITVER = $(shell git version 2>/dev/null || echo nogit)
37ifeq ($(GITVER),nogit) 45ifeq ($(GITVER),nogit)
38GITURL = http://www.kernel.org/pub/software/scm/git/git-1.5.2.tar.bz2 46GITURL = http://www.kernel.org/pub/software/scm/git/git-1.5.2.tar.bz2
39INITGIT = test -e git/git.c || ((curl "$(GITURL)" | tar -xj) && mv git-1.5.2 git) 47INITGIT = test -e git/git.c || ((curl "$(GITURL)" | tar -xj) && mv git-1.5.2 git)
40else 48else
41INITGIT = ./submodules.sh -i 49INITGIT = ./submodules.sh -i
42endif 50endif
43 51
44 52
45# 53cgit: cgit.c cgit.h VERSION $(OBJECTS)
46# basic build rules
47#
48all: cgit
49
50cgit: cgit.c cgit.h $(OBJECTS)
51 $(CC) $(CFLAGS) cgit.c -o cgit $(OBJECTS) $(EXTLIBS) 54 $(CC) $(CFLAGS) cgit.c -o cgit $(OBJECTS) $(EXTLIBS)
52 55
53$(OBJECTS): cgit.h git/libgit.a 56$(OBJECTS): cgit.h git/libgit.a
54 57
55git/libgit.a: 58git/libgit.a:
56 $(INITGIT) 59 $(INITGIT)
57 $(MAKE) -C git 60 $(MAKE) -C git
58 61
59# 62#
60# phony targets 63# phony targets
61# 64#
62install: all clean-cache 65install: all clean-cache
63 mkdir -p $(prefix) 66 mkdir -p $(prefix)
64 install cgit $(prefix)/$(CGIT_SCRIPT_NAME) 67 install cgit $(prefix)/$(CGIT_SCRIPT_NAME)
65 install cgit.css $(prefix)/cgit.css 68 install cgit.css $(prefix)/cgit.css
66 69
67clean-cgit: 70clean-cgit:
68 rm -f cgit *.o 71 rm -f cgit VERSION *.o
69 72
70distclean-cgit: clean-cgit 73distclean-cgit: clean-cgit
71 git clean -d -x 74 git clean -d -x
72 75
73clean-sub: 76clean-sub:
74 $(MAKE) -C git clean 77 $(MAKE) -C git clean
75 78
76distclean-sub: clean-sub 79distclean-sub: clean-sub
77 $(shell cd git && git clean -d -x) 80 $(shell cd git && git clean -d -x)
78 81
79clean-cache: 82clean-cache:
80 rm -rf $(CACHE_ROOT)/* 83 rm -rf $(CACHE_ROOT)/*
81 84
82clean: clean-cgit clean-sub 85clean: clean-cgit clean-sub
83 86
84distclean: distclean-cgit distclean-sub 87distclean: distclean-cgit distclean-sub
85 88
89version: clean-cgit
90 ./gen-version.sh
91 make
92
86.PHONY: all install clean clean-cgit clean-sub clean-cache \ 93.PHONY: all install clean clean-cgit clean-sub clean-cache \
87 distclean distclean-cgit distclean-sub 94 distclean distclean-cgit distclean-sub release version
diff --git a/cgit.c b/cgit.c
index 3fc90bf..11dff76 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,77 +1,74 @@
1/* cgit.c: cgi for the git scm 1/* cgit.c: cgi for the git scm
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10 10
11const char cgit_version[] = CGIT_VERSION;
12
13
14static int cgit_prepare_cache(struct cacheitem *item) 11static int cgit_prepare_cache(struct cacheitem *item)
15{ 12{
16 if (!cgit_repo && cgit_query_repo) { 13 if (!cgit_repo && cgit_query_repo) {
17 char *title = fmt("%s - %s", cgit_root_title, "Bad request"); 14 char *title = fmt("%s - %s", cgit_root_title, "Bad request");
18 cgit_print_docstart(title, item); 15 cgit_print_docstart(title, item);
19 cgit_print_pageheader(title, 0); 16 cgit_print_pageheader(title, 0);
20 cgit_print_error(fmt("Unknown repo: %s", cgit_query_repo)); 17 cgit_print_error(fmt("Unknown repo: %s", cgit_query_repo));
21 cgit_print_docend(); 18 cgit_print_docend();
22 return 0; 19 return 0;
23 } 20 }
24 21
25 if (!cgit_repo) { 22 if (!cgit_repo) {
26 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); 23 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root));
27 item->ttl = cgit_cache_root_ttl; 24 item->ttl = cgit_cache_root_ttl;
28 return 1; 25 return 1;
29 } 26 }
30 27
31 if (!cgit_cmd) { 28 if (!cgit_cmd) {
32 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, 29 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root,
33 cache_safe_filename(cgit_repo->url))); 30 cache_safe_filename(cgit_repo->url)));
34 item->ttl = cgit_cache_repo_ttl; 31 item->ttl = cgit_cache_repo_ttl;
35 } else { 32 } else {
36 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, 33 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root,
37 cache_safe_filename(cgit_repo->url), cgit_query_page, 34 cache_safe_filename(cgit_repo->url), cgit_query_page,
38 cache_safe_filename(cgit_querystring))); 35 cache_safe_filename(cgit_querystring)));
39 if (cgit_query_has_symref) 36 if (cgit_query_has_symref)
40 item->ttl = cgit_cache_dynamic_ttl; 37 item->ttl = cgit_cache_dynamic_ttl;
41 else if (cgit_query_has_sha1) 38 else if (cgit_query_has_sha1)
42 item->ttl = cgit_cache_static_ttl; 39 item->ttl = cgit_cache_static_ttl;
43 else 40 else
44 item->ttl = cgit_cache_repo_ttl; 41 item->ttl = cgit_cache_repo_ttl;
45 } 42 }
46 return 1; 43 return 1;
47} 44}
48 45
49static void cgit_print_repo_page(struct cacheitem *item) 46static void cgit_print_repo_page(struct cacheitem *item)
50{ 47{
51 char *title; 48 char *title;
52 int show_search; 49 int show_search;
53 50
54 if (!cgit_query_head) 51 if (!cgit_query_head)
55 cgit_query_head = cgit_repo->defbranch; 52 cgit_query_head = cgit_repo->defbranch;
56 53
57 if (chdir(cgit_repo->path)) { 54 if (chdir(cgit_repo->path)) {
58 title = fmt("%s - %s", cgit_root_title, "Bad request"); 55 title = fmt("%s - %s", cgit_root_title, "Bad request");
59 cgit_print_docstart(title, item); 56 cgit_print_docstart(title, item);
60 cgit_print_pageheader(title, 0); 57 cgit_print_pageheader(title, 0);
61 cgit_print_error(fmt("Unable to scan repository: %s", 58 cgit_print_error(fmt("Unable to scan repository: %s",
62 strerror(errno))); 59 strerror(errno)));
63 cgit_print_docend(); 60 cgit_print_docend();
64 return; 61 return;
65 } 62 }
66 63
67 title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); 64 title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc);
68 show_search = 0; 65 show_search = 0;
69 setenv("GIT_DIR", cgit_repo->path, 1); 66 setenv("GIT_DIR", cgit_repo->path, 1);
70 67
71 if ((cgit_cmd == CMD_SNAPSHOT) && cgit_repo->snapshots) { 68 if ((cgit_cmd == CMD_SNAPSHOT) && cgit_repo->snapshots) {
72 cgit_print_snapshot(item, cgit_query_sha1, "zip", 69 cgit_print_snapshot(item, cgit_query_sha1, "zip",
73 cgit_repo->url, cgit_query_name); 70 cgit_repo->url, cgit_query_name);
74 return; 71 return;
75 } 72 }
76 73
77 if (cgit_cmd == CMD_BLOB) { 74 if (cgit_cmd == CMD_BLOB) {
diff --git a/cgit.h b/cgit.h
index bd2dd0d..9558362 100644
--- a/cgit.h
+++ b/cgit.h
@@ -37,129 +37,129 @@
37 37
38 38
39/* 39/*
40 * Limits used for relative dates 40 * Limits used for relative dates
41 */ 41 */
42#define TM_MIN 60 42#define TM_MIN 60
43#define TM_HOUR (TM_MIN * 60) 43#define TM_HOUR (TM_MIN * 60)
44#define TM_DAY (TM_HOUR * 24) 44#define TM_DAY (TM_HOUR * 24)
45#define TM_WEEK (TM_DAY * 7) 45#define TM_WEEK (TM_DAY * 7)
46#define TM_YEAR (TM_DAY * 365) 46#define TM_YEAR (TM_DAY * 365)
47#define TM_MONTH (TM_YEAR / 12.0) 47#define TM_MONTH (TM_YEAR / 12.0)
48 48
49 49
50typedef void (*configfn)(const char *name, const char *value); 50typedef void (*configfn)(const char *name, const char *value);
51typedef void (*filepair_fn)(struct diff_filepair *pair); 51typedef void (*filepair_fn)(struct diff_filepair *pair);
52typedef void (*linediff_fn)(char *line, int len); 52typedef void (*linediff_fn)(char *line, int len);
53 53
54struct cacheitem { 54struct cacheitem {
55 char *name; 55 char *name;
56 struct stat st; 56 struct stat st;
57 int ttl; 57 int ttl;
58 int fd; 58 int fd;
59}; 59};
60 60
61struct repoinfo { 61struct repoinfo {
62 char *url; 62 char *url;
63 char *name; 63 char *name;
64 char *path; 64 char *path;
65 char *desc; 65 char *desc;
66 char *owner; 66 char *owner;
67 char *defbranch; 67 char *defbranch;
68 char *group; 68 char *group;
69 char *module_link; 69 char *module_link;
70 char *readme; 70 char *readme;
71 int snapshots; 71 int snapshots;
72 int enable_log_filecount; 72 int enable_log_filecount;
73 int enable_log_linecount; 73 int enable_log_linecount;
74}; 74};
75 75
76struct repolist { 76struct repolist {
77 int length; 77 int length;
78 int count; 78 int count;
79 struct repoinfo *repos; 79 struct repoinfo *repos;
80}; 80};
81 81
82struct commitinfo { 82struct commitinfo {
83 struct commit *commit; 83 struct commit *commit;
84 char *author; 84 char *author;
85 char *author_email; 85 char *author_email;
86 unsigned long author_date; 86 unsigned long author_date;
87 char *committer; 87 char *committer;
88 char *committer_email; 88 char *committer_email;
89 unsigned long committer_date; 89 unsigned long committer_date;
90 char *subject; 90 char *subject;
91 char *msg; 91 char *msg;
92}; 92};
93 93
94struct taginfo { 94struct taginfo {
95 char *tagger; 95 char *tagger;
96 char *tagger_email; 96 char *tagger_email;
97 int tagger_date; 97 int tagger_date;
98 char *msg; 98 char *msg;
99}; 99};
100 100
101extern const char cgit_version[]; 101extern const char *cgit_version;
102 102
103extern struct repolist cgit_repolist; 103extern struct repolist cgit_repolist;
104extern struct repoinfo *cgit_repo; 104extern struct repoinfo *cgit_repo;
105extern int cgit_cmd; 105extern int cgit_cmd;
106 106
107extern char *cgit_root_title; 107extern char *cgit_root_title;
108extern char *cgit_css; 108extern char *cgit_css;
109extern char *cgit_logo; 109extern char *cgit_logo;
110extern char *cgit_index_header; 110extern char *cgit_index_header;
111extern char *cgit_logo_link; 111extern char *cgit_logo_link;
112extern char *cgit_module_link; 112extern char *cgit_module_link;
113extern char *cgit_agefile; 113extern char *cgit_agefile;
114extern char *cgit_virtual_root; 114extern char *cgit_virtual_root;
115extern char *cgit_script_name; 115extern char *cgit_script_name;
116extern char *cgit_cache_root; 116extern char *cgit_cache_root;
117extern char *cgit_repo_group; 117extern char *cgit_repo_group;
118 118
119extern int cgit_nocache; 119extern int cgit_nocache;
120extern int cgit_snapshots; 120extern int cgit_snapshots;
121extern int cgit_enable_log_filecount; 121extern int cgit_enable_log_filecount;
122extern int cgit_enable_log_linecount; 122extern int cgit_enable_log_linecount;
123extern int cgit_max_lock_attempts; 123extern int cgit_max_lock_attempts;
124extern int cgit_cache_root_ttl; 124extern int cgit_cache_root_ttl;
125extern int cgit_cache_repo_ttl; 125extern int cgit_cache_repo_ttl;
126extern int cgit_cache_dynamic_ttl; 126extern int cgit_cache_dynamic_ttl;
127extern int cgit_cache_static_ttl; 127extern int cgit_cache_static_ttl;
128extern int cgit_cache_max_create_time; 128extern int cgit_cache_max_create_time;
129extern int cgit_summary_log; 129extern int cgit_summary_log;
130 130
131extern int cgit_max_msg_len; 131extern int cgit_max_msg_len;
132extern int cgit_max_repodesc_len; 132extern int cgit_max_repodesc_len;
133extern int cgit_max_commit_count; 133extern int cgit_max_commit_count;
134 134
135extern int cgit_query_has_symref; 135extern int cgit_query_has_symref;
136extern int cgit_query_has_sha1; 136extern int cgit_query_has_sha1;
137 137
138extern char *cgit_querystring; 138extern char *cgit_querystring;
139extern char *cgit_query_repo; 139extern char *cgit_query_repo;
140extern char *cgit_query_page; 140extern char *cgit_query_page;
141extern char *cgit_query_search; 141extern char *cgit_query_search;
142extern char *cgit_query_head; 142extern char *cgit_query_head;
143extern char *cgit_query_sha1; 143extern char *cgit_query_sha1;
144extern char *cgit_query_sha2; 144extern char *cgit_query_sha2;
145extern char *cgit_query_path; 145extern char *cgit_query_path;
146extern char *cgit_query_name; 146extern char *cgit_query_name;
147extern int cgit_query_ofs; 147extern int cgit_query_ofs;
148 148
149extern int htmlfd; 149extern int htmlfd;
150 150
151extern int cgit_get_cmd_index(const char *cmd); 151extern int cgit_get_cmd_index(const char *cmd);
152extern struct repoinfo *cgit_get_repoinfo(const char *url); 152extern struct repoinfo *cgit_get_repoinfo(const char *url);
153extern void cgit_global_config_cb(const char *name, const char *value); 153extern void cgit_global_config_cb(const char *name, const char *value);
154extern void cgit_repo_config_cb(const char *name, const char *value); 154extern void cgit_repo_config_cb(const char *name, const char *value);
155extern void cgit_querystring_cb(const char *name, const char *value); 155extern void cgit_querystring_cb(const char *name, const char *value);
156 156
157extern int chk_zero(int result, char *msg); 157extern int chk_zero(int result, char *msg);
158extern int chk_positive(int result, char *msg); 158extern int chk_positive(int result, char *msg);
159 159
160extern int hextoint(char c); 160extern int hextoint(char c);
161 161
162extern void *cgit_free_commitinfo(struct commitinfo *info); 162extern void *cgit_free_commitinfo(struct commitinfo *info);
163 163
164extern int cgit_diff_files(const unsigned char *old_sha1, 164extern int cgit_diff_files(const unsigned char *old_sha1,
165 const unsigned char *new_sha1, 165 const unsigned char *new_sha1,
diff --git a/gen-version.sh b/gen-version.sh
new file mode 100755
index 0000000..4c60f60
--- a/dev/null
+++ b/gen-version.sh
@@ -0,0 +1,4 @@
1v=$(git-describe --abbrev=4 HEAD | sed -e 's/-/./g')
2test -z "$v" && exit 1
3echo "CGIT_VERSION = $v"
4echo "CGIT_VERSION = $v" > VERSION
diff --git a/shared.c b/shared.c
index f20fb5c..f7f43b2 100644
--- a/shared.c
+++ b/shared.c
@@ -1,78 +1,80 @@
1/* shared.c: global vars + some callback functions 1/* shared.c: global vars + some callback functions
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10 10
11struct repolist cgit_repolist; 11struct repolist cgit_repolist;
12struct repoinfo *cgit_repo; 12struct repoinfo *cgit_repo;
13int cgit_cmd; 13int cgit_cmd;
14 14
15const char *cgit_version = CGIT_VERSION;
16
15char *cgit_root_title = "Git repository browser"; 17char *cgit_root_title = "Git repository browser";
16char *cgit_css = "/cgit.css"; 18char *cgit_css = "/cgit.css";
17char *cgit_logo = "/git-logo.png"; 19char *cgit_logo = "/git-logo.png";
18char *cgit_index_header = NULL; 20char *cgit_index_header = NULL;
19char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; 21char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/";
20char *cgit_module_link = "./?repo=%s&page=commit&id=%s"; 22char *cgit_module_link = "./?repo=%s&page=commit&id=%s";
21char *cgit_agefile = "info/web/last-modified"; 23char *cgit_agefile = "info/web/last-modified";
22char *cgit_virtual_root = NULL; 24char *cgit_virtual_root = NULL;
23char *cgit_script_name = CGIT_SCRIPT_NAME; 25char *cgit_script_name = CGIT_SCRIPT_NAME;
24char *cgit_cache_root = "/var/cache/cgit"; 26char *cgit_cache_root = "/var/cache/cgit";
25char *cgit_repo_group = NULL; 27char *cgit_repo_group = NULL;
26 28
27int cgit_nocache = 0; 29int cgit_nocache = 0;
28int cgit_snapshots = 0; 30int cgit_snapshots = 0;
29int cgit_enable_log_filecount = 0; 31int cgit_enable_log_filecount = 0;
30int cgit_enable_log_linecount = 0; 32int cgit_enable_log_linecount = 0;
31int cgit_max_lock_attempts = 5; 33int cgit_max_lock_attempts = 5;
32int cgit_cache_root_ttl = 5; 34int cgit_cache_root_ttl = 5;
33int cgit_cache_repo_ttl = 5; 35int cgit_cache_repo_ttl = 5;
34int cgit_cache_dynamic_ttl = 5; 36int cgit_cache_dynamic_ttl = 5;
35int cgit_cache_static_ttl = -1; 37int cgit_cache_static_ttl = -1;
36int cgit_cache_max_create_time = 5; 38int cgit_cache_max_create_time = 5;
37int cgit_summary_log = 0; 39int cgit_summary_log = 0;
38 40
39int cgit_max_msg_len = 60; 41int cgit_max_msg_len = 60;
40int cgit_max_repodesc_len = 60; 42int cgit_max_repodesc_len = 60;
41int cgit_max_commit_count = 50; 43int cgit_max_commit_count = 50;
42 44
43int cgit_query_has_symref = 0; 45int cgit_query_has_symref = 0;
44int cgit_query_has_sha1 = 0; 46int cgit_query_has_sha1 = 0;
45 47
46char *cgit_querystring = NULL; 48char *cgit_querystring = NULL;
47char *cgit_query_repo = NULL; 49char *cgit_query_repo = NULL;
48char *cgit_query_page = NULL; 50char *cgit_query_page = NULL;
49char *cgit_query_head = NULL; 51char *cgit_query_head = NULL;
50char *cgit_query_search = NULL; 52char *cgit_query_search = NULL;
51char *cgit_query_sha1 = NULL; 53char *cgit_query_sha1 = NULL;
52char *cgit_query_sha2 = NULL; 54char *cgit_query_sha2 = NULL;
53char *cgit_query_path = NULL; 55char *cgit_query_path = NULL;
54char *cgit_query_name = NULL; 56char *cgit_query_name = NULL;
55int cgit_query_ofs = 0; 57int cgit_query_ofs = 0;
56 58
57int htmlfd = 0; 59int htmlfd = 0;
58 60
59 61
60int cgit_get_cmd_index(const char *cmd) 62int cgit_get_cmd_index(const char *cmd)
61{ 63{
62 static char *cmds[] = {"log", "commit", "diff", "tree", "blob", 64 static char *cmds[] = {"log", "commit", "diff", "tree", "blob",
63 "snapshot", NULL}; 65 "snapshot", NULL};
64 int i; 66 int i;
65 67
66 for(i = 0; cmds[i]; i++) 68 for(i = 0; cmds[i]; i++)
67 if (!strcmp(cmd, cmds[i])) 69 if (!strcmp(cmd, cmds[i]))
68 return i + 1; 70 return i + 1;
69 return 0; 71 return 0;
70} 72}
71 73
72int chk_zero(int result, char *msg) 74int chk_zero(int result, char *msg)
73{ 75{
74 if (result != 0) 76 if (result != 0)
75 die("%s: %s", msg, strerror(errno)); 77 die("%s: %s", msg, strerror(errno));
76 return result; 78 return result;
77} 79}
78 80
diff --git a/ui-shared.c b/ui-shared.c
index 15d8254..110c696 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -201,129 +201,129 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
201void cgit_print_date(time_t secs, char *format) 201void cgit_print_date(time_t secs, char *format)
202{ 202{
203 char buf[64]; 203 char buf[64];
204 struct tm *time; 204 struct tm *time;
205 205
206 time = gmtime(&secs); 206 time = gmtime(&secs);
207 strftime(buf, sizeof(buf)-1, format, time); 207 strftime(buf, sizeof(buf)-1, format, time);
208 html_txt(buf); 208 html_txt(buf);
209} 209}
210 210
211void cgit_print_age(time_t t, time_t max_relative, char *format) 211void cgit_print_age(time_t t, time_t max_relative, char *format)
212{ 212{
213 time_t now, secs; 213 time_t now, secs;
214 214
215 time(&now); 215 time(&now);
216 secs = now - t; 216 secs = now - t;
217 217
218 if (secs > max_relative && max_relative >= 0) { 218 if (secs > max_relative && max_relative >= 0) {
219 cgit_print_date(t, format); 219 cgit_print_date(t, format);
220 return; 220 return;
221 } 221 }
222 222
223 if (secs < TM_HOUR * 2) { 223 if (secs < TM_HOUR * 2) {
224 htmlf("<span class='age-mins'>%.0f min.</span>", 224 htmlf("<span class='age-mins'>%.0f min.</span>",
225 secs * 1.0 / TM_MIN); 225 secs * 1.0 / TM_MIN);
226 return; 226 return;
227 } 227 }
228 if (secs < TM_DAY * 2) { 228 if (secs < TM_DAY * 2) {
229 htmlf("<span class='age-hours'>%.0f hours</span>", 229 htmlf("<span class='age-hours'>%.0f hours</span>",
230 secs * 1.0 / TM_HOUR); 230 secs * 1.0 / TM_HOUR);
231 return; 231 return;
232 } 232 }
233 if (secs < TM_WEEK * 2) { 233 if (secs < TM_WEEK * 2) {
234 htmlf("<span class='age-days'>%.0f days</span>", 234 htmlf("<span class='age-days'>%.0f days</span>",
235 secs * 1.0 / TM_DAY); 235 secs * 1.0 / TM_DAY);
236 return; 236 return;
237 } 237 }
238 if (secs < TM_MONTH * 2) { 238 if (secs < TM_MONTH * 2) {
239 htmlf("<span class='age-weeks'>%.0f weeks</span>", 239 htmlf("<span class='age-weeks'>%.0f weeks</span>",
240 secs * 1.0 / TM_WEEK); 240 secs * 1.0 / TM_WEEK);
241 return; 241 return;
242 } 242 }
243 if (secs < TM_YEAR * 2) { 243 if (secs < TM_YEAR * 2) {
244 htmlf("<span class='age-months'>%.0f months</span>", 244 htmlf("<span class='age-months'>%.0f months</span>",
245 secs * 1.0 / TM_MONTH); 245 secs * 1.0 / TM_MONTH);
246 return; 246 return;
247 } 247 }
248 htmlf("<span class='age-years'>%.0f years</span>", 248 htmlf("<span class='age-years'>%.0f years</span>",
249 secs * 1.0 / TM_YEAR); 249 secs * 1.0 / TM_YEAR);
250} 250}
251 251
252void cgit_print_docstart(char *title, struct cacheitem *item) 252void cgit_print_docstart(char *title, struct cacheitem *item)
253{ 253{
254 html("Content-Type: text/html; charset=utf-8\n"); 254 html("Content-Type: text/html; charset=utf-8\n");
255 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); 255 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime));
256 htmlf("Expires: %s\n", http_date(item->st.st_mtime + 256 htmlf("Expires: %s\n", http_date(item->st.st_mtime +
257 ttl_seconds(item->ttl))); 257 ttl_seconds(item->ttl)));
258 html("\n"); 258 html("\n");
259 html(cgit_doctype); 259 html(cgit_doctype);
260 html("<html>\n"); 260 html("<html>\n");
261 html("<head>\n"); 261 html("<head>\n");
262 html("<title>"); 262 html("<title>");
263 html_txt(title); 263 html_txt(title);
264 html("</title>\n"); 264 html("</title>\n");
265 htmlf("<meta name='generator' content='cgit v%s'/>\n", cgit_version); 265 htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version);
266 html("<link rel='stylesheet' type='text/css' href='"); 266 html("<link rel='stylesheet' type='text/css' href='");
267 html_attr(cgit_css); 267 html_attr(cgit_css);
268 html("'/>\n"); 268 html("'/>\n");
269 html("</head>\n"); 269 html("</head>\n");
270 html("<body>\n"); 270 html("<body>\n");
271} 271}
272 272
273void cgit_print_docend() 273void cgit_print_docend()
274{ 274{
275 html("</td></tr></table>"); 275 html("</td></tr></table>");
276 html("</body>\n</html>\n"); 276 html("</body>\n</html>\n");
277} 277}
278 278
279void cgit_print_pageheader(char *title, int show_search) 279void cgit_print_pageheader(char *title, int show_search)
280{ 280{
281 html("<table id='layout'>"); 281 html("<table id='layout'>");
282 html("<tr><td id='header'>"); 282 html("<tr><td id='header'>");
283 html(cgit_root_title); 283 html(cgit_root_title);
284 html("</td><td id='logo'>"); 284 html("</td><td id='logo'>");
285 html("<a href='"); 285 html("<a href='");
286 html_attr(cgit_logo_link); 286 html_attr(cgit_logo_link);
287 htmlf("'><img src='%s' alt='logo'/></a>", cgit_logo); 287 htmlf("'><img src='%s' alt='logo'/></a>", cgit_logo);
288 html("</td></tr>"); 288 html("</td></tr>");
289 html("<tr><td id='crumb'>"); 289 html("<tr><td id='crumb'>");
290 htmlf("<a href='%s'>root</a>", cgit_rooturl()); 290 htmlf("<a href='%s'>root</a>", cgit_rooturl());
291 if (cgit_query_repo) { 291 if (cgit_query_repo) {
292 htmlf(" : <a href='%s'>", cgit_repourl(cgit_repo->url)); 292 htmlf(" : <a href='%s'>", cgit_repourl(cgit_repo->url));
293 html_txt(cgit_repo->name); 293 html_txt(cgit_repo->name);
294 htmlf("</a> : %s", title); 294 htmlf("</a> : %s", title);
295 } 295 }
296 html("</td>"); 296 html("</td>");
297 html("<td id='search'>"); 297 html("<td id='search'>");
298 if (show_search) { 298 if (show_search) {
299 html("<form method='get' action='"); 299 html("<form method='get' action='");
300 html_attr(cgit_currurl()); 300 html_attr(cgit_currurl());
301 html("'>"); 301 html("'>");
302 if (!cgit_virtual_root) { 302 if (!cgit_virtual_root) {
303 if (cgit_query_repo) 303 if (cgit_query_repo)
304 html_hidden("r", cgit_query_repo); 304 html_hidden("r", cgit_query_repo);
305 if (cgit_query_page) 305 if (cgit_query_page)
306 html_hidden("p", cgit_query_page); 306 html_hidden("p", cgit_query_page);
307 } 307 }
308 if (cgit_query_head) 308 if (cgit_query_head)
309 html_hidden("h", cgit_query_head); 309 html_hidden("h", cgit_query_head);
310 if (cgit_query_sha1) 310 if (cgit_query_sha1)
311 html_hidden("id", cgit_query_sha1); 311 html_hidden("id", cgit_query_sha1);
312 if (cgit_query_sha2) 312 if (cgit_query_sha2)
313 html_hidden("id2", cgit_query_sha2); 313 html_hidden("id2", cgit_query_sha2);
314 html("<input type='text' name='q' value='"); 314 html("<input type='text' name='q' value='");
315 html_attr(cgit_query_search); 315 html_attr(cgit_query_search);
316 html("'/></form>"); 316 html("'/></form>");
317 } 317 }
318 html("</td></tr>"); 318 html("</td></tr>");
319 html("<tr><td id='content' colspan='2'>"); 319 html("<tr><td id='content' colspan='2'>");
320} 320}
321 321
322void cgit_print_snapshot_start(const char *mimetype, const char *filename, 322void cgit_print_snapshot_start(const char *mimetype, const char *filename,
323 struct cacheitem *item) 323 struct cacheitem *item)
324{ 324{
325 htmlf("Content-Type: %s\n", mimetype); 325 htmlf("Content-Type: %s\n", mimetype);
326 htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename); 326 htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename);
327 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); 327 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime));
328 htmlf("Expires: %s\n", http_date(item->st.st_mtime + 328 htmlf("Expires: %s\n", http_date(item->st.st_mtime +
329 ttl_seconds(item->ttl))); 329 ttl_seconds(item->ttl)));