gawk

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

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:
Mmain.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; } }