summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2007-05-20 12:33:59 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-05-20 12:33:59 (UTC)
commit977a0b173df6fe1a4d362fe4c70f9badff1fd46c (patch) (unidiff)
tree8bd383fff396bb1790c03ab5b461d899af997568
parentd4dbfdfbaea3aa93e824ea484787de10e73eae65 (diff)
parentde69ce020c4ccd7146d6ac72bbd8f417088e8c03 (diff)
downloadcgit-977a0b173df6fe1a4d362fe4c70f9badff1fd46c.zip
cgit-977a0b173df6fe1a4d362fe4c70f9badff1fd46c.tar.gz
cgit-977a0b173df6fe1a4d362fe4c70f9badff1fd46c.tar.bz2
Merge branch 'index-header'
* index-header: Teach cgit howto include an external file on index page. Add html_include()
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.h2
-rw-r--r--html.c14
-rw-r--r--shared.c3
-rw-r--r--ui-repolist.c5
4 files changed, 24 insertions, 0 deletions
diff --git a/cgit.h b/cgit.h
index f3d783e..3ee11bb 100644
--- a/cgit.h
+++ b/cgit.h
@@ -1,186 +1,188 @@
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
21typedef void (*configfn)(const char *name, const char *value); 21typedef void (*configfn)(const char *name, const char *value);
22typedef void (*filepair_fn)(struct diff_filepair *pair); 22typedef void (*filepair_fn)(struct diff_filepair *pair);
23typedef void (*linediff_fn)(char *line, int len); 23typedef void (*linediff_fn)(char *line, int len);
24 24
25struct cacheitem { 25struct 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
32struct repoinfo { 32struct 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 *defbranch; 38 char *defbranch;
39 char *module_link; 39 char *module_link;
40 int snapshots; 40 int snapshots;
41 int enable_log_filecount; 41 int enable_log_filecount;
42 int enable_log_linecount; 42 int enable_log_linecount;
43}; 43};
44 44
45struct repolist { 45struct repolist {
46 int length; 46 int length;
47 int count; 47 int count;
48 struct repoinfo *repos; 48 struct repoinfo *repos;
49}; 49};
50 50
51struct commitinfo { 51struct commitinfo {
52 struct commit *commit; 52 struct commit *commit;
53 char *author; 53 char *author;
54 char *author_email; 54 char *author_email;
55 unsigned long author_date; 55 unsigned long author_date;
56 char *committer; 56 char *committer;
57 char *committer_email; 57 char *committer_email;
58 unsigned long committer_date; 58 unsigned long committer_date;
59 char *subject; 59 char *subject;
60 char *msg; 60 char *msg;
61}; 61};
62 62
63struct taginfo { 63struct taginfo {
64 char *tagger; 64 char *tagger;
65 char *tagger_email; 65 char *tagger_email;
66 int tagger_date; 66 int tagger_date;
67 char *msg; 67 char *msg;
68}; 68};
69 69
70extern const char cgit_version[]; 70extern const char cgit_version[];
71 71
72extern struct repolist cgit_repolist; 72extern struct repolist cgit_repolist;
73extern struct repoinfo *cgit_repo; 73extern struct repoinfo *cgit_repo;
74 74
75extern char *cgit_root_title; 75extern char *cgit_root_title;
76extern char *cgit_css; 76extern char *cgit_css;
77extern char *cgit_logo; 77extern char *cgit_logo;
78extern char *cgit_index_header;
78extern char *cgit_logo_link; 79extern char *cgit_logo_link;
79extern char *cgit_module_link; 80extern char *cgit_module_link;
80extern char *cgit_virtual_root; 81extern char *cgit_virtual_root;
81extern char *cgit_script_name; 82extern char *cgit_script_name;
82extern char *cgit_cache_root; 83extern char *cgit_cache_root;
83 84
84extern int cgit_nocache; 85extern int cgit_nocache;
85extern int cgit_snapshots; 86extern int cgit_snapshots;
86extern int cgit_enable_log_filecount; 87extern int cgit_enable_log_filecount;
87extern int cgit_enable_log_linecount; 88extern int cgit_enable_log_linecount;
88extern int cgit_max_lock_attempts; 89extern int cgit_max_lock_attempts;
89extern int cgit_cache_root_ttl; 90extern int cgit_cache_root_ttl;
90extern int cgit_cache_repo_ttl; 91extern int cgit_cache_repo_ttl;
91extern int cgit_cache_dynamic_ttl; 92extern int cgit_cache_dynamic_ttl;
92extern int cgit_cache_static_ttl; 93extern int cgit_cache_static_ttl;
93extern int cgit_cache_max_create_time; 94extern int cgit_cache_max_create_time;
94 95
95extern int cgit_max_msg_len; 96extern int cgit_max_msg_len;
96extern int cgit_max_repodesc_len; 97extern int cgit_max_repodesc_len;
97extern int cgit_max_commit_count; 98extern int cgit_max_commit_count;
98 99
99extern int cgit_query_has_symref; 100extern int cgit_query_has_symref;
100extern int cgit_query_has_sha1; 101extern int cgit_query_has_sha1;
101 102
102extern char *cgit_querystring; 103extern char *cgit_querystring;
103extern char *cgit_query_repo; 104extern char *cgit_query_repo;
104extern char *cgit_query_page; 105extern char *cgit_query_page;
105extern char *cgit_query_search; 106extern char *cgit_query_search;
106extern char *cgit_query_head; 107extern char *cgit_query_head;
107extern char *cgit_query_sha1; 108extern char *cgit_query_sha1;
108extern char *cgit_query_sha2; 109extern char *cgit_query_sha2;
109extern char *cgit_query_path; 110extern char *cgit_query_path;
110extern char *cgit_query_name; 111extern char *cgit_query_name;
111extern int cgit_query_ofs; 112extern int cgit_query_ofs;
112 113
113extern int htmlfd; 114extern int htmlfd;
114 115
115extern void cgit_global_config_cb(const char *name, const char *value); 116extern void cgit_global_config_cb(const char *name, const char *value);
116extern void cgit_repo_config_cb(const char *name, const char *value); 117extern void cgit_repo_config_cb(const char *name, const char *value);
117extern void cgit_querystring_cb(const char *name, const char *value); 118extern void cgit_querystring_cb(const char *name, const char *value);
118 119
119extern int chk_zero(int result, char *msg); 120extern int chk_zero(int result, char *msg);
120extern int chk_positive(int result, char *msg); 121extern int chk_positive(int result, char *msg);
121 122
122extern int hextoint(char c); 123extern int hextoint(char c);
123 124
124extern void *cgit_free_commitinfo(struct commitinfo *info); 125extern void *cgit_free_commitinfo(struct commitinfo *info);
125 126
126extern int cgit_diff_files(const unsigned char *old_sha1, 127extern int cgit_diff_files(const unsigned char *old_sha1,
127 const unsigned char *new_sha1, 128 const unsigned char *new_sha1,
128 linediff_fn fn); 129 linediff_fn fn);
129 130
130extern void cgit_diff_tree(const unsigned char *old_sha1, 131extern void cgit_diff_tree(const unsigned char *old_sha1,
131 const unsigned char *new_sha1, 132 const unsigned char *new_sha1,
132 filepair_fn fn); 133 filepair_fn fn);
133 134
134extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 135extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
135 136
136extern char *fmt(const char *format,...); 137extern char *fmt(const char *format,...);
137 138
138extern void html(const char *txt); 139extern void html(const char *txt);
139extern void htmlf(const char *format,...); 140extern void htmlf(const char *format,...);
140extern void html_txt(char *txt); 141extern void html_txt(char *txt);
141extern void html_ntxt(int len, char *txt); 142extern void html_ntxt(int len, char *txt);
142extern void html_attr(char *txt); 143extern void html_attr(char *txt);
143extern void html_hidden(char *name, char *value); 144extern void html_hidden(char *name, char *value);
144extern void html_link_open(char *url, char *title, char *class); 145extern void html_link_open(char *url, char *title, char *class);
145extern void html_link_close(void); 146extern void html_link_close(void);
146extern void html_filemode(unsigned short mode); 147extern void html_filemode(unsigned short mode);
148extern int html_include(const char *filename);
147 149
148extern int cgit_read_config(const char *filename, configfn fn); 150extern int cgit_read_config(const char *filename, configfn fn);
149extern int cgit_parse_query(char *txt, configfn fn); 151extern int cgit_parse_query(char *txt, configfn fn);
150extern struct commitinfo *cgit_parse_commit(struct commit *commit); 152extern struct commitinfo *cgit_parse_commit(struct commit *commit);
151extern struct taginfo *cgit_parse_tag(struct tag *tag); 153extern struct taginfo *cgit_parse_tag(struct tag *tag);
152 154
153extern char *cache_safe_filename(const char *unsafe); 155extern char *cache_safe_filename(const char *unsafe);
154extern int cache_lock(struct cacheitem *item); 156extern int cache_lock(struct cacheitem *item);
155extern int cache_unlock(struct cacheitem *item); 157extern int cache_unlock(struct cacheitem *item);
156extern int cache_cancel_lock(struct cacheitem *item); 158extern int cache_cancel_lock(struct cacheitem *item);
157extern int cache_exist(struct cacheitem *item); 159extern int cache_exist(struct cacheitem *item);
158extern int cache_expired(struct cacheitem *item); 160extern int cache_expired(struct cacheitem *item);
159 161
160extern char *cgit_repourl(const char *reponame); 162extern char *cgit_repourl(const char *reponame);
161extern char *cgit_pageurl(const char *reponame, const char *pagename, 163extern char *cgit_pageurl(const char *reponame, const char *pagename,
162 const char *query); 164 const char *query);
163 165
164extern void cgit_print_error(char *msg); 166extern void cgit_print_error(char *msg);
165extern void cgit_print_date(unsigned long secs); 167extern void cgit_print_date(unsigned long secs);
166extern void cgit_print_docstart(char *title, struct cacheitem *item); 168extern void cgit_print_docstart(char *title, struct cacheitem *item);
167extern void cgit_print_docend(); 169extern void cgit_print_docend();
168extern void cgit_print_pageheader(char *title, int show_search); 170extern void cgit_print_pageheader(char *title, int show_search);
169extern void cgit_print_snapshot_start(const char *mimetype, 171extern void cgit_print_snapshot_start(const char *mimetype,
170 const char *filename, 172 const char *filename,
171 struct cacheitem *item); 173 struct cacheitem *item);
172 174
173extern void cgit_print_repolist(struct cacheitem *item); 175extern void cgit_print_repolist(struct cacheitem *item);
174extern void cgit_print_summary(); 176extern void cgit_print_summary();
175extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path); 177extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path);
176extern void cgit_print_view(const char *hex, char *path); 178extern void cgit_print_view(const char *hex, char *path);
177extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); 179extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path);
178extern void cgit_print_tree(const char *rev, const char *hex, char *path); 180extern void cgit_print_tree(const char *rev, const char *hex, char *path);
179extern void cgit_print_commit(const char *hex); 181extern void cgit_print_commit(const char *hex);
180extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, 182extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex,
181 char *path); 183 char *path);
182extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, 184extern void cgit_print_snapshot(struct cacheitem *item, const char *hex,
183 const char *format, const char *prefix, 185 const char *format, const char *prefix,
184 const char *filename); 186 const char *filename);
185 187
186#endif /* CGIT_H */ 188#endif /* CGIT_H */
diff --git a/html.c b/html.c
index 175b4b6..33a956f 100644
--- a/html.c
+++ b/html.c
@@ -1,168 +1,182 @@
1/* html.c: helper functions for html output 1/* html.c: helper functions for html output
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 *fmt(const char *format, ...) 11char *fmt(const char *format, ...)
12{ 12{
13 static char buf[8][1024]; 13 static char buf[8][1024];
14 static int bufidx; 14 static int bufidx;
15 int len; 15 int len;
16 va_list args; 16 va_list args;
17 17
18 bufidx++; 18 bufidx++;
19 bufidx &= 7; 19 bufidx &= 7;
20 20
21 va_start(args, format); 21 va_start(args, format);
22 len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args); 22 len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args);
23 va_end(args); 23 va_end(args);
24 if (len>sizeof(buf[bufidx])) 24 if (len>sizeof(buf[bufidx]))
25 die("[html.c] string truncated: %s", format); 25 die("[html.c] string truncated: %s", format);
26 return buf[bufidx]; 26 return buf[bufidx];
27} 27}
28 28
29void html(const char *txt) 29void html(const char *txt)
30{ 30{
31 write(htmlfd, txt, strlen(txt)); 31 write(htmlfd, txt, strlen(txt));
32} 32}
33 33
34void htmlf(const char *format, ...) 34void htmlf(const char *format, ...)
35{ 35{
36 static char buf[65536]; 36 static char buf[65536];
37 va_list args; 37 va_list args;
38 38
39 va_start(args, format); 39 va_start(args, format);
40 vsnprintf(buf, sizeof(buf), format, args); 40 vsnprintf(buf, sizeof(buf), format, args);
41 va_end(args); 41 va_end(args);
42 html(buf); 42 html(buf);
43} 43}
44 44
45void html_txt(char *txt) 45void html_txt(char *txt)
46{ 46{
47 char *t = txt; 47 char *t = txt;
48 while(t && *t){ 48 while(t && *t){
49 int c = *t; 49 int c = *t;
50 if (c=='<' || c=='>' || c=='&') { 50 if (c=='<' || c=='>' || c=='&') {
51 *t = '\0'; 51 *t = '\0';
52 html(txt); 52 html(txt);
53 *t = c; 53 *t = c;
54 if (c=='>') 54 if (c=='>')
55 html("&gt;"); 55 html("&gt;");
56 else if (c=='<') 56 else if (c=='<')
57 html("&lt;"); 57 html("&lt;");
58 else if (c=='&') 58 else if (c=='&')
59 html("&amp;"); 59 html("&amp;");
60 txt = t+1; 60 txt = t+1;
61 } 61 }
62 t++; 62 t++;
63 } 63 }
64 if (t!=txt) 64 if (t!=txt)
65 html(txt); 65 html(txt);
66} 66}
67 67
68void html_ntxt(int len, char *txt) 68void html_ntxt(int len, char *txt)
69{ 69{
70 char *t = txt; 70 char *t = txt;
71 while(t && *t && len--){ 71 while(t && *t && len--){
72 int c = *t; 72 int c = *t;
73 if (c=='<' || c=='>' || c=='&') { 73 if (c=='<' || c=='>' || c=='&') {
74 *t = '\0'; 74 *t = '\0';
75 html(txt); 75 html(txt);
76 *t = c; 76 *t = c;
77 if (c=='>') 77 if (c=='>')
78 html("&gt;"); 78 html("&gt;");
79 else if (c=='<') 79 else if (c=='<')
80 html("&lt;"); 80 html("&lt;");
81 else if (c=='&') 81 else if (c=='&')
82 html("&amp;"); 82 html("&amp;");
83 txt = t+1; 83 txt = t+1;
84 } 84 }
85 t++; 85 t++;
86 } 86 }
87 if (t!=txt) { 87 if (t!=txt) {
88 char c = *t; 88 char c = *t;
89 *t = '\0'; 89 *t = '\0';
90 html(txt); 90 html(txt);
91 *t = c; 91 *t = c;
92 } 92 }
93 if (len<0) 93 if (len<0)
94 html("..."); 94 html("...");
95} 95}
96 96
97void html_attr(char *txt) 97void html_attr(char *txt)
98{ 98{
99 char *t = txt; 99 char *t = txt;
100 while(t && *t){ 100 while(t && *t){
101 int c = *t; 101 int c = *t;
102 if (c=='<' || c=='>' || c=='\'') { 102 if (c=='<' || c=='>' || c=='\'') {
103 *t = '\0'; 103 *t = '\0';
104 html(txt); 104 html(txt);
105 *t = c; 105 *t = c;
106 if (c=='>') 106 if (c=='>')
107 html("&gt;"); 107 html("&gt;");
108 else if (c=='<') 108 else if (c=='<')
109 html("&lt;"); 109 html("&lt;");
110 else if (c=='\'') 110 else if (c=='\'')
111 html("&quote;"); 111 html("&quote;");
112 txt = t+1; 112 txt = t+1;
113 } 113 }
114 t++; 114 t++;
115 } 115 }
116 if (t!=txt) 116 if (t!=txt)
117 html(txt); 117 html(txt);
118} 118}
119 119
120void html_hidden(char *name, char *value) 120void html_hidden(char *name, char *value)
121{ 121{
122 html("<input type='hidden' name='"); 122 html("<input type='hidden' name='");
123 html_attr(name); 123 html_attr(name);
124 html("' value='"); 124 html("' value='");
125 html_attr(value); 125 html_attr(value);
126 html("'/>"); 126 html("'/>");
127} 127}
128 128
129void html_link_open(char *url, char *title, char *class) 129void html_link_open(char *url, char *title, char *class)
130{ 130{
131 html("<a href='"); 131 html("<a href='");
132 html_attr(url); 132 html_attr(url);
133 if (title) { 133 if (title) {
134 html("' title='"); 134 html("' title='");
135 html_attr(title); 135 html_attr(title);
136 } 136 }
137 if (class) { 137 if (class) {
138 html("' class='"); 138 html("' class='");
139 html_attr(class); 139 html_attr(class);
140 } 140 }
141 html("'>"); 141 html("'>");
142} 142}
143 143
144void html_link_close(void) 144void html_link_close(void)
145{ 145{
146 html("</a>"); 146 html("</a>");
147} 147}
148 148
149void html_fileperm(unsigned short mode) 149void html_fileperm(unsigned short mode)
150{ 150{
151 htmlf("%c%c%c", (mode & 4 ? 'r' : '-'), 151 htmlf("%c%c%c", (mode & 4 ? 'r' : '-'),
152 (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-')); 152 (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-'));
153} 153}
154 154
155void html_filemode(unsigned short mode) 155void html_filemode(unsigned short mode)
156{ 156{
157 if (S_ISDIR(mode)) 157 if (S_ISDIR(mode))
158 html("d"); 158 html("d");
159 else if (S_ISLNK(mode)) 159 else if (S_ISLNK(mode))
160 html("l"); 160 html("l");
161 else if (S_ISDIRLNK(mode)) 161 else if (S_ISDIRLNK(mode))
162 html("m"); 162 html("m");
163 else 163 else
164 html("-"); 164 html("-");
165 html_fileperm(mode >> 6); 165 html_fileperm(mode >> 6);
166 html_fileperm(mode >> 3); 166 html_fileperm(mode >> 3);
167 html_fileperm(mode); 167 html_fileperm(mode);
168} 168}
169
170int html_include(const char *filename)
171{
172 FILE *f;
173 char buf[4096];
174 size_t len;
175
176 if (!(f = fopen(filename, "r")))
177 return -1;
178 while((len = fread(buf, 1, 4096, f)) > 0)
179 write(htmlfd, buf, len);
180 fclose(f);
181 return 0;
182}
diff --git a/shared.c b/shared.c
index 53cd9b0..54b1813 100644
--- a/shared.c
+++ b/shared.c
@@ -1,295 +1,298 @@
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
11struct repolist cgit_repolist; 11struct repolist cgit_repolist;
12struct repoinfo *cgit_repo; 12struct repoinfo *cgit_repo;
13 13
14char *cgit_root_title = "Git repository browser"; 14char *cgit_root_title = "Git repository browser";
15char *cgit_css = "/cgit.css"; 15char *cgit_css = "/cgit.css";
16char *cgit_logo = "/git-logo.png"; 16char *cgit_logo = "/git-logo.png";
17char *cgit_index_header = NULL;
17char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; 18char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/";
18char *cgit_module_link = "./?repo=%s&page=commit&id=%s"; 19char *cgit_module_link = "./?repo=%s&page=commit&id=%s";
19char *cgit_virtual_root = NULL; 20char *cgit_virtual_root = NULL;
20char *cgit_script_name = CGIT_SCRIPT_NAME; 21char *cgit_script_name = CGIT_SCRIPT_NAME;
21char *cgit_cache_root = "/var/cache/cgit"; 22char *cgit_cache_root = "/var/cache/cgit";
22 23
23int cgit_nocache = 0; 24int cgit_nocache = 0;
24int cgit_snapshots = 0; 25int cgit_snapshots = 0;
25int cgit_enable_log_filecount = 0; 26int cgit_enable_log_filecount = 0;
26int cgit_enable_log_linecount = 0; 27int cgit_enable_log_linecount = 0;
27int cgit_max_lock_attempts = 5; 28int cgit_max_lock_attempts = 5;
28int cgit_cache_root_ttl = 5; 29int cgit_cache_root_ttl = 5;
29int cgit_cache_repo_ttl = 5; 30int cgit_cache_repo_ttl = 5;
30int cgit_cache_dynamic_ttl = 5; 31int cgit_cache_dynamic_ttl = 5;
31int cgit_cache_static_ttl = -1; 32int cgit_cache_static_ttl = -1;
32int cgit_cache_max_create_time = 5; 33int cgit_cache_max_create_time = 5;
33 34
34int cgit_max_msg_len = 60; 35int cgit_max_msg_len = 60;
35int cgit_max_repodesc_len = 60; 36int cgit_max_repodesc_len = 60;
36int cgit_max_commit_count = 50; 37int cgit_max_commit_count = 50;
37 38
38int cgit_query_has_symref = 0; 39int cgit_query_has_symref = 0;
39int cgit_query_has_sha1 = 0; 40int cgit_query_has_sha1 = 0;
40 41
41char *cgit_querystring = NULL; 42char *cgit_querystring = NULL;
42char *cgit_query_repo = NULL; 43char *cgit_query_repo = NULL;
43char *cgit_query_page = NULL; 44char *cgit_query_page = NULL;
44char *cgit_query_head = NULL; 45char *cgit_query_head = NULL;
45char *cgit_query_search = NULL; 46char *cgit_query_search = NULL;
46char *cgit_query_sha1 = NULL; 47char *cgit_query_sha1 = NULL;
47char *cgit_query_sha2 = NULL; 48char *cgit_query_sha2 = NULL;
48char *cgit_query_path = NULL; 49char *cgit_query_path = NULL;
49char *cgit_query_name = NULL; 50char *cgit_query_name = NULL;
50int cgit_query_ofs = 0; 51int cgit_query_ofs = 0;
51 52
52int htmlfd = 0; 53int htmlfd = 0;
53 54
54int chk_zero(int result, char *msg) 55int 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
61int chk_positive(int result, char *msg) 62int 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
68struct repoinfo *add_repo(const char *url) 69struct 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->defbranch = "master"; 89 ret->defbranch = "master";
89 ret->snapshots = cgit_snapshots; 90 ret->snapshots = cgit_snapshots;
90 ret->enable_log_filecount = cgit_enable_log_filecount; 91 ret->enable_log_filecount = cgit_enable_log_filecount;
91 ret->enable_log_linecount = cgit_enable_log_linecount; 92 ret->enable_log_linecount = cgit_enable_log_linecount;
92 ret->module_link = cgit_module_link; 93 ret->module_link = cgit_module_link;
93 return ret; 94 return ret;
94} 95}
95 96
96void cgit_global_config_cb(const char *name, const char *value) 97void cgit_global_config_cb(const char *name, const char *value)
97{ 98{
98 if (!strcmp(name, "root-title")) 99 if (!strcmp(name, "root-title"))
99 cgit_root_title = xstrdup(value); 100 cgit_root_title = xstrdup(value);
100 else if (!strcmp(name, "css")) 101 else if (!strcmp(name, "css"))
101 cgit_css = xstrdup(value); 102 cgit_css = xstrdup(value);
102 else if (!strcmp(name, "logo")) 103 else if (!strcmp(name, "logo"))
103 cgit_logo = xstrdup(value); 104 cgit_logo = xstrdup(value);
105 else if (!strcmp(name, "index-header"))
106 cgit_index_header = xstrdup(value);
104 else if (!strcmp(name, "logo-link")) 107 else if (!strcmp(name, "logo-link"))
105 cgit_logo_link = xstrdup(value); 108 cgit_logo_link = xstrdup(value);
106 else if (!strcmp(name, "module-link")) 109 else if (!strcmp(name, "module-link"))
107 cgit_module_link = xstrdup(value); 110 cgit_module_link = xstrdup(value);
108 else if (!strcmp(name, "virtual-root")) 111 else if (!strcmp(name, "virtual-root"))
109 cgit_virtual_root = xstrdup(value); 112 cgit_virtual_root = xstrdup(value);
110 else if (!strcmp(name, "nocache")) 113 else if (!strcmp(name, "nocache"))
111 cgit_nocache = atoi(value); 114 cgit_nocache = atoi(value);
112 else if (!strcmp(name, "snapshots")) 115 else if (!strcmp(name, "snapshots"))
113 cgit_snapshots = atoi(value); 116 cgit_snapshots = atoi(value);
114 else if (!strcmp(name, "enable-log-filecount")) 117 else if (!strcmp(name, "enable-log-filecount"))
115 cgit_enable_log_filecount = atoi(value); 118 cgit_enable_log_filecount = atoi(value);
116 else if (!strcmp(name, "enable-log-linecount")) 119 else if (!strcmp(name, "enable-log-linecount"))
117 cgit_enable_log_linecount = atoi(value); 120 cgit_enable_log_linecount = atoi(value);
118 else if (!strcmp(name, "cache-root")) 121 else if (!strcmp(name, "cache-root"))
119 cgit_cache_root = xstrdup(value); 122 cgit_cache_root = xstrdup(value);
120 else if (!strcmp(name, "cache-root-ttl")) 123 else if (!strcmp(name, "cache-root-ttl"))
121 cgit_cache_root_ttl = atoi(value); 124 cgit_cache_root_ttl = atoi(value);
122 else if (!strcmp(name, "cache-repo-ttl")) 125 else if (!strcmp(name, "cache-repo-ttl"))
123 cgit_cache_repo_ttl = atoi(value); 126 cgit_cache_repo_ttl = atoi(value);
124 else if (!strcmp(name, "cache-static-ttl")) 127 else if (!strcmp(name, "cache-static-ttl"))
125 cgit_cache_static_ttl = atoi(value); 128 cgit_cache_static_ttl = atoi(value);
126 else if (!strcmp(name, "cache-dynamic-ttl")) 129 else if (!strcmp(name, "cache-dynamic-ttl"))
127 cgit_cache_dynamic_ttl = atoi(value); 130 cgit_cache_dynamic_ttl = atoi(value);
128 else if (!strcmp(name, "max-message-length")) 131 else if (!strcmp(name, "max-message-length"))
129 cgit_max_msg_len = atoi(value); 132 cgit_max_msg_len = atoi(value);
130 else if (!strcmp(name, "max-repodesc-length")) 133 else if (!strcmp(name, "max-repodesc-length"))
131 cgit_max_repodesc_len = atoi(value); 134 cgit_max_repodesc_len = atoi(value);
132 else if (!strcmp(name, "max-commit-count")) 135 else if (!strcmp(name, "max-commit-count"))
133 cgit_max_commit_count = atoi(value); 136 cgit_max_commit_count = atoi(value);
134 else if (!strcmp(name, "repo.url")) 137 else if (!strcmp(name, "repo.url"))
135 cgit_repo = add_repo(value); 138 cgit_repo = add_repo(value);
136 else if (!strcmp(name, "repo.name")) 139 else if (!strcmp(name, "repo.name"))
137 cgit_repo->name = xstrdup(value); 140 cgit_repo->name = xstrdup(value);
138 else if (cgit_repo && !strcmp(name, "repo.path")) 141 else if (cgit_repo && !strcmp(name, "repo.path"))
139 cgit_repo->path = xstrdup(value); 142 cgit_repo->path = xstrdup(value);
140 else if (cgit_repo && !strcmp(name, "repo.desc")) 143 else if (cgit_repo && !strcmp(name, "repo.desc"))
141 cgit_repo->desc = xstrdup(value); 144 cgit_repo->desc = xstrdup(value);
142 else if (cgit_repo && !strcmp(name, "repo.owner")) 145 else if (cgit_repo && !strcmp(name, "repo.owner"))
143 cgit_repo->owner = xstrdup(value); 146 cgit_repo->owner = xstrdup(value);
144 else if (cgit_repo && !strcmp(name, "repo.defbranch")) 147 else if (cgit_repo && !strcmp(name, "repo.defbranch"))
145 cgit_repo->defbranch = xstrdup(value); 148 cgit_repo->defbranch = xstrdup(value);
146 else if (cgit_repo && !strcmp(name, "repo.snapshots")) 149 else if (cgit_repo && !strcmp(name, "repo.snapshots"))
147 cgit_repo->snapshots = cgit_snapshots * atoi(value); 150 cgit_repo->snapshots = cgit_snapshots * atoi(value);
148 else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount")) 151 else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount"))
149 cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value); 152 cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value);
150 else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount")) 153 else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount"))
151 cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value); 154 cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value);
152 else if (cgit_repo && !strcmp(name, "repo.module-link")) 155 else if (cgit_repo && !strcmp(name, "repo.module-link"))
153 cgit_repo->module_link= xstrdup(value); 156 cgit_repo->module_link= xstrdup(value);
154 else if (!strcmp(name, "include")) 157 else if (!strcmp(name, "include"))
155 cgit_read_config(value, cgit_global_config_cb); 158 cgit_read_config(value, cgit_global_config_cb);
156} 159}
157 160
158void cgit_querystring_cb(const char *name, const char *value) 161void cgit_querystring_cb(const char *name, const char *value)
159{ 162{
160 if (!strcmp(name,"r")) { 163 if (!strcmp(name,"r")) {
161 cgit_query_repo = xstrdup(value); 164 cgit_query_repo = xstrdup(value);
162 } else if (!strcmp(name, "p")) { 165 } else if (!strcmp(name, "p")) {
163 cgit_query_page = xstrdup(value); 166 cgit_query_page = xstrdup(value);
164 } else if (!strcmp(name, "q")) { 167 } else if (!strcmp(name, "q")) {
165 cgit_query_search = xstrdup(value); 168 cgit_query_search = xstrdup(value);
166 } else if (!strcmp(name, "h")) { 169 } else if (!strcmp(name, "h")) {
167 cgit_query_head = xstrdup(value); 170 cgit_query_head = xstrdup(value);
168 cgit_query_has_symref = 1; 171 cgit_query_has_symref = 1;
169 } else if (!strcmp(name, "id")) { 172 } else if (!strcmp(name, "id")) {
170 cgit_query_sha1 = xstrdup(value); 173 cgit_query_sha1 = xstrdup(value);
171 cgit_query_has_sha1 = 1; 174 cgit_query_has_sha1 = 1;
172 } else if (!strcmp(name, "id2")) { 175 } else if (!strcmp(name, "id2")) {
173 cgit_query_sha2 = xstrdup(value); 176 cgit_query_sha2 = xstrdup(value);
174 cgit_query_has_sha1 = 1; 177 cgit_query_has_sha1 = 1;
175 } else if (!strcmp(name, "ofs")) { 178 } else if (!strcmp(name, "ofs")) {
176 cgit_query_ofs = atoi(value); 179 cgit_query_ofs = atoi(value);
177 } else if (!strcmp(name, "path")) { 180 } else if (!strcmp(name, "path")) {
178 cgit_query_path = xstrdup(value); 181 cgit_query_path = xstrdup(value);
179 } else if (!strcmp(name, "name")) { 182 } else if (!strcmp(name, "name")) {
180 cgit_query_name = xstrdup(value); 183 cgit_query_name = xstrdup(value);
181 } 184 }
182} 185}
183 186
184void *cgit_free_commitinfo(struct commitinfo *info) 187void *cgit_free_commitinfo(struct commitinfo *info)
185{ 188{
186 free(info->author); 189 free(info->author);
187 free(info->author_email); 190 free(info->author_email);
188 free(info->committer); 191 free(info->committer);
189 free(info->committer_email); 192 free(info->committer_email);
190 free(info->subject); 193 free(info->subject);
191 free(info); 194 free(info);
192 return NULL; 195 return NULL;
193} 196}
194 197
195int hextoint(char c) 198int hextoint(char c)
196{ 199{
197 if (c >= 'a' && c <= 'f') 200 if (c >= 'a' && c <= 'f')
198 return 10 + c - 'a'; 201 return 10 + c - 'a';
199 else if (c >= 'A' && c <= 'F') 202 else if (c >= 'A' && c <= 'F')
200 return 10 + c - 'A'; 203 return 10 + c - 'A';
201 else if (c >= '0' && c <= '9') 204 else if (c >= '0' && c <= '9')
202 return c - '0'; 205 return c - '0';
203 else 206 else
204 return -1; 207 return -1;
205} 208}
206 209
207void cgit_diff_tree_cb(struct diff_queue_struct *q, 210void cgit_diff_tree_cb(struct diff_queue_struct *q,
208 struct diff_options *options, void *data) 211 struct diff_options *options, void *data)
209{ 212{
210 int i; 213 int i;
211 214
212 for (i = 0; i < q->nr; i++) { 215 for (i = 0; i < q->nr; i++) {
213 if (q->queue[i]->status == 'U') 216 if (q->queue[i]->status == 'U')
214 continue; 217 continue;
215 ((filepair_fn)data)(q->queue[i]); 218 ((filepair_fn)data)(q->queue[i]);
216 } 219 }
217} 220}
218 221
219static int load_mmfile(mmfile_t *file, const unsigned char *sha1) 222static int load_mmfile(mmfile_t *file, const unsigned char *sha1)
220{ 223{
221 enum object_type type; 224 enum object_type type;
222 225
223 if (is_null_sha1(sha1)) { 226 if (is_null_sha1(sha1)) {
224 file->ptr = (char *)""; 227 file->ptr = (char *)"";
225 file->size = 0; 228 file->size = 0;
226 } else { 229 } else {
227 file->ptr = read_sha1_file(sha1, &type, &file->size); 230 file->ptr = read_sha1_file(sha1, &type, &file->size);
228 } 231 }
229 return 1; 232 return 1;
230} 233}
231 234
232/* 235/*
233 * Receive diff-buffers from xdiff and concatenate them as 236 * Receive diff-buffers from xdiff and concatenate them as
234 * needed across multiple callbacks. 237 * needed across multiple callbacks.
235 * 238 *
236 * This is basically a copy of xdiff-interface.c/xdiff_outf(), 239 * This is basically a copy of xdiff-interface.c/xdiff_outf(),
237 * ripped from git and modified to use globals instead of 240 * ripped from git and modified to use globals instead of
238 * a special callback-struct. 241 * a special callback-struct.
239 */ 242 */
240char *diffbuf = NULL; 243char *diffbuf = NULL;
241int buflen = 0; 244int buflen = 0;
242 245
243int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) 246int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf)
244{ 247{
245 int i; 248 int i;
246 249
247 for (i = 0; i < nbuf; i++) { 250 for (i = 0; i < nbuf; i++) {
248 if (mb[i].ptr[mb[i].size-1] != '\n') { 251 if (mb[i].ptr[mb[i].size-1] != '\n') {
249 /* Incomplete line */ 252 /* Incomplete line */
250 diffbuf = xrealloc(diffbuf, buflen + mb[i].size); 253 diffbuf = xrealloc(diffbuf, buflen + mb[i].size);
251 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); 254 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size);
252 buflen += mb[i].size; 255 buflen += mb[i].size;
253 continue; 256 continue;
254 } 257 }
255 258
256 /* we have a complete line */ 259 /* we have a complete line */
257 if (!diffbuf) { 260 if (!diffbuf) {
258 ((linediff_fn)priv)(mb[i].ptr, mb[i].size); 261 ((linediff_fn)priv)(mb[i].ptr, mb[i].size);
259 continue; 262 continue;
260 } 263 }
261 diffbuf = xrealloc(diffbuf, buflen + mb[i].size); 264 diffbuf = xrealloc(diffbuf, buflen + mb[i].size);
262 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); 265 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size);
263 ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); 266 ((linediff_fn)priv)(diffbuf, buflen + mb[i].size);
264 free(diffbuf); 267 free(diffbuf);
265 diffbuf = NULL; 268 diffbuf = NULL;
266 buflen = 0; 269 buflen = 0;
267 } 270 }
268 if (diffbuf) { 271 if (diffbuf) {
269 ((linediff_fn)priv)(diffbuf, buflen); 272 ((linediff_fn)priv)(diffbuf, buflen);
270 free(diffbuf); 273 free(diffbuf);
271 diffbuf = NULL; 274 diffbuf = NULL;
272 buflen = 0; 275 buflen = 0;
273 } 276 }
274 return 0; 277 return 0;
275} 278}
276 279
277int cgit_diff_files(const unsigned char *old_sha1, 280int cgit_diff_files(const unsigned char *old_sha1,
278 const unsigned char *new_sha1, 281 const unsigned char *new_sha1,
279 linediff_fn fn) 282 linediff_fn fn)
280{ 283{
281 mmfile_t file1, file2; 284 mmfile_t file1, file2;
282 xpparam_t diff_params; 285 xpparam_t diff_params;
283 xdemitconf_t emit_params; 286 xdemitconf_t emit_params;
284 xdemitcb_t emit_cb; 287 xdemitcb_t emit_cb;
285 288
286 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) 289 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1))
287 return 1; 290 return 1;
288 291
289 diff_params.flags = XDF_NEED_MINIMAL; 292 diff_params.flags = XDF_NEED_MINIMAL;
290 emit_params.ctxlen = 3; 293 emit_params.ctxlen = 3;
291 emit_params.flags = XDL_EMIT_FUNCNAMES; 294 emit_params.flags = XDL_EMIT_FUNCNAMES;
292 emit_cb.outf = filediff_cb; 295 emit_cb.outf = filediff_cb;
293 emit_cb.priv = fn; 296 emit_cb.priv = fn;
294 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); 297 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);
295 return 0; 298 return 0;
diff --git a/ui-repolist.c b/ui-repolist.c
index d7311e4..8e367a2 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -1,53 +1,58 @@
1/* ui-repolist.c: functions for generating the repolist page 1/* ui-repolist.c: functions for generating the repolist page
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
11void cgit_print_repolist(struct cacheitem *item) 11void cgit_print_repolist(struct cacheitem *item)
12{ 12{
13 struct repoinfo *repo; 13 struct repoinfo *repo;
14 int i; 14 int i;
15 15
16 cgit_print_docstart(cgit_root_title, item); 16 cgit_print_docstart(cgit_root_title, item);
17 cgit_print_pageheader(cgit_root_title, 0); 17 cgit_print_pageheader(cgit_root_title, 0);
18 18
19 html("<table class='list nowrap'>"); 19 html("<table class='list nowrap'>");
20 if (cgit_index_header) {
21 html("<tr class='nohover'><td colspan='4' class='include-block'>");
22 html_include(cgit_index_header);
23 html("</td></tr>");
24 }
20 html("<tr class='nohover'>" 25 html("<tr class='nohover'>"
21 "<th class='left'>Name</th>" 26 "<th class='left'>Name</th>"
22 "<th class='left'>Description</th>" 27 "<th class='left'>Description</th>"
23 "<th class='left'>Owner</th>" 28 "<th class='left'>Owner</th>"
24 "<th class='left'>Links</th></tr>\n"); 29 "<th class='left'>Links</th></tr>\n");
25 30
26 for (i=0; i<cgit_repolist.count; i++) { 31 for (i=0; i<cgit_repolist.count; i++) {
27 repo = &cgit_repolist.repos[i]; 32 repo = &cgit_repolist.repos[i];
28 html("<tr><td>"); 33 html("<tr><td>");
29 html_link_open(cgit_repourl(repo->url), NULL, NULL); 34 html_link_open(cgit_repourl(repo->url), NULL, NULL);
30 html_txt(repo->name); 35 html_txt(repo->name);
31 html_link_close(); 36 html_link_close();
32 html("</td><td>"); 37 html("</td><td>");
33 html_ntxt(cgit_max_repodesc_len, repo->desc); 38 html_ntxt(cgit_max_repodesc_len, repo->desc);
34 html("</td><td>"); 39 html("</td><td>");
35 html_txt(repo->owner); 40 html_txt(repo->owner);
36 html("</td><td>"); 41 html("</td><td>");
37 html_link_open(cgit_pageurl(repo->name, "commit", NULL), 42 html_link_open(cgit_pageurl(repo->name, "commit", NULL),
38 "Commit: display last commit", NULL); 43 "Commit: display last commit", NULL);
39 html("C</a> "); 44 html("C</a> ");
40 html_link_open(cgit_pageurl(repo->name, "diff", NULL), 45 html_link_open(cgit_pageurl(repo->name, "diff", NULL),
41 "Diff: see changes introduced by last commit", NULL); 46 "Diff: see changes introduced by last commit", NULL);
42 html("D</a> "); 47 html("D</a> ");
43 html_link_open(cgit_pageurl(repo->name, "log", NULL), 48 html_link_open(cgit_pageurl(repo->name, "log", NULL),
44 "Log: show history of the main branch", NULL); 49 "Log: show history of the main branch", NULL);
45 html("L</a> "); 50 html("L</a> ");
46 html_link_open(cgit_pageurl(repo->name, "tree", NULL), 51 html_link_open(cgit_pageurl(repo->name, "tree", NULL),
47 "Tree: browse the files in the main branch", NULL); 52 "Tree: browse the files in the main branch", NULL);
48 html("T</a>"); 53 html("T</a>");
49 html("</td></tr>\n"); 54 html("</td></tr>\n");
50 } 55 }
51 html("</table>"); 56 html("</table>");
52 cgit_print_docend(); 57 cgit_print_docend();
53} 58}