char **env_alloc(CLI *c) {
    char **env=NULL, **p;
    unsigned n=0; /* (n+2) keeps the list NULL-terminated */
    char *name, host[40], port[6];
    X509 *peer_cert;

    if(!getnameinfo(&c->peer_addr.sa, c->peer_addr_len,
            host, 40, port, 6, NI_NUMERICHOST|NI_NUMERICSERV)) {
        /* just don't set these variables if getnameinfo() fails */
        env=str_realloc(env, (n+2)*sizeof(char *));
        env[n++]=str_printf("REMOTE_HOST=%s", host);
        env=str_realloc(env, (n+2)*sizeof(char *));
        env[n++]=str_printf("REMOTE_PORT=%s", port);
        if(c->opt->option.transparent_src) {
#ifndef LIBDIR
#define LIBDIR "."
#endif
#ifdef MACH64
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("LD_PRELOAD_32=" LIBDIR "/libstunnel.so");
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("LD_PRELOAD_64=" LIBDIR "/" MACH64 "/libstunnel.so");
#elif __osf /* for Tru64 _RLD_LIST is used instead */
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("_RLD_LIST=" LIBDIR "/libstunnel.so:DEFAULT");
#else
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("LD_PRELOAD=" LIBDIR "/libstunnel.so");
#endif
        }
    }

    if(c->ssl) {
        peer_cert=SSL_get_peer_certificate(c->ssl);
        if(peer_cert) {
            name=X509_NAME2text(X509_get_subject_name(peer_cert));
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_printf("SSL_CLIENT_DN=%s", name);
            str_free(name);
            name=X509_NAME2text(X509_get_issuer_name(peer_cert));
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_printf("SSL_CLIENT_I_DN=%s", name);
            str_free(name);
            X509_free(peer_cert);
        }
    }

    for(p=environ; *p; ++p) {
        env=str_realloc(env, (n+2)*sizeof(char *));
        env[n++]=str_dup(*p);
    }

    return env;
}
char **env_alloc(CLI *c) {
    char **env=NULL, **p;
    unsigned n=0;  
    char *name, host[40], port[6];
    X509 *peer_cert;

    if(!getnameinfo(&c->peer_addr.sa, c->peer_addr_len,
            host, 40, port, 6, NI_NUMERICHOST|NI_NUMERICSERV)) {
         
        env=str_realloc(env, (n+2)*sizeof(char *));
        env[n++]=str_printf("REMOTE_HOST=%s", host);
        env=str_realloc(env, (n+2)*sizeof(char *));
        env[n++]=str_printf("REMOTE_PORT=%s", port);
        if(c->opt->option.transparent_src) {
#ifndef LIBDIR
#define LIBDIR "."
#endif
#ifdef MACH64
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("LD_PRELOAD_32=" LIBDIR "/libstunnel.so");
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("LD_PRELOAD_64=" LIBDIR "/" MACH64 "/libstunnel.so");
#elif __osf  
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("_RLD_LIST=" LIBDIR "/libstunnel.so:DEFAULT");
#else
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_dup("LD_PRELOAD=" LIBDIR "/libstunnel.so");
#endif
        }
    }

    if(c->ssl) {
        peer_cert=SSL_get_peer_certificate(c->ssl);
        if(peer_cert) {
            name=X509_NAME2text(X509_get_subject_name(peer_cert));
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_printf("SSL_CLIENT_DN=%s", name);
            str_free(name);
            name=X509_NAME2text(X509_get_issuer_name(peer_cert));
            env=str_realloc(env, (n+2)*sizeof(char *));
            env[n++]=str_printf("SSL_CLIENT_I_DN=%s", name);
            str_free(name);
            X509_free(peer_cert);
        }
    }

    for(p=environ; *p; ++p) {
        env=str_realloc(env, (n+2)*sizeof(char *));
        env[n++]=str_dup(*p);
    }

    return env;
}