commit 87e78340cd1dde90cef00cb1bed8a0f475fbb6eb
parent 0bd4422223828bc88630c2f39bcea3a22a2c12ef
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date: Sat, 19 Dec 2020 18:51:04 -0800
Fix and polish requests and caching
It seems one should actually _read the specification_ of a protocol
which they are implementing a client for. As proof the issue with
multiple requests was that you cannot reuse connections.
The prompt is now printed to stderr.
Diffstat:
M | main.c | | | 77 | ++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/main.c b/main.c
@@ -114,7 +114,7 @@ input(char *buf, int size, const char *prompt, FILE *fp)
{
int len;
- fputs(prompt, stdout);
+ fputs(prompt, stderr);
if (fgets(buf, size, fp) == NULL)
return 1;
@@ -243,6 +243,33 @@ putfile(const char *path)
}
int
+gphsend(int sock, const char *request)
+{
+ if (send(sock, request, strlen(request), 0) == -1) {
+ warn("unable to send request");
+ return 1;
+ }
+ return 0;
+}
+
+int
+gphcache(const char *cache, const char *host, const char *path, const char *port)
+{
+ int sock;
+
+ sock = connect_to(host, port);
+ if (sock == -1)
+ return 1;
+
+ if (gphsend(sock, path) != 0 ||
+ fetch(sock, cache) != 0) {
+ close(sock);
+ return 1;
+ }
+ return close(sock);
+}
+
+int
gawkat(const char *path)
{
if (putfile(path) != 0)
@@ -253,7 +280,7 @@ gawkat(const char *path)
/* returns `<0` on error, if positive `n - 1` is
* be returned to the caller. */
int
-gawk(int sock, int depth, const char *tmpdir, const char *host, const char *path, const char *port)
+gawk(int depth, const char *tmpdir, const char *host, const char *path, const char *port)
{
char *argv[ARGV_MAX];
char inbuf[PATH_MAX + HOST_NAME_MAX + PROTO_MAX];
@@ -261,34 +288,23 @@ gawk(int sock, int depth, const char *tmpdir, const char *host, const char *path
char cache[PATH_MAX];
const char *nreq[3];
int argc;
- int closeit, unlinkit, done, newsock;
+ int unlinkit;
+ int done;
++depth;
- if (sock != -1) {
- closeit = 0;
- } else {
- closeit = 1;
- sock = connect_to(host, port);
- if (sock == -1)
- return -1;
- }
-
getcache(cache, tmpdir, host, port, path);
-
- unlinkit = 0;
- if (!exists(cache)) {
- if (send(sock, path, strlen(path), 0) == -1) {
- warn("unable to send request");
- return 1;
- }
- if (fetch(sock, cache) != 0)
- return 0; /* just return to the previous, if any. */
+ if (exists(cache))
+ unlinkit = 0;
+ else {
unlinkit = 1;
+ if (gphcache(cache, host, path, port) == 1)
+ return 0; /* let the user handle it */
}
done = 0;
snprintf(prompt, sizeof(prompt), "[%s] %s ", host, path);
+ gawkat(cache);
while (!done && input(inbuf, sizeof(inbuf), prompt, stdin) == 0) {
argc = argsplit(argv, LEN(argv), inbuf, ARG_SEP);
if (argc <= 0) {
@@ -320,7 +336,6 @@ gawk(int sock, int depth, const char *tmpdir, const char *host, const char *path
if (argc > 4)
goto invalid_input;
- newsock = 0;
nreq[0] = host;
nreq[1] = path;
nreq[2] = port;
@@ -333,18 +348,12 @@ gawk(int sock, int depth, const char *tmpdir, const char *host, const char *path
else {
nreq[0] = argv[1];
nreq[1] = argv[2];
- if (strcmp(host, nreq[0]) != 0)
- newsock = -1;
- if (argc == 3) {
+ if (argc == 3)
nreq[2] = argv[3];
- if (!newsock && strcmp(port, nreq[2]) != 0)
- newsock = -1;
- }
}
-
- if (!newsock)
- newsock = sock;
- done = gawk(newsock, depth, tmpdir, nreq[0], nreq[1], nreq[2]);
+ done = gawk(depth, tmpdir, nreq[0], nreq[1], nreq[2]);
+ if (done == 0)
+ gawkat(cache);
break;
default:
invalid_input:
@@ -354,8 +363,6 @@ invalid_input:
if (unlinkit && unlink(cache) == -1)
warn("unable to unlink '%s'", cache);
- if (closeit && close(sock) == -1)
- warn("unable to disconnect from '%s'", host);
if (ferror(stdin)) {
warn("'stdin'");
return -1;
@@ -371,7 +378,7 @@ main(int argc, char *argv[])
if (mkdtemp(t) == NULL)
err(1, "unable to create temp dir");
- gawk(-1, 0, t, "localhost", "/","gopher");
+ gawk(0, t, "localhost", "/","gopher");
if (rmdir(t) == -1)
err(1, "unable to remove temp dir");