/** 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>
#include <process.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "dsalib.h"
#include <ctype.h>

#include "nspr.h"

#define CONF_SUFFIX "cn=config"

DS_EXPORT_SYMBOL char *
ds_get_var_name(int varnum)
{
    if ( (varnum >= DS_CFG_MAX) || (varnum < 0) )
        return(NULL);                      /* failure */
    return(ds_cfg_info[varnum].dci_varname);
}

/*
 * Get config info.
 */
DS_EXPORT_SYMBOL char **
ds_get_config(int type)
{
    char        conffile[PATH_MAX];
    char        *configdir;
#if defined(USE_OPENLDAP)
    LDIFFP		*sf = NULL;
#else
    FILE        *sf = NULL;
#endif
    char        **conf_list = NULL;

    if ( (type != DS_REAL_CONFIG) && (type != DS_TMP_CONFIG) ) {
        ds_send_error("Invalid config file type.", 0);
        return(NULL);
    }

    if ( (configdir = ds_get_config_dir()) == NULL ) {
        ds_send_error("Cannot find configuration directory.", 0);
        return(NULL);
    }

    PR_snprintf(conffile, PATH_MAX, "%s/%s", configdir, DS_CONFIG_FILE);

#if defined(USE_OPENLDAP)
    sf = ldif_open(conffile, "r");
#else
    sf = fopen(conffile, "r");
#endif
    if ( !sf )  {
        ds_send_error("could not read config file.", 1);
        return(NULL);
    }

    conf_list = ds_get_conf_from_file(sf);

#if defined(USE_OPENLDAP)
    ldif_close(sf);
#else
    fclose(sf);
#endif
    if (!conf_list) {
        ds_send_error("failed to read the config file successfully.", 0);
        return(NULL);
    }
    return(conf_list);
}

/*
 * Frees the config list returned by ds_get_config().
 */
DS_EXPORT_SYMBOL void
ds_free_config(char **conf_list)
{
    int i;

    for (i=0; conf_list && conf_list[i]; i++) {
        PR_smprintf_free(conf_list[i]);
    }

    free((void *)conf_list);
}

/*
 * NOTE: the ordering of the following array elements must be kept in sync
 * with the ordering of the #defines in ../include/dsalib.h.
 */
struct ds_cfg_info ds_cfg_info[] = {
{"nsslapd-errorlog-level" },
{"nsslapd-referral" },
{"nsslapd-auditlog" },
{"nsslapd-localhost" },
{"nsslapd-port" },
{"nsslapd-security" },
{"nsslapd-secureport" },
{"nsslapd-ssl3ciphers"},
{"passwordstoragescheme"},
{"nsslapd-accesslog"},
{"nsslapd-errorlog"},
{"nsslapd-rootdn"},
{"nsslapd-rootpwstoragescheme"},
{"nsslapd-suffix"},
{"nsslapd-localuser"},
{"nsslapd-bakdir"},
{"nsslapd-tmpdir"},
{"nsslapd-instancedir"},
{0}
};

/*
 * Open the config file and look for option "option".  Return its
 * value, or NULL if the option was not found.
 */
DS_EXPORT_SYMBOL char *
ds_get_config_value( int option )
{
    char **all, *value, *retval;
    int i;
    char *attr = ds_get_var_name(option);

    if (attr == NULL)
	return NULL;

    all = ds_get_config( DS_REAL_CONFIG );
    if ( all == NULL ) {
	return NULL;
    }
    for ( i = 0; all[ i ] != NULL; i++ ) {
	if (( value = strchr( all[ i ], ':' )) != NULL ) {
	    *value = '\0';
	    ++value;
	    while (*value && isspace(*value))
		++value;
	}
	if ( !strcasecmp( attr, all[ i ] )) {
            retval = strdup(value);
            ds_free_config(all);
	    return retval;
	}
    }
    ds_free_config(all);
    return NULL;
}
