author | Lars Hjemli <hjemli@gmail.com> | 2007-05-13 15:15:06 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2007-05-13 15:15:06 (UTC) |
commit | c6cf3a424a0860d69b290254d9b19d35527b2d27 (patch) (unidiff) | |
tree | 2874f2c42e907cba1187ae32ee686daebc2de59e | |
parent | 80e577c3ef2a73becabff7e9c9c242f317a87de9 (diff) | |
download | cgit-c6cf3a424a0860d69b290254d9b19d35527b2d27.zip cgit-c6cf3a424a0860d69b290254d9b19d35527b2d27.tar.gz cgit-c6cf3a424a0860d69b290254d9b19d35527b2d27.tar.bz2 |
Add max-commit-count parameter to cgitrc
This enabled customizing number of commits shown per page in log view. It
also changes the default from 100 to 50, mainly due to the more cpu
intensive log pages (number of files/lines changed) but also since 100
log messages requires excessive scrolling.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cgit.c | 4 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | cgitrc | 4 | ||||
-rw-r--r-- | shared.c | 3 |
4 files changed, 10 insertions, 2 deletions
@@ -1,259 +1,259 @@ | |||
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 | ||
11 | const char cgit_version[] = CGIT_VERSION; | 11 | const char cgit_version[] = CGIT_VERSION; |
12 | 12 | ||
13 | 13 | ||
14 | static struct repoinfo *cgit_get_repoinfo(char *url) | 14 | static struct repoinfo *cgit_get_repoinfo(char *url) |
15 | { | 15 | { |
16 | int i; | 16 | int i; |
17 | struct repoinfo *repo; | 17 | struct repoinfo *repo; |
18 | 18 | ||
19 | for (i=0; i<cgit_repolist.count; i++) { | 19 | for (i=0; i<cgit_repolist.count; i++) { |
20 | repo = &cgit_repolist.repos[i]; | 20 | repo = &cgit_repolist.repos[i]; |
21 | if (!strcmp(repo->url, url)) | 21 | if (!strcmp(repo->url, url)) |
22 | return repo; | 22 | return repo; |
23 | } | 23 | } |
24 | return NULL; | 24 | return NULL; |
25 | } | 25 | } |
26 | 26 | ||
27 | 27 | ||
28 | static int cgit_prepare_cache(struct cacheitem *item) | 28 | static int cgit_prepare_cache(struct cacheitem *item) |
29 | { | 29 | { |
30 | if (!cgit_query_repo) { | 30 | if (!cgit_query_repo) { |
31 | item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); | 31 | item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); |
32 | item->ttl = cgit_cache_root_ttl; | 32 | item->ttl = cgit_cache_root_ttl; |
33 | return 1; | 33 | return 1; |
34 | } | 34 | } |
35 | cgit_repo = cgit_get_repoinfo(cgit_query_repo); | 35 | cgit_repo = cgit_get_repoinfo(cgit_query_repo); |
36 | if (!cgit_repo) { | 36 | if (!cgit_repo) { |
37 | char *title = fmt("%s - %s", cgit_root_title, "Bad request"); | 37 | char *title = fmt("%s - %s", cgit_root_title, "Bad request"); |
38 | cgit_print_docstart(title, item); | 38 | cgit_print_docstart(title, item); |
39 | cgit_print_pageheader(title, 0); | 39 | cgit_print_pageheader(title, 0); |
40 | cgit_print_error(fmt("Unknown repo: %s", cgit_query_repo)); | 40 | cgit_print_error(fmt("Unknown repo: %s", cgit_query_repo)); |
41 | cgit_print_docend(); | 41 | cgit_print_docend(); |
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | if (!cgit_query_page) { | 45 | if (!cgit_query_page) { |
46 | item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, | 46 | item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, |
47 | cgit_repo->url)); | 47 | cgit_repo->url)); |
48 | item->ttl = cgit_cache_repo_ttl; | 48 | item->ttl = cgit_cache_repo_ttl; |
49 | } else { | 49 | } else { |
50 | item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, | 50 | item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, |
51 | cgit_repo->url, cgit_query_page, | 51 | cgit_repo->url, cgit_query_page, |
52 | cache_safe_filename(cgit_querystring))); | 52 | cache_safe_filename(cgit_querystring))); |
53 | if (cgit_query_has_symref) | 53 | if (cgit_query_has_symref) |
54 | item->ttl = cgit_cache_dynamic_ttl; | 54 | item->ttl = cgit_cache_dynamic_ttl; |
55 | else if (cgit_query_has_sha1) | 55 | else if (cgit_query_has_sha1) |
56 | item->ttl = cgit_cache_static_ttl; | 56 | item->ttl = cgit_cache_static_ttl; |
57 | else | 57 | else |
58 | item->ttl = cgit_cache_repo_ttl; | 58 | item->ttl = cgit_cache_repo_ttl; |
59 | } | 59 | } |
60 | return 1; | 60 | return 1; |
61 | } | 61 | } |
62 | 62 | ||
63 | static void cgit_print_repo_page(struct cacheitem *item) | 63 | static void cgit_print_repo_page(struct cacheitem *item) |
64 | { | 64 | { |
65 | char *title; | 65 | char *title; |
66 | int show_search; | 66 | int show_search; |
67 | 67 | ||
68 | if (chdir(cgit_repo->path)) { | 68 | if (chdir(cgit_repo->path)) { |
69 | title = fmt("%s - %s", cgit_root_title, "Bad request"); | 69 | title = fmt("%s - %s", cgit_root_title, "Bad request"); |
70 | cgit_print_docstart(title, item); | 70 | cgit_print_docstart(title, item); |
71 | cgit_print_pageheader(title, 0); | 71 | cgit_print_pageheader(title, 0); |
72 | cgit_print_error(fmt("Unable to scan repository: %s", | 72 | cgit_print_error(fmt("Unable to scan repository: %s", |
73 | strerror(errno))); | 73 | strerror(errno))); |
74 | cgit_print_docend(); | 74 | cgit_print_docend(); |
75 | return; | 75 | return; |
76 | } | 76 | } |
77 | 77 | ||
78 | title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); | 78 | title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); |
79 | show_search = 0; | 79 | show_search = 0; |
80 | setenv("GIT_DIR", cgit_repo->path, 1); | 80 | setenv("GIT_DIR", cgit_repo->path, 1); |
81 | 81 | ||
82 | if (cgit_query_page) { | 82 | if (cgit_query_page) { |
83 | if (cgit_repo->snapshots && !strcmp(cgit_query_page, "snapshot")) { | 83 | if (cgit_repo->snapshots && !strcmp(cgit_query_page, "snapshot")) { |
84 | cgit_print_snapshot(item, cgit_query_sha1, "zip", | 84 | cgit_print_snapshot(item, cgit_query_sha1, "zip", |
85 | cgit_repo->url, cgit_query_name); | 85 | cgit_repo->url, cgit_query_name); |
86 | return; | 86 | return; |
87 | } | 87 | } |
88 | if (!strcmp(cgit_query_page, "blob")) { | 88 | if (!strcmp(cgit_query_page, "blob")) { |
89 | cgit_print_blob(item, cgit_query_sha1, cgit_query_path); | 89 | cgit_print_blob(item, cgit_query_sha1, cgit_query_path); |
90 | return; | 90 | return; |
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | if (cgit_query_page && !strcmp(cgit_query_page, "log")) | 94 | if (cgit_query_page && !strcmp(cgit_query_page, "log")) |
95 | show_search = 1; | 95 | show_search = 1; |
96 | 96 | ||
97 | cgit_print_docstart(title, item); | 97 | cgit_print_docstart(title, item); |
98 | 98 | ||
99 | 99 | ||
100 | if (!cgit_query_page) { | 100 | if (!cgit_query_page) { |
101 | cgit_print_pageheader("summary", show_search); | 101 | cgit_print_pageheader("summary", show_search); |
102 | cgit_print_summary(); | 102 | cgit_print_summary(); |
103 | cgit_print_docend(); | 103 | cgit_print_docend(); |
104 | return; | 104 | return; |
105 | } | 105 | } |
106 | 106 | ||
107 | cgit_print_pageheader(cgit_query_page, show_search); | 107 | cgit_print_pageheader(cgit_query_page, show_search); |
108 | 108 | ||
109 | if (!strcmp(cgit_query_page, "log")) { | 109 | if (!strcmp(cgit_query_page, "log")) { |
110 | cgit_print_log(cgit_query_head, cgit_query_ofs, 100, | 110 | cgit_print_log(cgit_query_head, cgit_query_ofs, |
111 | cgit_query_search); | 111 | cgit_max_commit_count, cgit_query_search); |
112 | } else if (!strcmp(cgit_query_page, "tree")) { | 112 | } else if (!strcmp(cgit_query_page, "tree")) { |
113 | cgit_print_tree(cgit_query_sha1, cgit_query_path); | 113 | cgit_print_tree(cgit_query_sha1, cgit_query_path); |
114 | } else if (!strcmp(cgit_query_page, "commit")) { | 114 | } else if (!strcmp(cgit_query_page, "commit")) { |
115 | cgit_print_commit(cgit_query_sha1); | 115 | cgit_print_commit(cgit_query_sha1); |
116 | } else if (!strcmp(cgit_query_page, "view")) { | 116 | } else if (!strcmp(cgit_query_page, "view")) { |
117 | cgit_print_view(cgit_query_sha1, cgit_query_path); | 117 | cgit_print_view(cgit_query_sha1, cgit_query_path); |
118 | } else if (!strcmp(cgit_query_page, "diff")) { | 118 | } else if (!strcmp(cgit_query_page, "diff")) { |
119 | cgit_print_diff(cgit_query_sha1, cgit_query_sha2); | 119 | cgit_print_diff(cgit_query_sha1, cgit_query_sha2); |
120 | } else { | 120 | } else { |
121 | cgit_print_error("Invalid request"); | 121 | cgit_print_error("Invalid request"); |
122 | } | 122 | } |
123 | cgit_print_docend(); | 123 | cgit_print_docend(); |
124 | } | 124 | } |
125 | 125 | ||
126 | static void cgit_fill_cache(struct cacheitem *item, int use_cache) | 126 | static void cgit_fill_cache(struct cacheitem *item, int use_cache) |
127 | { | 127 | { |
128 | static char buf[PATH_MAX]; | 128 | static char buf[PATH_MAX]; |
129 | int stdout2; | 129 | int stdout2; |
130 | 130 | ||
131 | getcwd(buf, sizeof(buf)); | 131 | getcwd(buf, sizeof(buf)); |
132 | item->st.st_mtime = time(NULL); | 132 | item->st.st_mtime = time(NULL); |
133 | 133 | ||
134 | if (use_cache) { | 134 | if (use_cache) { |
135 | stdout2 = chk_positive(dup(STDOUT_FILENO), | 135 | stdout2 = chk_positive(dup(STDOUT_FILENO), |
136 | "Preserving STDOUT"); | 136 | "Preserving STDOUT"); |
137 | chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); | 137 | chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); |
138 | chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); | 138 | chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); |
139 | } | 139 | } |
140 | 140 | ||
141 | if (cgit_query_repo) | 141 | if (cgit_query_repo) |
142 | cgit_print_repo_page(item); | 142 | cgit_print_repo_page(item); |
143 | else | 143 | else |
144 | cgit_print_repolist(item); | 144 | cgit_print_repolist(item); |
145 | 145 | ||
146 | if (use_cache) { | 146 | if (use_cache) { |
147 | chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); | 147 | chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); |
148 | chk_positive(dup2(stdout2, STDOUT_FILENO), | 148 | chk_positive(dup2(stdout2, STDOUT_FILENO), |
149 | "Restoring original STDOUT"); | 149 | "Restoring original STDOUT"); |
150 | chk_zero(close(stdout2), "Closing temporary STDOUT"); | 150 | chk_zero(close(stdout2), "Closing temporary STDOUT"); |
151 | } | 151 | } |
152 | 152 | ||
153 | chdir(buf); | 153 | chdir(buf); |
154 | } | 154 | } |
155 | 155 | ||
156 | static void cgit_check_cache(struct cacheitem *item) | 156 | static void cgit_check_cache(struct cacheitem *item) |
157 | { | 157 | { |
158 | int i = 0; | 158 | int i = 0; |
159 | 159 | ||
160 | top: | 160 | top: |
161 | if (++i > cgit_max_lock_attempts) { | 161 | if (++i > cgit_max_lock_attempts) { |
162 | die("cgit_refresh_cache: unable to lock %s: %s", | 162 | die("cgit_refresh_cache: unable to lock %s: %s", |
163 | item->name, strerror(errno)); | 163 | item->name, strerror(errno)); |
164 | } | 164 | } |
165 | if (!cache_exist(item)) { | 165 | if (!cache_exist(item)) { |
166 | if (!cache_lock(item)) { | 166 | if (!cache_lock(item)) { |
167 | sleep(1); | 167 | sleep(1); |
168 | goto top; | 168 | goto top; |
169 | } | 169 | } |
170 | if (!cache_exist(item)) { | 170 | if (!cache_exist(item)) { |
171 | cgit_fill_cache(item, 1); | 171 | cgit_fill_cache(item, 1); |
172 | cache_unlock(item); | 172 | cache_unlock(item); |
173 | } else { | 173 | } else { |
174 | cache_cancel_lock(item); | 174 | cache_cancel_lock(item); |
175 | } | 175 | } |
176 | } else if (cache_expired(item) && cache_lock(item)) { | 176 | } else if (cache_expired(item) && cache_lock(item)) { |
177 | if (cache_expired(item)) { | 177 | if (cache_expired(item)) { |
178 | cgit_fill_cache(item, 1); | 178 | cgit_fill_cache(item, 1); |
179 | cache_unlock(item); | 179 | cache_unlock(item); |
180 | } else { | 180 | } else { |
181 | cache_cancel_lock(item); | 181 | cache_cancel_lock(item); |
182 | } | 182 | } |
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | static void cgit_print_cache(struct cacheitem *item) | 186 | static void cgit_print_cache(struct cacheitem *item) |
187 | { | 187 | { |
188 | static char buf[4096]; | 188 | static char buf[4096]; |
189 | ssize_t i; | 189 | ssize_t i; |
190 | 190 | ||
191 | int fd = open(item->name, O_RDONLY); | 191 | int fd = open(item->name, O_RDONLY); |
192 | if (fd<0) | 192 | if (fd<0) |
193 | die("Unable to open cached file %s", item->name); | 193 | die("Unable to open cached file %s", item->name); |
194 | 194 | ||
195 | while((i=read(fd, buf, sizeof(buf))) > 0) | 195 | while((i=read(fd, buf, sizeof(buf))) > 0) |
196 | write(STDOUT_FILENO, buf, i); | 196 | write(STDOUT_FILENO, buf, i); |
197 | 197 | ||
198 | close(fd); | 198 | close(fd); |
199 | } | 199 | } |
200 | 200 | ||
201 | static void cgit_parse_args(int argc, const char **argv) | 201 | static void cgit_parse_args(int argc, const char **argv) |
202 | { | 202 | { |
203 | int i; | 203 | int i; |
204 | 204 | ||
205 | for (i = 1; i < argc; i++) { | 205 | for (i = 1; i < argc; i++) { |
206 | if (!strncmp(argv[i], "--cache=", 8)) { | 206 | if (!strncmp(argv[i], "--cache=", 8)) { |
207 | cgit_cache_root = xstrdup(argv[i]+8); | 207 | cgit_cache_root = xstrdup(argv[i]+8); |
208 | } | 208 | } |
209 | if (!strcmp(argv[i], "--nocache")) { | 209 | if (!strcmp(argv[i], "--nocache")) { |
210 | cgit_nocache = 1; | 210 | cgit_nocache = 1; |
211 | } | 211 | } |
212 | if (!strncmp(argv[i], "--query=", 8)) { | 212 | if (!strncmp(argv[i], "--query=", 8)) { |
213 | cgit_querystring = xstrdup(argv[i]+8); | 213 | cgit_querystring = xstrdup(argv[i]+8); |
214 | } | 214 | } |
215 | if (!strncmp(argv[i], "--repo=", 7)) { | 215 | if (!strncmp(argv[i], "--repo=", 7)) { |
216 | cgit_query_repo = xstrdup(argv[i]+7); | 216 | cgit_query_repo = xstrdup(argv[i]+7); |
217 | } | 217 | } |
218 | if (!strncmp(argv[i], "--page=", 7)) { | 218 | if (!strncmp(argv[i], "--page=", 7)) { |
219 | cgit_query_page = xstrdup(argv[i]+7); | 219 | cgit_query_page = xstrdup(argv[i]+7); |
220 | } | 220 | } |
221 | if (!strncmp(argv[i], "--head=", 7)) { | 221 | if (!strncmp(argv[i], "--head=", 7)) { |
222 | cgit_query_head = xstrdup(argv[i]+7); | 222 | cgit_query_head = xstrdup(argv[i]+7); |
223 | cgit_query_has_symref = 1; | 223 | cgit_query_has_symref = 1; |
224 | } | 224 | } |
225 | if (!strncmp(argv[i], "--sha1=", 7)) { | 225 | if (!strncmp(argv[i], "--sha1=", 7)) { |
226 | cgit_query_sha1 = xstrdup(argv[i]+7); | 226 | cgit_query_sha1 = xstrdup(argv[i]+7); |
227 | cgit_query_has_sha1 = 1; | 227 | cgit_query_has_sha1 = 1; |
228 | } | 228 | } |
229 | if (!strncmp(argv[i], "--ofs=", 6)) { | 229 | if (!strncmp(argv[i], "--ofs=", 6)) { |
230 | cgit_query_ofs = atoi(argv[i]+6); | 230 | cgit_query_ofs = atoi(argv[i]+6); |
231 | } | 231 | } |
232 | } | 232 | } |
233 | } | 233 | } |
234 | 234 | ||
235 | int main(int argc, const char **argv) | 235 | int main(int argc, const char **argv) |
236 | { | 236 | { |
237 | struct cacheitem item; | 237 | struct cacheitem item; |
238 | 238 | ||
239 | htmlfd = STDOUT_FILENO; | 239 | htmlfd = STDOUT_FILENO; |
240 | item.st.st_mtime = time(NULL); | 240 | item.st.st_mtime = time(NULL); |
241 | cgit_repolist.length = 0; | 241 | cgit_repolist.length = 0; |
242 | cgit_repolist.count = 0; | 242 | cgit_repolist.count = 0; |
243 | cgit_repolist.repos = NULL; | 243 | cgit_repolist.repos = NULL; |
244 | 244 | ||
245 | cgit_read_config("/etc/cgitrc", cgit_global_config_cb); | 245 | cgit_read_config("/etc/cgitrc", cgit_global_config_cb); |
246 | if (getenv("QUERY_STRING")) | 246 | if (getenv("QUERY_STRING")) |
247 | cgit_querystring = xstrdup(getenv("QUERY_STRING")); | 247 | cgit_querystring = xstrdup(getenv("QUERY_STRING")); |
248 | cgit_parse_args(argc, argv); | 248 | cgit_parse_args(argc, argv); |
249 | cgit_parse_query(cgit_querystring, cgit_querystring_cb); | 249 | cgit_parse_query(cgit_querystring, cgit_querystring_cb); |
250 | if (!cgit_prepare_cache(&item)) | 250 | if (!cgit_prepare_cache(&item)) |
251 | return 0; | 251 | return 0; |
252 | if (cgit_nocache) { | 252 | if (cgit_nocache) { |
253 | cgit_fill_cache(&item, 0); | 253 | cgit_fill_cache(&item, 0); |
254 | } else { | 254 | } else { |
255 | cgit_check_cache(&item); | 255 | cgit_check_cache(&item); |
256 | cgit_print_cache(&item); | 256 | cgit_print_cache(&item); |
257 | } | 257 | } |
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
@@ -1,181 +1,182 @@ | |||
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 | typedef void (*configfn)(const char *name, const char *value); | 21 | typedef void (*configfn)(const char *name, const char *value); |
22 | typedef void (*filepair_fn)(struct diff_filepair *pair); | 22 | typedef void (*filepair_fn)(struct diff_filepair *pair); |
23 | typedef void (*linediff_fn)(char *line, int len); | 23 | typedef void (*linediff_fn)(char *line, int len); |
24 | 24 | ||
25 | struct cacheitem { | 25 | struct cacheitem { |
26 | char *name; | 26 | char *name; |
27 | struct stat st; | 27 | struct stat st; |
28 | int ttl; | 28 | int ttl; |
29 | int fd; | 29 | int fd; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | struct repoinfo { | 32 | struct repoinfo { |
33 | char *url; | 33 | char *url; |
34 | char *name; | 34 | char *name; |
35 | char *path; | 35 | char *path; |
36 | char *desc; | 36 | char *desc; |
37 | char *owner; | 37 | char *owner; |
38 | char *module_link; | 38 | char *module_link; |
39 | int snapshots; | 39 | int snapshots; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct repolist { | 42 | struct repolist { |
43 | int length; | 43 | int length; |
44 | int count; | 44 | int count; |
45 | struct repoinfo *repos; | 45 | struct repoinfo *repos; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | struct commitinfo { | 48 | struct commitinfo { |
49 | struct commit *commit; | 49 | struct commit *commit; |
50 | char *author; | 50 | char *author; |
51 | char *author_email; | 51 | char *author_email; |
52 | unsigned long author_date; | 52 | unsigned long author_date; |
53 | char *committer; | 53 | char *committer; |
54 | char *committer_email; | 54 | char *committer_email; |
55 | unsigned long committer_date; | 55 | unsigned long committer_date; |
56 | char *subject; | 56 | char *subject; |
57 | char *msg; | 57 | char *msg; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct taginfo { | 60 | struct taginfo { |
61 | char *tagger; | 61 | char *tagger; |
62 | char *tagger_email; | 62 | char *tagger_email; |
63 | int tagger_date; | 63 | int tagger_date; |
64 | char *msg; | 64 | char *msg; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | extern const char cgit_version[]; | 67 | extern const char cgit_version[]; |
68 | 68 | ||
69 | extern struct repolist cgit_repolist; | 69 | extern struct repolist cgit_repolist; |
70 | extern struct repoinfo *cgit_repo; | 70 | extern struct repoinfo *cgit_repo; |
71 | 71 | ||
72 | extern char *cgit_root_title; | 72 | extern char *cgit_root_title; |
73 | extern char *cgit_css; | 73 | extern char *cgit_css; |
74 | extern char *cgit_logo; | 74 | extern char *cgit_logo; |
75 | extern char *cgit_logo_link; | 75 | extern char *cgit_logo_link; |
76 | extern char *cgit_module_link; | 76 | extern char *cgit_module_link; |
77 | extern char *cgit_virtual_root; | 77 | extern char *cgit_virtual_root; |
78 | extern char *cgit_cache_root; | 78 | extern char *cgit_cache_root; |
79 | 79 | ||
80 | extern int cgit_nocache; | 80 | extern int cgit_nocache; |
81 | extern int cgit_snapshots; | 81 | extern int cgit_snapshots; |
82 | extern int cgit_max_lock_attempts; | 82 | extern int cgit_max_lock_attempts; |
83 | extern int cgit_cache_root_ttl; | 83 | extern int cgit_cache_root_ttl; |
84 | extern int cgit_cache_repo_ttl; | 84 | extern int cgit_cache_repo_ttl; |
85 | extern int cgit_cache_dynamic_ttl; | 85 | extern int cgit_cache_dynamic_ttl; |
86 | extern int cgit_cache_static_ttl; | 86 | extern int cgit_cache_static_ttl; |
87 | extern int cgit_cache_max_create_time; | 87 | extern int cgit_cache_max_create_time; |
88 | 88 | ||
89 | extern int cgit_max_msg_len; | 89 | extern int cgit_max_msg_len; |
90 | extern int cgit_max_commit_count; | ||
90 | 91 | ||
91 | extern char *cgit_repo_name; | 92 | extern char *cgit_repo_name; |
92 | extern char *cgit_repo_desc; | 93 | extern char *cgit_repo_desc; |
93 | extern char *cgit_repo_owner; | 94 | extern char *cgit_repo_owner; |
94 | 95 | ||
95 | extern int cgit_query_has_symref; | 96 | extern int cgit_query_has_symref; |
96 | extern int cgit_query_has_sha1; | 97 | extern int cgit_query_has_sha1; |
97 | 98 | ||
98 | extern char *cgit_querystring; | 99 | extern char *cgit_querystring; |
99 | extern char *cgit_query_repo; | 100 | extern char *cgit_query_repo; |
100 | extern char *cgit_query_page; | 101 | extern char *cgit_query_page; |
101 | extern char *cgit_query_search; | 102 | extern char *cgit_query_search; |
102 | extern char *cgit_query_head; | 103 | extern char *cgit_query_head; |
103 | extern char *cgit_query_sha1; | 104 | extern char *cgit_query_sha1; |
104 | extern char *cgit_query_sha2; | 105 | extern char *cgit_query_sha2; |
105 | extern char *cgit_query_path; | 106 | extern char *cgit_query_path; |
106 | extern char *cgit_query_name; | 107 | extern char *cgit_query_name; |
107 | extern int cgit_query_ofs; | 108 | extern int cgit_query_ofs; |
108 | 109 | ||
109 | extern int htmlfd; | 110 | extern int htmlfd; |
110 | 111 | ||
111 | extern void cgit_global_config_cb(const char *name, const char *value); | 112 | extern void cgit_global_config_cb(const char *name, const char *value); |
112 | extern void cgit_repo_config_cb(const char *name, const char *value); | 113 | extern void cgit_repo_config_cb(const char *name, const char *value); |
113 | extern void cgit_querystring_cb(const char *name, const char *value); | 114 | extern void cgit_querystring_cb(const char *name, const char *value); |
114 | 115 | ||
115 | extern int chk_zero(int result, char *msg); | 116 | extern int chk_zero(int result, char *msg); |
116 | extern int chk_positive(int result, char *msg); | 117 | extern int chk_positive(int result, char *msg); |
117 | 118 | ||
118 | extern int hextoint(char c); | 119 | extern int hextoint(char c); |
119 | 120 | ||
120 | extern void *cgit_free_commitinfo(struct commitinfo *info); | 121 | extern void *cgit_free_commitinfo(struct commitinfo *info); |
121 | 122 | ||
122 | extern int cgit_diff_files(const unsigned char *old_sha1, | 123 | extern int cgit_diff_files(const unsigned char *old_sha1, |
123 | const unsigned char *new_sha1, | 124 | const unsigned char *new_sha1, |
124 | linediff_fn fn); | 125 | linediff_fn fn); |
125 | 126 | ||
126 | extern void cgit_diff_tree(const unsigned char *old_sha1, | 127 | extern void cgit_diff_tree(const unsigned char *old_sha1, |
127 | const unsigned char *new_sha1, | 128 | const unsigned char *new_sha1, |
128 | filepair_fn fn); | 129 | filepair_fn fn); |
129 | 130 | ||
130 | extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); | 131 | extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); |
131 | 132 | ||
132 | extern char *fmt(const char *format,...); | 133 | extern char *fmt(const char *format,...); |
133 | 134 | ||
134 | extern void html(const char *txt); | 135 | extern void html(const char *txt); |
135 | extern void htmlf(const char *format,...); | 136 | extern void htmlf(const char *format,...); |
136 | extern void html_txt(char *txt); | 137 | extern void html_txt(char *txt); |
137 | extern void html_ntxt(int len, char *txt); | 138 | extern void html_ntxt(int len, char *txt); |
138 | extern void html_attr(char *txt); | 139 | extern void html_attr(char *txt); |
139 | extern void html_hidden(char *name, char *value); | 140 | extern void html_hidden(char *name, char *value); |
140 | extern void html_link_open(char *url, char *title, char *class); | 141 | extern void html_link_open(char *url, char *title, char *class); |
141 | extern void html_link_close(void); | 142 | extern void html_link_close(void); |
142 | extern void html_filemode(unsigned short mode); | 143 | extern void html_filemode(unsigned short mode); |
143 | 144 | ||
144 | extern int cgit_read_config(const char *filename, configfn fn); | 145 | extern int cgit_read_config(const char *filename, configfn fn); |
145 | extern int cgit_parse_query(char *txt, configfn fn); | 146 | extern int cgit_parse_query(char *txt, configfn fn); |
146 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); | 147 | extern struct commitinfo *cgit_parse_commit(struct commit *commit); |
147 | extern struct taginfo *cgit_parse_tag(struct tag *tag); | 148 | extern struct taginfo *cgit_parse_tag(struct tag *tag); |
148 | 149 | ||
149 | extern char *cache_safe_filename(const char *unsafe); | 150 | extern char *cache_safe_filename(const char *unsafe); |
150 | extern int cache_lock(struct cacheitem *item); | 151 | extern int cache_lock(struct cacheitem *item); |
151 | extern int cache_unlock(struct cacheitem *item); | 152 | extern int cache_unlock(struct cacheitem *item); |
152 | extern int cache_cancel_lock(struct cacheitem *item); | 153 | extern int cache_cancel_lock(struct cacheitem *item); |
153 | extern int cache_exist(struct cacheitem *item); | 154 | extern int cache_exist(struct cacheitem *item); |
154 | extern int cache_expired(struct cacheitem *item); | 155 | extern int cache_expired(struct cacheitem *item); |
155 | 156 | ||
156 | extern char *cgit_repourl(const char *reponame); | 157 | extern char *cgit_repourl(const char *reponame); |
157 | extern char *cgit_pageurl(const char *reponame, const char *pagename, | 158 | extern char *cgit_pageurl(const char *reponame, const char *pagename, |
158 | const char *query); | 159 | const char *query); |
159 | 160 | ||
160 | extern void cgit_print_error(char *msg); | 161 | extern void cgit_print_error(char *msg); |
161 | extern void cgit_print_date(unsigned long secs); | 162 | extern void cgit_print_date(unsigned long secs); |
162 | extern void cgit_print_docstart(char *title, struct cacheitem *item); | 163 | extern void cgit_print_docstart(char *title, struct cacheitem *item); |
163 | extern void cgit_print_docend(); | 164 | extern void cgit_print_docend(); |
164 | extern void cgit_print_pageheader(char *title, int show_search); | 165 | extern void cgit_print_pageheader(char *title, int show_search); |
165 | extern void cgit_print_snapshot_start(const char *mimetype, | 166 | extern void cgit_print_snapshot_start(const char *mimetype, |
166 | const char *filename, | 167 | const char *filename, |
167 | struct cacheitem *item); | 168 | struct cacheitem *item); |
168 | 169 | ||
169 | extern void cgit_print_repolist(struct cacheitem *item); | 170 | extern void cgit_print_repolist(struct cacheitem *item); |
170 | extern void cgit_print_summary(); | 171 | extern void cgit_print_summary(); |
171 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep); | 172 | extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep); |
172 | extern void cgit_print_view(const char *hex, char *path); | 173 | extern void cgit_print_view(const char *hex, char *path); |
173 | extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); | 174 | extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); |
174 | extern void cgit_print_tree(const char *hex, char *path); | 175 | extern void cgit_print_tree(const char *hex, char *path); |
175 | extern void cgit_print_commit(const char *hex); | 176 | extern void cgit_print_commit(const char *hex); |
176 | extern void cgit_print_diff(const char *old_hex, const char *new_hex); | 177 | extern void cgit_print_diff(const char *old_hex, const char *new_hex); |
177 | extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, | 178 | extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, |
178 | const char *format, const char *prefix, | 179 | const char *format, const char *prefix, |
179 | const char *filename); | 180 | const char *filename); |
180 | 181 | ||
181 | #endif /* CGIT_H */ | 182 | #endif /* CGIT_H */ |
@@ -1,89 +1,93 @@ | |||
1 | ## | 1 | ## |
2 | ## cgitrc: template for /etc/cgitrc | 2 | ## cgitrc: template for /etc/cgitrc |
3 | ## | 3 | ## |
4 | 4 | ||
5 | 5 | ||
6 | ## Uncomment and set to 1 to deactivate caching of generated pages. Mostly | 6 | ## Uncomment and set to 1 to deactivate caching of generated pages. Mostly |
7 | ## usefull for testing. | 7 | ## usefull for testing. |
8 | #nocache=0 | 8 | #nocache=0 |
9 | 9 | ||
10 | 10 | ||
11 | ## Enable/disable snapshots by default. This can be overridden per repo | 11 | ## Enable/disable snapshots by default. This can be overridden per repo |
12 | #snapshots=0 | 12 | #snapshots=0 |
13 | 13 | ||
14 | 14 | ||
15 | ## Specify a root for virtual urls. This makes cgit generate urls like | 15 | ## Specify a root for virtual urls. This makes cgit generate urls like |
16 | ## | 16 | ## |
17 | ## http://localhost/git/repo/log/?id=master | 17 | ## http://localhost/git/repo/log/?id=master |
18 | ## | 18 | ## |
19 | ## instead of | 19 | ## instead of |
20 | ## | 20 | ## |
21 | ## http://localhost/cgit/cgit.cgi?r=repo&p=log&id=master | 21 | ## http://localhost/cgit/cgit.cgi?r=repo&p=log&id=master |
22 | ## | 22 | ## |
23 | ## For this to work with apache, rewrite rules must be added to httpd.conf, | 23 | ## For this to work with apache, rewrite rules must be added to httpd.conf, |
24 | ## possibly looking something like this: | 24 | ## possibly looking something like this: |
25 | ## | 25 | ## |
26 | ## RewriteRule ^/git/$ /cgit/cgit.cgi [L,QSA] | 26 | ## RewriteRule ^/git/$ /cgit/cgit.cgi [L,QSA] |
27 | ## RewriteRule ^/git/([^/]+)/$ /cgit/cgit.cgi?r=$1 [L,QSA] | 27 | ## RewriteRule ^/git/([^/]+)/$ /cgit/cgit.cgi?r=$1 [L,QSA] |
28 | ## RewriteRule ^/git/([^/]+)/([^/]+)/$ /cgit/cgit.cgi?r=$1&p=$2 [L,QSA] | 28 | ## RewriteRule ^/git/([^/]+)/([^/]+)/$ /cgit/cgit.cgi?r=$1&p=$2 [L,QSA] |
29 | ## | 29 | ## |
30 | ## This setting is disabled by default. | 30 | ## This setting is disabled by default. |
31 | #virtual-root=/git | 31 | #virtual-root=/git |
32 | 32 | ||
33 | 33 | ||
34 | ## Set the title printed on the root page | 34 | ## Set the title printed on the root page |
35 | #root-title=Git repository browser | 35 | #root-title=Git repository browser |
36 | 36 | ||
37 | 37 | ||
38 | ## Link to css file | 38 | ## Link to css file |
39 | #css=/cgit/cgit.css | 39 | #css=/cgit/cgit.css |
40 | 40 | ||
41 | 41 | ||
42 | ## Link to logo file | 42 | ## Link to logo file |
43 | #logo=/cgit/git-logo.png | 43 | #logo=/cgit/git-logo.png |
44 | 44 | ||
45 | 45 | ||
46 | ## Url loaded when clicking the logo | 46 | ## Url loaded when clicking the logo |
47 | #logo-link=http://www.kernel.org/pub/software/scm/git/docs/ | 47 | #logo-link=http://www.kernel.org/pub/software/scm/git/docs/ |
48 | 48 | ||
49 | 49 | ||
50 | ## Url loaded when clicking a submodule link | 50 | ## Url loaded when clicking a submodule link |
51 | #module-link=./?repo=%s&page=commit&id=%s | 51 | #module-link=./?repo=%s&page=commit&id=%s |
52 | 52 | ||
53 | 53 | ||
54 | ## Number of chars shown of commit subject message (in log view) | 54 | ## Number of chars shown of commit subject message (in log view) |
55 | #max-message-length=60 | 55 | #max-message-length=60 |
56 | 56 | ||
57 | 57 | ||
58 | ## Number of commits per page in log view | ||
59 | #max-commit-count=50 | ||
60 | |||
61 | |||
58 | ## Root of cached output | 62 | ## Root of cached output |
59 | #cache-root=/var/cache/cgit | 63 | #cache-root=/var/cache/cgit |
60 | 64 | ||
61 | 65 | ||
62 | ## | 66 | ## |
63 | ## Time-To-Live settings: specifies how long (in minutes) different pages | 67 | ## Time-To-Live settings: specifies how long (in minutes) different pages |
64 | ## should be cached (0 for instant expiration, -1 for immortal pages) | 68 | ## should be cached (0 for instant expiration, -1 for immortal pages) |
65 | ## | 69 | ## |
66 | 70 | ||
67 | ## ttl for root page | 71 | ## ttl for root page |
68 | #cache-root-ttl=5 | 72 | #cache-root-ttl=5 |
69 | 73 | ||
70 | ## ttl for repo summary page | 74 | ## ttl for repo summary page |
71 | #cache-repo-ttl=5 | 75 | #cache-repo-ttl=5 |
72 | 76 | ||
73 | ## ttl for other dynamic pages | 77 | ## ttl for other dynamic pages |
74 | #cache-dynamic-ttl=5 | 78 | #cache-dynamic-ttl=5 |
75 | 79 | ||
76 | ## ttl for static pages (addressed by SHA-1) | 80 | ## ttl for static pages (addressed by SHA-1) |
77 | #cache-static-ttl=-1 | 81 | #cache-static-ttl=-1 |
78 | 82 | ||
79 | 83 | ||
80 | 84 | ||
81 | ## Example repository entry. Required values are repo.url and repo.path (each | 85 | ## Example repository entry. Required values are repo.url and repo.path (each |
82 | ## repository section must start with repo.url). | 86 | ## repository section must start with repo.url). |
83 | #repo.url=cgit | 87 | #repo.url=cgit |
84 | #repo.name=cgit | 88 | #repo.name=cgit |
85 | #repo.desc=the caching cgi for git | 89 | #repo.desc=the caching cgi for git |
86 | #repo.path=/pub/git/cgit | 90 | #repo.path=/pub/git/cgit |
87 | #repo.owner=Lars Hjemli | 91 | #repo.owner=Lars Hjemli |
88 | #repo.snapshots=1 # override a sitewide snapshot-setting | 92 | #repo.snapshots=1 # override a sitewide snapshot-setting |
89 | #repo.module-link=/git/%s/commit/?id=%s # override the standard module-link | 93 | #repo.module-link=/git/%s/commit/?id=%s # override the standard module-link |
@@ -1,319 +1,322 @@ | |||
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 | ||
11 | struct repolist cgit_repolist; | 11 | struct repolist cgit_repolist; |
12 | struct repoinfo *cgit_repo; | 12 | struct repoinfo *cgit_repo; |
13 | 13 | ||
14 | char *cgit_root_title = "Git repository browser"; | 14 | char *cgit_root_title = "Git repository browser"; |
15 | char *cgit_css = "/cgit.css"; | 15 | char *cgit_css = "/cgit.css"; |
16 | char *cgit_logo = "/git-logo.png"; | 16 | char *cgit_logo = "/git-logo.png"; |
17 | char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; | 17 | char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; |
18 | char *cgit_module_link = "./?repo=%s&page=commit&id=%s"; | 18 | char *cgit_module_link = "./?repo=%s&page=commit&id=%s"; |
19 | char *cgit_virtual_root = NULL; | 19 | char *cgit_virtual_root = NULL; |
20 | 20 | ||
21 | char *cgit_cache_root = "/var/cache/cgit"; | 21 | char *cgit_cache_root = "/var/cache/cgit"; |
22 | 22 | ||
23 | int cgit_nocache = 0; | 23 | int cgit_nocache = 0; |
24 | int cgit_snapshots = 0; | 24 | int cgit_snapshots = 0; |
25 | int cgit_max_lock_attempts = 5; | 25 | int cgit_max_lock_attempts = 5; |
26 | int cgit_cache_root_ttl = 5; | 26 | int cgit_cache_root_ttl = 5; |
27 | int cgit_cache_repo_ttl = 5; | 27 | int cgit_cache_repo_ttl = 5; |
28 | int cgit_cache_dynamic_ttl = 5; | 28 | int cgit_cache_dynamic_ttl = 5; |
29 | int cgit_cache_static_ttl = -1; | 29 | int cgit_cache_static_ttl = -1; |
30 | int cgit_cache_max_create_time = 5; | 30 | int cgit_cache_max_create_time = 5; |
31 | 31 | ||
32 | int cgit_max_msg_len = 60; | 32 | int cgit_max_msg_len = 60; |
33 | int cgit_max_commit_count = 50; | ||
33 | 34 | ||
34 | char *cgit_repo_name = NULL; | 35 | char *cgit_repo_name = NULL; |
35 | char *cgit_repo_desc = NULL; | 36 | char *cgit_repo_desc = NULL; |
36 | char *cgit_repo_owner = NULL; | 37 | char *cgit_repo_owner = NULL; |
37 | 38 | ||
38 | int cgit_query_has_symref = 0; | 39 | int cgit_query_has_symref = 0; |
39 | int cgit_query_has_sha1 = 0; | 40 | int cgit_query_has_sha1 = 0; |
40 | 41 | ||
41 | char *cgit_querystring = NULL; | 42 | char *cgit_querystring = NULL; |
42 | char *cgit_query_repo = NULL; | 43 | char *cgit_query_repo = NULL; |
43 | char *cgit_query_page = NULL; | 44 | char *cgit_query_page = NULL; |
44 | char *cgit_query_head = NULL; | 45 | char *cgit_query_head = NULL; |
45 | char *cgit_query_search = NULL; | 46 | char *cgit_query_search = NULL; |
46 | char *cgit_query_sha1 = NULL; | 47 | char *cgit_query_sha1 = NULL; |
47 | char *cgit_query_sha2 = NULL; | 48 | char *cgit_query_sha2 = NULL; |
48 | char *cgit_query_path = NULL; | 49 | char *cgit_query_path = NULL; |
49 | char *cgit_query_name = NULL; | 50 | char *cgit_query_name = NULL; |
50 | int cgit_query_ofs = 0; | 51 | int cgit_query_ofs = 0; |
51 | 52 | ||
52 | int htmlfd = 0; | 53 | int htmlfd = 0; |
53 | 54 | ||
54 | int chk_zero(int result, char *msg) | 55 | int chk_zero(int result, char *msg) |
55 | { | 56 | { |
56 | if (result != 0) | 57 | if (result != 0) |
57 | die("%s: %s", msg, strerror(errno)); | 58 | die("%s: %s", msg, strerror(errno)); |
58 | return result; | 59 | return result; |
59 | } | 60 | } |
60 | 61 | ||
61 | int chk_positive(int result, char *msg) | 62 | int chk_positive(int result, char *msg) |
62 | { | 63 | { |
63 | if (result <= 0) | 64 | if (result <= 0) |
64 | die("%s: %s", msg, strerror(errno)); | 65 | die("%s: %s", msg, strerror(errno)); |
65 | return result; | 66 | return result; |
66 | } | 67 | } |
67 | 68 | ||
68 | struct repoinfo *add_repo(const char *url) | 69 | struct repoinfo *add_repo(const char *url) |
69 | { | 70 | { |
70 | struct repoinfo *ret; | 71 | struct repoinfo *ret; |
71 | 72 | ||
72 | if (++cgit_repolist.count > cgit_repolist.length) { | 73 | if (++cgit_repolist.count > cgit_repolist.length) { |
73 | if (cgit_repolist.length == 0) | 74 | if (cgit_repolist.length == 0) |
74 | cgit_repolist.length = 8; | 75 | cgit_repolist.length = 8; |
75 | else | 76 | else |
76 | cgit_repolist.length *= 2; | 77 | cgit_repolist.length *= 2; |
77 | cgit_repolist.repos = xrealloc(cgit_repolist.repos, | 78 | cgit_repolist.repos = xrealloc(cgit_repolist.repos, |
78 | cgit_repolist.length * | 79 | cgit_repolist.length * |
79 | sizeof(struct repoinfo)); | 80 | sizeof(struct repoinfo)); |
80 | } | 81 | } |
81 | 82 | ||
82 | ret = &cgit_repolist.repos[cgit_repolist.count-1]; | 83 | ret = &cgit_repolist.repos[cgit_repolist.count-1]; |
83 | ret->url = xstrdup(url); | 84 | ret->url = xstrdup(url); |
84 | ret->name = ret->url; | 85 | ret->name = ret->url; |
85 | ret->path = NULL; | 86 | ret->path = NULL; |
86 | ret->desc = NULL; | 87 | ret->desc = NULL; |
87 | ret->owner = NULL; | 88 | ret->owner = NULL; |
88 | ret->snapshots = cgit_snapshots; | 89 | ret->snapshots = cgit_snapshots; |
89 | ret->module_link = cgit_module_link; | 90 | ret->module_link = cgit_module_link; |
90 | return ret; | 91 | return ret; |
91 | } | 92 | } |
92 | 93 | ||
93 | void cgit_global_config_cb(const char *name, const char *value) | 94 | void cgit_global_config_cb(const char *name, const char *value) |
94 | { | 95 | { |
95 | if (!strcmp(name, "root-title")) | 96 | if (!strcmp(name, "root-title")) |
96 | cgit_root_title = xstrdup(value); | 97 | cgit_root_title = xstrdup(value); |
97 | else if (!strcmp(name, "css")) | 98 | else if (!strcmp(name, "css")) |
98 | cgit_css = xstrdup(value); | 99 | cgit_css = xstrdup(value); |
99 | else if (!strcmp(name, "logo")) | 100 | else if (!strcmp(name, "logo")) |
100 | cgit_logo = xstrdup(value); | 101 | cgit_logo = xstrdup(value); |
101 | else if (!strcmp(name, "logo-link")) | 102 | else if (!strcmp(name, "logo-link")) |
102 | cgit_logo_link = xstrdup(value); | 103 | cgit_logo_link = xstrdup(value); |
103 | else if (!strcmp(name, "module-link")) | 104 | else if (!strcmp(name, "module-link")) |
104 | cgit_module_link = xstrdup(value); | 105 | cgit_module_link = xstrdup(value); |
105 | else if (!strcmp(name, "virtual-root")) | 106 | else if (!strcmp(name, "virtual-root")) |
106 | cgit_virtual_root = xstrdup(value); | 107 | cgit_virtual_root = xstrdup(value); |
107 | else if (!strcmp(name, "nocache")) | 108 | else if (!strcmp(name, "nocache")) |
108 | cgit_nocache = atoi(value); | 109 | cgit_nocache = atoi(value); |
109 | else if (!strcmp(name, "snapshots")) | 110 | else if (!strcmp(name, "snapshots")) |
110 | cgit_snapshots = atoi(value); | 111 | cgit_snapshots = atoi(value); |
111 | else if (!strcmp(name, "cache-root")) | 112 | else if (!strcmp(name, "cache-root")) |
112 | cgit_cache_root = xstrdup(value); | 113 | cgit_cache_root = xstrdup(value); |
113 | else if (!strcmp(name, "cache-root-ttl")) | 114 | else if (!strcmp(name, "cache-root-ttl")) |
114 | cgit_cache_root_ttl = atoi(value); | 115 | cgit_cache_root_ttl = atoi(value); |
115 | else if (!strcmp(name, "cache-repo-ttl")) | 116 | else if (!strcmp(name, "cache-repo-ttl")) |
116 | cgit_cache_repo_ttl = atoi(value); | 117 | cgit_cache_repo_ttl = atoi(value); |
117 | else if (!strcmp(name, "cache-static-ttl")) | 118 | else if (!strcmp(name, "cache-static-ttl")) |
118 | cgit_cache_static_ttl = atoi(value); | 119 | cgit_cache_static_ttl = atoi(value); |
119 | else if (!strcmp(name, "cache-dynamic-ttl")) | 120 | else if (!strcmp(name, "cache-dynamic-ttl")) |
120 | cgit_cache_dynamic_ttl = atoi(value); | 121 | cgit_cache_dynamic_ttl = atoi(value); |
121 | else if (!strcmp(name, "max-message-length")) | 122 | else if (!strcmp(name, "max-message-length")) |
122 | cgit_max_msg_len = atoi(value); | 123 | cgit_max_msg_len = atoi(value); |
124 | else if (!strcmp(name, "max-commit-count")) | ||
125 | cgit_max_commit_count = atoi(value); | ||
123 | else if (!strcmp(name, "repo.url")) | 126 | else if (!strcmp(name, "repo.url")) |
124 | cgit_repo = add_repo(value); | 127 | cgit_repo = add_repo(value); |
125 | else if (!strcmp(name, "repo.name")) | 128 | else if (!strcmp(name, "repo.name")) |
126 | cgit_repo->name = xstrdup(value); | 129 | cgit_repo->name = xstrdup(value); |
127 | else if (cgit_repo && !strcmp(name, "repo.path")) | 130 | else if (cgit_repo && !strcmp(name, "repo.path")) |
128 | cgit_repo->path = xstrdup(value); | 131 | cgit_repo->path = xstrdup(value); |
129 | else if (cgit_repo && !strcmp(name, "repo.desc")) | 132 | else if (cgit_repo && !strcmp(name, "repo.desc")) |
130 | cgit_repo->desc = xstrdup(value); | 133 | cgit_repo->desc = xstrdup(value); |
131 | else if (cgit_repo && !strcmp(name, "repo.owner")) | 134 | else if (cgit_repo && !strcmp(name, "repo.owner")) |
132 | cgit_repo->owner = xstrdup(value); | 135 | cgit_repo->owner = xstrdup(value); |
133 | else if (cgit_repo && !strcmp(name, "repo.snapshots")) | 136 | else if (cgit_repo && !strcmp(name, "repo.snapshots")) |
134 | cgit_repo->snapshots = atoi(value); | 137 | cgit_repo->snapshots = atoi(value); |
135 | else if (cgit_repo && !strcmp(name, "repo.module-link")) | 138 | else if (cgit_repo && !strcmp(name, "repo.module-link")) |
136 | cgit_repo->module_link= xstrdup(value); | 139 | cgit_repo->module_link= xstrdup(value); |
137 | } | 140 | } |
138 | 141 | ||
139 | void cgit_repo_config_cb(const char *name, const char *value) | 142 | void cgit_repo_config_cb(const char *name, const char *value) |
140 | { | 143 | { |
141 | if (!strcmp(name, "name")) | 144 | if (!strcmp(name, "name")) |
142 | cgit_repo_name = xstrdup(value); | 145 | cgit_repo_name = xstrdup(value); |
143 | else if (!strcmp(name, "desc")) | 146 | else if (!strcmp(name, "desc")) |
144 | cgit_repo_desc = xstrdup(value); | 147 | cgit_repo_desc = xstrdup(value); |
145 | else if (!strcmp(name, "owner")) | 148 | else if (!strcmp(name, "owner")) |
146 | cgit_repo_owner = xstrdup(value); | 149 | cgit_repo_owner = xstrdup(value); |
147 | } | 150 | } |
148 | 151 | ||
149 | void cgit_querystring_cb(const char *name, const char *value) | 152 | void cgit_querystring_cb(const char *name, const char *value) |
150 | { | 153 | { |
151 | if (!strcmp(name,"r")) { | 154 | if (!strcmp(name,"r")) { |
152 | cgit_query_repo = xstrdup(value); | 155 | cgit_query_repo = xstrdup(value); |
153 | } else if (!strcmp(name, "p")) { | 156 | } else if (!strcmp(name, "p")) { |
154 | cgit_query_page = xstrdup(value); | 157 | cgit_query_page = xstrdup(value); |
155 | } else if (!strcmp(name, "q")) { | 158 | } else if (!strcmp(name, "q")) { |
156 | cgit_query_search = xstrdup(value); | 159 | cgit_query_search = xstrdup(value); |
157 | } else if (!strcmp(name, "h")) { | 160 | } else if (!strcmp(name, "h")) { |
158 | cgit_query_head = xstrdup(value); | 161 | cgit_query_head = xstrdup(value); |
159 | cgit_query_has_symref = 1; | 162 | cgit_query_has_symref = 1; |
160 | } else if (!strcmp(name, "id")) { | 163 | } else if (!strcmp(name, "id")) { |
161 | cgit_query_sha1 = xstrdup(value); | 164 | cgit_query_sha1 = xstrdup(value); |
162 | cgit_query_has_sha1 = 1; | 165 | cgit_query_has_sha1 = 1; |
163 | } else if (!strcmp(name, "id2")) { | 166 | } else if (!strcmp(name, "id2")) { |
164 | cgit_query_sha2 = xstrdup(value); | 167 | cgit_query_sha2 = xstrdup(value); |
165 | cgit_query_has_sha1 = 1; | 168 | cgit_query_has_sha1 = 1; |
166 | } else if (!strcmp(name, "ofs")) { | 169 | } else if (!strcmp(name, "ofs")) { |
167 | cgit_query_ofs = atoi(value); | 170 | cgit_query_ofs = atoi(value); |
168 | } else if (!strcmp(name, "path")) { | 171 | } else if (!strcmp(name, "path")) { |
169 | cgit_query_path = xstrdup(value); | 172 | cgit_query_path = xstrdup(value); |
170 | } else if (!strcmp(name, "name")) { | 173 | } else if (!strcmp(name, "name")) { |
171 | cgit_query_name = xstrdup(value); | 174 | cgit_query_name = xstrdup(value); |
172 | } | 175 | } |
173 | } | 176 | } |
174 | 177 | ||
175 | void *cgit_free_commitinfo(struct commitinfo *info) | 178 | void *cgit_free_commitinfo(struct commitinfo *info) |
176 | { | 179 | { |
177 | free(info->author); | 180 | free(info->author); |
178 | free(info->author_email); | 181 | free(info->author_email); |
179 | free(info->committer); | 182 | free(info->committer); |
180 | free(info->committer_email); | 183 | free(info->committer_email); |
181 | free(info->subject); | 184 | free(info->subject); |
182 | free(info); | 185 | free(info); |
183 | return NULL; | 186 | return NULL; |
184 | } | 187 | } |
185 | 188 | ||
186 | int hextoint(char c) | 189 | int hextoint(char c) |
187 | { | 190 | { |
188 | if (c >= 'a' && c <= 'f') | 191 | if (c >= 'a' && c <= 'f') |
189 | return 10 + c - 'a'; | 192 | return 10 + c - 'a'; |
190 | else if (c >= 'A' && c <= 'F') | 193 | else if (c >= 'A' && c <= 'F') |
191 | return 10 + c - 'A'; | 194 | return 10 + c - 'A'; |
192 | else if (c >= '0' && c <= '9') | 195 | else if (c >= '0' && c <= '9') |
193 | return c - '0'; | 196 | return c - '0'; |
194 | else | 197 | else |
195 | return -1; | 198 | return -1; |
196 | } | 199 | } |
197 | 200 | ||
198 | void cgit_diff_tree_cb(struct diff_queue_struct *q, | 201 | void cgit_diff_tree_cb(struct diff_queue_struct *q, |
199 | struct diff_options *options, void *data) | 202 | struct diff_options *options, void *data) |
200 | { | 203 | { |
201 | int i; | 204 | int i; |
202 | 205 | ||
203 | for (i = 0; i < q->nr; i++) { | 206 | for (i = 0; i < q->nr; i++) { |
204 | if (q->queue[i]->status == 'U') | 207 | if (q->queue[i]->status == 'U') |
205 | continue; | 208 | continue; |
206 | ((filepair_fn)data)(q->queue[i]); | 209 | ((filepair_fn)data)(q->queue[i]); |
207 | } | 210 | } |
208 | } | 211 | } |
209 | 212 | ||
210 | static int load_mmfile(mmfile_t *file, const unsigned char *sha1) | 213 | static int load_mmfile(mmfile_t *file, const unsigned char *sha1) |
211 | { | 214 | { |
212 | enum object_type type; | 215 | enum object_type type; |
213 | 216 | ||
214 | if (is_null_sha1(sha1)) { | 217 | if (is_null_sha1(sha1)) { |
215 | file->ptr = (char *)""; | 218 | file->ptr = (char *)""; |
216 | file->size = 0; | 219 | file->size = 0; |
217 | } else { | 220 | } else { |
218 | file->ptr = read_sha1_file(sha1, &type, &file->size); | 221 | file->ptr = read_sha1_file(sha1, &type, &file->size); |
219 | } | 222 | } |
220 | return 1; | 223 | return 1; |
221 | } | 224 | } |
222 | 225 | ||
223 | /* | 226 | /* |
224 | * Receive diff-buffers from xdiff and concatenate them as | 227 | * Receive diff-buffers from xdiff and concatenate them as |
225 | * needed across multiple callbacks. | 228 | * needed across multiple callbacks. |
226 | * | 229 | * |
227 | * This is basically a copy of xdiff-interface.c/xdiff_outf(), | 230 | * This is basically a copy of xdiff-interface.c/xdiff_outf(), |
228 | * ripped from git and modified to use globals instead of | 231 | * ripped from git and modified to use globals instead of |
229 | * a special callback-struct. | 232 | * a special callback-struct. |
230 | */ | 233 | */ |
231 | char *diffbuf = NULL; | 234 | char *diffbuf = NULL; |
232 | int buflen = 0; | 235 | int buflen = 0; |
233 | 236 | ||
234 | int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) | 237 | int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) |
235 | { | 238 | { |
236 | int i; | 239 | int i; |
237 | 240 | ||
238 | for (i = 0; i < nbuf; i++) { | 241 | for (i = 0; i < nbuf; i++) { |
239 | if (mb[i].ptr[mb[i].size-1] != '\n') { | 242 | if (mb[i].ptr[mb[i].size-1] != '\n') { |
240 | /* Incomplete line */ | 243 | /* Incomplete line */ |
241 | diffbuf = xrealloc(diffbuf, buflen + mb[i].size); | 244 | diffbuf = xrealloc(diffbuf, buflen + mb[i].size); |
242 | memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); | 245 | memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); |
243 | buflen += mb[i].size; | 246 | buflen += mb[i].size; |
244 | continue; | 247 | continue; |
245 | } | 248 | } |
246 | 249 | ||
247 | /* we have a complete line */ | 250 | /* we have a complete line */ |
248 | if (!diffbuf) { | 251 | if (!diffbuf) { |
249 | ((linediff_fn)priv)(mb[i].ptr, mb[i].size); | 252 | ((linediff_fn)priv)(mb[i].ptr, mb[i].size); |
250 | continue; | 253 | continue; |
251 | } | 254 | } |
252 | diffbuf = xrealloc(diffbuf, buflen + mb[i].size); | 255 | diffbuf = xrealloc(diffbuf, buflen + mb[i].size); |
253 | memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); | 256 | memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); |
254 | ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); | 257 | ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); |
255 | free(diffbuf); | 258 | free(diffbuf); |
256 | diffbuf = NULL; | 259 | diffbuf = NULL; |
257 | buflen = 0; | 260 | buflen = 0; |
258 | } | 261 | } |
259 | if (diffbuf) { | 262 | if (diffbuf) { |
260 | ((linediff_fn)priv)(diffbuf, buflen); | 263 | ((linediff_fn)priv)(diffbuf, buflen); |
261 | free(diffbuf); | 264 | free(diffbuf); |
262 | diffbuf = NULL; | 265 | diffbuf = NULL; |
263 | buflen = 0; | 266 | buflen = 0; |
264 | } | 267 | } |
265 | return 0; | 268 | return 0; |
266 | } | 269 | } |
267 | 270 | ||
268 | int cgit_diff_files(const unsigned char *old_sha1, | 271 | int cgit_diff_files(const unsigned char *old_sha1, |
269 | const unsigned char *new_sha1, | 272 | const unsigned char *new_sha1, |
270 | linediff_fn fn) | 273 | linediff_fn fn) |
271 | { | 274 | { |
272 | mmfile_t file1, file2; | 275 | mmfile_t file1, file2; |
273 | xpparam_t diff_params; | 276 | xpparam_t diff_params; |
274 | xdemitconf_t emit_params; | 277 | xdemitconf_t emit_params; |
275 | xdemitcb_t emit_cb; | 278 | xdemitcb_t emit_cb; |
276 | 279 | ||
277 | if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) | 280 | if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) |
278 | return 1; | 281 | return 1; |
279 | 282 | ||
280 | diff_params.flags = XDF_NEED_MINIMAL; | 283 | diff_params.flags = XDF_NEED_MINIMAL; |
281 | emit_params.ctxlen = 3; | 284 | emit_params.ctxlen = 3; |
282 | emit_params.flags = XDL_EMIT_FUNCNAMES; | 285 | emit_params.flags = XDL_EMIT_FUNCNAMES; |
283 | emit_cb.outf = filediff_cb; | 286 | emit_cb.outf = filediff_cb; |
284 | emit_cb.priv = fn; | 287 | emit_cb.priv = fn; |
285 | xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); | 288 | xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); |
286 | return 0; | 289 | return 0; |
287 | } | 290 | } |
288 | 291 | ||
289 | void cgit_diff_tree(const unsigned char *old_sha1, | 292 | void cgit_diff_tree(const unsigned char *old_sha1, |
290 | const unsigned char *new_sha1, | 293 | const unsigned char *new_sha1, |
291 | filepair_fn fn) | 294 | filepair_fn fn) |
292 | { | 295 | { |
293 | struct diff_options opt; | 296 | struct diff_options opt; |
294 | int ret; | 297 | int ret; |
295 | 298 | ||
296 | diff_setup(&opt); | 299 | diff_setup(&opt); |
297 | opt.output_format = DIFF_FORMAT_CALLBACK; | 300 | opt.output_format = DIFF_FORMAT_CALLBACK; |
298 | opt.detect_rename = 1; | 301 | opt.detect_rename = 1; |
299 | opt.recursive = 1; | 302 | opt.recursive = 1; |
300 | opt.format_callback = cgit_diff_tree_cb; | 303 | opt.format_callback = cgit_diff_tree_cb; |
301 | opt.format_callback_data = fn; | 304 | opt.format_callback_data = fn; |
302 | diff_setup_done(&opt); | 305 | diff_setup_done(&opt); |
303 | 306 | ||
304 | if (old_sha1) | 307 | if (old_sha1) |
305 | ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); | 308 | ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); |
306 | else | 309 | else |
307 | ret = diff_root_tree_sha1(new_sha1, "", &opt); | 310 | ret = diff_root_tree_sha1(new_sha1, "", &opt); |
308 | diffcore_std(&opt); | 311 | diffcore_std(&opt); |
309 | diff_flush(&opt); | 312 | diff_flush(&opt); |
310 | } | 313 | } |
311 | 314 | ||
312 | void cgit_diff_commit(struct commit *commit, filepair_fn fn) | 315 | void cgit_diff_commit(struct commit *commit, filepair_fn fn) |
313 | { | 316 | { |
314 | unsigned char *old_sha1 = NULL; | 317 | unsigned char *old_sha1 = NULL; |
315 | 318 | ||
316 | if (commit->parents) | 319 | if (commit->parents) |
317 | old_sha1 = commit->parents->item->object.sha1; | 320 | old_sha1 = commit->parents->item->object.sha1; |
318 | cgit_diff_tree(old_sha1, commit->object.sha1, fn); | 321 | cgit_diff_tree(old_sha1, commit->object.sha1, fn); |
319 | } | 322 | } |