]>
Commit | Line | Data |
---|---|---|
92747a90 | 1 | /* |
ae64bbc1 | 2 | * Copyright (c) 2005, 2006 Rene Scharfe |
92747a90 | 3 | */ |
731ab9cc RS |
4 | #include <time.h> |
5 | #include "cache.h" | |
c3f92812 | 6 | #include "commit.h" |
ae64bbc1 | 7 | #include "tar.h" |
56d1398a | 8 | #include "builtin.h" |
21754264 | 9 | #include "pkt-line.h" |
efd8696c | 10 | #include "archive.h" |
731ab9cc RS |
11 | |
12 | #define RECORDSIZE (512) | |
13 | #define BLOCKSIZE (RECORDSIZE * 20) | |
14 | ||
21754264 | 15 | static const char tar_tree_usage[] = |
3f0073a2 | 16 | "git-tar-tree [--remote=<repo>] <tree-ish> [basedir]"; |
731ab9cc | 17 | |
a633fca0 | 18 | static int generate_tar(int argc, const char **argv, const char *prefix) |
731ab9cc | 19 | { |
87af29f0 RS |
20 | struct archiver_args args; |
21 | int result; | |
22 | char *base = NULL; | |
731ab9cc | 23 | |
87af29f0 RS |
24 | memset(&args, 0, sizeof(args)); |
25 | if (argc != 2 && argc != 3) | |
731ab9cc | 26 | usage(tar_tree_usage); |
87af29f0 RS |
27 | if (argc == 3) { |
28 | int baselen = strlen(argv[2]); | |
29 | base = xmalloc(baselen + 2); | |
30 | memcpy(base, argv[2], baselen); | |
31 | base[baselen] = '/'; | |
32 | base[baselen + 1] = '\0'; | |
731ab9cc | 33 | } |
87af29f0 RS |
34 | args.base = base; |
35 | parse_treeish_arg(argv + 1, &args, NULL); | |
731ab9cc | 36 | |
87af29f0 RS |
37 | result = write_tar_archive(&args); |
38 | free(base); | |
39 | ||
40 | return result; | |
731ab9cc | 41 | } |
21754264 JH |
42 | |
43 | static const char *exec = "git-upload-tar"; | |
44 | ||
45 | static int remote_tar(int argc, const char **argv) | |
46 | { | |
47 | int fd[2], ret, len; | |
48 | pid_t pid; | |
49 | char buf[1024]; | |
50 | char *url; | |
51 | ||
52 | if (argc < 3 || 4 < argc) | |
53 | usage(tar_tree_usage); | |
54 | ||
55 | /* --remote=<repo> */ | |
9befac47 | 56 | url = xstrdup(argv[1]+9); |
21754264 JH |
57 | pid = git_connect(fd, url, exec); |
58 | if (pid < 0) | |
59 | return 1; | |
60 | ||
61 | packet_write(fd[1], "want %s\n", argv[2]); | |
62 | if (argv[3]) | |
63 | packet_write(fd[1], "base %s\n", argv[3]); | |
64 | packet_flush(fd[1]); | |
65 | ||
66 | len = packet_read_line(fd[0], buf, sizeof(buf)); | |
67 | if (!len) | |
68 | die("git-tar-tree: expected ACK/NAK, got EOF"); | |
69 | if (buf[len-1] == '\n') | |
70 | buf[--len] = 0; | |
71 | if (strcmp(buf, "ACK")) { | |
72 | if (5 < len && !strncmp(buf, "NACK ", 5)) | |
73 | die("git-tar-tree: NACK %s", buf + 5); | |
74 | die("git-tar-tree: protocol error"); | |
75 | } | |
76 | /* expect a flush */ | |
77 | len = packet_read_line(fd[0], buf, sizeof(buf)); | |
78 | if (len) | |
79 | die("git-tar-tree: expected a flush"); | |
80 | ||
81 | /* Now, start reading from fd[0] and spit it out to stdout */ | |
82 | ret = copy_fd(fd[0], 1); | |
83 | close(fd[0]); | |
84 | ||
85 | ret |= finish_connect(pid); | |
86 | return !!ret; | |
87 | } | |
88 | ||
a633fca0 | 89 | int cmd_tar_tree(int argc, const char **argv, const char *prefix) |
21754264 JH |
90 | { |
91 | if (argc < 2) | |
92 | usage(tar_tree_usage); | |
93 | if (!strncmp("--remote=", argv[1], 9)) | |
94 | return remote_tar(argc, argv); | |
a633fca0 | 95 | return generate_tar(argc, argv, prefix); |
21754264 | 96 | } |
52ba03cb RS |
97 | |
98 | /* ustar header + extended global header content */ | |
99 | #define HEADERSIZE (2 * RECORDSIZE) | |
100 | ||
a633fca0 | 101 | int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) |
52ba03cb RS |
102 | { |
103 | char buffer[HEADERSIZE]; | |
104 | struct ustar_header *header = (struct ustar_header *)buffer; | |
105 | char *content = buffer + RECORDSIZE; | |
106 | ssize_t n; | |
107 | ||
108 | n = xread(0, buffer, HEADERSIZE); | |
109 | if (n < HEADERSIZE) | |
110 | die("git-get-tar-commit-id: read error"); | |
111 | if (header->typeflag[0] != 'g') | |
112 | return 1; | |
113 | if (memcmp(content, "52 comment=", 11)) | |
114 | return 1; | |
115 | ||
116 | n = xwrite(1, content + 11, 41); | |
117 | if (n < 41) | |
118 | die("git-get-tar-commit-id: write error"); | |
119 | ||
120 | return 0; | |
121 | } |