Beispiel #1
0
static int query_get_string_answer(cmd_request_t cmd)
{
	struct booth_site *site;
	struct boothc_header reply;
	char *data;
	int data_len;
	int rv;
	struct booth_transport const *tpt;

	data = NULL;
	init_header(&cl.msg.header, cmd, 0, cl.options, 0, 0, sizeof(cl.msg));

	if (!*cl.site)
		site = local;
	else if (!find_site_by_name(cl.site, &site, 1)) {
		log_error("cannot find site \"%s\"", cl.site);
		rv = ENOENT;
		goto out;
	}

	tpt = booth_transport + TCP;
	rv = tpt->open(site);
	if (rv < 0)
		goto out_free;

	rv = tpt->send(site, &cl.msg, sizeof(cl.msg));
	if (rv < 0)
		goto out_free;

	rv = tpt->recv(site, &reply, sizeof(reply));
	if (rv < 0)
		goto out_free;

	data_len = ntohl(reply.length) - sizeof(reply);
	/* no tickets? */
	if (!data_len) {
		rv = 0;
		goto out_close;
	}

	data = malloc(data_len);
	if (!data) {
		rv = -ENOMEM;
		goto out_free;
	}
	rv = tpt->recv(site, data, data_len);
	if (rv < 0)
		goto out_free;

	do_write(STDOUT_FILENO, data, data_len);
	rv = 0;

out_free:
	free(data);
out_close:
	tpt->close(site);
out:
	return rv;
}
Beispiel #2
0
int check_site(char *site, int *is_local)
{
	struct booth_site *node;

	if (!check_max_len_valid(site, sizeof(node->addr_string)))
		return 0;

	if (find_site_by_name(site, &node, 0)) {
		*is_local = node->local;
		return 1;
	}

	return 0;
}
Beispiel #3
0
static int setup_config(int type)
{
	int rv;

	rv = read_config(cl.configfile, type);
	if (rv < 0)
		goto out;

	if (is_auth_req()) {
		rv = read_authkey();
		if (rv < 0)
			goto out;
#if HAVE_LIBGCRYPT
		if (!gcry_check_version(NULL)) {
			log_error("gcry_check_version");
			rv = -ENOENT;
			goto out;
		}
		gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
		gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
	}

	/* Set "local" pointer, ignoring errors. */
	if (cl.type == DAEMON && cl.site[0]) {
		if (!find_site_by_name(cl.site, &local, 1)) {
			log_error("Cannot find \"%s\" in the configuration.",
					cl.site);
			return -EINVAL;
		}
		local->local = 1;
	} else
		find_myself(NULL, type == CLIENT || type == GEOSTORE);


	rv = check_config(type);
	if (rv < 0)
		goto out;


	/* Per default the PID file name is derived from the
	 * configuration name. */
	if (!cl.lockfile[0]) {
		snprintf(cl.lockfile, sizeof(cl.lockfile)-1,
				"%s/%s.pid", BOOTH_RUN_DIR, booth_conf->name);
	}

out:
	return rv;
}
Beispiel #4
0
static int setup_config(int type)
{
	int rv;

	rv = read_config(cl.configfile, type);
	if (rv < 0)
		goto out;


	/* Set "local" pointer, ignoring errors. */
	if (cl.type == DAEMON && cl.site[0]) {
		if (!find_site_by_name(cl.site, &local, 1)) {
			log_error("Cannot find \"%s\" in the configuration.",
					cl.site);
			return -EINVAL;
		}
		local->local = 1;
	} else
		find_myself(NULL, type == CLIENT);


	rv = check_config(type);
	if (rv < 0)
		goto out;


	/* Per default the PID file name is derived from the
	 * configuration name. */
	if (!cl.lockfile[0]) {
		snprintf(cl.lockfile, sizeof(cl.lockfile)-1,
				"%s/%s.pid", BOOTH_RUN_DIR, booth_conf->name);
	}

out:
	return rv;
}
Beispiel #5
0
static int do_command(cmd_request_t cmd)
{
	struct booth_site *site;
	struct boothc_ticket_msg reply;
	struct booth_transport const *tpt;
	uint32_t leader_id;
	int rv;
	int reply_cnt = 0, msg_logged = 0;
	const char *op_str = "";

	if (cmd == CMD_GRANT)
		op_str = "grant";
	else if (cmd == CMD_REVOKE)
		op_str = "revoke";

	rv = 0;
	site = NULL;

	/* Always use TCP for client - at least for now. */
	tpt = booth_transport + TCP;

	if (!*cl.site)
		site = local;
	else {
		if (!find_site_by_name(cl.site, &site, 1)) {
			log_error("Site \"%s\" not configured.", cl.site);
			goto out_close;
		}
	}

	if (site->type == ARBITRATOR) {
		if (site == local) {
			log_error("We're just an arbitrator, cannot grant/revoke tickets here.");
		} else {
			log_error("%s is just an arbitrator, cannot grant/revoke tickets there.", cl.site);
		}
		goto out_close;
	}

	assert(site->type == SITE);

	/* We don't check for existence of ticket, so that asking can be
	 * done without local configuration, too.
	 * Although, that means that the UDP port has to be specified, too. */
	if (!cl.msg.ticket.id[0]) {
		/* If the loaded configuration has only a single ticket defined, use that. */
		if (booth_conf->ticket_count == 1) {
			strncpy(cl.msg.ticket.id, booth_conf->ticket[0].name,
				sizeof(cl.msg.ticket.id));
		} else {
			log_error("No ticket given.");
			goto out_close;
		}
	}

redirect:
	init_header(&cl.msg.header, cmd, 0, cl.options, 0, 0, sizeof(cl.msg));

	rv = tpt->open(site);
	if (rv < 0)
		goto out_close;

	rv = tpt->send(site, &cl.msg, sendmsglen(&cl.msg));
	if (rv < 0)
		goto out_close;

read_more:
	rv = tpt->recv_auth(site, &reply, sizeof(reply));
	if (rv < 0) {
		/* print any errors depending on the code sent by the
		 * server */
		(void)test_reply(ntohl(reply.header.result), cmd);
		goto out_close;
	}

	rv = test_reply(ntohl(reply.header.result), cmd);
	if (rv == 1) {
		tpt->close(site);
		leader_id = ntohl(reply.ticket.leader);
		if (!find_site_by_id(leader_id, &site)) {
			log_error("Message with unknown redirect site %x received", leader_id);
			rv = -1;
			goto out_close;
		}
		goto redirect;
	} else if (rv == 2 || rv == 3) {
		/* the server has more to say */
		/* don't wait too long */
		if (reply_cnt > 1 && !(cl.options & OPT_WAIT)) {
			rv = 0;
			log_info("Giving up on waiting for the definite result. "
				 "Please use \"booth list\" later to "
				 "see the outcome.");
			goto out_close;
		}
		if (reply_cnt == 0) {
			log_info("%s request sent, "
				"waiting for the result ...", op_str);
			msg_logged++;
		} else if (rv == 3 && msg_logged < 2) {
			log_info("waiting for the CIB commit ...");
			msg_logged++;
		}
		reply_cnt++;
		goto read_more;
	}

out_close:
	if (site)
		tpt->close(site);
	return rv;
}
Beispiel #6
0
static int query_get_string_answer(cmd_request_t cmd)
{
	struct booth_site *site;
	struct boothc_hdr_msg reply;
	struct boothc_header *header;
	char *data;
	int data_len;
	int rv;
	struct booth_transport const *tpt;
	int (*test_reply_f) (cmd_result_t reply_code, cmd_request_t cmd);
	size_t msg_size;
	void *request;

	if (cl.type == GEOSTORE) {
		test_reply_f = test_attr_reply;
		msg_size = sizeof(cl.attr_msg);
		request = &cl.attr_msg;
	} else {
		test_reply_f = test_reply;
		msg_size = sizeof(cl.msg);
		request = &cl.msg;
	}
	header = (struct boothc_header *)request;
	data = NULL;

	init_header(header, cmd, 0, cl.options, 0, 0, msg_size);

	if (!*cl.site)
		site = local;
	else if (!find_site_by_name(cl.site, &site, 1)) {
		log_error("cannot find site \"%s\"", cl.site);
		rv = ENOENT;
		goto out;
	}

	tpt = booth_transport + TCP;
	rv = tpt->open(site);
	if (rv < 0)
		goto out_close;

	rv = tpt->send(site, request, msg_size);
	if (rv < 0)
		goto out_close;

	rv = tpt->recv_auth(site, &reply, sizeof(reply));
	if (rv < 0)
		goto out_close;

	data_len = ntohl(reply.header.length) - rv;

	/* no attribute, or no ticket found */
	if (!data_len) {
		goto out_test_reply;
	}

	data = malloc(data_len+1);
	if (!data) {
		rv = -ENOMEM;
		goto out_close;
	}
	rv = tpt->recv(site, data, data_len);
	if (rv < 0)
		goto out_close;
	*(data+data_len) = '\0';

	*(data + data_len) = '\0';
	(void)fputs(data, stdout);
	fflush(stdout);
	rv = 0;

out_test_reply:
	rv = test_reply_f(ntohl(reply.header.result), cmd);
out_close:
	tpt->close(site);
out:
	if (data)
		free(data);
	return rv;
}