core.c 2.9 KB

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