8 /* Since we don't have anonymous Webcit access yet, you can
9 * allow the feed to be produced by a special user created just for
10 * this purpose. The Citadel Developers do not take any responsibility
11 * for the security of your system when you use this 'feature' */
12 #define ALLOW_ANON_RSS 0
13 #define ANON_RSS_USER ""
14 #define ANON_RSS_PASS ""
15 time_t if_modified_since; /**< the last modified stamp */
18 * view rss Config menu
19 * reply_to the original author
20 * subject the subject of the feed
22 void display_rss_control(char *reply_to, char *subject)
24 wprintf("<div style=\"align: right;\"><p>\n");
25 wprintf("<a href=\"display_enter?recp=");
28 if (strncasecmp(subject, "Re: ", 3)) wprintf("Re:%%20");
30 wprintf("\">[%s]</a> \n", _("Reply"));
31 wprintf("<a href=\"display_enter?recp=");
33 wprintf("&force_room=_MAIL_&subject=");
34 if (strncasecmp(subject, "Re: ", 3)) wprintf("Re:%%20");
36 wprintf("\">[%s]</a>\n", _("Email"));
37 wprintf("</p></div>\n");
42 * print the feed to the subscriber
43 * roomname the room we sould print out as rss
44 * request_method the way the rss is requested????
46 void display_rss(char *roomname, StrBuf *request_method)
56 iconv_t ic = (iconv_t)(-1) ;
57 char *ibuf; /**< Buffer of characters to be converted */
58 char *obuf; /**< Buffer for converted characters */
59 size_t ibuflen; /**< Length of input buffer */
60 size_t obuflen; /**< Length of output buffer */
61 char *osav; /**< Saved pointer to output buffer */
73 char content_type[256];
76 if (!WCC->logged_in) {
78 serv_printf("USER %s", ANON_RSS_USER);
79 serv_getln(buf, sizeof buf);
80 serv_printf("PASS %s", ANON_RSS_PASS);
81 serv_getln(buf, sizeof buf);
82 become_logged_in(ANON_RSS_USER, ANON_RSS_PASS, buf);
85 authorization_required(_("Not logged in"));
90 if (gotoroom((char *)roomname)) {
91 lprintf(3, "RSS: Can't goto requested room\n");
92 hprintf("HTTP/1.1 404 Not Found\r\n");
93 hprintf("Content-Type: text/html\r\n");
94 wprintf("Error retrieving RSS feed: couldn't find room\n");
99 nummsgs = load_msg_ptrs("MSGS LAST|15", 0);
101 lprintf(3, "RSS: No messages found\n");
102 hprintf("HTTP/1.1 404 Not Found\r\n");
103 hprintf("Content-Type: text/html\r\n");
104 wprintf(_("Error retrieving RSS feed: couldn't find messages\n"));
110 /** Read time of last message immediately */
111 Msg = GetMessagePtrAt(nummsgs - 1, WCC->summ);
113 serv_printf("MSG4 %ld", (Msg==NULL)? 0 : Msg->msgnum);
114 serv_getln(buf, sizeof buf);
116 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "000")) {
117 if (!strncasecmp(buf, "msgn=", 5)) {
118 strcpy(msgn, &buf[5]);
120 if (!strncasecmp(buf, "time=", 5)) {
122 gmtime_r(&now, &now_tm);
123 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
127 // Commented out. Play dumb for now, also doesn't work with anonrss hack
128 /* if (if_modified_since > 0 && if_modified_since > now) {
129 lprintf(3, "RSS: Feed not updated since the last time you looked\n");
130 hprintf("HTTP/1.1 304 Not Modified\r\n");
131 hprintf("Last-Modified: %s\r\n", date);
133 gmtime_r(&now, &now_tm);
134 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
135 hprintf("Date: %s\r\n", date);
136 if (*msgn) hprintf("ETag: %s\r\n", msgn); */
142 lprintf(3, "RSS: Yum yum! This feed is tasty!\n");
143 hprintf("HTTP/1.1 200 OK\r\n");
144 hprintf("Last-Modified: %s\r\n", date);
145 /* if (*msgn) wprintf("ETag: %s\r\n\r\n", msgn); */
146 hprintf("Content-Type: application/rss+xml\r\n");
147 hprintf("Server: %s\r\n", PACKAGE_STRING);
148 hprintf("Connection: close\r\n");
149 if (!strcasecmp(ChrPtr(request_method), "HEAD"))
152 /* <?xml.. etc confuses our subst parser, so do it here */
153 svput("XML_HEAD", WCS_STRING, "<?xml version=\"1.0\" ?>");
154 svput("XML_STYLE", WCS_STRING, "<?xml-stylesheet type=\"text/css\" href=\"/static/rss_browser.css\" ?>");
155 svput("ROOM", WCS_STRING, WCC->wc_roomname);
156 svput("NODE", WCS_STRING, serv_info.serv_humannode);
158 svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), WCC->http_host);
160 /** Get room info for description */
162 serv_getln(buf, sizeof buf);
163 char description[SIZ] = "";
166 serv_getln(buf, sizeof buf);
167 if (!strcmp(buf, "000"))
169 strncat(description, buf, strlen(buf));
172 svput("ROOM_DESCRIPTION", WCS_STRING, description);
174 svput("822_PUB_DATE", WCS_STRING, date);
176 svput("GENERATOR", WCS_STRING, PACKAGE_STRING);
177 do_template("rss_head", NULL);
179 /** Read all messages and output as RSS items */
180 for (a = 0; a < nummsgs; ++a) {
181 /** Read message and output each as RSS item */
182 Msg = GetMessagePtrAt(a, WCC->summ);
183 serv_printf("MSG4 %ld", (Msg==NULL)? 0 : Msg->msgnum);
184 serv_getln(buf, sizeof buf);
185 if (buf[0] != '1') continue;
196 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
197 if (!strcmp(buf, "000")) {
198 goto ENDITEM; /** screw it */
199 } else if (!strncasecmp(buf, "from=", 5)) {
200 strcpy(from, &buf[5]);
201 utf8ify_rfc822_string(from);
202 } else if (!strncasecmp(buf, "subj=", 5)) {
203 strcpy(subj, &buf[5]);
204 utf8ify_rfc822_string(subj);
205 } else if (!strncasecmp(buf, "hnod=", 5)) {
206 strcpy(node, &buf[5]);
207 } else if (!strncasecmp(buf, "room=", 5)) {
208 strcpy(room, &buf[5]);
209 } else if (!strncasecmp(buf, "rfca=", 5)) {
210 strcpy(rfca, &buf[5]);
211 } else if (!strncasecmp(buf, "rcpt=", 5)) {
212 strcpy(rcpt, &buf[5]);
213 } else if (!strncasecmp(buf, "msgn=", 5)) {
214 strcpy(msgn, &buf[5]);
215 } else if (!strncasecmp(buf, "time=", 5)) {
217 gmtime_r(&now, &now_tm);
218 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
222 svprintf(HKEY("SUBJ"), WCS_STRING, _("%s from"), subj);
224 svput("SUBJ", WCS_STRING, _("From"));
226 svprintf(HKEY("IN_ROOM"), WCS_STRING, _("%s in %s"), from, room);
227 if (strcmp(hnod, serv_info.serv_humannode) && !IsEmptyStr(hnod)) {
228 svprintf(HKEY("NODE"), WCS_STRING, _(" on %s"), hnod);
231 svprintf(HKEY("822_PUB_DATE"),WCS_STRING, _("%s"), date);
233 svprintf(HKEY("GUID"), WCS_STRING,"%s", msgn);
234 do_template("rss_item", NULL);
235 /** Now the hard part, the message itself */
236 strcpy(content_type, "text/plain");
237 while (serv_getln(buf, sizeof buf), !IsEmptyStr(buf)) {
238 if (!strcmp(buf, "000")) {
241 if (!strncasecmp(buf, "Content-type: ", 14)) {
243 safestrncpy(content_type, &buf[14], sizeof content_type);
244 len = strlen (content_type);
245 for (b = 0; b < len; ++b) {
246 if (!strncasecmp(&content_type[b], "charset=", 8)) {
247 safestrncpy(charset, &content_type[b + 8], sizeof charset);
250 for (b = 0; b < len; ++b) {
251 if (content_type[b] == ';') {
259 /** Set up a character set conversion if we need to */
261 if (strcasecmp(charset, "us-ascii") && strcasecmp(charset, "utf-8") && strcasecmp(charset, "") ) {
262 ctdl_iconv_open("UTF-8", charset, &ic);
263 if (ic == (iconv_t)(-1)) {
264 lprintf(5, "%s:%d iconv_open() failed: %s\n",
265 __FILE__, __LINE__, strerror(errno));
271 /** Messages in legacy Citadel variformat get handled thusly... */
272 if (!strcasecmp(content_type, "text/x-citadel-variformat")) {
276 serv_getln(buf, sizeof buf);
277 if (!strcmp(buf, "000")) {
279 wprintf("</blockquote>");
283 if (intext == 1 && isspace(buf[0])) {
287 if (bq == 0 && !strncmp(buf, " >", 2)) {
288 wprintf("<blockquote>");
290 } else if (bq == 1 && strncmp(buf, " >", 2)) {
291 wprintf("</blockquote>");
294 url(buf, sizeof(buf));
298 display_rss_control(from, subj);
300 /** Boring old 80-column fixed format text gets handled this way... */
301 else if (!strcasecmp(content_type, "text/plain")) {
302 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
305 if (buf[len-1] == '\n') buf[--len] = 0;
306 if (buf[len-1] == '\r') buf[--len] = 0;
309 if (ic != (iconv_t)(-1) ) {
313 obuf = (char *) malloc(obuflen);
315 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
316 osav[SIZ-obuflen] = 0;
317 safestrncpy(buf, osav, sizeof buf);
322 while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1])))
325 ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) {
326 wprintf("<blockquote>");
328 } else if ((bq == 1) &&
329 (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) {
330 wprintf("</blockquote>");
334 url(buf, sizeof(buf));
336 wprintf("</tt><br />\n");
338 display_rss_control(from, subj);
340 /** HTML is fun, but we've got to strip it first */
341 else if (!strcasecmp(content_type, "text/html")) {
342 Msg = GetMessagePtrAt(a, WCC->summ);
344 output_html(charset, 0, (Msg==NULL)? 0 : Msg->msgnum, NULL, NULL);
348 //wprintf(" </item>\n");
349 do_template("rss_item_end", NULL);
355 wprintf(" </channel>\n");
358 #ifdef ALLOW_ANON_RSS
359 end_webcit_session();