diff options
author | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
commit | 07274513e984f0b5544586c74508ccd16e7dcafa (patch) | |
tree | b32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/ecore/src/lib/ecore_file/ecore_file_download.c | |
parent | Added Irrlicht 1.8, but without all the Windows binaries. (diff) | |
download | SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.zip SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.gz SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.bz2 SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.xz |
Remove EFL, since it's been released now.
Diffstat (limited to 'libraries/ecore/src/lib/ecore_file/ecore_file_download.c')
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_download.c | 449 |
1 files changed, 0 insertions, 449 deletions
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_download.c b/libraries/ecore/src/lib/ecore_file/ecore_file_download.c deleted file mode 100644 index 971493e..0000000 --- a/libraries/ecore/src/lib/ecore_file/ecore_file_download.c +++ /dev/null | |||
@@ -1,449 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <stdio.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #ifdef BUILD_ECORE_CON | ||
10 | # include "Ecore_Con.h" | ||
11 | #endif | ||
12 | |||
13 | #include "ecore_file_private.h" | ||
14 | |||
15 | #ifdef BUILD_ECORE_CON | ||
16 | |||
17 | #define ECORE_MAGIC_FILE_DOWNLOAD_JOB 0xf7427cb8 | ||
18 | #define ECORE_FILE_DOWNLOAD_TIMEOUT 30 | ||
19 | |||
20 | struct _Ecore_File_Download_Job | ||
21 | { | ||
22 | ECORE_MAGIC; | ||
23 | |||
24 | Ecore_Con_Url *url_con; | ||
25 | FILE *file; | ||
26 | |||
27 | char *dst; | ||
28 | |||
29 | Ecore_File_Download_Completion_Cb completion_cb; | ||
30 | Ecore_File_Download_Progress_Cb progress_cb; | ||
31 | }; | ||
32 | |||
33 | #ifdef HAVE_CURL | ||
34 | Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst, | ||
35 | Ecore_File_Download_Completion_Cb completion_cb, | ||
36 | Ecore_File_Download_Progress_Cb progress_cb, | ||
37 | void *data, | ||
38 | Eina_Hash *headers); | ||
39 | |||
40 | static Eina_Bool _ecore_file_download_url_complete_cb(void *data, int type, void *event); | ||
41 | static Eina_Bool _ecore_file_download_url_progress_cb(void *data, int type, void *event); | ||
42 | #endif | ||
43 | |||
44 | static Ecore_Event_Handler *_url_complete_handler = NULL; | ||
45 | static Ecore_Event_Handler *_url_progress_download = NULL; | ||
46 | static Eina_List *_job_list; | ||
47 | |||
48 | static int download_init = 0; | ||
49 | |||
50 | #endif /* BUILD_ECORE_CON */ | ||
51 | |||
52 | int | ||
53 | ecore_file_download_init(void) | ||
54 | { | ||
55 | #ifdef BUILD_ECORE_CON | ||
56 | download_init++; | ||
57 | if (download_init > 1) return 1; | ||
58 | if (!ecore_con_init()) return 0; | ||
59 | if (!ecore_con_url_init()) | ||
60 | { | ||
61 | ecore_con_shutdown(); | ||
62 | return 0; | ||
63 | } | ||
64 | # ifdef HAVE_CURL | ||
65 | _url_complete_handler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _ecore_file_download_url_complete_cb, NULL); | ||
66 | _url_progress_download = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _ecore_file_download_url_progress_cb, NULL); | ||
67 | # endif | ||
68 | #endif /* BUILD_ECORE_CON */ | ||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | void | ||
73 | ecore_file_download_shutdown(void) | ||
74 | { | ||
75 | #ifdef BUILD_ECORE_CON | ||
76 | download_init--; | ||
77 | if (download_init > 0) return; | ||
78 | if (_url_complete_handler) | ||
79 | ecore_event_handler_del(_url_complete_handler); | ||
80 | if (_url_progress_download) | ||
81 | ecore_event_handler_del(_url_progress_download); | ||
82 | _url_complete_handler = NULL; | ||
83 | _url_progress_download = NULL; | ||
84 | ecore_file_download_abort_all(); | ||
85 | ecore_con_url_shutdown(); | ||
86 | ecore_con_shutdown(); | ||
87 | #endif /* BUILD_ECORE_CON */ | ||
88 | } | ||
89 | |||
90 | #ifdef BUILD_ECORE_CON | ||
91 | # ifdef HAVE_CURL | ||
92 | static Eina_Bool | ||
93 | _ecore_file_download_headers_foreach_cb(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata) | ||
94 | { | ||
95 | Ecore_File_Download_Job *job = fdata; | ||
96 | ecore_con_url_additional_header_add(job->url_con, key, data); | ||
97 | |||
98 | return EINA_TRUE; | ||
99 | } | ||
100 | # endif | ||
101 | #endif | ||
102 | |||
103 | static Eina_Bool | ||
104 | _ecore_file_download(const char *url, | ||
105 | const char *dst, | ||
106 | Ecore_File_Download_Completion_Cb completion_cb, | ||
107 | Ecore_File_Download_Progress_Cb progress_cb, | ||
108 | void *data, | ||
109 | Ecore_File_Download_Job **job_ret, | ||
110 | Eina_Hash *headers) | ||
111 | { | ||
112 | #ifdef BUILD_ECORE_CON | ||
113 | char *dir = ecore_file_dir_get(dst); | ||
114 | |||
115 | if (!ecore_file_is_dir(dir)) | ||
116 | { | ||
117 | ERR("%s is not a directory", dir); | ||
118 | free(dir); | ||
119 | return EINA_FALSE; | ||
120 | } | ||
121 | free(dir); | ||
122 | if (ecore_file_exists(dst)) | ||
123 | { | ||
124 | WRN("%s already exists", dst); | ||
125 | return EINA_FALSE; | ||
126 | } | ||
127 | |||
128 | if (!strncmp(url, "file://", 7)) | ||
129 | { | ||
130 | /* FIXME: Maybe fork? Might take a while to copy. | ||
131 | * Check filesize? */ | ||
132 | /* Just copy it */ | ||
133 | |||
134 | url += 7; | ||
135 | /* skip hostname */ | ||
136 | url = strchr(url, '/'); | ||
137 | return ecore_file_cp(url, dst); | ||
138 | } | ||
139 | # ifdef HAVE_CURL | ||
140 | else if ((!strncmp(url, "http://", 7)) || (!strncmp(url, "https://", 8)) || | ||
141 | (!strncmp(url, "ftp://", 6))) | ||
142 | { | ||
143 | /* download */ | ||
144 | Ecore_File_Download_Job *job; | ||
145 | |||
146 | job = _ecore_file_download_curl(url, dst, completion_cb, progress_cb, data, headers); | ||
147 | if(job_ret) *job_ret = job; | ||
148 | if(job) | ||
149 | return EINA_TRUE; | ||
150 | else | ||
151 | { | ||
152 | ERR("no job returned\n"); | ||
153 | return EINA_FALSE; | ||
154 | } | ||
155 | return job ? EINA_TRUE : EINA_FALSE; | ||
156 | } | ||
157 | # else | ||
158 | else if ((!strncmp(url, "http://", 7)) || (!strncmp(url, "https://", 8)) || | ||
159 | (!strncmp(url, "ftp://", 6))) | ||
160 | { | ||
161 | (void)completion_cb; | ||
162 | (void)progress_cb; | ||
163 | (void)data; | ||
164 | (void)job_ret; | ||
165 | (void)headers; | ||
166 | return EINA_FALSE; | ||
167 | } | ||
168 | # endif | ||
169 | else | ||
170 | { | ||
171 | return EINA_FALSE; | ||
172 | } | ||
173 | #else | ||
174 | (void)url; | ||
175 | (void)dst; | ||
176 | (void)completion_cb; | ||
177 | (void)progress_cb; | ||
178 | (void)data; | ||
179 | (void)job_ret; | ||
180 | (void)headers; | ||
181 | return EINA_FALSE; | ||
182 | #endif /* BUILD_ECORE_CON */ | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions | ||
187 | * | ||
188 | * @{ | ||
189 | */ | ||
190 | |||
191 | /** | ||
192 | * @brief Download the given url to the given destination. | ||
193 | * | ||
194 | * @param url The complete url to download. | ||
195 | * @param dst The local file to save the downloaded to. | ||
196 | * @param completion_cb A callback called on download complete. | ||
197 | * @param progress_cb A callback called during the download operation. | ||
198 | * @param data User data passed to both callbacks. | ||
199 | * @param job_ret Job used to abort the download. | ||
200 | * @return EINA_TRUE if the download start or EINA_FALSE on failure | ||
201 | * | ||
202 | * This function starts the download of the URL @p url and saves it to | ||
203 | * @p dst. @p url must provide the protocol, including 'http://', | ||
204 | * 'ftp://' or 'file://'. Ecore_File must be compiled with CURL to | ||
205 | * download using http and ftp protocols. If @p dst is ill-formed, or | ||
206 | * if it already exists, the function returns EINA_FALSE. When the | ||
207 | * download is complete, the callback @p completion_cb is called and | ||
208 | * @p data is passed to it. The @p status parameter of @p completion_cb | ||
209 | * will be filled with the status of the download (200, 404,...). The | ||
210 | * @p progress_cb is called during the download operation, each time a | ||
211 | * packet is received or when CURL wants. It can be used to display the | ||
212 | * percentage of the downloaded file. Return 0 from this callback, if provided, | ||
213 | * to continue the operation or anything else to abort the download. The only | ||
214 | * operations that can be aborted are those with protocol 'http' or 'ftp'. In | ||
215 | * that case @p job_ret can be filled. It can be used with | ||
216 | * ecore_file_download_abort() or ecore_file_download_abort_all() to | ||
217 | * respectively abort one or all download operations. This function returns | ||
218 | * EINA_TRUE if the download starts, EINA_FALSE otherwise. | ||
219 | */ | ||
220 | EAPI Eina_Bool | ||
221 | ecore_file_download(const char *url, | ||
222 | const char *dst, | ||
223 | Ecore_File_Download_Completion_Cb completion_cb, | ||
224 | Ecore_File_Download_Progress_Cb progress_cb, | ||
225 | void *data, | ||
226 | Ecore_File_Download_Job **job_ret) | ||
227 | { | ||
228 | return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, NULL); | ||
229 | } | ||
230 | |||
231 | /** | ||
232 | * @brief Download the given url to the given destination with additional headers. | ||
233 | * | ||
234 | * @param url The complete url to download. | ||
235 | * @param dst The local file to save the downloaded to. | ||
236 | * @param completion_cb A callback called on download complete. | ||
237 | * @param progress_cb A callback called during the download operation. | ||
238 | * @param data User data passed to both callbacks. | ||
239 | * @param job_ret Job used to abort the download. | ||
240 | * @param headers pointer of header lists. | ||
241 | * @return EINA_TRUE if the download start or EINA_FALSE on failure | ||
242 | */ | ||
243 | EAPI Eina_Bool | ||
244 | ecore_file_download_full(const char *url, | ||
245 | const char *dst, | ||
246 | Ecore_File_Download_Completion_Cb completion_cb, | ||
247 | Ecore_File_Download_Progress_Cb progress_cb, | ||
248 | void *data, | ||
249 | Ecore_File_Download_Job **job_ret, | ||
250 | Eina_Hash *headers) | ||
251 | { | ||
252 | return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, headers); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * @brief Check if the given protocol is available. | ||
257 | * | ||
258 | * @param protocol The protocol to check. | ||
259 | * @return EINA_TRUE if protocol is handled, EINA_FALSE otherwise. | ||
260 | * | ||
261 | * This function returns EINA_TRUE if @p protocol is supported, | ||
262 | * EINA_FALSE otherwise. @p protocol can be 'http://', 'ftp://' or | ||
263 | * 'file://'. Ecore_FILE must be compiled with CURL to handle http and | ||
264 | * ftp protocols. | ||
265 | */ | ||
266 | EAPI Eina_Bool | ||
267 | ecore_file_download_protocol_available(const char *protocol) | ||
268 | { | ||
269 | #ifdef BUILD_ECORE_CON | ||
270 | if (!strncmp(protocol, "file://", 7)) return EINA_TRUE; | ||
271 | # ifdef HAVE_CURL | ||
272 | else if (!strncmp(protocol, "http://", 7)) return EINA_TRUE; | ||
273 | else if (!strncmp(protocol, "ftp://", 6)) return EINA_TRUE; | ||
274 | # endif | ||
275 | #else | ||
276 | (void)protocol; | ||
277 | #endif /* BUILD_ECORE_CON */ | ||
278 | |||
279 | return EINA_FALSE; | ||
280 | } | ||
281 | |||
282 | #ifdef BUILD_ECORE_CON | ||
283 | |||
284 | # ifdef HAVE_CURL | ||
285 | static int | ||
286 | _ecore_file_download_url_compare_job(const void *data1, const void *data2) | ||
287 | { | ||
288 | const Ecore_File_Download_Job *job = data1; | ||
289 | const Ecore_Con_Url *url = data2; | ||
290 | |||
291 | if (job->url_con == url) return 0; | ||
292 | return -1; | ||
293 | } | ||
294 | |||
295 | static Eina_Bool | ||
296 | _ecore_file_download_url_complete_cb(void *data __UNUSED__, int type __UNUSED__, void *event) | ||
297 | { | ||
298 | Ecore_Con_Event_Url_Complete *ev = event; | ||
299 | Ecore_File_Download_Job *job; | ||
300 | |||
301 | job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con); | ||
302 | if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return ECORE_CALLBACK_PASS_ON; | ||
303 | |||
304 | fclose(job->file); | ||
305 | if (job->completion_cb) | ||
306 | job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, ev->status); | ||
307 | |||
308 | _job_list = eina_list_remove(_job_list, job); | ||
309 | free(job->dst); | ||
310 | ecore_con_url_free(job->url_con); | ||
311 | free(job); | ||
312 | |||
313 | return ECORE_CALLBACK_DONE; | ||
314 | } | ||
315 | |||
316 | static Eina_Bool | ||
317 | _ecore_file_download_url_progress_cb(void *data __UNUSED__, int type __UNUSED__, void *event) | ||
318 | { | ||
319 | /* this reports the downloads progress. if we return 0, then download | ||
320 | * continues, if we return anything else, then the download stops */ | ||
321 | Ecore_Con_Event_Url_Progress *ev = event; | ||
322 | Ecore_File_Download_Job *job; | ||
323 | |||
324 | job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con); | ||
325 | if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return ECORE_CALLBACK_PASS_ON; | ||
326 | |||
327 | if (job->progress_cb) | ||
328 | if (job->progress_cb(ecore_con_url_data_get(job->url_con), job->dst, | ||
329 | (long int) ev->down.total, (long int) ev->down.now, | ||
330 | (long int) ev->up.total, (long int) ev->up.now) != 0) | ||
331 | { | ||
332 | _job_list = eina_list_remove(_job_list, job); | ||
333 | fclose(job->file); | ||
334 | free(job->dst); | ||
335 | free(job); | ||
336 | |||
337 | return ECORE_CALLBACK_PASS_ON; | ||
338 | } | ||
339 | |||
340 | return ECORE_CALLBACK_DONE; | ||
341 | } | ||
342 | |||
343 | Ecore_File_Download_Job * | ||
344 | _ecore_file_download_curl(const char *url, const char *dst, | ||
345 | Ecore_File_Download_Completion_Cb completion_cb, | ||
346 | Ecore_File_Download_Progress_Cb progress_cb, | ||
347 | void *data, | ||
348 | Eina_Hash *headers) | ||
349 | { | ||
350 | Ecore_File_Download_Job *job; | ||
351 | |||
352 | job = calloc(1, sizeof(Ecore_File_Download_Job)); | ||
353 | if (!job) return NULL; | ||
354 | |||
355 | ECORE_MAGIC_SET(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB); | ||
356 | |||
357 | job->file = fopen(dst, "wb"); | ||
358 | if (!job->file) | ||
359 | { | ||
360 | free(job); | ||
361 | return NULL; | ||
362 | } | ||
363 | job->url_con = ecore_con_url_new(url); | ||
364 | if (!job->url_con) | ||
365 | { | ||
366 | fclose(job->file); | ||
367 | free(job); | ||
368 | return NULL; | ||
369 | } | ||
370 | |||
371 | if (headers) eina_hash_foreach(headers, _ecore_file_download_headers_foreach_cb, job); | ||
372 | ecore_con_url_fd_set(job->url_con, fileno(job->file)); | ||
373 | ecore_con_url_data_set(job->url_con, data); | ||
374 | |||
375 | job->dst = strdup(dst); | ||
376 | |||
377 | job->completion_cb = completion_cb; | ||
378 | job->progress_cb = progress_cb; | ||
379 | _job_list = eina_list_append(_job_list, job); | ||
380 | |||
381 | if (!ecore_con_url_get(job->url_con)) | ||
382 | { | ||
383 | ecore_con_url_free(job->url_con); | ||
384 | _job_list = eina_list_remove(_job_list, job); | ||
385 | fclose(job->file); | ||
386 | ecore_file_remove(job->dst); | ||
387 | free(job->dst); | ||
388 | free(job); | ||
389 | return NULL; | ||
390 | } | ||
391 | |||
392 | return job; | ||
393 | } | ||
394 | # endif | ||
395 | #endif | ||
396 | |||
397 | /** | ||
398 | * @brief Abort the given download job and call the completion_cb | ||
399 | * callbck with a status of 1 (error). | ||
400 | * | ||
401 | * @param job The download job to abort. | ||
402 | * | ||
403 | * This function aborts a download operation started by | ||
404 | * ecore_file_download(). @p job is the #Ecore_File_Download_Job | ||
405 | * structure filled by ecore_file_download(). If it is @c NULL, this | ||
406 | * function does nothing. To abort all the currently downloading | ||
407 | * operations, call ecore_file_download_abort_all(). | ||
408 | */ | ||
409 | EAPI void | ||
410 | ecore_file_download_abort(Ecore_File_Download_Job *job) | ||
411 | { | ||
412 | if (!job) | ||
413 | return; | ||
414 | |||
415 | #ifdef BUILD_ECORE_CON | ||
416 | if (job->completion_cb) | ||
417 | job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, 1); | ||
418 | # ifdef HAVE_CURL | ||
419 | ecore_con_url_free(job->url_con); | ||
420 | # endif | ||
421 | _job_list = eina_list_remove(_job_list, job); | ||
422 | fclose(job->file); | ||
423 | free(job->dst); | ||
424 | free(job); | ||
425 | #endif /* BUILD_ECORE_CON */ | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * @brief Abort all downloads. | ||
430 | * | ||
431 | * This function aborts all the downloads that have been started by | ||
432 | * ecore_file_download(). It loops over the started downloads and call | ||
433 | * ecore_file_download_abort() for each of them. To abort only one | ||
434 | * specific download operation, call ecore_file_download_abort(). | ||
435 | */ | ||
436 | EAPI void | ||
437 | ecore_file_download_abort_all(void) | ||
438 | { | ||
439 | #ifdef BUILD_ECORE_CON | ||
440 | Ecore_File_Download_Job *job; | ||
441 | |||
442 | EINA_LIST_FREE(_job_list, job) | ||
443 | ecore_file_download_abort(job); | ||
444 | #endif /* BUILD_ECORE_CON */ | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * @} | ||
449 | */ | ||