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.

94 lignes
2.3KB

  1. #define _XOPEN_SOURCE 500
  2. #include <sys/stat.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <ftw.h>
  6. #include "ed2k.h"
  7. #include "ed2k_util.h"
  8. #include "uio.h"
  9. static struct ed2k_util_opts l_opts;
  10. static enum error ed2k_util_hash(const char *file_path, blksize_t blksize,
  11. const struct stat *st)
  12. {
  13. unsigned char buf[blksize], hash[ED2K_HASH_SIZE];
  14. struct ed2k_ctx ed2k;
  15. FILE *f;
  16. size_t read_len;
  17. if (l_opts.pre_hash_fn) {
  18. enum error err = l_opts.pre_hash_fn(file_path, st, l_opts.data);
  19. if (err == ED2KUTIL_DONTHASH)
  20. return NOERR;
  21. else if (err != NOERR)
  22. return err;
  23. }
  24. f = fopen(file_path, "rb");
  25. if (!f) {
  26. uio_error("Failed to open file: %s (%s)", file_path, strerror(errno));
  27. return ERR_ED2KUTIL_FS;
  28. }
  29. ed2k_init(&ed2k);
  30. read_len = fread(buf, 1, sizeof(buf), f);
  31. while (read_len > 0) {
  32. ed2k_update(&ed2k, buf, read_len);
  33. read_len = fread(buf, 1, sizeof(buf), f);
  34. }
  35. // TODO check if eof or error
  36. ed2k_final(&ed2k, hash);
  37. fclose(f);
  38. if (l_opts.post_hash_fn)
  39. return l_opts.post_hash_fn(file_path, hash, st, l_opts.data);
  40. return NOERR;
  41. }
  42. static int ed2k_util_walk(const char *fpath, const struct stat *sb,
  43. int typeflag, struct FTW *ftwbuf)
  44. {
  45. if (typeflag == FTW_DNR) {
  46. uio_error("Cannot read directory '%s'. Skipping", fpath);
  47. return NOERR;
  48. }
  49. if (typeflag == FTW_D)
  50. return NOERR;
  51. if (typeflag != FTW_F) {
  52. uio_error("Unhandled error '%d'", typeflag);
  53. return ERR_ED2KUTIL_UNSUP;
  54. }
  55. return ed2k_util_hash(fpath, sb->st_blksize, sb);
  56. }
  57. enum error ed2k_util_iterpath(const char *path, const struct ed2k_util_opts *opts)
  58. {
  59. struct stat ts;
  60. if (stat(path, &ts) != 0) {
  61. uio_error("Stat failed for path: '%s' (%s)",
  62. path, strerror(errno));
  63. return ERR_ED2KUTIL_FS;
  64. }
  65. l_opts = *opts;
  66. if (S_ISREG(ts.st_mode)) {
  67. return ed2k_util_hash(path, ts.st_blksize, &ts);
  68. } else if (S_ISDIR(ts.st_mode)) {
  69. int ftwret = nftw(path, ed2k_util_walk, 20, 0);
  70. if (ftwret == -1) {
  71. uio_error("nftw failure");
  72. return ERR_ED2KUTIL_FS;
  73. }
  74. return ftwret;
  75. }
  76. uio_error("Unsupported file type: %d", ts.st_mode & S_IFMT);
  77. return ERR_ED2KUTIL_UNSUP;
  78. }