diff options
| author | Lars Hjemli <hjemli@gmail.com> | 2008-09-01 22:40:24 +0200 | 
|---|---|---|
| committer | Lars Hjemli <hjemli@gmail.com> | 2008-09-01 22:40:24 +0200 | 
| commit | 288d502b3d8e7fa916104b486bbb146521e5c716 (patch) | |
| tree | afa132f6c973ab30e0b8ed1201fb691fe91103c0 | |
| parent | 2cecf839a06ce951db0d5d95abf79004eff33ca7 (diff) | |
| parent | 02a545e63454530c1639014d3239c14ced2022c6 (diff) | |
| download | cgit-288d502b3d8e7fa916104b486bbb146521e5c716.tar.gz cgit-288d502b3d8e7fa916104b486bbb146521e5c716.tar.bz2 | |
Merge branch 'lh/clone'
* lh/clone:
  Add support for cloning over http
Conflicts:
	cmd.c
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | cmd.c | 19 | ||||
| -rw-r--r-- | html.c | 7 | ||||
| -rw-r--r-- | html.h | 1 | ||||
| -rw-r--r-- | ui-clone.c | 104 | ||||
| -rw-r--r-- | ui-clone.h | 8 | 
6 files changed, 140 insertions, 0 deletions
| @@ -57,6 +57,7 @@ OBJECTS += parsing.o  OBJECTS += shared.o  OBJECTS += ui-atom.o  OBJECTS += ui-blob.o +OBJECTS += ui-clone.o  OBJECTS += ui-commit.o  OBJECTS += ui-diff.o  OBJECTS += ui-log.o @@ -12,6 +12,7 @@  #include "ui-shared.h"  #include "ui-atom.h"  #include "ui-blob.h" +#include "ui-clone.h"  #include "ui-commit.h"  #include "ui-diff.h"  #include "ui-log.h" @@ -23,6 +24,11 @@  #include "ui-tag.h"  #include "ui-tree.h" +static void HEAD_fn(struct cgit_context *ctx) +{ +	cgit_clone_head(ctx); +} +  static void atom_fn(struct cgit_context *ctx)  {  	cgit_print_atom(ctx->qry.head, ctx->qry.path, 10); @@ -51,6 +57,11 @@ static void diff_fn(struct cgit_context *ctx)  	cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path);  } +static void info_fn(struct cgit_context *ctx) +{ +	cgit_clone_info(ctx); +} +  static void log_fn(struct cgit_context *ctx)  {  	cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, @@ -65,6 +76,11 @@ static void ls_cache_fn(struct cgit_context *ctx)  	cache_ls(ctx->cfg.cache_root);  } +static void objects_fn(struct cgit_context *ctx) +{ +	cgit_clone_objects(ctx); +} +  static void repolist_fn(struct cgit_context *ctx)  {  	cgit_print_repolist(); @@ -108,13 +124,16 @@ static void tree_fn(struct cgit_context *ctx)  struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)  {  	static struct cgit_cmd cmds[] = { +		def_cmd(HEAD, 1, 0),  		def_cmd(atom, 1, 0),  		def_cmd(about, 0, 1),  		def_cmd(blob, 1, 0),  		def_cmd(commit, 1, 1),  		def_cmd(diff, 1, 1), +		def_cmd(info, 1, 0),  		def_cmd(log, 1, 1),  		def_cmd(ls_cache, 0, 0), +		def_cmd(objects, 1, 0),  		def_cmd(patch, 1, 0),  		def_cmd(refs, 1, 1),  		def_cmd(repolist, 0, 0), @@ -51,6 +51,13 @@ void htmlf(const char *format, ...)  	html(buf);  } +void html_status(int code, int more_headers) +{ +	htmlf("Status: %d\n", code); +	if (!more_headers) +		html("\n"); +} +  void html_txt(char *txt)  {  	char *t = txt; @@ -5,6 +5,7 @@ extern int htmlfd;  extern void html(const char *txt);  extern void htmlf(const char *format,...); +extern void html_status(int code, int more_headers);  extern void html_txt(char *txt);  extern void html_ntxt(int len, char *txt);  extern void html_attr(char *txt); diff --git a/ui-clone.c b/ui-clone.c new file mode 100644 index 0000000..3a037ad --- /dev/null +++ b/ui-clone.c @@ -0,0 +1,104 @@ +/* ui-clone.c: functions for http cloning, based on + * git's http-backend.c by Shawn O. Pearce + * + * 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" + +static int print_ref_info(const char *refname, const unsigned char *sha1, +                          int flags, void *cb_data) +{ +	struct object *obj; + +	if (!(obj = parse_object(sha1))) +		return 0; + +	if (!strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/")) +		htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); +	else if (!prefixcmp(refname, "refs/tags") && obj->type == OBJ_TAG) { +		if (!(obj = deref_tag(obj, refname, 0))) +			return 0; +		htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); +		htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname); +	} +	return 0; +} + +static void print_pack_info(struct cgit_context *ctx) +{ +	struct packed_git *pack; +	int ofs; + +	ctx->page.mimetype = "text/plain"; +	ctx->page.filename = "objects/info/packs"; +	cgit_print_http_headers(ctx); +	ofs = strlen(ctx->repo->path) + strlen("/objects/pack/"); +	prepare_packed_git(); +	for (pack = packed_git; pack; pack = pack->next) +		if (pack->pack_local) +			htmlf("P %s\n", pack->pack_name + ofs); +} + +static void send_file(struct cgit_context *ctx, char *path) +{ +	struct stat st; +	int err; + +	if (stat(path, &st)) { +		switch (errno) { +		case ENOENT: +			err = 404; +			break; +		case EACCES: +			err = 403; +			break; +		default: +			err = 400; +		} +		html_status(err, 0); +		return; +	} +	ctx->page.mimetype = "application/octet-stream"; +	ctx->page.filename = path; +	if (prefixcmp(ctx->repo->path, path)) +		ctx->page.filename += strlen(ctx->repo->path) + 1; +	cgit_print_http_headers(ctx); +	html_include(path); +} + +void cgit_clone_info(struct cgit_context *ctx) +{ +	if (!ctx->qry.path || strcmp(ctx->qry.path, "refs")) +		return; + +	ctx->page.mimetype = "text/plain"; +	ctx->page.filename = "info/refs"; +	cgit_print_http_headers(ctx); +	for_each_ref(print_ref_info, ctx); +} + +void cgit_clone_objects(struct cgit_context *ctx) +{ +	if (!ctx->qry.path) { +		html_status(400, 0); +		return; +	} + +	if (!strcmp(ctx->qry.path, "info/packs")) { +		print_pack_info(ctx); +		return; +	} + +	send_file(ctx, git_path("objects/%s", ctx->qry.path)); +} + +void cgit_clone_head(struct cgit_context *ctx) +{ +	send_file(ctx, git_path("%s", "HEAD")); +} diff --git a/ui-clone.h b/ui-clone.h new file mode 100644 index 0000000..89cd4f1 --- /dev/null +++ b/ui-clone.h @@ -0,0 +1,8 @@ +#ifndef UI_CLONE_H +#define UI_CLONE_H + +void cgit_clone_info(struct cgit_context *ctx); +void cgit_clone_objects(struct cgit_context *ctx); +void cgit_clone_head(struct cgit_context *ctx); + +#endif /* UI_CLONE_H */ | 
