/*
 *   Copyright (c) 2000 David Parsons. All rights reserved.
 *   
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *  3. All advertising materials mentioning features or use of this
 *     software must display the following acknowledgement:
 *     
 *   This product includes software developed by David Parsons
 *   (orc@pell.chi.il.us)
 *
 *  4. My name may not be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *     
 *  THIS SOFTWARE IS PROVIDED BY DAVID PARSONS ``AS IS'' AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 *  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
 *  PARSONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 *  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 *  THE POSSIBILITY OF SUCH DAMAGE.
 */

static const char rcsid[] = "$Id: s.ntp.cc 1.5 02/05/04 01:28:37-07:00 root@egypt.pell.portland.or.us $";

/*
 * ntp: manage /etc/ntp.conf
 */

extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <string.h>
#include <dialog.h>
#include <ndialog.h>
#include <basis/validators.h>
}

#include <basis/Sysconfig.H>
#include <basis/Ntp.H>

#include "buttons.h"

extern "C" {
extern void Error(char *fmt, ...);
#include "util.h"
}

static ndObject o_servers;
static LIA ntp_servers;
static char use_ntp;

/*
 * enable or disable the o_servers object depending on whether use_ntp
 * is true or false.
 */
int
chk_time(ndObject obj, ndDisplay win)
{
    if (use_ntp)
	setWritable(o_servers);
    else
	setReadonly(o_servers);
    return 1;
}

/*
 * newNtpMenu() builds the yellow pages menu
 */
static ndObject
newNtpMenu()
{
    ndObject chain;
    ndObject check;

    check     = newCheck(0,1,0, "|Use Network Time Protocol to set the time",
			    &use_ntp, chk_time, "ntp.html#set");
    o_servers = newListWidget(0,3,32,5, ntp_servers, "Ntp servers",
			      0,0,0, "ntp.html#servers");

    chain = ObjChain(check, o_servers);
    if (use_ntp)
	setWritable(o_servers);
    else
	setReadonly(o_servers);

#if STAGE2
    chain = ObjChain(chain,     newOKButton(1, "NEXT", 0, 0));
    chain = ObjChain(chain,     newCancelButton(2, "BACK", 0, 0));
#else
    chain = ObjChain(chain,     newOKButton(0, "  OK  ", 0, 0));
    chain = ObjChain(chain,     newCancelButton(1, "CANCEL", 0, 0));
#endif

    return chain;
}

/*
 * ntpinventory() builds an inventory list detailing what the
 * yellow pages inventory now looks like.
 */
void
ntpinventory(char *inventory)
{
    if (use_ntp == 0)
	;
    else if (LIAcount(ntp_servers) == 0)
	strcat(inventory, "No NTP servers are defined\n");
    else {
	char *prompt = "NTP servers:";

	for (int i=0; i<LIAcount(ntp_servers); i++) {
	    sprintf(END(inventory), "%s%s\n", prompt,
					      LIAlist(ntp_servers)[i].item);
	    prompt = "            "/* same length as `NTP servers:' */;
	}
    }
} /* ntpinventory */


/*
 * ntpcommit() writes the menu back into the given Ntp and Sysconfig
 * records
 */
void
ntpcommit(Ntp &ntp, Sysconfig &sys)
{
    if (use_ntp) {
	symlink("../init.d/ntp", "/etc/rc.d/rc.m/ntp");
	ntp.drop("server");
	for (int i=0; i<LIAcount(ntp_servers); i++)
	    ntp["server"] += LIAlist(ntp_servers)[i].item;
    }
    else
	unlink("/etc/rc.d/rc.m/ntp");

    ntp.commit();
    sys.commit();
    deleteLIA(ntp_servers);
} /* ntpcommit */


/*
 * ntpinit() populates the menu variables from the given Ntp record
 */
void
ntpinit(Ntp &ntp, Sysconfig &sys)
{
    unsigned int i;
    char *p;

    use_ntp = (access("/etc/rc.d/rc.m/ntp", R_OK) == 0);

    ntp_servers = newLIA(0,0);

    for (i=0; i<ntp["server"].count(); i++)
	addToLIA(ntp_servers, 0, ntp["server"][i], 0);

    if (!ntp.has("driftfile"))
	ntp["driftfile"] = "/var/db/ntp.drift";
} /* ntpinit */


#if STAGE2
int
ntpmenu()
{
    int rc;
    ndObject chain;

    chain = newNtpMenu();
    rc = MENU(chain, -1, -1, "Network Time Protocol administration", 0, 0);
    deleteObjChain(chain);

    if (rc == MENU_OK)
	return NEXT_BUTTON;
    else if (rc == MENU_ESCAPE || rc == MENU_CANCEL)
	return BACK_BUTTON;
    else
	return ERROR_BUTTON;
} /* ntpmenu */

#else

extern "C" {
/*
 * doit actually splashes up the menus and gathers information
 */
int
doit()
{
    Ntp ntp;
    Sysconfig sys;
    int rc;
    ndObject chain;

    ntpinit(ntp, sys);
    chain = newNtpMenu();

    if ((rc = MENU(chain, -1, -1, "Network Time Protocol administration" , 0, 0)) == MENU_OK)
	ntpcommit(ntp, sys);

    deleteObjChain(chain);

    return (rc==MENU_OK) ? 0 : 1;
} /* doit */
} /* extern "C" */

#endif
