summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile1
-rw-r--r--cgit.c5
-rw-r--r--cgit.h1
-rw-r--r--configfile.c87
-rw-r--r--configfile.h8
-rw-r--r--parsing.c75
6 files changed, 99 insertions, 78 deletions
diff --git a/Makefile b/Makefile
index 223765d..355186e 100644
--- a/Makefile
+++ b/Makefile
@@ -38,32 +38,33 @@ endif
38# 38#
39%.d: %.c 39%.d: %.c
40 $(QUIET_MM)$(CC) $(CFLAGS) -MM $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@ 40 $(QUIET_MM)$(CC) $(CFLAGS) -MM $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@
41 41
42# 42#
43# Define a pattern rule for silent object building 43# Define a pattern rule for silent object building
44# 44#
45%.o: %.c 45%.o: %.c
46 $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< 46 $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
47 47
48 48
49EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto 49EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
50OBJECTS = 50OBJECTS =
51OBJECTS += cache.o 51OBJECTS += cache.o
52OBJECTS += cgit.o 52OBJECTS += cgit.o
53OBJECTS += cmd.o 53OBJECTS += cmd.o
54OBJECTS += configfile.o
54OBJECTS += html.o 55OBJECTS += html.o
55OBJECTS += parsing.o 56OBJECTS += parsing.o
56OBJECTS += shared.o 57OBJECTS += shared.o
57OBJECTS += ui-blob.o 58OBJECTS += ui-blob.o
58OBJECTS += ui-commit.o 59OBJECTS += ui-commit.o
59OBJECTS += ui-diff.o 60OBJECTS += ui-diff.o
60OBJECTS += ui-log.o 61OBJECTS += ui-log.o
61OBJECTS += ui-patch.o 62OBJECTS += ui-patch.o
62OBJECTS += ui-refs.o 63OBJECTS += ui-refs.o
63OBJECTS += ui-repolist.o 64OBJECTS += ui-repolist.o
64OBJECTS += ui-shared.o 65OBJECTS += ui-shared.o
65OBJECTS += ui-snapshot.o 66OBJECTS += ui-snapshot.o
66OBJECTS += ui-summary.o 67OBJECTS += ui-summary.o
67OBJECTS += ui-tag.o 68OBJECTS += ui-tag.o
68OBJECTS += ui-tree.o 69OBJECTS += ui-tree.o
69 70
diff --git a/cgit.c b/cgit.c
index 73b1f02..1f46e0d 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,27 +1,28 @@
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 "ui-shared.h" 13#include "ui-shared.h"
13 14
14const char *cgit_version = CGIT_VERSION; 15const char *cgit_version = CGIT_VERSION;
15 16
16void config_cb(const char *name, const char *value) 17void config_cb(const char *name, const char *value)
17{ 18{
18 if (!strcmp(name, "root-title")) 19 if (!strcmp(name, "root-title"))
19 ctx.cfg.root_title = xstrdup(value); 20 ctx.cfg.root_title = xstrdup(value);
20 else if (!strcmp(name, "css")) 21 else if (!strcmp(name, "css"))
21 ctx.cfg.css = xstrdup(value); 22 ctx.cfg.css = xstrdup(value);
22 else if (!strcmp(name, "logo")) 23 else if (!strcmp(name, "logo"))
23 ctx.cfg.logo = xstrdup(value); 24 ctx.cfg.logo = xstrdup(value);
24 else if (!strcmp(name, "index-header")) 25 else if (!strcmp(name, "index-header"))
25 ctx.cfg.index_header = xstrdup(value); 26 ctx.cfg.index_header = xstrdup(value);
26 else if (!strcmp(name, "index-info")) 27 else if (!strcmp(name, "index-info"))
27 ctx.cfg.index_info = xstrdup(value); 28 ctx.cfg.index_info = xstrdup(value);
@@ -90,33 +91,33 @@ void config_cb(const char *name, const char *value)
90 else if (ctx.repo && !strcmp(name, "repo.defbranch")) 91 else if (ctx.repo && !strcmp(name, "repo.defbranch"))
91 ctx.repo->defbranch = xstrdup(value); 92 ctx.repo->defbranch = xstrdup(value);
92 else if (ctx.repo && !strcmp(name, "repo.snapshots")) 93 else if (ctx.repo && !strcmp(name, "repo.snapshots"))
93 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ 94 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */
94 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) 95 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount"))
95 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 96 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
96 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) 97 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount"))
97 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 98 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
98 else if (ctx.repo && !strcmp(name, "repo.module-link")) 99 else if (ctx.repo && !strcmp(name, "repo.module-link"))
99 ctx.repo->module_link= xstrdup(value); 100 ctx.repo->module_link= xstrdup(value);
100 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { 101 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) {
101 if (*value == '/') 102 if (*value == '/')
102 ctx.repo->readme = xstrdup(value); 103 ctx.repo->readme = xstrdup(value);
103 else 104 else
104 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); 105 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value));
105 } else if (!strcmp(name, "include")) 106 } else if (!strcmp(name, "include"))
106 cgit_read_config(value, config_cb); 107 parse_configfile(value, config_cb);
107} 108}
108 109
109static void querystring_cb(const char *name, const char *value) 110static void querystring_cb(const char *name, const char *value)
110{ 111{
111 if (!strcmp(name,"r")) { 112 if (!strcmp(name,"r")) {
112 ctx.qry.repo = xstrdup(value); 113 ctx.qry.repo = xstrdup(value);
113 ctx.repo = cgit_get_repoinfo(value); 114 ctx.repo = cgit_get_repoinfo(value);
114 } else if (!strcmp(name, "p")) { 115 } else if (!strcmp(name, "p")) {
115 ctx.qry.page = xstrdup(value); 116 ctx.qry.page = xstrdup(value);
116 } else if (!strcmp(name, "url")) { 117 } else if (!strcmp(name, "url")) {
117 cgit_parse_url(value); 118 cgit_parse_url(value);
118 } else if (!strcmp(name, "qt")) { 119 } else if (!strcmp(name, "qt")) {
119 ctx.qry.grep = xstrdup(value); 120 ctx.qry.grep = xstrdup(value);
120 } else if (!strcmp(name, "q")) { 121 } else if (!strcmp(name, "q")) {
121 ctx.qry.search = xstrdup(value); 122 ctx.qry.search = xstrdup(value);
122 } else if (!strcmp(name, "h")) { 123 } else if (!strcmp(name, "h")) {
@@ -423,33 +424,33 @@ static void cgit_parse_args(int argc, const char **argv)
423 ctx.qry.ofs = atoi(argv[i]+6); 424 ctx.qry.ofs = atoi(argv[i]+6);
424 } 425 }
425 } 426 }
426} 427}
427 428
428int main(int argc, const char **argv) 429int main(int argc, const char **argv)
429{ 430{
430 struct cacheitem item; 431 struct cacheitem item;
431 const char *cgit_config_env = getenv("CGIT_CONFIG"); 432 const char *cgit_config_env = getenv("CGIT_CONFIG");
432 433
433 prepare_context(&ctx); 434 prepare_context(&ctx);
434 item.st.st_mtime = time(NULL); 435 item.st.st_mtime = time(NULL);
435 cgit_repolist.length = 0; 436 cgit_repolist.length = 0;
436 cgit_repolist.count = 0; 437 cgit_repolist.count = 0;
437 cgit_repolist.repos = NULL; 438 cgit_repolist.repos = NULL;
438 439
439 cgit_read_config(cgit_config_env ? cgit_config_env : CGIT_CONFIG, 440 parse_configfile(cgit_config_env ? cgit_config_env : CGIT_CONFIG,
440 config_cb); 441 config_cb);
441 if (getenv("SCRIPT_NAME")) 442 if (getenv("SCRIPT_NAME"))
442 ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME")); 443 ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME"));
443 if (getenv("QUERY_STRING")) 444 if (getenv("QUERY_STRING"))
444 ctx.qry.raw = xstrdup(getenv("QUERY_STRING")); 445 ctx.qry.raw = xstrdup(getenv("QUERY_STRING"));
445 cgit_parse_args(argc, argv); 446 cgit_parse_args(argc, argv);
446 cgit_parse_query(ctx.qry.raw, querystring_cb); 447 cgit_parse_query(ctx.qry.raw, querystring_cb);
447 if (!cgit_prepare_cache(&item)) 448 if (!cgit_prepare_cache(&item))
448 return 0; 449 return 0;
449 if (ctx.cfg.nocache) { 450 if (ctx.cfg.nocache) {
450 cgit_fill_cache(&item, 0); 451 cgit_fill_cache(&item, 0);
451 } else { 452 } else {
452 cgit_check_cache(&item); 453 cgit_check_cache(&item);
453 cgit_print_cache(&item); 454 cgit_print_cache(&item);
454 } 455 }
455 return 0; 456 return 0;
diff --git a/cgit.h b/cgit.h
index f600912..91d18f8 100644
--- a/cgit.h
+++ b/cgit.h
@@ -201,27 +201,26 @@ extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
201 int flags, void *cb_data); 201 int flags, void *cb_data);
202 202
203extern void *cgit_free_commitinfo(struct commitinfo *info); 203extern void *cgit_free_commitinfo(struct commitinfo *info);
204 204
205extern int cgit_diff_files(const unsigned char *old_sha1, 205extern int cgit_diff_files(const unsigned char *old_sha1,
206 const unsigned char *new_sha1, 206 const unsigned char *new_sha1,
207 linediff_fn fn); 207 linediff_fn fn);
208 208
209extern void cgit_diff_tree(const unsigned char *old_sha1, 209extern void cgit_diff_tree(const unsigned char *old_sha1,
210 const unsigned char *new_sha1, 210 const unsigned char *new_sha1,
211 filepair_fn fn, const char *prefix); 211 filepair_fn fn, const char *prefix);
212 212
213extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 213extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
214 214
215extern char *fmt(const char *format,...); 215extern char *fmt(const char *format,...);
216 216
217extern int cgit_read_config(const char *filename, configfn fn);
218extern int cgit_parse_query(char *txt, configfn fn); 217extern int cgit_parse_query(char *txt, configfn fn);
219extern struct commitinfo *cgit_parse_commit(struct commit *commit); 218extern struct commitinfo *cgit_parse_commit(struct commit *commit);
220extern struct taginfo *cgit_parse_tag(struct tag *tag); 219extern struct taginfo *cgit_parse_tag(struct tag *tag);
221extern void cgit_parse_url(const char *url); 220extern void cgit_parse_url(const char *url);
222 221
223extern const char *cgit_repobasename(const char *reponame); 222extern const char *cgit_repobasename(const char *reponame);
224 223
225extern int cgit_parse_snapshots_mask(const char *str); 224extern int cgit_parse_snapshots_mask(const char *str);
226 225
227#endif /* CGIT_H */ 226#endif /* CGIT_H */
diff --git a/configfile.c b/configfile.c
new file mode 100644
index 0000000..4908058
--- a/dev/null
+++ b/configfile.c
@@ -0,0 +1,87 @@
1/* configfile.c: parsing of config files
2 *
3 * Copyright (C) 2008 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
9#include <ctype.h>
10#include <stdio.h>
11#include "configfile.h"
12
13int next_char(FILE *f)
14{
15 int c = fgetc(f);
16 if (c=='\r') {
17 c = fgetc(f);
18 if (c!='\n') {
19 ungetc(c, f);
20 c = '\r';
21 }
22 }
23 return c;
24}
25
26void skip_line(FILE *f)
27{
28 int c;
29
30 while((c=next_char(f)) && c!='\n' && c!=EOF)
31 ;
32}
33
34int read_config_line(FILE *f, char *line, const char **value, int bufsize)
35{
36 int i = 0, isname = 0;
37
38 *value = NULL;
39 while(i<bufsize-1) {
40 int c = next_char(f);
41 if (!isname && (c=='#' || c==';')) {
42 skip_line(f);
43 continue;
44 }
45 if (!isname && isspace(c))
46 continue;
47
48 if (c=='=' && !*value) {
49 line[i] = 0;
50 *value = &line[i+1];
51 } else if (c=='\n' && !isname) {
52 i = 0;
53 continue;
54 } else if (c=='\n' || c==EOF) {
55 line[i] = 0;
56 break;
57 } else {
58 line[i]=c;
59 }
60 isname = 1;
61 i++;
62 }
63 line[i+1] = 0;
64 return i;
65}
66
67int parse_configfile(const char *filename, configfile_value_fn fn)
68{
69 static int nesting;
70 int len;
71 char line[256];
72 const char *value;
73 FILE *f;
74
75 /* cancel deeply nested include-commands */
76 if (nesting > 8)
77 return -1;
78 if (!(f = fopen(filename, "r")))
79 return -1;
80 nesting++;
81 while((len = read_config_line(f, line, &value, sizeof(line))) > 0)
82 fn(line, value);
83 nesting--;
84 fclose(f);
85 return 0;
86}
87
diff --git a/configfile.h b/configfile.h
new file mode 100644
index 0000000..04235e5
--- a/dev/null
+++ b/configfile.h
@@ -0,0 +1,8 @@
1#ifndef CONFIGFILE_H
2#define CONFIGFILE_H
3
4typedef void (*configfile_value_fn)(const char *name, const char *value);
5
6extern int parse_configfile(const char *filename, configfile_value_fn fn);
7
8#endif /* CONFIGFILE_H */
diff --git a/parsing.c b/parsing.c
index 8dce488..9a4a7a3 100644
--- a/parsing.c
+++ b/parsing.c
@@ -1,101 +1,26 @@
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
11int next_char(FILE *f)
12{
13 int c = fgetc(f);
14 if (c=='\r') {
15 c = fgetc(f);
16 if (c!='\n') {
17 ungetc(c, f);
18 c = '\r';
19 }
20 }
21 return c;
22}
23
24void skip_line(FILE *f)
25{
26 int c;
27
28 while((c=next_char(f)) && c!='\n' && c!=EOF)
29 ;
30}
31
32int read_config_line(FILE *f, char *line, const char **value, int bufsize)
33{
34 int i = 0, isname = 0;
35
36 *value = NULL;
37 while(i<bufsize-1) {
38 int c = next_char(f);
39 if (!isname && (c=='#' || c==';')) {
40 skip_line(f);
41 continue;
42 }
43 if (!isname && isspace(c))
44 continue;
45
46 if (c=='=' && !*value) {
47 line[i] = 0;
48 *value = &line[i+1];
49 } else if (c=='\n' && !isname) {
50 i = 0;
51 continue;
52 } else if (c=='\n' || c==EOF) {
53 line[i] = 0;
54 break;
55 } else {
56 line[i]=c;
57 }
58 isname = 1;
59 i++;
60 }
61 line[i+1] = 0;
62 return i;
63}
64
65int cgit_read_config(const char *filename, configfn fn)
66{
67 static int nesting;
68 int len;
69 char line[256];
70 const char *value;
71 FILE *f;
72
73 /* cancel deeply nested include-commands */
74 if (nesting > 8)
75 return -1;
76 if (!(f = fopen(filename, "r")))
77 return -1;
78 nesting++;
79 while((len = read_config_line(f, line, &value, sizeof(line))) > 0)
80 (*fn)(line, value);
81 nesting--;
82 fclose(f);
83 return 0;
84}
85
86char *convert_query_hexchar(char *txt) 11char *convert_query_hexchar(char *txt)
87{ 12{
88 int d1, d2; 13 int d1, d2;
89 if (strlen(txt) < 3) { 14 if (strlen(txt) < 3) {
90 *txt = '\0'; 15 *txt = '\0';
91 return txt-1; 16 return txt-1;
92 } 17 }
93 d1 = hextoint(*(txt+1)); 18 d1 = hextoint(*(txt+1));
94 d2 = hextoint(*(txt+2)); 19 d2 = hextoint(*(txt+2));
95 if (d1<0 || d2<0) { 20 if (d1<0 || d2<0) {
96 strcpy(txt, txt+3); 21 strcpy(txt, txt+3);
97 return txt-1; 22 return txt-1;
98 } else { 23 } else {
99 *txt = d1 * 16 + d2; 24 *txt = d1 * 16 + d2;
100 strcpy(txt+1, txt+3); 25 strcpy(txt+1, txt+3);
101 return txt; 26 return txt;