summaryrefslogtreecommitdiffstatshomepage
path: root/ui-plain.c
blob: 5addd9e686539ca41f264394ecf6836aa739af4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* ui-plain.c: functions for output of plain blobs by path
 *
 * Copyright (C) 2008 Lars Hjemli
 *
 * Licensed under GNU General Public License v2
 *   (see COPYING for full license text)
 */

#include "cgit.h"
#include "html.h"
#include "ui-shared.h"

char *curr_rev;
char *match_path;
int match;

static void print_object(const unsigned char *sha1, const char *path)
{
	enum object_type type;
	char *buf;
	unsigned long size;

	type = sha1_object_info(sha1, &size);
	if (type == OBJ_BAD) {
		html_status(404, "Not found", 0);
		return;
	}

	buf = read_sha1_file(sha1, &type, &size);
	if (!buf) {
		html_status(404, "Not found", 0);
		return;
	}
	ctx.page.mimetype = "text/plain";
	ctx.page.filename = fmt("%s", path);
	ctx.page.size = size;
	cgit_print_http_headers(&ctx);
	html_raw(buf, size);
	match = 1;
}

static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
		     const char *pathname, unsigned mode, int stage,
		     void *cbdata)
{
	if (S_ISDIR(mode))
		return READ_TREE_RECURSIVE;

	if (S_ISREG(mode))
		print_object(sha1, pathname);

	return 0;
}

void cgit_print_plain(struct cgit_context *ctx)
{
	const char *rev = ctx->qry.sha1;
	unsigned char sha1[20];
	struct commit *commit;
	const char *paths[] = {ctx->qry.path, NULL};

	if (!rev)
		rev = ctx->qry.head;

	curr_rev = xstrdup(rev);
	if (get_sha1(rev, sha1)) {
		html_status(404, "Not found", 0);
		return;
	}
	commit = lookup_commit_reference(sha1);
	if (!commit || parse_commit(commit)) {
		html_status(404, "Not found", 0);
		return;
	}
	match_path = ctx->qry.path;
	read_tree_recursive(commit->tree, NULL, 0, 0, paths, walk_tree, NULL);
	if (!match)
		html_status(404, "Not found", 0);
}
/span>, tmp, prefix); html(") ("); if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff)) cgit_commit_link("unidiff", NULL, NULL, ctx.qry.head, tmp, prefix, 1); else cgit_commit_link("side-by-side diff", NULL, NULL, ctx.qry.head, tmp, prefix, 1); html(")</td></tr>\n"); html("<tr><th>tree</th><td colspan='2' class='sha1'>"); tmp = xstrdup(hex); cgit_tree_link(sha1_to_hex(commit->tree->object.sha1), NULL, NULL, ctx.qry.head, tmp, NULL); if (prefix) { html(" /"); cgit_tree_link(prefix, NULL, NULL, ctx.qry.head, tmp, prefix); } html("</td></tr>\n"); for (p = commit->parents; p ; p = p->next) { parent = lookup_commit_reference(p->item->object.sha1); if (!parent) { html("<tr><td colspan='3'>"); cgit_print_error("Error reading parent commit"); html("</td></tr>"); continue; } html("<tr><th>parent</th>" "<td colspan='2' class='sha1'>"); tmp = tmp2 = sha1_to_hex(p->item->object.sha1); if (ctx.repo->enable_subject_links) { parent_info = cgit_parse_commit(parent); tmp2 = parent_info->subject; } cgit_commit_link(tmp2, NULL, NULL, ctx.qry.head, tmp, prefix, 0); html(" ("); cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex, sha1_to_hex(p->item->object.sha1), prefix, 0); html(")</td></tr>"); parents++; } if (ctx.repo->snapshots) { html("<tr><th>download</th><td colspan='2' class='sha1'>"); cgit_print_snapshot_links(ctx.qry.repo, ctx.qry.head, hex, ctx.repo->snapshots); html("</td></tr>"); } html("</table>\n"); html("<div class='commit-subject'>"); if (ctx.repo->commit_filter) cgit_open_filter(ctx.repo->commit_filter); html_txt(info->subject); if (ctx.repo->commit_filter) cgit_close_filter(ctx.repo->commit_filter); show_commit_decorations(commit); html("</div>"); html("<div class='commit-msg'>"); if (ctx.repo->commit_filter) cgit_open_filter(ctx.repo->commit_filter); html_txt(info->msg); if (ctx.repo->commit_filter) cgit_close_filter(ctx.repo->commit_filter); html("</div>"); if (notes.len != 0) { html("<div class='notes-header'>Notes</div>"); html("<div class='notes'>"); if (ctx.repo->commit_filter) cgit_open_filter(ctx.repo->commit_filter); html_txt(notes.buf); if (ctx.repo->commit_filter) cgit_close_filter(ctx.repo->commit_filter); html("</div>"); html("<div class='notes-footer'></div>"); } if (parents < 3) { if (parents) tmp = sha1_to_hex(commit->parents->item->object.sha1); else tmp = NULL; cgit_print_diff(ctx.qry.sha1, tmp, prefix); } strbuf_release(&notes); cgit_free_commitinfo(info); }