commit ed8079dc3e8ce513c788a5ab11444aac221cbc5b
parent 15983fa731e7e62fcc19db8dd04a12007a265e8f
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue, 6 Jul 2021 18:27:28 +0200
sfeed_mbox: add option to print content
- Add SFEED_MBOX_CONTENT environment option. When set to "1" it outputs the
content aswell. This is disabled by default for security reasons, because many
clients handle HTML in an insecure way.
- Print link and enclosure on one line and align them.
Diffstat:
M | sfeed_mbox.1 | | | 15 | ++++++++++++--- |
M | sfeed_mbox.c | | | 80 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
2 files changed, 85 insertions(+), 10 deletions(-)
diff --git a/sfeed_mbox.1 b/sfeed_mbox.1
@@ -1,4 +1,4 @@
-.Dd March 15, 2020
+.Dd July 6, 2020
.Dt SFEED_MBOX 1
.Os
.Sh NAME
@@ -28,12 +28,21 @@ The mbox data can be further processed by tools like
or
.Xr fdm 1
for example.
-See the README file for some useful examples.
+See the README file for some examples.
.Sh CUSTOM HEADERS
To make further filtering simpler some custom headers are set:
.Bl -tag -width Ds
.It X-Feedname
-The feedname (as set in sfeedrc).
+The feedname, this is the basename of the
+.Ar file .
+.El
+.Sh ENVIRONMENT VARIABLES
+.Bl -tag -width Ds
+.It Ev SFEED_MBOX_CONTENT
+Include the content.
+This is very insecure for some of the mail clients that interpret HTML code in
+an unsafe way.
+By default this is set to "0".
.El
.Sh EXIT STATUS
.Ex -std
diff --git a/sfeed_mbox.c b/sfeed_mbox.c
@@ -9,6 +9,7 @@
static char *line;
static size_t linesize;
static char host[256], *user, dtimebuf[32], mtimebuf[32];
+static int usecontent = 0; /* env variable: $SFEED_MBOX_CONTENT */
static unsigned long
djb2(unsigned char *s, unsigned long hash)
@@ -20,6 +21,38 @@ djb2(unsigned char *s, unsigned long hash)
return hash;
}
+/* Unescape / decode fields printed by string_print_encoded()
+ * "\\" to "\", "\t", to TAB, "\n" to newline. Unrecognised escape sequences
+ * are ignored: "\z" etc. Mangle "From " in mboxrd style (always prefix >). */
+static void
+printcontent(const char *s, FILE *fp)
+{
+escapefrom:
+ for (; *s == '>'; s++)
+ fputc('>', fp);
+ /* escape "From ", mboxrd-style. */
+ if (!strncmp(s, "From ", 5))
+ fputc('>', fp);
+
+ for (; *s; s++) {
+ switch (*s) {
+ case '\\':
+ s++;
+ switch (*s) {
+ case 'n':
+ fputc('\n', fp);
+ s++;
+ goto escapefrom;
+ case '\\': fputc('\\', fp); break;
+ case 't': fputc('\t', fp); break;
+ }
+ break;
+ default:
+ fputc(*s, fp); break;
+ }
+ }
+}
+
static void
printfeed(FILE *fp, const char *feedname)
{
@@ -28,6 +61,7 @@ printfeed(FILE *fp, const char *feedname)
time_t parsedtime;
unsigned long hash;
ssize_t linelen;
+ int ishtml;
while ((linelen = getline(&line, &linesize, fp)) > 0) {
if (line[linelen - 1] == '\n')
@@ -54,14 +88,44 @@ printfeed(FILE *fp, const char *feedname)
fields[FieldUnixTimestamp],
fields[FieldUnixTimestamp][0] ? "." : "",
hash, feedname);
- printf("Content-Type: text/plain; charset=\"utf-8\"\n");
- printf("Content-Transfer-Encoding: binary\n");
- printf("X-Feedname: %s\n\n", feedname);
- printf("%s\n", fields[FieldLink]);
- if (fields[FieldEnclosure][0])
- printf("\nEnclosure:\n%s\n", fields[FieldEnclosure]);
+ ishtml = usecontent && !strcmp(fields[FieldContentType], "html");
+ if (ishtml)
+ fputs("Content-Type: text/html; charset=\"utf-8\"\n", stdout);
+ else
+ fputs("Content-Type: text/plain; charset=\"utf-8\"\n", stdout);
+ fputs("Content-Transfer-Encoding: binary\n", stdout);
+ printf("X-Feedname: %s\n", feedname);
fputs("\n", stdout);
+
+ if (ishtml) {
+ fputs("<p>\n", stdout);
+ if (fields[FieldLink][0]) {
+ fputs("Link: <a href=\"", stdout);
+ xmlencode(fields[FieldLink], stdout);
+ fputs("\">", stdout);
+ fputs(fields[FieldLink], stdout);
+ fputs("</a><br/>\n", stdout);
+ }
+ if (fields[FieldEnclosure][0]) {
+ fputs("Enclosure: <a href=\"", stdout);
+ xmlencode(fields[FieldEnclosure], stdout);
+ fputs("\">", stdout);
+ fputs(fields[FieldEnclosure], stdout);
+ fputs("</a><br/>\n", stdout);
+ }
+ fputs("</p>\n", stdout);
+ } else {
+ if (fields[FieldLink][0])
+ printf("Link: %s\n", fields[FieldLink]);
+ if (fields[FieldEnclosure][0])
+ printf("Enclosure: %s\n", fields[FieldEnclosure]);
+ }
+ if (usecontent) {
+ fputs("\n", stdout);
+ printcontent(fields[FieldContent], stdout);
+ }
+ fputs("\n\n", stdout);
}
}
@@ -71,12 +135,14 @@ main(int argc, char *argv[])
struct tm tmnow;
time_t now;
FILE *fp;
- char *name;
+ char *name, *tmp;
int i;
if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
err(1, "pledge");
+ if ((tmp = getenv("SFEED_MBOX_CONTENT")))
+ usecontent = !strcmp(tmp, "1");
if (!(user = getenv("USER")))
user = "you";
if (gethostname(host, sizeof(host)) == -1)