ENGINE-524: user_ and machine_directory ENGINE-524
authorClaudio Luck <claudio.luck@pep.foundation>
Sat, 25 May 2019 01:50:29 +0200
branchENGINE-524
changeset 3836f7ec3ffc9487
parent 3740 248166aa4ab2
child 3837 28c820987e41
ENGINE-524: user_ and machine_directory
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/pgp_sequoia.c
src/platform_unix.c
src/platform_unix.h
     1.1 --- a/src/pEpEngine.c	Thu May 23 13:27:34 2019 +0200
     1.2 +++ b/src/pEpEngine.c	Sat May 25 01:50:29 2019 +0200
     1.3 @@ -780,17 +780,20 @@
     1.4  PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session);
     1.5  #endif // USE_GPG
     1.6  
     1.7 -DYNAMIC_API PEP_STATUS init(
     1.8 +DYNAMIC_API PEP_STATUS init_with_paths(
     1.9          PEP_SESSION *session,
    1.10 +        const char *machine_directory,
    1.11 +        const char *user_directory,
    1.12          messageToSend_t messageToSend,
    1.13          inject_sync_event_t inject_sync_event
    1.14      )
    1.15  {
    1.16      PEP_STATUS status = PEP_STATUS_OK;
    1.17      int int_result;
    1.18 -    
    1.19 +
    1.20      bool in_first = false;
    1.21      bool very_first = false;
    1.22 +    const char *db_file = NULL;
    1.23  
    1.24      assert(sqlite3_threadsafe());
    1.25      if (!sqlite3_threadsafe())
    1.26 @@ -804,7 +807,7 @@
    1.27      int _count = ++init_count;
    1.28      if (_count == 0)
    1.29          in_first = true;
    1.30 -    
    1.31 +
    1.32      // Race condition mitigated by calling caveat starts here :
    1.33      // If another call to init() preempts right now, then preemptive call
    1.34      // will have in_first false, will not create SQL tables, and following
    1.35 @@ -834,22 +837,28 @@
    1.36      _session->messageToSend = messageToSend;
    1.37      _session->inject_sync_event = inject_sync_event;
    1.38  
    1.39 +    if (user_directory)
    1.40 +        if (!(_session->user_directory = strndup (user_directory, PEP_MAX_PATH)))
    1.41 +            goto enomem;
    1.42 +    if (machine_directory)
    1.43 +        if (!(_session->machine_directory = strndup (machine_directory, PEP_MAX_PATH)))
    1.44 +            goto enomem;
    1.45 +
    1.46  #ifdef DEBUG_ERRORSTACK
    1.47      _session->errorstack = new_stringlist("init()");
    1.48  #endif
    1.49  
    1.50 -    assert(LOCAL_DB);
    1.51 -    if (LOCAL_DB == NULL) {
    1.52 -        status = PEP_INIT_CANNOT_OPEN_DB;
    1.53 +    status = unix_user_file_path(_session, LOCAL_DB_FILENAME, &db_file);
    1.54 +    if (status != PEP_STATUS_OK)
    1.55          goto pEp_error;
    1.56 -    }
    1.57 -    
    1.58 +    assert(db_file);
    1.59 +
    1.60  #if _PEP_SQLITE_DEBUG    
    1.61      sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
    1.62  #endif
    1.63  
    1.64      int_result = sqlite3_open_v2(
    1.65 -            LOCAL_DB,
    1.66 +            db_file,
    1.67              &_session->db,
    1.68              SQLITE_OPEN_READWRITE
    1.69                  | SQLITE_OPEN_CREATE
    1.70 @@ -857,18 +866,14 @@
    1.71                  | SQLITE_OPEN_PRIVATECACHE,
    1.72              NULL 
    1.73          );
    1.74 +    free(db_file);
    1.75 +    db_file = NULL;
    1.76  
    1.77      if (int_result != SQLITE_OK) {
    1.78          status = PEP_INIT_CANNOT_OPEN_DB;
    1.79          goto pEp_error;
    1.80      }
    1.81  
    1.82 -    assert(LOCAL_KEYS_DB);
    1.83 -    if (LOCAL_KEYS_DB == NULL) {
    1.84 -        status = PEP_INIT_CANNOT_OPEN_DB;
    1.85 -        goto pEp_error;
    1.86 -    }
    1.87 -
    1.88      int_result = sqlite3_exec(
    1.89              _session->db,
    1.90              "PRAGMA locking_mode=NORMAL;\n"
    1.91 @@ -888,19 +893,21 @@
    1.92          NULL);
    1.93  #endif
    1.94  
    1.95 -    assert(SYSTEM_DB);
    1.96 -    if (SYSTEM_DB == NULL) {
    1.97 -        status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
    1.98 +    status = unix_machine_file_path(_session, SYSTEM_DB_FILENAME, &db_file);
    1.99 +    if (status != PEP_STATUS_OK)
   1.100          goto pEp_error;
   1.101 -    }
   1.102 +    assert(db_file);
   1.103  
   1.104      int_result = sqlite3_open_v2(
   1.105 -            SYSTEM_DB, &_session->system_db,
   1.106 +            db_file,
   1.107 +            &_session->system_db,
   1.108              SQLITE_OPEN_READONLY
   1.109                  | SQLITE_OPEN_FULLMUTEX
   1.110                  | SQLITE_OPEN_SHAREDCACHE,
   1.111              NULL
   1.112          );
   1.113 +    free(db_file);
   1.114 +    db_file = NULL;
   1.115  
   1.116      if (int_result != SQLITE_OK) {
   1.117          status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   1.118 @@ -1988,6 +1995,15 @@
   1.119      }
   1.120  }
   1.121  
   1.122 +DYNAMIC_API PEP_STATUS init(
   1.123 +        PEP_SESSION *session,
   1.124 +        messageToSend_t messageToSend,
   1.125 +        inject_sync_event_t inject_sync_event
   1.126 +    )
   1.127 +{
   1.128 +    return init_with_paths(session, NULL, NULL, messageToSend, inject_sync_event);
   1.129 +}
   1.130 +
   1.131  DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
   1.132  {
   1.133      assert(session);
     2.1 --- a/src/pEpEngine.h	Thu May 23 13:27:34 2019 +0200
     2.2 +++ b/src/pEpEngine.h	Sat May 25 01:50:29 2019 +0200
     2.3 @@ -178,6 +178,34 @@
     2.4  //                                          application
     2.5  //      inject_sync_event (in)              callback for injecting a sync event
     2.6  //
     2.7 +//  caveat:
     2.8 +//      THE CALLER MUST GUARD THIS CALL EXTERNALLY WITH A MUTEX. release()
     2.9 +//      should be similarly guarded.
    2.10 +//
    2.11 +//      This function is a wrapper for init_with_paths(),
    2.12 +//      with passes NULL machine_directory and user_directory.
    2.13 +
    2.14 +
    2.15 +DYNAMIC_API PEP_STATUS init(
    2.16 +        PEP_SESSION *session,
    2.17 +        messageToSend_t messageToSend,
    2.18 +        inject_sync_event_t inject_sync_event
    2.19 +    );
    2.20 +
    2.21 +
    2.22 +// INIT_STATUS init_with_paths() - initialize pEpEngine for a thread on alternate directories
    2.23 +//
    2.24 +//  parameters:
    2.25 +//      session (out)                       init() allocates session memory and
    2.26 +//                                          returns a pointer as a handle
    2.27 +//      machine_directory (in)              non-default machine directory
    2.28 +//                                          (NULL for automatic platform specific defaults)
    2.29 +//      user_directory (in)                 non-default user directory
    2.30 +//                                          (NULL for automatic platform specific defaults)
    2.31 +//      messageToSend (in)                  callback for sending message by the
    2.32 +//                                          application
    2.33 +//      inject_sync_event (in)              callback for injecting a sync event
    2.34 +//
    2.35  //  return value:
    2.36  //      PEP_STATUS_OK = 0                   if init() succeeds
    2.37  //      PEP_INIT_SQLITE3_WITHOUT_MUTEX      if SQLite3 was compiled with
    2.38 @@ -203,11 +231,14 @@
    2.39  //      messageToSend can only be null if no transport is application based
    2.40  //      if transport system is not used it must not be NULL
    2.41  
    2.42 -DYNAMIC_API PEP_STATUS init(
    2.43 +DYNAMIC_API PEP_STATUS init_with_paths(
    2.44          PEP_SESSION *session,
    2.45 +        const char *machine_directory,
    2.46 +        const char *user_directory,
    2.47          messageToSend_t messageToSend,
    2.48          inject_sync_event_t inject_sync_event
    2.49 -    );
    2.50 +);
    2.51 +
    2.52  
    2.53  
    2.54  // void release() - release thread session handle
     3.1 --- a/src/pEp_internal.h	Thu May 23 13:27:34 2019 +0200
     3.2 +++ b/src/pEp_internal.h	Sat May 25 01:50:29 2019 +0200
     3.3 @@ -54,6 +54,14 @@
     3.4  
     3.5  #include "platform.h"
     3.6  
     3.7 +#ifndef LOCAL_DB_FILENAME
     3.8 +#define LOCAL_DB_FILENAME "management.db"
     3.9 +#endif
    3.10 +#define SYSTEM_DB_FILENAME "system.db"
    3.11 +#ifndef SYSTEM_DB_PREFIX
    3.12 +#define SYSTEM_DB_PREFIX "/usr/local/share/pEp"     /* package maintainers please override this */
    3.13 +#endif
    3.14 +
    3.15  #ifdef WIN32
    3.16  #define LOCAL_DB windoze_local_db()
    3.17  #define LOCAL_KEYS_DB windoze_local_db()
    3.18 @@ -62,20 +70,6 @@
    3.19  #else // UNIX
    3.20  #define _POSIX_C_SOURCE 200809L
    3.21  #include <dlfcn.h>
    3.22 -#ifdef NDEBUG
    3.23 -#define LOCAL_DB unix_local_db()
    3.24 -#define LOCAL_KEYS_DB unix_local_keys_db()
    3.25 -#else
    3.26 -#define LOCAL_DB unix_local_db(false)
    3.27 -#define LOCAL_KEYS_DB unix_local_keys_db(false)
    3.28 -#endif
    3.29 -#ifndef SYSTEM_DB
    3.30 -#ifdef NDEBUG
    3.31 -#define SYSTEM_DB unix_system_db()
    3.32 -#else
    3.33 -#define SYSTEM_DB unix_system_db(false)
    3.34 -#endif
    3.35 -#endif
    3.36  #ifndef LIBGPGME
    3.37  #define LIBGPGME "libgpgme-pthread.so"
    3.38  #endif
    3.39 @@ -159,6 +153,9 @@
    3.40  
    3.41      PEP_transport_t *transports;
    3.42  
    3.43 +    const char *user_directory;
    3.44 +    const char *machine_directory;
    3.45 +
    3.46      sqlite3 *db;
    3.47      sqlite3 *system_db;
    3.48  
     4.1 --- a/src/pgp_sequoia.c	Thu May 23 13:27:34 2019 +0200
     4.2 +++ b/src/pgp_sequoia.c	Sat May 25 01:50:29 2019 +0200
     4.3 @@ -5,8 +5,9 @@
     4.4  
     4.5  #define _GNU_SOURCE 1
     4.6  
     4.7 -#define MAX_PATH 1024
     4.8 +#ifndef SQ_KEYS_DB
     4.9  #define SQ_KEYS_DB "keys.db"
    4.10 +#endif
    4.11  
    4.12  #include "pEp_internal.h"
    4.13  #include "pgp_gpg.h"
    4.14 @@ -179,20 +180,24 @@
    4.15  PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    4.16  {
    4.17      PEP_STATUS status = PEP_STATUS_OK;
    4.18 -
    4.19 -    char path[MAX_PATH];
    4.20 -    if ((status = unix_local_db_file(path, SQ_KEYS_DB)) != PEP_STATUS_OK)
    4.21 +    const char * path_keys_db;
    4.22 +
    4.23 +    status = unix_user_file_path(session, "keys.db", &path_keys_db);
    4.24 +    if (status != PEP_STATUS_OK)
    4.25          ERROR_OUT(NULL, status,
    4.26                    "could not determine path to keys DB");
    4.27 +    assert(path_local_db);
    4.28  
    4.29      int sqlite_result;
    4.30 -    sqlite_result = sqlite3_open_v2(path,
    4.31 +    sqlite_result = sqlite3_open_v2(path_keys_db,
    4.32                                      &session->key_db,
    4.33                                      SQLITE_OPEN_READWRITE
    4.34                                      | SQLITE_OPEN_CREATE
    4.35                                      | SQLITE_OPEN_FULLMUTEX
    4.36                                      | SQLITE_OPEN_PRIVATECACHE,
    4.37                                      NULL);
    4.38 +    free(path_keys_db);
    4.39 +    path_keys_db = NULL;
    4.40  
    4.41      if (sqlite_result != SQLITE_OK)
    4.42          ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
     5.1 --- a/src/platform_unix.c	Thu May 23 13:27:34 2019 +0200
     5.2 +++ b/src/platform_unix.c	Sat May 25 01:50:29 2019 +0200
     5.3 @@ -9,6 +9,7 @@
     5.4  #endif
     5.5  #endif
     5.6  
     5.7 +#include <assert.h>
     5.8  #include <time.h>
     5.9  #include <string.h>
    5.10  #include <stdlib.h>
    5.11 @@ -19,20 +20,9 @@
    5.12  #include <fcntl.h>
    5.13  #include <regex.h>
    5.14  
    5.15 +#include "pEp_internal.h"
    5.16  #include "platform_unix.h"
    5.17  
    5.18 -#define MAX_PATH 1024
    5.19 -#ifndef LOCAL_DB_FILENAME
    5.20 -#define LOCAL_DB_FILENAME "management.db"      /* ".pEp_" prefix now added in *_local_db() */
    5.21 -#endif
    5.22 -#ifndef LOCAL_KEYS_DB_FILENAME
    5.23 -#define LOCAL_KEYS_DB_FILENAME "keys.db"
    5.24 -#endif
    5.25 -#define SYSTEM_DB_FILENAME "system.db"
    5.26 -#ifndef SYSTEM_DB_PREFIX
    5.27 -#define SYSTEM_DB_PREFIX "/usr/local/share/pEp"
    5.28 -#endif
    5.29 -
    5.30  #ifndef bool
    5.31  #define bool int
    5.32  #define true 1
    5.33 @@ -103,14 +93,14 @@
    5.34  
    5.35  const char *android_system_db(void)
    5.36  {
    5.37 -    static char buffer[MAX_PATH];
    5.38 +    static char buffer[PEP_MAX_PATH];
    5.39      static bool done = false;
    5.40  
    5.41      if (!done) {
    5.42          char *tw_env;
    5.43          if(tw_env = getenv("TRUSTWORDS")){
    5.44 -            char *p = stpncpy(buffer, tw_env, MAX_PATH);
    5.45 -            ssize_t len = MAX_PATH - (p - buffer) - 2;
    5.46 +            char *p = stpncpy(buffer, tw_env, PEP_MAX_PATH);
    5.47 +            ssize_t len = PEP_MAX_PATH - (p - buffer) - 2;
    5.48  
    5.49              if (len < strlen(SYSTEM_DB_FILENAME)) {
    5.50                  assert(0);
    5.51 @@ -176,60 +166,63 @@
    5.52  
    5.53  #endif
    5.54  
    5.55 -#ifdef NDEBUG
    5.56 -const char *unix_system_db(void)
    5.57 -#else
    5.58 -const char *unix_system_db(int reset)
    5.59 -#endif
    5.60 +PEP_STATUS unix_machine_file_path(PEP_SESSION session, const char *fname, char **path)
    5.61  {
    5.62 -    static char buffer[MAX_PATH];
    5.63 -    static bool done = false;
    5.64 +    assert(session);
    5.65 +    assert(fname);
    5.66  
    5.67 -    #ifdef NDEBUG
    5.68 -    if (!done)
    5.69 -    #else
    5.70 -    if ((!done) || reset)
    5.71 -    #endif
    5.72 -    {
    5.73 -        const char *home_env;
    5.74 -        const char *subdir;
    5.75 -        const char * const confvars[] = { "TRUSTWORDS", "PEP_HOME", "PEPHOME", NULL,             "HOME",   NULL };
    5.76 -        const char * const confvals[] = { NULL,         NULL,       NULL,      SYSTEM_DB_PREFIX, NULL,     NULL };
    5.77 -        const char * const confsdir[] = { "/",          "/",        "/",       "/",              "/.pEp/", NULL };
    5.78 -        const bool automkdir[]        = { false,        true,       true,      false,            true,     false }; // use this on dirs only!
    5.79 -        const bool enforceifset[]     = { true,         false,      false,     false,            false,    false };
    5.80 -        int cf_i;
    5.81 +    const char buffer[PEP_MAX_PATH];
    5.82 +    const char *s_dir = session->machine_directory;
    5.83 +    size_t f_len = strlen (fname);
    5.84  
    5.85 -        for (cf_i = 0; confvars[cf_i] || confvals[cf_i]; cf_i++) {
    5.86 -            if (((home_env = confvals[cf_i]) || (home_env = getenv (confvars[cf_i]))) && (subdir = confsdir[cf_i])) {
    5.87 -                char *p = stpncpy (buffer, home_env, MAX_PATH);
    5.88 -                ssize_t len = MAX_PATH - (p - buffer) - 2;
    5.89 +    const char * const confvars[] = { NULL,   "PER_MACHINE_DIRECTORY", "TRUSTWORDS", "PEP_HOME", "PEPHOME", NULL,            "HOME",    NULL };
    5.90 +    const char * const confvals[] = { s_dir,   NULL,                   NULL,         NULL,       NULL,      SYSTEM_DB_PREFIX, NULL,     NULL };
    5.91 +    const char * const confsdir[] = { "/",     "/",                    "/",          "/",        "/",       "/",              "/.pEp/", NULL };
    5.92 +    const bool automkdir[]        = { false,   true,                   false,        true,       true,      false,            true,     false }; // use this on dirs only!
    5.93 +    const bool enforceifset[]     = { true,    false,                  true,         false,      false,     false,            false,    false };
    5.94 +    const bool deprecated[]       = { false,   false,                  true,         true,       true,      true,             true,     false };
    5.95 +    const char *home_env;
    5.96 +    int cf_i;
    5.97 +    char *p;
    5.98  
    5.99 -                if (len < strlen (SYSTEM_DB_FILENAME) + strlen (confsdir[cf_i])) {
   5.100 -                    assert(0);
   5.101 -                    return NULL;
   5.102 +    for (cf_i = 0; confvars[cf_i] || confvals[cf_i] || confsdir[cf_i]; cf_i++) {
   5.103 +        if (((home_env = confvals[cf_i]) || (confvars[cf_i] && (home_env = getenv (confvars[cf_i])))) && (confsdir[cf_i])) {
   5.104 +
   5.105 +            if (confvars[cf_i] && deprecated[cf_i]) {
   5.106 +                printf("%s: the environment variable '%s' is deprecated, please use PER_MACHINE_DIRECTORY instead.\n", fname, confvars[cf_i]);
   5.107 +            }
   5.108 +
   5.109 +            p = stpncpy (buffer, home_env, PEP_MAX_PATH);
   5.110 +            ssize_t len = PEP_MAX_PATH - (p - buffer) - 2;
   5.111 +
   5.112 +            if (len < f_len + strlen (confsdir[cf_i])) {
   5.113 +                assert(0);
   5.114 +                return PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   5.115 +            }
   5.116 +
   5.117 +            while (*(p-1) == '/' && (p-1) > buffer)   /* drop trailing slashes, note '>' on decremented p */
   5.118 +                p--;
   5.119 +            p = stpncpy (p, confsdir[cf_i], len);
   5.120 +            if (automkdir[cf_i]) {
   5.121 +                if (mkdir (buffer, S_IRUSR | S_IWUSR | S_IXUSR) != 0 && errno != EEXIST) {
   5.122 +                    perror (buffer);
   5.123 +                    return PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   5.124                  }
   5.125 +            }
   5.126  
   5.127 -                p = stpncpy(p, confsdir[cf_i], len);
   5.128 -                if (automkdir[cf_i]) {
   5.129 -                    if (mkdir(buffer, S_IRUSR | S_IWUSR | S_IXUSR) != 0 && errno != EEXIST) {
   5.130 -                        perror(SYSTEM_DB_FILENAME);
   5.131 -                        return false;
   5.132 -                    }
   5.133 -                }
   5.134 -
   5.135 -                strncpy(p, SYSTEM_DB_FILENAME, len);
   5.136 -                if (access (buffer, R_OK) == 0) {
   5.137 -                    done = true;
   5.138 -                    return buffer;
   5.139 -                }
   5.140 -                else if (enforceifset[cf_i])
   5.141 -                    return NULL;
   5.142 +            strncpy (p, fname, len);
   5.143 +            if (access (buffer, R_OK) == 0) {
   5.144 +                *path = strndup (buffer, PEP_MAX_PATH);
   5.145 +                if (!*path)
   5.146 +                    return PEP_OUT_OF_MEMORY;
   5.147 +                return PEP_STATUS_OK;
   5.148 +            }
   5.149 +            else if (enforceifset[cf_i]) {
   5.150 +                return PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   5.151              }
   5.152          }
   5.153 -        return NULL;
   5.154      }
   5.155 -    return buffer;
   5.156 +    return PEP_UNKNOWN_DB_ERROR;
   5.157  }
   5.158  
   5.159  #if !defined(BSD) && !defined(__APPLE__)
   5.160 @@ -271,53 +264,55 @@
   5.161  
   5.162  #endif
   5.163  
   5.164 -#ifdef NDEBUG
   5.165 -PEP_STATUS unix_local_db_file(const char *buffer, const char *fname)
   5.166 -#else
   5.167 -PEP_STATUS unix_local_db_file(const char *buffer, const char *fname, int reset)
   5.168 -#endif
   5.169 +PEP_STATUS unix_user_file_path(PEP_SESSION session, const char *fname, char **path)
   5.170  {
   5.171 -    /*
   5.172 -     * TODO: move this to libpEpAdapter and create an have an export symbol here only.
   5.173 -     */
   5.174 +    assert(session);
   5.175 +    assert(fname);
   5.176 +
   5.177 +    const char buffer[PEP_MAX_PATH];
   5.178 +    const char *s_dir = session->user_directory;
   5.179 +    size_t f_len = strlen (fname);
   5.180 +
   5.181 +    /* Note: in HOME, a dot and pEp_ is prepended to the file (~/.pEp_management.db, vs ~/.pEp/management.db) */
   5.182 +    const char * const confvars[] = { NULL,  "PER_USER_DIRECTORY", "PEP_HOME", "PEPHOME", "HOME",   "HOME",    NULL };
   5.183 +    const char * const confvals[] = { s_dir,  NULL,                 NULL,       NULL,      NULL,     NULL,     NULL };
   5.184 +    const char * const confsdir[] = { "/",    "/",                  "/",        "/",       "/.pEp_", "/.pEp/", NULL };
   5.185 +    const bool automkdir[]        = { false,  true,                 true,       true,      false,    true,     false }; // use this on dirs only!
   5.186 +    const bool enforceifset[]     = { true,   true,                 true,       true,      false,    true,     false };
   5.187 +    const bool deprecated[]       = { false,  false,                true,       true,      false,    false,    false };
   5.188      const char *home_env;
   5.189 -    const char *subdir;
   5.190 -    /* Note: in HOME, a dot and pEp_ is prepended to the file (~/.pEp_management.db, vs ~/.pEp/management.db) */
   5.191 -    const char * const confvars[] = { "PEP_HOME", "PEPHOME", "HOME",   "HOME",   NULL };
   5.192 -    const char * const confvals[] = { NULL,       NULL,      NULL,     NULL,     NULL };
   5.193 -    const char * const confsdir[] = { "/",        "/",       "/.pEp_", "/.pEp/", NULL };
   5.194 -    const bool automkdir[]        = { true,       true,      false,    true,     false }; // use this on dirs only!
   5.195 -    const bool debugonly[]        = { true,       true,      false,    false,    false };
   5.196 -    const bool enforceifset[]     = { true,       true,      false,    true,     false };
   5.197      int cf_i;
   5.198 +    ssize_t len;
   5.199 +    char *p;
   5.200  
   5.201 -    for (cf_i = 0; confvars[cf_i] || confvals[cf_i]; cf_i++) {
   5.202 -        if (((home_env = confvals[cf_i]) || (home_env = getenv (confvars[cf_i]))) && (subdir = confsdir[cf_i])) {
   5.203 -            char *p = stpncpy (buffer, home_env, MAX_PATH);
   5.204 -            ssize_t len = MAX_PATH - (p - buffer) - 1;
   5.205 +    for (cf_i = 0; confvars[cf_i] || confvals[cf_i] || confsdir[cf_i]; cf_i++) {
   5.206 +        if (((home_env = confvals[cf_i]) || (confvars[cf_i] && (home_env = getenv (confvars[cf_i])))) && (confsdir[cf_i])) {
   5.207  
   5.208 -            if (len < strlen (fname) + strlen (confsdir[cf_i])) {
   5.209 +            if (confvars[cf_i] && deprecated[cf_i]) {
   5.210 +                printf("%s: the environment variable '%s' is deprecated, please use PER_USER_DIRECTORY instead.\n", fname, confvars[cf_i]);
   5.211 +            }
   5.212 +
   5.213 +            p = stpncpy (buffer, home_env, PEP_MAX_PATH);
   5.214 +            len = PEP_MAX_PATH - (p - buffer) - 1;
   5.215 +
   5.216 +            if (len < f_len + strlen (confsdir[cf_i])) {
   5.217                  assert(0);
   5.218                  return PEP_OUT_OF_MEMORY;
   5.219              }
   5.220  
   5.221 -#ifdef NDEBUG
   5.222 -            if (debugonly[cf_i] && enforceifset[cf_i]) {
   5.223 -                printf("WARNING: Variable '%s' MUST NOT be used in production!\n", confvars[cf_i]);
   5.224 -                // return PEP_INIT_CANNOT_OPEN_DB;
   5.225 -            }
   5.226 -#endif
   5.227 -
   5.228              p = stpncpy(p, confsdir[cf_i], len);
   5.229              if (automkdir[cf_i]) {
   5.230 -                if (mkdir(buffer, S_IRUSR | S_IWUSR | S_IXUSR) != 0 && errno != EEXIST) {
   5.231 -                    printf("ERROR: mkdir '%s' FAIL %d\n", confvals[cf_i], errno);
   5.232 +                if (mkdir (buffer, S_IRUSR | S_IWUSR | S_IXUSR) != 0 && errno != EEXIST) {
   5.233 +                    perror (buffer);
   5.234                      return PEP_INIT_CANNOT_OPEN_DB;
   5.235                  }
   5.236              }
   5.237  
   5.238              strncpy(p, fname, len);
   5.239              if (enforceifset[cf_i] || (access (buffer, R_OK) == 0)) {
   5.240 +                *path = strndup (buffer, PEP_MAX_PATH);
   5.241 +                if (!*path)
   5.242 +                    return PEP_OUT_OF_MEMORY;
   5.243                  return PEP_STATUS_OK;
   5.244              }
   5.245          }
   5.246 @@ -325,52 +320,6 @@
   5.247      return PEP_UNKNOWN_DB_ERROR;
   5.248  }
   5.249  
   5.250 -#ifdef NDEBUG
   5.251 -const char *unix_local_db(void)
   5.252 -#else
   5.253 -const char *unix_local_db(int reset)
   5.254 -#endif
   5.255 -{
   5.256 -    static char buffer[MAX_PATH];
   5.257 -    static bool done = false;
   5.258 -
   5.259 -    #ifdef NDEBUG
   5.260 -    if (!done)
   5.261 -        done = (PEP_STATUS_OK == unix_local_db_file(buffer, LOCAL_DB_FILENAME));
   5.262 -    #else
   5.263 -    if ((!done) || reset)
   5.264 -        done = (PEP_STATUS_OK == unix_local_db_file(buffer, LOCAL_DB_FILENAME, reset));
   5.265 -    #endif
   5.266 -
   5.267 -    if (done)
   5.268 -        return buffer;
   5.269 -    return NULL;
   5.270 -}
   5.271 -
   5.272 -#ifdef NDEBUG
   5.273 -const char *unix_local_keys_db(void)
   5.274 -#else
   5.275 -const char *unix_local_keys_db(int reset)
   5.276 -#endif
   5.277 -{
   5.278 -    static char buffer[MAX_PATH];
   5.279 -    static bool done = false;
   5.280 -
   5.281 -    #ifdef NDEBUG
   5.282 -    if (!done)
   5.283 -        done = (PEP_STATUS_OK == unix_local_db_file(buffer, LOCAL_KEYS_DB_FILENAME));
   5.284 -    #else
   5.285 -    if ((!done) || reset)
   5.286 -        done = (PEP_STATUS_OK == unix_local_db_file(buffer, LOCAL_KEYS_DB_FILENAME, reset));
   5.287 -    #endif
   5.288 -
   5.289 -    if (done) {
   5.290 -        return buffer;
   5.291 -    }
   5.292 -    return NULL;
   5.293 -}
   5.294 -
   5.295 -
   5.296  static const char *gpg_conf_path = ".gnupg";
   5.297  static const char *gpg_conf_name = "gpg.conf";
   5.298  static const char *gpg_agent_conf_name = "gpg-agent.conf";
     6.1 --- a/src/platform_unix.h	Thu May 23 13:27:34 2019 +0200
     6.2 +++ b/src/platform_unix.h	Sat May 25 01:50:29 2019 +0200
     6.3 @@ -22,17 +22,16 @@
     6.4  extern "C" {
     6.5  #endif
     6.6  
     6.7 +#define PEP_MAX_PATH 1024
     6.8 +
     6.9 +PEP_STATUS unix_user_file_path(PEP_SESSION session, const char *fname, char **buffer);
    6.10 +PEP_STATUS unix_machine_file_path(PEP_SESSION session, const char *fname, char **buffer);
    6.11 +
    6.12  #ifdef NDEBUG
    6.13 -int unix_local_db_file(const char *buffer, const char *fname);
    6.14 -const char *unix_local_db(void);
    6.15 -const char *unix_system_db(void);
    6.16  const char *gpg_conf(void);
    6.17  const char *gpg_agent_conf(void);
    6.18  const char *gpg_home(void);
    6.19  #else
    6.20 -int unix_local_db_file(const char *buffer, const char *fname, int reset);
    6.21 -const char *unix_local_db(int reset);
    6.22 -const char *unix_system_db(int reset);
    6.23  const char *gpg_conf(int reset);
    6.24  const char *gpg_agent_conf(int reset);
    6.25  const char *gpg_home(int reset);