-typedef struct rssnetcfg rssnetcfg;
-struct rssnetcfg {
- rssnetcfg *next;
- char url[256];
- char *rooms;
- time_t last_error_when;
- int ItemType;
-};
-
-#define RSS_UNSET (1<<0)
-#define RSS_RSS (1<<1)
-#define RSS_ATOM (1<<2)
-#define RSS_REQUIRE_BUF (1<<3)
-
-typedef struct _rss_item {
- char *roomlist;
- int done_parsing;
- StrBuf *guid;
- StrBuf *title;
- StrBuf *link;
- StrBuf *linkTitle;
- StrBuf *reLink;
- StrBuf *reLinkTitle;
- StrBuf *description;
- time_t pubdate;
- StrBuf *channel_title;
- int item_tag_nesting;
- StrBuf *author_or_creator;
- StrBuf *author_url;
- StrBuf *author_email;
-}rss_item;
-
-
-typedef void (*rss_handler_func)(StrBuf *CData,
- rss_item *ri,
- rssnetcfg *Cfg,
- const char** Attr);
-
-typedef struct __rss_xml_handler {
- int Flags;
- rss_handler_func Handler;
-}rss_xml_handler;
-
-
-typedef struct _rsscollection {
- StrBuf *CData;
- StrBuf *Key;
-
- rss_item *Item;
- rssnetcfg *Cfg;
-
- rss_xml_handler *Current;
-} rsscollection;
-
-struct rssnetcfg *rnclist = NULL;
-HashList *StartHandlers = NULL;
-HashList *EndHandlers = NULL;
-HashList *KnownNameSpaces = NULL;
-HashList *UrlShorteners = NULL;
-void AddRSSStartHandler(rss_handler_func Handler, int Flags, const char *key, long len)
-{
- rss_xml_handler *h;
- h = (rss_xml_handler*) malloc(sizeof (rss_xml_handler));
- h->Flags = Flags;
- h->Handler = Handler;
- Put(StartHandlers, key, len, h, NULL);
-}
-void AddRSSEndHandler(rss_handler_func Handler, int Flags, const char *key, long len)
-{
- rss_xml_handler *h;
- h = (rss_xml_handler*) malloc(sizeof (rss_xml_handler));
- h->Flags = Flags;
- h->Handler = Handler;
- Put(EndHandlers, key, len, h, NULL);
-}
-
-#if 0
-//#ifdef HAVE_ICONV
-#include <iconv.h>
-
-
-/*
- * dug this out of the trashcan of the midgard project, lets see if it works for us.
- * original code by Alexander Bokovoy <bokovoy@avilink.ne> distributed under GPL V2 or later
- */
-
-/* Returns:
- >= 0 - successfull, 0 means conversion doesn't use multibyte sequences
- -1 - error during iconv_open call
- -2 - error during iconv_close call
- ----------------------------------
- This function expects that multibyte encoding in 'charset' wouldn't have
- characters with more than 3 bytes. It is not intended to convert UTF-8 because
- we'll never receive UTF-8 in our handler (it is handled by Exat itself).
-*/
-static int
-fill_encoding_info (const char *charset, XML_Encoding * info)
-{
- iconv_t cd = (iconv_t)(-1);
- int flag;
- CtdlLogPrintf(0, "RSS: fill encoding info ...\n");
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- cd = iconv_open ("UCS-2LE", charset);
-#else
- cd = iconv_open ("UCS-2BE", charset);
-#endif
-
- if (cd == (iconv_t) (-1))
- {
- return -1;
- }
-
- {
- unsigned short out = 0;
- unsigned char buf[4];
- unsigned int i0, i1, i2;
- int result = 0;
- flag = 0;
- for (i0 = 0; i0 < 0x100; i0++)
- {
- buf[0] = i0;
- info->map[i0] = 0;
- //result = try (cd, buf, 1, &out);
- if (result < 0)
- {
- }
- else if (result > 0)
- {
- info->map[i0] = out;
- }
- else
- {
- for (i1 = 0; i1 < 0x100; i1++)
- {
- buf[1] = i1;
- ///result = try (cd, buf, 2, &out);
- if (result < 0)
- {
- }
- else if (result > 0)
- {
- flag++;
- info->map[i0] = -2;
- }
- else
- {
- for (i2 = 0; i2 < 0x100; i2++)
- {
- buf[2] = i2;
- ////result = try (cd, buf, 3, &out);
- if (result < 0)
- {
- }
- else if (result > 0)
- {
- flag++;
- info->map[i0] = -3;
- }
- }
- }
- }
- }
- }
- }
-
- if (iconv_close (cd) < 0)
- {
- return -2;
- }
- return flag;
-}
-
-static int
-iconv_convertor (void *data, const char *s)
-{
- XML_Encoding *info = data;
- int res;
- CtdlLogPrintf(0, "RSS: Converting ...\n");
-
- if (s == NULL)
- return -1;
-/*
- GByteArray *result;
- result = g_byte_array_new ();
- if (process_block (info->data, (char *) s, strlen (s), result) == 0)
- {
- res = *(result->data);
- g_byte_array_free (result, TRUE);
- return res;
- }
- g_byte_array_free (result, TRUE);
-*/
- return -1;
-}
-
-static void
-my_release (void *data)
-{
- iconv_t cd = (iconv_t) data;
- if (iconv_close (cd) != 0)
- {
-/// TODO: uh no. exit (1);
- }
-}
-int
-handle_unknown_xml_encoding (void *encodingHandleData,
- const XML_Char * name,
- XML_Encoding * info)
-{
- int result;
- CtdlLogPrintf(0, "RSS: unknown encoding ...\n");
- result = fill_encoding_info (name, info);
- if (result >= 0)
- {
- /*
- Special case: client asked for reverse conversion, we'll provide him with
- iconv descriptor which handles it. Client should release it by himself.
- */
- if(encodingHandleData != NULL)
- *((iconv_t *)encodingHandleData) = iconv_open(name, "UTF-8");
- /*
- Optimization: we do not need conversion function if encoding is one-to-one,
- info->map table will be enough
- */
- if (result == 0)
- {
- info->data = NULL;
- info->convert = NULL;
- info->release = NULL;
- return 1;
- }
- /*
- We do need conversion function because this encoding uses multibyte sequences
- */
- info->data = (void *) iconv_open ("UTF-8", name);
- if ((int)info->data == -1)
- return -1;
- info->convert = iconv_convertor;
- info->release = my_release;
- return 1;
- }
- if(encodingHandleData != NULL)
- *(iconv_t *)encodingHandleData = NULL;
- return 0;
-}
-
-///#endif
-#endif
-size_t GetLocationString( void *ptr, size_t size, size_t nmemb, void *userdata)
-{
-#define LOCATION "location"
- if (strncasecmp((char*)ptr, LOCATION, sizeof(LOCATION) - 1) == 0)
- {
- StrBuf *pURL = (StrBuf*) userdata;
- char *pch = (char*) ptr;
- char *pche;
-
- pche = pch + (size * nmemb);
- pch += sizeof(LOCATION);
-
- while (isspace(*pch) || (*pch == ':'))
- pch ++;
-
- while (isspace(*pche) || (*pche == '\0'))
- pche--;
-
- FlushStrBuf(pURL);
- StrBufPlain(pURL, pch, pche - pch + 1);
- }
- return size * nmemb;
-}
-
-int LookupUrl(StrBuf *ShorterUrlStr)
-{
- CURL *curl;
- char errmsg[1024] = "";
- StrBuf *Answer;
- int rc = 0;
-
- curl = curl_easy_init();
- if (!curl) {
- CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n");
- return 0;
- }
- Answer = NewStrBufPlain(NULL, SIZ);
-
- curl_easy_setopt(curl, CURLOPT_URL, ChrPtr(ShorterUrlStr));
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, Answer);
-// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, rss_libcurl_callback);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errmsg);
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
-#ifdef CURLOPT_HTTP_CONTENT_DECODING
- curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 1);
- curl_easy_setopt(curl, CURLOPT_ENCODING, "");
-#endif
- curl_easy_setopt(curl, CURLOPT_USERAGENT, CITADEL);
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180); /* die after 180 seconds */
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0);
-
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION , GetLocationString);
- curl_easy_setopt(curl, CURLOPT_WRITEHEADER, ShorterUrlStr);
-
-
- if (
- (!IsEmptyStr(config.c_ip_addr))
- && (strcmp(config.c_ip_addr, "*"))
- && (strcmp(config.c_ip_addr, "::"))
- && (strcmp(config.c_ip_addr, "0.0.0.0"))
- ) {
- curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr);
- }
-
- if (CtdlThreadCheckStop())
- goto shutdown ;
-
- rc = curl_easy_perform(curl);
- if (rc) {
- CtdlLogPrintf(CTDL_ALERT, "libcurl error %d: %s\n", rc, errmsg);
- rc = 0;
- }
- else
- rc = 1;
-
-shutdown:
- curl_easy_cleanup(curl);