#include #include #include #include "feed.h" #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #pragma varargck type "ß" char* #pragma varargck type "ś" char* int mainstacksize = 32768; Tzone *tzone; static char *datefmt = "YYYY-MM-DD hh:mm"; static void printitem(Biobuf *b, Feed *f, Item *i) { char *s; int n; s = i->author; if(s == nil){ s = f->editor; if(s == nil) s = f->title; } Bprint(b, "\n%τ\t%s\n", tmfmt(&i->published, datefmt), s); Bprint(b, " %ß\n", i->title); if(i->descr) Bprint(b, "%ś\n", i->descr); for(n = 0; n < i->nencls; n++) Bprint(b, " %s\n", i->encls[n]); Bprint(b, "→ %s\n", i->link); } static int cmpitem(void *a, void *b) { return tmnorm(&((Item*)a)->published) - tmnorm(&((Item*)b)->published); } static void freefeed(Feed *f) { int i; free(f->items); for(i = 0; i < f->nitems; i++) free(f->items[i].encls); f->free(f); free(f); } int sfmt(Fmt *f) { char *s; s = va_arg(f->args, char*); for(; *s; s++){ if(*s == '\n'){ if(s[1] != 0 && s[1] != '\n') fmtrune(f, ' '); }else{ fmtrune(f, *s); } } return 0; } static char * readall(int f) { int bufsz, sz, n; char *s; bufsz = 1023; s = nil; for(sz = 0;; sz += n){ if(bufsz-sz < 1024){ bufsz *= 2; s = realloc(s, bufsz); } if((n = readn(f, s+sz, bufsz-sz-1)) < 1) break; } if(n < 0 || sz < 1){ free(s); return nil; } s[sz] = 0; return s; } static int htmlfmt(Fmt *f) { int p[4], pid; char *s; s = va_arg(f->args, char*); if(s == nil) return 0; pipe(p); pipe(p+2); if((pid = rfork(RFPROC|RFFDG)) == 0){ dup(p[0], 0); dup(p[2], 1); close(p[0]); close(p[1]); close(p[2]); close(p[3]); close(2); execl("/bin/rc", "rc", "-c", "{echo .ll 9999i; echo .pl 1no; echo .po 4; cat | html2ms} | nroff -N", nil); sysfatal("execl: %r"); } if(pid < 0) sysfatal("failed: %r"); fprint(p[1], "%s", s); close(p[0]); close(p[1]); close(p[2]); s = readall(p[3]); close(p[3]); if(s != nil && *s){ s[strlen(s)-1] = 0; fmtstrcpy(f, s); free(s); } return 0; } static void usage(void) { fprint(2, "usage: %s [-d DATEFMT]\n", argv0); exits("usage"); } void main(int argc, char **argv) { Biobuf in, out; Feed *f; Item *i; ARGBEGIN{ case 'd': datefmt = EARGF(usage()); break; default: usage(); }ARGEND quotefmtinstall(); tmfmtinstall(); fmtinstall(L'ß', sfmt); fmtinstall(L'ś', htmlfmt); if((tzone = tzload("local")) == nil) sysfatal("%r"); Binit(&in, 0, OREAD); Binit(&out, 1, OWRITE); if((f = parserss(&in)) == nil) sysfatal("%r"); f->ttl = MAX(1, MIN(60, f->ttl)); /* 1..60min */ qsort(f->items, f->nitems, sizeof(Item), cmpitem); for(i = f->items; i != f->items+f->nitems; i++) printitem(&out, f, i); freefeed(f); exits(nil); }