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:
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') {