]>
Commit | Line | Data |
---|---|---|
f71a69ab JH |
1 | #ifndef COUNTERPART_ENV_NAME |
2 | #define COUNTERPART_ENV_NAME "GIT_SSH_FETCH" | |
3 | #endif | |
4 | #ifndef COUNTERPART_PROGRAM_NAME | |
5 | #define COUNTERPART_PROGRAM_NAME "git-ssh-fetch" | |
6 | #endif | |
7 | #ifndef MY_PROGRAM_NAME | |
8 | #define MY_PROGRAM_NAME "git-ssh-upload" | |
9 | #endif | |
10 | ||
6eb7ed54 DB |
11 | #include "cache.h" |
12 | #include "rsh.h" | |
c7c4bbe6 | 13 | #include "refs.h" |
6eb7ed54 | 14 | |
6da4016a | 15 | static unsigned char local_version = 1; |
96f1e58f | 16 | static unsigned char remote_version; |
dba385bb | 17 | |
96f1e58f | 18 | static int verbose; |
a5eda52b | 19 | |
6da4016a | 20 | static int serve_object(int fd_in, int fd_out) { |
6eb7ed54 | 21 | ssize_t size; |
d565b341 | 22 | unsigned char sha1[20]; |
dba385bb | 23 | signed char remote; |
93d26e4c AW |
24 | |
25 | size = read_in_full(fd_in, sha1, 20); | |
26 | if (size < 0) { | |
27 | perror("git-ssh-upload: read "); | |
28 | return -1; | |
29 | } | |
30 | if (!size) | |
31 | return -1; | |
dba385bb | 32 | |
a5eda52b DB |
33 | if (verbose) |
34 | fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); | |
35 | ||
dba385bb DB |
36 | remote = 0; |
37 | ||
a5eda52b | 38 | if (!has_sha1_file(sha1)) { |
215a7ad1 | 39 | fprintf(stderr, "git-ssh-upload: could not find %s\n", |
dba385bb DB |
40 | sha1_to_hex(sha1)); |
41 | remote = -1; | |
42 | } | |
43 | ||
93822c22 AW |
44 | if (write_in_full(fd_out, &remote, 1) != 1) |
45 | return 0; | |
dba385bb DB |
46 | |
47 | if (remote < 0) | |
48 | return 0; | |
49 | ||
a5eda52b | 50 | return write_sha1_to_fd(fd_out, sha1); |
dba385bb | 51 | } |
6eb7ed54 | 52 | |
6da4016a | 53 | static int serve_version(int fd_in, int fd_out) |
dba385bb | 54 | { |
93d26e4c | 55 | if (xread(fd_in, &remote_version, 1) < 1) |
dba385bb | 56 | return -1; |
93822c22 | 57 | write_in_full(fd_out, &local_version, 1); |
dba385bb DB |
58 | return 0; |
59 | } | |
6eb7ed54 | 60 | |
6da4016a | 61 | static int serve_ref(int fd_in, int fd_out) |
c7c4bbe6 DB |
62 | { |
63 | char ref[PATH_MAX]; | |
64 | unsigned char sha1[20]; | |
65 | int posn = 0; | |
66 | signed char remote = 0; | |
67 | do { | |
93d26e4c | 68 | if (posn >= PATH_MAX || xread(fd_in, ref + posn, 1) < 1) |
c7c4bbe6 DB |
69 | return -1; |
70 | posn++; | |
71 | } while (ref[posn - 1]); | |
a5eda52b DB |
72 | |
73 | if (verbose) | |
74 | fprintf(stderr, "Serving %s\n", ref); | |
75 | ||
c7c4bbe6 DB |
76 | if (get_ref_sha1(ref, sha1)) |
77 | remote = -1; | |
93822c22 AW |
78 | if (write_in_full(fd_out, &remote, 1) != 1) |
79 | return 0; | |
c7c4bbe6 DB |
80 | if (remote) |
81 | return 0; | |
93822c22 | 82 | write_in_full(fd_out, sha1, 20); |
c7c4bbe6 DB |
83 | return 0; |
84 | } | |
85 | ||
86 | ||
6da4016a | 87 | static void service(int fd_in, int fd_out) { |
dba385bb | 88 | char type; |
8a912bcb | 89 | ssize_t retval; |
dba385bb | 90 | do { |
93d26e4c | 91 | retval = xread(fd_in, &type, 1); |
dba385bb DB |
92 | if (retval < 1) { |
93 | if (retval < 0) | |
215a7ad1 | 94 | perror("git-ssh-upload: read "); |
6eb7ed54 DB |
95 | return; |
96 | } | |
dba385bb DB |
97 | if (type == 'v' && serve_version(fd_in, fd_out)) |
98 | return; | |
99 | if (type == 'o' && serve_object(fd_in, fd_out)) | |
100 | return; | |
c7c4bbe6 DB |
101 | if (type == 'r' && serve_ref(fd_in, fd_out)) |
102 | return; | |
6eb7ed54 DB |
103 | } while (1); |
104 | } | |
105 | ||
4d1f1190 | 106 | static const char ssh_push_usage[] = |
f71a69ab | 107 | MY_PROGRAM_NAME " [-c] [-t] [-a] [-w ref] commit-id url"; |
ee85cbc6 | 108 | |
6eb7ed54 DB |
109 | int main(int argc, char **argv) |
110 | { | |
111 | int arg = 1; | |
112 | char *commit_id; | |
113 | char *url; | |
114 | int fd_in, fd_out; | |
c7c81b3a | 115 | const char *prog; |
ee85cbc6 SV |
116 | unsigned char sha1[20]; |
117 | char hex[41]; | |
001d4a27 | 118 | |
f71a69ab JH |
119 | prog = getenv(COUNTERPART_ENV_NAME); |
120 | if (!prog) prog = COUNTERPART_PROGRAM_NAME; | |
5a327713 JH |
121 | |
122 | setup_git_directory(); | |
123 | ||
6eb7ed54 | 124 | while (arg < argc && argv[arg][0] == '-') { |
c7c4bbe6 DB |
125 | if (argv[arg][1] == 'w') |
126 | arg++; | |
6eb7ed54 DB |
127 | arg++; |
128 | } | |
ee85cbc6 SV |
129 | if (argc < arg + 2) |
130 | usage(ssh_push_usage); | |
6eb7ed54 DB |
131 | commit_id = argv[arg]; |
132 | url = argv[arg + 1]; | |
ee85cbc6 | 133 | if (get_sha1(commit_id, sha1)) |
31fff305 | 134 | die("Not a valid object name %s", commit_id); |
ee85cbc6 SV |
135 | memcpy(hex, sha1_to_hex(sha1), sizeof(hex)); |
136 | argv[arg] = hex; | |
137 | ||
001d4a27 | 138 | if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1)) |
6eb7ed54 DB |
139 | return 1; |
140 | ||
141 | service(fd_in, fd_out); | |
142 | return 0; | |
143 | } |