A tool for adding anime to your anidb list.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

86 lignes
2.1KB

  1. #define _XOPEN_SOURCE 500
  2. #include <sys/stat.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <assert.h>
  6. #include "util.h"
  7. #include "ed2k.h"
  8. #include "ed2k_util.h"
  9. #include "uio.h"
  10. #include "globals.h"
  11. static enum error ed2k_util_hash(const char *file_path, const struct stat *st, void *data)
  12. {
  13. off_t blksize = st->st_blksize;
  14. unsigned char buf[blksize], hash[ED2K_HASH_SIZE];
  15. struct ed2k_util_opts *opts = data;
  16. struct ed2k_ctx ed2k;
  17. enum error err;
  18. FILE *f;
  19. size_t read_len;
  20. int en;
  21. if (opts->pre_hash_fn) {
  22. err = opts->pre_hash_fn(file_path, st, opts->data);
  23. if (err == ED2KUTIL_DONTHASH)
  24. return NOERR;
  25. else if (err != NOERR)
  26. return err;
  27. }
  28. f = fopen(file_path, "rb");
  29. if (!f) {
  30. en = errno;
  31. uio_error("Failed to open file: %s (%s)", file_path, strerror(en));
  32. if (en == EINTR && should_exit)
  33. return ERR_SHOULD_EXIT;
  34. else
  35. return ERR_ITERPATH;
  36. }
  37. ed2k_init(&ed2k);
  38. read_len = fread(buf, 1, sizeof(buf), f);
  39. /* From my test, fread wont return anything special on signal interrupt */
  40. while (read_len > 0 && !should_exit) {
  41. ed2k_update(&ed2k, buf, read_len);
  42. read_len = fread(buf, 1, sizeof(buf), f);
  43. }
  44. if (should_exit) {
  45. err = ERR_SHOULD_EXIT;
  46. goto fail;
  47. }
  48. if (ferror(f)) { /* Loop stopped bcuz of error, not EOF */
  49. uio_error("Failure while reading file");
  50. err = ERR_ITERPATH;
  51. goto fail;
  52. }
  53. assert(feof(f));
  54. ed2k_final(&ed2k, hash);
  55. if (fclose(f) != 0) {
  56. en = errno;
  57. uio_debug("Fclose failed: %s", strerror(en));
  58. if (en == EINTR && should_exit)
  59. return ERR_SHOULD_EXIT;
  60. else
  61. return ERR_ITERPATH;
  62. }
  63. if (opts->post_hash_fn)
  64. return opts->post_hash_fn(file_path, hash, st, opts->data);
  65. return NOERR;
  66. fail:
  67. if (f) /* We can't get a 2nd interrupt now */
  68. fclose(f);
  69. return err;
  70. }
  71. enum error ed2k_util_iterpath(const char *path, const struct ed2k_util_opts *opts)
  72. {
  73. return util_iterpath(path, ed2k_util_hash, (void*)opts);
  74. }