static void _enclosure_iterator(const void *user_data, int i, const xmlNode *node) { const char *downloadtime; channel *c = (channel *)user_data; downloadtime = libxmlutil_attr_as_string(node, "downloadtime"); if (downloadtime) downloadtime = g_strdup(downloadtime); else downloadtime = get_rfc822_time(); g_hash_table_insert(c->downloaded_enclosures, (gpointer)libxmlutil_attr_as_string(node, "url"), (gpointer)downloadtime); }
static rss_file *rss_parse(const gchar *url, const xmlNode *root_element, gchar *fetched_time) { const char *version_string; const xmlNode *channel; rss_file *f; enum rss_version version; /* Do some sanity checking and extract the RSS version number. */ if (strcmp((char *)root_element->name, "rss")) { fprintf(stderr, "Error parsing RSS file %s: Unrecognized top-level element %s.\n", url, (char *)root_element->name); return NULL; } version_string = libxmlutil_attr_as_string(root_element, "version"); if (!strcmp(version_string, "2.0")) { version = RSS_VERSION_2_0; } else if (!strcmp(version_string, "0.91")) { version = RSS_VERSION_0_91; } else if (!strcmp(version_string, "0.92")) { version = RSS_VERSION_0_92; } else { version = RSS_UNKNOWN; } /* Find the channel tag and parse it. */ channel = libxmlutil_child_node_by_name(root_element, NULL, "channel"); if (channel) { /* Allocate RSS file structure and room for pointers to all entries. */ f = (rss_file *)malloc(sizeof(struct _rss_file)); f->fetched_time = g_strdup(fetched_time); f->num_items = libxmlutil_count_by_tag_name(channel, "item"); f->items = (rss_item **)malloc(sizeof(rss_item *) * f->num_items); f->version = version; /* Copy channel meta-information. */ f->channel_info.title = _dup_child_node_value(channel, "title"); f->channel_info.link = _dup_child_node_value(channel, "link"); f->channel_info.description = _dup_child_node_value(channel, "description"); f->channel_info.language = _dup_child_node_value(channel, "language"); libxmlutil_iterate_by_tag_name(channel, "item", f, _item_iterator); } else f = NULL; return f; }
channel *channel_new(const char *url, const char *channel_file, const char *spool_directory, const char *filename_pattern, int resume) { channel *c; xmlDocPtr doc; xmlNode *root_element = NULL; const char *s; c = (channel *)malloc(sizeof(struct _channel)); c->url = g_strdup(url); c->channel_filename = g_strdup(channel_file); c->spool_directory = g_strdup(spool_directory); c->filename_pattern = g_strdup(filename_pattern); // c->resume = resume; c->rss_last_fetched = NULL; c->downloaded_enclosures = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); if (g_file_test(c->channel_filename, G_FILE_TEST_EXISTS)) { doc = xmlReadFile(c->channel_filename, NULL, 0); if (!doc) { g_fprintf(stderr, "Error parsing channel file %s.\n", c->channel_filename); return NULL; } root_element = xmlDocGetRootElement(doc); if (!root_element) { xmlFreeDoc(doc); g_fprintf(stderr, "Error parsing channel file %s.\n", c->channel_filename); return NULL; } /* Fetch channel attributes. */ s = libxmlutil_attr_as_string(root_element, "rsslastfetched"); if (s) c->rss_last_fetched = g_strdup(s); /* Iterate encolsure elements. */ libxmlutil_iterate_by_tag_name(root_element, "enclosure", c, _enclosure_iterator); xmlFreeDoc(doc); } return c; }