Merge branch 'eb/mailinfo' into next
[git] / builtin-upload-tar.c
1 /*
2  * Copyright (c) 2006 Junio C Hamano
3  */
4 #include "cache.h"
5 #include "pkt-line.h"
6 #include "exec_cmd.h"
7 #include "builtin.h"
8
9 static const char upload_tar_usage[] = "git-upload-tar <repo>";
10
11 static int nak(const char *reason)
12 {
13         packet_write(1, "NACK %s\n", reason);
14         packet_flush(1);
15         return 1;
16 }
17
18 int cmd_upload_tar(int argc, const char **argv, char **envp)
19 {
20         int len;
21         const char *dir = argv[1];
22         char buf[8192];
23         unsigned char sha1[20];
24         char *base = NULL;
25         char hex[41];
26         int ac;
27         const char *av[4];
28
29         if (argc != 2)
30                 usage(upload_tar_usage);
31         if (strlen(dir) < sizeof(buf)-1)
32                 strcpy(buf, dir); /* enter-repo smudges its argument */
33         else
34                 packet_write(1, "NACK insanely long repository name %s\n", dir);
35         if (!enter_repo(buf, 0)) {
36                 packet_write(1, "NACK not a git archive %s\n", dir);
37                 packet_flush(1);
38                 return 1;
39         }
40
41         len = packet_read_line(0, buf, sizeof(buf));
42         if (len < 5 || strncmp("want ", buf, 5))
43                 return nak("expected want");
44         if (buf[len-1] == '\n')
45                 buf[--len] = 0;
46         if (get_sha1(buf + 5, sha1))
47                 return nak("expected sha1");
48         strcpy(hex, sha1_to_hex(sha1));
49
50         len = packet_read_line(0, buf, sizeof(buf));
51         if (len) {
52                 if (len < 5 || strncmp("base ", buf, 5))
53                         return nak("expected (optional) base");
54                 if (buf[len-1] == '\n')
55                         buf[--len] = 0;
56                 base = strdup(buf + 5);
57                 len = packet_read_line(0, buf, sizeof(buf));
58         }
59         if (len)
60                 return nak("expected flush");
61
62         packet_write(1, "ACK\n");
63         packet_flush(1);
64
65         ac = 0;
66         av[ac++] = "tar-tree";
67         av[ac++] = hex;
68         if (base)
69                 av[ac++] = base;
70         av[ac++] = NULL;
71         execv_git_cmd(av);
72         /* should it return that is an error */
73         return 1;
74 }