sfeed

Simple RSS and Atom feed parser
git clone https://git.sinitax.com/codemadness/sfeed
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

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:
Msfeed_mbox.1 | 15++++++++++++---
Msfeed_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)