4 * Generate some RSS for our rooms.
10 void display_rss(const char *roomname)
17 iconv_t ic = (iconv_t)(-1) ;
18 char *ibuf; /* Buffer of characters to be converted */
19 char *obuf; /* Buffer for converted characters */
20 size_t ibuflen; /* Length of input buffer */
21 size_t obuflen; /* Length of output buffer */
22 char *osav; /* Saved pointer to output buffer */
33 char content_type[256];
36 lprintf(3, "Running RSS reader\n");
38 authorization_required();
42 lprintf(3, "Going to a room %s\n", roomname);
43 if (gotoroom(roomname)) {
44 wprintf("HTTP/1.0 404 Not Found\r\n");
45 wprintf("Content-Type: text/html\r\n");
47 wprintf("Error retrieving RSS feed: couldn't find room or messages\n");
51 lprintf(3, "Loading up all the messages\n");
52 nummsgs = load_msg_ptrs("MSGS LAST|50", 0);
54 wprintf("HTTP/1.0 404 Not Found\r\n");
55 wprintf("Content-Type: text/html\r\n");
57 wprintf("Error retrieving RSS feed: couldn't find room or messages\n");
61 lprintf(3, "Getting date of the last one\n");
62 /* Read time of last message immediately */
63 serv_printf("MSG4 %ld", WC->msgarr[nummsgs - 1]);
64 serv_getln(buf, sizeof buf);
66 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "000")) {
67 if (!strncasecmp(buf, "time=", 5)) {
69 gmtime_r(&now, &now_tm);
70 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
76 output_headers(0, 0, 0, 0, 0, 0, 0);
77 wprintf("Content-Type: application/rss+xml\r\n");
79 wprintf("<?xml version=\"1.0\"?>\n");
80 wprintf("<rss version=\"2.0\">\n");
81 wprintf(" <channel>\n");
82 wprintf(" <title>%s - %s</title>\n", WC->wc_roomname, serv_info.serv_humannode);
83 wprintf(" <description>");
84 /* Get room info for description */
86 serv_getln(buf, sizeof buf);
89 serv_getln(buf, sizeof buf);
90 if (!strcmp(buf, "000"))
95 wprintf("</description>\n");
97 wprintf(" <pubDate>%s</pubDate>\n", buf);
99 wprintf(" <generator>%s</generator>\n", SERVER);
100 wprintf(" <docs>http://blogs.law.harvard.edu/tech/rss</docs>\n");
101 wprintf(" <ttl>30</ttl>\n");
103 /* Read all messages and output as RSS items */
104 for (a = 0; a < nummsgs; ++a) {
105 lprintf(3, "Sending message %d of %d\n", a+1, nummsgs);
106 /* Read message and output each as RSS item */
107 serv_printf("MSG4 %ld", WC->msgarr[a]);
108 serv_getln(buf, sizeof buf);
109 if (buf[0] != '1') continue;
120 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
121 if (!strcmp(buf, "000")) {
122 lprintf(3, "ENDITEM 1\n");
123 goto ENDITEM; /* screw it */
124 } else if (!strncasecmp(buf, "from=", 5)) {
125 strcpy(from, &buf[5]);
127 utf8ify_rfc822_string(from);
129 } else if (!strncasecmp(buf, "subj=", 5)) {
130 strcpy(subj, &buf[5]);
132 utf8ify_rfc822_string(subj);
134 } else if (!strncasecmp(buf, "hnod=", 5)) {
135 strcpy(node, &buf[5]);
136 } else if (!strncasecmp(buf, "room=", 5)) {
137 strcpy(room, &buf[5]);
138 } else if (!strncasecmp(buf, "rfca=", 5)) {
139 strcpy(rfca, &buf[5]);
140 } else if (!strncasecmp(buf, "rcpt=", 5)) {
141 strcpy(rcpt, &buf[5]);
142 } else if (!strncasecmp(buf, "msgn=", 5)) {
143 strcpy(msgn, &buf[5]);
144 } else if (!strncasecmp(buf, "time=", 5)) {
146 gmtime_r(&now, &now_tm);
147 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
150 wprintf(" <item>\n");
152 wprintf(" <title>%s from", subj);
154 wprintf(" <title>From");
156 wprintf(" %s", from);
157 wprintf(" in %s", room);
158 if (strcmp(hnod, serv_info.serv_humannode) && strlen(hnod) > 0) {
159 wprintf(" on %s", hnod);
161 wprintf("</title>\n");
163 wprintf(" <pubDate>%s</pubDate>\n", date);
165 wprintf(" <guid isPermaLink=\"false\">%s</guid>\n", msgn);
166 /* Now the hard part, the message itself */
167 strcpy(content_type, "text/plain");
168 while (serv_getln(buf, sizeof buf), strlen(buf) > 0) {
169 if (!strcmp(buf, "000")) {
170 lprintf(3, "ENDBODY 1\n");
173 if (!strncasecmp(buf, "Content-type: ", 14)) {
174 safestrncpy(content_type, &buf[14], sizeof content_type);
175 for (b = 0; b < strlen(content_type); ++b) {
176 if (!strncasecmp(&content_type[b], "charset=", 8)) {
177 safestrncpy(charset, &content_type[b + 8], sizeof charset);
180 for (b = 0; b < strlen(content_type); ++b) {
181 if (content_type[b] == ';') {
188 /* Set up a character set conversion if we need to */
190 if (strcasecmp(charset, "us-ascii") && strcasecmp(charset, "utf-8")) {
191 ic = iconv_open("UTF-8", charset);
192 if (ic == (iconv_t)(-1)) {
193 lprintf(5, "iconv_open() failed: %s\n", strerror(errno));
199 /* Messages in legacy Citadel variformat get handled thusly... */
200 if (!strcasecmp(content_type, "text/x-citadel-variformat")) {
203 wprintf(" <description><![CDATA[");
205 serv_getln(buf, sizeof buf);
206 if (!strcmp(buf, "000")) {
208 wprintf("</blockquote>");
212 if (intext == 1 && isspace(buf[0])) {
216 if (bq == 0 && !strncmp(buf, " >", 2)) {
217 wprintf("<blockquote>");
219 } else if (bq == 1 && strncmp(buf, " >", 2)) {
220 wprintf("</blockquote>");
227 wprintf("]]></description>\n");
229 /* Boring old 80-column fixed format text gets handled this way... */
230 else if (!strcasecmp(content_type, "text/plain")) {
231 wprintf(" <description><![CDATA[");
232 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
233 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
234 if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = 0;
237 if (ic != (iconv_t)(-1) ) {
239 ibuflen = strlen(ibuf);
241 obuf = (char *) malloc(obuflen);
243 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
244 osav[SIZ-obuflen] = 0;
245 safestrncpy(buf, osav, sizeof buf);
250 while ((strlen(buf) > 0) && (isspace(buf[strlen(buf) - 1])))
251 buf[strlen(buf) - 1] = 0;
253 ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) {
254 wprintf("<blockquote>");
256 } else if ((bq == 1) &&
257 (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) {
258 wprintf("</blockquote>");
264 wprintf("</tt><br />\n");
266 wprintf("]]></description>\n");
268 /* HTML is fun, but we've got to strip it first */
269 else if (!strcasecmp(content_type, "text/html")) {
270 wprintf(" <description><![CDATA[");
271 output_html(charset);
272 wprintf("]]></description>\n");
276 wprintf(" </item>\n");
278 lprintf(3, "Finished message %d of %d\n", a+1, nummsgs);
283 wprintf(" </channel>\n");