core.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #define _XOPEN_SOURCE 500
  2. #include <errno.h>
  3. #include <ftw.h>
  4. #include "core.h"
  5. #include "lmdb.h"
  6. bool LSUP_env_is_init = false;
  7. /** @brief Warning messages.
  8. *
  9. * The message corresponding to the rc is found by
  10. * warning_msg[rc - LSUP_MIN_WARNING]. #LSUP_strerror() facilitates this.
  11. */
  12. char *warning_msg[] = {
  13. "LSUP_NOACTION: No action or change of state occurred.",
  14. "LSUP_NORESULT: No result.",
  15. "LSUP_END: End of the loop reached.",
  16. "LSUP_CONFLICT: A conflict prevented a resource from being updated.",
  17. };
  18. /** @brief error messages.
  19. *
  20. * Note that all error values are < 0 so it is possible to set conditions to
  21. * be triggered only by error return values.
  22. *
  23. * The message corresponding to the rc is found by
  24. * err_msg[rc - LSUP_MIN_ERROR]. #LSUP_strerror() facilitates this.
  25. */
  26. char *err_msg[] = {
  27. "LSUP_ERROR: Runtime error.",
  28. "LSUP_PARSE_ERR: Error parsing input.",
  29. "LSUP_VALUE_ERR: Invalid input.",
  30. "LSUP_TXN_ERR: MDB transaction error.",
  31. "LSUP_DB_ERR: Database error.",
  32. "LSUP_NOT_IMPL_ERR: Feature is not implemented.",
  33. "LSUP_IO_ERR: Input/Output error.",
  34. "LSUP_MEM_ERR: Memory error.",
  35. "LSUP_CONFLICT_ERR: A resource conflict interrupted the operation.",
  36. "LSUP_ENV_ERR: Environment not initialized. Did you call LSUP_init()?",
  37. };
  38. char *LSUP_root_path = __FILE__; // This is trimmed to root path on init.
  39. LSUP_rc
  40. mkdir_p (const char *_path, mode_t mode)
  41. {
  42. char *path = strdup (_path);
  43. char *p;
  44. // Trim any trailing slash(es).
  45. for (p = path + strlen (path) - 1; p > path; p--)
  46. if (*p == '/') *p = '\0';
  47. else break;
  48. errno = 0;
  49. LSUP_rc rc = LSUP_NOACTION;
  50. /* Iterate the string */
  51. for (p = path + 1; *p; p++) {
  52. if (*p == '/') {
  53. /* Temporarily truncate */
  54. *p = '\0';
  55. if (mkdir (path, mode) != 0 && errno != EEXIST) goto finally;
  56. *p = '/';
  57. }
  58. }
  59. if (mkdir (path, mode) != 0) {
  60. if (errno != EEXIST) rc = errno;
  61. } else {
  62. rc = LSUP_OK;
  63. }
  64. finally:
  65. log_trace ("Path: %s", path);
  66. log_trace ("errno: %d", errno);
  67. log_trace ("rc: %d", rc);
  68. free (path);
  69. return rc;
  70. }
  71. int
  72. unlink_cb(
  73. const char *fpath, const struct stat *sb, int typeflag,
  74. struct FTW *ftwbuf)
  75. {
  76. log_debug ("Removing %s", fpath);
  77. int rv = remove(fpath);
  78. if (rv)
  79. perror(fpath);
  80. return rv;
  81. }
  82. int rm_r(const char *path)
  83. { return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); }
  84. const char *
  85. LSUP_strerror (LSUP_rc rc)
  86. {
  87. if (rc >= LSUP_MIN_ERROR && rc <= LSUP_MAX_ERROR)
  88. return err_msg[rc - LSUP_MIN_ERROR];
  89. if (rc >= LSUP_MIN_WARNING && rc <= LSUP_MAX_WARNING)
  90. return warning_msg[rc - LSUP_MIN_WARNING];
  91. return mdb_strerror (rc);
  92. }
  93. /* Inline extern functions. */
  94. int utf8_encode(const uint32_t utf, unsigned char *out);