gawk

[old] Sed-like interface to the Gopher protocol
Log | Files | Refs | LICENSE

commit 0bd4422223828bc88630c2f39bcea3a22a2c12ef
parent e6092335feee193caeb1360be8a95c61756b2729
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Sat, 19 Dec 2020 16:26:00 -0800

Polish caching

Remove files when not in use as would be expected and actually
display the cached content. Note that there is still trouble with
SIGPIPE.

Diffstat:
Mmain.c | 82++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 63 insertions(+), 19 deletions(-)

diff --git a/main.c b/main.c @@ -16,23 +16,37 @@ */ #include <sys/socket.h> +#include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> -#include <netdb.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> +#include <ctype.h> #include <err.h> #include <errno.h> #include <limits.h> -#include <ctype.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> #define LEN(X) (sizeof(X) / sizeof(*X)) + #define PROTO_MAX 16 #define BUFSIZE 4096 #define ARGV_MAX 16 #define ARG_SEP ":\t " +int +exists(const char *path) +{ + struct stat sb; + + if (stat(path, &sb) == -1 && errno == ENOENT) { + errno = 0; + return 0; + } + return 1; +} + FILE * wfopen(const char *path, const char *mode) { @@ -202,9 +216,37 @@ fetch(int sock, const char *path) } int +putfile(const char *path) +{ + FILE *in; + char buf[BUFSIZE]; + size_t bytes; + int error; + + in = wfopen(path, "r"); + if (in == NULL) + return 1; + + while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, bytes, stdout) != bytes) { + fclose(in); + warn("unable to write buffer"); + return 1; + } + } + + error = ferror(in); + if (fclose(in) || error) + warn("file error ocoured '%s'", path); + return 1; + return 0; +} + +int gawkat(const char *path) { - printf("gawking at %s\n", path); + if (putfile(path) != 0) + return 1; return 0; } @@ -219,7 +261,7 @@ 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, done, newsock; + int closeit, unlinkit, done, newsock; ++depth; @@ -232,19 +274,21 @@ gawk(int sock, int depth, const char *tmpdir, const char *host, const char *path return -1; } - if (send(sock, path, strlen(path), 0) == -1) { - warn("unable to send request"); - return 1; - } - - /* NOTE: could exist, test for it. */ getcache(cache, tmpdir, host, port, path); - if (fetch(sock, cache) != 0) - return 0; /* just return to the previous, if any. */ - snprintf(prompt, sizeof(prompt), "[%s] %s ", host, 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. */ + unlinkit = 1; + } done = 0; + snprintf(prompt, sizeof(prompt), "[%s] %s ", host, path); while (!done && input(inbuf, sizeof(inbuf), prompt, stdin) == 0) { argc = argsplit(argv, LEN(argv), inbuf, ARG_SEP); if (argc <= 0) { @@ -262,7 +306,7 @@ gawk(int sock, int depth, const char *tmpdir, const char *host, const char *path done = depth; break; case 'p': /* print */ - gawkat(path); + gawkat(cache); break; case 'b': /* back */ if (argc > 2) @@ -308,8 +352,8 @@ invalid_input: } } - /* NOTE: cleanup cache files IF created in this function */ - + 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)) {