Fix mimedef parsing & add the `-l' option

This commit is contained in:
styan 2020-06-20 22:44:05 +00:00
parent 0fddfb0dfd
commit 2a67a406ca
2 changed files with 44 additions and 5 deletions

View File

@ -6,7 +6,7 @@
.Nd plumb gemini pages based on the returned mime-type .Nd plumb gemini pages based on the returned mime-type
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl w .Op Fl lw
.Op Fl c Ar cert-file .Op Fl c Ar cert-file
.Op Fl d Ar default-handler .Op Fl d Ar default-handler
.Op Fl f Ar mimedef-file .Op Fl f Ar mimedef-file
@ -42,6 +42,8 @@ The host to connect through.
can also specify a port number. can also specify a port number.
.It Fl k Ar key-file .It Fl k Ar key-file
The key file to use for TLS. 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 .It Fl m Ar mimedef
Parse the argument as described below. Parse the argument as described below.
.It Fl p Ar port .It Fl p Ar port

View File

@ -26,6 +26,7 @@ struct mimedef {
char *recipe; char *recipe;
}; };
static ssize_t mimedef_print(struct mimedef *);
static struct mimedef *mimedef_parse(const char *); static struct mimedef *mimedef_parse(const char *);
static void mimedef_append(struct mimedef **, static void mimedef_append(struct mimedef **,
struct mimedef *); struct mimedef *);
@ -48,12 +49,13 @@ main(int argc, char *argv[])
ssize_t r; ssize_t r;
size_t i; size_t i;
size_t j; size_t j;
int lflag = 0;
int c; int c;
gemini_envinit(&gemini); gemini_envinit(&gemini);
if ((p = getenv("GEMINI_TOFU_WRITE")) != NULL && *p != '\0') if ((p = getenv("GEMINI_TOFU_WRITE")) != NULL && *p != '\0')
gemini.flags |= GEMINI_TOFU_WRITE; 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) { switch (c) {
case 'b': case 'b':
errno = 0; errno = 0;
@ -107,6 +109,9 @@ main(int argc, char *argv[])
if (i == 0 || optarg[i] != '\0') if (i == 0 || optarg[i] != '\0')
warnx("Invalid number: %s", optarg); warnx("Invalid number: %s", optarg);
break; break;
case 'l':
lflag = 1;
break;
case 'm': case 'm':
if ((tmime = mimedef_parse(optarg)) == NULL) if ((tmime = mimedef_parse(optarg)) == NULL)
err(EX_USAGE, "Invalid MIME-def: %s", err(EX_USAGE, "Invalid MIME-def: %s",
@ -130,6 +135,8 @@ main(int argc, char *argv[])
(void)setenv("PAGER", "more", 1); (void)setenv("PAGER", "more", 1);
if (mimedef_merge(mime) != 0) if (mimedef_merge(mime) != 0)
err(EX_OSERR, "Could not merge the MIME-defs"); 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++) { for (i = 0; i < argc; i++) {
if (gemini_connect(&gemini, argv[i]) != 0) { if (gemini_connect(&gemini, argv[i]) != 0) {
warn("Failed to connect to %s", argv[i]); warn("Failed to connect to %s", argv[i]);
@ -180,7 +187,7 @@ err:
gemini_fini(&gemini); gemini_fini(&gemini);
return (EX_SOFTWARE); return (EX_SOFTWARE);
usage: 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" "[-d default-handler]\n"
" [-f mimedef-file] [-h proxy-host] " " [-f mimedef-file] [-h proxy-host] "
"[-k key-file]\n" "[-k key-file]\n"
@ -190,6 +197,37 @@ usage:
return (EX_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 * struct mimedef *
mimedef_parse(const char *s) mimedef_parse(const char *s)
{ {
@ -208,8 +246,7 @@ mimedef_parse(const char *s)
if (isblank(s[i])) { /* recipe */ if (isblank(s[i])) { /* recipe */
if (target == NULL) if (target == NULL)
goto err; goto err;
for (i++, j = i; for (i++, j = i; s[j] != '\0' && s[j] != '\n';
s[j] != '\0' && !isspace(s[j]);
j++) j++)
/* do nothing */; /* do nothing */;
if (strappend(&recipe, s + i, j - i, '\n') != 0) if (strappend(&recipe, s + i, j - i, '\n') != 0)