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)
54 iconv_t ic = (iconv_t)(-1) ;
55 char *ibuf; /**< Buffer of characters to be converted */
56 char *obuf; /**< Buffer for converted characters */
57 size_t ibuflen; /**< Length of input buffer */
58 size_t obuflen; /**< Length of output buffer */
59 char *osav; /**< Saved pointer to output buffer */
71 char content_type[256];
76 serv_printf("USER %s", ANON_RSS_USER);
77 serv_getln(buf, sizeof buf);
78 serv_printf("PASS %s", ANON_RSS_PASS);
79 serv_getln(buf, sizeof buf);
80 become_logged_in(ANON_RSS_USER, ANON_RSS_PASS, buf);
83 authorization_required(_("Not logged in"));
88 if (gotoroom((char *)roomname)) {
89 lprintf(3, "RSS: Can't goto requested room\n");
90 hprintf("HTTP/1.1 404 Not Found\r\n");
91 hprintf("Content-Type: text/html\r\n");
92 wprintf("Error retrieving RSS feed: couldn't find room\n");
97 nummsgs = load_msg_ptrs("MSGS LAST|15", 0);
99 lprintf(3, "RSS: No messages found\n");
100 hprintf("HTTP/1.1 404 Not Found\r\n");
101 hprintf("Content-Type: text/html\r\n");
102 wprintf(_("Error retrieving RSS feed: couldn't find messages\n"));
108 /** Read time of last message immediately */
109 serv_printf("MSG4 %ld", WC->msgarr[nummsgs - 1]);
110 serv_getln(buf, sizeof buf);
112 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "000")) {
113 if (!strncasecmp(buf, "msgn=", 5)) {
114 strcpy(msgn, &buf[5]);
116 if (!strncasecmp(buf, "time=", 5)) {
118 gmtime_r(&now, &now_tm);
119 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
123 // Commented out. Play dumb for now, also doesn't work with anonrss hack
124 /* if (if_modified_since > 0 && if_modified_since > now) {
125 lprintf(3, "RSS: Feed not updated since the last time you looked\n");
126 hprintf("HTTP/1.1 304 Not Modified\r\n");
127 hprintf("Last-Modified: %s\r\n", date);
129 gmtime_r(&now, &now_tm);
130 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
131 hprintf("Date: %s\r\n", date);
132 if (*msgn) hprintf("ETag: %s\r\n", msgn); */
138 lprintf(3, "RSS: Yum yum! This feed is tasty!\n");
139 hprintf("HTTP/1.1 200 OK\r\n");
140 hprintf("Last-Modified: %s\r\n", date);
141 /* if (*msgn) wprintf("ETag: %s\r\n\r\n", msgn); */
142 hprintf("Content-Type: application/rss+xml\r\n");
143 hprintf("Server: %s\r\n", PACKAGE_STRING);
144 hprintf("Connection: close\r\n");
145 if (!strcasecmp(ChrPtr(request_method), "HEAD"))
148 /* <?xml.. etc confuses our subst parser, so do it here */
149 svput("XML_HEAD", WCS_STRING, "<?xml version=\"1.0\" ?>");
150 svput("XML_STYLE", WCS_STRING, "<?xml-stylesheet type=\"text/css\" href=\"/static/rss_browser.css\" ?>");
151 svput("ROOM", WCS_STRING, WC->wc_roomname);
152 svput("NODE", WCS_STRING, serv_info.serv_humannode);
154 svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), WC->http_host);
156 /** Get room info for description */
158 serv_getln(buf, sizeof buf);
159 char description[SIZ] = "";
162 serv_getln(buf, sizeof buf);
163 if (!strcmp(buf, "000"))
165 strncat(description, buf, strlen(buf));
168 svput("ROOM_DESCRIPTION", WCS_STRING, description);
170 svput("822_PUB_DATE", WCS_STRING, date);
172 svput("GENERATOR", WCS_STRING, PACKAGE_STRING);
173 do_template("rss_head", NULL);
175 /** Read all messages and output as RSS items */
176 for (a = 0; a < nummsgs; ++a) {
177 /** Read message and output each as RSS item */
178 serv_printf("MSG4 %ld", WC->msgarr[a]);
179 serv_getln(buf, sizeof buf);
180 if (buf[0] != '1') continue;
191 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
192 if (!strcmp(buf, "000")) {
193 goto ENDITEM; /** screw it */
194 } else if (!strncasecmp(buf, "from=", 5)) {
195 strcpy(from, &buf[5]);
196 utf8ify_rfc822_string(from);
197 } else if (!strncasecmp(buf, "subj=", 5)) {
198 strcpy(subj, &buf[5]);
199 utf8ify_rfc822_string(subj);
200 } else if (!strncasecmp(buf, "hnod=", 5)) {
201 strcpy(node, &buf[5]);
202 } else if (!strncasecmp(buf, "room=", 5)) {
203 strcpy(room, &buf[5]);
204 } else if (!strncasecmp(buf, "rfca=", 5)) {
205 strcpy(rfca, &buf[5]);
206 } else if (!strncasecmp(buf, "rcpt=", 5)) {
207 strcpy(rcpt, &buf[5]);
208 } else if (!strncasecmp(buf, "msgn=", 5)) {
209 strcpy(msgn, &buf[5]);
210 } else if (!strncasecmp(buf, "time=", 5)) {
212 gmtime_r(&now, &now_tm);
213 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
217 svprintf(HKEY("SUBJ"), WCS_STRING, _("%s from"), subj);
219 svput("SUBJ", WCS_STRING, _("From"));
221 svprintf(HKEY("IN_ROOM"), WCS_STRING, _("%s in %s"), from, room);
222 if (strcmp(hnod, serv_info.serv_humannode) && !IsEmptyStr(hnod)) {
223 svprintf(HKEY("NODE"), WCS_STRING, _(" on %s"), hnod);
226 svprintf(HKEY("822_PUB_DATE"),WCS_STRING, _("%s"), date);
228 svprintf(HKEY("GUID"), WCS_STRING,"%s", msgn);
229 do_template("rss_item", NULL);
230 /** Now the hard part, the message itself */
231 strcpy(content_type, "text/plain");
232 while (serv_getln(buf, sizeof buf), !IsEmptyStr(buf)) {
233 if (!strcmp(buf, "000")) {
236 if (!strncasecmp(buf, "Content-type: ", 14)) {
238 safestrncpy(content_type, &buf[14], sizeof content_type);
239 len = strlen (content_type);
240 for (b = 0; b < len; ++b) {
241 if (!strncasecmp(&content_type[b], "charset=", 8)) {
242 safestrncpy(charset, &content_type[b + 8], sizeof charset);
245 for (b = 0; b < len; ++b) {
246 if (content_type[b] == ';') {
254 /** Set up a character set conversion if we need to */
256 if (strcasecmp(charset, "us-ascii") && strcasecmp(charset, "utf-8") && strcasecmp(charset, "") ) {
257 ic = ctdl_iconv_open("UTF-8", charset);
258 if (ic == (iconv_t)(-1)) {
259 lprintf(5, "%s:%d iconv_open() failed: %s\n",
260 __FILE__, __LINE__, strerror(errno));
266 /** Messages in legacy Citadel variformat get handled thusly... */
267 if (!strcasecmp(content_type, "text/x-citadel-variformat")) {
271 serv_getln(buf, sizeof buf);
272 if (!strcmp(buf, "000")) {
274 wprintf("</blockquote>");
278 if (intext == 1 && isspace(buf[0])) {
282 if (bq == 0 && !strncmp(buf, " >", 2)) {
283 wprintf("<blockquote>");
285 } else if (bq == 1 && strncmp(buf, " >", 2)) {
286 wprintf("</blockquote>");
289 url(buf, sizeof(buf));
293 display_rss_control(from, subj);
295 /** Boring old 80-column fixed format text gets handled this way... */
296 else if (!strcasecmp(content_type, "text/plain")) {
297 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
300 if (buf[len-1] == '\n') buf[--len] = 0;
301 if (buf[len-1] == '\r') buf[--len] = 0;
304 if (ic != (iconv_t)(-1) ) {
308 obuf = (char *) malloc(obuflen);
310 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
311 osav[SIZ-obuflen] = 0;
312 safestrncpy(buf, osav, sizeof buf);
317 while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1])))
320 ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) {
321 wprintf("<blockquote>");
323 } else if ((bq == 1) &&
324 (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) {
325 wprintf("</blockquote>");
329 url(buf, sizeof(buf));
331 wprintf("</tt><br />\n");
333 display_rss_control(from, subj);
335 /** HTML is fun, but we've got to strip it first */
336 else if (!strcasecmp(content_type, "text/html")) {
337 output_html(charset, 0, WC->msgarr[a]);
341 //wprintf(" </item>\n");
342 do_template("rss_item_end", NULL);
348 wprintf(" </channel>\n");
351 #ifdef ALLOW_ANON_RSS
352 end_webcit_session();