diff options
| author | 2008-08-06 08:20:24 (JST) | |
|---|---|---|
| committer | 2008-08-06 18:21:09 (JST) | |
| commit | 02a545e63454530c1639014d3239c14ced2022c6 (patch) | |
| tree | da4c89a94b117d936f2eeb486c9dedf192e6746e /ui-clone.c | |
| parent | 0f0ab148c6d444316af10e6b4c7a60630fed45d3 (diff) | |
| download | cgit-02a545e63454530c1639014d3239c14ced2022c6.zip cgit-02a545e63454530c1639014d3239c14ced2022c6.tar.gz | |
Add support for cloning over http
This patch implements basic support for cloning over http, based on the
work on git-http-backend by Shawn O. Pearce.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'ui-clone.c')
| -rw-r--r-- | ui-clone.c | 104 |
1 files changed, 104 insertions, 0 deletions
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 @@ | |||
| 1 | /* ui-clone.c: functions for http cloning, based on | ||
| 2 | * git's http-backend.c by Shawn O. Pearce | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Lars Hjemli | ||
| 5 | * | ||
| 6 | * Licensed under GNU General Public License v2 | ||
| 7 | * (see COPYING for full license text) | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include "cgit.h" | ||
| 11 | #include "html.h" | ||
| 12 | #include "ui-shared.h" | ||
| 13 | |||
| 14 | static int print_ref_info(const char *refname, const unsigned char *sha1, | ||
| 15 | int flags, void *cb_data) | ||
| 16 | { | ||
| 17 | struct object *obj; | ||
| 18 | |||
| 19 | if (!(obj = parse_object(sha1))) | ||
| 20 | return 0; | ||
| 21 | |||
| 22 | if (!strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/")) | ||
| 23 | htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); | ||
| 24 | else if (!prefixcmp(refname, "refs/tags") && obj->type == OBJ_TAG) { | ||
| 25 | if (!(obj = deref_tag(obj, refname, 0))) | ||
| 26 | return 0; | ||
| 27 | htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); | ||
| 28 | htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname); | ||
| 29 | } | ||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | static void print_pack_info(struct cgit_context *ctx) | ||
| 34 | { | ||
| 35 | struct packed_git *pack; | ||
| 36 | int ofs; | ||
| 37 | |||
| 38 | ctx->page.mimetype = "text/plain"; | ||
| 39 | ctx->page.filename = "objects/info/packs"; | ||
| 40 | cgit_print_http_headers(ctx); | ||
| 41 | ofs = strlen(ctx->repo->path) + strlen("/objects/pack/"); | ||
| 42 | prepare_packed_git(); | ||
| 43 | for (pack = packed_git; pack; pack = pack->next) | ||
| 44 | if (pack->pack_local) | ||
| 45 | htmlf("P %s\n", pack->pack_name + ofs); | ||
| 46 | } | ||
| 47 | |||
| 48 | static void send_file(struct cgit_context *ctx, char *path) | ||
| 49 | { | ||
| 50 | struct stat st; | ||
| 51 | int err; | ||
| 52 | |||
| 53 | if (stat(path, &st)) { | ||
| 54 | switch (errno) { | ||
| 55 | case ENOENT: | ||
| 56 | err = 404; | ||
| 57 | break; | ||
| 58 | case EACCES: | ||
| 59 | err = 403; | ||
| 60 | break; | ||
| 61 | default: | ||
| 62 | err = 400; | ||
| 63 | } | ||
| 64 | html_status(err, 0); | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | ctx->page.mimetype = "application/octet-stream"; | ||
| 68 | ctx->page.filename = path; | ||
| 69 | if (prefixcmp(ctx->repo->path, path)) | ||
| 70 | ctx->page.filename += strlen(ctx->repo->path) + 1; | ||
| 71 | cgit_print_http_headers(ctx); | ||
| 72 | html_include(path); | ||
| 73 | } | ||
| 74 | |||
| 75 | void cgit_clone_info(struct cgit_context *ctx) | ||
| 76 | { | ||
| 77 | if (!ctx->qry.path || strcmp(ctx->qry.path, "refs")) | ||
| 78 | return; | ||
| 79 | |||
| 80 | ctx->page.mimetype = "text/plain"; | ||
| 81 | ctx->page.filename = "info/refs"; | ||
| 82 | cgit_print_http_headers(ctx); | ||
| 83 | for_each_ref(print_ref_info, ctx); | ||
| 84 | } | ||
| 85 | |||
| 86 | void cgit_clone_objects(struct cgit_context *ctx) | ||
| 87 | { | ||
| 88 | if (!ctx->qry.path) { | ||
| 89 | html_status(400, 0); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | |||
| 93 | if (!strcmp(ctx->qry.path, "info/packs")) { | ||
| 94 | print_pack_info(ctx); | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | |||
| 98 | send_file(ctx, git_path("objects/%s", ctx->qry.path)); | ||
| 99 | } | ||
| 100 | |||
| 101 | void cgit_clone_head(struct cgit_context *ctx) | ||
| 102 | { | ||
| 103 | send_file(ctx, git_path("%s", "HEAD")); | ||
| 104 | } | ||
