summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.c3
-rw-r--r--cgit.h2
-rw-r--r--html.c64
-rw-r--r--html.h2
-rw-r--r--parsing.c49
-rw-r--r--shared.c12
6 files changed, 68 insertions, 64 deletions
diff --git a/cgit.c b/cgit.c
index 1f46e0d..763242a 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,36 +1,37 @@
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#include "cache.h" 10#include "cache.h"
11#include "cmd.h" 11#include "cmd.h"
12#include "configfile.h" 12#include "configfile.h"
13#include "html.h"
13#include "ui-shared.h" 14#include "ui-shared.h"
14 15
15const char *cgit_version = CGIT_VERSION; 16const char *cgit_version = CGIT_VERSION;
16 17
17void config_cb(const char *name, const char *value) 18void config_cb(const char *name, const char *value)
18{ 19{
19 if (!strcmp(name, "root-title")) 20 if (!strcmp(name, "root-title"))
20 ctx.cfg.root_title = xstrdup(value); 21 ctx.cfg.root_title = xstrdup(value);
21 else if (!strcmp(name, "css")) 22 else if (!strcmp(name, "css"))
22 ctx.cfg.css = xstrdup(value); 23 ctx.cfg.css = xstrdup(value);
23 else if (!strcmp(name, "logo")) 24 else if (!strcmp(name, "logo"))
24 ctx.cfg.logo = xstrdup(value); 25 ctx.cfg.logo = xstrdup(value);
25 else if (!strcmp(name, "index-header")) 26 else if (!strcmp(name, "index-header"))
26 ctx.cfg.index_header = xstrdup(value); 27 ctx.cfg.index_header = xstrdup(value);
27 else if (!strcmp(name, "index-info")) 28 else if (!strcmp(name, "index-info"))
28 ctx.cfg.index_info = xstrdup(value); 29 ctx.cfg.index_info = xstrdup(value);
29 else if (!strcmp(name, "logo-link")) 30 else if (!strcmp(name, "logo-link"))
30 ctx.cfg.logo_link = xstrdup(value); 31 ctx.cfg.logo_link = xstrdup(value);
31 else if (!strcmp(name, "module-link")) 32 else if (!strcmp(name, "module-link"))
32 ctx.cfg.module_link = xstrdup(value); 33 ctx.cfg.module_link = xstrdup(value);
33 else if (!strcmp(name, "virtual-root")) { 34 else if (!strcmp(name, "virtual-root")) {
34 ctx.cfg.virtual_root = trim_end(value, '/'); 35 ctx.cfg.virtual_root = trim_end(value, '/');
35 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 36 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
36 ctx.cfg.virtual_root = ""; 37 ctx.cfg.virtual_root = "";
@@ -423,35 +424,35 @@ static void cgit_parse_args(int argc, const char **argv)
423 if (!strncmp(argv[i], "--ofs=", 6)) { 424 if (!strncmp(argv[i], "--ofs=", 6)) {
424 ctx.qry.ofs = atoi(argv[i]+6); 425 ctx.qry.ofs = atoi(argv[i]+6);
425 } 426 }
426 } 427 }
427} 428}
428 429
429int main(int argc, const char **argv) 430int main(int argc, const char **argv)
430{ 431{
431 struct cacheitem item; 432 struct cacheitem item;
432 const char *cgit_config_env = getenv("CGIT_CONFIG"); 433 const char *cgit_config_env = getenv("CGIT_CONFIG");
433 434
434 prepare_context(&ctx); 435 prepare_context(&ctx);
435 item.st.st_mtime = time(NULL); 436 item.st.st_mtime = time(NULL);
436 cgit_repolist.length = 0; 437 cgit_repolist.length = 0;
437 cgit_repolist.count = 0; 438 cgit_repolist.count = 0;
438 cgit_repolist.repos = NULL; 439 cgit_repolist.repos = NULL;
439 440
440 parse_configfile(cgit_config_env ? cgit_config_env : CGIT_CONFIG, 441 parse_configfile(cgit_config_env ? cgit_config_env : CGIT_CONFIG,
441 config_cb); 442 config_cb);
442 if (getenv("SCRIPT_NAME")) 443 if (getenv("SCRIPT_NAME"))
443 ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME")); 444 ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME"));
444 if (getenv("QUERY_STRING")) 445 if (getenv("QUERY_STRING"))
445 ctx.qry.raw = xstrdup(getenv("QUERY_STRING")); 446 ctx.qry.raw = xstrdup(getenv("QUERY_STRING"));
446 cgit_parse_args(argc, argv); 447 cgit_parse_args(argc, argv);
447 cgit_parse_query(ctx.qry.raw, querystring_cb); 448 http_parse_querystring(ctx.qry.raw, querystring_cb);
448 if (!cgit_prepare_cache(&item)) 449 if (!cgit_prepare_cache(&item))
449 return 0; 450 return 0;
450 if (ctx.cfg.nocache) { 451 if (ctx.cfg.nocache) {
451 cgit_fill_cache(&item, 0); 452 cgit_fill_cache(&item, 0);
452 } else { 453 } else {
453 cgit_check_cache(&item); 454 cgit_check_cache(&item);
454 cgit_print_cache(&item); 455 cgit_print_cache(&item);
455 } 456 }
456 return 0; 457 return 0;
457} 458}
diff --git a/cgit.h b/cgit.h
index 91d18f8..ee8c716 100644
--- a/cgit.h
+++ b/cgit.h
@@ -170,57 +170,55 @@ struct cgit_context {
170 struct cgit_page page; 170 struct cgit_page page;
171}; 171};
172 172
173struct cgit_snapshot_format { 173struct cgit_snapshot_format {
174 const char *suffix; 174 const char *suffix;
175 const char *mimetype; 175 const char *mimetype;
176 write_archive_fn_t write_func; 176 write_archive_fn_t write_func;
177 int bit; 177 int bit;
178}; 178};
179 179
180extern const char *cgit_version; 180extern const char *cgit_version;
181 181
182extern struct cgit_repolist cgit_repolist; 182extern struct cgit_repolist cgit_repolist;
183extern struct cgit_context ctx; 183extern struct cgit_context ctx;
184extern const struct cgit_snapshot_format cgit_snapshot_formats[]; 184extern const struct cgit_snapshot_format cgit_snapshot_formats[];
185 185
186extern struct cgit_repo *cgit_add_repo(const char *url); 186extern struct cgit_repo *cgit_add_repo(const char *url);
187extern struct cgit_repo *cgit_get_repoinfo(const char *url); 187extern struct cgit_repo *cgit_get_repoinfo(const char *url);
188extern void cgit_repo_config_cb(const char *name, const char *value); 188extern void cgit_repo_config_cb(const char *name, const char *value);
189 189
190extern int chk_zero(int result, char *msg); 190extern int chk_zero(int result, char *msg);
191extern int chk_positive(int result, char *msg); 191extern int chk_positive(int result, char *msg);
192extern int chk_non_negative(int result, char *msg); 192extern int chk_non_negative(int result, char *msg);
193 193
194extern int hextoint(char c);
195extern char *trim_end(const char *str, char c); 194extern char *trim_end(const char *str, char c);
196extern char *strlpart(char *txt, int maxlen); 195extern char *strlpart(char *txt, int maxlen);
197extern char *strrpart(char *txt, int maxlen); 196extern char *strrpart(char *txt, int maxlen);
198 197
199extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); 198extern void cgit_add_ref(struct reflist *list, struct refinfo *ref);
200extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, 199extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
201 int flags, void *cb_data); 200 int flags, void *cb_data);
202 201
203extern void *cgit_free_commitinfo(struct commitinfo *info); 202extern void *cgit_free_commitinfo(struct commitinfo *info);
204 203
205extern int cgit_diff_files(const unsigned char *old_sha1, 204extern int cgit_diff_files(const unsigned char *old_sha1,
206 const unsigned char *new_sha1, 205 const unsigned char *new_sha1,
207 linediff_fn fn); 206 linediff_fn fn);
208 207
209extern void cgit_diff_tree(const unsigned char *old_sha1, 208extern void cgit_diff_tree(const unsigned char *old_sha1,
210 const unsigned char *new_sha1, 209 const unsigned char *new_sha1,
211 filepair_fn fn, const char *prefix); 210 filepair_fn fn, const char *prefix);
212 211
213extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 212extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
214 213
215extern char *fmt(const char *format,...); 214extern char *fmt(const char *format,...);
216 215
217extern int cgit_parse_query(char *txt, configfn fn);
218extern struct commitinfo *cgit_parse_commit(struct commit *commit); 216extern struct commitinfo *cgit_parse_commit(struct commit *commit);
219extern struct taginfo *cgit_parse_tag(struct tag *tag); 217extern struct taginfo *cgit_parse_tag(struct tag *tag);
220extern void cgit_parse_url(const char *url); 218extern void cgit_parse_url(const char *url);
221 219
222extern const char *cgit_repobasename(const char *reponame); 220extern const char *cgit_repobasename(const char *reponame);
223 221
224extern int cgit_parse_snapshots_mask(const char *str); 222extern int cgit_parse_snapshots_mask(const char *str);
225 223
226#endif /* CGIT_H */ 224#endif /* CGIT_H */
diff --git a/html.c b/html.c
index 0962e71..98ffaf9 100644
--- a/html.c
+++ b/html.c
@@ -164,24 +164,88 @@ void html_link_open(char *url, char *title, char *class)
164void html_link_close(void) 164void html_link_close(void)
165{ 165{
166 html("</a>"); 166 html("</a>");
167} 167}
168 168
169void html_fileperm(unsigned short mode) 169void html_fileperm(unsigned short mode)
170{ 170{
171 htmlf("%c%c%c", (mode & 4 ? 'r' : '-'), 171 htmlf("%c%c%c", (mode & 4 ? 'r' : '-'),
172 (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-')); 172 (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-'));
173} 173}
174 174
175int html_include(const char *filename) 175int html_include(const char *filename)
176{ 176{
177 FILE *f; 177 FILE *f;
178 char buf[4096]; 178 char buf[4096];
179 size_t len; 179 size_t len;
180 180
181 if (!(f = fopen(filename, "r"))) 181 if (!(f = fopen(filename, "r")))
182 return -1; 182 return -1;
183 while((len = fread(buf, 1, 4096, f)) > 0) 183 while((len = fread(buf, 1, 4096, f)) > 0)
184 write(htmlfd, buf, len); 184 write(htmlfd, buf, len);
185 fclose(f); 185 fclose(f);
186 return 0; 186 return 0;
187} 187}
188
189int hextoint(char c)
190{
191 if (c >= 'a' && c <= 'f')
192 return 10 + c - 'a';
193 else if (c >= 'A' && c <= 'F')
194 return 10 + c - 'A';
195 else if (c >= '0' && c <= '9')
196 return c - '0';
197 else
198 return -1;
199}
200
201char *convert_query_hexchar(char *txt)
202{
203 int d1, d2;
204 if (strlen(txt) < 3) {
205 *txt = '\0';
206 return txt-1;
207 }
208 d1 = hextoint(*(txt+1));
209 d2 = hextoint(*(txt+2));
210 if (d1<0 || d2<0) {
211 strcpy(txt, txt+3);
212 return txt-1;
213 } else {
214 *txt = d1 * 16 + d2;
215 strcpy(txt+1, txt+3);
216 return txt;
217 }
218}
219
220int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value))
221{
222 char *t, *value = NULL, c;
223
224 if (!txt)
225 return 0;
226
227 t = txt = strdup(txt);
228 if (t == NULL) {
229 printf("Out of memory\n");
230 exit(1);
231 }
232 while((c=*t) != '\0') {
233 if (c=='=') {
234 *t = '\0';
235 value = t+1;
236 } else if (c=='+') {
237 *t = ' ';
238 } else if (c=='%') {
239 t = convert_query_hexchar(t);
240 } else if (c=='&') {
241 *t = '\0';
242 (*fn)(txt, value);
243 txt = t+1;
244 value = NULL;
245 }
246 t++;
247 }
248 if (t!=txt)
249 (*fn)(txt, value);
250 return 0;
251}
diff --git a/html.h b/html.h
index 63f4551..e6fdc54 100644
--- a/html.h
+++ b/html.h
@@ -1,18 +1,20 @@
1#ifndef HTML_H 1#ifndef HTML_H
2#define HTML_H 2#define HTML_H
3 3
4extern int htmlfd; 4extern int htmlfd;
5 5
6extern void html(const char *txt); 6extern void html(const char *txt);
7extern void htmlf(const char *format,...); 7extern void htmlf(const char *format,...);
8extern void html_txt(char *txt); 8extern void html_txt(char *txt);
9extern void html_ntxt(int len, char *txt); 9extern void html_ntxt(int len, char *txt);
10extern void html_attr(char *txt); 10extern void html_attr(char *txt);
11extern void html_hidden(char *name, char *value); 11extern void html_hidden(char *name, char *value);
12extern void html_option(char *value, char *text, char *selected_value); 12extern void html_option(char *value, char *text, char *selected_value);
13extern void html_link_open(char *url, char *title, char *class); 13extern void html_link_open(char *url, char *title, char *class);
14extern void html_link_close(void); 14extern void html_link_close(void);
15extern void html_fileperm(unsigned short mode); 15extern void html_fileperm(unsigned short mode);
16extern int html_include(const char *filename); 16extern int html_include(const char *filename);
17 17
18extern int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value));
19
18#endif /* HTML_H */ 20#endif /* HTML_H */
diff --git a/parsing.c b/parsing.c
index 9a4a7a3..66e8b3d 100644
--- a/parsing.c
+++ b/parsing.c
@@ -1,83 +1,34 @@
1/* config.c: parsing of config files 1/* config.c: parsing of config files
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
11char *convert_query_hexchar(char *txt)
12{
13 int d1, d2;
14 if (strlen(txt) < 3) {
15 *txt = '\0';
16 return txt-1;
17 }
18 d1 = hextoint(*(txt+1));
19 d2 = hextoint(*(txt+2));
20 if (d1<0 || d2<0) {
21 strcpy(txt, txt+3);
22 return txt-1;
23 } else {
24 *txt = d1 * 16 + d2;
25 strcpy(txt+1, txt+3);
26 return txt;
27 }
28}
29
30int cgit_parse_query(char *txt, configfn fn)
31{
32 char *t, *value = NULL, c;
33
34 if (!txt)
35 return 0;
36
37 t = txt = xstrdup(txt);
38
39 while((c=*t) != '\0') {
40 if (c=='=') {
41 *t = '\0';
42 value = t+1;
43 } else if (c=='+') {
44 *t = ' ';
45 } else if (c=='%') {
46 t = convert_query_hexchar(t);
47 } else if (c=='&') {
48 *t = '\0';
49 (*fn)(txt, value);
50 txt = t+1;
51 value = NULL;
52 }
53 t++;
54 }
55 if (t!=txt)
56 (*fn)(txt, value);
57 return 0;
58}
59
60/* 11/*
61 * url syntax: [repo ['/' cmd [ '/' path]]] 12 * url syntax: [repo ['/' cmd [ '/' path]]]
62 * repo: any valid repo url, may contain '/' 13 * repo: any valid repo url, may contain '/'
63 * cmd: log | commit | diff | tree | view | blob | snapshot 14 * cmd: log | commit | diff | tree | view | blob | snapshot
64 * path: any valid path, may contain '/' 15 * path: any valid path, may contain '/'
65 * 16 *
66 */ 17 */
67void cgit_parse_url(const char *url) 18void cgit_parse_url(const char *url)
68{ 19{
69 char *cmd, *p; 20 char *cmd, *p;
70 21
71 ctx.repo = NULL; 22 ctx.repo = NULL;
72 if (!url || url[0] == '\0') 23 if (!url || url[0] == '\0')
73 return; 24 return;
74 25
75 ctx.repo = cgit_get_repoinfo(url); 26 ctx.repo = cgit_get_repoinfo(url);
76 if (ctx.repo) { 27 if (ctx.repo) {
77 ctx.qry.repo = ctx.repo->url; 28 ctx.qry.repo = ctx.repo->url;
78 return; 29 return;
79 } 30 }
80 31
81 cmd = strchr(url, '/'); 32 cmd = strchr(url, '/');
82 while (!ctx.repo && cmd) { 33 while (!ctx.repo && cmd) {
83 cmd[0] = '\0'; 34 cmd[0] = '\0';
diff --git a/shared.c b/shared.c
index 48002ac..f5875e4 100644
--- a/shared.c
+++ b/shared.c
@@ -68,60 +68,48 @@ struct cgit_repo *cgit_get_repoinfo(const char *url)
68 int i; 68 int i;
69 struct cgit_repo *repo; 69 struct cgit_repo *repo;
70 70
71 for (i=0; i<cgit_repolist.count; i++) { 71 for (i=0; i<cgit_repolist.count; i++) {
72 repo = &cgit_repolist.repos[i]; 72 repo = &cgit_repolist.repos[i];
73 if (!strcmp(repo->url, url)) 73 if (!strcmp(repo->url, url))
74 return repo; 74 return repo;
75 } 75 }
76 return NULL; 76 return NULL;
77} 77}
78 78
79void *cgit_free_commitinfo(struct commitinfo *info) 79void *cgit_free_commitinfo(struct commitinfo *info)
80{ 80{
81 free(info->author); 81 free(info->author);
82 free(info->author_email); 82 free(info->author_email);
83 free(info->committer); 83 free(info->committer);
84 free(info->committer_email); 84 free(info->committer_email);
85 free(info->subject); 85 free(info->subject);
86 free(info->msg); 86 free(info->msg);
87 free(info->msg_encoding); 87 free(info->msg_encoding);
88 free(info); 88 free(info);
89 return NULL; 89 return NULL;
90} 90}
91 91
92int hextoint(char c)
93{
94 if (c >= 'a' && c <= 'f')
95 return 10 + c - 'a';
96 else if (c >= 'A' && c <= 'F')
97 return 10 + c - 'A';
98 else if (c >= '0' && c <= '9')
99 return c - '0';
100 else
101 return -1;
102}
103
104char *trim_end(const char *str, char c) 92char *trim_end(const char *str, char c)
105{ 93{
106 int len; 94 int len;
107 char *s, *t; 95 char *s, *t;
108 96
109 if (str == NULL) 97 if (str == NULL)
110 return NULL; 98 return NULL;
111 t = (char *)str; 99 t = (char *)str;
112 len = strlen(t); 100 len = strlen(t);
113 while(len > 0 && t[len - 1] == c) 101 while(len > 0 && t[len - 1] == c)
114 len--; 102 len--;
115 103
116 if (len == 0) 104 if (len == 0)
117 return NULL; 105 return NULL;
118 106
119 c = t[len]; 107 c = t[len];
120 t[len] = '\0'; 108 t[len] = '\0';
121 s = xstrdup(t); 109 s = xstrdup(t);
122 t[len] = c; 110 t[len] = c;
123 return s; 111 return s;
124} 112}
125 113
126char *strlpart(char *txt, int maxlen) 114char *strlpart(char *txt, int maxlen)
127{ 115{