mirror of
https://github.com/git/git
synced 2024-08-25 10:45:59 +00:00
![Jeff King](/assets/img/avatar_default.png)
It's more readable to use starts_with() instead of strncmp() to match a prefix, as the latter requires a manually-computed length, and has the funny "matching is zero" return value common to cmp functions. This patch converts several cases which were found with: git grep 'strncmp(.*, [0-9]*)' But note that it doesn't convert all such cases. There are several where the magic length number is repeated elsewhere in the code, like: /* handle "buf" which isn't NUL-terminated and might be too small */ if (len >= 3 && !strncmp(buf, "foo", 3)) or: /* exact match for "foo", but within a larger string */ if (end - buf == 3 && !strncmp(buf, "foo", 3)) While it would not produce the wrong outcome to use starts_with() in these cases, we'd still be left with one instance of "3". We're better to leave them for now, as the repeated "3" makes it clear that the two are linked (there may be other refactorings that handle both, but they're out of scope for this patch). A few things to note while reading the patch: - all cases but one are trying to match, and so lose the extra "!". The case in the first hunk of urlmatch.c is not-matching, and hence gains a "!". - the case in remote-fd.c is matching the beginning of "connect foo", but we never look at str+8 to parse the "foo" part (which would make this a candidate for skip_prefix(), not starts_with()). This seems at first glance like a bug, but is a limitation of how remote-fd works. - the second hunk in urlmatch.c shows some cases adjacent to other strncmp() calls that are left. These are of the "exact match within a larger string" type, as described above. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
83 lines
1.8 KiB
C
83 lines
1.8 KiB
C
#include "builtin.h"
|
|
#include "transport.h"
|
|
|
|
static const char usage_msg[] =
|
|
"git remote-fd <remote> <url>";
|
|
|
|
/*
|
|
* URL syntax:
|
|
* 'fd::<inoutfd>[/<anything>]' Read/write socket pair
|
|
* <inoutfd>.
|
|
* 'fd::<infd>,<outfd>[/<anything>]' Read pipe <infd> and write
|
|
* pipe <outfd>.
|
|
* [foo] indicates 'foo' is optional. <anything> is any string.
|
|
*
|
|
* The data output to <outfd>/<inoutfd> should be passed unmolested to
|
|
* git-receive-pack/git-upload-pack/git-upload-archive and output of
|
|
* git-receive-pack/git-upload-pack/git-upload-archive should be passed
|
|
* unmolested to <infd>/<inoutfd>.
|
|
*
|
|
*/
|
|
|
|
#define MAXCOMMAND 4096
|
|
|
|
static void command_loop(int input_fd, int output_fd)
|
|
{
|
|
char buffer[MAXCOMMAND];
|
|
|
|
while (1) {
|
|
size_t i;
|
|
if (!fgets(buffer, MAXCOMMAND - 1, stdin)) {
|
|
if (ferror(stdin))
|
|
die("Input error");
|
|
return;
|
|
}
|
|
/* Strip end of line characters. */
|
|
i = strlen(buffer);
|
|
while (i > 0 && isspace(buffer[i - 1]))
|
|
buffer[--i] = 0;
|
|
|
|
if (!strcmp(buffer, "capabilities")) {
|
|
printf("*connect\n\n");
|
|
fflush(stdout);
|
|
} else if (starts_with(buffer, "connect ")) {
|
|
printf("\n");
|
|
fflush(stdout);
|
|
if (bidirectional_transfer_loop(input_fd,
|
|
output_fd))
|
|
die("Copying data between file descriptors failed");
|
|
return;
|
|
} else {
|
|
die("Bad command: %s", buffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
int cmd_remote_fd(int argc, const char **argv, const char *prefix)
|
|
{
|
|
int input_fd = -1;
|
|
int output_fd = -1;
|
|
char *end;
|
|
|
|
if (argc != 3)
|
|
usage(usage_msg);
|
|
|
|
input_fd = (int)strtoul(argv[2], &end, 10);
|
|
|
|
if ((end == argv[2]) || (*end != ',' && *end != '/' && *end))
|
|
die("Bad URL syntax");
|
|
|
|
if (*end == '/' || !*end) {
|
|
output_fd = input_fd;
|
|
} else {
|
|
char *end2;
|
|
output_fd = (int)strtoul(end + 1, &end2, 10);
|
|
|
|
if ((end2 == end + 1) || (*end2 != '/' && *end2))
|
|
die("Bad URL syntax");
|
|
}
|
|
|
|
command_loop(input_fd, output_fd);
|
|
return 0;
|
|
}
|