#include <u.h>#include <libc.h>#include <bio.h>#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 voidprintitem(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 intcmpitem(void *a, void *b){ return tmnorm(&((Item*)a)->published) - tmnorm(&((Item*)b)->published);} static voidfreefeed(Feed *f){ int i; free(f->items); for(i = 0; i < f->nitems; i++) free(f->items[i].encls); f->free(f); free(f);} intsfmt(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 inthtmlfmt(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 voidusage(void){ fprint(2, "usage: %s [-d DATEFMT]\n", argv0); exits("usage");} voidmain(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);}
#include <u.h>
#include <libc.h>
#include <bio.h>
#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);
}