/*
 * Written by Alexei V. Galatenko <agalat@castle.nmd.msu.ru>
 * and Andrey V. Savochkin <saw@msu.ru>
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

#define NUM_POSIX	6

extern char **environ;

const char *posix_env[] = {
    "LANG",
    "LC_COLLATE",
    "LC_CTYPE",
    "LC_MONETARY",
    "LC_NUMERIC",
    "TZ",
};

void free_env (char **env)
{
    int i;
    for (i = 0; env [i] != NULL; i++)
        free (env [i]);
    free (env);
}

int make_environment(int keep_env, const char *home, char ***env)
{
    int i, j;
    char *tmpe;

    if (keep_env) {
        /* calculate the number of environment variables */
        if (environ == NULL) 
            return 1;
        
        for (i = 0; environ[i] != NULL; i++);
        /* allocate the memory for remembering enironment */
            *env = (char **) calloc (i + 1, sizeof (char *));
        if (*env == NULL)
            return 1;
            
        /* preserve the original environment */
        for (i = 0; environ[i] != NULL; i++) {
            (*env)[i] = malloc(strlen(environ[i]) + 1);
            if ((*env)[i] == NULL) {
                free_env (*env);
                return 1;
            }
            strcpy((*env)[i], environ[i]);
        }
        (*env)[i] = NULL;
    }
    else {
        /* allocate the memory for remembering enironment */
        *env = (char **) calloc (NUM_POSIX + 3, sizeof (char *));
        if (*env == NULL)
            return 1;

        /* Adding terminal description */
        tmpe = getenv("TERM");
        if (tmpe == NULL) 
            tmpe = "dumb";
        (*env)[0] = malloc(strlen(tmpe) + sizeof ("TERM="));
        if ((*env)[0] == NULL) {
            free_env (*env);
            return 1;
        }
        sprintf ((*env)[0], "TERM=%s", tmpe);

        /* Adding home directory */
        (*env)[1] = malloc(strlen(home) + sizeof ("HOME="));
        if ((*env)[1] == NULL) {
            free_env (*env);
            return 1;
        }
        sprintf ((*env)[1], "HOME=%s", home);

        /* filling POSIX environment */
        for (i = 2, j = 0; j < NUM_POSIX; j++) {
            tmpe = getenv(posix_env[j]);
            if (tmpe == NULL)
                continue;
            (*env)[i] = malloc(strlen (posix_env[j]) + sizeof "=" +
                                   strlen (tmpe));
            if ((*env)[i] == NULL) {
                free_env (*env);
                return 1;	
            }
            sprintf ((*env)[i], "%s=%s", posix_env[j], tmpe);
                i++;
        }

        (*env)[i] = NULL;
    }
    return 0;
}
