summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2007-01-11 23:46:17 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-01-11 23:46:17 (UTC)
commit5cd2bf7e7f3f3daf6107cd3a269bad78e342de70 (patch) (unidiff)
tree7ce9368e94b39114e772c279f741bd8106f611d2
parent2c2047ff67a1e0053f95776e5079e432f69cea54 (diff)
downloadcgit-5cd2bf7e7f3f3daf6107cd3a269bad78e342de70.zip
cgit-5cd2bf7e7f3f3daf6107cd3a269bad78e342de70.tar.gz
cgit-5cd2bf7e7f3f3daf6107cd3a269bad78e342de70.tar.bz2
WIP: add paths/backlinks to tree/blobview
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c2
-rw-r--r--cgit.h3
-rw-r--r--shared.c3
-rw-r--r--ui-tree.c12
4 files changed, 15 insertions, 5 deletions
diff --git a/cgit.c b/cgit.c
index a3a04d9..9535abc 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,155 +1,155 @@
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
11const char cgit_version[] = CGIT_VERSION; 11const char cgit_version[] = CGIT_VERSION;
12 12
13static void cgit_prepare_cache(struct cacheitem *item) 13static void cgit_prepare_cache(struct cacheitem *item)
14{ 14{
15 if (!cgit_query_repo) { 15 if (!cgit_query_repo) {
16 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); 16 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root));
17 item->ttl = cgit_cache_root_ttl; 17 item->ttl = cgit_cache_root_ttl;
18 } else if (!cgit_query_page) { 18 } else if (!cgit_query_page) {
19 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, 19 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root,
20 cgit_query_repo)); 20 cgit_query_repo));
21 item->ttl = cgit_cache_repo_ttl; 21 item->ttl = cgit_cache_repo_ttl;
22 } else { 22 } else {
23 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, 23 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root,
24 cgit_query_repo, cgit_query_page, 24 cgit_query_repo, cgit_query_page,
25 cache_safe_filename(cgit_querystring))); 25 cache_safe_filename(cgit_querystring)));
26 if (cgit_query_has_symref) 26 if (cgit_query_has_symref)
27 item->ttl = cgit_cache_dynamic_ttl; 27 item->ttl = cgit_cache_dynamic_ttl;
28 else if (cgit_query_has_sha1) 28 else if (cgit_query_has_sha1)
29 item->ttl = cgit_cache_static_ttl; 29 item->ttl = cgit_cache_static_ttl;
30 else 30 else
31 item->ttl = cgit_cache_repo_ttl; 31 item->ttl = cgit_cache_repo_ttl;
32 } 32 }
33} 33}
34 34
35static void cgit_print_repo_page(struct cacheitem *item) 35static void cgit_print_repo_page(struct cacheitem *item)
36{ 36{
37 if (chdir(fmt("%s/%s", cgit_root, cgit_query_repo)) || 37 if (chdir(fmt("%s/%s", cgit_root, cgit_query_repo)) ||
38 cgit_read_config("info/cgit", cgit_repo_config_cb)) { 38 cgit_read_config("info/cgit", cgit_repo_config_cb)) {
39 char *title = fmt("%s - %s", cgit_root_title, "Bad request"); 39 char *title = fmt("%s - %s", cgit_root_title, "Bad request");
40 cgit_print_docstart(title, item); 40 cgit_print_docstart(title, item);
41 cgit_print_pageheader(title, 0); 41 cgit_print_pageheader(title, 0);
42 cgit_print_error(fmt("Unable to scan repository: %s", 42 cgit_print_error(fmt("Unable to scan repository: %s",
43 strerror(errno))); 43 strerror(errno)));
44 cgit_print_docend(); 44 cgit_print_docend();
45 return; 45 return;
46 } 46 }
47 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1); 47 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1);
48 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc); 48 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc);
49 int show_search = 0; 49 int show_search = 0;
50 if (cgit_query_page && !strcmp(cgit_query_page, "log")) 50 if (cgit_query_page && !strcmp(cgit_query_page, "log"))
51 show_search = 1; 51 show_search = 1;
52 cgit_print_docstart(title, item); 52 cgit_print_docstart(title, item);
53 cgit_print_pageheader(title, show_search); 53 cgit_print_pageheader(title, show_search);
54 if (!cgit_query_page) { 54 if (!cgit_query_page) {
55 cgit_print_summary(); 55 cgit_print_summary();
56 } else if (!strcmp(cgit_query_page, "log")) { 56 } else if (!strcmp(cgit_query_page, "log")) {
57 cgit_print_log(cgit_query_head, cgit_query_ofs, 100, cgit_query_search); 57 cgit_print_log(cgit_query_head, cgit_query_ofs, 100, cgit_query_search);
58 } else if (!strcmp(cgit_query_page, "tree")) { 58 } else if (!strcmp(cgit_query_page, "tree")) {
59 cgit_print_tree(cgit_query_sha1); 59 cgit_print_tree(cgit_query_sha1, cgit_query_path);
60 } else if (!strcmp(cgit_query_page, "commit")) { 60 } else if (!strcmp(cgit_query_page, "commit")) {
61 cgit_print_commit(cgit_query_sha1); 61 cgit_print_commit(cgit_query_sha1);
62 } else if (!strcmp(cgit_query_page, "view")) { 62 } else if (!strcmp(cgit_query_page, "view")) {
63 cgit_print_view(cgit_query_sha1); 63 cgit_print_view(cgit_query_sha1);
64 } else if (!strcmp(cgit_query_page, "diff")) { 64 } else if (!strcmp(cgit_query_page, "diff")) {
65 cgit_print_diff(cgit_query_sha1, cgit_query_sha2); 65 cgit_print_diff(cgit_query_sha1, cgit_query_sha2);
66 } 66 }
67 cgit_print_docend(); 67 cgit_print_docend();
68} 68}
69 69
70static void cgit_fill_cache(struct cacheitem *item) 70static void cgit_fill_cache(struct cacheitem *item)
71{ 71{
72 static char buf[PATH_MAX]; 72 static char buf[PATH_MAX];
73 73
74 getcwd(buf, sizeof(buf)); 74 getcwd(buf, sizeof(buf));
75 htmlfd = item->fd; 75 htmlfd = item->fd;
76 item->st.st_mtime = time(NULL); 76 item->st.st_mtime = time(NULL);
77 if (cgit_query_repo) 77 if (cgit_query_repo)
78 cgit_print_repo_page(item); 78 cgit_print_repo_page(item);
79 else 79 else
80 cgit_print_repolist(item); 80 cgit_print_repolist(item);
81 chdir(buf); 81 chdir(buf);
82} 82}
83 83
84static void cgit_check_cache(struct cacheitem *item) 84static void cgit_check_cache(struct cacheitem *item)
85{ 85{
86 int i = 0; 86 int i = 0;
87 87
88 top: 88 top:
89 if (++i > cgit_max_lock_attempts) { 89 if (++i > cgit_max_lock_attempts) {
90 die("cgit_refresh_cache: unable to lock %s: %s", 90 die("cgit_refresh_cache: unable to lock %s: %s",
91 item->name, strerror(errno)); 91 item->name, strerror(errno));
92 } 92 }
93 if (!cache_exist(item)) { 93 if (!cache_exist(item)) {
94 if (!cache_lock(item)) { 94 if (!cache_lock(item)) {
95 sleep(1); 95 sleep(1);
96 goto top; 96 goto top;
97 } 97 }
98 if (!cache_exist(item)) { 98 if (!cache_exist(item)) {
99 cgit_fill_cache(item); 99 cgit_fill_cache(item);
100 cache_unlock(item); 100 cache_unlock(item);
101 } else { 101 } else {
102 cache_cancel_lock(item); 102 cache_cancel_lock(item);
103 } 103 }
104 } else if (cache_expired(item) && cache_lock(item)) { 104 } else if (cache_expired(item) && cache_lock(item)) {
105 if (cache_expired(item)) { 105 if (cache_expired(item)) {
106 cgit_fill_cache(item); 106 cgit_fill_cache(item);
107 cache_unlock(item); 107 cache_unlock(item);
108 } else { 108 } else {
109 cache_cancel_lock(item); 109 cache_cancel_lock(item);
110 } 110 }
111 } 111 }
112} 112}
113 113
114static void cgit_print_cache(struct cacheitem *item) 114static void cgit_print_cache(struct cacheitem *item)
115{ 115{
116 static char buf[4096]; 116 static char buf[4096];
117 ssize_t i; 117 ssize_t i;
118 118
119 int fd = open(item->name, O_RDONLY); 119 int fd = open(item->name, O_RDONLY);
120 if (fd<0) 120 if (fd<0)
121 die("Unable to open cached file %s", item->name); 121 die("Unable to open cached file %s", item->name);
122 122
123 while((i=read(fd, buf, sizeof(buf))) > 0) 123 while((i=read(fd, buf, sizeof(buf))) > 0)
124 write(STDOUT_FILENO, buf, i); 124 write(STDOUT_FILENO, buf, i);
125 125
126 close(fd); 126 close(fd);
127} 127}
128 128
129static void cgit_parse_args(int argc, const char **argv) 129static void cgit_parse_args(int argc, const char **argv)
130{ 130{
131 int i; 131 int i;
132 132
133 for (i = 1; i < argc; i++) { 133 for (i = 1; i < argc; i++) {
134 if (!strncmp(argv[i], "--root=", 7)) { 134 if (!strncmp(argv[i], "--root=", 7)) {
135 cgit_root = xstrdup(argv[i]+7); 135 cgit_root = xstrdup(argv[i]+7);
136 } 136 }
137 if (!strncmp(argv[i], "--cache=", 8)) { 137 if (!strncmp(argv[i], "--cache=", 8)) {
138 cgit_cache_root = xstrdup(argv[i]+8); 138 cgit_cache_root = xstrdup(argv[i]+8);
139 } 139 }
140 if (!strcmp(argv[i], "--nocache")) { 140 if (!strcmp(argv[i], "--nocache")) {
141 cgit_nocache = 1; 141 cgit_nocache = 1;
142 } 142 }
143 if (!strncmp(argv[i], "--query=", 8)) { 143 if (!strncmp(argv[i], "--query=", 8)) {
144 cgit_querystring = xstrdup(argv[i]+8); 144 cgit_querystring = xstrdup(argv[i]+8);
145 } 145 }
146 if (!strncmp(argv[i], "--repo=", 7)) { 146 if (!strncmp(argv[i], "--repo=", 7)) {
147 cgit_query_repo = xstrdup(argv[i]+7); 147 cgit_query_repo = xstrdup(argv[i]+7);
148 } 148 }
149 if (!strncmp(argv[i], "--page=", 7)) { 149 if (!strncmp(argv[i], "--page=", 7)) {
150 cgit_query_page = xstrdup(argv[i]+7); 150 cgit_query_page = xstrdup(argv[i]+7);
151 } 151 }
152 if (!strncmp(argv[i], "--head=", 7)) { 152 if (!strncmp(argv[i], "--head=", 7)) {
153 cgit_query_head = xstrdup(argv[i]+7); 153 cgit_query_head = xstrdup(argv[i]+7);
154 cgit_query_has_symref = 1; 154 cgit_query_has_symref = 1;
155 } 155 }
diff --git a/cgit.h b/cgit.h
index 3601e49..5e19b11 100644
--- a/cgit.h
+++ b/cgit.h
@@ -1,115 +1,116 @@
1#ifndef CGIT_H 1#ifndef CGIT_H
2#define CGIT_H 2#define CGIT_H
3 3
4#include "git.h" 4#include "git.h"
5#include <openssl/sha.h> 5#include <openssl/sha.h>
6#include <ctype.h> 6#include <ctype.h>
7#include <sched.h> 7#include <sched.h>
8 8
9typedef void (*configfn)(const char *name, const char *value); 9typedef void (*configfn)(const char *name, const char *value);
10 10
11struct cacheitem { 11struct cacheitem {
12 char *name; 12 char *name;
13 struct stat st; 13 struct stat st;
14 int ttl; 14 int ttl;
15 int fd; 15 int fd;
16}; 16};
17 17
18struct commitinfo { 18struct commitinfo {
19 struct commit *commit; 19 struct commit *commit;
20 char *author; 20 char *author;
21 char *author_email; 21 char *author_email;
22 unsigned long author_date; 22 unsigned long author_date;
23 char *committer; 23 char *committer;
24 char *committer_email; 24 char *committer_email;
25 unsigned long committer_date; 25 unsigned long committer_date;
26 char *subject; 26 char *subject;
27 char *msg; 27 char *msg;
28}; 28};
29 29
30extern const char cgit_version[]; 30extern const char cgit_version[];
31 31
32extern char *cgit_root; 32extern char *cgit_root;
33extern char *cgit_root_title; 33extern char *cgit_root_title;
34extern char *cgit_css; 34extern char *cgit_css;
35extern char *cgit_logo; 35extern char *cgit_logo;
36extern char *cgit_logo_link; 36extern char *cgit_logo_link;
37extern char *cgit_virtual_root; 37extern char *cgit_virtual_root;
38extern char *cgit_cache_root; 38extern char *cgit_cache_root;
39 39
40extern int cgit_nocache; 40extern int cgit_nocache;
41extern int cgit_max_lock_attempts; 41extern int cgit_max_lock_attempts;
42extern int cgit_cache_root_ttl; 42extern int cgit_cache_root_ttl;
43extern int cgit_cache_repo_ttl; 43extern int cgit_cache_repo_ttl;
44extern int cgit_cache_dynamic_ttl; 44extern int cgit_cache_dynamic_ttl;
45extern int cgit_cache_static_ttl; 45extern int cgit_cache_static_ttl;
46extern int cgit_cache_max_create_time; 46extern int cgit_cache_max_create_time;
47 47
48extern char *cgit_repo_name; 48extern char *cgit_repo_name;
49extern char *cgit_repo_desc; 49extern char *cgit_repo_desc;
50extern char *cgit_repo_owner; 50extern char *cgit_repo_owner;
51 51
52extern int cgit_query_has_symref; 52extern int cgit_query_has_symref;
53extern int cgit_query_has_sha1; 53extern int cgit_query_has_sha1;
54 54
55extern char *cgit_querystring; 55extern char *cgit_querystring;
56extern char *cgit_query_repo; 56extern char *cgit_query_repo;
57extern char *cgit_query_page; 57extern char *cgit_query_page;
58extern char *cgit_query_search; 58extern char *cgit_query_search;
59extern char *cgit_query_head; 59extern char *cgit_query_head;
60extern char *cgit_query_sha1; 60extern char *cgit_query_sha1;
61extern char *cgit_query_sha2; 61extern char *cgit_query_sha2;
62extern char *cgit_query_path;
62extern int cgit_query_ofs; 63extern int cgit_query_ofs;
63 64
64extern int htmlfd; 65extern int htmlfd;
65 66
66extern void cgit_global_config_cb(const char *name, const char *value); 67extern void cgit_global_config_cb(const char *name, const char *value);
67extern void cgit_repo_config_cb(const char *name, const char *value); 68extern void cgit_repo_config_cb(const char *name, const char *value);
68extern void cgit_querystring_cb(const char *name, const char *value); 69extern void cgit_querystring_cb(const char *name, const char *value);
69 70
70extern int hextoint(char c); 71extern int hextoint(char c);
71 72
72extern void *cgit_free_commitinfo(struct commitinfo *info); 73extern void *cgit_free_commitinfo(struct commitinfo *info);
73 74
74extern char *fmt(const char *format,...); 75extern char *fmt(const char *format,...);
75 76
76extern void html(const char *txt); 77extern void html(const char *txt);
77extern void htmlf(const char *format,...); 78extern void htmlf(const char *format,...);
78extern void html_txt(char *txt); 79extern void html_txt(char *txt);
79extern void html_ntxt(int len, char *txt); 80extern void html_ntxt(int len, char *txt);
80extern void html_attr(char *txt); 81extern void html_attr(char *txt);
81extern void html_hidden(char *name, char *value); 82extern void html_hidden(char *name, char *value);
82extern void html_link_open(char *url, char *title, char *class); 83extern void html_link_open(char *url, char *title, char *class);
83extern void html_link_close(void); 84extern void html_link_close(void);
84extern void html_filemode(unsigned short mode); 85extern void html_filemode(unsigned short mode);
85 86
86extern int cgit_read_config(const char *filename, configfn fn); 87extern int cgit_read_config(const char *filename, configfn fn);
87extern int cgit_parse_query(char *txt, configfn fn); 88extern int cgit_parse_query(char *txt, configfn fn);
88extern struct commitinfo *cgit_parse_commit(struct commit *commit); 89extern struct commitinfo *cgit_parse_commit(struct commit *commit);
89 90
90extern char *cache_safe_filename(const char *unsafe); 91extern char *cache_safe_filename(const char *unsafe);
91extern int cache_lock(struct cacheitem *item); 92extern int cache_lock(struct cacheitem *item);
92extern int cache_unlock(struct cacheitem *item); 93extern int cache_unlock(struct cacheitem *item);
93extern int cache_cancel_lock(struct cacheitem *item); 94extern int cache_cancel_lock(struct cacheitem *item);
94extern int cache_exist(struct cacheitem *item); 95extern int cache_exist(struct cacheitem *item);
95extern int cache_expired(struct cacheitem *item); 96extern int cache_expired(struct cacheitem *item);
96 97
97extern char *cgit_repourl(const char *reponame); 98extern char *cgit_repourl(const char *reponame);
98extern char *cgit_pageurl(const char *reponame, const char *pagename, 99extern char *cgit_pageurl(const char *reponame, const char *pagename,
99 const char *query); 100 const char *query);
100 101
101extern void cgit_print_error(char *msg); 102extern void cgit_print_error(char *msg);
102extern void cgit_print_date(unsigned long secs); 103extern void cgit_print_date(unsigned long secs);
103extern void cgit_print_docstart(char *title, struct cacheitem *item); 104extern void cgit_print_docstart(char *title, struct cacheitem *item);
104extern void cgit_print_docend(); 105extern void cgit_print_docend();
105extern void cgit_print_pageheader(char *title, int show_search); 106extern void cgit_print_pageheader(char *title, int show_search);
106 107
107extern void cgit_print_repolist(struct cacheitem *item); 108extern void cgit_print_repolist(struct cacheitem *item);
108extern void cgit_print_summary(); 109extern void cgit_print_summary();
109extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep); 110extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep);
110extern void cgit_print_view(const char *hex); 111extern void cgit_print_view(const char *hex);
111extern void cgit_print_tree(const char *hex); 112extern void cgit_print_tree(const char *hex, char *path);
112extern void cgit_print_commit(const char *hex); 113extern void cgit_print_commit(const char *hex);
113extern void cgit_print_diff(const char *old_hex, const char *new_hex); 114extern void cgit_print_diff(const char *old_hex, const char *new_hex);
114 115
115#endif /* CGIT_H */ 116#endif /* CGIT_H */
diff --git a/shared.c b/shared.c
index e4595fa..dd711a8 100644
--- a/shared.c
+++ b/shared.c
@@ -1,128 +1,131 @@
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
11char *cgit_root = "/usr/src/git"; 11char *cgit_root = "/usr/src/git";
12char *cgit_root_title = "Git repository browser"; 12char *cgit_root_title = "Git repository browser";
13char *cgit_css = "/cgit.css"; 13char *cgit_css = "/cgit.css";
14char *cgit_logo = "/git-logo.png"; 14char *cgit_logo = "/git-logo.png";
15char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; 15char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/";
16char *cgit_virtual_root = NULL; 16char *cgit_virtual_root = NULL;
17 17
18char *cgit_cache_root = "/var/cache/cgit"; 18char *cgit_cache_root = "/var/cache/cgit";
19 19
20int cgit_nocache = 0; 20int cgit_nocache = 0;
21int cgit_max_lock_attempts = 5; 21int cgit_max_lock_attempts = 5;
22int cgit_cache_root_ttl = 5; 22int cgit_cache_root_ttl = 5;
23int cgit_cache_repo_ttl = 5; 23int cgit_cache_repo_ttl = 5;
24int cgit_cache_dynamic_ttl = 5; 24int cgit_cache_dynamic_ttl = 5;
25int cgit_cache_static_ttl = -1; 25int cgit_cache_static_ttl = -1;
26int cgit_cache_max_create_time = 5; 26int cgit_cache_max_create_time = 5;
27 27
28char *cgit_repo_name = NULL; 28char *cgit_repo_name = NULL;
29char *cgit_repo_desc = NULL; 29char *cgit_repo_desc = NULL;
30char *cgit_repo_owner = NULL; 30char *cgit_repo_owner = NULL;
31 31
32int cgit_query_has_symref = 0; 32int cgit_query_has_symref = 0;
33int cgit_query_has_sha1 = 0; 33int cgit_query_has_sha1 = 0;
34 34
35char *cgit_querystring = NULL; 35char *cgit_querystring = NULL;
36char *cgit_query_repo = NULL; 36char *cgit_query_repo = NULL;
37char *cgit_query_page = NULL; 37char *cgit_query_page = NULL;
38char *cgit_query_head = NULL; 38char *cgit_query_head = NULL;
39char *cgit_query_search = NULL; 39char *cgit_query_search = NULL;
40char *cgit_query_sha1 = NULL; 40char *cgit_query_sha1 = NULL;
41char *cgit_query_sha2 = NULL; 41char *cgit_query_sha2 = NULL;
42char *cgit_query_path = NULL;
42int cgit_query_ofs = 0; 43int cgit_query_ofs = 0;
43 44
44int htmlfd = 0; 45int htmlfd = 0;
45 46
46void cgit_global_config_cb(const char *name, const char *value) 47void cgit_global_config_cb(const char *name, const char *value)
47{ 48{
48 if (!strcmp(name, "root")) 49 if (!strcmp(name, "root"))
49 cgit_root = xstrdup(value); 50 cgit_root = xstrdup(value);
50 else if (!strcmp(name, "root-title")) 51 else if (!strcmp(name, "root-title"))
51 cgit_root_title = xstrdup(value); 52 cgit_root_title = xstrdup(value);
52 else if (!strcmp(name, "css")) 53 else if (!strcmp(name, "css"))
53 cgit_css = xstrdup(value); 54 cgit_css = xstrdup(value);
54 else if (!strcmp(name, "logo")) 55 else if (!strcmp(name, "logo"))
55 cgit_logo = xstrdup(value); 56 cgit_logo = xstrdup(value);
56 else if (!strcmp(name, "logo-link")) 57 else if (!strcmp(name, "logo-link"))
57 cgit_logo_link = xstrdup(value); 58 cgit_logo_link = xstrdup(value);
58 else if (!strcmp(name, "virtual-root")) 59 else if (!strcmp(name, "virtual-root"))
59 cgit_virtual_root = xstrdup(value); 60 cgit_virtual_root = xstrdup(value);
60 else if (!strcmp(name, "nocache")) 61 else if (!strcmp(name, "nocache"))
61 cgit_nocache = atoi(value); 62 cgit_nocache = atoi(value);
62 else if (!strcmp(name, "cache-root")) 63 else if (!strcmp(name, "cache-root"))
63 cgit_cache_root = xstrdup(value); 64 cgit_cache_root = xstrdup(value);
64 else if (!strcmp(name, "cache-root-ttl")) 65 else if (!strcmp(name, "cache-root-ttl"))
65 cgit_cache_root_ttl = atoi(value); 66 cgit_cache_root_ttl = atoi(value);
66 else if (!strcmp(name, "cache-repo-ttl")) 67 else if (!strcmp(name, "cache-repo-ttl"))
67 cgit_cache_repo_ttl = atoi(value); 68 cgit_cache_repo_ttl = atoi(value);
68 else if (!strcmp(name, "cache-static-ttl")) 69 else if (!strcmp(name, "cache-static-ttl"))
69 cgit_cache_static_ttl = atoi(value); 70 cgit_cache_static_ttl = atoi(value);
70 else if (!strcmp(name, "cache-dynamic-ttl")) 71 else if (!strcmp(name, "cache-dynamic-ttl"))
71 cgit_cache_dynamic_ttl = atoi(value); 72 cgit_cache_dynamic_ttl = atoi(value);
72} 73}
73 74
74void cgit_repo_config_cb(const char *name, const char *value) 75void cgit_repo_config_cb(const char *name, const char *value)
75{ 76{
76 if (!strcmp(name, "name")) 77 if (!strcmp(name, "name"))
77 cgit_repo_name = xstrdup(value); 78 cgit_repo_name = xstrdup(value);
78 else if (!strcmp(name, "desc")) 79 else if (!strcmp(name, "desc"))
79 cgit_repo_desc = xstrdup(value); 80 cgit_repo_desc = xstrdup(value);
80 else if (!strcmp(name, "owner")) 81 else if (!strcmp(name, "owner"))
81 cgit_repo_owner = xstrdup(value); 82 cgit_repo_owner = xstrdup(value);
82} 83}
83 84
84void cgit_querystring_cb(const char *name, const char *value) 85void cgit_querystring_cb(const char *name, const char *value)
85{ 86{
86 if (!strcmp(name,"r")) { 87 if (!strcmp(name,"r")) {
87 cgit_query_repo = xstrdup(value); 88 cgit_query_repo = xstrdup(value);
88 } else if (!strcmp(name, "p")) { 89 } else if (!strcmp(name, "p")) {
89 cgit_query_page = xstrdup(value); 90 cgit_query_page = xstrdup(value);
90 } else if (!strcmp(name, "q")) { 91 } else if (!strcmp(name, "q")) {
91 cgit_query_search = xstrdup(value); 92 cgit_query_search = xstrdup(value);
92 } else if (!strcmp(name, "h")) { 93 } else if (!strcmp(name, "h")) {
93 cgit_query_head = xstrdup(value); 94 cgit_query_head = xstrdup(value);
94 cgit_query_has_symref = 1; 95 cgit_query_has_symref = 1;
95 } else if (!strcmp(name, "id")) { 96 } else if (!strcmp(name, "id")) {
96 cgit_query_sha1 = xstrdup(value); 97 cgit_query_sha1 = xstrdup(value);
97 cgit_query_has_sha1 = 1; 98 cgit_query_has_sha1 = 1;
98 } else if (!strcmp(name, "id2")) { 99 } else if (!strcmp(name, "id2")) {
99 cgit_query_sha2 = xstrdup(value); 100 cgit_query_sha2 = xstrdup(value);
100 cgit_query_has_sha1 = 1; 101 cgit_query_has_sha1 = 1;
101 } else if (!strcmp(name, "ofs")) { 102 } else if (!strcmp(name, "ofs")) {
102 cgit_query_ofs = atoi(value); 103 cgit_query_ofs = atoi(value);
104 } else if (!strcmp(name, "path")) {
105 cgit_query_path = xstrdup(value);
103 } 106 }
104} 107}
105 108
106void *cgit_free_commitinfo(struct commitinfo *info) 109void *cgit_free_commitinfo(struct commitinfo *info)
107{ 110{
108 free(info->author); 111 free(info->author);
109 free(info->author_email); 112 free(info->author_email);
110 free(info->committer); 113 free(info->committer);
111 free(info->committer_email); 114 free(info->committer_email);
112 free(info->subject); 115 free(info->subject);
113 free(info); 116 free(info);
114 return NULL; 117 return NULL;
115} 118}
116 119
117int hextoint(char c) 120int hextoint(char c)
118{ 121{
119 if (c >= 'a' && c <= 'f') 122 if (c >= 'a' && c <= 'f')
120 return 10 + c - 'a'; 123 return 10 + c - 'a';
121 else if (c >= 'A' && c <= 'F') 124 else if (c >= 'A' && c <= 'F')
122 return 10 + c - 'A'; 125 return 10 + c - 'A';
123 else if (c >= '0' && c <= '9') 126 else if (c >= '0' && c <= '9')
124 return c - '0'; 127 return c - '0';
125 else 128 else
126 return -1; 129 return -1;
127} 130}
128 131
diff --git a/ui-tree.c b/ui-tree.c
index 54dcdbe..ed9f05e 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -1,73 +1,79 @@
1/* ui-tree.c: functions for tree output 1/* ui-tree.c: functions for tree 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
11 11
12static int print_entry(const unsigned char *sha1, const char *base, 12static int print_entry(const unsigned char *sha1, const char *base,
13 int baselen, const char *pathname, unsigned int mode, 13 int baselen, const char *pathname, unsigned int mode,
14 int stage) 14 int stage)
15{ 15{
16 char *name; 16 char *name;
17 char type[20]; 17 char type[20];
18 unsigned long size; 18 unsigned long size;
19 19
20 if (sha1_object_info(sha1, type, &size)) { 20 if (sha1_object_info(sha1, type, &size)) {
21 cgit_print_error(fmt("Bad object name: %s", 21 cgit_print_error(fmt("Bad object name: %s",
22 sha1_to_hex(sha1))); 22 sha1_to_hex(sha1)));
23 return 0; 23 return 0;
24 } 24 }
25 name = xstrdup(pathname); 25 name = xstrdup(pathname);
26 html("<tr><td class='filemode'>"); 26 html("<tr><td class='filemode'>");
27 html_filemode(mode); 27 html_filemode(mode);
28 html("</td><td>"); 28 html("</td><td>");
29 if (S_ISDIR(mode)) { 29 if (S_ISDIR(mode)) {
30 html("<div class='ls-dir'><a href='"); 30 html("<div class='ls-dir'><a href='");
31 html_attr(cgit_pageurl(cgit_query_repo, "tree", 31 html_attr(cgit_pageurl(cgit_query_repo, "tree",
32 fmt("id=%s", sha1_to_hex(sha1)))); 32 fmt("id=%s&path=%s%s/",
33 sha1_to_hex(sha1),
34 cgit_query_path ? cgit_query_path : "",
35 pathname)));
33 } else { 36 } else {
34 html("<div class='ls-blob'><a href='"); 37 html("<div class='ls-blob'><a href='");
35 html_attr(cgit_pageurl(cgit_query_repo, "view", 38 html_attr(cgit_pageurl(cgit_query_repo, "view",
36 fmt("id=%s", sha1_to_hex(sha1)))); 39 fmt("id=%s&path=%s%s", sha1_to_hex(sha1),
40 cgit_query_path ? cgit_query_path : "",
41 pathname)));
37 } 42 }
38 html("'>"); 43 html("'>");
39 html_txt(name); 44 html_txt(name);
40 if (S_ISDIR(mode)) 45 if (S_ISDIR(mode))
41 html("/"); 46 html("/");
42 html("</a></div></td>"); 47 html("</a></div></td>");
43 htmlf("<td class='filesize'>%li</td>", size); 48 htmlf("<td class='filesize'>%li</td>", size);
44 html("</tr>\n"); 49 html("</tr>\n");
45 free(name); 50 free(name);
46 return 0; 51 return 0;
47} 52}
48 53
49void cgit_print_tree(const char *hex) 54void cgit_print_tree(const char *hex, char *path)
50{ 55{
51 struct tree *tree; 56 struct tree *tree;
52 unsigned char sha1[20]; 57 unsigned char sha1[20];
53 58
54 if (get_sha1_hex(hex, sha1)) { 59 if (get_sha1_hex(hex, sha1)) {
55 cgit_print_error(fmt("Invalid object id: %s", hex)); 60 cgit_print_error(fmt("Invalid object id: %s", hex));
56 return; 61 return;
57 } 62 }
58 tree = parse_tree_indirect(sha1); 63 tree = parse_tree_indirect(sha1);
59 if (!tree) { 64 if (!tree) {
60 cgit_print_error(fmt("Not a tree object: %s", hex)); 65 cgit_print_error(fmt("Not a tree object: %s", hex));
61 return; 66 return;
62 } 67 }
63 68
64 html("<h2>Tree content</h2>\n"); 69 html("<h2>Tree content</h2>\n");
70 html_txt(path);
65 html("<table class='list'>\n"); 71 html("<table class='list'>\n");
66 html("<tr>"); 72 html("<tr>");
67 html("<th class='left'>Mode</th>"); 73 html("<th class='left'>Mode</th>");
68 html("<th class='left'>Name</th>"); 74 html("<th class='left'>Name</th>");
69 html("<th class='right'>Size</th>"); 75 html("<th class='right'>Size</th>");
70 html("</tr>\n"); 76 html("</tr>\n");
71 read_tree_recursive(tree, "", 0, 1, NULL, print_entry); 77 read_tree_recursive(tree, "", 0, 1, NULL, print_entry);
72 html("</table>\n"); 78 html("</table>\n");
73} 79}