all repos — cgit @ 4458abf64172a62b92810c2293450106e6dfc763

a hyperfast web frontend for git written in c

ui-clone.c (view raw)

  1/* ui-clone.c: functions for http cloning, based on
  2 * git's http-backend.c by Shawn O. Pearce
  3 *
  4 * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
  5 *
  6 * Licensed under GNU General Public License v2
  7 *   (see COPYING for full license text)
  8 */
  9
 10#include "cgit.h"
 11#include "ui-clone.h"
 12#include "html.h"
 13#include "ui-shared.h"
 14
 15static int print_ref_info(const char *refname, const struct object_id *oid,
 16                          int flags, void *cb_data)
 17{
 18	struct object *obj;
 19
 20	if (!(obj = parse_object(oid->hash)))
 21		return 0;
 22
 23	htmlf("%s\t%s\n", oid_to_hex(oid), refname);
 24	if (obj->type == OBJ_TAG) {
 25		if (!(obj = deref_tag(obj, refname, 0)))
 26			return 0;
 27		htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname);
 28	}
 29	return 0;
 30}
 31
 32static void print_pack_info(void)
 33{
 34	struct packed_git *pack;
 35	char *offset;
 36
 37	ctx.page.mimetype = "text/plain";
 38	ctx.page.filename = "objects/info/packs";
 39	cgit_print_http_headers();
 40	prepare_packed_git();
 41	for (pack = packed_git; pack; pack = pack->next) {
 42		if (pack->pack_local) {
 43			offset = strrchr(pack->pack_name, '/');
 44			if (offset && offset[1] != '\0')
 45				++offset;
 46			else
 47				offset = pack->pack_name;
 48			htmlf("P %s\n", offset);
 49		}
 50	}
 51}
 52
 53static void send_file(const char *path)
 54{
 55	struct stat st;
 56
 57	if (stat(path, &st)) {
 58		switch (errno) {
 59		case ENOENT:
 60			cgit_print_error_page(404, "Not found", "Not found");
 61			break;
 62		case EACCES:
 63			cgit_print_error_page(403, "Forbidden", "Forbidden");
 64			break;
 65		default:
 66			cgit_print_error_page(400, "Bad request", "Bad request");
 67		}
 68		return;
 69	}
 70	ctx.page.mimetype = "application/octet-stream";
 71	ctx.page.filename = path;
 72	skip_prefix(path, ctx.repo->path, &ctx.page.filename);
 73	skip_prefix(ctx.page.filename, "/", &ctx.page.filename);
 74	cgit_print_http_headers();
 75	html_include(path);
 76}
 77
 78void cgit_clone_info(void)
 79{
 80	if (!ctx.qry.path || strcmp(ctx.qry.path, "refs")) {
 81		cgit_print_error_page(400, "Bad request", "Bad request");
 82		return;
 83	}
 84
 85	ctx.page.mimetype = "text/plain";
 86	ctx.page.filename = "info/refs";
 87	cgit_print_http_headers();
 88	for_each_ref(print_ref_info, NULL);
 89}
 90
 91void cgit_clone_objects(void)
 92{
 93	if (!ctx.qry.path) {
 94		cgit_print_error_page(400, "Bad request", "Bad request");
 95		return;
 96	}
 97
 98	if (!strcmp(ctx.qry.path, "info/packs")) {
 99		print_pack_info();
100		return;
101	}
102
103	send_file(git_path("objects/%s", ctx.qry.path));
104}
105
106void cgit_clone_head(void)
107{
108	send_file(git_path("%s", "HEAD"));
109}