commit 83fc771d7dc844383b4db3dce8d60fa668200b2b
parent 5d1d82df44be5ed2fd399a7a1c2f4c97ebeca954
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date: Wed, 23 Dec 2020 15:33:12 -0800
Fix error handling
gawk() now ignores errors unless the new global fatal flag is set.
Diffstat:
M | main.c | | | 41 | ++++++++++++++++++++++------------------- |
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/main.c b/main.c
@@ -43,9 +43,9 @@
#define MY_URL_MAX 72
#define MY_FILTER_MAX 4
+enum address { AR_PATH, AR_HOST, AR_PORT, AR_NULL }; /* NOTE: see reqtoaddr() */
enum gphitem { GI_INFO, GI_PATH, GI_HOST, GI_PORT, GI_NULL };
-/* NOTE: before changing see reqtoaddr() */
-enum address { AR_PATH, AR_HOST, AR_PORT, AR_NULL };
+enum status { ERROR = -1, OK, UNWIND };
typedef int (item_command)(int, const char **, int, const char **);
typedef int (filter)(int, const char **, unsigned int, const char **);
@@ -56,6 +56,7 @@ int gawk(const char **);
static int timeout = 5 * 1000;
static char tmpdir[] = "/tmp/gawk-XXXXXXXXXXX";
static const char *default_address[] = { "/", "localhost", "70" };
+static int fatal;
/* This exists to make it easy to track down later */
const char **
@@ -311,7 +312,6 @@ gph_write(const char **addr, const char *path)
return close(sock);
}
-/* Returns -1 on fatal error, 0 on no match, and 1 on match. */
int
splitrun(filter **filters, int argc, const char **argv, unsigned int index, char *s, item_command *func)
{
@@ -323,7 +323,7 @@ splitrun(filter **filters, int argc, const char **argv, unsigned int index, char
/* NOTE: not foolproof */
if (item[4] != NULL && strcmp(item[4], "+") != 0) {
warnx("%d: Not a valid gopher item.", index);
- return 1;
+ return UNWIND;
}
for (i = 0; filters[i] != NULL; ++i) {
@@ -347,12 +347,13 @@ run_filters(const char *cache, filter **filters, int argc, const char **argv, it
fp = wfopen(cache, "r");
if (fp == NULL)
- return 1;
+ return UNWIND;
error = 0;
- for (i = 0; !error && fgets(item, sizeof(item), fp) != NULL && *item != '.'; ++i)
+ for (i = 0; !error && fgets(item, sizeof(item), fp) && *item != '.'; ++i)
error = splitrun(filters, argc, argv, i, item, func);
- wfclose(fp); /* not fatal */
+
+ wfclose(fp);
return error;
}
@@ -414,7 +415,7 @@ sgoto(int argc, const char **argv, int depth, const char **addr)
const char *newaddr[AR_NULL];
if (warg(0, 3, argc, argv))
- return 1;
+ return ERROR;
newaddr[AR_HOST] = addr[AR_HOST];
newaddr[AR_PATH] = "/";
@@ -438,12 +439,12 @@ sunwind(int argc, const char **argv, int depth, const char **addr)
unsigned int n;
if (warg(0, 1, argc, argv))
- return 1;
+ return ERROR;
if (argc == 0)
n = 1;
else if (strtorange(&n, 1, INT_MAX, argv[0]))
- return 0;
+ return ERROR;
return n;
}
@@ -479,17 +480,17 @@ cfetch(int argc, const char **argv, int i, const char **request)
const char *output;
if (warg(0, 1, argc, argv))
- return 0;
+ return ERROR;
if (argc > 0)
output = argv[0];
else if ((output = basename(request[GI_PATH])) == NULL) {
warn("unable to get basename '%s'", request[GI_PATH]);
- return 0;
+ return ERROR;
}
if (gph_write(reqtoaddr(request), output) != 0)
- return 0;
+ return ERROR;
warnx("'%s/%s' written to '%s'", request[GI_HOST], request[GI_PATH], output);
return 0;
}
@@ -501,7 +502,7 @@ cextern(int argc, const char **argv, int index, const char **item)
int i;
if (warg(1, -1, argc, argv))
- return 0;
+ return ERROR;
snprintf(url, sizeof(url), "%s/%s", item[GI_HOST], item[GI_PATH]);
for (i = 0; i < argc; ++i)
@@ -511,7 +512,7 @@ cextern(int argc, const char **argv, int index, const char **item)
switch (fork()) {
case -1:
warn("unable to fork");
- return 0;
+ return ERROR;
case 0:
execvp(*argv, (char *const *)argv);
warn("execvp '%s'", *argv);
@@ -588,20 +589,20 @@ execute(int argc, const char **argv, int depth, const char *cache,
unsigned int i;
if (argc == 0 || argv[0][0] == '\0')
- return 0;
+ return ERROR;
filters[0] = NULL;
for (i = 0; argv[0][i + 1] != '\0' && i < LEN(filters) - 1; ++i) {
filters[i] = getfilter(argv[0][i]);
if (filters[i] == NULL) {
warnx("'%c': Not a filter.", argv[0][i]);
- return 0;
+ return ERROR;
}
}
filters[i] = NULL;
if (argv[0][i + 1] != '\0') {
warnx("Too many filters");
- return 0;
+ return ERROR;
}
cmd = NULL;
@@ -610,7 +611,7 @@ execute(int argc, const char **argv, int depth, const char *cache,
cmd = getstackc(argv[0][i]);
if (cmd == NULL) {
warnx("'%c': Not a command.", argv[0][i]);
- return 0;
+ return ERROR;
}
}
@@ -663,6 +664,8 @@ gawk(const char **addr)
warnx("Too many arguments.");
} else if (argc > 0) {
done = execute(argc, (const char **)argv, depth, cache, addr);
+ if (done == ERROR && !fatal)
+ done = 0;
}
}