/*
 * sysdb.c  -  System database routines for mknbi-mgl
 *
 * Copyright (C) 2005-2007 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  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; either version 2 of the License, or
 *  any later version.
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: sysdb.c,v 1.8 2007/01/06 18:31:29 gkminix Exp $
 */

#include <common.h>
#include <nblib.h>
#include "mknbi.h"

#ifndef MKNBI_H_MGL
#error Included wrong header file
#endif


static struct sysdef dbdata;		/* Buffer for database data */



/*
 * Values for output file type database option. This is different to the
 * array containing the command line option values, because in the database
 * we need the OUTPUT_USER type in order to be able to use a user provided
 * loader file. On the command line, providing a loader file name automatically
 * selects the OUTPUT_USER type.
 */
static struct enumdef otypes[] = {
	{ "plain",	OUTPUT_PLAIN },
	{ "netboot",	OUTPUT_NETBOOT },
	{ "pxe",	OUTPUT_PXE },
	{ "dos",	OUTPUT_DOS },
	{ "user",	OUTPUT_USER },
	{ NULL,		OUTPUT_USER }
};



/*
 * Parameters in each section of database file
 */
static struct paramdef dbparams[] = {
  { "outfile",	 	par_file,	NULL,	{&dbdata.outname}},
  { "infile",		par_file,	NULL,	{&dbdata.mglname}},
  { "runtime",		par_file,	NULL,	{&dbdata.rtname}},
  { "loader",		par_file,	NULL,	{&dbdata.ldname}},
  { "include",		par_string,	NULL,	{&dbdata.incpath}},
  { "filetype",		par_enum,	otypes,	{&dbdata.outtype}},
  { NULL,	 	par_null,	NULL,	{NULL}}
};



/*
 * Copy a string from the database entry into the systems entry
 */
static inline void copyentry __F((sysentry, dbentry),
				char **sysentry AND
				char **dbentry)
{
  if (*dbentry != NULL) {
	if (*sysentry == NULL && **dbentry != '\0')
		*sysentry = *dbentry;
	else
		free(*dbentry);
	*dbentry = NULL;
  }
}



/*
 * Read system database
 */
void getdb __F((name, sysentry),
				const char *name AND
				struct sysdef *sysentry)
{
  char *namebuf;

  /* Read one entry from database file */
  namebuf = (char *)nbmalloc(strlen(name) + strlen(DBSECTNAME) + 2);
  sprintf(namebuf, "%s:%s", DBSECTNAME, name);
  memzero(&dbdata, sizeof(dbdata));
  dbdata.outtype = OUTPUT_USER;
  if (!opensysdb(TRUE))
	nbexit(-1);
  if (!readsysdb(namebuf, dbparams))
	nbexit(-1);
  closesysdb();

  /* Check that parameters are correct */
  if (dbdata.outtype != OUTPUT_USER && dbdata.ldname != NULL) {
	prnerr("unable to use filetype and loader parameters together in section <%s>",
						namebuf);
	nbexit(EXIT_DB);
  }

  /* Copy database data into systems entry */
  copyentry(&(sysentry->outname), &(dbdata.outname));
  copyentry(&(sysentry->mglname), &(dbdata.mglname));
  copyentry(&(sysentry->rtname), &(dbdata.rtname));
  copyentry(&(sysentry->incpath), &(dbdata.incpath));
  if (sysentry->ldname == NULL) {
	if (dbdata.ldname != NULL) {
		copyentry(&(sysentry->ldname), &(dbdata.ldname));
		sysentry->outtype = OUTPUT_USER;
	} else if (sysentry->outtype == OUTPUT_USER)
		sysentry->outtype = dbdata.outtype;
  }

  /* Check for missing parameters */
  if (sysentry->outname == NULL) {
	prnerr("need output file name in section <%s>", namebuf);
	nbexit(EXIT_DB);
  }
  free(namebuf);
}



/*
 * Write one entry into the database file
 */
void putdb __F((name, sysentry, definc),
				const char *name AND
				struct sysdef *sysentry AND
				const char *definc)
{
  char *sectname;
  int len;

  /* Check if we have something to write at all */
  if (name == NULL || (len = strlen(name)) == 0)
	return;

  /* Copy the boot definition into our own static data area */
  if (sysentry != &dbdata)
	dbdata = *sysentry;

  /* Generate section name */
  sectname = (char *)nbmalloc(len + strlen(DBSECTNAME) + 3);
  sprintf(sectname, "%s:%s", DBSECTNAME, name);

  /* Remove default values */
  if (dbdata.incpath != NULL && !strcmp(dbdata.incpath, definc)) {
	free(dbdata.incpath);
	dbdata.incpath = NULL;
  }

  /* Write section into database */
  if (!opensysdb(FALSE))
	nbexit(-1);
  if (!writesysdb(sectname, dbparams))
	nbexit(-1);
  closesysdb();
  free(sectname);
}

