Back to index

im-sdk  12.3.91
Defines | Functions
clientenv.c File Reference
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <sys/utsname.h>
#include "iiimcfint.h"

Go to the source code of this file.

Defines

#define NODE_KEY   "node="
#define NODE_KEY_LEN   (5)
#define SERVICE_KEY   "service="
#define SERVICE_KEY_LEN   (8)
#define CERT_FILE   "tls_cert="
#define CERT_FILE_LEN   (9)
#define CERT_KEY_FILE   "tls_key="
#define CERT_KEY_FILE_LEN   (8)
#define CERT_CA_FILE   "tls_cafile="
#define CERT_CA_FILE_LEN   (11)
#define CERT_CA_PATH   "tls_capath="
#define CERT_CA_PATH_LEN   (11)
#define USE_TLS   "use_tls="
#define USE_TLS_LEN   (8)
#define SERVER_FILE   ".iiim/server"
#define SERVER_FILE_LEN   (12)
#define SERVER_COMPAT_FILE   ".iiimp"
#define SERVER_COMPAT_FILE_LEN   (6)
#define SERVER_COMPAT_KEY   "iiimp.server=iiimp://"
#define SERVER_COMPAT_KEY_LEN   (21)
#define CONFIG_DIR_BASE   ".iiim"
#define CONFIG_DIR_AUTH   ".iiim/auth"
#define CONFIG_FILE_PASSWD   ".iiim/auth/passwd"
#define PASSWORD_FILE_LEN   (17)
#define AUTH_PASSWORD_LEN   (32)
#define HOME_ENV   "HOME"
#define IIIM_SERVER_ENV   "IIIM_SERVER"
#define CLIENT_TYPE   "generic IIIMP client"
#define POSITION_HEAD(p, n)
#define POSITION_TAIL(p, n)
#define POSITION_TAIL_COMPAT(p, n)
#define S_IAMB   0x1FF

Functions

static IIIMF_status get_param (const char **buf, size_t *nbyte, const char *key, size_t key_len, char **param_ret)
static IIIMF_status get_param_compat (const char **buf, size_t *nbyte, const char *key, size_t key_len, char **param_ret)
static void iiimcf_client_config_free (IIIMCF_client_conf *pconf)
static IIIMCF_client_confiiimcf_client_config_new (char *node, char *service)
static IIIMF_status iiimcf_client_file_server (IIIMCF_client_env *penv)
static IIIMF_status iiimcf_client_file_compat_server (IIIMCF_client_env *penv)
static IIIMF_status iiimcf_client_environ_server (IIIMCF_client_env *penv)
static void auth_password_generate (char *password, size_t length)
static int auth_password_file_init (char *password_file, size_t home_dir_len)
static int auth_password_file_open (const char *home_dir)
static IIIMF_status iiimcf_client_auth_password (IIIMCF_client_env *penv)
static IIIMF_status iiimcf_client_os_arch (IIIMCF_client_env *penv)
static IIIMF_status dir_valid (const char *path_name, uid_t euid)
static IIIMF_status iiimcf_alternate_unix_domain_socket_file_dir (IIIMCF_client_env *penv, char **path_name)
IIIMF_status iiimcf_create_client_env (IIIMCF_attr attr, IIIMCF_client_env **ppenv)
IIIMF_status iiimcf_delete_client_env (IIIMCF_client_env *penv)
IIIMF_status iiimcf_create_im_connect_message (IIIMCF_handle_rec *ph, IIIMP_message **ppmes)
IIIMF_status iiimcf_create_client_descriptor_message (IIIMCF_handle_rec *ph, IIIMP_message **ppmes)

Define Documentation

#define AUTH_PASSWORD_LEN   (32)

Definition at line 58 of file clientenv.c.

#define CERT_CA_FILE   "tls_cafile="

Definition at line 39 of file clientenv.c.

#define CERT_CA_FILE_LEN   (11)

Definition at line 40 of file clientenv.c.

#define CERT_CA_PATH   "tls_capath="

Definition at line 41 of file clientenv.c.

#define CERT_CA_PATH_LEN   (11)

Definition at line 42 of file clientenv.c.

#define CERT_FILE   "tls_cert="

Definition at line 35 of file clientenv.c.

#define CERT_FILE_LEN   (9)

Definition at line 36 of file clientenv.c.

#define CERT_KEY_FILE   "tls_key="

Definition at line 37 of file clientenv.c.

#define CERT_KEY_FILE_LEN   (8)

Definition at line 38 of file clientenv.c.

#define CLIENT_TYPE   "generic IIIMP client"

Definition at line 62 of file clientenv.c.

#define CONFIG_DIR_AUTH   ".iiim/auth"

Definition at line 55 of file clientenv.c.

#define CONFIG_DIR_BASE   ".iiim"

Definition at line 54 of file clientenv.c.

#define CONFIG_FILE_PASSWD   ".iiim/auth/passwd"

Definition at line 56 of file clientenv.c.

#define HOME_ENV   "HOME"

Definition at line 59 of file clientenv.c.

#define IIIM_SERVER_ENV   "IIIM_SERVER"

Definition at line 60 of file clientenv.c.

#define NODE_KEY   "node="

Definition at line 31 of file clientenv.c.

#define NODE_KEY_LEN   (5)

Definition at line 32 of file clientenv.c.

#define PASSWORD_FILE_LEN   (17)

Definition at line 57 of file clientenv.c.

#define POSITION_HEAD (   p,
 
)
Value:
for (; 0 < n; --(n), (p)++) { \
              if ((' ' != *(p)) && ('\t' != *(p)) && \
                  ('\r' != *(p)) && ('\n' != *(p))) { \
                     break; \
              } \
       } \
       if ((0 < (n)) && ((',' == *(p)) || (';' == *(p)))) { \
              --(n); \
              (p)++; \
       } \
       for (; 0 < n; --(n), (p)++) { \
              if ((' ' != *(p)) && ('\t' != *(p)) && \
                  ('\r' != *(p)) && ('\n' != *(p))) { \
                     break; \
              } \
       }

Definition at line 65 of file clientenv.c.

#define POSITION_TAIL (   p,
 
)
Value:
for (; 0 < n; --(n), (p)++) { \
              if ((',' == *(p)) || (';' == *(p)) || \
                  (' ' == *(p)) || ('\t' == *(p)) || \
                  ('\r' == *(p)) || ('\n' == *(p))) { \
                     break; \
              } \
       }

Definition at line 83 of file clientenv.c.

#define POSITION_TAIL_COMPAT (   p,
 
)
Value:
for (; 0 < n; --(n), (p)++) { \
              if ((':' == *(p)) || ('\r' == *(p)) || ('\n' == *(p))) { \
                     break; \
              } \
       }

Definition at line 92 of file clientenv.c.

#define S_IAMB   0x1FF
#define SERVER_COMPAT_FILE   ".iiimp"

Definition at line 49 of file clientenv.c.

#define SERVER_COMPAT_FILE_LEN   (6)

Definition at line 50 of file clientenv.c.

#define SERVER_COMPAT_KEY   "iiimp.server=iiimp://"

Definition at line 51 of file clientenv.c.

#define SERVER_COMPAT_KEY_LEN   (21)

Definition at line 52 of file clientenv.c.

#define SERVER_FILE   ".iiim/server"

Definition at line 46 of file clientenv.c.

#define SERVER_FILE_LEN   (12)

Definition at line 47 of file clientenv.c.

#define SERVICE_KEY   "service="

Definition at line 33 of file clientenv.c.

#define SERVICE_KEY_LEN   (8)

Definition at line 34 of file clientenv.c.

#define USE_TLS   "use_tls="

Definition at line 43 of file clientenv.c.

#define USE_TLS_LEN   (8)

Definition at line 44 of file clientenv.c.


Function Documentation

static int auth_password_file_init ( char *  password_file,
size_t  home_dir_len 
) [static]

Definition at line 532 of file clientenv.c.

{
    int              fd;
    char      pwd_buf[AUTH_PASSWORD_LEN + 1];
    struct stat      st;
    ssize_t   len;

    /* ${HOME}/.iiim */
    (void)strcpy(password_file + home_dir_len, CONFIG_DIR_BASE);
    if (0 != stat(password_file, &st)) {
       if (ENOENT != errno) return -1;
       if (0 != mkdir(password_file, 0777)) return -1;
    }

    /* ${HOME}/.iiim/auth */
    (void)strcpy(password_file + home_dir_len, CONFIG_DIR_AUTH);
    if (0 != stat(password_file, &st)) {
       if (ENOENT != errno) return -1;
       if (0 != mkdir(password_file, 0700)) return -1;
    }

    /* ${HOME}/.iiim/auth/password */
    (void)strcpy(password_file + home_dir_len, CONFIG_FILE_PASSWD);
    fd = open(password_file, O_CREAT | O_WRONLY, 0600);
    if (-1 == fd) return -1;

    auth_password_generate(pwd_buf, AUTH_PASSWORD_LEN);

    len = write(fd, pwd_buf, AUTH_PASSWORD_LEN + 1);
    (void)close(fd);

    if ((AUTH_PASSWORD_LEN + 1) == len) {
       return 0;
    } else {
       return -1;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int auth_password_file_open ( const char *  home_dir) [static]

Definition at line 575 of file clientenv.c.

{
    char *    password_file;
    char *    home_env;
    int              home_dir_len;
    int              len;
    struct stat      st;
    int              fd;

    password_file = NULL;

    if (NULL == home_dir) {
       home_env = getenv("HOME");
       if (NULL != home_env) {
           home_dir = home_env;
       }
       if (NULL == home_dir) {
           return -1;
       }
    }

    home_dir_len = strlen(home_dir);
    len = (home_dir_len + 1 + PASSWORD_FILE_LEN);

    password_file = malloc(len + 1);
    if (NULL == password_file) {
       return -1;
    }

    (void)strcpy(password_file, home_dir);
    *(password_file + home_dir_len) = '/';
    home_dir_len += 1;
    (void)strcpy(password_file + home_dir_len, CONFIG_FILE_PASSWD);

    if (0 != stat(password_file, &st)) {
       (void)auth_password_file_init(password_file, home_dir_len);
    }

    fd = open(password_file, O_RDONLY, 0);
    free(password_file);

    return fd;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void auth_password_generate ( char *  password,
size_t  length 
) [static]

Definition at line 485 of file clientenv.c.

{
    int                     fd;
    unsigned int     seed;
    int                     c;
    int                     i;
    int                     r;
    unsigned int *   p;
    size_t           n;
    char *           c62;

    *(password + length) = '\0';

    c62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    fd = open("/dev/random", O_RDONLY, 0);
    if (0 <= fd) {
       r = 0;
       n = ((sizeof (unsigned int)) * length);
       p = (unsigned int * )malloc(n);
       if (NULL != p) {
           r = read(fd, p, n);
       }
       (void)close(fd);
       if (r == length) {
           for (i = 0; i < length; i++) {
              *(password + i) = *(c62 + (*(p + i) % 62));
           }
           free(p);
           return;
       }
       free(p);
    }

    seed = (time(NULL) + getpid());
    srand(seed);
    for (i = 0; i < length; i++) {
       c = rand();
       *(password + i) = *(c62 + (c % 62));
    }

    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static IIIMF_status dir_valid ( const char *  path_name,
uid_t  euid 
) [static]

Definition at line 705 of file clientenv.c.

{
       struct stat   st;

#if !defined(S_IAMB)
#define       S_IAMB 0x1FF
#endif /* !S_IAMB */

       if ((0 == lstat(path_name, &st)) &&
           (0 != S_ISDIR(st.st_mode)) &&
           (euid == st.st_uid) &&
           ((S_IAMB & st.st_mode) == S_IRWXU)) {
           return IIIMF_STATUS_SUCCESS;
       } else {
           return IIIMF_STATUS_FAIL;
       }
}

Here is the caller graph for this function:

static IIIMF_status get_param ( const char **  buf,
size_t *  nbyte,
const char *  key,
size_t  key_len,
char **  param_ret 
) [static]

Definition at line 101 of file clientenv.c.

{
    const char *     b;
    const char *     p;
    size_t           n;
    size_t           m;
    size_t           len;
    char *           param;

    b = *buf;
    n = *nbyte;

    if (n < key_len) return IIIMF_STATUS_CONFIG;

    if (0 != strncasecmp(b, key, key_len)) {
       return IIIMF_STATUS_CONFIG;
    }

    b += key_len;
    n -= key_len;
    p = b;
    m = n;

    POSITION_TAIL(b, n);

    len = (m - n);

    param = (char *)malloc(len + 1);
    if (NULL == param) return IIIMF_STATUS_MALLOC;

    (void)memcpy(param, p, len);
    *(param + len) = '\0';

    *buf = b;
    *nbyte = n;
    *param_ret = param;

    return IIIMF_STATUS_SUCCESS;
}

Here is the caller graph for this function:

static IIIMF_status get_param_compat ( const char **  buf,
size_t *  nbyte,
const char *  key,
size_t  key_len,
char **  param_ret 
) [static]

Definition at line 149 of file clientenv.c.

{
    const char *     b;
    const char *     p;
    size_t           n;
    size_t           m;
    size_t           len;
    char *           param;

    b = *buf;
    n = *nbyte;

    if (n < key_len) return IIIMF_STATUS_CONFIG;

    if (0 != strncasecmp(b, key, key_len)) {
       return IIIMF_STATUS_CONFIG;
    }

    b += key_len;
    n -= key_len;
    p = b;
    m = n;

    POSITION_TAIL_COMPAT(b, n);

    len = (m - n);

    param = (char *)malloc(len + 1);
    if (NULL == param) return IIIMF_STATUS_MALLOC;

    (void)memcpy(param, p, len);
    *(param + len) = '\0';

    *buf = b;
    *nbyte = n;
    *param_ret = param;

    return IIIMF_STATUS_SUCCESS;
}

Here is the caller graph for this function:

static IIIMF_status iiimcf_alternate_unix_domain_socket_file_dir ( IIIMCF_client_env penv,
char **  path_name 
) [static]

Definition at line 725 of file clientenv.c.

{
    DIR *            dir;
    struct dirent *  dirent;
    char *           base_name;
    size_t           base_name_len;
    char *           dir_name;
    size_t           dir_name_len;
    IIIMF_status     found;
    uid_t            euid;

    dir = opendir("/tmp");
    if (NULL == dir) return IIIMF_STATUS_FAIL;

    base_name_len = (strlen(".iiimp-unix-") + strlen(penv->user_name) + 1);
    base_name = (char *)malloc(base_name_len + 1);
    if (NULL == base_name) {
       closedir(dir);
       return IIIMF_STATUS_MALLOC;
    }
    snprintf(base_name, base_name_len + 1, ".iiimp-unix-%s-", penv->user_name);

    euid = geteuid();

    found = IIIMF_STATUS_FAIL;
    while (NULL != (dirent = readdir(dir))) {
       if (0 != strncmp(dirent->d_name, base_name, base_name_len)) {
           continue;
       }

       dir_name_len = (strlen("/tmp") + 1 + strlen(dirent->d_name) + 1);
       dir_name = (char *)malloc(dir_name_len);
       if (NULL == dir_name) {
           found = IIIMF_STATUS_MALLOC;
           break;
       }
       snprintf(dir_name, dir_name_len, "/tmp/%s", dirent->d_name);
       found = dir_valid(dir_name, euid);

       if (IIIMF_STATUS_SUCCESS == found) {
           (*path_name) = dir_name;
           break;
       }

       free(dir_name);
    }

    free(base_name);
    closedir(dir);

    return found;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 622 of file clientenv.c.

{
    char *    password;

    if (penv->password) return IIIMF_STATUS_SUCCESS;

#if 0
    int              fd;
    int              len;
    int              i;
    char      pwd_buf[AUTH_PASSWORD_LEN + 1];

    password = NULL;
    fd = -1;

    if (!penv->home_dir) return IIIMF_STATUS_CONFIG;
    fd = auth_password_file_open(penv->home_dir);
    if (-1 == fd) return IIIMF_STATUS_CONFIG;

    len = read(fd, pwd_buf, AUTH_PASSWORD_LEN);
    (void)close(fd);

    if (AUTH_PASSWORD_LEN != len) return IIIMF_STATUS_CONFIG;

    for (i = 0; i < AUTH_PASSWORD_LEN; i++) {
       if (0 == isalnum(pwd_buf[i])) {
           return IIIMF_STATUS_CONFIG;
       }
    }
    if (AUTH_PASSWORD_LEN != i) {
       return IIIMF_STATUS_CONFIG;
    }

    password = malloc(AUTH_PASSWORD_LEN + 1);
    if (NULL == password) return IIIMF_STATUS_MALLOC;
    (void)memcpy(password, pwd_buf, AUTH_PASSWORD_LEN);
    *(password + AUTH_PASSWORD_LEN) = '\0';

    penv->password = password;

#endif
    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void iiimcf_client_config_free ( IIIMCF_client_conf pconf) [static]

Definition at line 196 of file clientenv.c.

{
    IIIMCF_client_conf *pc;
    IIIMCF_client_conf *pc2;

    if (!pconf) return;
    for (pc = pconf; pc; ) {
        pc2 = pc->next;
        if(pc->server_node) free(pc->server_node);
        if(pc->service) free(pc->service);
        if(pc->cert_file) free(pc->cert_file);
        if(pc->cert_key) free(pc->cert_key);
        if(pc->ca_file) free(pc->ca_file);
        if(pc->ca_path) free(pc->ca_path);
        free(pc);
        pc = pc2;
    }
}

Here is the caller graph for this function:

static IIIMCF_client_conf* iiimcf_client_config_new ( char *  node,
char *  service 
) [static]

Definition at line 218 of file clientenv.c.

{
    IIIMCF_client_conf *ret;
    ret = malloc(sizeof(*ret));
    if (!ret) return NULL;
    memset(ret, 0, sizeof(*ret));

    ret->server_node = node;
    ret->service = service;
    return ret;
}

Here is the caller graph for this function:

Definition at line 455 of file clientenv.c.

{
    IIIMF_status     status;
    const char *     p;
    size_t           rest;
    char *           node;
    char *           service;

    p = getenv(IIIM_SERVER_ENV);
    if (NULL == p) return IIIMF_STATUS_FAIL;

    rest = strlen(p);

    status = get_param(&p, &rest, "", 0, &node);
    if (IIIMF_STATUS_SUCCESS != status) {
       return status;
    }

    POSITION_HEAD(p, rest);

    status = get_param(&p, &rest, "", 0, &service);

    penv->pconf = iiimcf_client_config_new(node, service);

    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 369 of file clientenv.c.

{
    int                     fd;
    IIIMF_status     status;
    char *           server_file;
    size_t           server_file_len;
    size_t           home_dir_len;
    struct stat             st;
    int                     stat_ret;
    char *           pa;
    const char *     p;
    size_t           rest;
    char *           node = NULL;
    char *           service;

    if (!penv->home_dir) return IIIMF_STATUS_CONFIG;
    home_dir_len = strlen(penv->home_dir);
    server_file_len = (home_dir_len + 1 + SERVER_COMPAT_FILE_LEN);

    server_file = (char *)malloc(server_file_len + 1);
    if (NULL == server_file) {
       return IIIMF_STATUS_MALLOC;
    }

    (void)strcpy(server_file, penv->home_dir);
    *(server_file + home_dir_len) = '/';
    (void)strcpy(server_file + home_dir_len + 1, SERVER_COMPAT_FILE);

    fd = open(server_file, O_RDONLY, 0);
    free(server_file);
    if (fd < 0) return IIIMF_STATUS_CONFIG;
    stat_ret = fstat(fd, &st);
    if (stat_ret < 0) {
       return IIIMF_STATUS_CONFIG;
    }

    pa = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
    (void)close(fd);
    if (NULL == pa) return IIIMF_STATUS_CONFIG;

    p = pa;
    rest = st.st_size;

    while (0 < rest) {
       for (; 0 < rest; --rest, p++) {
           if (('\r' == *p) || ('\n' == *p)) {
              p += 1;
              rest -= 1;
              break;
           }
       }
       if (rest < SERVER_COMPAT_KEY_LEN) break;

       status = get_param_compat(&p, &rest,
                              SERVER_COMPAT_KEY,
                              SERVER_COMPAT_KEY_LEN,
                              &node);
       if (IIIMF_STATUS_SUCCESS == status) {
           p += 1;
           rest -= 1;
           break;
       }
    }
    if (!node) {
       return IIIMF_STATUS_CONFIG;
    }

    status = get_param_compat(&p, &rest, "", 0, &service);

    (void)munmap(pa, st.st_size);

    if ('\0' == *service) {
       free(service);
       service = NULL;
    }

    if (IIIMF_STATUS_SUCCESS == status) {
        penv->pconf = iiimcf_client_config_new(node, service);
    }

    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 234 of file clientenv.c.

{
    int                     fd;
    IIIMF_status     status;
    char *           server_file;
    size_t           server_file_len;
    size_t           home_dir_len;
    struct stat             st;
    int                     stat_ret;
    char *           pa;
    const char *     p;
    size_t           rest;
    IIIMCF_client_conf  *pconf = NULL;
    char *           node = NULL;

    if (!penv->home_dir) return IIIMF_STATUS_CONFIG;

    home_dir_len = strlen(penv->home_dir);
    server_file_len = (home_dir_len + 1 + SERVER_FILE_LEN);

    server_file = (char *)malloc(server_file_len + 1);
    if (NULL == server_file) {
       return IIIMF_STATUS_MALLOC;
    }

    (void)strcpy(server_file, penv->home_dir);
    *(server_file + home_dir_len) = '/';
    (void)strcpy(server_file + home_dir_len + 1, SERVER_FILE);

    fd = open(server_file, O_RDONLY, 0);
    free(server_file);
    if (fd < 0) return IIIMF_STATUS_CONFIG;

    stat_ret = fstat(fd, &st);
    if (stat_ret < 0) {
       return IIIMF_STATUS_CONFIG;
    }

    pa = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
    (void)close(fd);
    if (NULL == pa) return IIIMF_STATUS_CONFIG;

    p = pa;
    rest = st.st_size;

    /* create client pconfig */
    for (; rest > 0; ) {
        POSITION_HEAD(p, rest);
        if (rest == 0) break;

        if (!strncasecmp(p, NODE_KEY, NODE_KEY_LEN)) {
            IIIMCF_client_conf *pconf_next;
            status = get_param(&p, &rest, NODE_KEY, NODE_KEY_LEN, &node);
            if (IIIMF_STATUS_SUCCESS != status) {
                goto error;
            }
            if (!penv->pconf) {
                /* if penv->pconf is not yet initialized, the first one */
                penv->pconf = iiimcf_client_config_new(node, NULL);
                if (!penv->pconf) {
                    free(node);
                    goto error;
                }
                pconf = penv->pconf;
            } else {
                /* otherwise, create new pconfig and link to penv->pconf */
                pconf_next = iiimcf_client_config_new(node, NULL);
                if (!pconf_next) {
                    free(node);
                    goto error;
                }
                pconf->next = pconf_next;
                pconf = pconf_next;
            }
        } else if (!strncasecmp(p, SERVICE_KEY, SERVICE_KEY_LEN)) {
            if (!pconf) goto error;
            status = get_param(&p, &rest, SERVICE_KEY, SERVICE_KEY_LEN, &pconf->service);
            if (IIIMF_STATUS_SUCCESS != status) {
               goto error;
            }
        } else if (!strncasecmp(p, CERT_FILE, CERT_FILE_LEN)) {
            if (!pconf) goto error;
            status = get_param(&p, &rest, CERT_FILE, CERT_FILE_LEN, &pconf->cert_file);
            if (IIIMF_STATUS_SUCCESS != status) {
               goto error;
            }
        } else if (!strncasecmp(p, CERT_KEY_FILE, CERT_KEY_FILE_LEN)) {
            if (!pconf) goto error;
            status = get_param(&p, &rest, CERT_FILE, CERT_FILE_LEN, &pconf->cert_key);
            if (IIIMF_STATUS_SUCCESS != status) {
               goto error;
            }
        } else if (!strncasecmp(p, CERT_CA_FILE, CERT_CA_FILE_LEN)) {
            if (!pconf) goto error;
            status = get_param(&p, &rest, CERT_CA_FILE, CERT_CA_FILE_LEN, &pconf->ca_file);
            if (IIIMF_STATUS_SUCCESS != status) {
               goto error;
            }
        } else if (!strncasecmp(p, CERT_CA_PATH, CERT_CA_PATH_LEN)) {
            if (!pconf) goto error;
            status = get_param(&p, &rest, CERT_CA_PATH, CERT_CA_PATH_LEN, &pconf->ca_path);
            if (IIIMF_STATUS_SUCCESS != status) {
               goto error;
            }
        } else if (!strncasecmp(p, USE_TLS, USE_TLS_LEN)) {
            char *use_tls;
            if (!pconf) goto error;
            status = get_param(&p, &rest, USE_TLS, USE_TLS_LEN, &use_tls);
            if (IIIMF_STATUS_SUCCESS != status) {
               goto error;
            }
            if (!strcasecmp(use_tls, "yes")) {
                pconf->use_tls = 1;
            }
            free(use_tls);
        } else {
            POSITION_TAIL(p, rest);
        }
    }

    (void)munmap(pa, st.st_size);
    return IIIMF_STATUS_SUCCESS;

error:

    iiimcf_client_config_free(penv->pconf);
    penv->pconf = NULL;
    (void)munmap(pa, st.st_size);
    return IIIMF_STATUS_CONFIG;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 669 of file clientenv.c.

{

#if defined(OS_ARCH)
    penv->os_arch = strdup(OS_ARCH);
#else /* !OS_ARCH */
#if defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
    {
        char arch[16];
       int ret;
       ret = sysinfo(SI_ARCHITECTURE, arch, sizeof (arch));
       if (-1 == ret) {
           penv->os_arch = NULL;
       } else if ((0 == strcmp(arch, "sparc")) ||
                 (0 == strcmp(arch, "ppc"))) {
           penv->os_arch = strdup(arch);
       } else if (0 == strcmp(arch, "i386")) {
           penv->os_arch = strdup("x86");
       } else {
           penv->os_arch = strdup("Unknown");
       }
    }
#else /* !HAVE_SYSINFO || !SI_ARCHITECTURE */
    penv->os_arch = strdup("Unknown");
#endif /* !HAVE_SYSINFO || !SI_ARCHITECTURE */
#endif /* !OS_ARCH */
    if (!penv->os_arch)
       return IIIMF_STATUS_MALLOC;

    return IIIMF_STATUS_SUCCESS;
}

Here is the caller graph for this function:

Definition at line 1054 of file clientenv.c.

{
    IIIMF_status st;
    IIIMCF_client_env *penv = ph->penv;
    IIIMP_message *pmes;
    IIIMP_imattribute *pimattr;
    IIIMP_client_descriptor *cdesc;
    IIIMP_string *type, *os_name, *os_arch, *os_ver;
    IIIMP_string *X_display_name, *X_server_vendor;

    pmes = NULL;
    pimattr = NULL;
    cdesc = NULL;
    type = os_name = os_arch = os_ver = NULL;
    X_display_name = X_server_vendor = NULL;

    st = iiimf_data_string_ascii_new(ph->data_s, penv->type, &type);
    if (st != IIIMF_STATUS_SUCCESS) goto error;
    st = iiimf_data_string_ascii_new(ph->data_s, penv->os_name, &os_name);
    if (st != IIIMF_STATUS_SUCCESS) goto error;
    st = iiimf_data_string_ascii_new(ph->data_s, penv->os_arch, &os_arch);
    if (st != IIIMF_STATUS_SUCCESS) goto error;
    st = iiimf_data_string_ascii_new(ph->data_s, penv->os_version, &os_ver);
    if (st != IIIMF_STATUS_SUCCESS) goto error;

    if (penv->X_display_name) {
       st = iiimf_data_string_ascii_new(ph->data_s,
                                    penv->X_display_name,
                                    &X_display_name);
       if (st != IIIMF_STATUS_SUCCESS) goto error;
    }
    if (penv->X_server_vendor) {
       st = iiimf_data_string_ascii_new(ph->data_s,
                                    penv->X_server_vendor,
                                    &X_server_vendor);
       if (st != IIIMF_STATUS_SUCCESS) goto error;
    }

    cdesc = iiimp_client_descriptor_new(ph->data_s,
                                   type, os_name, os_arch, os_ver,
                                   X_display_name, X_server_vendor);
    if (!cdesc) goto error;

    pimattr = iiimp_imattribute_client_descriptor_new(ph->data_s,
                                                IIIMP_IMATTRIBUTE_CLIENT_DESCRIPTOR,
                                                0, cdesc);
    if (!pimattr) goto error;

    pmes = iiimp_setimvalues_new(ph->data_s, ph->im_id, pimattr);
    if (!pmes) goto error;

    *ppmes = pmes;

    return IIIMF_STATUS_SUCCESS;

error:
    if (type) iiimp_string_delete(ph->data_s, type);
    if (os_name) iiimp_string_delete(ph->data_s, os_name);
    if (os_arch) iiimp_string_delete(ph->data_s, os_arch);
    if (os_ver) iiimp_string_delete(ph->data_s, os_ver);
    if (X_display_name) iiimp_string_delete(ph->data_s, X_display_name);
    if (X_server_vendor) iiimp_string_delete(ph->data_s, X_server_vendor);
    if (cdesc) iiimp_client_descriptor_delete(ph->data_s, cdesc);
    if (pimattr) iiimp_imattribute_delete(ph->data_s, pimattr);

    return IIIMF_STATUS_MALLOC;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 783 of file clientenv.c.

{
    IIIMCF_client_env *penv;
    IIIMCF_client_conf *pconf;
    IIIMF_status st;
    const char *server_node, *service, *user_name, *password;
    const char *clientname, *x_display_name, *x_server_vendor;

    server_node = service = user_name = password = NULL;
    clientname = x_display_name = x_server_vendor = NULL;

    penv = (IIIMCF_client_env *)malloc(sizeof (IIIMCF_client_env));
    if (!penv) return IIIMF_STATUS_MALLOC;
    memset(penv, 0, sizeof(*penv));

    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_SERVER_ADDRESS,
                                  &server_node);

    if (st != IIIMF_STATUS_SUCCESS && st != IIIMF_STATUS_NO_ATTR_VALUE) goto error;

    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_SERVER_SERVICE,
                                  &service);
    if (st != IIIMF_STATUS_SUCCESS && st != IIIMF_STATUS_NO_ATTR_VALUE) goto error;

    if (server_node || service) {
        penv->pconf = iiimcf_client_config_new(server_node ? strdup(server_node) : NULL,
                                              service ?  strdup(service) : NULL);
        if (!penv->pconf) goto memory_error;
    }


    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_USERNAME,
                                  &user_name);
    if (st == IIIMF_STATUS_SUCCESS) {
       penv->user_name = strdup(user_name);
       if (!penv->user_name) goto memory_error;
    } else if (st != IIIMF_STATUS_NO_ATTR_VALUE) {
       goto error;
    }
    {
       struct passwd *pwd;
       /* TODO!  Use penv->user_name to check the
          home directory. */
       if ((pwd = getpwuid(geteuid()))) {
           if (!penv->user_name)
              penv->user_name = strdup(pwd->pw_name);
           if (!penv->user_name) goto memory_error;
           penv->home_dir = strdup(pwd->pw_dir);
           if (!penv->home_dir) goto memory_error;
       }
    }
    /* We still fail to get user_name, set "Unknown" with force.  */
    if (!penv->user_name) {
       penv->user_name = strdup("Unknown");
       if (!penv->user_name) goto memory_error;
    }

    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_PASSWORD,
                                  &password);
    if (st == IIIMF_STATUS_SUCCESS) {
       penv->password = strdup(password);
       if (!penv->password) goto memory_error;
    } else if (st == IIIMF_STATUS_NO_ATTR_VALUE) {
       st = iiimcf_client_auth_password(penv);
       if ((st != IIIMF_STATUS_SUCCESS)
           && (st != IIIMF_STATUS_CONFIG))
           goto error;
    } else {
       goto error;
    }

    if (!server_node && !service) {
       st = iiimcf_client_environ_server(penv);
       if (st != IIIMF_STATUS_SUCCESS) {
           st = iiimcf_client_file_server(penv);
           if (st != IIIMF_STATUS_SUCCESS) {
              st = iiimcf_client_file_compat_server(penv);
           }
       }
    }
    if (!penv->pconf) {
        /* 
         * we don't have any pconfiguration.
         * prepare default one.
         */
        int node_len;
        char *tmp_node;

        /* 
         * first try to /tmp/.iiimp-unix-${USERNAME}/
         */
       node_len = strlen("/tmp/.iiimp-unix-") + strlen(penv->user_name);
        tmp_node = malloc(node_len + 1);
        if (!tmp_node) goto memory_error;
        snprintf(tmp_node, node_len + 1, "/tmp/.iiimp-unix-%s", penv->user_name);
        tmp_node[node_len] = '\0';

       if (IIIMF_STATUS_SUCCESS != dir_valid(tmp_node, geteuid())) {
           /* 
            * try /tmp/.iiimp-unix-${USERNAME}-xxxxxxxx/
            */
           free(tmp_node);
           tmp_node = NULL;
           st = iiimcf_alternate_unix_domain_socket_file_dir(penv, &tmp_node);
       }

       if (NULL != tmp_node) {
           penv->pconf = iiimcf_client_config_new(tmp_node, NULL);
           if (!penv->pconf) {
              free(tmp_node);
              goto memory_error;
           }
       }

        /* 
         * second try to $SOCKETDIR/.iiimp-unix/
         */
        tmp_node = strdup(SOCKETDIR "/.iiimp-unix");
        if (!tmp_node) goto memory_error;
       pconf = iiimcf_client_config_new(tmp_node, NULL);
        if (NULL == pconf) {
            free(tmp_node);
            goto memory_error;
        }

       if (NULL == penv->pconf) {
           penv->pconf = pconf;
       } else {
           penv->pconf->next = pconf;
       }
    }

    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_CLIENT_TYPE,
                                  &clientname);
    if (st == IIIMF_STATUS_SUCCESS) {
       penv->type = strdup(clientname);
    } else if (st == IIIMF_STATUS_NO_ATTR_VALUE) {
       penv->type = strdup(CLIENT_TYPE);
    } else {
       goto error;
    }
    if (!penv->type) goto memory_error;

    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_CLIENT_X_DISPLAY_NAME,
                                  &x_display_name);
    if (st == IIIMF_STATUS_SUCCESS) {
       penv->X_display_name = strdup(x_display_name);
       if (!penv->X_display_name) goto memory_error;
    } else if (st != IIIMF_STATUS_NO_ATTR_VALUE) {
       goto error;
    }

    st = iiimcf_attr_get_string_value(attr,
                                  IIIMCF_ATTR_CLIENT_X_SERVER_VENDOR,
                                  &x_server_vendor);
    if (st == IIIMF_STATUS_SUCCESS) {
       penv->X_server_vendor = strdup(x_server_vendor);
       if (!penv->X_server_vendor) goto memory_error;
    } else if (st != IIIMF_STATUS_NO_ATTR_VALUE) {
       goto error;
    }

    {
       struct utsname name;
       if (-1 != uname(&name)) {
           penv->node = strdup(name.nodename);
           if (!penv->node) goto memory_error;
           penv->os_name = strdup(name.sysname);
           if (!penv->os_name) goto memory_error;
           penv->os_version = strdup(name.release);
           if (!penv->os_version) goto memory_error;
       }
    }

    st = iiimcf_client_os_arch(penv);
    if ((st != IIIMF_STATUS_SUCCESS)
       && (st != IIIMF_STATUS_CONFIG))
       goto error;

    *ppenv = penv;

    return IIIMF_STATUS_SUCCESS;

memory_error:
    st = IIIMF_STATUS_MALLOC;
error:
    iiimcf_delete_client_env(penv);
    return st;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1004 of file clientenv.c.

{
    int len;
    char *user;
    IIIMF_status st;
    IIIMP_message *pmes;
    IIIMP_string *pim_user;
    IIIMCF_client_env *penv = ph->penv;

    len = strlen(penv->user_name);
    if (penv->node) len += strlen(penv->node);
    if (penv->X_display_name) len += strlen(penv->X_display_name);
    else len += 4;
    if (penv->password) len += strlen(penv->password);
    user = (char*) malloc(sizeof(char) * (len + 1 + 1 + 1)); /* for @, #, and \0. */
    if (!user) return IIIMF_STATUS_MALLOC;
    strcpy(user, penv->user_name);
    if (penv->node) {
       strcat(user, "@");
       strcat(user, penv->node);
        /* printf("penv->X_display_name [%s]\n", penv->X_display_name); */
        if (penv->X_display_name) {
         strcat(user, penv->X_display_name);
        } else {
         penv->X_display_name = strdup(":0.0");
         strcat(user, ":0.0");
        }
    }
    if (penv->password) {
       strcat(user, "#");
       strcat(user, penv->password);
    }
    st = iiimf_data_string_ascii_new(ph->data_s, user, &pim_user);
    free(user);
    if (st != IIIMF_STATUS_SUCCESS) return st;
    pmes = iiimp_connect_new(ph->data_s, pim_user, NULL);
    if (!pmes) {
       iiimp_string_delete(ph->data_s, pim_user);
       return IIIMF_STATUS_MALLOC;
    }

    *ppmes = pmes;

    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 983 of file clientenv.c.

{
    if (penv->user_name) free(penv->user_name);
    if (penv->password) free(penv->password);
    if (penv->home_dir) free(penv->home_dir);
    if (penv->node) free(penv->node);
    if (penv->type) free(penv->type);
    if (penv->os_name) free(penv->os_name);
    if (penv->os_arch) free(penv->os_arch);
    if (penv->os_version) free(penv->os_version);
    if (penv->X_display_name) free(penv->X_display_name);
    if (penv->X_server_vendor) free(penv->X_server_vendor);
    if (penv->pconf)  iiimcf_client_config_free(penv->pconf);

    free(penv);
    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function: