git/connect.c

#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "config.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "pkt-line.h"
#include "quote.h"
#include "refs.h"
#include "run-command.h"
#include "remote.h"
#include "connect.h"
#include "url.h"
#include "string-list.h"
#include "oid-array.h"
#include "path.h"
#include "transport.h"
#include "trace2.h"
#include "strbuf.h"
#include "version.h"
#include "protocol.h"
#include "alias.h"
#include "bundle-uri.h"

static char *server_capabilities_v1;
static struct strvec server_capabilities_v2 =;
static const char *next_server_feature_value(const char *feature, size_t *len, size_t *offset);

static int check_ref(const char *name, unsigned int flags)
{}

int check_ref_type(const struct ref *ref, int flags)
{}

static NORETURN void die_initial_contact(int unexpected)
{}

/* Checks if the server supports the capability 'c' */
int server_supports_v2(const char *c)
{}

void ensure_server_supports_v2(const char *c)
{}

int server_feature_v2(const char *c, const char **v)
{}

int server_supports_feature(const char *c, const char *feature,
			    int die_on_error)
{}

static void process_capabilities_v2(struct packet_reader *reader)
{}

enum protocol_version discover_version(struct packet_reader *reader)
{}

static void parse_one_symref_info(struct string_list *symref, const char *val, int len)
{}

static void annotate_refs_with_symref_info(struct ref *ref)
{}

static void process_capabilities(struct packet_reader *reader, int *linelen)
{}

static int process_dummy_ref(const struct packet_reader *reader)
{}

static void check_no_capabilities(const char *line, int len)
{}

static int process_ref(const struct packet_reader *reader, int len,
		       struct ref ***list, unsigned int flags,
		       struct oid_array *extra_have)
{}

static int process_shallow(const struct packet_reader *reader, int len,
			   struct oid_array *shallow_points)
{}

enum get_remote_heads_state {};

/*
 * Read all the refs from the other end
 */
struct ref **get_remote_heads(struct packet_reader *reader,
			      struct ref **list, unsigned int flags,
			      struct oid_array *extra_have,
			      struct oid_array *shallow_points)
{}

/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */
static int process_ref_v2(struct packet_reader *reader, struct ref ***list,
			  const char **unborn_head_target)
{}

void check_stateless_delimiter(int stateless_rpc,
			      struct packet_reader *reader,
			      const char *error)
{}

static void send_capabilities(int fd_out, struct packet_reader *reader)
{}

int get_remote_bundle_uri(int fd_out, struct packet_reader *reader,
			  struct bundle_list *bundles, int stateless_rpc)
{}

struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
			     struct ref **list, int for_push,
			     struct transport_ls_refs_options *transport_options,
			     const struct string_list *server_options,
			     int stateless_rpc)
{}

const char *parse_feature_value(const char *feature_list, const char *feature, size_t *lenp, size_t *offset)
{}

int server_supports_hash(const char *desired, int *feature_supported)
{}

int parse_feature_request(const char *feature_list, const char *feature)
{}

static const char *next_server_feature_value(const char *feature, size_t *len, size_t *offset)
{}

const char *server_feature_value(const char *feature, size_t *len)
{}

int server_supports(const char *feature)
{}

enum protocol {};

int url_is_local_not_ssh(const char *url)
{}

static const char *prot_name(enum protocol protocol)
{}

static enum protocol get_protocol(const char *name)
{}

static char *host_end(char **hoststart, int removebrackets)
{}

#define STR_(s)
#define STR(s)

static void get_host_and_port(char **host, const char **port)
{}

static void enable_keepalive(int sockfd)
{}

#ifndef NO_IPV6

static const char *ai_name(const struct addrinfo *ai)
{}

/*
 * Returns a connected socket() fd, or else die()s.
 */
static int git_tcp_connect_sock(char *host, int flags)
{}

#else /* NO_IPV6 */

/*
 * Returns a connected socket() fd, or else die()s.
 */
static int git_tcp_connect_sock(char *host, int flags)
{
	struct strbuf error_message = STRBUF_INIT;
	int sockfd = -1;
	const char *port = STR(DEFAULT_GIT_PORT);
	char *ep;
	struct hostent *he;
	struct sockaddr_in sa;
	char **ap;
	unsigned int nport;
	int cnt;

	get_host_and_port(&host, &port);

	if (flags & CONNECT_VERBOSE)
		fprintf(stderr, _("Looking up %s ... "), host);

	he = gethostbyname(host);
	if (!he)
		die(_("unable to look up %s (%s)"), host, hstrerror(h_errno));
	nport = strtoul(port, &ep, 10);
	if ( ep == port || *ep ) {
		/* Not numeric */
		struct servent *se = getservbyname(port,"tcp");
		if ( !se )
			die(_("unknown port %s"), port);
		nport = se->s_port;
	}

	if (flags & CONNECT_VERBOSE)
		/* TRANSLATORS: this is the end of "Looking up %s ... " */
		fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port);

	for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) {
		memset(&sa, 0, sizeof sa);
		sa.sin_family = he->h_addrtype;
		sa.sin_port = htons(nport);
		memcpy(&sa.sin_addr, *ap, he->h_length);

		sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
		if ((sockfd < 0) ||
		    connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
			strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
				host,
				cnt,
				inet_ntoa(*(struct in_addr *)&sa.sin_addr),
				strerror(errno));
			if (0 <= sockfd)
				close(sockfd);
			sockfd = -1;
			continue;
		}
		if (flags & CONNECT_VERBOSE)
			fprintf(stderr, "%s ",
				inet_ntoa(*(struct in_addr *)&sa.sin_addr));
		break;
	}

	if (sockfd < 0)
		die(_("unable to connect to %s:\n%s"), host, error_message.buf);

	enable_keepalive(sockfd);

	if (flags & CONNECT_VERBOSE)
		/* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */
		fprintf_ln(stderr, _("done."));

	return sockfd;
}

#endif /* NO_IPV6 */


/*
 * Dummy child_process returned by git_connect() if the transport protocol
 * does not need fork(2).
 */
static struct child_process no_fork =;

int git_connection_is_socket(struct child_process *conn)
{}

static struct child_process *git_tcp_connect(int fd[2], char *host, int flags)
{}


static char *git_proxy_command;

static int git_proxy_command_options(const char *var, const char *value,
		const struct config_context *ctx, void *cb)
{}

static int git_use_proxy(const char *host)
{}

static struct child_process *git_proxy_connect(int fd[2], char *host)
{}

static char *get_port(char *host)
{}

/*
 * Extract protocol and relevant parts from the specified connection URL.
 * The caller must free() the returned strings.
 */
static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
				       char **ret_path)
{}

static const char *get_ssh_command(void)
{}

enum ssh_variant {};

static void override_ssh_variant(enum ssh_variant *ssh_variant)
{}

static enum ssh_variant determine_ssh_variant(const char *ssh_command,
					      int is_cmdline)
{}

/*
 * Open a connection using Git's native protocol.
 *
 * The caller is responsible for freeing hostandport, but this function may
 * modify it (for example, to truncate it to remove the port part).
 */
static struct child_process *git_connect_git(int fd[2], char *hostandport,
					     const char *path, const char *prog,
					     enum protocol_version version,
					     int flags)
{}

/*
 * Append the appropriate environment variables to `env` and options to
 * `args` for running ssh in Git's SSH-tunneled transport.
 */
static void push_ssh_options(struct strvec *args, struct strvec *env,
			     enum ssh_variant variant, const char *port,
			     enum protocol_version version, int flags)
{}

/* Prepare a child_process for use by Git's SSH-tunneled transport. */
static void fill_ssh_args(struct child_process *conn, const char *ssh_host,
			  const char *port, enum protocol_version version,
			  int flags)
{}

/*
 * This returns the dummy child_process `no_fork` if the transport protocol
 * does not need fork(2), or a struct child_process object if it does.  Once
 * done, finish the connection with finish_connect() with the value returned
 * from this function (it is safe to call finish_connect() with NULL to
 * support the former case).
 *
 * If it returns, the connect is successful; it just dies on errors (this
 * will hopefully be changed in a libification effort, to return NULL when
 * the connection failed).
 */
struct child_process *git_connect(int fd[2], const char *url,
				  const char *name,
				  const char *prog, int flags)
{}

int finish_connect(struct child_process *conn)
{}