summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2006-12-11 15:48:03 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2006-12-11 15:49:18 (UTC)
commit74620f12e4f7e91cb0a0b4ca731e07272d1b65f6 (patch) (unidiff)
tree2e4db980535682c0a606d425b2937126d4b2c09b
parent5a106eb09b9b5e189b96cc736046a92b054f6c7f (diff)
downloadcgit-74620f12e4f7e91cb0a0b4ca731e07272d1b65f6.zip
cgit-74620f12e4f7e91cb0a0b4ca731e07272d1b65f6.tar.gz
cgit-74620f12e4f7e91cb0a0b4ca731e07272d1b65f6.tar.bz2
Move functions for repolist output into ui-repolist.c
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--cgit.c69
-rw-r--r--cgit.h8
-rw-r--r--ui-repolist.c60
-rw-r--r--ui-shared.c21
5 files changed, 90 insertions, 70 deletions
diff --git a/Makefile b/Makefile
index a4291f7..81ebb18 100644
--- a/Makefile
+++ b/Makefile
@@ -1,27 +1,27 @@
1CGIT_VERSION = 0.1-pre 1CGIT_VERSION = 0.1-pre
2 2
3INSTALL_BIN = /var/www/htdocs/cgit.cgi 3INSTALL_BIN = /var/www/htdocs/cgit.cgi
4INSTALL_CSS = /var/www/htdocs/cgit.css 4INSTALL_CSS = /var/www/htdocs/cgit.css
5CACHE_ROOT = /var/cache/cgit 5CACHE_ROOT = /var/cache/cgit
6 6
7EXTLIBS = ../git/libgit.a ../git/xdiff/lib.a -lz -lcrypto 7EXTLIBS = ../git/libgit.a ../git/xdiff/lib.a -lz -lcrypto
8OBJECTS = parsing.o html.o cache.o ui-shared.o 8OBJECTS = parsing.o html.o cache.o ui-shared.o ui-repolist.o
9 9
10CFLAGS += -Wall 10CFLAGS += -Wall
11 11
12all: cgit 12all: cgit
13 13
14install: all 14install: all
15 install cgit $(INSTALL_BIN) 15 install cgit $(INSTALL_BIN)
16 install cgit.css $(INSTALL_CSS) 16 install cgit.css $(INSTALL_CSS)
17 rm -rf $(CACHE_ROOT)/* 17 rm -rf $(CACHE_ROOT)/*
18 18
19cgit: cgit.c cgit.h git.h $(OBJECTS) 19cgit: cgit.c cgit.h git.h $(OBJECTS)
20 $(CC) $(CFLAGS) -DCGIT_VERSION='"$(CGIT_VERSION)"' cgit.c -o cgit \ 20 $(CC) $(CFLAGS) -DCGIT_VERSION='"$(CGIT_VERSION)"' cgit.c -o cgit \
21 $(OBJECTS) $(EXTLIBS) 21 $(OBJECTS) $(EXTLIBS)
22 22
23$(OBJECTS): cgit.h git.h 23$(OBJECTS): cgit.h git.h
24 24
25.PHONY: clean 25.PHONY: clean
26clean: 26clean:
27 rm -f cgit *.o 27 rm -f cgit *.o
diff --git a/cgit.c b/cgit.c
index 5438fa1..b3ff512 100644
--- a/cgit.c
+++ b/cgit.c
@@ -39,195 +39,126 @@ char *cgit_querystring = NULL;
39char *cgit_query_repo = NULL; 39char *cgit_query_repo = NULL;
40char *cgit_query_page = NULL; 40char *cgit_query_page = NULL;
41char *cgit_query_head = NULL; 41char *cgit_query_head = NULL;
42char *cgit_query_sha1 = NULL; 42char *cgit_query_sha1 = NULL;
43 43
44struct cacheitem cacheitem; 44struct cacheitem cacheitem;
45 45
46void cgit_global_config_cb(const char *name, const char *value) 46void cgit_global_config_cb(const char *name, const char *value)
47{ 47{
48 if (!strcmp(name, "root")) 48 if (!strcmp(name, "root"))
49 cgit_root = xstrdup(value); 49 cgit_root = xstrdup(value);
50 else if (!strcmp(name, "root-title")) 50 else if (!strcmp(name, "root-title"))
51 cgit_root_title = xstrdup(value); 51 cgit_root_title = xstrdup(value);
52 else if (!strcmp(name, "css")) 52 else if (!strcmp(name, "css"))
53 cgit_css = xstrdup(value); 53 cgit_css = xstrdup(value);
54 else if (!strcmp(name, "logo")) 54 else if (!strcmp(name, "logo"))
55 cgit_logo = xstrdup(value); 55 cgit_logo = xstrdup(value);
56 else if (!strcmp(name, "logo-link")) 56 else if (!strcmp(name, "logo-link"))
57 cgit_logo_link = xstrdup(value); 57 cgit_logo_link = xstrdup(value);
58 else if (!strcmp(name, "virtual-root")) 58 else if (!strcmp(name, "virtual-root"))
59 cgit_virtual_root = xstrdup(value); 59 cgit_virtual_root = xstrdup(value);
60} 60}
61 61
62void cgit_repo_config_cb(const char *name, const char *value) 62void cgit_repo_config_cb(const char *name, const char *value)
63{ 63{
64 if (!strcmp(name, "name")) 64 if (!strcmp(name, "name"))
65 cgit_repo_name = xstrdup(value); 65 cgit_repo_name = xstrdup(value);
66 else if (!strcmp(name, "desc")) 66 else if (!strcmp(name, "desc"))
67 cgit_repo_desc = xstrdup(value); 67 cgit_repo_desc = xstrdup(value);
68 else if (!strcmp(name, "owner")) 68 else if (!strcmp(name, "owner"))
69 cgit_repo_owner = xstrdup(value); 69 cgit_repo_owner = xstrdup(value);
70} 70}
71 71
72void cgit_querystring_cb(const char *name, const char *value) 72void cgit_querystring_cb(const char *name, const char *value)
73{ 73{
74 if (!strcmp(name,"r")) 74 if (!strcmp(name,"r"))
75 cgit_query_repo = xstrdup(value); 75 cgit_query_repo = xstrdup(value);
76 else if (!strcmp(name, "p")) 76 else if (!strcmp(name, "p"))
77 cgit_query_page = xstrdup(value); 77 cgit_query_page = xstrdup(value);
78 else if (!strcmp(name, "h")) { 78 else if (!strcmp(name, "h")) {
79 cgit_query_head = xstrdup(value); 79 cgit_query_head = xstrdup(value);
80 cgit_query_has_symref = 1; 80 cgit_query_has_symref = 1;
81 } else if (!strcmp(name, "id")) { 81 } else if (!strcmp(name, "id")) {
82 cgit_query_sha1 = xstrdup(value); 82 cgit_query_sha1 = xstrdup(value);
83 cgit_query_has_sha1 = 1; 83 cgit_query_has_sha1 = 1;
84 } 84 }
85} 85}
86 86
87char *cgit_repourl(const char *reponame)
88{
89 if (cgit_virtual_root) {
90 return fmt("%s/%s/", cgit_virtual_root, reponame);
91 } else {
92 return fmt("?r=%s", reponame);
93 }
94}
95
96char *cgit_pageurl(const char *reponame, const char *pagename,
97 const char *query)
98{
99 if (cgit_virtual_root) {
100 return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame,
101 pagename, query);
102 } else {
103 return fmt("?r=%s&p=%s&%s", reponame, pagename, query);
104 }
105}
106
107static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, 87static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
108 int flags, void *cb_data) 88 int flags, void *cb_data)
109{ 89{
110 struct commit *commit; 90 struct commit *commit;
111 char buf[256], *url; 91 char buf[256], *url;
112 92
113 commit = lookup_commit(sha1); 93 commit = lookup_commit(sha1);
114 if (commit && !parse_commit(commit)){ 94 if (commit && !parse_commit(commit)){
115 html("<tr><td>"); 95 html("<tr><td>");
116 url = cgit_pageurl(cgit_query_repo, "log", 96 url = cgit_pageurl(cgit_query_repo, "log",
117 fmt("h=%s", refname)); 97 fmt("h=%s", refname));
118 html_link_open(url, NULL, NULL); 98 html_link_open(url, NULL, NULL);
119 strncpy(buf, refname, sizeof(buf)); 99 strncpy(buf, refname, sizeof(buf));
120 html_txt(buf); 100 html_txt(buf);
121 html_link_close(); 101 html_link_close();
122 html("</td><td>"); 102 html("</td><td>");
123 pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf, 103 pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf,
124 sizeof(buf), 0, NULL, NULL, 0); 104 sizeof(buf), 0, NULL, NULL, 0);
125 html_txt(buf); 105 html_txt(buf);
126 html("</td></tr>\n"); 106 html("</td></tr>\n");
127 } else { 107 } else {
128 html("<tr><td>"); 108 html("<tr><td>");
129 html_txt(buf); 109 html_txt(buf);
130 html("</td><td>"); 110 html("</td><td>");
131 htmlf("*** bad ref %s", sha1_to_hex(sha1)); 111 htmlf("*** bad ref %s", sha1_to_hex(sha1));
132 html("</td></tr>\n"); 112 html("</td></tr>\n");
133 } 113 }
134 return 0; 114 return 0;
135} 115}
136 116
137static void cgit_print_repolist(struct cacheitem *item)
138{
139 DIR *d;
140 struct dirent *de;
141 struct stat st;
142 char *name;
143
144 chdir(cgit_root);
145 cgit_print_docstart(cgit_root_title, item);
146 cgit_print_pageheader(cgit_root_title);
147
148 if (!(d = opendir("."))) {
149 cgit_print_error(fmt("Unable to scan repository directory: %s",
150 strerror(errno)));
151 cgit_print_docend();
152 return;
153 }
154
155 html("<h2>Repositories</h2>\n");
156 html("<table class='list'>");
157 html("<tr><th>Name</th><th>Description</th><th>Owner</th></tr>\n");
158 while ((de = readdir(d)) != NULL) {
159 if (de->d_name[0] == '.')
160 continue;
161 if (stat(de->d_name, &st) < 0)
162 continue;
163 if (!S_ISDIR(st.st_mode))
164 continue;
165
166 cgit_repo_name = cgit_repo_desc = cgit_repo_owner = NULL;
167 name = fmt("%s/info/cgit", de->d_name);
168 if (cgit_read_config(name, cgit_repo_config_cb))
169 continue;
170
171 html("<tr><td>");
172 html_link_open(cgit_repourl(de->d_name), NULL, NULL);
173 html_txt(cgit_repo_name);
174 html_link_close();
175 html("</td><td>");
176 html_txt(cgit_repo_desc);
177 html("</td><td>");
178 html_txt(cgit_repo_owner);
179 html("</td></tr>\n");
180 }
181 closedir(d);
182 html("</table>");
183 cgit_print_docend();
184}
185
186static void cgit_print_branches() 117static void cgit_print_branches()
187{ 118{
188 html("<table class='list'>"); 119 html("<table class='list'>");
189 html("<tr><th>Branch name</th><th>Head commit</th></tr>\n"); 120 html("<tr><th>Branch name</th><th>Head commit</th></tr>\n");
190 for_each_branch_ref(cgit_print_branch_cb, NULL); 121 for_each_branch_ref(cgit_print_branch_cb, NULL);
191 html("</table>"); 122 html("</table>");
192} 123}
193 124
194static int get_one_line(char *txt) 125static int get_one_line(char *txt)
195{ 126{
196 char *t; 127 char *t;
197 128
198 for(t=txt; *t != '\n' && t != '\0'; t++) 129 for(t=txt; *t != '\n' && t != '\0'; t++)
199 ; 130 ;
200 *t = '\0'; 131 *t = '\0';
201 return t-txt-1; 132 return t-txt-1;
202} 133}
203 134
204static void cgit_print_commit_shortlog(struct commit *commit) 135static void cgit_print_commit_shortlog(struct commit *commit)
205{ 136{
206 char *h, *t, *p; 137 char *h, *t, *p;
207 char *tree = NULL, *author = NULL, *subject = NULL; 138 char *tree = NULL, *author = NULL, *subject = NULL;
208 int len; 139 int len;
209 time_t sec; 140 time_t sec;
210 struct tm *time; 141 struct tm *time;
211 char buf[32]; 142 char buf[32];
212 143
213 h = t = commit->buffer; 144 h = t = commit->buffer;
214 145
215 if (strncmp(h, "tree ", 5)) 146 if (strncmp(h, "tree ", 5))
216 die("Bad commit format: %s", 147 die("Bad commit format: %s",
217 sha1_to_hex(commit->object.sha1)); 148 sha1_to_hex(commit->object.sha1));
218 149
219 len = get_one_line(h); 150 len = get_one_line(h);
220 tree = h+5; 151 tree = h+5;
221 h += len + 2; 152 h += len + 2;
222 153
223 while (!strncmp(h, "parent ", 7)) 154 while (!strncmp(h, "parent ", 7))
224 h += get_one_line(h) + 2; 155 h += get_one_line(h) + 2;
225 156
226 if (!strncmp(h, "author ", 7)) { 157 if (!strncmp(h, "author ", 7)) {
227 author = h+7; 158 author = h+7;
228 h += get_one_line(h) + 2; 159 h += get_one_line(h) + 2;
229 t = author; 160 t = author;
230 while(t!=h && *t!='<') 161 while(t!=h && *t!='<')
231 t++; 162 t++;
232 *t='\0'; 163 *t='\0';
233 p = t; 164 p = t;
diff --git a/cgit.h b/cgit.h
index e64fbd7..bf5bd8d 100644
--- a/cgit.h
+++ b/cgit.h
@@ -20,55 +20,63 @@ extern const char cgit_version[];
20extern char *cgit_root; 20extern char *cgit_root;
21extern char *cgit_root_title; 21extern char *cgit_root_title;
22extern char *cgit_css; 22extern char *cgit_css;
23extern char *cgit_logo; 23extern char *cgit_logo;
24extern char *cgit_logo_link; 24extern char *cgit_logo_link;
25extern char *cgit_virtual_root; 25extern char *cgit_virtual_root;
26extern char *cgit_cache_root; 26extern char *cgit_cache_root;
27 27
28extern int cgit_max_lock_attempts; 28extern int cgit_max_lock_attempts;
29extern int cgit_cache_root_ttl; 29extern int cgit_cache_root_ttl;
30extern int cgit_cache_repo_ttl; 30extern int cgit_cache_repo_ttl;
31extern int cgit_cache_dynamic_ttl; 31extern int cgit_cache_dynamic_ttl;
32extern int cgit_cache_static_ttl; 32extern int cgit_cache_static_ttl;
33extern int cgit_cache_max_create_time; 33extern int cgit_cache_max_create_time;
34 34
35extern char *cgit_repo_name; 35extern char *cgit_repo_name;
36extern char *cgit_repo_desc; 36extern char *cgit_repo_desc;
37extern char *cgit_repo_owner; 37extern char *cgit_repo_owner;
38 38
39extern int cgit_query_has_symref; 39extern int cgit_query_has_symref;
40extern int cgit_query_has_sha1; 40extern int cgit_query_has_sha1;
41 41
42extern char *cgit_querystring; 42extern char *cgit_querystring;
43extern char *cgit_query_repo; 43extern char *cgit_query_repo;
44extern char *cgit_query_page; 44extern char *cgit_query_page;
45extern char *cgit_query_head; 45extern char *cgit_query_head;
46extern char *cgit_query_sha1; 46extern char *cgit_query_sha1;
47 47
48extern int htmlfd; 48extern int htmlfd;
49 49
50extern char *fmt(const char *format,...); 50extern char *fmt(const char *format,...);
51 51
52extern void html(const char *txt); 52extern void html(const char *txt);
53extern void htmlf(const char *format,...); 53extern void htmlf(const char *format,...);
54extern void html_txt(char *txt); 54extern void html_txt(char *txt);
55extern void html_attr(char *txt); 55extern void html_attr(char *txt);
56extern void html_link_open(char *url, char *title, char *class); 56extern void html_link_open(char *url, char *title, char *class);
57extern void html_link_close(void); 57extern void html_link_close(void);
58 58
59extern int cgit_read_config(const char *filename, configfn fn); 59extern int cgit_read_config(const char *filename, configfn fn);
60extern int cgit_parse_query(char *txt, configfn fn); 60extern int cgit_parse_query(char *txt, configfn fn);
61 61
62extern void cache_prepare(struct cacheitem *item); 62extern void cache_prepare(struct cacheitem *item);
63extern int cache_lock(struct cacheitem *item); 63extern int cache_lock(struct cacheitem *item);
64extern int cache_unlock(struct cacheitem *item); 64extern int cache_unlock(struct cacheitem *item);
65extern int cache_exist(struct cacheitem *item); 65extern int cache_exist(struct cacheitem *item);
66extern int cache_expired(struct cacheitem *item); 66extern int cache_expired(struct cacheitem *item);
67 67
68extern char *cgit_repourl(const char *reponame);
69extern char *cgit_pageurl(const char *reponame, const char *pagename,
70 const char *query);
71
68extern void cgit_print_error(char *msg); 72extern void cgit_print_error(char *msg);
69extern void cgit_print_docstart(char *title, struct cacheitem *item); 73extern void cgit_print_docstart(char *title, struct cacheitem *item);
70extern void cgit_print_docend(); 74extern void cgit_print_docend();
71extern void cgit_print_pageheader(char *title); 75extern void cgit_print_pageheader(char *title);
72 76
77extern void cgit_print_repolist(struct cacheitem *item);
78
79
80extern void cgit_repo_config_cb(const char *name, const char *value);
73 81
74#endif /* CGIT_H */ 82#endif /* CGIT_H */
diff --git a/ui-repolist.c b/ui-repolist.c
new file mode 100644
index 0000000..1fe7059
--- a/dev/null
+++ b/ui-repolist.c
@@ -0,0 +1,60 @@
1/* ui-repolist.c: functions for generating the repolist page
2 *
3 * Copyright (C) 2006 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
11void cgit_print_repolist(struct cacheitem *item)
12{
13 DIR *d;
14 struct dirent *de;
15 struct stat st;
16 char *name;
17
18 chdir(cgit_root);
19 cgit_print_docstart(cgit_root_title, item);
20 cgit_print_pageheader(cgit_root_title);
21
22 if (!(d = opendir("."))) {
23 cgit_print_error(fmt("Unable to scan repository directory: %s",
24 strerror(errno)));
25 cgit_print_docend();
26 return;
27 }
28
29 html("<h2>Repositories</h2>\n");
30 html("<table class='list'>");
31 html("<tr><th>Name</th><th>Description</th><th>Owner</th></tr>\n");
32 while ((de = readdir(d)) != NULL) {
33 if (de->d_name[0] == '.')
34 continue;
35 if (stat(de->d_name, &st) < 0)
36 continue;
37 if (!S_ISDIR(st.st_mode))
38 continue;
39
40 cgit_repo_name = cgit_repo_desc = cgit_repo_owner = NULL;
41 name = fmt("%s/info/cgit", de->d_name);
42 if (cgit_read_config(name, cgit_repo_config_cb))
43 continue;
44
45 html("<tr><td>");
46 html_link_open(cgit_repourl(de->d_name), NULL, NULL);
47 html_txt(cgit_repo_name);
48 html_link_close();
49 html("</td><td>");
50 html_txt(cgit_repo_desc);
51 html("</td><td>");
52 html_txt(cgit_repo_owner);
53 html("</td></tr>\n");
54 }
55 closedir(d);
56 html("</table>");
57 cgit_print_docend();
58}
59
60
diff --git a/ui-shared.c b/ui-shared.c
index e795043..cb8a8df 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -1,76 +1,97 @@
1/* ui-shared.c: common web output functions 1/* ui-shared.c: common web output 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
11const char cgit_doctype[] = 11const char cgit_doctype[] =
12"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" 12"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
13" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 13" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
14 14
15static char *http_date(time_t t) 15static char *http_date(time_t t)
16{ 16{
17 static char day[][4] = 17 static char day[][4] =
18 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 18 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
19 static char month[][4] = 19 static char month[][4] =
20 {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 20 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
21 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; 21 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"};
22 struct tm *tm = gmtime(&t); 22 struct tm *tm = gmtime(&t);
23 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday], 23 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday],
24 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, 24 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year,
25 tm->tm_hour, tm->tm_min, tm->tm_sec); 25 tm->tm_hour, tm->tm_min, tm->tm_sec);
26} 26}
27 27
28static int ttl_seconds(int ttl) 28static int ttl_seconds(int ttl)
29{ 29{
30 if (ttl<0) 30 if (ttl<0)
31 return 60 * 60 * 24 * 365; 31 return 60 * 60 * 24 * 365;
32 else 32 else
33 return ttl * 60; 33 return ttl * 60;
34} 34}
35 35
36void cgit_print_error(char *msg) 36void cgit_print_error(char *msg)
37{ 37{
38 html("<div class='error'>"); 38 html("<div class='error'>");
39 html_txt(msg); 39 html_txt(msg);
40 html("</div>\n"); 40 html("</div>\n");
41} 41}
42
43char *cgit_repourl(const char *reponame)
44{
45 if (cgit_virtual_root) {
46 return fmt("%s/%s/", cgit_virtual_root, reponame);
47 } else {
48 return fmt("?r=%s", reponame);
49 }
50}
51
52char *cgit_pageurl(const char *reponame, const char *pagename,
53 const char *query)
54{
55 if (cgit_virtual_root) {
56 return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame,
57 pagename, query);
58 } else {
59 return fmt("?r=%s&p=%s&%s", reponame, pagename, query);
60 }
61}
62
42void cgit_print_docstart(char *title, struct cacheitem *item) 63void cgit_print_docstart(char *title, struct cacheitem *item)
43{ 64{
44 html("Content-Type: text/html; charset=utf-8\n"); 65 html("Content-Type: text/html; charset=utf-8\n");
45 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); 66 htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime));
46 htmlf("Expires: %s\n", http_date(item->st.st_mtime + 67 htmlf("Expires: %s\n", http_date(item->st.st_mtime +
47 ttl_seconds(item->ttl))); 68 ttl_seconds(item->ttl)));
48 html("\n"); 69 html("\n");
49 html(cgit_doctype); 70 html(cgit_doctype);
50 html("<html>\n"); 71 html("<html>\n");
51 html("<head>\n"); 72 html("<head>\n");
52 html("<title>"); 73 html("<title>");
53 html_txt(title); 74 html_txt(title);
54 html("</title>\n"); 75 html("</title>\n");
55 htmlf("<meta name='generator' content='cgit v%s'/>\n", cgit_version); 76 htmlf("<meta name='generator' content='cgit v%s'/>\n", cgit_version);
56 html("<link rel='stylesheet' type='text/css' href='"); 77 html("<link rel='stylesheet' type='text/css' href='");
57 html_attr(cgit_css); 78 html_attr(cgit_css);
58 html("'/>\n"); 79 html("'/>\n");
59 html("</head>\n"); 80 html("</head>\n");
60 html("<body>\n"); 81 html("<body>\n");
61} 82}
62 83
63void cgit_print_docend() 84void cgit_print_docend()
64{ 85{
65 html("</body>\n</html>\n"); 86 html("</body>\n</html>\n");
66} 87}
67 88
68void cgit_print_pageheader(char *title) 89void cgit_print_pageheader(char *title)
69{ 90{
70 html("<div id='header'>"); 91 html("<div id='header'>");
71 htmlf("<a href='%s'>", cgit_logo_link); 92 htmlf("<a href='%s'>", cgit_logo_link);
72 htmlf("<img id='logo' src='%s'/>\n", cgit_logo); 93 htmlf("<img id='logo' src='%s'/>\n", cgit_logo);
73 htmlf("</a>"); 94 htmlf("</a>");
74 html_txt(title); 95 html_txt(title);
75 html("</div>"); 96 html("</div>");
76} 97}