diff --git a/gemini-pipe.1 b/gemini-pipe.1 index 4579d1b..bb5dc0f 100644 --- a/gemini-pipe.1 +++ b/gemini-pipe.1 @@ -6,7 +6,7 @@ .Nd plumb gemini pages based on the returned mime-type .Sh SYNOPSIS .Nm -.Op Fl w +.Op Fl lw .Op Fl c Ar cert-file .Op Fl d Ar default-handler .Op Fl f Ar mimedef-file @@ -42,6 +42,8 @@ The host to connect through. can also specify a port number. .It Fl k Ar key-file The key file to use for TLS. +.It Fl l +Print a list of all mimedefs in use and exit. .It Fl m Ar mimedef Parse the argument as described below. .It Fl p Ar port diff --git a/gemini-pipe.c b/gemini-pipe.c index abd29a8..4e7c572 100644 --- a/gemini-pipe.c +++ b/gemini-pipe.c @@ -26,6 +26,7 @@ struct mimedef { char *recipe; }; +static ssize_t mimedef_print(struct mimedef *); static struct mimedef *mimedef_parse(const char *); static void mimedef_append(struct mimedef **, struct mimedef *); @@ -48,12 +49,13 @@ main(int argc, char *argv[]) ssize_t r; size_t i; size_t j; + int lflag = 0; int c; gemini_envinit(&gemini); if ((p = getenv("GEMINI_TOFU_WRITE")) != NULL && *p != '\0') gemini.flags |= GEMINI_TOFU_WRITE; - while ((c = getopt(argc, argv, "b:c:d:f:h:k:m:p:r:t:w")) != -1) + while ((c = getopt(argc, argv, "b:c:d:f:h:k:lm:p:r:t:w")) != -1) switch (c) { case 'b': errno = 0; @@ -107,6 +109,9 @@ main(int argc, char *argv[]) if (i == 0 || optarg[i] != '\0') warnx("Invalid number: %s", optarg); break; + case 'l': + lflag = 1; + break; case 'm': if ((tmime = mimedef_parse(optarg)) == NULL) err(EX_USAGE, "Invalid MIME-def: %s", @@ -130,6 +135,8 @@ main(int argc, char *argv[]) (void)setenv("PAGER", "more", 1); if (mimedef_merge(mime) != 0) err(EX_OSERR, "Could not merge the MIME-defs"); + if (lflag) + return (mimedef_print(mime) >= 0 ? 0 : EX_IOERR); for (i = 0; i < argc; i++) { if (gemini_connect(&gemini, argv[i]) != 0) { warn("Failed to connect to %s", argv[i]); @@ -180,7 +187,7 @@ err: gemini_fini(&gemini); return (EX_SOFTWARE); usage: - (void)fprintf(stderr, "usage: gemini-pipe [-w] [-c cert-file] " + (void)fprintf(stderr, "usage: gemini-pipe [-lw] [-c cert-file] " "[-d default-handler]\n" " [-f mimedef-file] [-h proxy-host] " "[-k key-file]\n" @@ -190,6 +197,37 @@ usage: return (EX_USAGE); } +ssize_t +mimedef_print(struct mimedef *mime) +{ + struct mimedef *t; + ssize_t r; + size_t i; + size_t j; + size_t l; + + for (t = mime, l = 0; t != NULL; t = t->next) { + if ((r = printf("%s\n", t->target)) < 0) + return (r); + l += r; + if (t->recipe == NULL) + continue; + for (i = 0; t->recipe[i] != '\0'; + i = j + (t->recipe[j] == '\n')) { + for (j = i; t->recipe[j] != '\0' && + t->recipe[j] != '\n'; j++) + /* do nothing */; + if (j - i > INT_MAX) + return (-1); + if ((r = printf("\t%.*s\n", (int)(j - i), + t->recipe + i)) < 0) + return (r); + l += r; + } + } + return (l); +} + struct mimedef * mimedef_parse(const char *s) { @@ -208,8 +246,7 @@ mimedef_parse(const char *s) if (isblank(s[i])) { /* recipe */ if (target == NULL) goto err; - for (i++, j = i; - s[j] != '\0' && !isspace(s[j]); + for (i++, j = i; s[j] != '\0' && s[j] != '\n'; j++) /* do nothing */; if (strappend(&recipe, s + i, j - i, '\n') != 0)