ap

An audio player suited to my tastes
Log | Files | Refs | README | LICENSE

commit b812bd1c77fa47277f75c5d161962ce4941176c3
parent d232acdd309a71bd6f7bf92edea2573ff289c77b
Author: Jacob R. Edwards <n/a>
Date:   Thu, 13 Oct 2022 17:59:03 -0700

Implement common reading functions between client and server

Diffstat:
Maps/aps.c | 64+++++++++++++++++++++++-----------------------------------------
Maps/aps.h | 2+-
Mlib/ap/Makefile | 2+-
Mlib/ap/ap.h | 1+
Mlib/ap/buf.c | 19+++++++++++++++++++
Mlib/ap/buf.h | 1+
Mlib/ap/client.c | 33++++++---------------------------
7 files changed, 52 insertions(+), 70 deletions(-)

diff --git a/aps/aps.c b/aps/aps.c @@ -217,54 +217,38 @@ aps_update(struct aps *aps) return 0; } -char * -aps_read(struct aps *aps, int s) +int +aps_read(struct aps *aps, int fd, char **command) { - char *end; - int len; - struct buf *buf; - - buf = aps->clients[s].request; - if (buf->len == buf->size) { - if (buf->size == UINT_MAX || bufresize(buf, - (buf->size > UINT_MAX / 4) ? UINT_MAX : (MAX(128, buf->size) * 4))) { - aps_errordrop(aps, s, errstr); - return NULL; - } - } - - len = recv(s, buf->data + buf->len, buf->size - buf->len, 0); - if (len == -1) - return NULL; - buf->len += len; + ssize_t len; - end = memchr(buf->data + (buf->len - len), '\n', len); - if (end == NULL) - return NULL; /* not a full command yet */ - *end = 0; - - return end + 1; + len = bufread(aps->clients[fd].request, fd, 4096); + if (len <= 0) + return -1; + return bufgetline(aps->clients[fd].request, command) < 0; } int -aps_command(struct aps *aps, int s) +aps_command(struct aps *aps, int fd) { char *(*com)(struct aps *, int, int, char **); - char **argv; - char *next; + char *buf, **argv; char *status; - struct buf *buf; unsigned int i; - unsigned int len; - if ((next = aps_read(aps, s)) == NULL) + buf = NULL; + if (aps_read(aps, fd, &buf) < 0) + return -1; + if (buf == NULL) return 0; - buf = aps->clients[s].request; - aps_logfmt(aps, COMMAND, s, "input '%s'", buf->data); - argv = asplit(buf->data, NULL); - if (argv == NULL) - return 1; + aps_logfmt(aps, COMMAND, fd, "input '%s'", buf); + + argv = asplit(buf, NULL); + if (argv == NULL) { + status = "Unable to split arguments"; + goto exit; + } if (*argv == NULL) { status = "No command"; goto exit; @@ -277,14 +261,12 @@ aps_command(struct aps *aps, int s) if (com == NULL) status = "Command not found"; else - status = com(aps, s, arglen(argv + 1), argv + 1); + status = com(aps, fd, arglen(argv + 1), argv + 1); exit: - len = next - (char *)buf->data; - bufshift(buf, len); - free(argv); - return aps_bufstatus(aps, s, status); + free(buf); + return aps_bufstatus(aps, fd, status); } void diff --git a/aps/aps.h b/aps/aps.h @@ -30,7 +30,7 @@ int aps_respond(struct aps *, int); int aps_handle(struct aps *, int); int aps_named(struct aps *); int aps_update(struct aps *); -char *aps_read(struct aps *, int); +int aps_read(struct aps *, int, char **); int aps_command(struct aps *, int); void aps_errordrop(struct aps *, int, char *); char *aps_seek(struct aps *, char *); diff --git a/lib/ap/Makefile b/lib/ap/Makefile @@ -1,5 +1,5 @@ name = ap -src = buf.c client.c con.c item.c quote.c sock.c +src = buf.c client.c con.c item.c quote.c read.c sock.c inc = ap.h ${src:.c=.h} cflags = -I.. diff --git a/lib/ap/ap.h b/lib/ap/ap.h @@ -2,4 +2,5 @@ #include "con.h" #include "item.h" #include "quote.h" +#include "read.h" #include "sock.h" diff --git a/lib/ap/buf.c b/lib/ap/buf.c @@ -141,3 +141,22 @@ bufline(struct buf *buf, char *line) return 1; return bufappend(buf, "\n", 1); } + +int +bufgetline(struct buf *buf, char **line) +{ + char *end; + size_t len; + + if (!(end = memchr(buf->data, '\n', buf->len))) + return 0; + + len = end - buf->data; + if (!(*line = malloc(len))) + return -1; + + memcpy(*line, buf->data, len - 1); + (*line)[len] = 0; + bufshift(buf, len); + return 1; +} diff --git a/lib/ap/buf.h b/lib/ap/buf.h @@ -12,3 +12,4 @@ int bufappend(struct buf *, void *, size_t); int bufshift(struct buf *, size_t); int bufword(struct buf *, char *); int bufline(struct buf *, char *); +int bufgetline(struct buf *, char **); diff --git a/lib/ap/client.c b/lib/ap/client.c @@ -78,44 +78,23 @@ apc_write(struct apc *apc) return n <= 0; } -int -apc_recv(struct apc *apc) -{ - char buf[4096]; - int len; - - len = recv(apc->con->sock, buf, sizeof(buf), 0); - if (len <= 0) - return 1; - return bufappend(apc->response, buf, len); -} - char * apc_read(struct apc *apc) { - size_t offset, len; - char *buf, *end; + ssize_t len; + char *buf; if (apc->status) { free(apc->status); apc->status = NULL; } - for (offset = 0; (end = memchr(apc->response->data + offset, '\n', - apc->response->len - offset)) == NULL;) { - offset += apc->response->len; - if (apc_recv(apc)) + buf = NULL; + while ((len = bufgetline(apc->response, &buf)) == 0) + if (bufread(apc->response, apc->con->sock, 4096) <= 0) return NULL; - } - - len = end - apc->response->data; - buf = malloc(len + 1); - if (buf == NULL) + if (len < 0) return NULL; - memcpy(buf, apc->response->data, len); - buf[len] = 0; - - bufshift(apc->response, len + 1); if (strcmp(buf, "ok") == 0 || strncmp(buf, "error: ", 7) == 0) { if (*buf == 'e') {