gawk

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

commit 07d81ad3a7d2a9e134595fff249b3ae89172d740
parent eb0c6118a0a696be48995faa496e1c919252e2cb
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Thu, 24 Dec 2020 00:04:56 -0800

Allow cfetch to download into a specified directory

Diffstat:
Mmain.c | 52+++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/main.c b/main.c @@ -35,7 +35,7 @@ #define LEN(X) (sizeof(X) / sizeof(*X)) -enum address { AR_PATH, AR_HOST, AR_PORT, AR_NULL }; /* NOTE: see reqtoaddr() */ +enum address { AR_PATH, AR_HOST, AR_PORT, AR_NULL }; /* NOTE: see itemtoaddr() */ enum gphitem { GI_INFO, GI_PATH, GI_HOST, GI_PORT, GI_PLUS, GI_NULL }; enum status { ERROR = -1, OK, UNWIND }; @@ -51,7 +51,7 @@ static int timeout = 5 * 1000; /* This exists to make it easy to track down later */ const char ** -reqtoaddr(const char **request) +itemtoaddr(const char **request) { return request + 1; } @@ -123,6 +123,16 @@ exists(const char *path) } int +isdir(const char *path) +{ + struct stat sb; + + if (stat(path, &sb) == -1 && errno == ENOENT) + return 0; + return S_ISDIR(sb.st_mode); +} + +int strtorange(unsigned int *r, unsigned int min, unsigned int max, const char *s) { char *ep; @@ -450,23 +460,43 @@ cprintn(int argc, const char **argv, int i, const char **s) } int -cfetch(int argc, const char **argv, int i, const char **request) +timid_gopher(const char **addr, const char *path) +{ + if (!exists(path)) + return gopher(addr, path); + warnc(EEXIST, "'%s'", path); + return 1; +} + +int +cfetch(int argc, const char **argv, int i, const char **item) { - const char *output; + const char *path; + char pathbuf[MY_PATH_MAX]; if (warg(0, 1, argc, argv)) 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]); + if (!argv[0]) + path = basename(item[GI_PATH]); + else if (!isdir(argv[0])) + path = argv[0]; + else { + path = basename(item[GI_PATH]); + if (path != NULL) { + snprintf(pathbuf, sizeof(pathbuf), "%s/%s", argv[0], path); + path = pathbuf; + } + } + + if (!path) { + warn("Unable to get basename '%s'", item[GI_PATH]); return ERROR; } - if (gopher(reqtoaddr(request), output) != 0) + if (timid_gopher(itemtoaddr(item), path)) return ERROR; - warnx("'%s/%s' written to '%s'", request[GI_HOST], request[GI_PATH], output); + warnx("'%s%s' written to '%s'", item[GI_HOST], item[GI_PATH], path); return 0; } @@ -500,7 +530,7 @@ cextern(int argc, const char **argv, int index, const char **item) int cgoto(int argc, const char **argv, int index, const char **item) { - return gawk(reqtoaddr(item)); + return gawk(itemtoaddr(item)); } item_command *