~sircmpwn/himitsu

17e02672451151302fcdc6d5eac1f727c713770c — Drew DeVault a month ago c629782
Buffer client data and split into lines
2 files changed, 74 insertions(+), 10 deletions(-)

M himitsud/service.c
M include/service.h
M himitsud/service.c => himitsud/service.c +70 -9
@@ 20,8 20,8 @@ static void
client_hup(struct hi_service *service, struct hi_service_client *client)
{
	for (size_t i = 0; i < service->nfds; ++i) {
		if (service->fds[i].fd == client->clientfd) {
			close(client->clientfd);
		if (service->fds[i].fd == client->fd) {
			close(client->fd);
			free(client->buffer);
			--service->nfds;
			int r = service->nfds - i;


@@ 38,6 38,34 @@ client_hup(struct hi_service *service, struct hi_service_client *client)
}

static void
client_oom(struct hi_service *service, struct hi_service_client *client)
{
	char *error = "error out of memory\n";
	write(client->fd, error, sizeof(error) - 1);
	client_hup(service, client);
}

static void
client_errno(struct hi_service *service, struct hi_service_client *client)
{
	char buf[1024];
	int n = snprintf(buf, sizeof(buf), "error %s\n", strerror(errno));
	if (n <= 0 || (size_t)n >= sizeof(buf)) {
		strcpy(buf, "error meta-error\n");
	}
	write(client->fd, buf, strlen(buf));
	client_hup(service, client);
}

static void
process_client_cmd(struct hi_service *service,
		struct hi_service_client *client,
		const char *cmd)
{
	fprintf(stderr, "client cmd: %s\n", cmd);
}

static void
client_readable(struct hi_service *service,
		struct hi_service_client *client,
		short revents)


@@ 46,6 74,40 @@ client_readable(struct hi_service *service,
		client_hup(service, client);
		return;
	}
	if (client->bufsz - client->buflen < 1024) {
		size_t desired = client->bufsz + 4096;
		if (desired >= HISERVICE_MAX_BUFSZ) {
			char *error = "error exceeded max packet size\n";
			write(client->fd, error, sizeof(error) - 1);
			client_hup(service, client);
			return;
		}
		char *newbuf = realloc(client->buffer, desired + 1 /* NUL */);
		if (!newbuf) {
			client_oom(service, client);
			return;
		}
		client->buffer = newbuf;
		client->bufsz = desired;
	}
	ssize_t n = read(client->fd, &client->buffer[client->buflen],
			client->bufsz - client->buflen);
	if (n < 0) {
		client_errno(service, client);
		return;
	}
	client->buflen += n;
	client->buffer[client->buflen] = '\0';
	char *newline;
	while (client->buflen && (newline = strchr(client->buffer, '\n'))) {
		*newline = '\0';
		process_client_cmd(service, client, client->buffer);
		size_t l = newline - client->buffer;
		++l;
		memmove(client->buffer, &client->buffer[l], client->buflen - l);
		client->buflen -= l;
		client->buffer[client->buflen] = '\0';
	}
}

static void


@@ 87,7 149,10 @@ accept_client(struct hi_service *service)
	service->fds[service->nfds].fd = clientfd;
	service->fds[service->nfds].events = POLLIN | POLLHUP | POLLERR;
	struct hi_service_client *client = &service->clients[service->nfds - 1];
	client->clientfd = clientfd;
	client->fd = clientfd;
	client->bufsz = 4096;
	client->buflen = 0;
	client->buffer = calloc(client->bufsz + 1 /* NUL */, 1);
	++service->nfds;
}



@@ 182,12 247,8 @@ himitsu_service_run(struct hi_service *service)
void
himitsu_service_finish(struct hi_service *service)
{
	close(service->sockfd);
	for (size_t i = 0; i < sizeof(service->clients)
			/ sizeof(service->clients[0]); ++i) {
		if (service->clients[i].clientfd > 0) {
			close(service->clients[i].clientfd);
		}
	for (size_t i = 0; i < service->nfds; ++i) {
		close(service->fds[i].fd);
	}
	unlink(service->sockpath);
	free(service->sockpath);

M include/service.h => include/service.h +4 -1
@@ 4,11 4,14 @@
#include <stdbool.h>

#define HISERVICE_MAX_FDS 128
#define HISERVICE_MAX_BUFSZ 16384

struct hi_secstore;

struct hi_service_client {
	int clientfd;
	int fd;
	char *buffer;
	size_t bufsz, buflen;
};

struct hi_service {