/** BEGIN COPYRIGHT BLOCK
 * This Program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; version 2 of the License.
 * 
 * This Program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA.
 * 
 * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * END COPYRIGHT BLOCK **/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#if defined( XP_WIN32 )
#include <windows.h>
#endif
#include "dsalib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "nspr.h"
#include "plstr.h"

/*
 * Returns the instance directory path of the server.
 * Info is returned in a static area. The caller must 
 * copy it for reuse if needed.
 */
DS_EXPORT_SYMBOL char *
ds_get_instance_dir()
{
    char        *ds_name;
 
    if ( (ds_name = ds_get_server_name()) == NULL ) {
        return(NULL);
    } else {
        return ds_get_config_value(DS_INSTDIR);
    }
}

/*
 * Returns the config file location of the server. Info is 
 * returned in a static area. The caller must copy it 
 * for reuse if needed.
 */
DS_EXPORT_SYMBOL char *
ds_get_config_dir()
{
    char *ds_name;
    char *configdir_env;
    static char configdir[PATH_MAX];

    if ((configdir_env = getenv("DS_CONFIG_DIR"))) {
        return configdir_env;
    } else {
        if ( (ds_name = ds_get_server_name()) == NULL )
            return(NULL);
        PR_snprintf(configdir, sizeof(configdir), "%s/%s", INSTCONFIGDIR, ds_name);
        return (configdir);
    }
}

/*
 * set config_dir to environment variable DS_CONFIG_DIR
 * to retrieve the value using ds_get_config_dir later.
 */
DS_EXPORT_SYMBOL void
ds_set_config_dir(char *config_dir)
{
    static char env[PATH_MAX];
    PR_snprintf(env, sizeof(env), "DS_CONFIG_DIR=%s", config_dir);
    putenv(env);
}

/*
 * Returns the run dir of the server, where pid files are put.
 * Info is returned in a static area. The caller must copy it 
 * for reuse if needed.
 */
DS_EXPORT_SYMBOL char *
ds_get_run_dir()
{
    char *rundir_env = NULL;
    static char rundir[PATH_MAX];
    char *inst_dir = NULL;
    char *inst_name = NULL;
    char *start_script = NULL;
    char *sysconfig_script = NULL;
    char *p = NULL;
    char *start = NULL;
    char line[BIG_LINE];
    FILE *fp = NULL;

    if ((rundir_env = getenv("DS_RUN_DIR"))) {
        return (rundir_env);
    } else {
        /* Use the instance name to locate the instance sysconfig script */
        inst_dir = ds_get_instance_dir();
        start_script = PR_smprintf("%s%cstart-slapd", inst_dir, FILE_PATHSEP);
        fp = fopen(start_script, "r");
        if (fp) {
            while(fgets(line, BIG_LINE, fp)) {
                /* Find the line with the instance name */
                if ((start = strstr(line, "INSTANCE"))) {
                    /* skip any spaces after start-dirsrv */
                    start += strlen("INSTANCE=");

                    /* find the end of the instance name */
                    p = start;
                    while (!isspace(*p)) {
                        p++;
                    }
                    *p = '\0';

                    if (strlen(start) > 0) {
                        inst_name = PR_smprintf("%s", start);
                    }

                    break;
                }
            }
            fclose(fp);
        }

        /* We're done if we didn't parse the instance name. */
        if ((inst_name == NULL) || (strlen(inst_name) == 0)) {
            goto free_and_exit;
        }

        /* Get the RUN_DIR line from the instance sysconfig script */
        sysconfig_script = PR_smprintf("%s%cdirsrv-%s", INITCONFIGDIR, FILE_PATHSEP, inst_name);
        fp = fopen(sysconfig_script, "r");
        if (fp) {
            while(fgets(line, BIG_LINE, fp)) {
                /* Find line starting with RUN_DIR */
                if (strncmp(line, "RUN_DIR", 7) == 0) {
                    /* Chop off the variable name and export of the variable */
                    if ((start = strchr(line, '='))) {
                        start++;
                        if ((p = strrchr(start, ';'))) {
                            *p = '\0';
                            for (--p; isspace(*p); p--) {
                                *p = '\0';
                            }
                            PR_snprintf(rundir, sizeof(rundir), "%s", start);
                        }
                    }
                    break;
                }
            }
            fclose(fp);
        }

free_and_exit:
        PR_smprintf_free(start_script);
        PR_smprintf_free(sysconfig_script);
        PR_smprintf_free(inst_name);

        if (rundir[0] != '\0') {
            return (rundir);
        } else {
            return NULL;
        }
    }
}

/*
 * set run_dir to environment variable DS_RUN_DIR
 * to retrieve the value using ds_get_run_dir later.
 */
DS_EXPORT_SYMBOL void
ds_set_run_dir(char *run_dir)
{
    static char env[PATH_MAX];
    PR_snprintf(env, sizeof(env), "DS_RUN_DIR=%s", run_dir);
    putenv(env);
}

/*
 * Returns the bakup dir of the server, where db backup files are put.
 * Info is returned in a static area. The caller must copy it 
 * for reuse if needed.
 */
DS_EXPORT_SYMBOL char *
ds_get_bak_dir()
{
    char *bakdir;

    if ((bakdir = getenv("DS_BAK_DIR"))) {
        return bakdir;
    } else {
        return ds_get_config_value(DS_BAKDIR);
    }
}

/*
 * set bak_dir to environment variable DS_BAK_DIR
 * to retrieve the value using ds_get_bak_dir later.
 */
DS_EXPORT_SYMBOL void
ds_set_bak_dir(char *bak_dir)
{
    static char env[PATH_MAX];
    PR_snprintf(env, sizeof(env), "DS_BAK_DIR=%s", bak_dir);
    putenv(env);
}

/*
 * Returns the tmp dir of the server, where tmp files are put.
 * Info is returned in a static area. The caller must copy it 
 * for reuse if needed.
 */
DS_EXPORT_SYMBOL char *
ds_get_tmp_dir()
{
    char *tmpdir;

    if ((tmpdir = getenv("DS_TMP_DIR"))) {
        return tmpdir;
    } else {
        return ds_get_config_value(DS_TMPDIR);
    }
}

/*
 * set bak_dir to environment variable DS_TMP_DIR
 * to retrieve the value using ds_get_tmp_dir later.
 */
DS_EXPORT_SYMBOL void
ds_set_tmp_dir(char *tmp_dir)
{
    static char env[PATH_MAX];
    PR_snprintf(env, sizeof(env), "DS_TMP_DIR=%s", tmp_dir);
    putenv(env);
}

/*
 * Returns the install location of the server under the admserv
 * directory.
 */
DS_EXPORT_SYMBOL char *
ds_get_admserv_based_root()
{
    char        *root;
    char        *ds_name;
    static char install_root[PATH_MAX];
 
    if ( (root = getenv("ADMSERV_ROOT")) == NULL )
        return(NULL);
    if ( (ds_name = ds_get_server_name()) == NULL )
        return(NULL);
    PR_snprintf(install_root, sizeof(install_root), "%s/%s", root, ds_name);
    return(install_root);
}

/*
 * Returns the Directory Server instance name.
 */
DS_EXPORT_SYMBOL char *
ds_get_server_name()
{
    if( getenv("SERVER_NAMES") )
        return( getenv("SERVER_NAMES") );
    else {
        static char logfile[PATH_MAX];
        char *buf;
        char *out = logfile;
        buf = getenv("SCRIPT_NAME");
        if ( buf && (*buf == '/') )
            buf++;
        while ( buf && *buf && (*buf != '/') ) {
            *out++ = *buf++;
        }
        *out = 0;
        return logfile;
    }
}

/*
 * Returns the Directory Server instance name without the "slapd-" prefix
 */
DS_EXPORT_SYMBOL char *
ds_get_short_name()
{
    static char shortname[PATH_MAX] = {0};

    if (shortname[0]) {
        return shortname;
    }

    if( getenv("SERVER_NAMES") ) {
        char *ptr = strstr(getenv("SERVER_NAMES"), "slapd-");
        if (ptr) {
            PL_strncpyz(shortname, ptr+6, sizeof(shortname));
        } else {
            PL_strncpyz(shortname, getenv("SERVER_NAMES"), sizeof(shortname));
        }
    } else {
        char *buf;
        char *out = shortname;
        buf = getenv("SCRIPT_NAME");
        if (buf) {
            buf = strstr(getenv("SCRIPT_NAME"), "slapd-");
            if (buf) {
                buf += 6;
                while ( buf && *buf && (*buf != '/') ) {
                    *out++ = *buf++;
                }
                *out = 0;
            } else {
                PL_strncpyz(shortname, getenv("SCRIPT_NAME"), sizeof(shortname));
            }
        } else {
            PL_strncpyz(shortname, getenv("SCRIPT_NAME"), sizeof(shortname));
        }
    }
    return shortname;
}

DS_EXPORT_SYMBOL char *
ds_get_logfile_name(int config_type)
{
    char        *filename;
    char        **ds_config = NULL;
    static char logfile[PATH_MAX+1];
 
    if ( (ds_config = ds_get_config(DS_REAL_CONFIG)) == NULL ) {
        /* For DS 4.0, no error output if file doesn't exist - that's
           a normal situation */
        /* ds_send_error("ds_get_config(DS_REAL_CONFIG) == NULL", 0); */
        return(NULL);
    }
    filename = ds_get_value(ds_config, ds_get_var_name(config_type), 0, 1);

    if ( filename == NULL ) {
        /* For DS 4.0, no error output if file doesn't exist - that's
           a normal situation */
        /* ds_send_error("ds_get_logfile_name: filename == NULL", 0); */
        ds_free_config(ds_config);
        return(NULL);
    }
    if ( ((int) strlen(filename)) >= PATH_MAX ) {
        ds_send_error("ds_get_logfile_name: filename too long", 0);
        free(filename);
        ds_free_config(ds_config);
        return(NULL);
    }
    PL_strncpyz(logfile, filename, sizeof(logfile));
    free(filename);
    ds_free_config(ds_config);
    return(logfile);
}

DS_EXPORT_SYMBOL char *
ds_get_errors_name()
{
    return( ds_get_logfile_name(DS_ERRORLOG) );
}

DS_EXPORT_SYMBOL char *
ds_get_access_name()
{
    return( ds_get_logfile_name(DS_ACCESSLOG) );
}

DS_EXPORT_SYMBOL char *
ds_get_audit_name()
{
    return( ds_get_logfile_name(DS_AUDITFILE) );
}

