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