-
Notifications
You must be signed in to change notification settings - Fork 0
/
builtin-upload-tar.c
74 lines (66 loc) · 1.59 KB
/
builtin-upload-tar.c
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
/*
* Copyright (c) 2006 Junio C Hamano
*/
#include "cache.h"
#include "pkt-line.h"
#include "exec_cmd.h"
#include "builtin.h"
static const char upload_tar_usage[] = "git-upload-tar <repo>";
static int nak(const char *reason)
{
packet_write(1, "NACK %s\n", reason);
packet_flush(1);
return 1;
}
int cmd_upload_tar(int argc, const char **argv, char **envp)
{
int len;
const char *dir = argv[1];
char buf[8192];
unsigned char sha1[20];
char *base = NULL;
char hex[41];
int ac;
const char *av[4];
if (argc != 2)
usage(upload_tar_usage);
if (strlen(dir) < sizeof(buf)-1)
strcpy(buf, dir); /* enter-repo smudges its argument */
else
packet_write(1, "NACK insanely long repository name %s\n", dir);
if (!enter_repo(buf, 0)) {
packet_write(1, "NACK not a git archive %s\n", dir);
packet_flush(1);
return 1;
}
len = packet_read_line(0, buf, sizeof(buf));
if (len < 5 || strncmp("want ", buf, 5))
return nak("expected want");
if (buf[len-1] == '\n')
buf[--len] = 0;
if (get_sha1(buf + 5, sha1))
return nak("expected sha1");
strcpy(hex, sha1_to_hex(sha1));
len = packet_read_line(0, buf, sizeof(buf));
if (len) {
if (len < 5 || strncmp("base ", buf, 5))
return nak("expected (optional) base");
if (buf[len-1] == '\n')
buf[--len] = 0;
base = strdup(buf + 5);
len = packet_read_line(0, buf, sizeof(buf));
}
if (len)
return nak("expected flush");
packet_write(1, "ACK\n");
packet_flush(1);
ac = 0;
av[ac++] = "tar-tree";
av[ac++] = hex;
if (base)
av[ac++] = base;
av[ac++] = NULL;
execv_git_cmd(av);
/* should it return that is an error */
return 1;
}