]>
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 | |
ee85cbc6 SV |
15 | #include <string.h> |
16 | ||
6da4016a LT |
17 | static unsigned char local_version = 1; |
18 | static unsigned char remote_version = 0; | |
dba385bb | 19 | |
a5eda52b DB |
20 | static int verbose = 0; |
21 | ||
6da4016a | 22 | static int serve_object(int fd_in, int fd_out) { |
6eb7ed54 | 23 | ssize_t size; |
d565b341 | 24 | unsigned char sha1[20]; |
dba385bb | 25 | signed char remote; |
a5eda52b | 26 | int posn = 0; |
dba385bb DB |
27 | do { |
28 | size = read(fd_in, sha1 + posn, 20 - posn); | |
29 | if (size < 0) { | |
215a7ad1 | 30 | perror("git-ssh-upload: read "); |
dba385bb DB |
31 | return -1; |
32 | } | |
33 | if (!size) | |
34 | return -1; | |
35 | posn += size; | |
36 | } while (posn < 20); | |
37 | ||
a5eda52b DB |
38 | if (verbose) |
39 | fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); | |
40 | ||
dba385bb DB |
41 | remote = 0; |
42 | ||
a5eda52b | 43 | if (!has_sha1_file(sha1)) { |
215a7ad1 | 44 | fprintf(stderr, "git-ssh-upload: could not find %s\n", |
dba385bb DB |
45 | sha1_to_hex(sha1)); |
46 | remote = -1; | |
47 | } | |
48 | ||
49 | write(fd_out, &remote, 1); | |
50 | ||
51 | if (remote < 0) | |
52 | return 0; | |
53 | ||
a5eda52b | 54 | return write_sha1_to_fd(fd_out, sha1); |
dba385bb | 55 | } |
6eb7ed54 | 56 | |
6da4016a | 57 | static int serve_version(int fd_in, int fd_out) |
dba385bb DB |
58 | { |
59 | if (read(fd_in, &remote_version, 1) < 1) | |
60 | return -1; | |
61 | write(fd_out, &local_version, 1); | |
62 | return 0; | |
63 | } | |
6eb7ed54 | 64 | |
6da4016a | 65 | static int serve_ref(int fd_in, int fd_out) |
c7c4bbe6 DB |
66 | { |
67 | char ref[PATH_MAX]; | |
68 | unsigned char sha1[20]; | |
69 | int posn = 0; | |
70 | signed char remote = 0; | |
71 | do { | |
72 | if (read(fd_in, ref + posn, 1) < 1) | |
73 | return -1; | |
74 | posn++; | |
75 | } while (ref[posn - 1]); | |
a5eda52b DB |
76 | |
77 | if (verbose) | |
78 | fprintf(stderr, "Serving %s\n", ref); | |
79 | ||
c7c4bbe6 DB |
80 | if (get_ref_sha1(ref, sha1)) |
81 | remote = -1; | |
82 | write(fd_out, &remote, 1); | |
83 | if (remote) | |
84 | return 0; | |
85 | write(fd_out, sha1, 20); | |
86 | return 0; | |
87 | } | |
88 | ||
89 | ||
6da4016a | 90 | static void service(int fd_in, int fd_out) { |
dba385bb DB |
91 | char type; |
92 | int retval; | |
93 | do { | |
94 | retval = read(fd_in, &type, 1); | |
95 | if (retval < 1) { | |
96 | if (retval < 0) | |
215a7ad1 | 97 | perror("git-ssh-upload: read "); |
6eb7ed54 DB |
98 | return; |
99 | } | |
dba385bb DB |
100 | if (type == 'v' && serve_version(fd_in, fd_out)) |
101 | return; | |
102 | if (type == 'o' && serve_object(fd_in, fd_out)) | |
103 | return; | |
c7c4bbe6 DB |
104 | if (type == 'r' && serve_ref(fd_in, fd_out)) |
105 | return; | |
6eb7ed54 DB |
106 | } while (1); |
107 | } | |
108 | ||
4d1f1190 | 109 | static const char ssh_push_usage[] = |
f71a69ab | 110 | MY_PROGRAM_NAME " [-c] [-t] [-a] [-w ref] commit-id url"; |
ee85cbc6 | 111 | |
6eb7ed54 DB |
112 | int main(int argc, char **argv) |
113 | { | |
114 | int arg = 1; | |
115 | char *commit_id; | |
116 | char *url; | |
117 | int fd_in, fd_out; | |
c7c81b3a | 118 | const char *prog; |
ee85cbc6 SV |
119 | unsigned char sha1[20]; |
120 | char hex[41]; | |
001d4a27 | 121 | |
f71a69ab JH |
122 | prog = getenv(COUNTERPART_ENV_NAME); |
123 | if (!prog) prog = COUNTERPART_PROGRAM_NAME; | |
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 SV |
133 | if (get_sha1(commit_id, sha1)) |
134 | usage(ssh_push_usage); | |
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 | } |