src/platform_unix.c
author Edouard Tisserant
Fri, 04 Sep 2015 21:41:11 +0200
changeset 347 098632924bd2
parent 346 68a5a5e22905
child 349 9d03512b1556
permissions -rw-r--r--
Locate system.db given by android, using SAFEWORDS env var
vb@1
     1
#define _POSIX_C_SOURCE 200809L
vb@1
     2
vb@1
     3
#include <string.h>
vb@1
     4
#include <stdlib.h>
vb@1
     5
#include <assert.h>
Edouard@158
     6
#include <sys/stat.h>
vb@149
     7
#include <sys/types.h>
Edouard@158
     8
#include <fcntl.h>
Edouard@158
     9
vb@1
    10
#include "platform_unix.h"
vb@1
    11
vb@1
    12
#define MAX_PATH 1024
vb@1
    13
#define LOCAL_DB_FILENAME ".pEp_management.db"
Edouard@347
    14
#define SYSTEM_DB_FILENAME "system.db"
vb@1
    15
vb@1
    16
#ifndef bool
vb@1
    17
#define bool int
vb@1
    18
#define true 1
vb@1
    19
#define false 0
vb@1
    20
#endif
vb@1
    21
Edouard@347
    22
#ifdef ANDROID
Edouard@347
    23
char *stpncpy(char *dst, const char *src, size_t n)
Edouard@333
    24
{
Edouard@333
    25
    if (n != 0) {
Edouard@333
    26
        char *d = dst;
Edouard@333
    27
        const char *s = src;
Edouard@333
    28
Edouard@333
    29
        dst = &dst[n];
Edouard@333
    30
        do {
Edouard@333
    31
            if ((*d++ = *s++) == 0) {
Edouard@333
    32
                dst = d - 1;
Edouard@333
    33
                /* NUL pad the remaining n-1 bytes */
Edouard@333
    34
                while (--n != 0)
Edouard@333
    35
                    *d++ = 0;
Edouard@333
    36
                break;
Edouard@333
    37
            }
Edouard@333
    38
        } while (--n != 0);
Edouard@333
    39
    }
Edouard@333
    40
    return (dst);
Edouard@333
    41
}
Edouard@333
    42
Edouard@338
    43
char *stpcpy(char *dst, const char *src)
Edouard@338
    44
{
Edouard@338
    45
    for (;; ++dst, ++src) {
Edouard@338
    46
        *dst = *src;
Edouard@338
    47
        if (*dst == 0)
Edouard@338
    48
            break;
Edouard@338
    49
    }
Edouard@338
    50
    return dst;
Edouard@338
    51
}
Edouard@338
    52
Edouard@338
    53
long int random(void){
Edouard@338
    54
  unsigned short xsubi[3] = {'p', 'E', 'p'};
Edouard@338
    55
  return nrand48(xsubi);
Edouard@338
    56
}
Edouard@347
    57
Edouard@347
    58
const char *android_system_db(void)
Edouard@347
    59
{
Edouard@347
    60
    static char buffer[MAX_PATH];
Edouard@347
    61
    static bool done = false;
Edouard@347
    62
Edouard@347
    63
    if (!done) {
Edouard@347
    64
        char *sw_env;
Edouard@347
    65
        if(sw_env = getenv("SAFEWORDS")){
Edouard@347
    66
            char *p = stpncpy(buffer, sw_env, MAX_PATH);
Edouard@347
    67
            size_t len = MAX_PATH - (p - buffer) - 2;
Edouard@347
    68
Edouard@347
    69
            if (len < strlen(SYSTEM_DB_FILENAME)) {
Edouard@347
    70
                assert(0);
Edouard@347
    71
                return NULL;
Edouard@347
    72
            }
Edouard@347
    73
Edouard@347
    74
            *p++ = '/';
Edouard@347
    75
            strncpy(p, SYSTEM_DB_FILENAME, len);
Edouard@347
    76
            done = true;
Edouard@347
    77
        }else{
Edouard@347
    78
            return NULL;
Edouard@347
    79
        }
Edouard@347
    80
Edouard@347
    81
    }
Edouard@347
    82
    return buffer;
Edouard@347
    83
}
Edouard@338
    84
#endif
Edouard@338
    85
vb@1
    86
const char *unix_local_db(void)
vb@1
    87
{
vb@1
    88
    static char buffer[MAX_PATH];
vb@1
    89
    static bool done = false;
vb@1
    90
vb@1
    91
    if (!done) {
Edouard@346
    92
        char *home_env;
Edouard@346
    93
        if(home_env = getenv("HOME")){
Edouard@347
    94
            char *p = stpncpy(buffer, home_env, MAX_PATH);
Edouard@346
    95
            size_t len = MAX_PATH - (p - buffer) - 2;
vb@1
    96
Edouard@346
    97
            if (len < strlen(LOCAL_DB_FILENAME)) {
Edouard@346
    98
                assert(0);
Edouard@346
    99
                return NULL;
Edouard@346
   100
            }
Edouard@346
   101
Edouard@346
   102
            *p++ = '/';
Edouard@346
   103
            strncpy(p, LOCAL_DB_FILENAME, len);
Edouard@346
   104
            done = true;
Edouard@346
   105
        }else{
vb@1
   106
            return NULL;
vb@1
   107
        }
vb@1
   108
vb@1
   109
    }
vb@1
   110
    return buffer;
vb@1
   111
}
vb@1
   112
vb@1
   113
static const char *gpg_conf_path = ".gnupg";
vb@1
   114
static const char *gpg_conf_name = "gpg.conf";
Edouard@158
   115
static const char *gpg_conf_empty = "# Created by pEpEngine\n";
vb@1
   116
Edouard@168
   117
static bool ensure_gpg_home(const char **conf, const char **home){
Edouard@168
   118
    static char path[MAX_PATH];
Edouard@158
   119
    static char dirname[MAX_PATH];
vb@1
   120
    static bool done = false;
vb@1
   121
vb@1
   122
    if (!done) {
Edouard@168
   123
        char *p;
Edouard@168
   124
        size_t len;
Edouard@168
   125
        char *gpg_home_env = getenv("GNUPGHOME");
Edouard@346
   126
        char *home_env = getenv("HOME");
Edouard@158
   127
Edouard@168
   128
        if(gpg_home_env){
Edouard@168
   129
Edouard@347
   130
            p = stpncpy(path, gpg_home_env, MAX_PATH);
Edouard@168
   131
            len = MAX_PATH - (p - path) - 2;
Edouard@168
   132
Edouard@158
   133
            if (len < strlen(gpg_conf_name))
Edouard@158
   134
            {
Edouard@158
   135
                assert(0);
Edouard@168
   136
                return false;
Edouard@158
   137
            }
Edouard@158
   138
Edouard@346
   139
        }else if(home_env){
vb@1
   140
Edouard@347
   141
            p = stpncpy(path, home_env, MAX_PATH);
Edouard@168
   142
            len = MAX_PATH - (p - path) - 3;
Edouard@158
   143
Edouard@158
   144
            if (len < strlen(gpg_conf_path) + strlen(gpg_conf_name))
Edouard@158
   145
            {
Edouard@158
   146
                assert(0);
Edouard@168
   147
                return false;
Edouard@158
   148
            }
Edouard@158
   149
Edouard@158
   150
            *p++ = '/';
Edouard@158
   151
            strncpy(p, gpg_conf_path, len);
Edouard@158
   152
            p += strlen(gpg_conf_path);
Edouard@158
   153
            len -= strlen(gpg_conf_path) - 1;
Edouard@346
   154
Edouard@346
   155
        }else{
Edouard@346
   156
Edouard@346
   157
            assert(0);
Edouard@346
   158
            return false;
vb@1
   159
        }
vb@1
   160
Edouard@168
   161
        strncpy(dirname, path, MAX_PATH);
Edouard@168
   162
        *p++ = '/';
Edouard@168
   163
        strncpy(p, gpg_conf_name, len);
Edouard@168
   164
Edouard@168
   165
        if(access(path, F_OK)){ 
Edouard@158
   166
            int fd;
Edouard@158
   167
            if(access(dirname, F_OK )) { 
Edouard@158
   168
                mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR);
Edouard@158
   169
            }
vb@149
   170
Edouard@168
   171
            fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
vb@149
   172
Edouard@158
   173
            if(fd>0) {
Edouard@158
   174
                write(fd, gpg_conf_empty, strlen(gpg_conf_empty));
Edouard@158
   175
                close(fd);
Edouard@158
   176
            }
Edouard@158
   177
        }
vb@1
   178
vb@1
   179
        done = true;
vb@1
   180
    }
Edouard@168
   181
Edouard@168
   182
    if(conf) *conf=path;
Edouard@168
   183
    if(home) *home=dirname;
Edouard@168
   184
Edouard@168
   185
    return true;
vb@1
   186
}
Edouard@168
   187
Edouard@168
   188
const char *gpg_conf(void)
Edouard@168
   189
{
Edouard@168
   190
    const char *conf;
Edouard@168
   191
    if(ensure_gpg_home(&conf, NULL))
Edouard@168
   192
        return conf;
Edouard@168
   193
    return NULL;
Edouard@168
   194
}
Edouard@168
   195
Edouard@168
   196
const char *gpg_home(void)
Edouard@168
   197
{
Edouard@168
   198
    const char *home;
Edouard@168
   199
    if(ensure_gpg_home(NULL, &home))
Edouard@168
   200
        return home;
Edouard@168
   201
    return NULL;
Edouard@168
   202
}