commit bd3e341b2ef355e6f25e97c1478e7227202f52ff
parent 0fd60dd1f4f09fc5f0d2879037b46538df5668e2
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date: Tue, 22 Dec 2020 01:45:06 -0800
Add external content command
Separate fgroup's substring match functionality into a separate
filter, fstrmatch.
Add simple command which forks and executes a list of arguments
replacing an argument which contains a sole `%' with the url (actually
it doesn't have a protocol so it's not a url).
Diffstat:
M | main.c | | | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 63 insertions(+), 4 deletions(-)
diff --git a/main.c b/main.c
@@ -36,6 +36,7 @@
#define ARGV_MAX 16
#define ARG_SEP ":\t "
#define CMD_SEP ";\n"
+#define URL_MAX 128
enum gphitem { GI_INFO, GI_PATH, GI_HOST, GI_PORT, GI_NULL };
@@ -308,6 +309,7 @@ splitrun(int argc, const char **argv, int index, char *request, command *func)
{
char *fields[6];
+ /* NOTE: argsplit ignores multiple terminators. */
if (argsplit(fields, LEN(fields), request, "\t\r\n") != 4)
if (fields[4] != NULL && strcmp(fields[4], "+") != 0) {
warnx("%d: Not a valid gopher item.", index);
@@ -355,6 +357,32 @@ findex(const char *cache, int argc, const char **argv, command *func)
}
int
+fstrmatch(const char *cache, int argc, const char **argv, command *func)
+{
+ FILE *fp;
+ char buf[LINE_MAX];
+ int anystr;
+ int i;
+
+ fp = wfopen(cache, "r");
+ if (fp == NULL)
+ return 1;
+
+ if (!argv[0])
+ anystr = 1;
+ else anystr = 0;
+
+ for (i = 0; fgets(buf, sizeof(buf), fp) != NULL; ++i) {
+ if (*buf == '.')
+ break;
+ if (anystr || strcasestr(buf, argv[0]))
+ splitrun(argc - 1, argv + 1, i, buf, func);
+ }
+
+ return wfclose(fp);
+}
+
+int
fgroup(const char *cache, int argc, const char **argv, command *func)
{
FILE *fp;
@@ -373,10 +401,8 @@ fgroup(const char *cache, int argc, const char **argv, command *func)
for (i = 0; fgets(buf, sizeof(buf), fp) != NULL; ++i) {
if (*buf == '.')
break;
- if (anytype || argc < 1 || strchr(argv[0], *buf)) {
- if (argc < 2 || strcasestr(buf, argv[1]))
- splitrun(argc - 2, argv + 2, i, buf, func);
- }
+ if (anytype || strchr(argv[0], *buf))
+ splitrun(argc - 1, argv + 1, i, buf, func);
}
return wfclose(fp);
@@ -476,6 +502,35 @@ cfetch(int argc, const char **argv, int i, const char **request)
return 0;
}
+int
+cextern(int argc, const char **argv, int index, const char **item)
+{
+ char url[URL_MAX];
+ int i;
+
+ if (argc == 0) {
+ warnx("%s: Not enough arguments.", __func__);
+ return 1;
+ }
+
+ snprintf(url, sizeof(url), "%s/%s", item[GI_HOST], item[GI_PATH]);
+ for (i = 0; i < argc; ++i)
+ if (strcmp(argv[i], "%") == 0)
+ argv[i] = url;
+
+ switch (fork()) {
+ case -1:
+ warn("unable to fork");
+ return 1;
+ case 0:
+ execvp(*argv, (char *const *)argv);
+ warn("execvp '%s'", *argv);
+ _exit(1);
+ }
+
+ return 0;
+}
+
command *
getcommand(int c)
{
@@ -486,6 +541,8 @@ getcommand(int c)
return cprintn;
case 'f':
return cfetch;
+ case 'e':
+ return cextern;
default:
return NULL;
}
@@ -499,6 +556,8 @@ getfilter(int c)
return fgroup;
case 'i':
return findex;
+ case 's':
+ return fstrmatch;
default:
return NULL;
}