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.

154 lignes
3.8KB

  1. #define _XOPEN_SOURCE 500
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <assert.h>
  6. #include <errno.h>
  7. #include <sys/stat.h>
  8. #include <ftw.h>
  9. #include "util.h"
  10. #include "error.h"
  11. #include "uio.h"
  12. void util_byte2hex(const uint8_t* bytes, size_t bytes_len,
  13. bool uppercase, char* out)
  14. {
  15. const char* hex = (uppercase) ? "0123456789ABCDEF" : "0123456789abcdef";
  16. for (size_t i = 0; i < bytes_len; i++) {
  17. *out++ = hex[bytes[i] >> 4];
  18. *out++ = hex[bytes[i] & 0xF];
  19. }
  20. *out = '\0';
  21. }
  22. void util_hex2byte(const char *str, uint8_t* out_bytes)
  23. {
  24. while (*str) {
  25. if (*str >= '0' && *str <= '9')
  26. *out_bytes = (*str - '0') << 4;
  27. if (*str >= 'A' && *str <= 'F')
  28. *out_bytes = (*str - ('A' - 10)) << 4;
  29. else
  30. *out_bytes = (*str - ('a' - 10)) << 4;
  31. str++;
  32. if (*str >= '0' && *str <= '9')
  33. *out_bytes |= (*str - '0');
  34. if (*str >= 'A' && *str <= 'F')
  35. *out_bytes |= (*str - ('A' - 10));
  36. else
  37. *out_bytes |= (*str - ('a' - 10));
  38. out_bytes++;
  39. str++;
  40. }
  41. }
  42. const char *util_get_home()
  43. {
  44. const char *home_env = getenv("HOME");
  45. return home_env; /* TODO this can be null, use other methods as fallback */
  46. }
  47. char *util_basename(const char *fullpath)
  48. {
  49. char *name_part = strrchr(fullpath, '/');
  50. if (name_part)
  51. name_part++;
  52. else
  53. name_part = (char*)fullpath;
  54. return name_part;
  55. }
  56. uint64_t util_timespec_diff(const struct timespec *past,
  57. const struct timespec *future)
  58. {
  59. int64_t sdiff = future->tv_sec - past->tv_sec;
  60. int64_t nsdiff = future->tv_nsec - past->tv_nsec;
  61. return sdiff * 1000 + (nsdiff / 1000000);
  62. }
  63. uint64_t util_iso2unix(const char *isotime)
  64. {
  65. struct tm tm = {0};
  66. char *ms = strptime(isotime, "%Y-%m-%d", &tm);
  67. if (!ms || (*ms != '\0' && *ms != ' ' && *ms != 'T'))
  68. return 0;
  69. if (*ms == '\0')
  70. ms = "T00:00:00";
  71. ms = strptime(ms + 1, "%H:%M", &tm);
  72. if (!ms || (*ms != '\0' && *ms != ':'))
  73. return 0;
  74. if (*ms == '\0')
  75. ms = ":00";
  76. ms = strptime(ms + 1, "%S", &tm);
  77. if (!ms)
  78. return 0;
  79. return mktime(&tm);
  80. }
  81. /* nftw doesn't support passing in user data to the callback function :/ */
  82. static util_itercb global_iterpath_cb = NULL;
  83. static void *global_iterpath_data = NULL;
  84. static int util_iterpath_walk(const char *fpath, const struct stat *sb,
  85. int typeflag, struct FTW *ftwbuf)
  86. {
  87. if (typeflag == FTW_DNR) {
  88. uio_error("Cannot read directory '%s'. Skipping", fpath);
  89. return NOERR;
  90. }
  91. if (typeflag == FTW_D)
  92. return NOERR;
  93. if (typeflag != FTW_F) {
  94. uio_error("Unhandled error '%d'", typeflag);
  95. return ERR_ITERPATH;
  96. }
  97. return global_iterpath_cb(fpath, sb, global_iterpath_data);
  98. }
  99. enum error util_iterpath(const char *path, util_itercb cb, void *data)
  100. {
  101. assert(global_iterpath_cb == NULL);
  102. enum error ret = ERR_ITERPATH;
  103. struct stat ts;
  104. if (stat(path, &ts) != 0) {
  105. uio_error("Stat failed for path: '%s' (%s)",
  106. path, strerror(errno));
  107. goto error;
  108. }
  109. if (S_ISREG(ts.st_mode)) {
  110. /* If the path is a regular file, call the cb once */
  111. ret = cb(path, &ts, data);
  112. goto end;
  113. } else if (S_ISDIR(ts.st_mode)) {
  114. global_iterpath_cb = cb;
  115. global_iterpath_data = data;
  116. /* If a directory, walk over it */
  117. ret = nftw(path, util_iterpath_walk, 20, 0);
  118. if (ret == -1) {
  119. uio_error("nftw failure");
  120. goto error;
  121. }
  122. goto end;
  123. }
  124. uio_error("Unsupported file type: %d", ts.st_mode & S_IFMT);
  125. end:
  126. global_iterpath_cb = global_iterpath_data = NULL;
  127. return ret;
  128. error:
  129. ret = ERR_ITERPATH;
  130. goto end;
  131. }