/*
    Configuration file management
    Copyright (c) Tudor Hulubei & Andrei Pitis, April 1994

This file is part of UIT (UNIX Interactive Tools)

UIT 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; either version 2, or (at your option) any later version.  

UIT 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 
UIT; see the file COPYING.  If not, write to the Free Software Foundation, 
675 Mass Ave, Cambridge, MA 02139, USA.  */ 


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "config.h"



configuration *configuration_init(char *filename)
{
    configuration *this = (configuration *)malloc(sizeof(configuration)); 
    this->file = fopen(filename, "r");
    this->status = this->file != NULL;
    return this;
}


void configuration_end(configuration *this)
{
    if (this->file) fclose(this->file);
}


int configuration_getline(configuration *this)
{
    int len;
    char *comment;

    if (fgets(this->line, MAXLINE - 1, this->file) == NULL)
	return 0;
    if ((len = strlen(this->line)) == MAXLINE - 1)
	fatal("line too long");
    if (comment = strchr(this->line, '#')) *comment = 0;
    else this->line[len - 1] = 0;
    return 1;
}


int configuration_getsectionptr(configuration *this, char *section_name)
{
    char buf[MAXLINE];

    fseek(this->file, 0, SEEK_SET);
    while (configuration_getline(this))
    {
	sscanf(this->line, "%s", buf);
	if (strcmp(section_name, buf) == 0)
	    return ftell(this->file);
    }
    return -1;
}


int  configuration_getstatus(configuration *this)
{
    return this->status; 
}


void configuration_getfielddata(configuration *this, int sectionptr, char *field_name,
				  char **dest, int fields, int seek)
{
    int fld;
    char buf[MAXLINE], *ptr, *tmp;

/*
 *  Assuming the section fields are read in the correct order is a lot faster.
 */
 
    if (seek) fseek(this->file, sectionptr, SEEK_SET);

    memset(dest, 0, fields * sizeof(char *));

    while (configuration_getline(this) && *this->line)
    {
	*buf = 0;
	sscanf(this->line, "%s", buf);
	if (!isalpha(*buf) && *buf != '^') return;
	if (strcmp(field_name, buf) == 0)
	{
	    if ((ptr = strchr(this->line, '=')) && *++ptr)
	    {
		for (dest[0] = ptr, fld = 1; *ptr && fld < fields; ptr++)
		    if (*ptr == ';')
		    {
			*ptr = 0;
			if (*(ptr + 1) && *(ptr + 1) != ';')
			    dest[fld] = ptr + 1;
			fld++;
		    }
		if (ptr = strchr(ptr, ';')) *ptr = 0;
	    }
	    for (fld = 0; fld < fields; fld++)
		if (dest[fld])
		{
		    while (isspace(*dest[fld])) dest[fld]++;
		    tmp = dest[fld] + strlen(dest[fld]) - 1;
		    while (isspace(*tmp) && tmp >= dest[fld]) tmp--;
		    *(tmp + 1) = 0;
		    if (dest[fld][0] == 0) dest[fld] = NULL;
		}
	    return;
	}
    }
}
