Revision ae5d8470f6b8e1abdef19bf033472c63fb72b735 authored by Marco Roeland on 05 April 2006, 20:28:28 UTC, committed by Junio C Hamano on 05 April 2006, 21:07:21 UTC
The "--amend" option is used to amend the tip of the current branch. This
documentation text was copied straight from the commit that implemented it.

Some minor format tweaks for asciidoc were taken from work by Francis Daly
in commit b0d08a5.. It looks good now also in the html page.

[jc: amended further to follow the recommendation by Francis in
commit 3070b60].

Signed-off-by: Marco Roeland <marco.roeland@xs4all.nl>
Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 3ffe0c2
Raw File
rsh.c
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "rsh.h"
#include "quote.h"
#include "cache.h"

#define COMMAND_SIZE 4096

/*
 * Append a string to a string buffer, with or without shell quoting.
 * Return true if the buffer overflowed.
 */
static int add_to_string(char **ptrp, int *sizep, const char *str, int quote)
{
	char *p = *ptrp;
	int size = *sizep;
	int oc;
	int err = 0;

	if ( quote ) {
		oc = sq_quote_buf(p, size, str);
	} else {
		oc = strlen(str);
		memcpy(p, str, (oc >= size) ? size-1 : oc);
	}

	if ( oc >= size ) {
		err = 1;
		oc = size-1;
	}

	*ptrp  += oc;
	**ptrp  = '\0';
	*sizep -= oc;
	return err;
}

int setup_connection(int *fd_in, int *fd_out, const char *remote_prog, 
		     char *url, int rmt_argc, char **rmt_argv)
{
	char *host;
	char *path;
	int sv[2];
	char command[COMMAND_SIZE];
	char *posn;
	int sizen;
	int of;
	int i;

	if (!strcmp(url, "-")) {
		*fd_in = 0;
		*fd_out = 1;
		return 0;
	}

	host = strstr(url, "//");
	if (host) {
		host += 2;
		path = strchr(host, '/');
	} else {
		host = url;
		path = strchr(host, ':');
		if (path)
			*(path++) = '\0';
	}
	if (!path) {
		return error("Bad URL: %s", url);
	}
	/* $GIT_RSH <host> "env GIT_DIR=<path> <remote_prog> <args...>" */
	sizen = COMMAND_SIZE;
	posn = command;
	of = 0;
	of |= add_to_string(&posn, &sizen, "env ", 0);
	of |= add_to_string(&posn, &sizen, GIT_DIR_ENVIRONMENT "=", 0);
	of |= add_to_string(&posn, &sizen, path, 1);
	of |= add_to_string(&posn, &sizen, " ", 0);
	of |= add_to_string(&posn, &sizen, remote_prog, 1);

	for ( i = 0 ; i < rmt_argc ; i++ ) {
		of |= add_to_string(&posn, &sizen, " ", 0);
		of |= add_to_string(&posn, &sizen, rmt_argv[i], 1);
	}

	of |= add_to_string(&posn, &sizen, " -", 0);

	if ( of )
		return error("Command line too long");

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv))
		return error("Couldn't create socket");

	if (!fork()) {
		const char *ssh, *ssh_basename;
		ssh = getenv("GIT_SSH");
		if (!ssh) ssh = "ssh";
		ssh_basename = strrchr(ssh, '/');
		if (!ssh_basename)
			ssh_basename = ssh;
		else
			ssh_basename++;
		close(sv[1]);
		dup2(sv[0], 0);
		dup2(sv[0], 1);
		execlp(ssh, ssh_basename, host, command, NULL);
	}
	close(sv[0]);
	*fd_in = sv[1];
	*fd_out = sv[1];
	return 0;
}
back to top