p≡p engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

903 lines
26 KiB

3 years ago
3 years ago
3 years ago
7 years ago
6 years ago
7 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
6 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
3 years ago
3 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
3 years ago
3 years ago
3 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well.
9 months ago
3 years ago
  1. /** @file */
  2. /** @brief File description for doxygen missing. FIXME */
  3. // This file is under GNU General Public License 3.0
  4. // see LICENSE.txt
  5. #define _POSIX_C_SOURCE 200809L
  6. #ifdef ANDROID
  7. #ifndef __LP64__
  8. #include <time64.h>
  9. #endif
  10. #endif
  11. #include <stdbool.h>
  12. #include <time.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <assert.h>
  16. #include <stdio.h>
  17. #include <glob.h>
  18. #include <errno.h>
  19. #include <sys/stat.h>
  20. #include <sys/types.h>
  21. #include <fcntl.h>
  22. #include <regex.h>
  23. #include "pEpEngine.h" /* For PEP_STATUS */
  24. #include "platform_unix.h"
  25. #include "dynamic_api.h"
  26. #define MAX_PATH 1024
  27. #ifndef LOCAL_DB_FILENAME
  28. #define OLD_LOCAL_DB_FILENAME ".pEp_management.db"
  29. #define OLD_KEYS_DB_FILENAME ".pEp_keys.db"
  30. #define LOCAL_DB_FILENAME "management.db"
  31. #define KEYS_DB_FILENAME "keys.db"
  32. #endif
  33. #define SYSTEM_DB_FILENAME "system.db"
  34. #ifdef ANDROID
  35. #include <uuid.h>
  36. /* FIXME : timegm will miss when linking for x86_64 on android, when supported */
  37. #ifndef __LP64__
  38. time_t timegm(struct tm* const t) {
  39. static const time_t kTimeMax = ~(1L << (sizeof(time_t) * CHAR_BIT - 1));
  40. static const time_t kTimeMin = (1L << (sizeof(time_t) * CHAR_BIT - 1));
  41. time64_t result = timegm64(t);
  42. if (result < kTimeMin || result > kTimeMax)
  43. return -1;
  44. return result;
  45. }
  46. #endif
  47. char *stpncpy(char *dst, const char *src, size_t n)
  48. {
  49. if (n != 0) {
  50. char *d = dst;
  51. const char *s = src;
  52. dst = &dst[n];
  53. do {
  54. if ((*d++ = *s++) == 0) {
  55. dst = d - 1;
  56. /* NUL pad the remaining n-1 bytes */
  57. while (--n != 0)
  58. *d++ = 0;
  59. break;
  60. }
  61. } while (--n != 0);
  62. }
  63. return (dst);
  64. }
  65. char *stpcpy(char *dst, const char *src)
  66. {
  67. for (;; ++dst, ++src) {
  68. *dst = *src;
  69. if (*dst == 0)
  70. break;
  71. }
  72. return dst;
  73. }
  74. /*
  75. long int random(void)
  76. {
  77. static bool seeded = false;
  78. static unsigned short xsubi[3];
  79. if(!seeded)
  80. {
  81. const long long t = (long long)time(NULL);
  82. xsubi[0] = (unsigned short)t;
  83. xsubi[1] = (unsigned short)(t>>16);
  84. xsubi[2] = (unsigned short)(t>>32);
  85. seeded = true;
  86. }
  87. return nrand48(xsubi);
  88. } */
  89. /* This is a non-caching function: see the comments in "Internal path caching
  90. functionality" below. */
  91. static char *_android_system_db(void)
  92. {
  93. char *buffer = malloc (MAX_PATH);
  94. if (buffer == NULL)
  95. return NULL;
  96. char *tw_env;
  97. if(tw_env = getenv("TRUSTWORDS")){
  98. char *p = stpncpy(buffer, tw_env, MAX_PATH);
  99. ssize_t len = MAX_PATH - (p - buffer) - 2;
  100. if (len < strlen(SYSTEM_DB_FILENAME)) {
  101. assert(0);
  102. return NULL;
  103. }
  104. *p++ = '/';
  105. strncpy(p, SYSTEM_DB_FILENAME, len);
  106. }else{
  107. return NULL;
  108. }
  109. return buffer;
  110. }
  111. void uuid_generate_random(pEpUUID out)
  112. {
  113. uuid_t *uuid;
  114. uuid_rc_t rc_create;
  115. size_t size = sizeof(uuid_string_t);
  116. void *_out = out;
  117. if ((rc_create = uuid_create(&uuid)) != UUID_RC_OK ||
  118. uuid_make(uuid, UUID_MAKE_V1) != UUID_RC_OK ||
  119. uuid_export(uuid, UUID_FMT_BIN, &_out, &size) != UUID_RC_OK)
  120. {
  121. memset(out, 0, sizeof(pEpUUID));
  122. }
  123. if (rc_create == UUID_RC_OK)
  124. {
  125. uuid_destroy(uuid);
  126. }
  127. }
  128. void uuid_unparse_upper(pEpUUID uu, uuid_string_t out)
  129. {
  130. uuid_t *uuid;
  131. uuid_rc_t rc_create;
  132. size_t size = sizeof(uuid_string_t);
  133. void *_out = out;
  134. if ((rc_create = uuid_create(&uuid)) != UUID_RC_OK ||
  135. uuid_import(uuid, UUID_FMT_BIN, uu, sizeof(pEpUUID)) != UUID_RC_OK ||
  136. uuid_export(uuid, UUID_FMT_STR, &_out, &size) != UUID_RC_OK)
  137. {
  138. memset(out, 0, sizeof(uuid_string_t));
  139. }
  140. else
  141. {
  142. out[sizeof(uuid_string_t) - 1] = 0;
  143. }
  144. if (rc_create == UUID_RC_OK)
  145. {
  146. uuid_destroy(uuid);
  147. }
  148. }
  149. #endif
  150. #if !defined(BSD) && !defined(__APPLE__)
  151. size_t strlcpy(char* dst, const char* src, size_t size) {
  152. size_t retval = strlen(src);
  153. size_t size_to_copy = (retval < size ? retval : size - 1);
  154. // strlcpy doc says src and dst not allowed to overlap, as
  155. // it's undefined. So this is acceptable:
  156. memcpy((void*)dst, (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
  157. dst[size_to_copy] = '\0';
  158. return retval;
  159. }
  160. size_t strlcat(char* dst, const char* src, size_t size) {
  161. size_t start_len = strnlen(dst, size);
  162. if (start_len == size)
  163. return size; // no copy, no null termination in size bytes, according to spec
  164. size_t add_len = strlen(src);
  165. size_t retval = start_len + add_len;
  166. size_t size_to_copy = (retval < size ? add_len : (size - start_len) - 1);
  167. // strlcat doc says src and dst not allowed to overlap, as
  168. // it's undefined. So this is acceptable:
  169. memcpy((void*)(dst + start_len), (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
  170. dst[start_len + size_to_copy] = '\0';
  171. return retval;
  172. }
  173. char *strnstr(const char *big, const char *little, size_t len) {
  174. if (big == NULL || little == NULL)
  175. return NULL;
  176. if (*little == '\0')
  177. return (char*)big;
  178. const char* curr_big = big;
  179. size_t little_len = strlen(little);
  180. size_t remaining = len;
  181. const char* retval = NULL;
  182. for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
  183. // find first-char match
  184. if (*curr_big != *little) {
  185. continue;
  186. }
  187. retval = curr_big;
  188. const char* inner_big = retval + 1;
  189. const char* curr_little = little + 1;
  190. int j;
  191. for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
  192. if (*inner_big != *curr_little) {
  193. retval = NULL;
  194. break;
  195. }
  196. }
  197. if (retval)
  198. break;
  199. }
  200. return (char*)retval;
  201. }
  202. // #ifdef USE_NETPGP
  203. // // FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
  204. // int regnexec(const regex_t* preg, const char* string,
  205. // size_t len, size_t nmatch, regmatch_t pmatch[], int eflags) {
  206. // return regexec(preg, string, nmatch, pmatch, eflags);
  207. // }
  208. // #endif
  209. #endif
  210. /**
  211. * @internal
  212. *
  213. * <!-- _stradd() -->
  214. *
  215. * @brief TODO
  216. *
  217. * @param[in] **first char
  218. * @param[in] *second constchar
  219. *
  220. */
  221. static char *_stradd(char **first, const char *second)
  222. {
  223. assert(first && *first && second);
  224. if (!(first && *first && second))
  225. return NULL;
  226. size_t len1 = strlen(*first);
  227. size_t len2 = strlen(second);
  228. size_t size = len1 + len2 + 1;
  229. char *_first = realloc(*first, size);
  230. assert(_first);
  231. if (!_first)
  232. return NULL;
  233. *first = _first;
  234. strlcat(*first, second, size);
  235. return *first;
  236. }
  237. /**
  238. * @internal
  239. *
  240. * <!-- _empty() -->
  241. *
  242. * @brief TODO
  243. *
  244. * @param[in] **p char
  245. *
  246. */
  247. static void _empty(char **p)
  248. {
  249. free(*p);
  250. *p = NULL;
  251. }
  252. /**
  253. * @internal
  254. *
  255. * <!-- _move() -->
  256. *
  257. * @brief TODO
  258. *
  259. * @param[in] *o constchar
  260. * @param[in] *ext constchar
  261. * @param[in] *n constchar
  262. *
  263. */
  264. static void _move(const char *o, const char *ext, const char *n)
  265. {
  266. assert(o && ext && n);
  267. if (!(o && ext && n))
  268. return;
  269. char *_old = strdup(o);
  270. assert(_old);
  271. if (!_old)
  272. return;
  273. char *r = _stradd(&_old, ext);
  274. if (!r) {
  275. free(_old);
  276. return;
  277. }
  278. char *_new = strdup(n);
  279. assert(_new);
  280. if (!_new) {
  281. free(_old);
  282. return;
  283. }
  284. r = _stradd(&_new, ext);
  285. if (r)
  286. rename(_old, _new);
  287. free(_old);
  288. free(_new);
  289. }
  290. /**
  291. * @internal
  292. *
  293. * <!-- _strdup_or_NULL() -->
  294. *
  295. * @brief Return a malloc-allocated copy of the given string, or (this
  296. * is the added functionality with respect to the standard
  297. * strdup) a malloc-allocated copy of "" if the argument is
  298. * NULL.
  299. *
  300. * @param[in] *original constchar
  301. * @retval NULL out of memory
  302. * @retval non-NULL malloc-allocated buffer
  303. */
  304. static char *_strdup_or_NULL(const char *original)
  305. {
  306. if (original == NULL)
  307. original = "";
  308. return strdup (original);
  309. }
  310. /*
  311. * Environment variable expansion
  312. * **********************************************************************
  313. */
  314. /* The state of a DFA implementing variable recognition in _expand_variables ,
  315. below. */
  316. enum _expand_variable_state {
  317. _expand_variable_state_non_variable,
  318. _expand_variable_state_after_dollar,
  319. _expand_variable_state_after_backslash,
  320. _expand_variable_state_in_variable
  321. };
  322. /**
  323. * @internal
  324. *
  325. * <!-- _expand_variables() -->
  326. *
  327. * @brief Set a malloc-allocated '\0'-terminated string which is
  328. * a copy of the argument with shell variables expanded, where
  329. * variable references use Unix shell-style syntax $VARIABLE.
  330. * Notice that the alternative syntax ${VARIABLE} is not
  331. * supported.
  332. * See [FIXME: deployment-engineer documentation].
  333. *
  334. * @param[in] string_with_variables char *
  335. * @param[out] copy_with_variables_expanded char **
  336. * @retval PEP_STATUS_OK success
  337. * @retval PEP_UNBOUND_ENVIRONMENT_VARIABLE unknown variable referenced
  338. * @retval PEP_PATH_SYNTAX_ERROR invalid syntax in argument
  339. * @retval PEP_OUT_OF_MEMORY out of memory
  340. *
  341. */
  342. static PEP_STATUS _expand_variables(char **out,
  343. const char *string_with_variables)
  344. {
  345. PEP_STATUS res = PEP_STATUS_OK;
  346. size_t in_length = strlen(string_with_variables);
  347. const char *variable_name_beginning; /* This points within the input. */
  348. char *variable_name_copy = NULL /* we free on error. */;
  349. size_t allocated_size
  350. #ifdef NDEBUG
  351. = 1024;
  352. #else
  353. = 1 /* Notice that 0 is incorrect: this grows by doubling. */;
  354. #endif // #ifdef NDEBUG
  355. int out_index = 0; /* The out index is also the used out size */
  356. const char *in = string_with_variables;
  357. /* In the pEp engine we adopt the convention of "" behaving the same as
  358. NULL. Notice that we never free this, so it is not a problem if this
  359. string is not malloc-allocated. */
  360. if (in == NULL)
  361. in = "";
  362. /* We free on error. */
  363. * out = NULL ;
  364. /* Recognise a variable according to POSIX syntax which, luckily for us,
  365. only allows for letters, digits and underscores -- The first character
  366. may not be a digit... */
  367. #define VALID_FIRST_CHARACTER_FOR_VARIABLE(c) \
  368. ( ((c) >= 'a' && (c) <= 'z') \
  369. || ((c) >= 'A' && (c) <= 'Z') \
  370. || ((c) == '_'))
  371. /* ...But characters after the first may be. */
  372. #define VALID_NON_FIRST_CHARACTER_FOR_VARIABLE(c) \
  373. ( VALID_FIRST_CHARACTER_FOR_VARIABLE(c) \
  374. || ((c) >= '0' && (c) <= '9'))
  375. /* Append the char argument to the result string, automatically resizing it
  376. if needed. */
  377. #define EMIT_CHAR(c) \
  378. do \
  379. { \
  380. if (out_index == allocated_size) { \
  381. allocated_size *= 2; \
  382. /*fprintf (stderr, "ALLOCATED SIZE: %i -> %i\n", (int) allocated_size / 2, (int) allocated_size);*/\
  383. * out = realloc (* out, allocated_size); \
  384. if (* out == NULL) \
  385. FATAL (PEP_OUT_OF_MEMORY, \
  386. "cannot grow buffer"); \
  387. } \
  388. (* out) [out_index] = (c); \
  389. out_index ++; \
  390. } \
  391. while (false)
  392. /* Append the string argument to the output string, automatically resizing
  393. it as needed. */
  394. #define EMIT_STRING(s) \
  395. do { \
  396. const char *p; \
  397. for (p = (s); (* p) != '\0'; p ++) \
  398. EMIT_CHAR (* p); \
  399. } while (false)
  400. /* Emit the expansion of the environment variable whose name is delimited on
  401. the left by variable_name_beginning and on the right by the character
  402. coming right *before* in. Fail fatally if the variable is unbound.
  403. The expansion is emitted by appending to the result string, automatically
  404. resizing it as needed. */
  405. #define EMIT_CURRENT_VARIABLE \
  406. do { \
  407. const char *variable_past_end = in; \
  408. size_t variable_name_length \
  409. = variable_past_end - variable_name_beginning; \
  410. strcpy (variable_name_copy, variable_name_beginning); \
  411. variable_name_copy [variable_name_length] = '\0'; \
  412. const char *variable_value = getenv (variable_name_copy); \
  413. if (variable_value == NULL) \
  414. FATAL_NAME (PEP_UNBOUND_ENVIRONMENT_VARIABLE, \
  415. "unbound variable", variable_name_copy); \
  416. EMIT_STRING (variable_value); \
  417. } while (false)
  418. #define FATAL(code, message) \
  419. do { res = (code); goto failure; } while (false)
  420. #define FATAL_NAME(code, message, name) \
  421. FATAL((code), (message))
  422. /* We can allocate buffers, now that we have FATAL. */
  423. if ((variable_name_copy
  424. = malloc (in_length + 1 /* a safe upper bound for a sub-string. */))
  425. == NULL)
  426. FATAL (PEP_OUT_OF_MEMORY, "out of mmeory");
  427. if (((* out) = malloc (allocated_size)) == NULL)
  428. FATAL (PEP_OUT_OF_MEMORY, "out of memory");
  429. /* This logic implements a DFA. */
  430. enum _expand_variable_state s = _expand_variable_state_non_variable;
  431. char c;
  432. while (true) {
  433. c = * in;
  434. switch (s) {
  435. case _expand_variable_state_non_variable:
  436. if (c == '$') {
  437. variable_name_beginning = in + 1;
  438. s = _expand_variable_state_after_dollar;
  439. }
  440. else if (c == '\\')
  441. s = _expand_variable_state_after_backslash;
  442. else /* This includes c == '\0'. */
  443. EMIT_CHAR (c);
  444. if (c == '\0')
  445. goto success;
  446. break;
  447. case _expand_variable_state_after_backslash:
  448. if (c == '$' || c == '\\') {
  449. EMIT_CHAR (c);
  450. s = _expand_variable_state_non_variable;
  451. }
  452. else if (c == '\0') /* Just to give a nicer error message */
  453. FATAL (PEP_PATH_SYNTAX_ERROR, "trailing unescaped '\\'");
  454. else /* this would be correct even with '\0' */
  455. FATAL (PEP_PATH_SYNTAX_ERROR, "invalid escape");
  456. break;
  457. case _expand_variable_state_after_dollar:
  458. if (VALID_FIRST_CHARACTER_FOR_VARIABLE (c))
  459. s = _expand_variable_state_in_variable;
  460. else if (c == '\0') /* Just to give a nicer error message */
  461. FATAL (PEP_PATH_SYNTAX_ERROR,"trailing '$' character");
  462. else if (c == '\\') /* Just to give a nicer error message */
  463. FATAL (PEP_PATH_SYNTAX_ERROR,
  464. "empty variable name followed by escape");
  465. else if (c == '$') /* Just to give a nicer error message */
  466. FATAL (PEP_PATH_SYNTAX_ERROR, "two consecutive '$' characters");
  467. else
  468. FATAL (PEP_PATH_SYNTAX_ERROR,
  469. "invalid variable first character after '$'");
  470. break;
  471. case _expand_variable_state_in_variable:
  472. if (VALID_NON_FIRST_CHARACTER_FOR_VARIABLE (c))
  473. /* Do nothing */;
  474. else if (c == '\\') {
  475. EMIT_CURRENT_VARIABLE;
  476. s = _expand_variable_state_after_backslash;
  477. }
  478. else {
  479. /* This includes c == '\0'. */
  480. EMIT_CURRENT_VARIABLE;
  481. EMIT_CHAR (c);
  482. if (c == '\0')
  483. goto success;
  484. else
  485. s = _expand_variable_state_non_variable;
  486. }
  487. break;
  488. default:
  489. FATAL (PEP_STATEMACHINE_INVALID_STATE /* Slightly questionable: this
  490. should be an assertion. */,
  491. "impossible DFA state");
  492. } /* switch */
  493. in ++;
  494. } /* while */
  495. success:
  496. free(variable_name_copy);
  497. return res;
  498. failure:
  499. free(* out);
  500. * out = NULL;
  501. goto success;
  502. #undef VALID_FIRST_CHARACTER_FOR_VARIABLE
  503. #undef VALID_NON_FIRST_CHARACTER_FOR_VARIABLE
  504. #undef EMIT_CHAR
  505. #undef EMIT_STRING
  506. #undef EMIT_CURRENT_VARIABLE
  507. #undef FATAL
  508. #undef FATAL_NAME
  509. }
  510. /*
  511. * Internal path caching functionality
  512. * **********************************************************************
  513. */
  514. /* Several functions in this compilation unit return paths to files or
  515. * directories, always returning pointers to the same internally managed memory
  516. * at every call.
  517. *
  518. * The cache is filled at engine initialisation, using the value of environment
  519. * variables at initialisation time: after that point no out-of-memory errors
  520. * are possible, until reset.
  521. *
  522. * In debugging mode the cache can be "reset", with every path recomputed on
  523. * demand according to the current environment.
  524. */
  525. /* For each path we define:
  526. - a static char * variable pointing to the cached value;
  527. - a prototype for a static function returning a malloc-allocated copy of
  528. the value, unexapanded, not using the cache (to be defined below by hand);
  529. - a public API function returning a pointer to cached memory. */
  530. #define DEFINE_CACHED_PATH(name) \
  531. /* A static variable holding the cached path, or NULL. */ \
  532. static char *_ ## name ## _cache = NULL; \
  533. \
  534. /* A prototype for the hand-written function returning the \
  535. computed value for the path, without using the cache and \
  536. without expanding variables. */ \
  537. static char *_ ## name(void); \
  538. \
  539. /* The public version of the function, using the cache. */ \
  540. DYNAMIC_API const char *name(void) \
  541. { \
  542. if (_ ## name ## _cache == NULL) { \
  543. /* It is unusual and slightly bizarre than a path is \
  544. accessed before initialisation; however it can happen \
  545. in the engine test suite. */ \
  546. fprintf (stderr, \
  547. "WARNING: accessing %s before its cache is set:" \
  548. " this should not happen in production.\n", \
  549. #name); \
  550. reset_path_cache(); \
  551. } \
  552. return _ ## name ## _cache; \
  553. }
  554. /* Define cached paths using the functionality above: */
  555. DEFINE_CACHED_PATH (per_user_relative_directory)
  556. DEFINE_CACHED_PATH (per_user_directory)
  557. DEFINE_CACHED_PATH (per_machine_directory)
  558. #ifdef ANDROID
  559. DEFINE_CACHED_PATH (android_system_db)
  560. #endif
  561. DEFINE_CACHED_PATH (unix_system_db)
  562. DEFINE_CACHED_PATH (unix_local_db)
  563. /* Free every cache variable and re-initialise it to NULL: this
  564. re-initialisation is important when this function is used here,
  565. internally, as part of cleanup on errors. */
  566. DYNAMIC_API void clear_path_cache (void)
  567. {
  568. #define UNSET(name) \
  569. do { \
  570. free((void *) _ ## name ## _cache); \
  571. (_ ## name ## _cache) = NULL; \
  572. } while (false)
  573. UNSET (per_user_relative_directory);
  574. UNSET (per_user_directory);
  575. UNSET (per_machine_directory);
  576. #ifdef ANDROID
  577. UNSET (android_system_db);
  578. #endif
  579. UNSET (unix_system_db);
  580. UNSET (unix_local_db);
  581. #undef UNSET
  582. }
  583. DYNAMIC_API PEP_STATUS reset_path_cache(void)
  584. {
  585. PEP_STATUS res = PEP_STATUS_OK;
  586. #define SET_OR_FAIL(name) \
  587. do { \
  588. unexpanded_path = (_ ## name)(); \
  589. if (unexpanded_path == NULL) { \
  590. res = PEP_OUT_OF_MEMORY; \
  591. goto free_everything_and_fail; \
  592. } \
  593. res = _expand_variables(& _ ## name ## _cache, unexpanded_path); \
  594. if (res != PEP_STATUS_OK) \
  595. goto free_everything_and_fail; \
  596. /* Clear unxpanded_path for the next call of SET_OR_FAIL. */ \
  597. free((void *) unexpanded_path); \
  598. unexpanded_path = NULL; \
  599. } while (false)
  600. /* In case this is not the first invocation, start by releasing memory. */
  601. clear_path_cache ();
  602. const char *unexpanded_path = NULL;
  603. SET_OR_FAIL (per_user_relative_directory);
  604. SET_OR_FAIL (per_user_directory);
  605. SET_OR_FAIL (per_machine_directory);
  606. #ifdef ANDROID
  607. SET_OR_FAIL (android_system_db);
  608. #endif
  609. SET_OR_FAIL (unix_system_db);
  610. SET_OR_FAIL (unix_local_db);
  611. return res;
  612. free_everything_and_fail:
  613. free((void *) unexpanded_path);
  614. clear_path_cache ();
  615. return res;
  616. #undef SET_OR_FAIL
  617. }
  618. /**
  619. * @internal
  620. *
  621. * <!-- _per_user_directory() -->
  622. *
  623. * @brief TODO
  624. *
  625. */
  626. static char *_per_user_relative_directory(void)
  627. {
  628. return _strdup_or_NULL(PER_USER_DIRECTORY);
  629. }
  630. /**
  631. * @internal
  632. *
  633. * <!-- _per_user_directory() -->
  634. *
  635. * @brief TODO
  636. *
  637. */
  638. static char *_per_user_directory(void)
  639. {
  640. char *path = NULL;
  641. const char *home = NULL;
  642. #ifndef NDEBUG
  643. home = getenv("PEP_HOME");
  644. if (!home)
  645. #endif
  646. home = getenv("HOME");
  647. assert(home);
  648. if (!home)
  649. return NULL;
  650. path = strdup(home);
  651. assert(path);
  652. if (!path)
  653. return NULL;
  654. char *_path = _stradd(&path, "/");
  655. if (!_path)
  656. goto error;
  657. _path = _stradd(&path, PER_USER_DIRECTORY);
  658. if (!_path)
  659. goto error;
  660. return path;
  661. error:
  662. _empty(&path);
  663. return NULL;
  664. }
  665. char *_unix_local_db(void)
  666. {
  667. char* path = (char *) _per_user_directory() /* This memory is not shared. */;
  668. if (!path)
  669. return NULL;
  670. char *path_c = NULL;
  671. char *old_path = NULL;
  672. char *old_path_c = NULL;
  673. struct stat dir;
  674. int r = stat(path, &dir);
  675. if (r) {
  676. if (errno == ENOENT) {
  677. // directory does not yet exist
  678. r = mkdir(path, 0700);
  679. if (r)
  680. goto error;
  681. }
  682. else {
  683. goto error;
  684. }
  685. }
  686. char *_path = _stradd(&path, "/");
  687. if (!_path)
  688. goto error;
  689. // make a copy of this path in case we need to move files
  690. path_c = strdup(path);
  691. assert(path_c);
  692. if (!path_c)
  693. goto error;
  694. _path = _stradd(&path, LOCAL_DB_FILENAME);
  695. if (!_path)
  696. goto error;
  697. struct stat file;
  698. r = stat(path, &file);
  699. if (r) {
  700. if (errno == ENOENT) {
  701. // we do not have management.db yet, let's test if we need to move
  702. // one with the old name
  703. const char *home = NULL;
  704. #ifndef NDEBUG
  705. home = getenv("PEP_HOME");
  706. if (!home)
  707. #endif
  708. home = getenv("HOME");
  709. // we were already checking for HOME existing, so this is only a
  710. // safeguard
  711. assert(home);
  712. old_path = strdup(home);
  713. assert(old_path);
  714. if (!old_path)
  715. goto error;
  716. char *_old_path = _stradd(&old_path, "/");
  717. if (!_old_path)
  718. goto error;
  719. old_path_c = strdup(old_path);
  720. assert(old_path_c);
  721. if (!old_path_c)
  722. goto error;
  723. _old_path = _stradd(&old_path, OLD_LOCAL_DB_FILENAME);
  724. if (!_old_path)
  725. goto error;
  726. struct stat old;
  727. r = stat(old_path, &old);
  728. if (r == 0) {
  729. // old file existing, new file not yet existing, move
  730. rename(old_path, path);
  731. // if required move associated files, too
  732. _move(old_path, "-shm", path);
  733. _move(old_path, "-wal", path);
  734. // move keys database
  735. _old_path = _stradd(&old_path_c, OLD_KEYS_DB_FILENAME);
  736. if (!_old_path)
  737. goto error;
  738. _path = _stradd(&path_c, KEYS_DB_FILENAME);
  739. if (!_path)
  740. goto error;
  741. rename(old_path_c, path_c);
  742. // if required move associated files, too
  743. _move(old_path_c, "-shm", path_c);
  744. _move(old_path_c, "-wal", path_c);
  745. }
  746. }
  747. else {
  748. goto error;
  749. }
  750. }
  751. goto the_end;
  752. error:
  753. _empty(&path);
  754. the_end:
  755. free(path_c);
  756. free(old_path);
  757. free(old_path_c);
  758. return path;
  759. }
  760. static char *_per_machine_directory(void) {
  761. return _strdup_or_NULL(PER_MACHINE_DIRECTORY);
  762. }
  763. char *_unix_system_db(void)
  764. {
  765. char *path = NULL;
  766. path = _per_machine_directory() /* Use this fresh copy. */;
  767. assert(path);
  768. if (!path)
  769. return NULL;
  770. char *_path = _stradd(&path, "/");
  771. if (!_path)
  772. goto error;
  773. _path = _stradd(&path, SYSTEM_DB_FILENAME);
  774. if (!_path)
  775. goto error;
  776. return path;
  777. error:
  778. _empty(&path);
  779. return NULL;
  780. }