|
diff --git a/html.c b/html.c index 83fc7a9..36e9a2f 100644 --- a/ html.c+++ b/ html.c |
|
@@ -1,257 +1,257 @@ |
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 <unistd.h> |
9 | #include <unistd.h> |
10 | #include <stdio.h> |
10 | #include <stdio.h> |
11 | #include <stdlib.h> |
11 | #include <stdlib.h> |
12 | #include <stdarg.h> |
12 | #include <stdarg.h> |
13 | #include <string.h> |
13 | #include <string.h> |
14 | #include <errno.h> |
14 | #include <errno.h> |
15 | |
15 | |
16 | int htmlfd = STDOUT_FILENO; |
16 | int htmlfd = STDOUT_FILENO; |
17 | |
17 | |
18 | char *fmt(const char *format, ...) |
18 | char *fmt(const char *format, ...) |
19 | { |
19 | { |
20 | static char buf[8][1024]; |
20 | static char buf[8][1024]; |
21 | static int bufidx; |
21 | static int bufidx; |
22 | int len; |
22 | int len; |
23 | va_list args; |
23 | va_list args; |
24 | |
24 | |
25 | bufidx++; |
25 | bufidx++; |
26 | bufidx &= 7; |
26 | bufidx &= 7; |
27 | |
27 | |
28 | va_start(args, format); |
28 | va_start(args, format); |
29 | len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args); |
29 | len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args); |
30 | va_end(args); |
30 | va_end(args); |
31 | if (len>sizeof(buf[bufidx])) { |
31 | if (len>sizeof(buf[bufidx])) { |
32 | fprintf(stderr, "[html.c] string truncated: %s\n", format); |
32 | fprintf(stderr, "[html.c] string truncated: %s\n", format); |
33 | exit(1); |
33 | exit(1); |
34 | } |
34 | } |
35 | return buf[bufidx]; |
35 | return buf[bufidx]; |
36 | } |
36 | } |
37 | |
37 | |
38 | void html_raw(const char *data, size_t size) |
38 | void html_raw(const char *data, size_t size) |
39 | { |
39 | { |
40 | write(htmlfd, data, size); |
40 | write(htmlfd, data, size); |
41 | } |
41 | } |
42 | |
42 | |
43 | void html(const char *txt) |
43 | void html(const char *txt) |
44 | { |
44 | { |
45 | write(htmlfd, txt, strlen(txt)); |
45 | write(htmlfd, txt, strlen(txt)); |
46 | } |
46 | } |
47 | |
47 | |
48 | void htmlf(const char *format, ...) |
48 | void htmlf(const char *format, ...) |
49 | { |
49 | { |
50 | static char buf[65536]; |
50 | static char buf[65536]; |
51 | va_list args; |
51 | va_list args; |
52 | |
52 | |
53 | va_start(args, format); |
53 | va_start(args, format); |
54 | vsnprintf(buf, sizeof(buf), format, args); |
54 | vsnprintf(buf, sizeof(buf), format, args); |
55 | va_end(args); |
55 | va_end(args); |
56 | html(buf); |
56 | html(buf); |
57 | } |
57 | } |
58 | |
58 | |
59 | void html_status(int code, int more_headers) |
59 | void html_status(int code, const char *msg, int more_headers) |
60 | { |
60 | { |
61 | htmlf("Status: %d\n", code); |
61 | htmlf("Status: %d %s\n", code, msg); |
62 | if (!more_headers) |
62 | if (!more_headers) |
63 | html("\n"); |
63 | html("\n"); |
64 | } |
64 | } |
65 | |
65 | |
66 | void html_txt(char *txt) |
66 | void html_txt(char *txt) |
67 | { |
67 | { |
68 | char *t = txt; |
68 | char *t = txt; |
69 | while(t && *t){ |
69 | while(t && *t){ |
70 | int c = *t; |
70 | int c = *t; |
71 | if (c=='<' || c=='>' || c=='&') { |
71 | if (c=='<' || c=='>' || c=='&') { |
72 | write(htmlfd, txt, t - txt); |
72 | write(htmlfd, txt, t - txt); |
73 | if (c=='>') |
73 | if (c=='>') |
74 | html(">"); |
74 | html(">"); |
75 | else if (c=='<') |
75 | else if (c=='<') |
76 | html("<"); |
76 | html("<"); |
77 | else if (c=='&') |
77 | else if (c=='&') |
78 | html("&"); |
78 | html("&"); |
79 | txt = t+1; |
79 | txt = t+1; |
80 | } |
80 | } |
81 | t++; |
81 | t++; |
82 | } |
82 | } |
83 | if (t!=txt) |
83 | if (t!=txt) |
84 | html(txt); |
84 | html(txt); |
85 | } |
85 | } |
86 | |
86 | |
87 | void html_ntxt(int len, char *txt) |
87 | void html_ntxt(int len, char *txt) |
88 | { |
88 | { |
89 | char *t = txt; |
89 | char *t = txt; |
90 | while(t && *t && len--){ |
90 | while(t && *t && len--){ |
91 | int c = *t; |
91 | int c = *t; |
92 | if (c=='<' || c=='>' || c=='&') { |
92 | if (c=='<' || c=='>' || c=='&') { |
93 | write(htmlfd, txt, t - txt); |
93 | write(htmlfd, txt, t - txt); |
94 | if (c=='>') |
94 | if (c=='>') |
95 | html(">"); |
95 | html(">"); |
96 | else if (c=='<') |
96 | else if (c=='<') |
97 | html("<"); |
97 | html("<"); |
98 | else if (c=='&') |
98 | else if (c=='&') |
99 | html("&"); |
99 | html("&"); |
100 | txt = t+1; |
100 | txt = t+1; |
101 | } |
101 | } |
102 | t++; |
102 | t++; |
103 | } |
103 | } |
104 | if (t!=txt) |
104 | if (t!=txt) |
105 | write(htmlfd, txt, t - txt); |
105 | write(htmlfd, txt, t - txt); |
106 | if (len<0) |
106 | if (len<0) |
107 | html("..."); |
107 | html("..."); |
108 | } |
108 | } |
109 | |
109 | |
110 | void html_attr(char *txt) |
110 | void html_attr(char *txt) |
111 | { |
111 | { |
112 | char *t = txt; |
112 | char *t = txt; |
113 | while(t && *t){ |
113 | while(t && *t){ |
114 | int c = *t; |
114 | int c = *t; |
115 | if (c=='<' || c=='>' || c=='\'') { |
115 | if (c=='<' || c=='>' || c=='\'') { |
116 | write(htmlfd, txt, t - txt); |
116 | write(htmlfd, txt, t - txt); |
117 | if (c=='>') |
117 | if (c=='>') |
118 | html(">"); |
118 | html(">"); |
119 | else if (c=='<') |
119 | else if (c=='<') |
120 | html("<"); |
120 | html("<"); |
121 | else if (c=='\'') |
121 | else if (c=='\'') |
122 | html(""e;"); |
122 | html(""e;"); |
123 | txt = t+1; |
123 | txt = t+1; |
124 | } |
124 | } |
125 | t++; |
125 | t++; |
126 | } |
126 | } |
127 | if (t!=txt) |
127 | if (t!=txt) |
128 | html(txt); |
128 | html(txt); |
129 | } |
129 | } |
130 | |
130 | |
131 | void html_hidden(char *name, char *value) |
131 | void html_hidden(char *name, char *value) |
132 | { |
132 | { |
133 | html("<input type='hidden' name='"); |
133 | html("<input type='hidden' name='"); |
134 | html_attr(name); |
134 | html_attr(name); |
135 | html("' value='"); |
135 | html("' value='"); |
136 | html_attr(value); |
136 | html_attr(value); |
137 | html("'/>"); |
137 | html("'/>"); |
138 | } |
138 | } |
139 | |
139 | |
140 | void html_option(char *value, char *text, char *selected_value) |
140 | void html_option(char *value, char *text, char *selected_value) |
141 | { |
141 | { |
142 | html("<option value='"); |
142 | html("<option value='"); |
143 | html_attr(value); |
143 | html_attr(value); |
144 | html("'"); |
144 | html("'"); |
145 | if (selected_value && !strcmp(selected_value, value)) |
145 | if (selected_value && !strcmp(selected_value, value)) |
146 | html(" selected='selected'"); |
146 | html(" selected='selected'"); |
147 | html(">"); |
147 | html(">"); |
148 | html_txt(text); |
148 | html_txt(text); |
149 | html("</option>\n"); |
149 | html("</option>\n"); |
150 | } |
150 | } |
151 | |
151 | |
152 | void html_link_open(char *url, char *title, char *class) |
152 | void html_link_open(char *url, char *title, char *class) |
153 | { |
153 | { |
154 | html("<a href='"); |
154 | html("<a href='"); |
155 | html_attr(url); |
155 | html_attr(url); |
156 | if (title) { |
156 | if (title) { |
157 | html("' title='"); |
157 | html("' title='"); |
158 | html_attr(title); |
158 | html_attr(title); |
159 | } |
159 | } |
160 | if (class) { |
160 | if (class) { |
161 | html("' class='"); |
161 | html("' class='"); |
162 | html_attr(class); |
162 | html_attr(class); |
163 | } |
163 | } |
164 | html("'>"); |
164 | html("'>"); |
165 | } |
165 | } |
166 | |
166 | |
167 | void html_link_close(void) |
167 | void html_link_close(void) |
168 | { |
168 | { |
169 | html("</a>"); |
169 | html("</a>"); |
170 | } |
170 | } |
171 | |
171 | |
172 | void html_fileperm(unsigned short mode) |
172 | void html_fileperm(unsigned short mode) |
173 | { |
173 | { |
174 | htmlf("%c%c%c", (mode & 4 ? 'r' : '-'), |
174 | htmlf("%c%c%c", (mode & 4 ? 'r' : '-'), |
175 | (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-')); |
175 | (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-')); |
176 | } |
176 | } |
177 | |
177 | |
178 | int html_include(const char *filename) |
178 | int html_include(const char *filename) |
179 | { |
179 | { |
180 | FILE *f; |
180 | FILE *f; |
181 | char buf[4096]; |
181 | char buf[4096]; |
182 | size_t len; |
182 | size_t len; |
183 | |
183 | |
184 | if (!(f = fopen(filename, "r"))) { |
184 | if (!(f = fopen(filename, "r"))) { |
185 | fprintf(stderr, "[cgit] Failed to include file %s: %s (%d).\n", |
185 | fprintf(stderr, "[cgit] Failed to include file %s: %s (%d).\n", |
186 | filename, strerror(errno), errno); |
186 | filename, strerror(errno), errno); |
187 | return -1; |
187 | return -1; |
188 | } |
188 | } |
189 | while((len = fread(buf, 1, 4096, f)) > 0) |
189 | while((len = fread(buf, 1, 4096, f)) > 0) |
190 | write(htmlfd, buf, len); |
190 | write(htmlfd, buf, len); |
191 | fclose(f); |
191 | fclose(f); |
192 | return 0; |
192 | return 0; |
193 | } |
193 | } |
194 | |
194 | |
195 | int hextoint(char c) |
195 | int hextoint(char c) |
196 | { |
196 | { |
197 | if (c >= 'a' && c <= 'f') |
197 | if (c >= 'a' && c <= 'f') |
198 | return 10 + c - 'a'; |
198 | return 10 + c - 'a'; |
199 | else if (c >= 'A' && c <= 'F') |
199 | else if (c >= 'A' && c <= 'F') |
200 | return 10 + c - 'A'; |
200 | return 10 + c - 'A'; |
201 | else if (c >= '0' && c <= '9') |
201 | else if (c >= '0' && c <= '9') |
202 | return c - '0'; |
202 | return c - '0'; |
203 | else |
203 | else |
204 | return -1; |
204 | return -1; |
205 | } |
205 | } |
206 | |
206 | |
207 | char *convert_query_hexchar(char *txt) |
207 | char *convert_query_hexchar(char *txt) |
208 | { |
208 | { |
209 | int d1, d2; |
209 | int d1, d2; |
210 | if (strlen(txt) < 3) { |
210 | if (strlen(txt) < 3) { |
211 | *txt = '\0'; |
211 | *txt = '\0'; |
212 | return txt-1; |
212 | return txt-1; |
213 | } |
213 | } |
214 | d1 = hextoint(*(txt+1)); |
214 | d1 = hextoint(*(txt+1)); |
215 | d2 = hextoint(*(txt+2)); |
215 | d2 = hextoint(*(txt+2)); |
216 | if (d1<0 || d2<0) { |
216 | if (d1<0 || d2<0) { |
217 | strcpy(txt, txt+3); |
217 | strcpy(txt, txt+3); |
218 | return txt-1; |
218 | return txt-1; |
219 | } else { |
219 | } else { |
220 | *txt = d1 * 16 + d2; |
220 | *txt = d1 * 16 + d2; |
221 | strcpy(txt+1, txt+3); |
221 | strcpy(txt+1, txt+3); |
222 | return txt; |
222 | return txt; |
223 | } |
223 | } |
224 | } |
224 | } |
225 | |
225 | |
226 | int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value)) |
226 | int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value)) |
227 | { |
227 | { |
228 | char *t, *value = NULL, c; |
228 | char *t, *value = NULL, c; |
229 | |
229 | |
230 | if (!txt) |
230 | if (!txt) |
231 | return 0; |
231 | return 0; |
232 | |
232 | |
233 | t = txt = strdup(txt); |
233 | t = txt = strdup(txt); |
234 | if (t == NULL) { |
234 | if (t == NULL) { |
235 | printf("Out of memory\n"); |
235 | printf("Out of memory\n"); |
236 | exit(1); |
236 | exit(1); |
237 | } |
237 | } |
238 | while((c=*t) != '\0') { |
238 | while((c=*t) != '\0') { |
239 | if (c=='=') { |
239 | if (c=='=') { |
240 | *t = '\0'; |
240 | *t = '\0'; |
241 | value = t+1; |
241 | value = t+1; |
242 | } else if (c=='+') { |
242 | } else if (c=='+') { |
243 | *t = ' '; |
243 | *t = ' '; |
244 | } else if (c=='%') { |
244 | } else if (c=='%') { |
245 | t = convert_query_hexchar(t); |
245 | t = convert_query_hexchar(t); |
246 | } else if (c=='&') { |
246 | } else if (c=='&') { |
247 | *t = '\0'; |
247 | *t = '\0'; |
248 | (*fn)(txt, value); |
248 | (*fn)(txt, value); |
249 | txt = t+1; |
249 | txt = t+1; |
250 | value = NULL; |
250 | value = NULL; |
251 | } |
251 | } |
252 | t++; |
252 | t++; |
253 | } |
253 | } |
254 | if (t!=txt) |
254 | if (t!=txt) |
255 | (*fn)(txt, value); |
255 | (*fn)(txt, value); |
256 | return 0; |
256 | return 0; |
257 | } |
257 | } |
|
|
diff --git a/html.h b/html.h index 49462a2..3c32935 100644 --- a/ html.h+++ b/ html.h |
|
@@ -1,22 +1,22 @@ |
1 | #ifndef HTML_H |
1 | #ifndef HTML_H |
2 | #define HTML_H |
2 | #define HTML_H |
3 | |
3 | |
4 | extern int htmlfd; |
4 | extern int htmlfd; |
5 | |
5 | |
6 | extern void html_raw(const char *txt, size_t size); |
6 | extern void html_raw(const char *txt, size_t size); |
7 | extern void html(const char *txt); |
7 | extern void html(const char *txt); |
8 | extern void htmlf(const char *format,...); |
8 | extern void htmlf(const char *format,...); |
9 | extern void html_status(int code, int more_headers); |
9 | extern void html_status(int code, const char *msg, int more_headers); |
10 | extern void html_txt(char *txt); |
10 | extern void html_txt(char *txt); |
11 | extern void html_ntxt(int len, char *txt); |
11 | extern void html_ntxt(int len, char *txt); |
12 | extern void html_attr(char *txt); |
12 | extern void html_attr(char *txt); |
13 | extern void html_hidden(char *name, char *value); |
13 | extern void html_hidden(char *name, char *value); |
14 | extern void html_option(char *value, char *text, char *selected_value); |
14 | extern void html_option(char *value, char *text, char *selected_value); |
15 | extern void html_link_open(char *url, char *title, char *class); |
15 | extern void html_link_open(char *url, char *title, char *class); |
16 | extern void html_link_close(void); |
16 | extern void html_link_close(void); |
17 | extern void html_fileperm(unsigned short mode); |
17 | extern void html_fileperm(unsigned short mode); |
18 | extern int html_include(const char *filename); |
18 | extern int html_include(const char *filename); |
19 | |
19 | |
20 | extern int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value)); |
20 | extern int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value)); |
21 | |
21 | |
22 | #endif /* HTML_H */ |
22 | #endif /* HTML_H */ |
|
|
|
|
@@ -1,104 +1,102 @@ |
1 | /* ui-clone.c: functions for http cloning, based on |
1 | /* ui-clone.c: functions for http cloning, based on |
2 | * git's http-backend.c by Shawn O. Pearce |
2 | * git's http-backend.c by Shawn O. Pearce |
3 | * |
3 | * |
4 | * Copyright (C) 2008 Lars Hjemli |
4 | * Copyright (C) 2008 Lars Hjemli |
5 | * |
5 | * |
6 | * Licensed under GNU General Public License v2 |
6 | * Licensed under GNU General Public License v2 |
7 | * (see COPYING for full license text) |
7 | * (see COPYING for full license text) |
8 | */ |
8 | */ |
9 | |
9 | |
10 | #include "cgit.h" |
10 | #include "cgit.h" |
11 | #include "html.h" |
11 | #include "html.h" |
12 | #include "ui-shared.h" |
12 | #include "ui-shared.h" |
13 | |
13 | |
14 | static int print_ref_info(const char *refname, const unsigned char *sha1, |
14 | static int print_ref_info(const char *refname, const unsigned char *sha1, |
15 | int flags, void *cb_data) |
15 | int flags, void *cb_data) |
16 | { |
16 | { |
17 | struct object *obj; |
17 | struct object *obj; |
18 | |
18 | |
19 | if (!(obj = parse_object(sha1))) |
19 | if (!(obj = parse_object(sha1))) |
20 | return 0; |
20 | return 0; |
21 | |
21 | |
22 | if (!strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/")) |
22 | if (!strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/")) |
23 | htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); |
23 | htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); |
24 | else if (!prefixcmp(refname, "refs/tags") && obj->type == OBJ_TAG) { |
24 | else if (!prefixcmp(refname, "refs/tags") && obj->type == OBJ_TAG) { |
25 | if (!(obj = deref_tag(obj, refname, 0))) |
25 | if (!(obj = deref_tag(obj, refname, 0))) |
26 | return 0; |
26 | return 0; |
27 | htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); |
27 | htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); |
28 | htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname); |
28 | htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname); |
29 | } |
29 | } |
30 | return 0; |
30 | return 0; |
31 | } |
31 | } |
32 | |
32 | |
33 | static void print_pack_info(struct cgit_context *ctx) |
33 | static void print_pack_info(struct cgit_context *ctx) |
34 | { |
34 | { |
35 | struct packed_git *pack; |
35 | struct packed_git *pack; |
36 | int ofs; |
36 | int ofs; |
37 | |
37 | |
38 | ctx->page.mimetype = "text/plain"; |
38 | ctx->page.mimetype = "text/plain"; |
39 | ctx->page.filename = "objects/info/packs"; |
39 | ctx->page.filename = "objects/info/packs"; |
40 | cgit_print_http_headers(ctx); |
40 | cgit_print_http_headers(ctx); |
41 | ofs = strlen(ctx->repo->path) + strlen("/objects/pack/"); |
41 | ofs = strlen(ctx->repo->path) + strlen("/objects/pack/"); |
42 | prepare_packed_git(); |
42 | prepare_packed_git(); |
43 | for (pack = packed_git; pack; pack = pack->next) |
43 | for (pack = packed_git; pack; pack = pack->next) |
44 | if (pack->pack_local) |
44 | if (pack->pack_local) |
45 | htmlf("P %s\n", pack->pack_name + ofs); |
45 | htmlf("P %s\n", pack->pack_name + ofs); |
46 | } |
46 | } |
47 | |
47 | |
48 | static void send_file(struct cgit_context *ctx, char *path) |
48 | static void send_file(struct cgit_context *ctx, char *path) |
49 | { |
49 | { |
50 | struct stat st; |
50 | struct stat st; |
51 | int err; |
| |
52 | |
51 | |
53 | if (stat(path, &st)) { |
52 | if (stat(path, &st)) { |
54 | switch (errno) { |
53 | switch (errno) { |
55 | case ENOENT: |
54 | case ENOENT: |
56 | err = 404; |
55 | html_status(404, "Not found", 0); |
57 | break; |
56 | break; |
58 | case EACCES: |
57 | case EACCES: |
59 | err = 403; |
58 | html_status(403, "Forbidden", 0); |
60 | break; |
59 | break; |
61 | default: |
60 | default: |
62 | err = 400; |
61 | html_status(400, "Bad request", 0); |
63 | } |
62 | } |
64 | html_status(err, 0); |
| |
65 | return; |
63 | return; |
66 | } |
64 | } |
67 | ctx->page.mimetype = "application/octet-stream"; |
65 | ctx->page.mimetype = "application/octet-stream"; |
68 | ctx->page.filename = path; |
66 | ctx->page.filename = path; |
69 | if (prefixcmp(ctx->repo->path, path)) |
67 | if (prefixcmp(ctx->repo->path, path)) |
70 | ctx->page.filename += strlen(ctx->repo->path) + 1; |
68 | ctx->page.filename += strlen(ctx->repo->path) + 1; |
71 | cgit_print_http_headers(ctx); |
69 | cgit_print_http_headers(ctx); |
72 | html_include(path); |
70 | html_include(path); |
73 | } |
71 | } |
74 | |
72 | |
75 | void cgit_clone_info(struct cgit_context *ctx) |
73 | void cgit_clone_info(struct cgit_context *ctx) |
76 | { |
74 | { |
77 | if (!ctx->qry.path || strcmp(ctx->qry.path, "refs")) |
75 | if (!ctx->qry.path || strcmp(ctx->qry.path, "refs")) |
78 | return; |
76 | return; |
79 | |
77 | |
80 | ctx->page.mimetype = "text/plain"; |
78 | ctx->page.mimetype = "text/plain"; |
81 | ctx->page.filename = "info/refs"; |
79 | ctx->page.filename = "info/refs"; |
82 | cgit_print_http_headers(ctx); |
80 | cgit_print_http_headers(ctx); |
83 | for_each_ref(print_ref_info, ctx); |
81 | for_each_ref(print_ref_info, ctx); |
84 | } |
82 | } |
85 | |
83 | |
86 | void cgit_clone_objects(struct cgit_context *ctx) |
84 | void cgit_clone_objects(struct cgit_context *ctx) |
87 | { |
85 | { |
88 | if (!ctx->qry.path) { |
86 | if (!ctx->qry.path) { |
89 | html_status(400, 0); |
87 | html_status(400, "Bad request", 0); |
90 | return; |
88 | return; |
91 | } |
89 | } |
92 | |
90 | |
93 | if (!strcmp(ctx->qry.path, "info/packs")) { |
91 | if (!strcmp(ctx->qry.path, "info/packs")) { |
94 | print_pack_info(ctx); |
92 | print_pack_info(ctx); |
95 | return; |
93 | return; |
96 | } |
94 | } |
97 | |
95 | |
98 | send_file(ctx, git_path("objects/%s", ctx->qry.path)); |
96 | send_file(ctx, git_path("objects/%s", ctx->qry.path)); |
99 | } |
97 | } |
100 | |
98 | |
101 | void cgit_clone_head(struct cgit_context *ctx) |
99 | void cgit_clone_head(struct cgit_context *ctx) |
102 | { |
100 | { |
103 | send_file(ctx, git_path("%s", "HEAD")); |
101 | send_file(ctx, git_path("%s", "HEAD")); |
104 | } |
102 | } |
|
|
|
|
@@ -1,82 +1,82 @@ |
1 | /* ui-plain.c: functions for output of plain blobs by path |
1 | /* ui-plain.c: functions for output of plain blobs by path |
2 | * |
2 | * |
3 | * Copyright (C) 2008 Lars Hjemli |
3 | * Copyright (C) 2008 Lars Hjemli |
4 | * |
4 | * |
5 | * Licensed under GNU General Public License v2 |
5 | * Licensed under GNU General Public License v2 |
6 | * (see COPYING for full license text) |
6 | * (see COPYING for full license text) |
7 | */ |
7 | */ |
8 | |
8 | |
9 | #include "cgit.h" |
9 | #include "cgit.h" |
10 | #include "html.h" |
10 | #include "html.h" |
11 | #include "ui-shared.h" |
11 | #include "ui-shared.h" |
12 | |
12 | |
13 | char *curr_rev; |
13 | char *curr_rev; |
14 | char *match_path; |
14 | char *match_path; |
15 | int match; |
15 | int match; |
16 | |
16 | |
17 | static void print_object(const unsigned char *sha1, const char *path) |
17 | static void print_object(const unsigned char *sha1, const char *path) |
18 | { |
18 | { |
19 | enum object_type type; |
19 | enum object_type type; |
20 | char *buf; |
20 | char *buf; |
21 | size_t size; |
21 | size_t size; |
22 | |
22 | |
23 | type = sha1_object_info(sha1, &size); |
23 | type = sha1_object_info(sha1, &size); |
24 | if (type == OBJ_BAD) { |
24 | if (type == OBJ_BAD) { |
25 | html_status(404, 0); |
25 | html_status(404, "Not found", 0); |
26 | return; |
26 | return; |
27 | } |
27 | } |
28 | |
28 | |
29 | buf = read_sha1_file(sha1, &type, &size); |
29 | buf = read_sha1_file(sha1, &type, &size); |
30 | if (!buf) { |
30 | if (!buf) { |
31 | html_status(404, 0); |
31 | html_status(404, "Not found", 0); |
32 | return; |
32 | return; |
33 | } |
33 | } |
34 | ctx.page.mimetype = "text/plain"; |
34 | ctx.page.mimetype = "text/plain"; |
35 | ctx.page.filename = fmt("%s", path); |
35 | ctx.page.filename = fmt("%s", path); |
36 | ctx.page.size = size; |
36 | ctx.page.size = size; |
37 | cgit_print_http_headers(&ctx); |
37 | cgit_print_http_headers(&ctx); |
38 | html_raw(buf, size); |
38 | html_raw(buf, size); |
39 | match = 1; |
39 | match = 1; |
40 | } |
40 | } |
41 | |
41 | |
42 | static int walk_tree(const unsigned char *sha1, const char *base, int baselen, |
42 | static int walk_tree(const unsigned char *sha1, const char *base, int baselen, |
43 | const char *pathname, unsigned mode, int stage, |
43 | const char *pathname, unsigned mode, int stage, |
44 | void *cbdata) |
44 | void *cbdata) |
45 | { |
45 | { |
46 | fprintf(stderr, "[cgit] walk_tree.pathname=%s", pathname); |
46 | fprintf(stderr, "[cgit] walk_tree.pathname=%s", pathname); |
47 | |
47 | |
48 | if (!pathname || strcmp(match_path, pathname)) |
48 | if (!pathname || strcmp(match_path, pathname)) |
49 | return READ_TREE_RECURSIVE; |
49 | return READ_TREE_RECURSIVE; |
50 | |
50 | |
51 | if (S_ISREG(mode)) |
51 | if (S_ISREG(mode)) |
52 | print_object(sha1, pathname); |
52 | print_object(sha1, pathname); |
53 | |
53 | |
54 | return 0; |
54 | return 0; |
55 | } |
55 | } |
56 | |
56 | |
57 | void cgit_print_plain(struct cgit_context *ctx) |
57 | void cgit_print_plain(struct cgit_context *ctx) |
58 | { |
58 | { |
59 | const char *rev = ctx->qry.sha1; |
59 | const char *rev = ctx->qry.sha1; |
60 | unsigned char sha1[20]; |
60 | unsigned char sha1[20]; |
61 | struct commit *commit; |
61 | struct commit *commit; |
62 | const char *paths[] = {ctx->qry.path, NULL}; |
62 | const char *paths[] = {ctx->qry.path, NULL}; |
63 | |
63 | |
64 | if (!rev) |
64 | if (!rev) |
65 | rev = ctx->qry.head; |
65 | rev = ctx->qry.head; |
66 | |
66 | |
67 | curr_rev = xstrdup(rev); |
67 | curr_rev = xstrdup(rev); |
68 | if (get_sha1(rev, sha1)) { |
68 | if (get_sha1(rev, sha1)) { |
69 | html_status(404, 0); |
69 | html_status(404, "Not found", 0); |
70 | return; |
70 | return; |
71 | } |
71 | } |
72 | commit = lookup_commit_reference(sha1); |
72 | commit = lookup_commit_reference(sha1); |
73 | if (!commit || parse_commit(commit)) { |
73 | if (!commit || parse_commit(commit)) { |
74 | html_status(404, 0); |
74 | html_status(404, "Not found", 0); |
75 | return; |
75 | return; |
76 | } |
76 | } |
77 | match_path = ctx->qry.path; |
77 | match_path = ctx->qry.path; |
78 | fprintf(stderr, "[cgit] match_path=%s", match_path); |
78 | fprintf(stderr, "[cgit] match_path=%s", match_path); |
79 | read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL); |
79 | read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL); |
80 | if (!match) |
80 | if (!match) |
81 | html_status(404, 0); |
81 | html_status(404, "Not found", 0); |
82 | } |
82 | } |
|