123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include "util.h"
- static struct feed f;
- static char *prefixpath = "/", *host = "127.0.0.1", *port = "70"; /* default */
- static char *line;
- static size_t linesize;
- static time_t comparetime;
- /* Escape characters in gopher, CR and LF are ignored */
- void
- gophertext(FILE *fp, const char *s)
- {
- for (; *s; s++) {
- switch (*s) {
- case '\r': /* ignore CR */
- case '\n': /* ignore LF */
- break;
- case '\t':
- fputs(" ", fp);
- break;
- default:
- putc(*s, fp);
- break;
- }
- }
- }
- static void
- printfeed(FILE *fpitems, FILE *fpin, struct feed *f)
- {
- struct uri u;
- char *fields[FieldLast];
- char *itemhost, *itemport, *itempath, *itemquery, *itemfragment;
- ssize_t linelen;
- unsigned int isnew;
- struct tm rtm, *tm;
- time_t parsedtime;
- int itemtype;
- if (f->name[0]) {
- fprintf(fpitems, "i%s\t\t%s\t%s\r\n", f->name, host, port);
- fprintf(fpitems, "i\t\t%s\t%s\r\n", host, port);
- }
- while ((linelen = getline(&line, &linesize, fpin)) > 0 &&
- !ferror(fpitems)) {
- if (line[linelen - 1] == '\n')
- line[--linelen] = '\0';
- parseline(line, fields);
- itemhost = host;
- itemport = port;
- itemtype = 'i';
- itempath = fields[FieldLink];
- itemquery = "";
- itemfragment = "";
- if (fields[FieldLink][0]) {
- itemtype = 'h';
- /* if it's a gopher URL then change it into a DirEntity */
- if (!strncmp(fields[FieldLink], "gopher://", 9) &&
- uri_parse(fields[FieldLink], &u) != -1) {
- itemhost = u.host;
- itemport = u.port[0] ? u.port : "70";
- itemtype = '1';
- itempath = u.path;
- itemquery = u.query;
- itemfragment = u.fragment;
- if (itempath[0] == '/') {
- itempath++;
- if (*itempath) {
- itemtype = *itempath;
- itempath++;
- }
- }
- }
- }
- parsedtime = 0;
- if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
- (tm = localtime_r(&parsedtime, &rtm))) {
- isnew = (parsedtime >= comparetime) ? 1 : 0;
- f->totalnew += isnew;
- fprintf(fpitems, "%c%c %04d-%02d-%02d %02d:%02d ",
- itemtype,
- isnew ? 'N' : ' ',
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min);
- } else {
- fprintf(fpitems, "%c ", itemtype);
- }
- f->total++;
- gophertext(fpitems, fields[FieldTitle]);
- fputs("\t", fpitems);
- if (itemtype == 'h' && fields[FieldLink] == itempath)
- fputs("URL:", fpitems);
- gophertext(fpitems, itempath);
- if (itemquery[0]) {
- fputs("?", fpitems);
- gophertext(fpitems, itemquery);
- }
- if (itemfragment[0]) {
- fputs("#", fpitems);
- gophertext(fpitems, itemfragment);
- }
- fprintf(fpitems, "\t%s\t%s\r\n", itemhost, itemport);
- }
- fputs(".\r\n", fpitems);
- }
- int
- main(int argc, char *argv[])
- {
- FILE *fpitems, *fpindex, *fp;
- char *name, *p;
- int i;
- if (argc == 1) {
- if (pledge("stdio", NULL) == -1)
- err(1, "pledge");
- } else {
- if (unveil("/", "r") == -1)
- err(1, "unveil: /");
- if (unveil(".", "rwc") == -1)
- err(1, "unveil: .");
- if (pledge("stdio rpath wpath cpath", NULL) == -1)
- err(1, "pledge");
- }
- if ((comparetime = time(NULL)) == (time_t)-1)
- errx(1, "time");
- /* 1 day is old news */
- comparetime -= 86400;
- if ((p = getenv("SFEED_GOPHER_HOST")))
- host = p;
- if ((p = getenv("SFEED_GOPHER_PORT")))
- port = p;
- if (argc == 1) {
- f.name = "";
- printfeed(stdout, stdin, &f);
- checkfileerror(stdin, "<stdin>", 'r');
- checkfileerror(stdout, "<stdout>", 'w');
- } else {
- if ((p = getenv("SFEED_GOPHER_PATH")))
- prefixpath = p;
- /* write main index page */
- if (!(fpindex = fopen("index", "wb")))
- err(1, "fopen: index");
- for (i = 1; i < argc; i++) {
- memset(&f, 0, sizeof(f));
- name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
- f.name = name;
- if (!(fp = fopen(argv[i], "r")))
- err(1, "fopen: %s", argv[i]);
- if (!(fpitems = fopen(name, "wb")))
- err(1, "fopen");
- printfeed(fpitems, fp, &f);
- checkfileerror(fp, argv[i], 'r');
- checkfileerror(fpitems, name, 'w');
- fclose(fp);
- fclose(fpitems);
- /* append directory item to index */
- fputs("1", fpindex);
- gophertext(fpindex, name);
- fprintf(fpindex, " (%lu/%lu)\t", f.totalnew, f.total);
- gophertext(fpindex, prefixpath);
- gophertext(fpindex, name);
- fprintf(fpindex, "\t%s\t%s\r\n", host, port);
- }
- fputs(".\r\n", fpindex);
- checkfileerror(fpindex, "index", 'w');
- fclose(fpindex);
- }
- return 0;
- }
|