4 static const char receive_pack_usage
[] = "git-receive-pack [--unpack=executable] <git-dir> [heads]";
6 static const char *unpacker
= "git-unpack-objects";
8 static int path_match(const char *path
, int nr
, char **match
)
11 int pathlen
= strlen(path
);
13 for (i
= 0; i
< nr
; i
++) {
17 if (!len
|| len
> pathlen
)
19 if (memcmp(path
+ pathlen
- len
, s
, len
))
21 if (pathlen
> len
&& path
[pathlen
- len
- 1] != '/')
29 static void safe_write(int fd
, const void *buf
, unsigned n
)
32 int ret
= write(fd
, buf
, n
);
39 die("write error (disk full?)");
40 if (errno
== EAGAIN
|| errno
== EINTR
)
42 die("write error (%s)", strerror(errno
));
47 * If we buffered things up above (we don't, but we should),
50 static void flush_safe(int fd
)
55 * Write a packetized stream, where each line is preceded by
56 * its length (including the header) as a 4-byte hex number.
57 * A length of 'zero' means end of stream (and a length of 1-3
60 #define hex(a) (hexchar[(a) & 15])
61 static void packet_write(const char *fmt
, ...)
63 static char buffer
[1000];
64 static char hexchar
[] = "0123456789abcdef";
69 n
= vsnprintf(buffer
+ 4, sizeof(buffer
) - 4, fmt
, args
);
71 if (n
>= sizeof(buffer
)-4)
72 die("protocol error: impossibly long line");
74 buffer
[0] = hex(n
>> 12);
75 buffer
[1] = hex(n
>> 8);
76 buffer
[2] = hex(n
>> 4);
78 safe_write(1, buffer
, n
);
81 static void show_ref(const char *path
, unsigned char *sha1
)
83 packet_write("%s %s\n", sha1_to_hex(sha1
), path
);
86 static int read_ref(const char *path
, unsigned char *sha1
)
89 int fd
= open(path
, O_RDONLY
);
93 if (read(fd
, buffer
, sizeof(buffer
)) >= 40)
94 ret
= get_sha1_hex(buffer
, sha1
);
100 static void write_head_info(const char *base
, int nr
, char **match
)
102 DIR *dir
= opendir(base
);
106 int baselen
= strlen(base
);
107 char *path
= xmalloc(baselen
+ 257);
108 memcpy(path
, base
, baselen
);
110 while ((de
= readdir(dir
)) != NULL
) {
115 if (de
->d_name
[0] == '.')
117 namelen
= strlen(de
->d_name
);
120 memcpy(path
+ baselen
, de
->d_name
, namelen
+1);
121 if (lstat(path
, &st
) < 0)
123 if (S_ISDIR(st
.st_mode
)) {
124 path
[baselen
+ namelen
] = '/';
125 path
[baselen
+ namelen
+ 1] = 0;
126 write_head_info(path
, nr
, match
);
129 if (read_ref(path
, sha1
) < 0)
131 if (nr
&& !path_match(path
, nr
, match
))
133 show_ref(path
, sha1
);
141 * This is all pretty stupid, but we use this packetized line
142 * format to make a streaming format possible without ever
143 * over-running the read buffers. That way we'll never read
144 * into what might be the pack data (which should go to another
147 * The writing side could use stdio, but since the reading
148 * side can't, we stay with pure read/write interfaces.
150 static void safe_read(int fd
, void *buffer
, unsigned size
)
155 int ret
= read(0, buffer
+ n
, size
- n
);
157 if (errno
== EINTR
|| errno
== EAGAIN
)
159 die("read error (%s)", strerror(errno
));
162 die("unexpected EOF");
167 static int safe_read_line(char *buffer
, unsigned size
)
171 safe_read(0, buffer
, 4);
174 for (n
= 0; n
< 4; n
++) {
175 unsigned char c
= buffer
[n
];
177 if (c
>= '0' && c
<= '9') {
181 if (c
>= 'a' && c
<= 'f') {
185 if (c
>= 'A' && c
<= 'F') {
189 die("protocol error: bad line length character");
193 if (len
< 4 || len
>= size
)
194 die("protocol error: bad line length %d", len
);
195 safe_read(0, buffer
+ 4, len
- 4);
205 struct line
*commands
= NULL
;
208 * This gets called after(if) we've successfully
209 * unpacked the data payload.
211 static void execute_commands(void)
213 struct line
*line
= commands
;
216 printf("%s", line
->data
);
221 static void read_head_info(void)
223 struct line
**p
= &commands
;
225 static char line
[1000];
226 int len
= safe_read_line(line
, sizeof(line
));
230 n
= xmalloc(sizeof(struct line
) + len
);
232 memcpy(n
->data
, line
+ 4, len
- 3);
238 static void unpack(void)
243 die("unpack fork failed");
245 char *const envp
[] = { "GIT_DIR=.", NULL
};
246 execle(unpacker
, unpacker
, NULL
, envp
);
247 die("unpack execute failed");
252 int retval
= waitpid(pid
, &status
, 0);
257 die("waitpid failed (%s)", strerror(retval
));
260 die("waitpid is confused");
261 if (WIFSIGNALED(status
))
262 die("%s died of signal %d", unpacker
, WTERMSIG(status
));
263 if (!WIFEXITED(status
))
264 die("%s died out of really strange complications", unpacker
);
265 code
= WEXITSTATUS(status
);
267 die("%s exited with error code %d", unpacker
, code
);
272 int main(int argc
, char **argv
)
275 const char *dir
= NULL
;
279 for (i
= 1; i
< argc
; i
++) {
280 const char *arg
= *argv
++;
283 if (!strncmp(arg
, "--unpack=", 9)) {
287 /* Do flag handling here */
288 usage(receive_pack_usage
);
292 nr_heads
= argc
- i
- 1;
296 usage(receive_pack_usage
);
298 /* chdir to the directory. If that fails, try appending ".git" */
299 if (chdir(dir
) < 0) {
300 static char path
[PATH_MAX
];
301 snprintf(path
, sizeof(path
), "%s.git", dir
);
303 die("unable to cd to %s", dir
);
306 /* If we have a ".git" directory, chdir to it */
309 if (access("objects", X_OK
) < 0 || access("refs/heads", X_OK
) < 0)
310 die("%s doesn't appear to be a git directory", dir
);
311 write_head_info("refs/", nr_heads
, heads
);
314 safe_write(1, "0000", 4);