summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2008-08-06 08:53:50 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-08-06 09:21:30 (UTC)
commite5da4bca54574522b28f88cab0dc8ebad9e35a73 (patch) (unidiff)
tree08e02b9e0962a12040faab27e7841a74a800ddf2
parent02a545e63454530c1639014d3239c14ced2022c6 (diff)
downloadcgit-e5da4bca54574522b28f88cab0dc8ebad9e35a73.zip
cgit-e5da4bca54574522b28f88cab0dc8ebad9e35a73.tar.gz
cgit-e5da4bca54574522b28f88cab0dc8ebad9e35a73.tar.bz2
Implement plain view
This implements a way to access plain blobs by path (similar to the tree view) instead of by sha1. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile1
-rw-r--r--cgit.c1
-rw-r--r--cgit.h1
-rw-r--r--cmd.c7
-rw-r--r--html.c5
-rw-r--r--html.h1
-rw-r--r--ui-plain.c82
-rw-r--r--ui-plain.h6
-rw-r--r--ui-shared.c2
9 files changed, 106 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 78aad10..a305894 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ OBJECTS += ui-commit.o
61OBJECTS += ui-diff.o 61OBJECTS += ui-diff.o
62OBJECTS += ui-log.o 62OBJECTS += ui-log.o
63OBJECTS += ui-patch.o 63OBJECTS += ui-patch.o
64OBJECTS += ui-plain.o
64OBJECTS += ui-refs.o 65OBJECTS += ui-refs.o
65OBJECTS += ui-repolist.o 66OBJECTS += ui-repolist.o
66OBJECTS += ui-shared.o 67OBJECTS += ui-shared.o
diff --git a/cgit.c b/cgit.c
index f49fffa..497337b 100644
--- a/cgit.c
+++ b/cgit.c
@@ -187,6 +187,7 @@ static void prepare_context(struct cgit_context *ctx)
187 ctx->page.mimetype = "text/html"; 187 ctx->page.mimetype = "text/html";
188 ctx->page.charset = PAGE_ENCODING; 188 ctx->page.charset = PAGE_ENCODING;
189 ctx->page.filename = NULL; 189 ctx->page.filename = NULL;
190 ctx->page.size = 0;
190 ctx->page.modified = time(NULL); 191 ctx->page.modified = time(NULL);
191 ctx->page.expires = ctx->page.modified; 192 ctx->page.expires = ctx->page.modified;
192} 193}
diff --git a/cgit.h b/cgit.h
index b01fa31..e2af0c2 100644
--- a/cgit.h
+++ b/cgit.h
@@ -165,6 +165,7 @@ struct cgit_config {
165struct cgit_page { 165struct cgit_page {
166 time_t modified; 166 time_t modified;
167 time_t expires; 167 time_t expires;
168 size_t size;
168 char *mimetype; 169 char *mimetype;
169 char *charset; 170 char *charset;
170 char *filename; 171 char *filename;
diff --git a/cmd.c b/cmd.c
index 03e165c..2b34189 100644
--- a/cmd.c
+++ b/cmd.c
@@ -16,6 +16,7 @@
16#include "ui-diff.h" 16#include "ui-diff.h"
17#include "ui-log.h" 17#include "ui-log.h"
18#include "ui-patch.h" 18#include "ui-patch.h"
19#include "ui-plain.h"
19#include "ui-refs.h" 20#include "ui-refs.h"
20#include "ui-repolist.h" 21#include "ui-repolist.h"
21#include "ui-snapshot.h" 22#include "ui-snapshot.h"
@@ -85,6 +86,11 @@ static void patch_fn(struct cgit_context *ctx)
85 cgit_print_patch(ctx->qry.sha1); 86 cgit_print_patch(ctx->qry.sha1);
86} 87}
87 88
89static void plain_fn(struct cgit_context *ctx)
90{
91 cgit_print_plain(ctx);
92}
93
88static void refs_fn(struct cgit_context *ctx) 94static void refs_fn(struct cgit_context *ctx)
89{ 95{
90 cgit_print_refs(); 96 cgit_print_refs();
@@ -128,6 +134,7 @@ struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
128 def_cmd(ls_cache, 0, 0), 134 def_cmd(ls_cache, 0, 0),
129 def_cmd(objects, 1, 0), 135 def_cmd(objects, 1, 0),
130 def_cmd(patch, 1, 0), 136 def_cmd(patch, 1, 0),
137 def_cmd(plain, 1, 0),
131 def_cmd(refs, 1, 1), 138 def_cmd(refs, 1, 1),
132 def_cmd(repolist, 0, 0), 139 def_cmd(repolist, 0, 0),
133 def_cmd(snapshot, 1, 0), 140 def_cmd(snapshot, 1, 0),
diff --git a/html.c b/html.c
index 1237076..83fc7a9 100644
--- a/html.c
+++ b/html.c
@@ -35,6 +35,11 @@ char *fmt(const char *format, ...)
35 return buf[bufidx]; 35 return buf[bufidx];
36} 36}
37 37
38void html_raw(const char *data, size_t size)
39{
40 write(htmlfd, data, size);
41}
42
38void html(const char *txt) 43void html(const char *txt)
39{ 44{
40 write(htmlfd, txt, strlen(txt)); 45 write(htmlfd, txt, strlen(txt));
diff --git a/html.h b/html.h
index 2bde28d..49462a2 100644
--- a/html.h
+++ b/html.h
@@ -3,6 +3,7 @@
3 3
4extern int htmlfd; 4extern int htmlfd;
5 5
6extern void html_raw(const char *txt, size_t size);
6extern void html(const char *txt); 7extern void html(const char *txt);
7extern void htmlf(const char *format,...); 8extern void htmlf(const char *format,...);
8extern void html_status(int code, int more_headers); 9extern void html_status(int code, int more_headers);
diff --git a/ui-plain.c b/ui-plain.c
new file mode 100644
index 0000000..28deae5
--- a/dev/null
+++ b/ui-plain.c
@@ -0,0 +1,82 @@
1/* ui-plain.c: functions for output of plain blobs by path
2 *
3 * Copyright (C) 2008 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
9#include "cgit.h"
10#include "html.h"
11#include "ui-shared.h"
12
13char *curr_rev;
14char *match_path;
15int match;
16
17static void print_object(const unsigned char *sha1, const char *path)
18{
19 enum object_type type;
20 char *buf;
21 size_t size;
22
23 type = sha1_object_info(sha1, &size);
24 if (type == OBJ_BAD) {
25 html_status(404, 0);
26 return;
27 }
28
29 buf = read_sha1_file(sha1, &type, &size);
30 if (!buf) {
31 html_status(404, 0);
32 return;
33 }
34 ctx.page.mimetype = "text/plain";
35 ctx.page.filename = fmt("%s", path);
36 ctx.page.size = size;
37 cgit_print_http_headers(&ctx);
38 html_raw(buf, size);
39 match = 1;
40}
41
42static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
43 const char *pathname, unsigned mode, int stage,
44 void *cbdata)
45{
46 fprintf(stderr, "[cgit] walk_tree.pathname=%s", pathname);
47
48 if (!pathname || strcmp(match_path, pathname))
49 return READ_TREE_RECURSIVE;
50
51 if (S_ISREG(mode))
52 print_object(sha1, pathname);
53
54 return 0;
55}
56
57void cgit_print_plain(struct cgit_context *ctx)
58{
59 const char *rev = ctx->qry.sha1;
60 unsigned char sha1[20];
61 struct commit *commit;
62 const char *paths[] = {ctx->qry.path, NULL};
63
64 if (!rev)
65 rev = ctx->qry.head;
66
67 curr_rev = xstrdup(rev);
68 if (get_sha1(rev, sha1)) {
69 html_status(404, 0);
70 return;
71 }
72 commit = lookup_commit_reference(sha1);
73 if (!commit || parse_commit(commit)) {
74 html_status(404, 0);
75 return;
76 }
77 match_path = ctx->qry.path;
78 fprintf(stderr, "[cgit] match_path=%s", match_path);
79 read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL);
80 if (!match)
81 html_status(404, 0);
82}
diff --git a/ui-plain.h b/ui-plain.h
new file mode 100644
index 0000000..4373118
--- a/dev/null
+++ b/ui-plain.h
@@ -0,0 +1,6 @@
1#ifndef UI_PLAIN_H
2#define UI_PLAIN_H
3
4extern void cgit_print_plain(struct cgit_context *ctx);
5
6#endif /* UI_PLAIN_H */
diff --git a/ui-shared.c b/ui-shared.c
index 197ee37..4408969 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -418,6 +418,8 @@ void cgit_print_http_headers(struct cgit_context *ctx)
418 ctx->page.charset); 418 ctx->page.charset);
419 else if (ctx->page.mimetype) 419 else if (ctx->page.mimetype)
420 htmlf("Content-Type: %s\n", ctx->page.mimetype); 420 htmlf("Content-Type: %s\n", ctx->page.mimetype);
421 if (ctx->page.size)
422 htmlf("Content-Length: %ld\n", ctx->page.size);
421 if (ctx->page.filename) 423 if (ctx->page.filename)
422 htmlf("Content-Disposition: inline; filename=\"%s\"\n", 424 htmlf("Content-Disposition: inline; filename=\"%s\"\n",
423 ctx->page.filename); 425 ctx->page.filename);