/* 
 * HostConf: the interface to /etc/host.conf
 *
 * Copyright (c) 1997 David L Parsons 
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by David L Parsons (orc@pell.chi.il.us).  My name may not be used
 * to endorse or promote products derived from this software without
 * specific prior written permission.  THIS SOFTWARE IS PROVIDED
 * ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.
 */
static const char rcsid[] = "$Id: s.HostConf.cc 1.8 98/06/23 21:53:36-00:00 orc $";

extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include <ctype.h>
}
#include <string.h>

#include "HostConf.H"
#include "util.H"

/*
 * load up host.conf, or suitable defaults
 */
HostConf::HostConf():Karray()
{
    if (Refresh() == EOF) {
	/* No /etc/host.conf; build a suitable template file. */
	autoappend(1);	/* we can add to this array on the fly */
	changed(1);

	create("order");
	valueof("order") = "hosts";
	valueof("order") += "bind";
	create("multi");
	valueof("multi") = "on";
    }
    changed(0);
} /* HostConf::HostConf */

/*
 * if anything has changed, write it to disk.
 * 
 * TODO: file locking, dirty file checking.
 */
int
HostConf::commit()
{
    FILE *cf;

    if (changed()) {
	if (backup(HOST_CONF) != 0)
	    return EOF;
	if ((cf = fopen(HOST_CONF, "w")) == (FILE*)0)
	    return EOF;
	make_header(cf, 0);
	print(cf);
	fclose(cf);
	Karray::changed(0);
    }
    return 0;
} /* HostConf::commit */


/*
 * has the disk configuration file been touched since we last loaded it in?
 */
int
HostConf::dirty()
{
    return 0;
}

/*
 * Refresh() the configuration from the disk image 
 */
int
HostConf::Refresh()
{
    FILE *cf;

    if ((cf = fopen(HOST_CONF, "r")) != (FILE*)0) {
	Karray::Erase();		/* never merge configurations */
	Karray::autoappend(1);
	read(cf);
	Karray::changed(0);
	fclose(cf);
	return 0;
    }
    return EOF;
} /* HostConf::Refresh */


/*
 * read() a configuration file from the given file descriptor.
 */
int
HostConf::read(FILE *in)
{
    char bfr[200];
    char *token;
    char *ptr;
    char *f, *t;

    while (fgets(bfr, sizeof bfr, in) != 0) {
	strtok(bfr, "\n#");

	token = strtok(bfr, "\t ");

	if (token && *token) {
	    ptr = strtok(NULL, "\n");

	    drop(token);
	    if (ptr) {
		/* strip spaces out of the token */
		for (t = f = ptr; *f; f++)
		    if (!isspace(*f))
			*t++ = *f;
		*t = 0;

		create(token, ptr);
	    }
	}
    }
    return count();
} /* HostConf::read */


/*
 * print() writes the contents of host.conf out to the given FILE*
 */
int
HostConf::print(FILE *out)
{
    int i, j;

    static char *listopts[] = {
	"order",
	"multi",
	0
    };

    for (j=0;  listopts[j]; j++) {
	if ((i = locate(listopts[j])) >= 0) {
	    KW& val = *_list[i]._content;

	    if ( (char*)val != 0 )
		fprintf(out, "%s %s\n", listopts[j], (char*)val);
	}
    }
    return 0;
} /* HostConf::print */
