commit 0eeeb0505fb7fd62a4ac1be9bfeac0070fd808c4
parent 05177ec3488a7ce20153d73f079433684c4631ce
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date: Mon, 21 Dec 2020 16:34:11 -0800
Move cfetch() line selection to external function
This was done for new commands which might make use of it.
Diffstat:
M | main.c | | | 97 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 67 insertions(+), 30 deletions(-)
diff --git a/main.c b/main.c
@@ -198,6 +198,38 @@ putprompt(const char *prompt)
warn("isatty %d", STDIN_FILENO);
}
+/* NOTE: Perhaps I should just store the gopher-text in an array.
+ * It would make this trivial and simple, simply `gphindex[N]`.
+ *
+ * It seems like too much though, it probably wouldn't exceed 1 MiB
+ * even after 1000 are stacked but it seems wrong. I suppose my
+ * /tmp is in memory anyway though. */
+char *
+getlines(unsigned int *i, unsigned int *indexes, int n, FILE *fp)
+{
+ char *line;
+ size_t size;
+ unsigned int j;
+ int more;
+
+ line = NULL;
+ size = 0;
+ more = 1;
+ for (; more && getline(&line, &size, fp) != -1; ++*i) {
+ more = 0;
+ for (j = 0; j < n; ++j) {
+ if (*i == indexes[j])
+ return line;
+ else if (*i < indexes[j])
+ more = 1;
+ }
+ }
+
+ if (line)
+ free(line);
+ return NULL;
+}
+
int
input(char *buf, int size, const char *delims, const char *prompt, FILE *fp)
{
@@ -439,6 +471,27 @@ cmatch(const char *path, int argc, const char **argv)
return 0;
}
+int
+getfromline(char *line, const char *output)
+{
+ char *fields[GI_NULL + 1];
+
+ if (argsplit(fields, LEN(fields), line, "\t\r\n") != LEN(fields) - 1) {
+ warnx("Not a valid gopher item.");
+ return 1;
+ }
+
+ if (output == NULL)
+ if ((output = basename(fields[GI_PATH])) == NULL) {
+ warn("unable to get basename '%s'", fields[GI_PATH]);
+ return 1;
+ }
+ if (selwrite(fields[GI_HOST], fields[GI_PORT], fields[GI_PATH], output) != 0)
+ return 1;
+ warnx("'%s/%s' written to '%s'", fields[GI_HOST], fields[GI_PATH], output);
+ return 0;
+}
+
/* argv[0] is the line index (starting from 0) of the file to
* download. If present argv[1] is the location to write the file
* to, otherwise it is written to the basename(3) of it's selector
@@ -448,12 +501,11 @@ int
cfetch(int argc, const char **argv, const char *cache, const char *host, const char *port)
{
FILE *fp;
- char *fields[GI_NULL + 1];
- char *line;
const char *output;
- int error;
- int i, n;
- size_t size;
+ char *line;
+ unsigned int i;
+ int n;
+ int status;
if (argc == 0) {
warn("No index given");
@@ -473,34 +525,19 @@ cfetch(int argc, const char **argv, const char *cache, const char *host, const c
if (fp == NULL)
return 1;
- error = 1;
- line = NULL;
- size = 0;
- for (i = 0; i <= n && getline(&line, &size, fp) != -1; ++i) {
- if (i == n) {
- if (argsplit(fields, LEN(fields), line, "\t\r\n") != LEN(fields) - 1) {
- warnx("Not a valid gopher item.");
- break;
- }
- if (output == NULL)
- if ((output = basename(fields[GI_PATH])) == NULL) {
- warn("unable to get basename '%s'", fields[GI_PATH]);
- break;
- }
- if (selwrite(fields[GI_HOST], fields[GI_PORT], fields[GI_PATH], output) == 0)
- error = 0;
- }
+ i = 0;
+ line = getlines(&i, (unsigned int *)&n, 1, fp);
+ if (line == NULL) {
+ if (!ferror(fp))
+ warnx("%d: Out of range.", n);
+ wfclose(fp);
+ return 1;
}
+ wfclose(fp);
- if (error && n > i)
- warnx("%d: Out of range.", n);
- else if (!error)
- warnx("'%s/%s' written to '%s'", fields[GI_HOST], fields[GI_PATH], output);
-
+ status = getfromline(line, output);
free(line);
- if (wfclose(fp) || error)
- return 1;
- return 0;
+ return status;
}
int