diff options
Diffstat (limited to 'src/fs/fs_dirmetascan.c')
-rw-r--r-- | src/fs/fs_dirmetascan.c | 217 |
1 files changed, 107 insertions, 110 deletions
diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c index 115f99391..dd207e2c9 100644 --- a/src/fs/fs_dirmetascan.c +++ b/src/fs/fs_dirmetascan.c | |||
@@ -80,13 +80,12 @@ struct GNUNET_FS_DirScanner | |||
80 | /** | 80 | /** |
81 | * Task scheduled when we are done. | 81 | * Task scheduled when we are done. |
82 | */ | 82 | */ |
83 | struct GNUNET_SCHEDULER_Task * stop_task; | 83 | struct GNUNET_SCHEDULER_Task *stop_task; |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * Arguments for helper. | 86 | * Arguments for helper. |
87 | */ | 87 | */ |
88 | char *args[4]; | 88 | char *args[4]; |
89 | |||
90 | }; | 89 | }; |
91 | 90 | ||
92 | 91 | ||
@@ -151,11 +150,9 @@ advance (struct GNUNET_FS_ShareTreeItem *pos) | |||
151 | 150 | ||
152 | GNUNET_assert (NULL != pos); | 151 | GNUNET_assert (NULL != pos); |
153 | moved = 0; /* must not terminate, even on file, otherwise "normal" */ | 152 | moved = 0; /* must not terminate, even on file, otherwise "normal" */ |
154 | while ( (pos->is_directory == GNUNET_YES) || | 153 | while ((pos->is_directory == GNUNET_YES) || (0 == moved)) |
155 | (0 == moved) ) | ||
156 | { | 154 | { |
157 | if ( (moved != -1) && | 155 | if ((moved != -1) && (NULL != pos->children_head)) |
158 | (NULL != pos->children_head) ) | ||
159 | { | 156 | { |
160 | pos = pos->children_head; | 157 | pos = pos->children_head; |
161 | moved = 1; /* can terminate if file */ | 158 | moved = 1; /* can terminate if file */ |
@@ -190,8 +187,8 @@ advance (struct GNUNET_FS_ShareTreeItem *pos) | |||
190 | */ | 187 | */ |
191 | static struct GNUNET_FS_ShareTreeItem * | 188 | static struct GNUNET_FS_ShareTreeItem * |
192 | expand_tree (struct GNUNET_FS_ShareTreeItem *parent, | 189 | expand_tree (struct GNUNET_FS_ShareTreeItem *parent, |
193 | const char *filename, | 190 | const char *filename, |
194 | int is_directory) | 191 | int is_directory) |
195 | { | 192 | { |
196 | struct GNUNET_FS_ShareTreeItem *chld; | 193 | struct GNUNET_FS_ShareTreeItem *chld; |
197 | size_t slen; | 194 | size_t slen; |
@@ -200,20 +197,19 @@ expand_tree (struct GNUNET_FS_ShareTreeItem *parent, | |||
200 | chld->parent = parent; | 197 | chld->parent = parent; |
201 | chld->filename = GNUNET_strdup (filename); | 198 | chld->filename = GNUNET_strdup (filename); |
202 | GNUNET_asprintf (&chld->short_filename, | 199 | GNUNET_asprintf (&chld->short_filename, |
203 | "%s%s", | 200 | "%s%s", |
204 | GNUNET_STRINGS_get_short_name (filename), | 201 | GNUNET_STRINGS_get_short_name (filename), |
205 | is_directory == GNUNET_YES ? "/" : ""); | 202 | is_directory == GNUNET_YES ? "/" : ""); |
206 | /* make sure we do not end with '//' */ | 203 | /* make sure we do not end with '//' */ |
207 | slen = strlen (chld->short_filename); | 204 | slen = strlen (chld->short_filename); |
208 | if ( (slen >= 2) && | 205 | if ((slen >= 2) && (chld->short_filename[slen - 1] == '/') && |
209 | (chld->short_filename[slen-1] == '/') && | 206 | (chld->short_filename[slen - 2] == '/')) |
210 | (chld->short_filename[slen-2] == '/') ) | 207 | chld->short_filename[slen - 1] = '\0'; |
211 | chld->short_filename[slen-1] = '\0'; | ||
212 | chld->is_directory = is_directory; | 208 | chld->is_directory = is_directory; |
213 | if (NULL != parent) | 209 | if (NULL != parent) |
214 | GNUNET_CONTAINER_DLL_insert (parent->children_head, | 210 | GNUNET_CONTAINER_DLL_insert (parent->children_head, |
215 | parent->children_tail, | 211 | parent->children_tail, |
216 | chld); | 212 | chld); |
217 | return chld; | 213 | return chld; |
218 | } | 214 | } |
219 | 215 | ||
@@ -235,8 +231,9 @@ finish_scan (void *cls) | |||
235 | ds->helper = NULL; | 231 | ds->helper = NULL; |
236 | } | 232 | } |
237 | ds->progress_callback (ds->progress_callback_cls, | 233 | ds->progress_callback (ds->progress_callback_cls, |
238 | NULL, GNUNET_SYSERR, | 234 | NULL, |
239 | GNUNET_FS_DIRSCANNER_FINISHED); | 235 | GNUNET_SYSERR, |
236 | GNUNET_FS_DIRSCANNER_FINISHED); | ||
240 | } | 237 | } |
241 | 238 | ||
242 | 239 | ||
@@ -251,8 +248,7 @@ finish_scan (void *cls) | |||
251 | * #GNUNET_SYSERR to stop further processing with error | 248 | * #GNUNET_SYSERR to stop further processing with error |
252 | */ | 249 | */ |
253 | static int | 250 | static int |
254 | process_helper_msgs (void *cls, | 251 | process_helper_msgs (void *cls, const struct GNUNET_MessageHeader *msg) |
255 | const struct GNUNET_MessageHeader *msg) | ||
256 | { | 252 | { |
257 | struct GNUNET_FS_DirScanner *ds = cls; | 253 | struct GNUNET_FS_DirScanner *ds = cls; |
258 | const char *filename; | 254 | const char *filename; |
@@ -265,34 +261,31 @@ process_helper_msgs (void *cls, | |||
265 | (unsigned int) ntohs (msg->type)); | 261 | (unsigned int) ntohs (msg->type)); |
266 | #endif | 262 | #endif |
267 | left = ntohs (msg->size) - sizeof (struct GNUNET_MessageHeader); | 263 | left = ntohs (msg->size) - sizeof (struct GNUNET_MessageHeader); |
268 | filename = (const char*) &msg[1]; | 264 | filename = (const char *) &msg[1]; |
269 | switch (ntohs (msg->type)) | 265 | switch (ntohs (msg->type)) |
270 | { | 266 | { |
271 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_FILE: | 267 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_FILE: |
272 | if (filename[left-1] != '\0') | 268 | if (filename[left - 1] != '\0') |
273 | { | 269 | { |
274 | GNUNET_break (0); | 270 | GNUNET_break (0); |
275 | break; | 271 | break; |
276 | } | 272 | } |
277 | ds->progress_callback (ds->progress_callback_cls, | 273 | ds->progress_callback (ds->progress_callback_cls, |
278 | filename, GNUNET_NO, | 274 | filename, |
279 | GNUNET_FS_DIRSCANNER_FILE_START); | 275 | GNUNET_NO, |
276 | GNUNET_FS_DIRSCANNER_FILE_START); | ||
280 | if (NULL == ds->toplevel) | 277 | if (NULL == ds->toplevel) |
281 | { | 278 | { |
282 | ds->toplevel = expand_tree (ds->pos, | 279 | ds->toplevel = expand_tree (ds->pos, filename, GNUNET_NO); |
283 | filename, | ||
284 | GNUNET_NO); | ||
285 | } | 280 | } |
286 | else | 281 | else |
287 | { | 282 | { |
288 | GNUNET_assert (NULL != ds->pos); | 283 | GNUNET_assert (NULL != ds->pos); |
289 | (void) expand_tree (ds->pos, | 284 | (void) expand_tree (ds->pos, filename, GNUNET_NO); |
290 | filename, | ||
291 | GNUNET_NO); | ||
292 | } | 285 | } |
293 | return GNUNET_OK; | 286 | return GNUNET_OK; |
294 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY: | 287 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY: |
295 | if (filename[left-1] != '\0') | 288 | if (filename[left - 1] != '\0') |
296 | { | 289 | { |
297 | GNUNET_break (0); | 290 | GNUNET_break (0); |
298 | break; | 291 | break; |
@@ -301,29 +294,29 @@ process_helper_msgs (void *cls, | |||
301 | { | 294 | { |
302 | if (NULL == ds->pos) | 295 | if (NULL == ds->pos) |
303 | { | 296 | { |
304 | GNUNET_break (0); | 297 | GNUNET_break (0); |
305 | break; | 298 | break; |
306 | } | 299 | } |
307 | ds->pos = ds->pos->parent; | 300 | ds->pos = ds->pos->parent; |
308 | return GNUNET_OK; | 301 | return GNUNET_OK; |
309 | } | 302 | } |
310 | ds->progress_callback (ds->progress_callback_cls, | 303 | ds->progress_callback (ds->progress_callback_cls, |
311 | filename, GNUNET_YES, | 304 | filename, |
312 | GNUNET_FS_DIRSCANNER_FILE_START); | 305 | GNUNET_YES, |
313 | ds->pos = expand_tree (ds->pos, | 306 | GNUNET_FS_DIRSCANNER_FILE_START); |
314 | filename, | 307 | ds->pos = expand_tree (ds->pos, filename, GNUNET_YES); |
315 | GNUNET_YES); | ||
316 | if (NULL == ds->toplevel) | 308 | if (NULL == ds->toplevel) |
317 | ds->toplevel = ds->pos; | 309 | ds->toplevel = ds->pos; |
318 | return GNUNET_OK; | 310 | return GNUNET_OK; |
319 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR: | 311 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR: |
320 | break; | 312 | break; |
321 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE: | 313 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE: |
322 | if ('\0' != filename[left-1]) | 314 | if ('\0' != filename[left - 1]) |
323 | break; | 315 | break; |
324 | ds->progress_callback (ds->progress_callback_cls, | 316 | ds->progress_callback (ds->progress_callback_cls, |
325 | filename, GNUNET_SYSERR, | 317 | filename, |
326 | GNUNET_FS_DIRSCANNER_FILE_IGNORED); | 318 | GNUNET_SYSERR, |
319 | GNUNET_FS_DIRSCANNER_FILE_IGNORED); | ||
327 | return GNUNET_OK; | 320 | return GNUNET_OK; |
328 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE: | 321 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE: |
329 | if (0 != left) | 322 | if (0 != left) |
@@ -334,65 +327,66 @@ process_helper_msgs (void *cls, | |||
334 | if (NULL == ds->toplevel) | 327 | if (NULL == ds->toplevel) |
335 | break; | 328 | break; |
336 | ds->progress_callback (ds->progress_callback_cls, | 329 | ds->progress_callback (ds->progress_callback_cls, |
337 | NULL, GNUNET_SYSERR, | 330 | NULL, |
338 | GNUNET_FS_DIRSCANNER_ALL_COUNTED); | 331 | GNUNET_SYSERR, |
332 | GNUNET_FS_DIRSCANNER_ALL_COUNTED); | ||
339 | ds->pos = ds->toplevel; | 333 | ds->pos = ds->toplevel; |
340 | if (GNUNET_YES == ds->pos->is_directory) | 334 | if (GNUNET_YES == ds->pos->is_directory) |
341 | ds->pos = advance (ds->pos); | 335 | ds->pos = advance (ds->pos); |
342 | return GNUNET_OK; | 336 | return GNUNET_OK; |
343 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA: | 337 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA: { |
344 | { | 338 | size_t nlen; |
345 | size_t nlen; | 339 | const char *end; |
346 | const char *end; | ||
347 | 340 | ||
348 | if (NULL == ds->pos) | 341 | if (NULL == ds->pos) |
349 | { | 342 | { |
350 | GNUNET_break (0); | 343 | GNUNET_break (0); |
351 | break; | 344 | break; |
352 | } | 345 | } |
353 | end = memchr (filename, 0, left); | 346 | end = memchr (filename, 0, left); |
354 | if (NULL == end) | 347 | if (NULL == end) |
355 | { | 348 | { |
356 | GNUNET_break (0); | 349 | GNUNET_break (0); |
357 | break; | 350 | break; |
358 | } | 351 | } |
359 | end++; | 352 | end++; |
360 | nlen = end - filename; | 353 | nlen = end - filename; |
361 | left -= nlen; | 354 | left -= nlen; |
362 | if (0 != strcmp (filename, | 355 | if (0 != strcmp (filename, ds->pos->filename)) |
363 | ds->pos->filename)) | 356 | { |
364 | { | 357 | GNUNET_break (0); |
365 | GNUNET_break (0); | 358 | break; |
366 | break; | 359 | } |
367 | } | 360 | ds->progress_callback (ds->progress_callback_cls, |
368 | ds->progress_callback (ds->progress_callback_cls, | 361 | filename, |
369 | filename, | 362 | GNUNET_YES, |
370 | GNUNET_YES, | 363 | GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED); |
371 | GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED); | 364 | if (0 < left) |
372 | if (0 < left) | 365 | { |
366 | ds->pos->meta = GNUNET_CONTAINER_meta_data_deserialize (end, left); | ||
367 | if (NULL == ds->pos->meta) | ||
373 | { | 368 | { |
374 | ds->pos->meta = GNUNET_CONTAINER_meta_data_deserialize (end, | 369 | GNUNET_break (0); |
375 | left); | 370 | break; |
376 | if (NULL == ds->pos->meta) | ||
377 | { | ||
378 | GNUNET_break (0); | ||
379 | break; | ||
380 | } | ||
381 | /* having full filenames is too dangerous; always make sure we clean them up */ | ||
382 | GNUNET_CONTAINER_meta_data_delete (ds->pos->meta, | ||
383 | EXTRACTOR_METATYPE_FILENAME, | ||
384 | NULL, 0); | ||
385 | /* instead, put in our 'safer' original filename */ | ||
386 | GNUNET_CONTAINER_meta_data_insert (ds->pos->meta, "<libgnunetfs>", | ||
387 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, | ||
388 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", | ||
389 | ds->pos->short_filename, | ||
390 | strlen (ds->pos->short_filename) + 1); | ||
391 | } | 371 | } |
392 | ds->pos->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (ds->pos->meta); | 372 | /* having full filenames is too dangerous; always make sure we clean them up */ |
393 | ds->pos = advance (ds->pos); | 373 | GNUNET_CONTAINER_meta_data_delete (ds->pos->meta, |
394 | return GNUNET_OK; | 374 | EXTRACTOR_METATYPE_FILENAME, |
375 | NULL, | ||
376 | 0); | ||
377 | /* instead, put in our 'safer' original filename */ | ||
378 | GNUNET_CONTAINER_meta_data_insert (ds->pos->meta, | ||
379 | "<libgnunetfs>", | ||
380 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, | ||
381 | EXTRACTOR_METAFORMAT_UTF8, | ||
382 | "text/plain", | ||
383 | ds->pos->short_filename, | ||
384 | strlen (ds->pos->short_filename) + 1); | ||
395 | } | 385 | } |
386 | ds->pos->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (ds->pos->meta); | ||
387 | ds->pos = advance (ds->pos); | ||
388 | return GNUNET_OK; | ||
389 | } | ||
396 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED: | 390 | case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED: |
397 | if (NULL != ds->pos) | 391 | if (NULL != ds->pos) |
398 | { | 392 | { |
@@ -406,16 +400,16 @@ process_helper_msgs (void *cls, | |||
406 | } | 400 | } |
407 | if (NULL == ds->toplevel) | 401 | if (NULL == ds->toplevel) |
408 | break; | 402 | break; |
409 | ds->stop_task = GNUNET_SCHEDULER_add_now (&finish_scan, | 403 | ds->stop_task = GNUNET_SCHEDULER_add_now (&finish_scan, ds); |
410 | ds); | ||
411 | return GNUNET_OK; | 404 | return GNUNET_OK; |
412 | default: | 405 | default: |
413 | GNUNET_break (0); | 406 | GNUNET_break (0); |
414 | break; | 407 | break; |
415 | } | 408 | } |
416 | ds->progress_callback (ds->progress_callback_cls, | 409 | ds->progress_callback (ds->progress_callback_cls, |
417 | NULL, GNUNET_SYSERR, | 410 | NULL, |
418 | GNUNET_FS_DIRSCANNER_INTERNAL_ERROR); | 411 | GNUNET_SYSERR, |
412 | GNUNET_FS_DIRSCANNER_INTERNAL_ERROR); | ||
419 | return GNUNET_OK; | 413 | return GNUNET_OK; |
420 | } | 414 | } |
421 | 415 | ||
@@ -434,8 +428,9 @@ helper_died_cb (void *cls) | |||
434 | if (NULL != ds->stop_task) | 428 | if (NULL != ds->stop_task) |
435 | return; /* normal death, was finished */ | 429 | return; /* normal death, was finished */ |
436 | ds->progress_callback (ds->progress_callback_cls, | 430 | ds->progress_callback (ds->progress_callback_cls, |
437 | NULL, GNUNET_SYSERR, | 431 | NULL, |
438 | GNUNET_FS_DIRSCANNER_INTERNAL_ERROR); | 432 | GNUNET_SYSERR, |
433 | GNUNET_FS_DIRSCANNER_INTERNAL_ERROR); | ||
439 | } | 434 | } |
440 | 435 | ||
441 | 436 | ||
@@ -452,22 +447,23 @@ helper_died_cb (void *cls) | |||
452 | */ | 447 | */ |
453 | struct GNUNET_FS_DirScanner * | 448 | struct GNUNET_FS_DirScanner * |
454 | GNUNET_FS_directory_scan_start (const char *filename, | 449 | GNUNET_FS_directory_scan_start (const char *filename, |
455 | int disable_extractor, const char *ex, | 450 | int disable_extractor, |
456 | GNUNET_FS_DirScannerProgressCallback cb, | 451 | const char *ex, |
457 | void *cb_cls) | 452 | GNUNET_FS_DirScannerProgressCallback cb, |
453 | void *cb_cls) | ||
458 | { | 454 | { |
459 | struct stat sbuf; | 455 | struct stat sbuf; |
460 | char *filename_expanded; | 456 | char *filename_expanded; |
461 | struct GNUNET_FS_DirScanner *ds; | 457 | struct GNUNET_FS_DirScanner *ds; |
462 | 458 | ||
463 | if (0 != STAT (filename, &sbuf)) | 459 | if (0 != stat (filename, &sbuf)) |
464 | return NULL; | 460 | return NULL; |
465 | filename_expanded = GNUNET_STRINGS_filename_expand (filename); | 461 | filename_expanded = GNUNET_STRINGS_filename_expand (filename); |
466 | if (NULL == filename_expanded) | 462 | if (NULL == filename_expanded) |
467 | return NULL; | 463 | return NULL; |
468 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 464 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
469 | "Starting to scan directory `%s'\n", | 465 | "Starting to scan directory `%s'\n", |
470 | filename_expanded); | 466 | filename_expanded); |
471 | ds = GNUNET_new (struct GNUNET_FS_DirScanner); | 467 | ds = GNUNET_new (struct GNUNET_FS_DirScanner); |
472 | ds->progress_callback = cb; | 468 | ds->progress_callback = cb; |
473 | ds->progress_callback_cls = cb_cls; | 469 | ds->progress_callback_cls = cb_cls; |
@@ -481,12 +477,13 @@ GNUNET_FS_directory_scan_start (const char *filename, | |||
481 | ds->args[2] = ds->ex_arg; | 477 | ds->args[2] = ds->ex_arg; |
482 | ds->args[3] = NULL; | 478 | ds->args[3] = NULL; |
483 | ds->helper = GNUNET_HELPER_start (GNUNET_NO, | 479 | ds->helper = GNUNET_HELPER_start (GNUNET_NO, |
484 | "gnunet-helper-fs-publish", | 480 | "gnunet-helper-fs-publish", |
485 | ds->args, | 481 | ds->args, |
486 | &process_helper_msgs, | 482 | &process_helper_msgs, |
487 | &helper_died_cb, ds); | 483 | &helper_died_cb, |
484 | ds); | ||
488 | if (NULL == ds->helper) | 485 | if (NULL == ds->helper) |
489 | { | 486 | { |
490 | GNUNET_free (filename_expanded); | 487 | GNUNET_free (filename_expanded); |
491 | GNUNET_free (ds); | 488 | GNUNET_free (ds); |
492 | return NULL; | 489 | return NULL; |