-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | cgit.c | 3 | ||||
-rw-r--r-- | cgit.h | 5 | ||||
-rw-r--r-- | shared.c | 2 | ||||
-rw-r--r-- | ui-shared.c | 24 | ||||
-rw-r--r-- | ui-summary.c | 33 | ||||
-rw-r--r-- | ui-tag.c | 74 |
7 files changed, 111 insertions, 32 deletions
@@ -1,58 +1,58 @@ | |||
1 | prefix = /var/www/htdocs/cgit | 1 | prefix = /var/www/htdocs/cgit |
2 | SHA1_HEADER = <openssl/sha.h> | 2 | SHA1_HEADER = <openssl/sha.h> |
3 | CACHE_ROOT = /var/cache/cgit | 3 | CACHE_ROOT = /var/cache/cgit |
4 | CGIT_CONFIG = /etc/cgitrc | 4 | CGIT_CONFIG = /etc/cgitrc |
5 | CGIT_SCRIPT_NAME = cgit.cgi | 5 | CGIT_SCRIPT_NAME = cgit.cgi |
6 | 6 | ||
7 | # | 7 | # |
8 | # Let the user override the above settings. | 8 | # Let the user override the above settings. |
9 | # | 9 | # |
10 | -include cgit.conf | 10 | -include cgit.conf |
11 | 11 | ||
12 | 12 | ||
13 | CGIT_VERSION = 0.5 | 13 | CGIT_VERSION = 0.5 |
14 | 14 | ||
15 | all: cgit | 15 | all: cgit |
16 | 16 | ||
17 | VERSION: | 17 | VERSION: |
18 | sh gen-version.sh | 18 | sh gen-version.sh |
19 | 19 | ||
20 | -include VERSION | 20 | -include VERSION |
21 | 21 | ||
22 | 22 | ||
23 | EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto | 23 | EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto |
24 | OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ | 24 | OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ |
25 | 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 \ |
26 | ui-snapshot.o ui-blob.o | 26 | ui-snapshot.o ui-blob.o ui-tag.o |
27 | 27 | ||
28 | CFLAGS += -Wall | 28 | CFLAGS += -Wall |
29 | 29 | ||
30 | ifdef DEBUG | 30 | ifdef DEBUG |
31 | CFLAGS += -g | 31 | CFLAGS += -g |
32 | endif | 32 | endif |
33 | 33 | ||
34 | CFLAGS += -Igit | 34 | CFLAGS += -Igit |
35 | CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)' | 35 | CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)' |
36 | CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"' | 36 | CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"' |
37 | CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"' | 37 | CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"' |
38 | CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"' | 38 | CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"' |
39 | 39 | ||
40 | 40 | ||
41 | # | 41 | # |
42 | # 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. |
43 | # | 43 | # |
44 | GITVER = $(shell git version 2>/dev/null || echo nogit) | 44 | GITVER = $(shell git version 2>/dev/null || echo nogit) |
45 | ifeq ($(GITVER),nogit) | 45 | ifeq ($(GITVER),nogit) |
46 | GITURL = http://www.kernel.org/pub/software/scm/git/git-1.5.2.tar.bz2 | 46 | GITURL = http://www.kernel.org/pub/software/scm/git/git-1.5.2.tar.bz2 |
47 | INITGIT = test -e git/git.c || ((curl "$(GITURL)" | tar -xj) && mv git-1.5.2 git) | 47 | INITGIT = test -e git/git.c || ((curl "$(GITURL)" | tar -xj) && mv git-1.5.2 git) |
48 | else | 48 | else |
49 | INITGIT = ./submodules.sh -i | 49 | INITGIT = ./submodules.sh -i |
50 | endif | 50 | endif |
51 | 51 | ||
52 | 52 | ||
53 | cgit: cgit.c cgit.h VERSION $(OBJECTS) | 53 | cgit: cgit.c cgit.h VERSION $(OBJECTS) |
54 | $(CC) $(CFLAGS) cgit.c -o cgit $(OBJECTS) $(EXTLIBS) | 54 | $(CC) $(CFLAGS) cgit.c -o cgit $(OBJECTS) $(EXTLIBS) |
55 | 55 | ||
56 | $(OBJECTS): cgit.h git/libgit.a | 56 | $(OBJECTS): cgit.h git/libgit.a |
57 | 57 | ||
58 | git/libgit.a: | 58 | git/libgit.a: |
@@ -72,64 +72,67 @@ static void cgit_print_repo_page(struct cacheitem *item) | |||
72 | cgit_repo->url, cgit_query_name); | 72 | cgit_repo->url, cgit_query_name); |
73 | return; | 73 | return; |
74 | } | 74 | } |
75 | 75 | ||
76 | if (cgit_cmd == CMD_BLOB) { | 76 | if (cgit_cmd == CMD_BLOB) { |
77 | cgit_print_blob(item, cgit_query_sha1, cgit_query_path); | 77 | cgit_print_blob(item, cgit_query_sha1, cgit_query_path); |
78 | return; | 78 | return; |
79 | } | 79 | } |
80 | 80 | ||
81 | show_search = (cgit_cmd == CMD_LOG); | 81 | show_search = (cgit_cmd == CMD_LOG); |
82 | cgit_print_docstart(title, item); | 82 | cgit_print_docstart(title, item); |
83 | if (!cgit_cmd) { | 83 | if (!cgit_cmd) { |
84 | cgit_print_pageheader("summary", show_search); | 84 | cgit_print_pageheader("summary", show_search); |
85 | cgit_print_summary(); | 85 | cgit_print_summary(); |
86 | cgit_print_docend(); | 86 | cgit_print_docend(); |
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | 89 | ||
90 | cgit_print_pageheader(cgit_query_page, show_search); | 90 | cgit_print_pageheader(cgit_query_page, show_search); |
91 | 91 | ||
92 | switch(cgit_cmd) { | 92 | switch(cgit_cmd) { |
93 | case CMD_LOG: | 93 | case CMD_LOG: |
94 | cgit_print_log(cgit_query_sha1, cgit_query_ofs, | 94 | cgit_print_log(cgit_query_sha1, cgit_query_ofs, |
95 | cgit_max_commit_count, cgit_query_search, | 95 | cgit_max_commit_count, cgit_query_search, |
96 | cgit_query_path, 1); | 96 | cgit_query_path, 1); |
97 | break; | 97 | break; |
98 | case CMD_TREE: | 98 | case CMD_TREE: |
99 | cgit_print_tree(cgit_query_sha1, cgit_query_path); | 99 | cgit_print_tree(cgit_query_sha1, cgit_query_path); |
100 | break; | 100 | break; |
101 | case CMD_COMMIT: | 101 | case CMD_COMMIT: |
102 | cgit_print_commit(cgit_query_sha1); | 102 | cgit_print_commit(cgit_query_sha1); |
103 | break; | 103 | break; |
104 | case CMD_TAG: | ||
105 | cgit_print_tag(cgit_query_sha1); | ||
106 | break; | ||
104 | case CMD_DIFF: | 107 | case CMD_DIFF: |
105 | cgit_print_diff(cgit_query_sha1, cgit_query_sha2); | 108 | cgit_print_diff(cgit_query_sha1, cgit_query_sha2); |
106 | break; | 109 | break; |
107 | default: | 110 | default: |
108 | cgit_print_error("Invalid request"); | 111 | cgit_print_error("Invalid request"); |
109 | } | 112 | } |
110 | cgit_print_docend(); | 113 | cgit_print_docend(); |
111 | } | 114 | } |
112 | 115 | ||
113 | static void cgit_fill_cache(struct cacheitem *item, int use_cache) | 116 | static void cgit_fill_cache(struct cacheitem *item, int use_cache) |
114 | { | 117 | { |
115 | static char buf[PATH_MAX]; | 118 | static char buf[PATH_MAX]; |
116 | int stdout2; | 119 | int stdout2; |
117 | 120 | ||
118 | getcwd(buf, sizeof(buf)); | 121 | getcwd(buf, sizeof(buf)); |
119 | item->st.st_mtime = time(NULL); | 122 | item->st.st_mtime = time(NULL); |
120 | 123 | ||
121 | if (use_cache) { | 124 | if (use_cache) { |
122 | stdout2 = chk_positive(dup(STDOUT_FILENO), | 125 | stdout2 = chk_positive(dup(STDOUT_FILENO), |
123 | "Preserving STDOUT"); | 126 | "Preserving STDOUT"); |
124 | chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); | 127 | chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); |
125 | chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); | 128 | chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); |
126 | } | 129 | } |
127 | 130 | ||
128 | if (cgit_repo) | 131 | if (cgit_repo) |
129 | cgit_print_repo_page(item); | 132 | cgit_print_repo_page(item); |
130 | else | 133 | else |
131 | cgit_print_repolist(item); | 134 | cgit_print_repolist(item); |
132 | 135 | ||
133 | if (use_cache) { | 136 | if (use_cache) { |
134 | chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); | 137 | chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); |
135 | chk_positive(dup2(stdout2, STDOUT_FILENO), | 138 | chk_positive(dup2(stdout2, STDOUT_FILENO), |
@@ -1,62 +1,62 @@ | |||
1 | #ifndef CGIT_H | 1 | #ifndef CGIT_H |
2 | #define CGIT_H | 2 | #define CGIT_H |
3 | 3 | ||
4 | 4 | ||
5 | #include <git-compat-util.h> | 5 | #include <git-compat-util.h> |
6 | #include <cache.h> | 6 | #include <cache.h> |
7 | #include <grep.h> | 7 | #include <grep.h> |
8 | #include <object.h> | 8 | #include <object.h> |
9 | #include <tree.h> | 9 | #include <tree.h> |
10 | #include <commit.h> | 10 | #include <commit.h> |
11 | #include <tag.h> | 11 | #include <tag.h> |
12 | #include <diff.h> | 12 | #include <diff.h> |
13 | #include <diffcore.h> | 13 | #include <diffcore.h> |
14 | #include <refs.h> | 14 | #include <refs.h> |
15 | #include <revision.h> | 15 | #include <revision.h> |
16 | #include <log-tree.h> | 16 | #include <log-tree.h> |
17 | #include <archive.h> | 17 | #include <archive.h> |
18 | #include <xdiff/xdiff.h> | 18 | #include <xdiff/xdiff.h> |
19 | 19 | ||
20 | 20 | ||
21 | /* | 21 | /* |
22 | * The valid cgit repo-commands | 22 | * The valid cgit repo-commands |
23 | */ | 23 | */ |
24 | #define CMD_LOG 1 | 24 | #define CMD_LOG 1 |
25 | #define CMD_COMMIT 2 | 25 | #define CMD_COMMIT 2 |
26 | #define CMD_DIFF 3 | 26 | #define CMD_DIFF 3 |
27 | #define CMD_TREE 4 | 27 | #define CMD_TREE 4 |
28 | #define CMD_BLOB 5 | 28 | #define CMD_BLOB 5 |
29 | #define CMD_SNAPSHOT 6 | 29 | #define CMD_SNAPSHOT 6 |
30 | 30 | #define CMD_TAG 7 | |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Dateformats used on misc. pages | 33 | * Dateformats used on misc. pages |
34 | */ | 34 | */ |
35 | #define FMT_LONGDATE "%Y-%m-%d %H:%M:%S" | 35 | #define FMT_LONGDATE "%Y-%m-%d %H:%M:%S" |
36 | #define FMT_SHORTDATE "%Y-%m-%d" | 36 | #define FMT_SHORTDATE "%Y-%m-%d" |
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 | ||
50 | typedef void (*configfn)(const char *name, const char *value); | 50 | typedef void (*configfn)(const char *name, const char *value); |
51 | typedef void (*filepair_fn)(struct diff_filepair *pair); | 51 | typedef void (*filepair_fn)(struct diff_filepair *pair); |
52 | typedef void (*linediff_fn)(char *line, int len); | 52 | typedef void (*linediff_fn)(char *line, int len); |
53 | 53 | ||
54 | struct cacheitem { | 54 | struct 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 | ||
61 | struct repoinfo { | 61 | struct repoinfo { |
62 | char *url; | 62 | char *url; |
@@ -183,54 +183,57 @@ extern void html_attr(char *txt); | |||
183 | extern void html_hidden(char *name, char *value); | 183 | extern void html_hidden(char *name, char *value); |
184 | extern void html_link_open(char *url, char *title, char *class); | 184 | extern void html_link_open(char *url, char *title, char *class); |
185 | extern void html_link_close(void); | 185 | extern void html_link_close(void); |
186 | extern void html_filemode(unsigned short mode); | 186 | extern void html_filemode(unsigned short mode); |
187 | extern int html_include(const char *filename); | 187 | extern int html_include(const char *filename); |
188 | 188 | ||
189 | extern int cgit_read_config(const char *filename, configfn fn); | 189 | extern int cgit_read_config(const char *filename, configfn fn); |
190 | extern int cgit_parse_query(char *txt, configfn fn); | 190 | extern int cgit_parse_query(char *txt, configfn fn); |
191 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); | 191 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); |
192 | extern struct taginfo *cgit_parse_tag(struct tag *tag); | 192 | extern struct taginfo *cgit_parse_tag(struct tag *tag); |
193 | extern void cgit_parse_url(const char *url); | 193 | extern void cgit_parse_url(const char *url); |
194 | 194 | ||
195 | extern char *cache_safe_filename(const char *unsafe); | 195 | extern char *cache_safe_filename(const char *unsafe); |
196 | extern int cache_lock(struct cacheitem *item); | 196 | extern int cache_lock(struct cacheitem *item); |
197 | extern int cache_unlock(struct cacheitem *item); | 197 | extern int cache_unlock(struct cacheitem *item); |
198 | extern int cache_cancel_lock(struct cacheitem *item); | 198 | extern int cache_cancel_lock(struct cacheitem *item); |
199 | extern int cache_exist(struct cacheitem *item); | 199 | extern int cache_exist(struct cacheitem *item); |
200 | extern int cache_expired(struct cacheitem *item); | 200 | extern int cache_expired(struct cacheitem *item); |
201 | 201 | ||
202 | extern char *cgit_repourl(const char *reponame); | 202 | extern char *cgit_repourl(const char *reponame); |
203 | extern char *cgit_pageurl(const char *reponame, const char *pagename, | 203 | extern char *cgit_pageurl(const char *reponame, const char *pagename, |
204 | const char *query); | 204 | const char *query); |
205 | 205 | ||
206 | extern void cgit_tree_link(char *name, char *title, char *class, char *head, | 206 | extern void cgit_tree_link(char *name, char *title, char *class, char *head, |
207 | char *rev, char *path); | 207 | char *rev, char *path); |
208 | extern void cgit_log_link(char *name, char *title, char *class, char *head, | 208 | extern void cgit_log_link(char *name, char *title, char *class, char *head, |
209 | char *rev, char *path, int ofs); | 209 | char *rev, char *path, int ofs); |
210 | extern void cgit_commit_link(char *name, char *title, char *class, char *head, | 210 | extern void cgit_commit_link(char *name, char *title, char *class, char *head, |
211 | char *rev); | 211 | char *rev); |
212 | extern void cgit_diff_link(char *name, char *title, char *class, char *head, | 212 | extern void cgit_diff_link(char *name, char *title, char *class, char *head, |
213 | char *new_rev, char *old_rev, char *path); | 213 | char *new_rev, char *old_rev, char *path); |
214 | 214 | ||
215 | extern void cgit_object_link(struct object *obj); | ||
216 | |||
215 | extern void cgit_print_error(char *msg); | 217 | extern void cgit_print_error(char *msg); |
216 | extern void cgit_print_date(time_t secs, char *format); | 218 | extern void cgit_print_date(time_t secs, char *format); |
217 | extern void cgit_print_age(time_t t, time_t max_relative, char *format); | 219 | extern void cgit_print_age(time_t t, time_t max_relative, char *format); |
218 | extern void cgit_print_docstart(char *title, struct cacheitem *item); | 220 | extern void cgit_print_docstart(char *title, struct cacheitem *item); |
219 | extern void cgit_print_docend(); | 221 | extern void cgit_print_docend(); |
220 | extern void cgit_print_pageheader(char *title, int show_search); | 222 | extern void cgit_print_pageheader(char *title, int show_search); |
221 | extern void cgit_print_snapshot_start(const char *mimetype, | 223 | extern void cgit_print_snapshot_start(const char *mimetype, |
222 | const char *filename, | 224 | const char *filename, |
223 | struct cacheitem *item); | 225 | struct cacheitem *item); |
224 | 226 | ||
225 | extern void cgit_print_repolist(struct cacheitem *item); | 227 | extern void cgit_print_repolist(struct cacheitem *item); |
226 | extern void cgit_print_summary(); | 228 | extern void cgit_print_summary(); |
227 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path, int pager); | 229 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path, int pager); |
228 | extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); | 230 | extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); |
229 | extern void cgit_print_tree(const char *rev, char *path); | 231 | extern void cgit_print_tree(const char *rev, char *path); |
230 | extern void cgit_print_commit(char *hex); | 232 | extern void cgit_print_commit(char *hex); |
233 | extern void cgit_print_tag(char *revname); | ||
231 | extern void cgit_print_diff(const char *new_hex, const char *old_hex); | 234 | extern void cgit_print_diff(const char *new_hex, const char *old_hex); |
232 | extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, | 235 | extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, |
233 | const char *format, const char *prefix, | 236 | const char *format, const char *prefix, |
234 | const char *filename); | 237 | const char *filename); |
235 | 238 | ||
236 | #endif /* CGIT_H */ | 239 | #endif /* CGIT_H */ |
@@ -34,65 +34,65 @@ int cgit_enable_log_linecount = 0; | |||
34 | int cgit_max_lock_attempts = 5; | 34 | int cgit_max_lock_attempts = 5; |
35 | int cgit_cache_root_ttl = 5; | 35 | int cgit_cache_root_ttl = 5; |
36 | int cgit_cache_repo_ttl = 5; | 36 | int cgit_cache_repo_ttl = 5; |
37 | int cgit_cache_dynamic_ttl = 5; | 37 | int cgit_cache_dynamic_ttl = 5; |
38 | int cgit_cache_static_ttl = -1; | 38 | int cgit_cache_static_ttl = -1; |
39 | int cgit_cache_max_create_time = 5; | 39 | int cgit_cache_max_create_time = 5; |
40 | int cgit_summary_log = 0; | 40 | int cgit_summary_log = 0; |
41 | 41 | ||
42 | int cgit_max_msg_len = 60; | 42 | int cgit_max_msg_len = 60; |
43 | int cgit_max_repodesc_len = 60; | 43 | int cgit_max_repodesc_len = 60; |
44 | int cgit_max_commit_count = 50; | 44 | int cgit_max_commit_count = 50; |
45 | 45 | ||
46 | int cgit_query_has_symref = 0; | 46 | int cgit_query_has_symref = 0; |
47 | int cgit_query_has_sha1 = 0; | 47 | int cgit_query_has_sha1 = 0; |
48 | 48 | ||
49 | char *cgit_querystring = NULL; | 49 | char *cgit_querystring = NULL; |
50 | char *cgit_query_repo = NULL; | 50 | char *cgit_query_repo = NULL; |
51 | char *cgit_query_page = NULL; | 51 | char *cgit_query_page = NULL; |
52 | char *cgit_query_head = NULL; | 52 | char *cgit_query_head = NULL; |
53 | char *cgit_query_search = NULL; | 53 | char *cgit_query_search = NULL; |
54 | char *cgit_query_sha1 = NULL; | 54 | char *cgit_query_sha1 = NULL; |
55 | char *cgit_query_sha2 = NULL; | 55 | char *cgit_query_sha2 = NULL; |
56 | char *cgit_query_path = NULL; | 56 | char *cgit_query_path = NULL; |
57 | char *cgit_query_name = NULL; | 57 | char *cgit_query_name = NULL; |
58 | int cgit_query_ofs = 0; | 58 | int cgit_query_ofs = 0; |
59 | 59 | ||
60 | int htmlfd = 0; | 60 | int htmlfd = 0; |
61 | 61 | ||
62 | 62 | ||
63 | int cgit_get_cmd_index(const char *cmd) | 63 | int cgit_get_cmd_index(const char *cmd) |
64 | { | 64 | { |
65 | static char *cmds[] = {"log", "commit", "diff", "tree", "blob", | 65 | static char *cmds[] = {"log", "commit", "diff", "tree", "blob", |
66 | "snapshot", NULL}; | 66 | "snapshot", "tag", NULL}; |
67 | int i; | 67 | int i; |
68 | 68 | ||
69 | for(i = 0; cmds[i]; i++) | 69 | for(i = 0; cmds[i]; i++) |
70 | if (!strcmp(cmd, cmds[i])) | 70 | if (!strcmp(cmd, cmds[i])) |
71 | return i + 1; | 71 | return i + 1; |
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | int chk_zero(int result, char *msg) | 75 | int chk_zero(int result, char *msg) |
76 | { | 76 | { |
77 | if (result != 0) | 77 | if (result != 0) |
78 | die("%s: %s", msg, strerror(errno)); | 78 | die("%s: %s", msg, strerror(errno)); |
79 | return result; | 79 | return result; |
80 | } | 80 | } |
81 | 81 | ||
82 | int chk_positive(int result, char *msg) | 82 | int chk_positive(int result, char *msg) |
83 | { | 83 | { |
84 | if (result <= 0) | 84 | if (result <= 0) |
85 | die("%s: %s", msg, strerror(errno)); | 85 | die("%s: %s", msg, strerror(errno)); |
86 | return result; | 86 | return result; |
87 | } | 87 | } |
88 | 88 | ||
89 | struct repoinfo *add_repo(const char *url) | 89 | struct repoinfo *add_repo(const char *url) |
90 | { | 90 | { |
91 | struct repoinfo *ret; | 91 | struct repoinfo *ret; |
92 | 92 | ||
93 | if (++cgit_repolist.count > cgit_repolist.length) { | 93 | if (++cgit_repolist.count > cgit_repolist.length) { |
94 | if (cgit_repolist.length == 0) | 94 | if (cgit_repolist.length == 0) |
95 | cgit_repolist.length = 8; | 95 | cgit_repolist.length = 8; |
96 | else | 96 | else |
97 | cgit_repolist.length *= 2; | 97 | cgit_repolist.length *= 2; |
98 | cgit_repolist.repos = xrealloc(cgit_repolist.repos, | 98 | cgit_repolist.repos = xrealloc(cgit_repolist.repos, |
diff --git a/ui-shared.c b/ui-shared.c index d4376ce..fd71c12 100644 --- a/ui-shared.c +++ b/ui-shared.c | |||
@@ -189,64 +189,88 @@ void cgit_commit_link(char *name, char *title, char *class, char *head, | |||
189 | { | 189 | { |
190 | if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) { | 190 | if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) { |
191 | name[cgit_max_msg_len] = '\0'; | 191 | name[cgit_max_msg_len] = '\0'; |
192 | name[cgit_max_msg_len - 1] = '.'; | 192 | name[cgit_max_msg_len - 1] = '.'; |
193 | name[cgit_max_msg_len - 2] = '.'; | 193 | name[cgit_max_msg_len - 2] = '.'; |
194 | name[cgit_max_msg_len - 3] = '.'; | 194 | name[cgit_max_msg_len - 3] = '.'; |
195 | } | 195 | } |
196 | reporevlink("commit", name, title, class, head, rev, NULL); | 196 | reporevlink("commit", name, title, class, head, rev, NULL); |
197 | } | 197 | } |
198 | 198 | ||
199 | void cgit_diff_link(char *name, char *title, char *class, char *head, | 199 | void cgit_diff_link(char *name, char *title, char *class, char *head, |
200 | char *new_rev, char *old_rev, char *path) | 200 | char *new_rev, char *old_rev, char *path) |
201 | { | 201 | { |
202 | char *delim; | 202 | char *delim; |
203 | 203 | ||
204 | delim = repolink(title, class, "diff", head, path); | 204 | delim = repolink(title, class, "diff", head, path); |
205 | if (new_rev && strcmp(new_rev, cgit_query_head)) { | 205 | if (new_rev && strcmp(new_rev, cgit_query_head)) { |
206 | html(delim); | 206 | html(delim); |
207 | html("id="); | 207 | html("id="); |
208 | html_attr(new_rev); | 208 | html_attr(new_rev); |
209 | delim = "&"; | 209 | delim = "&"; |
210 | } | 210 | } |
211 | if (old_rev) { | 211 | if (old_rev) { |
212 | html(delim); | 212 | html(delim); |
213 | html("id2="); | 213 | html("id2="); |
214 | html_attr(old_rev); | 214 | html_attr(old_rev); |
215 | } | 215 | } |
216 | html("'>"); | 216 | html("'>"); |
217 | html_txt(name); | 217 | html_txt(name); |
218 | html("</a>"); | 218 | html("</a>"); |
219 | } | 219 | } |
220 | 220 | ||
221 | void cgit_object_link(struct object *obj) | ||
222 | { | ||
223 | char *page, *arg, *url; | ||
224 | |||
225 | if (obj->type == OBJ_COMMIT) { | ||
226 | cgit_commit_link(fmt("commit %s", sha1_to_hex(obj->sha1)), NULL, NULL, | ||
227 | cgit_query_head, sha1_to_hex(obj->sha1)); | ||
228 | return; | ||
229 | } else if (obj->type == OBJ_TREE) { | ||
230 | page = "tree"; | ||
231 | arg = "id"; | ||
232 | } else { | ||
233 | page = "blob"; | ||
234 | arg = "id"; | ||
235 | } | ||
236 | |||
237 | url = cgit_pageurl(cgit_query_repo, page, | ||
238 | fmt("%s=%s", arg, sha1_to_hex(obj->sha1))); | ||
239 | html_link_open(url, NULL, NULL); | ||
240 | htmlf("%s %s", typename(obj->type), | ||
241 | sha1_to_hex(obj->sha1)); | ||
242 | html_link_close(); | ||
243 | } | ||
244 | |||
221 | void cgit_print_date(time_t secs, char *format) | 245 | void cgit_print_date(time_t secs, char *format) |
222 | { | 246 | { |
223 | char buf[64]; | 247 | char buf[64]; |
224 | struct tm *time; | 248 | struct tm *time; |
225 | 249 | ||
226 | time = gmtime(&secs); | 250 | time = gmtime(&secs); |
227 | strftime(buf, sizeof(buf)-1, format, time); | 251 | strftime(buf, sizeof(buf)-1, format, time); |
228 | html_txt(buf); | 252 | html_txt(buf); |
229 | } | 253 | } |
230 | 254 | ||
231 | void cgit_print_age(time_t t, time_t max_relative, char *format) | 255 | void cgit_print_age(time_t t, time_t max_relative, char *format) |
232 | { | 256 | { |
233 | time_t now, secs; | 257 | time_t now, secs; |
234 | 258 | ||
235 | time(&now); | 259 | time(&now); |
236 | secs = now - t; | 260 | secs = now - t; |
237 | 261 | ||
238 | if (secs > max_relative && max_relative >= 0) { | 262 | if (secs > max_relative && max_relative >= 0) { |
239 | cgit_print_date(t, format); | 263 | cgit_print_date(t, format); |
240 | return; | 264 | return; |
241 | } | 265 | } |
242 | 266 | ||
243 | if (secs < TM_HOUR * 2) { | 267 | if (secs < TM_HOUR * 2) { |
244 | htmlf("<span class='age-mins'>%.0f min.</span>", | 268 | htmlf("<span class='age-mins'>%.0f min.</span>", |
245 | secs * 1.0 / TM_MIN); | 269 | secs * 1.0 / TM_MIN); |
246 | return; | 270 | return; |
247 | } | 271 | } |
248 | if (secs < TM_DAY * 2) { | 272 | if (secs < TM_DAY * 2) { |
249 | htmlf("<span class='age-hours'>%.0f hours</span>", | 273 | htmlf("<span class='age-hours'>%.0f hours</span>", |
250 | secs * 1.0 / TM_HOUR); | 274 | secs * 1.0 / TM_HOUR); |
251 | return; | 275 | return; |
252 | } | 276 | } |
diff --git a/ui-summary.c b/ui-summary.c index b4bc6d8..de8a180 100644 --- a/ui-summary.c +++ b/ui-summary.c | |||
@@ -18,138 +18,113 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, | |||
18 | char buf[256]; | 18 | char buf[256]; |
19 | char *ref; | 19 | char *ref; |
20 | 20 | ||
21 | ref = xstrdup(refname); | 21 | ref = xstrdup(refname); |
22 | strncpy(buf, refname, sizeof(buf)); | 22 | strncpy(buf, refname, sizeof(buf)); |
23 | commit = lookup_commit(sha1); | 23 | commit = lookup_commit(sha1); |
24 | // object is not really parsed at this point, because of some fallout | 24 | // object is not really parsed at this point, because of some fallout |
25 | // from previous calls to git functions in cgit_print_log() | 25 | // from previous calls to git functions in cgit_print_log() |
26 | commit->object.parsed = 0; | 26 | commit->object.parsed = 0; |
27 | if (commit && !parse_commit(commit)){ | 27 | if (commit && !parse_commit(commit)){ |
28 | info = cgit_parse_commit(commit); | 28 | info = cgit_parse_commit(commit); |
29 | html("<tr><td>"); | 29 | html("<tr><td>"); |
30 | cgit_log_link(ref, NULL, NULL, ref, NULL, NULL, 0); | 30 | cgit_log_link(ref, NULL, NULL, ref, NULL, NULL, 0); |
31 | html("</td><td>"); | 31 | html("</td><td>"); |
32 | cgit_print_age(commit->date, -1, NULL); | 32 | cgit_print_age(commit->date, -1, NULL); |
33 | html("</td><td>"); | 33 | html("</td><td>"); |
34 | html_txt(info->author); | 34 | html_txt(info->author); |
35 | html("</td><td>"); | 35 | html("</td><td>"); |
36 | cgit_commit_link(info->subject, NULL, NULL, ref, NULL); | 36 | cgit_commit_link(info->subject, NULL, NULL, ref, NULL); |
37 | html("</td></tr>\n"); | 37 | html("</td></tr>\n"); |
38 | cgit_free_commitinfo(info); | 38 | cgit_free_commitinfo(info); |
39 | } else { | 39 | } else { |
40 | html("<tr><td>"); | 40 | html("<tr><td>"); |
41 | html_txt(buf); | 41 | html_txt(buf); |
42 | html("</td><td colspan='3'>"); | 42 | html("</td><td colspan='3'>"); |
43 | htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); | 43 | htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); |
44 | html("</td></tr>\n"); | 44 | html("</td></tr>\n"); |
45 | } | 45 | } |
46 | free(ref); | 46 | free(ref); |
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | |||
51 | static void cgit_print_object_ref(struct object *obj) | ||
52 | { | ||
53 | char *page, *arg, *url; | ||
54 | |||
55 | if (obj->type == OBJ_COMMIT) { | ||
56 | cgit_commit_link(fmt("commit %s", sha1_to_hex(obj->sha1)), NULL, NULL, | ||
57 | cgit_query_head, sha1_to_hex(obj->sha1)); | ||
58 | return; | ||
59 | } else if (obj->type == OBJ_TREE) { | ||
60 | page = "tree"; | ||
61 | arg = "id"; | ||
62 | } else { | ||
63 | page = "view"; | ||
64 | arg = "id"; | ||
65 | } | ||
66 | |||
67 | url = cgit_pageurl(cgit_query_repo, page, | ||
68 | fmt("%s=%s", arg, sha1_to_hex(obj->sha1))); | ||
69 | html_link_open(url, NULL, NULL); | ||
70 | htmlf("%s %s", typename(obj->type), | ||
71 | sha1_to_hex(obj->sha1)); | ||
72 | html_link_close(); | ||
73 | } | ||
74 | |||
75 | static void print_tag_header() | 50 | static void print_tag_header() |
76 | { | 51 | { |
77 | html("<tr class='nohover'><th class='left'>Tag</th>" | 52 | html("<tr class='nohover'><th class='left'>Tag</th>" |
78 | "<th class='left'>Age</th>" | 53 | "<th class='left'>Age</th>" |
79 | "<th class='left'>Author</th>" | 54 | "<th class='left'>Author</th>" |
80 | "<th class='left'>Reference</th></tr>\n"); | 55 | "<th class='left'>Reference</th></tr>\n"); |
81 | header = 1; | 56 | header = 1; |
82 | } | 57 | } |
83 | 58 | ||
84 | static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, | 59 | static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, |
85 | int flags, void *cb_data) | 60 | int flags, void *cb_data) |
86 | { | 61 | { |
87 | struct tag *tag; | 62 | struct tag *tag; |
88 | struct taginfo *info; | 63 | struct taginfo *info; |
89 | struct object *obj; | 64 | struct object *obj; |
90 | char buf[256], *url; | 65 | char buf[256], *url; |
91 | 66 | ||
92 | strncpy(buf, refname, sizeof(buf)); | 67 | strncpy(buf, refname, sizeof(buf)); |
93 | obj = parse_object(sha1); | 68 | obj = parse_object(sha1); |
94 | if (!obj) | 69 | if (!obj) |
95 | return 1; | 70 | return 1; |
96 | if (obj->type == OBJ_TAG) { | 71 | if (obj->type == OBJ_TAG) { |
97 | tag = lookup_tag(sha1); | 72 | tag = lookup_tag(sha1); |
98 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) | 73 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) |
99 | return 2; | 74 | return 2; |
100 | if (!header) | 75 | if (!header) |
101 | print_tag_header(); | 76 | print_tag_header(); |
102 | html("<tr><td>"); | 77 | html("<tr><td>"); |
103 | url = cgit_pageurl(cgit_query_repo, "view", | 78 | url = cgit_pageurl(cgit_query_repo, "tag", |
104 | fmt("id=%s", sha1_to_hex(sha1))); | 79 | fmt("id=%s", refname)); |
105 | html_link_open(url, NULL, NULL); | 80 | html_link_open(url, NULL, NULL); |
106 | html_txt(buf); | 81 | html_txt(buf); |
107 | html_link_close(); | 82 | html_link_close(); |
108 | html("</td><td>"); | 83 | html("</td><td>"); |
109 | if (info->tagger_date > 0) | 84 | if (info->tagger_date > 0) |
110 | cgit_print_age(info->tagger_date, -1, NULL); | 85 | cgit_print_age(info->tagger_date, -1, NULL); |
111 | html("</td><td>"); | 86 | html("</td><td>"); |
112 | if (info->tagger) | 87 | if (info->tagger) |
113 | html(info->tagger); | 88 | html(info->tagger); |
114 | html("</td><td>"); | 89 | html("</td><td>"); |
115 | cgit_print_object_ref(tag->tagged); | 90 | cgit_object_link(tag->tagged); |
116 | html("</td></tr>\n"); | 91 | html("</td></tr>\n"); |
117 | } else { | 92 | } else { |
118 | if (!header) | 93 | if (!header) |
119 | print_tag_header(); | 94 | print_tag_header(); |
120 | html("<tr><td>"); | 95 | html("<tr><td>"); |
121 | html_txt(buf); | 96 | html_txt(buf); |
122 | html("</td><td colspan='2'/><td>"); | 97 | html("</td><td colspan='2'/><td>"); |
123 | cgit_print_object_ref(obj); | 98 | cgit_object_link(obj); |
124 | html("</td></tr>\n"); | 99 | html("</td></tr>\n"); |
125 | } | 100 | } |
126 | return 0; | 101 | return 0; |
127 | } | 102 | } |
128 | 103 | ||
129 | static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1, | 104 | static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1, |
130 | int flags, void *cb_data) | 105 | int flags, void *cb_data) |
131 | { | 106 | { |
132 | struct tag *tag; | 107 | struct tag *tag; |
133 | struct taginfo *info; | 108 | struct taginfo *info; |
134 | struct object *obj; | 109 | struct object *obj; |
135 | char buf[256], *url; | 110 | char buf[256], *url; |
136 | unsigned char fileid[20]; | 111 | unsigned char fileid[20]; |
137 | 112 | ||
138 | if (prefixcmp(refname, "refs/archives")) | 113 | if (prefixcmp(refname, "refs/archives")) |
139 | return 0; | 114 | return 0; |
140 | strncpy(buf, refname+14, sizeof(buf)); | 115 | strncpy(buf, refname+14, sizeof(buf)); |
141 | obj = parse_object(sha1); | 116 | obj = parse_object(sha1); |
142 | if (!obj) | 117 | if (!obj) |
143 | return 1; | 118 | return 1; |
144 | if (obj->type == OBJ_TAG) { | 119 | if (obj->type == OBJ_TAG) { |
145 | tag = lookup_tag(sha1); | 120 | tag = lookup_tag(sha1); |
146 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) | 121 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) |
147 | return 0; | 122 | return 0; |
148 | hashcpy(fileid, tag->tagged->sha1); | 123 | hashcpy(fileid, tag->tagged->sha1); |
149 | } else if (obj->type != OBJ_BLOB) { | 124 | } else if (obj->type != OBJ_BLOB) { |
150 | return 0; | 125 | return 0; |
151 | } else { | 126 | } else { |
152 | hashcpy(fileid, sha1); | 127 | hashcpy(fileid, sha1); |
153 | } | 128 | } |
154 | if (!header) { | 129 | if (!header) { |
155 | html("<table id='downloads'>"); | 130 | html("<table id='downloads'>"); |
diff --git a/ui-tag.c b/ui-tag.c new file mode 100644 index 0000000..a6989ff --- a/dev/null +++ b/ui-tag.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* ui-tag.c: display a tag | ||
2 | * | ||
3 | * Copyright (C) 2007 Lars Hjemli | ||
4 | * | ||
5 | * Licensed under GNU General Public License v2 | ||
6 | * (see COPYING for full license text) | ||
7 | */ | ||
8 | |||
9 | #include "cgit.h" | ||
10 | |||
11 | |||
12 | static void print_tag_content(char *buf) | ||
13 | { | ||
14 | char *p; | ||
15 | |||
16 | if (!buf) | ||
17 | return; | ||
18 | |||
19 | html("<div class='commit-subject'>"); | ||
20 | p = strchr(buf, '\n'); | ||
21 | if (p) | ||
22 | *p = '\0'; | ||
23 | html_txt(buf); | ||
24 | html("</div>"); | ||
25 | if (p) { | ||
26 | html("<div class='commit-msg'>"); | ||
27 | html_txt(++p); | ||
28 | html("</div>"); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | void cgit_print_tag(char *revname) | ||
33 | { | ||
34 | unsigned char sha1[20]; | ||
35 | struct object *obj; | ||
36 | struct tag *tag; | ||
37 | struct taginfo *info; | ||
38 | |||
39 | if (get_sha1(revname, sha1)) { | ||
40 | cgit_print_error(fmt("Bad tag reference: %s", revname)); | ||
41 | return; | ||
42 | } | ||
43 | obj = parse_object(sha1); | ||
44 | if (!obj) { | ||
45 | cgit_print_error(fmt("Bad object id: %s", sha1_to_hex(sha1))); | ||
46 | return; | ||
47 | } | ||
48 | if (obj->type == OBJ_TAG) { | ||
49 | tag = lookup_tag(sha1); | ||
50 | if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) { | ||
51 | cgit_print_error(fmt("Bad tag object: %s", revname)); | ||
52 | return; | ||
53 | } | ||
54 | html("<table class='commit-info'>\n"); | ||
55 | htmlf("<tr><td>Tag name</td><td>%s (%s)</td></tr>\n", | ||
56 | revname, sha1_to_hex(sha1)); | ||
57 | if (info->tagger_date > 0) { | ||
58 | html("<tr><td>Tag date</td><td>"); | ||
59 | cgit_print_date(info->tagger_date, FMT_LONGDATE); | ||
60 | html("</td><tr>\n"); | ||
61 | } | ||
62 | if (info->tagger) { | ||
63 | html("<tr><td>Tagged by</td><td>"); | ||
64 | html_txt(info->tagger); | ||
65 | html("</td></tr>\n"); | ||
66 | } | ||
67 | html("<tr><td>Tagged object</td><td>"); | ||
68 | cgit_object_link(tag->tagged); | ||
69 | html("</td></tr>\n"); | ||
70 | html("</table>\n"); | ||
71 | print_tag_content(info->msg); | ||
72 | } | ||
73 | return; | ||
74 | } | ||