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(const StrBuf *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 */
63 char description[SIZ] = "";
74 char content_type[256];
77 if (!WCC->logged_in) {
82 serv_printf("USER %s", ANON_RSS_USER);
83 serv_getln(buf, sizeof buf);
84 serv_printf("PASS %s", ANON_RSS_PASS);
86 StrBuf_ServGetln(Buf);
87 User = NewStrBufPlain(HKEY(ANON_RSS_USER));
88 Pass = NewStrBufPlain(HKEY(ANON_RSS_PASS));
89 become_logged_in(User, Pass, Buf);
95 authorization_required(_("Not logged in"));
100 if (gotoroom(roomname)) {
101 lprintf(3, "RSS: Can't goto requested room\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 room\n");
109 nummsgs = load_msg_ptrs("MSGS LAST|15", 0);
111 lprintf(3, "RSS: No messages found\n");
112 hprintf("HTTP/1.1 404 Not Found\r\n");
113 hprintf("Content-Type: text/html\r\n");
114 wprintf(_("Error retrieving RSS feed: couldn't find messages\n"));
120 /** Read time of last message immediately */
121 Msg = GetMessagePtrAt(nummsgs - 1, WCC->summ);
123 serv_printf("MSG4 %ld", (Msg==NULL)? 0 : Msg->msgnum);
124 serv_getln(buf, sizeof buf);
126 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "000")) {
127 if (!strncasecmp(buf, "msgn=", 5)) {
128 strcpy(msgn, &buf[5]);
130 if (!strncasecmp(buf, "time=", 5)) {
132 gmtime_r(&now, &now_tm);
133 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
137 /*/ Commented out. Play dumb for now, also doesn't work with anonrss hack */
138 /* if (if_modified_since > 0 && if_modified_since > now) {
139 lprintf(3, "RSS: Feed not updated since the last time you looked\n");
140 hprintf("HTTP/1.1 304 Not Modified\r\n");
141 hprintf("Last-Modified: %s\r\n", date);
143 gmtime_r(&now, &now_tm);
144 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
145 hprintf("Date: %s\r\n", date);
146 if (*msgn) hprintf("ETag: %s\r\n", msgn); * /
152 lprintf(3, "RSS: Yum yum! This feed is tasty!\n");
153 hprintf("HTTP/1.1 200 OK\r\n");
154 hprintf("Last-Modified: %s\r\n", date);
155 /* if (*msgn) wprintf("ETag: %s\r\n\r\n", msgn); */
156 hprintf("Content-Type: application/rss+xml\r\n");
157 hprintf("Server: %s\r\n", PACKAGE_STRING);
158 hprintf("Connection: close\r\n");
159 if (!strcasecmp(ChrPtr(request_method), "HEAD"))
162 /* <?xml.. etc confuses our subst parser, so do it here */
163 svput("XML_HEAD", WCS_STRING, "<?xml version=\"1.0\" ?>");
164 svput("XML_STYLE", WCS_STRING, "<?xml-stylesheet type=\"text/css\" href=\"/static/rss_browser.css\" ?>");
165 SVPutBuf("ROOM", WCC->wc_roomname, 1);
166 SVPutBuf("NODE", WCC->serv_info->serv_humannode, 1);
168 svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), ChrPtr(WCC->http_host));
170 /** Get room info for description */
172 serv_getln(buf, sizeof buf);
175 serv_getln(buf, sizeof buf);
176 if (!strcmp(buf, "000"))
178 strncat(description, buf, strlen(buf));
181 svput("ROOM_DESCRIPTION", WCS_STRING, description);
183 svput("822_PUB_DATE", WCS_STRING, date);
185 svput("GENERATOR", WCS_STRING, PACKAGE_STRING);
186 do_template("rss_head", NULL);
188 /** Read all messages and output as RSS items */
189 for (a = 0; a < nummsgs; ++a) {
190 /** Read message and output each as RSS item */
191 Msg = GetMessagePtrAt(a, WCC->summ);
192 serv_printf("MSG4 %ld", (Msg==NULL)? 0 : Msg->msgnum);
193 serv_getln(buf, sizeof buf);
194 if (buf[0] != '1') continue;
205 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
206 if (!strcmp(buf, "000")) {
207 goto ENDITEM; /** screw it */
208 } else if (!strncasecmp(buf, "from=", 5)) {
209 strcpy(from, &buf[5]);
210 utf8ify_rfc822_string(from);
211 } else if (!strncasecmp(buf, "subj=", 5)) {
212 strcpy(subj, &buf[5]);
213 utf8ify_rfc822_string(subj);
214 } else if (!strncasecmp(buf, "hnod=", 5)) {
215 strcpy(node, &buf[5]);
216 } else if (!strncasecmp(buf, "room=", 5)) {
217 strcpy(room, &buf[5]);
218 } else if (!strncasecmp(buf, "rfca=", 5)) {
219 strcpy(rfca, &buf[5]);
220 } else if (!strncasecmp(buf, "rcpt=", 5)) {
221 strcpy(rcpt, &buf[5]);
222 } else if (!strncasecmp(buf, "msgn=", 5)) {
223 strcpy(msgn, &buf[5]);
224 } else if (!strncasecmp(buf, "time=", 5)) {
226 gmtime_r(&now, &now_tm);
227 strftime(date, sizeof date, "%a, %d %b %Y %H:%M:%S GMT", &now_tm);
231 svprintf(HKEY("SUBJ"), WCS_STRING, _("%s from"), subj);
233 svput("SUBJ", WCS_STRING, _("From"));
235 svprintf(HKEY("IN_ROOM"), WCS_STRING, _("%s in %s"), from, room);
236 if (strcmp(hnod, ChrPtr(WCC->serv_info->serv_humannode)) && !IsEmptyStr(hnod)) {
237 svprintf(HKEY("NODE"), WCS_STRING, _(" on %s"), hnod);
240 svprintf(HKEY("822_PUB_DATE"),WCS_STRING, _("%s"), date);
242 svprintf(HKEY("GUID"), WCS_STRING,"%s", msgn);
243 do_template("rss_item", NULL);
244 /** Now the hard part, the message itself */
245 strcpy(content_type, "text/plain");
246 while (serv_getln(buf, sizeof buf), !IsEmptyStr(buf)) {
247 if (!strcmp(buf, "000")) {
250 if (!strncasecmp(buf, "Content-type: ", 14)) {
252 safestrncpy(content_type, &buf[14], sizeof content_type);
253 len = strlen (content_type);
254 for (b = 0; b < len; ++b) {
255 if (!strncasecmp(&content_type[b], "charset=", 8)) {
256 safestrncpy(charset, &content_type[b + 8], sizeof charset);
259 for (b = 0; b < len; ++b) {
260 if (content_type[b] == ';') {
268 /** Set up a character set conversion if we need to */
270 if (strcasecmp(charset, "us-ascii") && strcasecmp(charset, "utf-8") && strcasecmp(charset, "") ) {
271 ctdl_iconv_open("UTF-8", charset, &ic);
272 if (ic == (iconv_t)(-1)) {
273 lprintf(5, "%s:%d iconv_open() failed: %s\n",
274 __FILE__, __LINE__, strerror(errno));
280 /** Messages in legacy Citadel variformat get handled thusly... */
281 if (!strcasecmp(content_type, "text/x-citadel-variformat")) {
285 serv_getln(buf, sizeof buf);
286 if (!strcmp(buf, "000")) {
288 wprintf("</blockquote>");
292 if (intext == 1 && isspace(buf[0])) {
296 if (bq == 0 && !strncmp(buf, " >", 2)) {
297 wprintf("<blockquote>");
299 } else if (bq == 1 && strncmp(buf, " >", 2)) {
300 wprintf("</blockquote>");
303 url(buf, sizeof(buf));
307 display_rss_control(from, subj);
309 /** Boring old 80-column fixed format text gets handled this way... */
310 else if (!strcasecmp(content_type, "text/plain")) {
311 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
314 if (buf[len-1] == '\n') buf[--len] = 0;
315 if (buf[len-1] == '\r') buf[--len] = 0;
318 if (ic != (iconv_t)(-1) ) {
322 obuf = (char *) malloc(obuflen);
324 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
325 osav[SIZ-obuflen] = 0;
326 safestrncpy(buf, osav, sizeof buf);
331 while ((!IsEmptyStr(buf)) && (isspace(buf[len - 1])))
334 ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) {
335 wprintf("<blockquote>");
337 } else if ((bq == 1) &&
338 (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) {
339 wprintf("</blockquote>");
343 url(buf, sizeof(buf));
345 wprintf("</tt><br />\n");
347 display_rss_control(from, subj);
349 /** HTML is fun, but we've got to strip it first */
350 else if (!strcasecmp(content_type, "text/html")) {
351 Msg = GetMessagePtrAt(a, WCC->summ);
353 output_html(charset, 0, (Msg==NULL)? 0 : Msg->msgnum, NULL, NULL);
357 /* wprintf(" </item>\n"); */
358 do_template("rss_item_end", NULL);
364 wprintf(" </channel>\n");
367 #ifdef ALLOW_ANON_RSS
368 end_webcit_session();