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