core.c 2.7 KB

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