sfeed

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

commit 87f6ee55fc14327321e9d606ac9683c112fefaa9
parent b8b24fe4131e7e7fb46eb330b14ce340844b601a
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Wed,  9 Apr 2014 00:00:13 +0200

cleanup, remove javascript hotkey

Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>

Diffstat:
MCHANGELOG | 5+----
Msfeed_frames.c | 30++++++++++++++++--------------
Msfeed_html.c | 27+++++++++------------------
Msfeed_plain.c | 4++--
Msfeed_stats.c | 6++++--
Msfeed_web.c | 6+++---
Mutil.c | 20+++++++++++++-------
7 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -4,10 +4,7 @@ v0.9 Features: --------- - * Feeds are now by default updated in parallel for a huge speedup in performance. - * Added hotkeys to sfeed_html to toggle showing only new items (n key) and - focusing the menu (s key) or items (i key) using a tiny bit of - javascript. + * Feeds are now by default updated in parallel for an increase in performance. * Auto-detect XML character set encoding (sfeed_xmlenc). * Auto-detect RSS/Atom feeds from web-pages (sfeed_web). * Added sfeed_frames, a formatting program to output feeds as a HTML file with diff --git a/sfeed_frames.c b/sfeed_frames.c @@ -8,16 +8,19 @@ #include <sys/stat.h> #include <utime.h> #include <errno.h> +#include <limits.h> #include "util.h" static unsigned int showsidebar = 1; /* show sidebar ? */ -static FILE *fpindex = NULL, *fpitems = NULL, *fpmenu = NULL, *fpcontent = NULL; +static FILE *fpindex = NULL, *fpitems = NULL, *fpmenu = NULL; +static FILE *fpcontent = NULL; static char *line = NULL; -static struct feed *feeds = NULL; /* start of feeds linked-list. */ +static struct feed *feeds = NULL; -static void /* print error message to stderr */ +/* print string to stderr and exit program with EXIT_FAILURE */ +static void die(const char *s) { fputs("sfeed_frames: ", stderr); fputs(s, stderr); @@ -64,12 +67,11 @@ printcontent(const char *s, FILE *fp) { /* TODO: bufsiz - 1 ? */ static size_t -makepathname(char *buffer, size_t bufsiz, const char *path) { - const char *p = path; +makepathname(const char *path, char *buffer, size_t bufsiz) { size_t i = 0, r = 0; - for(; *p && i < bufsiz; p++) { - if(isalpha((int)*p) || isdigit((int)*p)) { + for(; *path && i < bufsiz - 1; p++) { + if(isalpha((int)*path) || isdigit((int)*path)) { buffer[i++] = tolower((int)*p); r = 0; } else { @@ -92,16 +94,16 @@ fileexists(const char *path) { int main(int argc, char **argv) { + struct feed *f, *feedcurrent = NULL; char *fields[FieldLast]; char name[256]; /* TODO: bigger size? */ char *basepath = "."; - /* TODO: max path size? */ - char dirpath[1024], filepath[1024], reldirpath[1024], relfilepath[1024]; + char dirpath[PATH_MAX], filepath[PATH_MAX]; + char reldirpath[PATH_MAX], relfilepath[PATH_MAX]; unsigned long totalfeeds = 0, totalnew = 0; unsigned int isnew; - struct feed *f, *feedcurrent = NULL; time_t parsedtime, comparetime; - size_t size = 0, namelen = 0, basepathlen = 0; + size_t linesize = 0, namelen, basepathlen; struct stat st; struct utimbuf contenttime; @@ -133,14 +135,14 @@ main(int argc, char **argv) { "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>" "<body class=\"frame\"><div id=\"items\">", fpitems); - while(parseline(&line, &size, fields, FieldLast, '\t', stdin) > 0) { + while(parseline(&line, &linesize, fields, FieldLast, '\t', stdin) > 0) { /* first of feed section or new feed section. */ if(!totalfeeds || (feedcurrent && strcmp(feedcurrent->name, fields[FieldFeedName]))) { /* TODO: makepathname isnt necesary if fields[FieldFeedName] is the same as the previous line */ /* TODO: move this part below where FieldFeedName is checked if its different ? */ /* make directory for feedname */ - if(!(namelen = makepathname(name, sizeof(name) - 1, fields[FieldFeedName]))) + if(!(namelen = makepathname(fields[FieldFeedName], name, sizeof(name)))) continue; if(snprintf(dirpath, sizeof(dirpath), "%s/%s", basepath, name) <= 0) @@ -192,7 +194,7 @@ main(int argc, char **argv) { } /* write content */ - if(!(namelen = makepathname(name, sizeof(name), fields[FieldTitle]))) + if(!(namelen = makepathname(fields[FieldTitle], name, sizeof(name)))) continue; if(snprintf(filepath, sizeof(filepath), "%s/%s.html", dirpath, name) <= 0) die("snprintf() format error"); diff --git a/sfeed_html.c b/sfeed_html.c @@ -39,11 +39,11 @@ main(void) { fputs( "<!DOCTYPE HTML>\n" "<html dir=\"ltr\" lang=\"en\">\n" - " <head>\n" - " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" - " <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n" - " </head>\n" - " <body class=\"noframe\">\n", + "\t<head>\n" + "\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" + "\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n" + "\t</head>\n" + "\t<body class=\"noframe\">\n", stdout); if(!(feedcurrent = calloc(1, sizeof(struct feed)))) @@ -55,7 +55,8 @@ main(void) { isnew = (parsedtime >= comparetime); islink = (fields[FieldLink][0] != '\0'); /* first of feed section or new feed section. */ - if(!totalfeeds || (feedcurrent && strcmp(feedcurrent->name, fields[FieldFeedName]))) { /* TODO: allocate feedcurrent before here, feedcurrent can be NULL */ + /* TODO: allocate feedcurrent before here, feedcurrent can be NULL */ + if(!totalfeeds || (feedcurrent && strcmp(feedcurrent->name, fields[FieldFeedName]))) { if(!(f = calloc(1, sizeof(struct feed)))) die("can't allocate enough memory"); /*f->next = NULL;*/ @@ -146,19 +147,9 @@ main(void) { } fputs("\t\t</ul>\n\t</div>\n", stdout); } - /* toggle showing only new with "n" */ - fputs("<script type=\"text/javascript\">" - "var b=document.body;window.onkeypress=function(e){" - "switch(String.fromCharCode(e.which)){" - "case 'n':var n='newonly';b.className=/*toggle new only*/" - "b.className.indexOf(n)==-1?b.className+' '+n:b.className.replace(n,'');break;" - "case 'm':case 's':b.querySelector('#sidebar a').focus();break; /*focus menu*/" - "case 'i':b.querySelector('#items').focus();break;/*focus items*/" - "}};" - "</script>", stdout); fputs( - " </body>\n" - " <title>Newsfeed (", + "\t</body>\n" + "\t<title>Newsfeed (", stdout); fprintf(stdout, "%lu", totalnew); fputs(")</title>\n</html>", stdout); diff --git a/sfeed_plain.c b/sfeed_plain.c @@ -6,7 +6,7 @@ #include "util.h" static void -printutf8padded(const char *s, size_t len, FILE *fp, int pad) { +printutf8padded(FILE *fp, const char *s, size_t len, int pad) { size_t n = 0, i; for(i = 0; s[i] && n < len; i++) { @@ -34,7 +34,7 @@ main(void) { if(fields[FieldFeedName][0] != '\0') printf("%-15.15s ", fields[FieldFeedName]); printf("%-30.30s ", fields[FieldTimeFormatted]); - printutf8padded(fields[FieldTitle], 70, stdout, ' '); + printutf8padded(stdout, fields[FieldTitle], 70, ' '); fputs(" ", stdout); if(fields[FieldBaseSiteUrl][0] != '\0') printlink(fields[FieldLink], fields[FieldBaseSiteUrl], stdout); diff --git a/sfeed_stats.c b/sfeed_stats.c @@ -44,7 +44,8 @@ main(void) { isnew = (parsedtime >= comparetime); islink = (fields[FieldLink][0] != '\0'); /* first of feed section or new feed section. */ - if(!totalfeeds || (feedcurrent && strcmp(feedcurrent->name, fields[FieldFeedName]))) { /* TODO: allocate feedcurrent before here, feedcurrent can be NULL */ + /* TODO: allocate feedcurrent before here, feedcurrent can be NULL */ + if(!totalfeeds || (feedcurrent && strcmp(feedcurrent->name, fields[FieldFeedName]))) { if(!(f = calloc(1, sizeof(struct feed)))) die("can't allocate enough memory"); if(totalfeeds) { /* end previous one. */ @@ -79,7 +80,8 @@ main(void) { for(feedcurrent = feeds; feedcurrent; feedcurrent = feedcurrent->next) { if(!feedcurrent->name || feedcurrent->name[0] == '\0') continue; - fprintf(stdout, "%c %-20.20s [%4lu/%-4lu]", feedcurrent->totalnew > 0 ? 'N' : ' ', + fprintf(stdout, "%c %-20.20s [%4lu/%-4lu]", + feedcurrent->totalnew > 0 ? 'N' : ' ', feedcurrent->name, feedcurrent->totalnew, feedcurrent->total); if(feedcurrent->timenewestformat && feedcurrent->timenewestformat[0]) fprintf(stdout, " %s", feedcurrent->timenewestformat); diff --git a/sfeed_web.c b/sfeed_web.c @@ -38,7 +38,7 @@ xmlattr(XMLParser *p, const char *tag, size_t taglen, const char *name, return; if(isbase) { if(!strncasecmp(name, "href", namelen)) - strlcpy(basehref, value, sizeof(basehref) - 1); + strlcpy(basehref, value, sizeof(basehref)); } else if(islink) { if(!strncasecmp(name, "type", namelen)) { if(!strncasecmp(value, "application/atom", strlen("application/atom")) || @@ -46,7 +46,7 @@ xmlattr(XMLParser *p, const char *tag, size_t taglen, const char *name, isfeedlink = 1; } } else if(!strncasecmp(name, "href", namelen)) - strlcpy(feedlink, value, sizeof(feedlink) - 1); + strlcpy(feedlink, value, sizeof(feedlink)); } } @@ -56,7 +56,7 @@ main(int argc, char **argv) { /* base href */ if(argc > 1) - strlcpy(basehref, argv[1], sizeof(basehref) - 1); + strlcpy(basehref, argv[1], sizeof(basehref)); xmlparser_init(&x, stdin); x.xmltagstart = xmltagstart; diff --git a/util.c b/util.c @@ -72,15 +72,17 @@ afgets(char **p, size_t *size, FILE *fp) { return NULL; } -void /* print link; if link is relative use baseurl to make it absolute */ +/* print link; if link is relative use baseurl to make it absolute */ +void printlink(const char *link, const char *baseurl, FILE *fp) { const char *ebaseproto, *ebasedomain, *p; int isrelative; /* protocol part */ for(p = link; *p && (isalpha((int)*p) || isdigit((int)*p) || *p == '+' || *p == '-' || *p == '.'); p++); + /* relative link (baseurl is used). */ isrelative = strncmp(p, "://", strlen("://")); - if(isrelative) { /* relative link (baseurl is used). */ + if(isrelative) { if((ebaseproto = strstr(baseurl, "://"))) { ebaseproto += strlen("://"); fwrite(baseurl, 1, ebaseproto - baseurl, fp); @@ -92,13 +94,15 @@ printlink(const char *link, const char *baseurl, FILE *fp) { if(link[0] == '/') { /* relative to baseurl domain (not path). */ if(link[1] == '/') /* absolute url but with protocol from baseurl. */ link += 2; - else if((ebasedomain = strchr(ebaseproto, '/'))) /* relative to baseurl and baseurl path. */ + else if((ebasedomain = strchr(ebaseproto, '/'))) + /* relative to baseurl and baseurl path. */ fwrite(ebaseproto, 1, ebasedomain - ebaseproto, fp); else fputs(ebaseproto, stdout); - } else if((ebasedomain = strrchr(ebaseproto, '/'))) /* relative to baseurl and baseurl path. */ + } else if((ebasedomain = strrchr(ebaseproto, '/'))) { + /* relative to baseurl and baseurl path. */ fwrite(ebaseproto, 1, ebasedomain - ebaseproto + 1, fp); - else { + } else { fputs(ebaseproto, fp); if(*baseurl && *link) fputc('/', fp); @@ -108,13 +112,15 @@ printlink(const char *link, const char *baseurl, FILE *fp) { } unsigned int -parseline(char **line, size_t *size, char **fields, unsigned int maxfields, int separator, FILE *fp) { +parseline(char **line, size_t *size, char **fields, + unsigned int maxfields, int separator, FILE *fp) +{ unsigned int i = 0; char *prev, *s; if(afgets(line, size, fp)) { for(prev = *line; (s = strchr(prev, separator)) && i <= maxfields; i++) { - *s = '\0'; /* null terminate string. */ + *s = '\0'; fields[i] = prev; prev = s + 1; }