Revision 7d09fbe4ab7f080a8f8f5dcef7e0f3edf5e26019 authored by Serge E. Hallyn on 18 April 2006, 13:11:06 UTC, committed by Junio C Hamano on 25 April 2006, 06:07:54 UTC
The set_reuse_addr() error case was the only error case in
socklist() where we returned rather than continued.  Not sure
why.  Either we must free the socklist, or continue.  This patch
continues on error.

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
(cherry picked from 0032d548db56eac9ea09b4ba05843365f6325b85 commit)
1 parent 1ab661d
Raw File
ssh-upload.c
#ifndef COUNTERPART_ENV_NAME
#define COUNTERPART_ENV_NAME "GIT_SSH_FETCH"
#endif
#ifndef COUNTERPART_PROGRAM_NAME
#define COUNTERPART_PROGRAM_NAME "git-ssh-fetch"
#endif
#ifndef MY_PROGRAM_NAME
#define MY_PROGRAM_NAME "git-ssh-upload"
#endif

#include "cache.h"
#include "rsh.h"
#include "refs.h"

#include <string.h>

static unsigned char local_version = 1;
static unsigned char remote_version = 0;

static int verbose = 0;

static int serve_object(int fd_in, int fd_out) {
	ssize_t size;
	unsigned char sha1[20];
	signed char remote;
	int posn = 0;
	do {
		size = read(fd_in, sha1 + posn, 20 - posn);
		if (size < 0) {
			perror("git-ssh-upload: read ");
			return -1;
		}
		if (!size)
			return -1;
		posn += size;
	} while (posn < 20);
	
	if (verbose)
		fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1));

	remote = 0;
	
	if (!has_sha1_file(sha1)) {
		fprintf(stderr, "git-ssh-upload: could not find %s\n",
			sha1_to_hex(sha1));
		remote = -1;
	}
	
	write(fd_out, &remote, 1);
	
	if (remote < 0)
		return 0;
	
	return write_sha1_to_fd(fd_out, sha1);
}

static int serve_version(int fd_in, int fd_out)
{
	if (read(fd_in, &remote_version, 1) < 1)
		return -1;
	write(fd_out, &local_version, 1);
	return 0;
}

static int serve_ref(int fd_in, int fd_out)
{
	char ref[PATH_MAX];
	unsigned char sha1[20];
	int posn = 0;
	signed char remote = 0;
	do {
		if (read(fd_in, ref + posn, 1) < 1)
			return -1;
		posn++;
	} while (ref[posn - 1]);

	if (verbose)
		fprintf(stderr, "Serving %s\n", ref);

	if (get_ref_sha1(ref, sha1))
		remote = -1;
	write(fd_out, &remote, 1);
	if (remote)
		return 0;
	write(fd_out, sha1, 20);
        return 0;
}


static void service(int fd_in, int fd_out) {
	char type;
	int retval;
	do {
		retval = read(fd_in, &type, 1);
		if (retval < 1) {
			if (retval < 0)
				perror("git-ssh-upload: read ");
			return;
		}
		if (type == 'v' && serve_version(fd_in, fd_out))
			return;
		if (type == 'o' && serve_object(fd_in, fd_out))
			return;
		if (type == 'r' && serve_ref(fd_in, fd_out))
			return;
	} while (1);
}

static const char ssh_push_usage[] =
	MY_PROGRAM_NAME " [-c] [-t] [-a] [-w ref] commit-id url";

int main(int argc, char **argv)
{
	int arg = 1;
        char *commit_id;
        char *url;
	int fd_in, fd_out;
	const char *prog;
	unsigned char sha1[20];
	char hex[41];

	prog = getenv(COUNTERPART_ENV_NAME);
	if (!prog) prog = COUNTERPART_PROGRAM_NAME;

	setup_git_directory();

	while (arg < argc && argv[arg][0] == '-') {
		if (argv[arg][1] == 'w')
			arg++;
                arg++;
        }
	if (argc < arg + 2)
		usage(ssh_push_usage);
	commit_id = argv[arg];
	url = argv[arg + 1];
	if (get_sha1(commit_id, sha1))
		usage(ssh_push_usage);
	memcpy(hex, sha1_to_hex(sha1), sizeof(hex));
	argv[arg] = hex;

	if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
		return 1;

	service(fd_in, fd_out);
	return 0;
}
back to top