src/platform_unix.c
author Edouard Tisserant
Fri, 21 Aug 2015 17:12:59 +0200
changeset 338 962f6656d2c8
parent 333 77d486037ec9
child 346 68a5a5e22905
permissions -rw-r--r--
Fixes for missing entries in android libc
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"
vb@1
    14
vb@1
    15
#ifndef bool
vb@1
    16
#define bool int
vb@1
    17
#define true 1
vb@1
    18
#define false 0
vb@1
    19
#endif
vb@1
    20
Edouard@333
    21
char *
Edouard@333
    22
local_stpncpy(char *dst, const char *src, size_t n)
Edouard@333
    23
{
Edouard@333
    24
    if (n != 0) {
Edouard@333
    25
        char *d = dst;
Edouard@333
    26
        const char *s = src;
Edouard@333
    27
Edouard@333
    28
        dst = &dst[n];
Edouard@333
    29
        do {
Edouard@333
    30
            if ((*d++ = *s++) == 0) {
Edouard@333
    31
                dst = d - 1;
Edouard@333
    32
                /* NUL pad the remaining n-1 bytes */
Edouard@333
    33
                while (--n != 0)
Edouard@333
    34
                    *d++ = 0;
Edouard@333
    35
                break;
Edouard@333
    36
            }
Edouard@333
    37
        } while (--n != 0);
Edouard@333
    38
    }
Edouard@333
    39
    return (dst);
Edouard@333
    40
}
Edouard@333
    41
Edouard@338
    42
#ifdef ANDROID
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@338
    57
#endif
Edouard@338
    58
vb@1
    59
const char *unix_local_db(void)
vb@1
    60
{
vb@1
    61
    static char buffer[MAX_PATH];
vb@1
    62
    static bool done = false;
vb@1
    63
vb@1
    64
    if (!done) {
Edouard@333
    65
        char *p = local_stpncpy(buffer, getenv("HOME"), MAX_PATH);
vb@1
    66
        size_t len = MAX_PATH - (p - buffer) - 2;
vb@1
    67
vb@1
    68
        if (len < strlen(LOCAL_DB_FILENAME)) {
vb@1
    69
            assert(0);
vb@1
    70
            return NULL;
vb@1
    71
        }
vb@1
    72
vb@1
    73
        *p++ = '/';
vb@1
    74
        strncpy(p, LOCAL_DB_FILENAME, len);
vb@1
    75
        done = true;
vb@1
    76
    }
vb@1
    77
    return buffer;
vb@1
    78
}
vb@1
    79
vb@1
    80
static const char *gpg_conf_path = ".gnupg";
vb@1
    81
static const char *gpg_conf_name = "gpg.conf";
Edouard@158
    82
static const char *gpg_conf_empty = "# Created by pEpEngine\n";
vb@1
    83
Edouard@168
    84
static bool ensure_gpg_home(const char **conf, const char **home){
Edouard@168
    85
    static char path[MAX_PATH];
Edouard@158
    86
    static char dirname[MAX_PATH];
vb@1
    87
    static bool done = false;
vb@1
    88
vb@1
    89
    if (!done) {
Edouard@168
    90
        char *p;
Edouard@168
    91
        size_t len;
Edouard@168
    92
        char *gpg_home_env = getenv("GNUPGHOME");
Edouard@158
    93
Edouard@168
    94
        if(gpg_home_env){
Edouard@168
    95
Edouard@333
    96
            p = local_stpncpy(path, gpg_home_env, MAX_PATH);
Edouard@168
    97
            len = MAX_PATH - (p - path) - 2;
Edouard@168
    98
Edouard@158
    99
            if (len < strlen(gpg_conf_name))
Edouard@158
   100
            {
Edouard@158
   101
                assert(0);
Edouard@168
   102
                return false;
Edouard@158
   103
            }
Edouard@158
   104
Edouard@158
   105
        }else{
vb@1
   106
Edouard@333
   107
            p = local_stpncpy(path, getenv("HOME"), MAX_PATH);
Edouard@168
   108
            len = MAX_PATH - (p - path) - 3;
Edouard@158
   109
Edouard@158
   110
            if (len < strlen(gpg_conf_path) + strlen(gpg_conf_name))
Edouard@158
   111
            {
Edouard@158
   112
                assert(0);
Edouard@168
   113
                return false;
Edouard@158
   114
            }
Edouard@158
   115
Edouard@158
   116
            *p++ = '/';
Edouard@158
   117
            strncpy(p, gpg_conf_path, len);
Edouard@158
   118
            p += strlen(gpg_conf_path);
Edouard@158
   119
            len -= strlen(gpg_conf_path) - 1;
vb@1
   120
        }
vb@1
   121
Edouard@168
   122
        strncpy(dirname, path, MAX_PATH);
Edouard@168
   123
        *p++ = '/';
Edouard@168
   124
        strncpy(p, gpg_conf_name, len);
Edouard@168
   125
Edouard@168
   126
        if(access(path, F_OK)){ 
Edouard@158
   127
            int fd;
Edouard@158
   128
            if(access(dirname, F_OK )) { 
Edouard@158
   129
                mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR);
Edouard@158
   130
            }
vb@149
   131
Edouard@168
   132
            fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
vb@149
   133
Edouard@158
   134
            if(fd>0) {
Edouard@158
   135
                write(fd, gpg_conf_empty, strlen(gpg_conf_empty));
Edouard@158
   136
                close(fd);
Edouard@158
   137
            }
Edouard@158
   138
        }
vb@1
   139
vb@1
   140
        done = true;
vb@1
   141
    }
Edouard@168
   142
Edouard@168
   143
    if(conf) *conf=path;
Edouard@168
   144
    if(home) *home=dirname;
Edouard@168
   145
Edouard@168
   146
    return true;
vb@1
   147
}
Edouard@168
   148
Edouard@168
   149
const char *gpg_conf(void)
Edouard@168
   150
{
Edouard@168
   151
    const char *conf;
Edouard@168
   152
    if(ensure_gpg_home(&conf, NULL))
Edouard@168
   153
        return conf;
Edouard@168
   154
    return NULL;
Edouard@168
   155
}
Edouard@168
   156
Edouard@168
   157
const char *gpg_home(void)
Edouard@168
   158
{
Edouard@168
   159
    const char *home;
Edouard@168
   160
    if(ensure_gpg_home(NULL, &home))
Edouard@168
   161
        return home;
Edouard@168
   162
    return NULL;
Edouard@168
   163
}