all repos — cgit @ c1572bb5ec4540b5008490cf471cc4a5e65ef728

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#include "packfile.h"
 15
 16static int print_ref_info(const char *refname, const struct object_id *oid,
 17                          int flags, void *cb_data)
 18{
 19	struct object *obj;
 20
 21	if (!(obj = parse_object(oid)))
 22		return 0;
 23
 24	htmlf("%s\t%s\n", oid_to_hex(oid), refname);
 25	if (obj->type == OBJ_TAG) {
 26		if (!(obj = deref_tag(obj, refname, 0)))
 27			return 0;
 28		htmlf("%s\t%s^{}\n", oid_to_hex(&obj->oid), refname);
 29	}
 30	return 0;
 31}
 32
 33static void print_pack_info(void)
 34{
 35	struct packed_git *pack;
 36	char *offset;
 37
 38	ctx.page.mimetype = "text/plain";
 39	ctx.page.filename = "objects/info/packs";
 40	cgit_print_http_headers();
 41	prepare_packed_git();
 42	for (pack = packed_git; pack; pack = pack->next) {
 43		if (pack->pack_local) {
 44			offset = strrchr(pack->pack_name, '/');
 45			if (offset && offset[1] != '\0')
 46				++offset;
 47			else
 48				offset = pack->pack_name;
 49			htmlf("P %s\n", offset);
 50		}
 51	}
 52}
 53
 54static void send_file(const char *path)
 55{
 56	struct stat st;
 57
 58	if (stat(path, &st)) {
 59		switch (errno) {
 60		case ENOENT:
 61			cgit_print_error_page(404, "Not found", "Not found");
 62			break;
 63		case EACCES:
 64			cgit_print_error_page(403, "Forbidden", "Forbidden");
 65			break;
 66		default:
 67			cgit_print_error_page(400, "Bad request", "Bad request");
 68		}
 69		return;
 70	}
 71	ctx.page.mimetype = "application/octet-stream";
 72	ctx.page.filename = path;
 73	skip_prefix(path, ctx.repo->path, &ctx.page.filename);
 74	skip_prefix(ctx.page.filename, "/", &ctx.page.filename);
 75	cgit_print_http_headers();
 76	html_include(path);
 77}
 78
 79void cgit_clone_info(void)
 80{
 81	if (!ctx.qry.path || strcmp(ctx.qry.path, "refs")) {
 82		cgit_print_error_page(400, "Bad request", "Bad request");
 83		return;
 84	}
 85
 86	ctx.page.mimetype = "text/plain";
 87	ctx.page.filename = "info/refs";
 88	cgit_print_http_headers();
 89	for_each_ref(print_ref_info, NULL);
 90}
 91
 92void cgit_clone_objects(void)
 93{
 94	if (!ctx.qry.path) {
 95		cgit_print_error_page(400, "Bad request", "Bad request");
 96		return;
 97	}
 98
 99	if (!strcmp(ctx.qry.path, "info/packs")) {
100		print_pack_info();
101		return;
102	}
103
104	send_file(git_path("objects/%s", ctx.qry.path));
105}
106
107void cgit_clone_head(void)
108{
109	send_file(git_path("%s", "HEAD"));
110}