http://www.autistici.org/bakunin/libmrss/doc/ sagte mir nicht zu, da:
abhaengig von libnxml es werden erst alle Eintraege gespeichert bevor sie weitergegeben werden Daher meine Loesung: So muesst ihr die lib verwenden:
Zeilennummern
1 #include <stdio.h>
2 #include "feed.h"
3
4 void show_feed ( struct feed_entry * fe, void * userdata)
5 {
6 printf ( ">> title: %s \n " , fe-> title);
7 printf ( ">> link: %s \n " , fe-> link);
8 printf ( ">> published: %s \n " , fe-> published);
9 printf ( ">> updated: %s \n " , fe-> updated);
10 printf ( ">> author: %s \n " , fe-> author);
11 printf ( ">> author_name: %s \n " , fe-> author_name);
12 printf ( ">> author_email: %s \n " , fe-> author_email);
13 printf ( ">> id: %s \n " , fe-> id);
14 printf ( ">> summary: %s \n " , fe-> summary);
15 printf ( ">> userdata: %s \n " , ( char *) userdata);
16
17 printf ( " \n " );
18 feed_free_entry ( fe);
19
20 }
21
22 int main ()
23 {
24 feed_parse ( "http://www.heise.de/newsticker/heise-feed.xml" , show_feed,
25 NULL);
26 printf ( "------------------ \n " );
27 feed_parse ( "http://rss.golem.de/rss.php?feed=ATOM1.0" , show_feed, NULL);
28 printf ( "------RSS--------- \n " );
29 feed_parse ( "http://news.google.
30 de/news?pz=1&cf=all&ned=de&hl=de&topic=h&num=3&output=rss" ,
31 show_feed, NULL);
32 printf ( "------RSS--------- \n " );
33 feed_parse ( "http://rss.golem.de/rss.php?feed=RSS1.0" , show_feed,
34 "userdata" );
35 } feed.h:
Zeilennummern
1 struct feed_entry
2 {
3 char * title;
4 char * link;
5 char * published;
6 char * updated;
7 char * id;
8 char * author;
9 char * author_name;
10 char * author_email;
11 char * summary;
12 };
13
14 extern void feed_parse ( char * url, void * feed_function, void * userdata);
15 extern void feed_free_entry ( struct feed_entry * fe); Nun der eigentliche Kern - feed.c:
Zeilennummern
1 #include <stdio.h>
2 #include <string.h>
3 #include <strings.h>
4 #include <curl/curl.h>
5 #include <libxml/parser.h>
6 #include <libxml/xmlerror.h>
7
8 #include "feed.h"
9
10
11 enum _feed_progress
12 {
13 NONE,
14 FEED_AUTHOR,
15 FEED_TITLE,
16 FEED_ID,
17 FEED_UPDATED,
18 ENTRY_BEGIN,
19 ENTRY,
20 TITLE,
21 LINK,
22 PUBLISHED,
23 UPDATED,
24 ID,
25 AUTHOR_BEGIN,
26 AUTHOR,
27 AUTHOR_NAME,
28 AUTHOR_EMAIL,
29 AUTHOR_END,
30 SUMMARY,
31 ENTRY_END
32 };
33
34 struct _feed_userdata
35 {
36 enum _feed_progress feed_entry_progress;
37 struct feed_entry * feed_entry;
38 void (* feed_function)( void *, void *);
39 void * userdata;
40 };
41
42 char * __join_together ( char * a, char * b, int len_b)
43 {
44 int len = len_b+ 1 ;
45 int len_a = 0 ;
46 int i;
47 char * txt;
48
49 if ( a != NULL)
50 len_a = strlen ( a);
51
52 len += len_a;
53
54 txt = malloc ( sizeof ( char )* len);
55
56 for ( i = 0 ; i < len_a; i++)
57 txt[ i] = a[ i];
58
59 for ( i = 0 ; i < len_b; i++)
60 txt[ i+ len_a] = b[ i];
61
62 txt[ len- 1 ] = '\0' ;
63
64 if ( a != NULL)
65 free ( a);
66
67 return txt;
68 }
69
70
71 char * __extract_attribute ( int nb_attributes, const xmlChar ** attributes,
72 char * attribute, char * a)
73 {
74 for ( int i = 0 ; i < nb_attributes; i++)
75 if (! strcmp (( char *) attributes[ i* 5 ], attribute))
76 return __join_together ( a, ( char *) attributes[( i* 5 )+ 3 ], attributes[( i* 5 )
77 + 4 ] - attributes[( i* 5 )+ 3 ]);
78
79 return NULL;
80 }
81 size_t _chunk_parse ( void * ptr, size_t size, size_t nmemb, void * stream)
82 {
83 char * txt = ptr;
84 xmlParseChunk ( stream, txt, size* nmemb, 0 );
85
86 return nmemb* size;
87 }
88
89
90 int _get_feed ( char * url, void * cbfunction, void * userdata)
91 {
92
93 CURLcode ret;
94 CURL * hnd = curl_easy_init ();
95 curl_easy_setopt ( hnd, CURLOPT_INFILESIZE_LARGE, ( curl_off_t)- 1 );
96 curl_easy_setopt ( hnd, CURLOPT_URL, url);
97 curl_easy_setopt ( hnd, CURLOPT_NOPROGRESS, 1 );
98 curl_easy_setopt ( hnd, CURLOPT_FAILONERROR, 0 );
99 curl_easy_setopt ( hnd, CURLOPT_USERAGENT, "libmessage" );
100 curl_easy_setopt ( hnd, CURLOPT_RESUME_FROM_LARGE, ( curl_off_t) 0 );
101 curl_easy_setopt ( hnd, CURLOPT_MAXREDIRS, 50 );
102 curl_easy_setopt ( hnd, CURLOPT_SSLVERSION, 0 );
103 curl_easy_setopt ( hnd, CURLOPT_TIMECONDITION, 0 );
104 curl_easy_setopt ( hnd, CURLOPT_TIMEVALUE, 0 );
105 curl_easy_setopt ( hnd, CURLOPT_CUSTOMREQUEST, NULL);
106 curl_easy_setopt ( hnd, CURLOPT_CONNECTTIMEOUT, 0 );
107 curl_easy_setopt ( hnd, CURLOPT_HTTPAUTH, 1 );
108 curl_easy_setopt ( hnd, CURLOPT_ENCODING, NULL);
109 curl_easy_setopt ( hnd, CURLOPT_IPRESOLVE, 0 );
110 curl_easy_setopt ( hnd, CURLOPT_IGNORE_CONTENT_LENGTH, 0 );
111 curl_easy_setopt ( hnd, CURLOPT_POSTREDIR, 0 );
112 curl_easy_setopt ( hnd, CURLOPT_WRITEFUNCTION, cbfunction);
113 curl_easy_setopt ( hnd, CURLOPT_WRITEDATA, userdata);
114
115 ret = curl_easy_perform ( hnd);
116 curl_easy_cleanup ( hnd);
117 return ( int ) ret;
118
119 }
120
121 void _feed_charactersSAX ( void * userdata, const xmlChar * characters, int len)
122 {
123 char * ch = ( char *) characters;
124 struct _feed_userdata * fu = userdata;
125
126 #ifdef STRICT
127 if ( fu-> feed_entry_progress != NONE && fu-> feed_entry == NULL)
128 {
129 printf ( "!!fu->feed_entry_progress != NONE && fu->feed_entry ==
130 NULL \n " );
131 exit ( 1 );
132 }
133 #endif
134 /*
135 for (int i = 0; i < len; i++)
136 printf("%c", ch[i]);
137 printf("\n");
138 */
139 if ( fu-> feed_entry_progress == TITLE)
140 fu-> feed_entry-> title = __join_together ( fu-> feed_entry-> title, ch, len);
141 else if ( fu-> feed_entry_progress == PUBLISHED)
142 fu-> feed_entry-> published = __join_together ( fu-> feed_entry-> published,
143 ch, len);
144 else if ( fu-> feed_entry_progress == UPDATED)
145 fu-> feed_entry-> updated = __join_together ( fu-> feed_entry-> updated, ch,
146 len);
147 else if ( fu-> feed_entry_progress == ID)
148 fu-> feed_entry-> id = __join_together ( fu-> feed_entry-> id, ch, len);
149 else if ( fu-> feed_entry_progress == SUMMARY)
150 fu-> feed_entry-> summary = __join_together ( fu-> feed_entry-> summary, ch,
151 len);
152 else if ( fu-> feed_entry_progress == LINK)
153 fu-> feed_entry-> link = __join_together ( fu-> feed_entry-> link, ch, len);
154
155 else if ( fu-> feed_entry_progress == AUTHOR)
156 fu-> feed_entry-> author = __join_together ( fu-> feed_entry-> author, ch,
157 len);
158 else if ( fu-> feed_entry_progress == AUTHOR_NAME)
159 fu-> feed_entry-> author_name = __join_together ( fu-> feed_entry->
160 author_name, ch, len);
161 else if ( fu-> feed_entry_progress == AUTHOR_EMAIL)
162 fu-> feed_entry-> author_email= __join_together ( fu-> feed_entry->
163 author_email, ch, len);
164
165 }
166
167 void _feed_startElementSAX ( void * userdata, const xmlChar * characters,
168 const xmlChar * prefix,
169 const xmlChar * URI,
170 int nb_namespaces,
171 const xmlChar ** namespaces,
172 int nb_attributes,
173 int nb_defaulted,
174 const xmlChar ** attributes )
175 {
176 char * ch = ( char *) characters;
177 struct _feed_userdata * fu = userdata;
178
179 // printf("-------------<%s>---------------\n", ch);
180
181 if (! strncasecmp ( ch, "entry" , 6 ) || ! strncasecmp ( ch, "item" , 5 ))
182 {
183 fu-> feed_entry = malloc ( sizeof ( struct feed_entry));
184 memset ( fu-> feed_entry, 0 , sizeof ( struct feed_entry));
185 fu-> feed_entry_progress = ENTRY;
186 }
187
188 if ( fu-> feed_entry_progress < ENTRY_END && fu-> feed_entry_progress >
189 ENTRY_BEGIN)
190 {
191 if (! strncasecmp ( ch, "title" , 6 ))
192 fu-> feed_entry_progress = TITLE;
193 else if (! strncasecmp ( ch, "link" , 5 ))
194 {
195 fu-> feed_entry_progress = LINK;
196 fu-> feed_entry-> link = __extract_attribute ( nb_attributes,
197 attributes, "href" , fu-> feed_entry-> link);
198 }
199 else if (! strncasecmp ( ch, "published" , 10 ))
200 fu-> feed_entry_progress = PUBLISHED;
201 else if (! strncasecmp ( ch, "updated" , 8 ))
202 fu-> feed_entry_progress = UPDATED;
203 else if (! strncasecmp ( ch, "id" , 3 ))
204 fu-> feed_entry_progress = ID;
205 else if (! strncasecmp ( ch, "author" , 7 ))
206 fu-> feed_entry_progress = AUTHOR;
207 else if (! strncasecmp ( ch, "summary" , 8 ) || ! strncasecmp ( ch,
208 "description" , 12 ))
209 fu-> feed_entry_progress = SUMMARY;
210
211 if ( fu-> feed_entry_progress < AUTHOR_END && fu-> feed_entry_progress >
212 AUTHOR_BEGIN)
213 {
214 if (! strncasecmp ( ch, "name" , 5 ))
215 {
216 fu-> feed_entry_progress = AUTHOR_NAME;
217 if ( fu-> feed_entry-> author != NULL)
218 {
219 free ( fu-> feed_entry-> author);
220 fu-> feed_entry-> author = NULL;
221 }
222
223 }
224 if (! strncasecmp ( ch, "email" , 6 ))
225 {
226 fu-> feed_entry_progress = AUTHOR_EMAIL;
227 if ( fu-> feed_entry-> author != NULL)
228 {
229 free ( fu-> feed_entry-> author);
230 fu-> feed_entry-> author = NULL;
231 }
232 }
233 }
234 }
235
236 }
237 void _feed_endElementSAX ( void * userdata, const xmlChar * characters,
238 const xmlChar * prefix,
239 const xmlChar * URI )
240 {
241 char * ch = ( char *) characters;
242 struct _feed_userdata * fu = userdata;
243
244
245 if (! strncasecmp ( ch, "entry" , 6 ) || ! strncasecmp ( ch, "item" , 5 ))
246 {
247 fu-> feed_function ( fu-> feed_entry, fu-> userdata);
248 fu-> feed_entry_progress = ENTRY_END;
249 }
250 else if (! strncasecmp ( ch, "author" , 7 ))
251 fu-> feed_entry_progress = AUTHOR_END;
252
253
254 if ( fu-> feed_entry_progress < ENTRY_END && fu-> feed_entry_progress >
255 ENTRY_BEGIN)
256 fu-> feed_entry_progress = ENTRY;
257 if ( fu-> feed_entry_progress < AUTHOR_END && fu-> feed_entry_progress >
258 AUTHOR_BEGIN)
259 fu-> feed_entry_progress = AUTHOR_BEGIN;
260 }
261
262
263 void _init_parser ( char * url, void * feed_function, void * userdata)
264 {
265 struct _feed_userdata fu;
266 xmlParserCtxtPtr ctxt;
267 xmlSAXHandler xsh;
268 memset (& xsh, 0 , sizeof ( xmlSAXHandler));
269
270 fu. feed_entry_progress = NONE;
271 fu. feed_entry = NULL;
272 fu. feed_function = feed_function;
273 fu. userdata = userdata;
274
275 xsh. initialized = XML_SAX2_MAGIC;
276 xsh. characters = _feed_charactersSAX;
277 xsh. startElementNs = _feed_startElementSAX;
278 xsh. endElementNs = _feed_endElementSAX;
279
280 ctxt = xmlCreatePushParserCtxt (& xsh, & fu, NULL, 0 , NULL);
281
282 _get_feed ( url, _chunk_parse, ctxt);
283
284 xmlParseChunk ( ctxt, "" , 0 , 1 );
285
286 xmlFreeParserCtxt ( ctxt);
287 }
288
289 extern void feed_parse ( char * url, void * feed_function, void * userdata)
290 {
291 _init_parser ( url, feed_function, userdata);
292 }
293
294 static inline void feed_free_ifyoucan ( void * p)
295 {
296 if ( p != NULL)
297 free ( p);
298 }
299
300 extern void feed_free_entry ( struct feed_entry * fe)
301 {
302 //printf("title\n");
303 feed_free_ifyoucan ( fe-> title);
304 //printf("link\n");
305 feed_free_ifyoucan ( fe-> link);
306 //printf("published\n");
307 feed_free_ifyoucan ( fe-> published);
308 //printf("updated\n");
309 feed_free_ifyoucan ( fe-> updated);
310 //printf("id\n");
311 feed_free_ifyoucan ( fe-> id);
312 //printf("author\n");
313 feed_free_ifyoucan ( fe-> author);
314 //printf("author_name\n");
315 feed_free_ifyoucan ( fe-> author_name);
316 //printf("author_email\n");
317 feed_free_ifyoucan ( fe-> author_email);
318 //printf("summary\n");
319 feed_free_ifyoucan ( fe-> summary);
320
321 feed_free_ifyoucan ( fe);
322 } und hier noch das Makefile:
CC=/usr/bin/gcc
CFLAGS=-O2 -g -Wall
all: feedtest
feed.o: feed.c
$(CC) $(CFLAGS) -o feed.o -Wall -std=c99 -fPIC feed.c -I /usr/include/libxml2/ -c
feedtest: feed.o feedtest.c
$(CC) $(CFLAGS) -std=c99 -lxml2 -lcurl -o feedtest feedtest.c feed.o
clean:
rm -f feedtest feed.o