Introduction
Introduction Statistics Contact Development Disclaimer Help
sfeed_mbox.c - sfeed - RSS and Atom parser
git clone git://git.codemadness.org/sfeed
Log
Files
Refs
README
LICENSE
---
sfeed_mbox.c (4890B)
---
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <unistd.h>
6
7 #include "util.h"
8
9 static char *line;
10 static size_t linesize;
11 static char host[256], *user, dtimebuf[32], mtimebuf[32];
12 static int usecontent = 0; /* env variable: $SFEED_MBOX_CONTENT */
13
14 static unsigned long long
15 djb2(unsigned char *s, unsigned long long hash)
16 {
17 int c;
18
19 while ((c = *s++))
20 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
21 return hash;
22 }
23
24 /* Unescape / decode fields printed by string_print_encoded()
25 * "\\" to "\", "\t", to TAB, "\n" to newline. Other escape sequences are
26 * ignored: "\z" etc. Mangle "From " in mboxrd style (always prefix >). …
27 static void
28 printcontent(const char *s, FILE *fp)
29 {
30 escapefrom:
31 for (; *s == '>'; s++)
32 putc('>', fp);
33 /* escape "From ", mboxrd-style. */
34 if (!strncmp(s, "From ", 5))
35 putc('>', fp);
36
37 for (; *s; s++) {
38 switch (*s) {
39 case '\\':
40 if (*(s + 1) == '\0')
41 break;
42 s++;
43 switch (*s) {
44 case 'n':
45 putc('\n', fp);
46 s++;
47 goto escapefrom;
48 case '\\': putc('\\', fp); break;
49 case 't': putc('\t', fp); break;
50 }
51 break;
52 default:
53 putc(*s, fp); break;
54 }
55 }
56 }
57
58 static void
59 printfeed(FILE *fp, const char *feedname)
60 {
61 char *fields[FieldLast], timebuf[32];
62 struct tm parsedtm, *tm;
63 time_t parsedtime;
64 unsigned long long hash;
65 ssize_t linelen;
66 int ishtml;
67
68 while ((linelen = getline(&line, &linesize, fp)) > 0 &&
69 !ferror(stdout)) {
70 if (line[linelen - 1] == '\n')
71 line[--linelen] = '\0';
72 hash = djb2((unsigned char *)line, 5381ULL);
73 parseline(line, fields);
74
75 /* mbox + mail header */
76 printf("From MAILER-DAEMON %s\n", mtimebuf);
77
78 parsedtime = 0;
79 if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) …
80 (tm = gmtime_r(&parsedtime, &parsedtm)) &&
81 strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:…
82 printf("Date: %s\n", timebuf);
83 } else {
84 printf("Date: %s\n", dtimebuf); /* invalid/missi…
85 }
86
87 printf("From: %s <anonymous@>\n", fields[FieldAuthor][0]…
88 printf("To: %s <%s@%s>\n", user, user, host);
89 printf("Subject: %s\n", fields[FieldTitle]);
90 printf("Message-ID: <%s%s%llu@%s>\n",
91 fields[FieldUnixTimestamp],
92 fields[FieldUnixTimestamp][0] ? "." : "",
93 hash, feedname);
94
95 ishtml = usecontent && !strcmp(fields[FieldContentType],…
96 if (ishtml)
97 fputs("Content-Type: text/html; charset=\"utf-8\…
98 else
99 fputs("Content-Type: text/plain; charset=\"utf-8…
100 fputs("Content-Transfer-Encoding: binary\n", stdout);
101 printf("X-Feedname: %s\n", feedname);
102 fputs("\n", stdout);
103
104 if (ishtml) {
105 fputs("<p>\n", stdout);
106 if (fields[FieldLink][0]) {
107 fputs("Link: <a href=\"", stdout);
108 xmlencode(fields[FieldLink], stdout);
109 fputs("\">", stdout);
110 xmlencode(fields[FieldLink], stdout);
111 fputs("</a><br/>\n", stdout);
112 }
113 if (fields[FieldEnclosure][0]) {
114 fputs("Enclosure: <a href=\"", stdout);
115 xmlencode(fields[FieldEnclosure], stdout…
116 fputs("\">", stdout);
117 xmlencode(fields[FieldEnclosure], stdout…
118 fputs("</a><br/>\n", stdout);
119 }
120 fputs("</p>\n", stdout);
121 } else {
122 if (fields[FieldLink][0])
123 printf("Link: %s\n", fields[FieldLi…
124 if (fields[FieldEnclosure][0])
125 printf("Enclosure: %s\n", fields[FieldEn…
126 }
127 if (usecontent) {
128 fputs("\n", stdout);
129 if (ishtml && fields[FieldLink][0]) {
130 fputs("<base href=\"", stdout);
131 xmlencode(fields[FieldLink], stdout);
132 fputs("\"/>\n", stdout);
133 }
134 printcontent(fields[FieldContent], stdout);
135 }
136 fputs("\n\n", stdout);
137 }
138 }
139
140 int
141 main(int argc, char *argv[])
142 {
143 struct tm tmnow;
144 time_t now;
145 FILE *fp;
146 char *name, *tmp;
147 int i;
148
149 if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
150 err(1, "pledge");
151
152 if ((tmp = getenv("SFEED_MBOX_CONTENT")))
153 usecontent = !strcmp(tmp, "1");
154 if (!(user = getenv("USER")))
155 user = "you";
156 if (gethostname(host, sizeof(host)) == -1)
157 err(1, "gethostname");
158 if ((now = time(NULL)) == (time_t)-1)
159 errx(1, "time");
160 if (!gmtime_r(&now, &tmnow))
161 err(1, "gmtime_r: can't get current time");
162 if (!strftime(mtimebuf, sizeof(mtimebuf), "%a %b %d %H:%M:%S %Y"…
163 errx(1, "strftime: can't format current time");
164 if (!strftime(dtimebuf, sizeof(dtimebuf), "%a, %d %b %Y %H:%M:%S…
165 errx(1, "strftime: can't format current time");
166
167 if (argc == 1) {
168 printfeed(stdin, "");
169 checkfileerror(stdin, "<stdin>", 'r');
170 } else {
171 for (i = 1; i < argc; i++) {
172 if (!(fp = fopen(argv[i], "r")))
173 err(1, "fopen: %s", argv[i]);
174 name = ((name = strrchr(argv[i], '/'))) ? name +…
175 printfeed(fp, name);
176 checkfileerror(fp, argv[i], 'r');
177 checkfileerror(stdout, "<stdout>", 'w');
178 fclose(fp);
179 }
180 }
181
182 checkfileerror(stdout, "<stdout>", 'w');
183
184 return 0;
185 }
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.