summaryrefslogtreecommitdiffabout
path: root/cgit.c
Unidiff
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/cgit.c b/cgit.c
index 0fa203c..2795ecc 100644
--- a/cgit.c
+++ b/cgit.c
@@ -57,105 +57,131 @@ static int cgit_prepare_cache(struct cacheitem *item)
57 else 57 else
58 item->ttl = cgit_cache_repo_ttl; 58 item->ttl = cgit_cache_repo_ttl;
59 } 59 }
60 return 1; 60 return 1;
61} 61}
62 62
63static void cgit_print_repo_page(struct cacheitem *item) 63static void cgit_print_repo_page(struct cacheitem *item)
64{ 64{
65 char *title; 65 char *title;
66 int show_search; 66 int show_search;
67 67
68 if (chdir(cgit_repo->path)) { 68 if (chdir(cgit_repo->path)) {
69 title = fmt("%s - %s", cgit_root_title, "Bad request"); 69 title = fmt("%s - %s", cgit_root_title, "Bad request");
70 cgit_print_docstart(title, item); 70 cgit_print_docstart(title, item);
71 cgit_print_pageheader(title, 0); 71 cgit_print_pageheader(title, 0);
72 cgit_print_error(fmt("Unable to scan repository: %s", 72 cgit_print_error(fmt("Unable to scan repository: %s",
73 strerror(errno))); 73 strerror(errno)));
74 cgit_print_docend(); 74 cgit_print_docend();
75 return; 75 return;
76 } 76 }
77 77
78 title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); 78 title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc);
79 show_search = 0; 79 show_search = 0;
80 setenv("GIT_DIR", cgit_repo->path, 1); 80 setenv("GIT_DIR", cgit_repo->path, 1);
81
82 if (cgit_query_page && !strcmp(cgit_query_page, "snapshot")) {
83 cgit_print_snapshot(item, cgit_query_sha1, "zip",
84 cgit_repo->url, cgit_query_name);
85 return;
86 }
87
81 if (cgit_query_page && !strcmp(cgit_query_page, "log")) 88 if (cgit_query_page && !strcmp(cgit_query_page, "log"))
82 show_search = 1; 89 show_search = 1;
83 cgit_print_docstart(title, item); 90 cgit_print_docstart(title, item);
84 cgit_print_pageheader(title, show_search); 91 cgit_print_pageheader(title, show_search);
85 if (!cgit_query_page) { 92 if (!cgit_query_page) {
86 cgit_print_summary(); 93 cgit_print_summary();
87 } else if (!strcmp(cgit_query_page, "log")) { 94 } else if (!strcmp(cgit_query_page, "log")) {
88 cgit_print_log(cgit_query_head, cgit_query_ofs, 100, cgit_query_search); 95 cgit_print_log(cgit_query_head, cgit_query_ofs, 100,
96 cgit_query_search);
89 } else if (!strcmp(cgit_query_page, "tree")) { 97 } else if (!strcmp(cgit_query_page, "tree")) {
90 cgit_print_tree(cgit_query_sha1, cgit_query_path); 98 cgit_print_tree(cgit_query_sha1, cgit_query_path);
91 } else if (!strcmp(cgit_query_page, "commit")) { 99 } else if (!strcmp(cgit_query_page, "commit")) {
92 cgit_print_commit(cgit_query_sha1); 100 cgit_print_commit(cgit_query_sha1);
93 } else if (!strcmp(cgit_query_page, "view")) { 101 } else if (!strcmp(cgit_query_page, "view")) {
94 cgit_print_view(cgit_query_sha1); 102 cgit_print_view(cgit_query_sha1);
95 } else if (!strcmp(cgit_query_page, "diff")) { 103 } else if (!strcmp(cgit_query_page, "diff")) {
96 cgit_print_diff(cgit_query_sha1, cgit_query_sha2); 104 cgit_print_diff(cgit_query_sha1, cgit_query_sha2);
105 } else {
106 cgit_print_error("Invalid request");
97 } 107 }
98 cgit_print_docend(); 108 cgit_print_docend();
99} 109}
100 110
101static void cgit_fill_cache(struct cacheitem *item) 111static void cgit_fill_cache(struct cacheitem *item, int use_cache)
102{ 112{
103 static char buf[PATH_MAX]; 113 static char buf[PATH_MAX];
114 int stdout2;
104 115
105 getcwd(buf, sizeof(buf)); 116 getcwd(buf, sizeof(buf));
106 htmlfd = item->fd;
107 item->st.st_mtime = time(NULL); 117 item->st.st_mtime = time(NULL);
118
119 if (use_cache) {
120 stdout2 = chk_positive(dup(STDOUT_FILENO),
121 "Preserving STDOUT");
122 chk_zero(close(STDOUT_FILENO), "Closing STDOUT");
123 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)");
124 }
125
108 if (cgit_query_repo) 126 if (cgit_query_repo)
109 cgit_print_repo_page(item); 127 cgit_print_repo_page(item);
110 else 128 else
111 cgit_print_repolist(item); 129 cgit_print_repolist(item);
130
131 if (use_cache) {
132 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT");
133 chk_positive(dup2(stdout2, STDOUT_FILENO),
134 "Restoring original STDOUT");
135 chk_zero(close(stdout2), "Closing temporary STDOUT");
136 }
137
112 chdir(buf); 138 chdir(buf);
113} 139}
114 140
115static void cgit_check_cache(struct cacheitem *item) 141static void cgit_check_cache(struct cacheitem *item)
116{ 142{
117 int i = 0; 143 int i = 0;
118 144
119 top: 145 top:
120 if (++i > cgit_max_lock_attempts) { 146 if (++i > cgit_max_lock_attempts) {
121 die("cgit_refresh_cache: unable to lock %s: %s", 147 die("cgit_refresh_cache: unable to lock %s: %s",
122 item->name, strerror(errno)); 148 item->name, strerror(errno));
123 } 149 }
124 if (!cache_exist(item)) { 150 if (!cache_exist(item)) {
125 if (!cache_lock(item)) { 151 if (!cache_lock(item)) {
126 sleep(1); 152 sleep(1);
127 goto top; 153 goto top;
128 } 154 }
129 if (!cache_exist(item)) { 155 if (!cache_exist(item)) {
130 cgit_fill_cache(item); 156 cgit_fill_cache(item, 1);
131 cache_unlock(item); 157 cache_unlock(item);
132 } else { 158 } else {
133 cache_cancel_lock(item); 159 cache_cancel_lock(item);
134 } 160 }
135 } else if (cache_expired(item) && cache_lock(item)) { 161 } else if (cache_expired(item) && cache_lock(item)) {
136 if (cache_expired(item)) { 162 if (cache_expired(item)) {
137 cgit_fill_cache(item); 163 cgit_fill_cache(item, 1);
138 cache_unlock(item); 164 cache_unlock(item);
139 } else { 165 } else {
140 cache_cancel_lock(item); 166 cache_cancel_lock(item);
141 } 167 }
142 } 168 }
143} 169}
144 170
145static void cgit_print_cache(struct cacheitem *item) 171static void cgit_print_cache(struct cacheitem *item)
146{ 172{
147 static char buf[4096]; 173 static char buf[4096];
148 ssize_t i; 174 ssize_t i;
149 175
150 int fd = open(item->name, O_RDONLY); 176 int fd = open(item->name, O_RDONLY);
151 if (fd<0) 177 if (fd<0)
152 die("Unable to open cached file %s", item->name); 178 die("Unable to open cached file %s", item->name);
153 179
154 while((i=read(fd, buf, sizeof(buf))) > 0) 180 while((i=read(fd, buf, sizeof(buf))) > 0)
155 write(STDOUT_FILENO, buf, i); 181 write(STDOUT_FILENO, buf, i);
156 182
157 close(fd); 183 close(fd);
158} 184}
159 185
160static void cgit_parse_args(int argc, const char **argv) 186static void cgit_parse_args(int argc, const char **argv)
161{ 187{
@@ -188,32 +214,31 @@ static void cgit_parse_args(int argc, const char **argv)
188 if (!strncmp(argv[i], "--ofs=", 6)) { 214 if (!strncmp(argv[i], "--ofs=", 6)) {
189 cgit_query_ofs = atoi(argv[i]+6); 215 cgit_query_ofs = atoi(argv[i]+6);
190 } 216 }
191 } 217 }
192} 218}
193 219
194int main(int argc, const char **argv) 220int main(int argc, const char **argv)
195{ 221{
196 struct cacheitem item; 222 struct cacheitem item;
197 223
198 htmlfd = STDOUT_FILENO; 224 htmlfd = STDOUT_FILENO;
199 item.st.st_mtime = time(NULL); 225 item.st.st_mtime = time(NULL);
200 cgit_repolist.length = 0; 226 cgit_repolist.length = 0;
201 cgit_repolist.count = 0; 227 cgit_repolist.count = 0;
202 cgit_repolist.repos = NULL; 228 cgit_repolist.repos = NULL;
203 229
204 cgit_read_config("/etc/cgitrc", cgit_global_config_cb); 230 cgit_read_config("/etc/cgitrc", cgit_global_config_cb);
205 if (getenv("QUERY_STRING")) 231 if (getenv("QUERY_STRING"))
206 cgit_querystring = xstrdup(getenv("QUERY_STRING")); 232 cgit_querystring = xstrdup(getenv("QUERY_STRING"));
207 cgit_parse_args(argc, argv); 233 cgit_parse_args(argc, argv);
208 cgit_parse_query(cgit_querystring, cgit_querystring_cb); 234 cgit_parse_query(cgit_querystring, cgit_querystring_cb);
209 if (!cgit_prepare_cache(&item)) 235 if (!cgit_prepare_cache(&item))
210 return 0; 236 return 0;
211 if (cgit_nocache) { 237 if (cgit_nocache) {
212 item.fd = STDOUT_FILENO; 238 cgit_fill_cache(&item, 0);
213 cgit_fill_cache(&item);
214 } else { 239 } else {
215 cgit_check_cache(&item); 240 cgit_check_cache(&item);
216 cgit_print_cache(&item); 241 cgit_print_cache(&item);
217 } 242 }
218 return 0; 243 return 0;
219} 244}