aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_hash.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-05-06 19:59:59 +0000
committerChristian Grothoff <christian@grothoff.org>2010-05-06 19:59:59 +0000
commit7db4f64461a77f19bb39f1b84d26f96e6acf40ab (patch)
tree7d2adef1cebe18d80806bba3d534e9a1e4a44ac6 /src/util/crypto_hash.c
parent0ece77aca2114b6e5ec153477fccb43ceb807c77 (diff)
downloadgnunet-7db4f64461a77f19bb39f1b84d26f96e6acf40ab.tar.gz
gnunet-7db4f64461a77f19bb39f1b84d26f96e6acf40ab.zip
allow file hashing cancellation -- and make use of it
Diffstat (limited to 'src/util/crypto_hash.c')
-rw-r--r--src/util/crypto_hash.c76
1 files changed, 57 insertions, 19 deletions
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index dcee545f7..60104b604 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -372,7 +372,7 @@ GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret)
372/** 372/**
373 * Context used when hashing a file. 373 * Context used when hashing a file.
374 */ 374 */
375struct FileHashContext 375struct GNUNET_CRYPTO_FileHashContext
376{ 376{
377 377
378 /** 378 /**
@@ -396,14 +396,19 @@ struct FileHashContext
396 char *filename; 396 char *filename;
397 397
398 /** 398 /**
399 * Cummulated hash. 399 * File descriptor.
400 */ 400 */
401 struct sha512_ctx hctx; 401 struct GNUNET_DISK_FileHandle *fh;
402 402
403 /** 403 /**
404 * Blocksize. 404 * Our scheduler.
405 */ 405 */
406 size_t bsize; 406 struct GNUNET_SCHEDULER_Handle *sched;
407
408 /**
409 * Cummulated hash.
410 */
411 struct sha512_ctx hctx;
407 412
408 /** 413 /**
409 * Size of the file. 414 * Size of the file.
@@ -416,9 +421,14 @@ struct FileHashContext
416 uint64_t offset; 421 uint64_t offset;
417 422
418 /** 423 /**
419 * File descriptor. 424 * Current task for hashing.
420 */ 425 */
421 struct GNUNET_DISK_FileHandle *fh; 426 GNUNET_SCHEDULER_TaskIdentifier task;
427
428 /**
429 * Blocksize.
430 */
431 size_t bsize;
422 432
423}; 433};
424 434
@@ -428,7 +438,8 @@ struct FileHashContext
428 * and free associated resources. 438 * and free associated resources.
429 */ 439 */
430static void 440static void
431file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res) 441file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc,
442 const GNUNET_HashCode * res)
432{ 443{
433 fhc->callback (fhc->callback_cls, res); 444 fhc->callback (fhc->callback_cls, res);
434 GNUNET_free (fhc->filename); 445 GNUNET_free (fhc->filename);
@@ -447,10 +458,11 @@ file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res)
447static void 458static void
448file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 459file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
449{ 460{
450 struct FileHashContext *fhc = cls; 461 struct GNUNET_CRYPTO_FileHashContext *fhc = cls;
451 GNUNET_HashCode res; 462 GNUNET_HashCode res;
452 size_t delta; 463 size_t delta;
453 464
465 fhc->task = GNUNET_SCHEDULER_NO_TASK;
454 GNUNET_assert (fhc->offset < fhc->fsize); 466 GNUNET_assert (fhc->offset < fhc->fsize);
455 delta = fhc->bsize; 467 delta = fhc->bsize;
456 if (fhc->fsize - fhc->offset < delta) 468 if (fhc->fsize - fhc->offset < delta)
@@ -470,8 +482,10 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
470 file_hash_finish (fhc, &res); 482 file_hash_finish (fhc, &res);
471 return; 483 return;
472 } 484 }
473 GNUNET_SCHEDULER_add_after (tc->sched, 485 fhc->task
474 GNUNET_SCHEDULER_NO_TASK, &file_hash_task, fhc); 486 = GNUNET_SCHEDULER_add_after (tc->sched,
487 GNUNET_SCHEDULER_NO_TASK,
488 &file_hash_task, fhc);
475} 489}
476 490
477 491
@@ -484,8 +498,9 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
484 * @param blocksize number of bytes to process in one task 498 * @param blocksize number of bytes to process in one task
485 * @param callback function to call upon completion 499 * @param callback function to call upon completion
486 * @param callback_cls closure for callback 500 * @param callback_cls closure for callback
501 * @return NULL on (immediate) errror
487 */ 502 */
488void 503struct GNUNET_CRYPTO_FileHashContext *
489GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched, 504GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
490 enum GNUNET_SCHEDULER_Priority priority, 505 enum GNUNET_SCHEDULER_Priority priority,
491 const char *filename, 506 const char *filename,
@@ -493,12 +508,13 @@ GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
493 GNUNET_CRYPTO_HashCompletedCallback callback, 508 GNUNET_CRYPTO_HashCompletedCallback callback,
494 void *callback_cls) 509 void *callback_cls)
495{ 510{
496 struct FileHashContext *fhc; 511 struct GNUNET_CRYPTO_FileHashContext *fhc;
497 512
498 GNUNET_assert (blocksize > 0); 513 GNUNET_assert (blocksize > 0);
499 fhc = GNUNET_malloc (sizeof (struct FileHashContext) + blocksize); 514 fhc = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize);
500 fhc->callback = callback; 515 fhc->callback = callback;
501 fhc->callback_cls = callback_cls; 516 fhc->callback_cls = callback_cls;
517 fhc->sched = sched;
502 fhc->buffer = (unsigned char *) &fhc[1]; 518 fhc->buffer = (unsigned char *) &fhc[1];
503 fhc->filename = GNUNET_strdup (filename); 519 fhc->filename = GNUNET_strdup (filename);
504 fhc->fh = NULL; 520 fhc->fh = NULL;
@@ -506,21 +522,43 @@ GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
506 fhc->bsize = blocksize; 522 fhc->bsize = blocksize;
507 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO)) 523 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO))
508 { 524 {
509 file_hash_finish (fhc, NULL); 525 GNUNET_free (fhc->filename);
510 return; 526 GNUNET_free (fhc);
527 return NULL;
511 } 528 }
512 fhc->fh = GNUNET_DISK_file_open (filename, 529 fhc->fh = GNUNET_DISK_file_open (filename,
513 GNUNET_DISK_OPEN_READ, 530 GNUNET_DISK_OPEN_READ,
514 GNUNET_DISK_PERM_NONE); 531 GNUNET_DISK_PERM_NONE);
515 if (!fhc->fh) 532 if (!fhc->fh)
516 { 533 {
517 file_hash_finish (fhc, NULL); 534 GNUNET_free (fhc->filename);
518 return; 535 GNUNET_free (fhc);
536 return NULL;
519 } 537 }
520 GNUNET_SCHEDULER_add_with_priority (sched, priority, &file_hash_task, fhc); 538 fhc->task
539 = GNUNET_SCHEDULER_add_with_priority (sched, priority,
540 &file_hash_task, fhc);
541 return fhc;
542}
543
544
545/**
546 * Cancel a file hashing operation.
547 *
548 * @param fhc operation to cancel (callback must not yet have been invoked)
549 */
550void
551GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc)
552{
553 GNUNET_SCHEDULER_cancel (fhc->sched,
554 fhc->task);
555 GNUNET_free (fhc->filename);
556 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fhc->fh));
557 GNUNET_free (fhc);
521} 558}
522 559
523 560
561
524/* ***************** binary-ASCII encoding *************** */ 562/* ***************** binary-ASCII encoding *************** */
525 563
526/** 564/**