Example #1
0
static int handshake_capabilities(struct child_process *process,
				  struct subprocess_capability *capabilities,
				  unsigned int *supported_capabilities)
{
	int i;
	char *line;

	for (i = 0; capabilities[i].name; i++) {
		if (packet_write_fmt_gently(process->in, "capability=%s\n",
					    capabilities[i].name))
			return error("Could not write requested capability");
	}
	if (packet_flush_gently(process->in))
		return error("Could not write flush packet");

	while ((line = packet_read_line(process->out, NULL))) {
		const char *p;
		if (!skip_prefix(line, "capability=", &p))
			continue;

		for (i = 0;
		     capabilities[i].name && strcmp(p, capabilities[i].name);
		     i++)
			;
		if (capabilities[i].name) {
			if (supported_capabilities)
				*supported_capabilities |= capabilities[i].flag;
		} else {
			warning("subprocess '%s' requested unsupported capability '%s'",
				process->argv[0], p);
		}
	}

	return 0;
}
Example #2
0
static int handshake_version(struct child_process *process,
			     const char *welcome_prefix, int *versions,
			     int *chosen_version)
{
	int version_scratch;
	int i;
	char *line;
	const char *p;

	if (!chosen_version)
		chosen_version = &version_scratch;

	if (packet_write_fmt_gently(process->in, "%s-client\n",
				    welcome_prefix))
		return error("Could not write client identification");
	for (i = 0; versions[i]; i++) {
		if (packet_write_fmt_gently(process->in, "version=%d\n",
					    versions[i]))
			return error("Could not write requested version");
	}
	if (packet_flush_gently(process->in))
		return error("Could not write flush packet");

	if (!(line = packet_read_line(process->out, NULL)) ||
	    !skip_prefix(line, welcome_prefix, &p) ||
	    strcmp(p, "-server"))
		return error("Unexpected line '%s', expected %s-server",
			     line ? line : "<flush packet>", welcome_prefix);
	if (!(line = packet_read_line(process->out, NULL)) ||
	    !skip_prefix(line, "version=", &p) ||
	    strtol_i(p, 10, chosen_version))
		return error("Unexpected line '%s', expected version",
			     line ? line : "<flush packet>");
	if ((line = packet_read_line(process->out, NULL)))
		return error("Unexpected line '%s', expected flush", line);

	/* Check to make sure that the version received is supported */
	for (i = 0; versions[i]; i++) {
		if (versions[i] == *chosen_version)
			break;
	}
	if (!versions[i])
		return error("Version %d not supported", *chosen_version);

	return 0;
}
Example #3
0
int write_packetized_from_fd(int fd_in, int fd_out)
{
	static char buf[LARGE_PACKET_DATA_MAX];
	int err = 0;
	ssize_t bytes_to_write;

	while (!err) {
		bytes_to_write = xread(fd_in, buf, sizeof(buf));
		if (bytes_to_write < 0)
			return COPY_READ_ERROR;
		if (bytes_to_write == 0)
			break;
		err = packet_write_gently(fd_out, buf, bytes_to_write);
	}
	if (!err)
		err = packet_flush_gently(fd_out);
	return err;
}
Example #4
0
int packet_writel(int fd, const char *line, ...)
{
	va_list args;
	int err;
	va_start(args, line);
	for (;;) {
		if (!line)
			break;
		if (strlen(line) > LARGE_PACKET_DATA_MAX)
			return -1;
		err = packet_write_fmt_gently(fd, "%s\n", line);
		if (err)
			return err;
		line = va_arg(args, const char*);
	}
	va_end(args);
	return packet_flush_gently(fd);
}
Example #5
0
int write_packetized_from_buf(const char *src_in, size_t len, int fd_out)
{
	int err = 0;
	size_t bytes_written = 0;
	size_t bytes_to_write;

	while (!err) {
		if ((len - bytes_written) > LARGE_PACKET_DATA_MAX)
			bytes_to_write = LARGE_PACKET_DATA_MAX;
		else
			bytes_to_write = len - bytes_written;
		if (bytes_to_write == 0)
			break;
		err = packet_write_gently(fd_out, src_in + bytes_written, bytes_to_write);
		bytes_written += bytes_to_write;
	}
	if (!err)
		err = packet_flush_gently(fd_out);
	return err;
}