/* * Entry point for RSS feed generator */ void feed_rss(void) { char buf[1024]; output_headers(0, 0, 0, 0, 1, 0); hprintf("Content-type: text/xml; charset=utf-8\r\n"); hprintf( "Server: %s / %s\r\n" "Connection: close\r\n" , PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software) ); begin_burst(); wc_printf("<?xml version=\"1.0\"?>" "<rss version=\"2.0\">" "<channel>" ); wc_printf("<title>"); escputs(ChrPtr(WC->CurRoom.name)); wc_printf("</title>"); wc_printf("<link>"); escputs(ChrPtr(site_prefix)); wc_printf("/</link>"); serv_puts("RINF"); serv_getln(buf, sizeof buf); if (buf[0] == '1') { wc_printf("<description>\r\n"); while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { escputs(buf); wc_printf("\r\n"); } wc_printf("</description>"); } wc_printf("<image><title>"); escputs(ChrPtr(WC->CurRoom.name)); wc_printf("</title><url>"); escputs(ChrPtr(site_prefix)); wc_printf("/roompic?room="); urlescputs(ChrPtr(WC->CurRoom.name)); wc_printf("</url><link>"); escputs(ChrPtr(site_prefix)); wc_printf("/</link></image>\r\n"); feed_rss_do_room_info_as_description(); feed_rss_do_messages(); wc_printf("</channel>" "</rss>" "\r\n\r\n" ); wDumpContent(0); }
/* * Display the OpenIDs associated with an account */ void display_openids(void) { wcsession *WCC = WC; char buf[1024]; int bg = 0; output_headers(1, 1, 1, 0, 0, 0); do_template("box_begin_1"); StrBufAppendBufPlain(WCC->WBuf, _("Manage Account/OpenID Associations"), -1, 0); do_template("box_begin_2"); if (WCC->serv_info->serv_supports_openid) { wc_printf("<table class=\"altern\">"); serv_puts("OIDL"); serv_getln(buf, sizeof buf); if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { bg = 1 - bg; wc_printf("<tr class=\"%s\">", (bg ? "even" : "odd")); wc_printf("<td><img src=\"static/webcit_icons/openid-small.gif\"></td><td>"); escputs(buf); wc_printf("</td><td>"); wc_printf("<a href=\"openid_detach?id_to_detach="); urlescputs(buf); wc_printf("\" onClick=\"return confirm('%s');\">", _("Do you really want to delete this OpenID?")); wc_printf("%s</a>", _("(delete)")); wc_printf("</td></tr>\n"); } wc_printf("</table><br>\n"); wc_printf("<form method=\"POST\" action=\"openid_attach\">\n"); wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WCC->nonce); wc_printf(_("Add an OpenID: ")); wc_printf("<input type=\"text\" name=\"openid_url\" class=\"openid_urlarea\" size=\"40\">\n"); wc_printf("<input type=\"submit\" name=\"attach_button\" value=\"%s\">" "</form></center>\n", _("Attach")); } else { wc_printf(_("%s does not permit authentication via OpenID."), ChrPtr(WCC->serv_info->serv_humannode)); } do_template("box_end"); wDumpContent(2); }
/* * Display a list of all pages in a Wiki room (template callback) */ void tmplput_display_wiki_pagelist(StrBuf *Target, WCTemplputParams *TP) { StrBuf *Buf; int row = 0; if (!IsEmptyStr(bstr("query"))) { serv_printf("MSGS SEARCH|%s||4", bstr("query")); /* search-reduced list */ } else { serv_printf("MSGS ALL|||4"); /* full list */ } Buf = NewStrBuf(); StrBuf_ServGetln(Buf); if (GetServerStatus(Buf, NULL) == 1) { StrBuf *pagetitle = NewStrBuf(); wc_printf("<table class=\"wiki_pagelist_background\">"); wc_printf("<th>%s</th>", _("Page title")); while((StrBuf_ServGetln(Buf) >= 0) && strcmp(ChrPtr(Buf), "000")) { StrBufExtract_token(pagetitle, Buf, 1, '|'); if (!bmstrcasestr((char *)ChrPtr(pagetitle), "_HISTORY_")) { /* no history pages */ wc_printf("<tr bgcolor=\"%s\">", ((row%2) ? "#FFFFFF" : "#DDDDDD")); wc_printf("<td><a href=\"wiki?page="); urlescputs(ChrPtr(pagetitle)); wc_printf("\">"); escputs(ChrPtr(pagetitle)); wc_printf("</a></td>"); wc_printf("</tr>\n"); ++row; } } wc_printf("</table>\n"); FreeStrBuf(&pagetitle); } FreeStrBuf(&Buf); }
/* * RSS feed generator -- do one message */ void feed_rss_one_message(long msgnum) { int in_body = 0; int in_messagetext = 0; int found_title = 0; int found_guid = 0; char pubdate[128]; StrBuf *messagetext = NULL; int is_top_level_post = 1; const char *BufPtr = NULL; StrBuf *Line = NewStrBufPlain(NULL, 1024); char buf[1024]; int permalink_hash = 0; /* Phase 1: read the message into memory */ serv_printf("MSG4 %ld", msgnum); serv_getln(buf, sizeof buf); if (buf[0] != '1') return; StrBuf *ServerResponse = NewStrBuf(); while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { StrBufAppendPrintf(ServerResponse, "%s\n", buf); } /* Phase 2: help SkyNet become self-aware */ BufPtr = NULL; while (StrBufSipLine(Line, ServerResponse, &BufPtr), ((BufPtr!=StrBufNOTNULL)&&(BufPtr!=NULL)) ) { if (in_body) { /* do nothing */ } else if (StrLength(Line) == 0) { ++in_body; } else if ((StrLength(Line) > 5) && (!strncasecmp(ChrPtr(Line), "wefw=", 5))) { is_top_level_post = 0; /* presence of references means it's a reply/comment */ } else if ((StrLength(Line) > 5) && (!strncasecmp(ChrPtr(Line), "msgn=", 5))) { StrBufCutLeft(Line, 5); permalink_hash = ThreadIdHash(Line); } } /* * Phase 3: output the message in RSS <item> form * (suppress replies [comments] if this is a blog room) */ if ( (WC->CurRoom.view != VIEW_BLOG) || (is_top_level_post == 1) ) { wc_printf("<item>"); wc_printf("<link>%s/readfwd?go=", ChrPtr(site_prefix)); urlescputs(ChrPtr(WC->CurRoom.name)); if ((WC->CurRoom.view == VIEW_BLOG) && (permalink_hash != 0)) { wc_printf("?p=%d", permalink_hash); } else { wc_printf("?start_reading_at=%ld", msgnum); } wc_printf("</link>"); BufPtr = NULL; in_body = 0; in_messagetext = 0; while (StrBufSipLine(Line, ServerResponse, &BufPtr), ((BufPtr!=StrBufNOTNULL)&&(BufPtr!=NULL)) ) { safestrncpy(buf, ChrPtr(Line), sizeof buf); /* XML parsers can be picky; strip out nonprintable header characters */ if ((strlen(buf)>=6) && (buf[4]=='=')) { char *p = &buf[5]; while (*p) { if (!isprint(*p)) { *p = 0; } ++p; } } /* Now output fields */ if (in_body) { if (in_messagetext) { StrBufAppendBufPlain(messagetext, buf, -1, 0); StrBufAppendBufPlain(messagetext, HKEY("\r\n"), 0); } else if (IsEmptyStr(buf)) { in_messagetext = 1; } } else if (!strncasecmp(buf, "subj=", 5)) { wc_printf("<title>"); escputs(&buf[5]); wc_printf("</title>"); ++found_title; } else if (!strncasecmp(buf, "exti=", 5)) { wc_printf("<guid isPermaLink=\"false\">"); escputs(&buf[5]); wc_printf("</guid>"); ++found_guid; } else if (!strncasecmp(buf, "time=", 5)) { http_datestring(pubdate, sizeof pubdate, atol(&buf[5])); wc_printf("<pubDate>%s</pubDate>", pubdate); } else if (!strncasecmp(buf, "text", 4)) { if (!found_title) { wc_printf("<title>Message #%ld</title>", msgnum); } if (!found_guid) { wc_printf("<guid isPermaLink=\"false\">%ld@%s</guid>", msgnum, ChrPtr(WC->serv_info->serv_humannode) ); } wc_printf("<description>"); in_body = 1; messagetext = NewStrBuf(); } } if (in_body) { cdataout((char*)ChrPtr(messagetext)); FreeStrBuf(&messagetext); wc_printf("</description>"); } wc_printf("</item>"); } FreeStrBuf(&Line); FreeStrBuf(&ServerResponse); return; }
/* * Display the revision history for a wiki page (template callback) */ void tmplput_display_wiki_history(StrBuf *Target, WCTemplputParams *TP) { char pagename[128]; StrBuf *Buf; int row = 0; safestrncpy(pagename, bstr("page"), sizeof pagename); str_wiki_index(pagename); serv_printf("WIKI history|%s", pagename); Buf = NewStrBuf(); StrBuf_ServGetln(Buf); if (GetServerStatus(Buf, NULL) == 1) { time_t rev_date; char rev_date_displayed[64]; StrBuf *rev_uuid = NewStrBuf(); StrBuf *author = NewStrBuf(); StrBuf *node = NewStrBuf(); wc_printf("<table class=\"wiki_history_background\">"); wc_printf("<th>%s</th>", _("Date")); wc_printf("<th>%s</th>", _("Author")); while((StrBuf_ServGetln(Buf) >= 0) && strcmp(ChrPtr(Buf), "000")) { rev_date = extract_long(ChrPtr(Buf), 1); webcit_fmt_date(rev_date_displayed, sizeof rev_date_displayed, rev_date, DATEFMT_FULL); StrBufExtract_token(author, Buf, 2, '|'); wc_printf("<tr bgcolor=\"%s\">", ((row%2) ? "#FFFFFF" : "#DDDDDD")); wc_printf("<td>%s</td><td>", rev_date_displayed); if (!strcasecmp(ChrPtr(node), (char *)WC->serv_info->serv_nodename)) { escputs(ChrPtr(author)); wc_printf(" @ "); escputs(ChrPtr(node)); } else { wc_printf("<a href=\"showuser?who="); urlescputs(ChrPtr(author)); wc_printf("\">"); escputs(ChrPtr(author)); wc_printf("</a>"); } wc_printf("</td>"); if (row == 0) { wc_printf("<td><a href=\"wiki?page=%s", bstr("page")); wc_printf("?go="); urlescputs(ChrPtr(WC->CurRoom.name)); wc_printf("\">%s</a></td>", _("(show)")); wc_printf("<td>(%s)</td>", _("Current version")); } else { wc_printf("<td><a href=\"wiki?page=%s?rev=%s", bstr("page"), ChrPtr(rev_uuid) ); wc_printf("?go="); urlescputs(ChrPtr(WC->CurRoom.name)); wc_printf("\">%s</a></td>", _("(show)")); wc_printf("<td><a href=\"javascript:GetLoggedInFirst(encodeURIComponent('wiki?page=%s?rev=%s?revert=1'))\">%s</a></td>", bstr("page"), ChrPtr(rev_uuid), _("(revert)") ); } wc_printf("</tr>\n"); /* Extract all fields except the author and date after displaying the row. This * is deliberate, because the timestamp reflects when the diff was written, not * when the version which it reflects was written. Similarly, the name associated * with each diff is the author who created the newer version of the page that * made the diff happen. */ StrBufExtract_token(rev_uuid, Buf, 0, '|'); StrBufExtract_token(node, Buf, 3, '|'); ++row; } wc_printf("</table>\n"); FreeStrBuf(&author); FreeStrBuf(&node); FreeStrBuf(&rev_uuid); } else { wc_printf("%s", ChrPtr(Buf)); } FreeStrBuf(&Buf); }