/*
 *   Copyright (c) 1996 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.yellowpages.cc 1.10 01/02/08 11:34:02-08:00 orc@downbelow.pell.portland.or.us $";

/*
 * yellowpages: manage /etc/yp.conf
 */

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

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

#include "buttons.h"

static char nisdomain[40];
static char opt_ypmaster;
static LIA ypservers;

/* forward declarations */
static int chk_nisdomain(ndObject obj, ndDisplay display);
static int chk_ypmaster(ndObject obj, ndDisplay display);
static int finalcheck(ndObject obj, ndDisplay display);

extern "C" {
extern void Error(char *fmt, ...);
extern void safecopy(char *dest, char *src);
extern char *END(char *string);
}

static ndObject o_nisdom, o_ypmaster, o_ypservers;

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

    o_nisdom = newString(0,0,28,sizeof nisdomain, nisdomain,
			 0, "NIS domain", chk_nisdomain, "nis.html#domain");

    o_ypmaster = newCheck(11,3,0,"|This machine is a NIS server",
			    &opt_ypmaster, chk_ypmaster, "nis.html#master");

    o_ypservers = newListWidget(10,5,28,5,ypservers,"NIS Servers",
				0, 0, 0, "nis.html#servers");

    chain = ObjChain(o_nisdom, o_ypmaster);
    chain = ObjChain(chain,    o_ypservers);

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

    return chain;
}

/*
 * yellowpagesinventory() builds an inventory list detailing what the
 * yellow pages inventory now looks like.
 */
void
yellowpagesinventory(char *inventory)
{
    if (strlen(nisdomain) == 0)
	strcat(inventory, "NIS is disabled\n");
    else {
	sprintf(END(inventory), "NIS domain: %s\n", nisdomain);
	if (opt_ypmaster)
	    strcat(inventory, "This machine is a NIS master\n");
	else {
	    int i;
	    char *prompt = "NIS servers:";

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


/*
 * callbacks for the various menu items
 */

static int
finalcheck(ndObject obj, ndDisplay display)
{
#if STAGE2
    return 1;
#else
    char inventory[400];
    /* build an inventory list for the "changes are done" message
     */
    inventory[0] = 0;

    yellowpagesinventory(inventory);
    return dialog_yesno((unsigned char*) "Change NIS settings?",
			  (unsigned char*) inventory, -1, -1) == 0;
#endif
} /* finalcheck */


/*
 * chk_nisdomain() turns fields on or off depending on whether we're
 *                 in a NIS domain or not.
 */
static int
chk_nisdomain(ndObject obj, ndDisplay display)
{
    char *dom = (char*)objDataPtr(obj);
    int active = (strlen(dom) > 0);

    if (active) {
	setWritable(o_ypmaster);
	if (opt_ypmaster == 0)
	    setWritable(o_ypservers);
    }
    else {
	setReadonly(o_ypservers);
	setReadonly(o_ypmaster);
    }
    touchObj(o_ypservers);
    touchObj(o_ypmaster);
    return 1;
} /* chk_nisdomain */


/*
 * chk_ypmaster() turns the ypmasters list on or off depending on
 * whether we are a yp master or not.
 */
static int
chk_ypmaster(ndObject obj, ndDisplay display)
{
    if (opt_ypmaster)
	setReadonly(o_ypservers);
    else
	setWritable(o_ypservers);
    drawObj(o_ypservers, display);

    return 1;
} /* chk_ypmaster */


/*
 * yellowpagescommit() writes the menu back into the given YP and Sysconfig
 * records
 */
void
yellowpagescommit(YP &yp, Sysconfig &system)
{
    if (strlen(nisdomain) > 0)
	system["DOMAINNAME"] = nisdomain;
    else
	system.drop("DOMAINNAME");

    if (opt_ypmaster)
	system["YPMASTER"] = "1";
    else
	system.drop("YPMASTER");

    yp.Zero();

    int i;
    for (i=0; i<LIAcount(ypservers); i++)
	yp += LIAlist(ypservers)[i].item;
    deleteLIA(ypservers);

    system.commit();
    yp.commit();
} /* yellowpagescommit */


/*
 * yellowpagesinit() populates the menu variables from the given YP and
 * Sysconfig records
 */
void
yellowpagesinit(YP &yp, Sysconfig &system)
{
    unsigned int i;
    char *p;

    safecopy(nisdomain,  (char*)system["DOMAINNAME"]);
    p = (char*)system["YPMASTER"];

    opt_ypmaster = (p != (char*)0) && (strlen(p) > 0);

    ypservers = newLIA(0,0);

    for (i=0; i<yp.count(); i++)
	addToLIA(ypservers, 0, yp[i], 0);

    if (strlen(nisdomain) == 0) {
	setReadonly(o_ypmaster);
	setReadonly(o_ypservers);
    }
    else {
	if (opt_ypmaster)
	    setReadonly(o_ypservers);
	else
	    setWritable(o_ypservers);
	setWritable(o_ypmaster);
    }
} /* yellowpagesinit */


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

    chain = newYellowPagesMenu();
    rc = MENU(chain, -1, -1, "Yellow Pages (NIS) 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;
} /* yellowpagesmenu */

#else

extern "C" {
/*
 * doit actually splashes up the menus and gathers information
 */
int
doit()
{
    Sysconfig system;
    YP yp;
    int rc;
    ndObject chain;

    if (yp.magic()) {
	rc = dialog_yesno("WARNING!", "Yellow pages were set up by the\n"
				      "system.  Are you sure you want to\n"
				      "modify the yellow pages settings\n"
				      "(these changes will be lost the next\n"
				      "time the system reboots)?",
				      -1,-1);
	if (rc != 0)
	    return 1;
    }
    yellowpagesinit(yp, system);
    chain = newYellowPagesMenu();

    if ((rc = MENU(chain, -1, -1, "Yellow Pages (NIS) administration" , 0, 0)) == MENU_OK)
	yellowpagescommit(yp, system);

    deleteObjChain(chain);

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

#endif
