/*
 * Functions to set Univention Configuration Registry variables.
 *
 * 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
 * (at your option) 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */
#include "netcfg.h"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>

static const char *UCR[] = {
	"/usr/sbin/ucr",
	"set",
};

static char **ucr_args;
static unsigned int ucr_count;

static void ucr_free(void)
{
	char **c;

	if (!ucr_args)
		return;

	for (c = ucr_args; *c; c++)
		free(*c);
	free(ucr_args);
	ucr_args = NULL;
	ucr_count = 0;
}

void ucr_init(void)
{
	ucr_free();

	ucr_args = realloc(ucr_args, 2 * ARRAY_SIZE(UCR) * sizeof(char *));
	assert(ucr_args);

	for (ucr_count = 0; ucr_count < ARRAY_SIZE(UCR); ucr_count++)
		asprintf(&ucr_args[ucr_count], "%s", UCR[ucr_count]);
}

static void ucr_next(void)
{
	if (!(ucr_count & (ucr_count - 1))) {
		ucr_args = realloc(ucr_args, 2 * ucr_count * sizeof(char *));
		assert(ucr_args);
	}
}

void ucr_add(const char *template, ...)
{
	va_list ap;

	if (!ucr_args)
		return;

	ucr_next();
	va_start(ap, template);
	vasprintf(&ucr_args[ucr_count++], template, ap);
	va_end(ap);
}

static void ucr_exec_now(void)
{
	pid_t pid;

	ucr_next();
	ucr_args[ucr_count] = NULL;

	pid = fork();
	if (!pid) {
		chroot("/instmnt");
		chdir(".");
		execv(UCR[0], ucr_args);
	}
}

static void ucr_exec_later(char *filename)
{
	FILE *fp;
	unsigned int i;

	if ((fp = file_open(filename, "w"))) {
		if (fchmod(fileno(fp), 0755) != 0)
			exit(1);
		fprintf(fp, "#!/bin/sh\nin-target ");
		for (i = 0; i < ucr_count; i++)
			/* FIXME: This is not save for single quotes */
			fprintf(fp, "'%s'%c", ucr_args[i], i + 1 >= ucr_count ? '\n' : ' ');
		fclose(fp);
	}
}

void ucr_exec(void)
{
	if (!ucr_args)
		return;

	switch (1) {
		case 0: ucr_exec_now(); break;
		case 1: ucr_exec_later("/usr/lib/post-base-installer.d/55netcfg-ucr"); break;
		case 2: ucr_exec_later("/usr/lib/finish-install.d/55netcfg-ucr"); break;
	}
}
