コード例 #1
0
ファイル: main.c プロジェクト: danfrincu/booth
static int loop(int type)
{
	void (*workfn) (int ci);
	void (*deadfn) (int ci);
	int rv, i;

	rv = setup_config(type);
	if (rv < 0)
		goto fail;

	rv = setup_timer();
	if (rv < 0)
		goto fail;

	rv = setup_transport();
	if (rv < 0)
		goto fail;

	rv = setup_ticket();
	if (rv < 0)
		goto fail;

	rv = setup_listener(BOOTHC_SOCK_PATH);
	if (rv < 0)
		goto fail;
	client_add(rv, process_listener, NULL);

        while (1) {
                rv = poll(pollfd, client_maxi + 1, poll_timeout);
                if (rv == -1 && errno == EINTR)
                        continue;
                if (rv < 0) {
                        log_error("poll errno %d", errno);
			goto fail;
                }

                for (i = 0; i <= client_maxi; i++) {
                        if (client[i].fd < 0)
                                continue;
                        if (pollfd[i].revents & POLLIN) {
                                workfn = client[i].workfn;
                                if (workfn)
                                        workfn(i);
                        }
                        if (pollfd[i].revents &
			    (POLLERR | POLLHUP | POLLNVAL)) {
                                deadfn = client[i].deadfn;
                                if (deadfn)
                                        deadfn(i);
                        }
                }

		process_timerlist();
	}

	return 0;

fail:
	return -1;
}
コード例 #2
0
ファイル: main.c プロジェクト: inouekazu/booth
static int loop(int fd)
{
	void (*workfn) (int ci);
	void (*deadfn) (int ci);
	int rv, i;

	rv = setup_transport();
	if (rv < 0)
		goto fail;

	rv = setup_ticket();
	if (rv < 0)
		goto fail;

	rv = write_daemon_state(fd, BOOTHD_STARTED);
	if (rv != 0) {
		log_error("write daemon state %d to lockfile error %s: %s",
                      BOOTHD_STARTED, cl.lockfile, strerror(errno));
		goto fail;
	}

	log_info("BOOTH %s daemon started, node id is 0x%08X (%d).",
		type_to_string(local->type),
			local->site_id, local->site_id);

	while (1) {
		rv = poll(pollfds, client_maxi + 1, poll_timeout);
		if (rv == -1 && errno == EINTR)
			continue;
		if (rv < 0) {
			log_error("poll failed: %s (%d)", strerror(errno), errno);
			goto fail;
		}

		for (i = 0; i <= client_maxi; i++) {
			if (clients[i].fd < 0)
				continue;

			if (pollfds[i].revents & POLLIN) {
				workfn = clients[i].workfn;
				if (workfn)
					workfn(i);
			}
			if (pollfds[i].revents &
					(POLLERR | POLLHUP | POLLNVAL)) {
				deadfn = clients[i].deadfn;
				if (deadfn)
					deadfn(i);
			}
		}

		process_tickets();
	}

	return 0;

fail:
	return -1;
}
コード例 #3
0
ファイル: main.c プロジェクト: aspiers/booth
static int loop(void)
{
	void (*workfn) (int ci);
	void (*deadfn) (int ci);
	int rv, i;

        while (1) {
                rv = poll(pollfd, client_maxi + 1, poll_timeout);
                if (rv == -1 && errno == EINTR)
                        continue;
                if (rv < 0) {
                        log_error("poll failed: %s (%d)", strerror(errno), errno);
                        goto fail;
                }

                for (i = 0; i <= client_maxi; i++) {
                        if (client[i].fd < 0)
                                continue;
                        if (pollfd[i].revents & POLLIN) {
                                workfn = client[i].workfn;
                                if (workfn)
                                        workfn(i);
                        }
                        if (pollfd[i].revents &
			    (POLLERR | POLLHUP | POLLNVAL)) {
                                deadfn = client[i].deadfn;
                                if (deadfn)
                                        deadfn(i);
                        }
                }

		process_timerlist();
	}

	return 0;

fail:
	return -1;
}
コード例 #4
0
ファイル: main.c プロジェクト: aspiers/booth
void process_connection(int ci)
{
	struct boothc_header h;
	char *data = NULL;
	char *site, *ticket;
	int local, rv;
	void (*deadfn) (int ci);

	rv = do_read(client[ci].fd, &h, sizeof(h));

	if (rv < 0) {
		if (errno == ECONNRESET)
			log_debug("client %d connection reset for fd %d", ci, client[ci].fd);
		else 
			log_debug("client %d read failed for fd %d: %s (%d)",
				  ci, client[ci].fd,
				  strerror(errno), errno);

		deadfn = client[ci].deadfn;
		if(deadfn) {
			log_debug("run deadfn");
			deadfn(ci);
		}
		return;
	}
	if (h.magic != BOOTHC_MAGIC) {
		log_error("connection %d magic error %x", ci, h.magic);
		return;
	}
	if (h.version != BOOTHC_VERSION) {
		log_error("connection %d version error %x", ci, h.version);
		return;
	}

	if (h.len) {
		data = malloc(h.len);
		if (!data) {
			log_error("process_connection no mem %u", h.len);
			return;
		}
		memset(data, 0, h.len);

		rv = do_read(client[ci].fd, data, h.len);
		if (rv < 0) {
			log_error("connection %d read data error %d", ci, rv);
			goto out;
		}
	}

	switch (h.cmd) {
	case BOOTHC_CMD_LIST:
		assert(!data);
		h.result = list_ticket(&data, &h.len);
		break;

	case BOOTHC_CMD_GRANT:
		h.len = 0;
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = grant_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_REVOKE:
		h.len = 0;
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = revoke_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_CATCHUP:
		h.result = catchup_ticket(&data, h.len);	
		break;

	default:
		log_error("connection %d cmd %x unknown", ci, h.cmd);
		break;
	}

reply:
	rv = do_write(client[ci].fd, &h, sizeof(h));
	if (rv < 0)
		log_error("connection %d write error %d", ci, rv);
	if (h.len) {
		rv = do_write(client[ci].fd, data, h.len);
		if (rv < 0)
			log_error("connection %d write error %d", ci, rv);
	}
out:
	free(data);	
}
コード例 #5
0
ファイル: main.c プロジェクト: Ferritt1975/booth
/* Only used for client requests, TCP ???*/
void process_connection(int ci)
{
	struct boothc_ticket_msg msg;
	int rv, len, expr, fd;
	void (*deadfn) (int ci);


	fd = clients[ci].fd;
	rv = do_read(fd, &msg.header, sizeof(msg.header));

	if (rv < 0) {
		if (errno == ECONNRESET)
			log_debug("client %d connection reset for fd %d",
					ci, clients[ci].fd);

		goto kill;
	}

	if (check_boothc_header(&msg.header, -1) < 0)
		goto kill;

	/* Basic sanity checks already done. */
	len = ntohl(msg.header.length);
	if (len) {
		if (len != sizeof(msg)) {
bad_len:
			log_error("got wrong length %u", len);
			return;
		}
		expr = len - sizeof(msg.header);
		rv = do_read(clients[ci].fd, msg.header.data, expr);
		if (rv < 0) {
			log_error("connection %d read data error %d, wanted %d",
					ci, rv, expr);
			goto kill;
		}
	}


	/* For CMD_GRANT and CMD_REVOKE:
	 * Don't close connection immediately, but send
	 * result a second later? */
	switch (ntohl(msg.header.cmd)) {
	case CMD_LIST:
		ticket_answer_list(fd, &msg);
		goto kill;

	case CMD_GRANT:
	case CMD_REVOKE:
		/* Expect boothc_ticket_site_msg. */
		if (len != sizeof(msg))
			goto bad_len;
		process_client_request(&clients[ci], &msg);
		return;

	default:
		log_error("connection %d cmd %x unknown",
				ci, ntohl(msg.header.cmd));
		init_header(&msg.header, CL_RESULT, 0, 0, RLT_INVALID_ARG, 0, sizeof(msg.header));
		send_header_only(fd, &msg.header);
		goto kill;
	}

	assert(0);
	return;

kill:
	deadfn = clients[ci].deadfn;
	if(deadfn) {
		deadfn(ci);
	}
	return;
}