commit e6092335feee193caeb1360be8a95c61756b2729
parent 9787d16a53436f6c7bfeb54b03dd2b695981fa70
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date: Sat, 19 Dec 2020 14:12:13 -0800
Add caching
Add file caching although you still cannot display the content.
Diffstat:
M | main.c | | | 123 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 66 insertions(+), 57 deletions(-)
diff --git a/main.c b/main.c
@@ -33,7 +33,16 @@
#define ARGV_MAX 16
#define ARG_SEP ":\t "
-static char *format_prog = "gophmt"; /* not released, costom formatter */
+FILE *
+wfopen(const char *path, const char *mode)
+{
+ FILE *fp;
+
+ fp = fopen(path, mode);
+ if (fp == NULL)
+ warn("unable to open '%s' ('%s')", path, mode);
+ return fp;
+}
int
resolve(struct addrinfo **ai, const char *host, const char *proto)
@@ -134,6 +143,22 @@ newpath(char *path, char *newpath)
}
}
+void
+getcache(char *cache, const char *tmpdir, const char *host, const char *port, const char *path)
+{
+ int i;
+ char tmp[PATH_MAX];
+
+ for (i = 0; path[i] != '\0'; ++i) {
+ if (path[i] == '/')
+ tmp[i] = '-';
+ else
+ tmp[i] = path[i];
+ }
+ tmp[i] = '\0';
+ snprintf(cache, PATH_MAX, "%s/%s-%s-%s", tmpdir, host, port, tmp);
+}
+
int
argsplit(char **argv, int arg_max, char *s, const char *sep)
{
@@ -151,81 +176,47 @@ argsplit(char **argv, int arg_max, char *s, const char *sep)
return argc;
}
-/* NOTE: implement caching */
int
-getgph(int sock, const char *path)
+fetch(int sock, const char *path)
{
- ssize_t bytes;
+ FILE *fp;
char buf[BUFSIZE];
+ ssize_t bytes;
+ int error;
- /* NOTE: SIGPIPE is recieved */
- if (send(sock, path, strlen(path), 0) == -1) {
- warn("unable to send request");
+ fp = wfopen(path, "w+");
+ if (fp == NULL)
return 1;
- }
while ((bytes = recv(sock, buf, sizeof(buf), 0)) > 0) {
- if (fwrite(buf, 1, bytes, stdout) != bytes)
+ if (fwrite(buf, 1, bytes, fp) != bytes) {
+ fclose(fp);
return 1;
+ }
}
+ error = ferror(fp);
+ if (fclose(fp) || error)
+ return 1;
return 0;
}
int
-gawkat(int sock, const char *path)
+gawkat(const char *path)
{
- int status;
- int fds[2];
- char *argv[2];
-
- if (pipe(fds) == -1) {
- warn("unable to pipe");
- return 1;
- }
-
- argv[0] = format_prog;
- argv[1] = NULL;
-
- switch (fork()) {
- case -1:
- warn("unable to fork");
- return 1;
- case 0:
- if (dup2(fds[1], STDIN_FILENO) == -1) {
- warn("unable to setup pipe");
- _exit(1);
- }
- execvp(*argv, argv);
- warn("execvp %s", *argv);
- return 1;
- default:
- if (dup2(fds[0], STDOUT_FILENO) == -1) {
- warn("unable to setup pipe");
- status = 1;
- break;
- }
- if ((status = getgph(sock, path)) == 0) {
- wait(&status);
- if (status)
- warnx("child exited %d", status);
- }
- }
-
- if (close(fds[0]) || close(fds[1]))
- warn("unable to close pipe");
-
- return status;
+ printf("gawking at %s\n", path);
+ return 0;
}
/* returns `<0` on error, if positive `n - 1` is
* be returned to the caller. */
int
-gawk(int sock, int depth, const char *host, const char *path, const char *port)
+gawk(int sock, 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];
char prompt[64]; /* you wouldn't want it longer anyway */
+ char cache[PATH_MAX];
const char *nreq[3];
int argc;
int closeit, done, newsock;
@@ -241,6 +232,16 @@ gawk(int sock, int depth, const char *host, const char *path, const char *port)
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);
done = 0;
@@ -261,9 +262,7 @@ gawk(int sock, int depth, const char *host, const char *path, const char *port)
done = depth;
break;
case 'p': /* print */
- puts("gawking");
- /* NOTE: SIGPIPE on second call.
- * gawkat(sock, path); */
+ gawkat(path);
break;
case 'b': /* back */
if (argc > 2)
@@ -301,7 +300,7 @@ gawk(int sock, int depth, const char *host, const char *path, const char *port)
if (!newsock)
newsock = sock;
- done = gawk(newsock, depth, nreq[0], nreq[1], nreq[2]);
+ done = gawk(newsock, depth, tmpdir, nreq[0], nreq[1], nreq[2]);
break;
default:
invalid_input:
@@ -309,6 +308,8 @@ invalid_input:
}
}
+ /* NOTE: cleanup cache files IF created in this function */
+
if (closeit && close(sock) == -1)
warn("unable to disconnect from '%s'", host);
if (ferror(stdin)) {
@@ -321,7 +322,15 @@ invalid_input:
int
main(int argc, char *argv[])
{
- gawk(-1, 0, "localhost", "/","gopher");
+ char t[64];
+ strcpy(t, "/tmp/gawk-XXXXXXXXXXX");
+ if (mkdtemp(t) == NULL)
+ err(1, "unable to create temp dir");
+
+ gawk(-1, 0, t, "localhost", "/","gopher");
+
+ if (rmdir(t) == -1)
+ err(1, "unable to remove temp dir");
return 0;
}