/*
 * dpkg-trigger - trigger management utility
 *
 * Copyright © 2007 Canonical Ltd.
 * Written by Ian Jackson <ian@davenant.greenend.org.uk>
 *
 * This 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 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, see <http://www.gnu.org/licenses/>.
 */

#include <config.h>
#include <compat.h>

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/termios.h>

#include <fcntl.h>
#if HAVE_LOCALE_H
#include <locale.h>
#endif
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/options.h>
#include <dpkg/trigdeferred.h>
#include <dpkg/triglib.h>

static const char printforhelp[] = N_(
"Type dpkg-trigger --help for help about this utility.");

static void DPKG_ATTR_NORET
printversion(const struct cmdinfo *ci, const char *value)
{
	printf(_("Debian %s package trigger utility version %s.\n"),
	       dpkg_get_progname(), DPKG_VERSION_ARCH);

	printf(_(
"This is free software; see the GNU General Public License version 2 or\n"
"later for copying conditions. There is NO warranty.\n"));

	m_output(stdout, _("<standard output>"));

	exit(0);
}

static void DPKG_ATTR_NORET
usage(const struct cmdinfo *ci, const char *value)
{
	printf(_(
"Usage: %s [<options> ...] <trigger-name>\n"
"       %s [<options> ...] <command>\n"
"\n"), dpkg_get_progname(), dpkg_get_progname());

	printf(_(
"Commands:\n"
"  --check-supported                Check if the running dpkg supports triggers.\n"
"\n"));

	printf(_(
"  -h|--help                        Show this help message.\n"
"  --version                        Show the version.\n"
"\n"));

	printf(_(
"Options:\n"
"  --admindir=<directory>           Use <directory> instead of %s.\n"
"  --by-package=<package>           Override trigger awaiter (normally set\n"
"                                     by dpkg).\n"
"  --no-await                       No package needs to await the processing.\n"
"  --no-act                         Just test - don't actually change anything.\n"
"\n"), ADMINDIR);

	m_output(stdout, _("<standard output>"));

	exit(0);
}

static const char *admindir;
static int f_noact, f_check;

static const char *bypackage, *activate;
static bool done_trig, ctrig;

static void
noawait(const struct cmdinfo *ci, const char *value)
{
	bypackage = "-";
}

static void
yespackage(const char *awname)
{
	trigdef_update_printf(" %s", awname);
}

static void
tdm_add_trig_begin(const char *trig)
{
	ctrig = !strcmp(trig, activate);
	trigdef_update_printf("%s", trig);
	if (!ctrig || done_trig)
		return;
	yespackage(bypackage);
	done_trig = true;
}

static void
tdm_add_package(const char *awname)
{
	if (ctrig && !strcmp(awname, bypackage))
		return;
	yespackage(awname);
}

static void
tdm_add_trig_end(void)
{
	trigdef_update_printf("\n");
}

static const struct trigdefmeths tdm_add = {
	.trig_begin = tdm_add_trig_begin,
	.package = tdm_add_package,
	.trig_end = tdm_add_trig_end,
};

static void DPKG_ATTR_NORET
do_check(void)
{
	enum trigdef_update_status uf;

	uf = trigdef_update_start(tduf_nolockok);
	switch (uf) {
	case tdus_error_no_dir:
		fprintf(stderr, _("%s: triggers data directory not yet created\n"),
		        dpkg_get_progname());
		exit(1);
	case tdus_error_no_deferred:
		fprintf(stderr, _("%s: trigger records not yet in existence\n"),
		        dpkg_get_progname());
		exit(1);
	case tdus_ok:
	case tdus_error_empty_deferred:
		exit(0);
	default:
		internerr("unknown trigdef_update_start return value '%d'", uf);
	}
}

static const struct cmdinfo cmdinfos[] = {
	{ "admindir",        0,   1, NULL,     &admindir },
	{ "by-package",      'f', 1, NULL,     &bypackage },
	{ "no-await",        0,   0, NULL,     &bypackage, noawait },
	{ "no-act",          0,   0, &f_noact, NULL,       NULL, 1 },
	{ "check-supported", 0,   0, &f_check, NULL,       NULL, 1 },
	{ "help",            'h', 0, NULL,     NULL,       usage   },
	{ "version",         0,   0, NULL,     NULL,       printversion  },
	{  NULL  }
};

int
main(int argc, const char *const *argv)
{
	int uf;
	const char *badname;
	enum trigdef_updateflags tduf;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	dpkg_set_progname("dpkg-trigger");
	standard_startup();
	myopt(&argv, cmdinfos, printforhelp);

	admindir = dpkg_db_set_dir(admindir);

	setvbuf(stdout, NULL, _IONBF, 0);

	if (f_check) {
		if (*argv)
			badusage(_("--%s takes no arguments"),
			         "check-supported");
		do_check();
	}

	if (!*argv || argv[1])
		badusage(_("takes one argument, the trigger name"));

	if (!bypackage) {
		bypackage = getenv("DPKG_MAINTSCRIPT_PACKAGE");
		if (!bypackage)
			ohshit(_("must be called from a maintainer script"
			         " (or with a --by-package option)"));
	}
	if (strcmp(bypackage, "-") &&
	    (badname = pkg_name_is_illegal(bypackage, NULL)))
		ohshit(_("illegal awaited package name '%.250s': %.250s"),
		       bypackage, badname);

	activate = argv[0];
	badname = trig_name_is_illegal(activate);
	if (badname)
		badusage(_("invalid trigger name `%.250s': %.250s"),
		         activate, badname);

	trigdef_set_methods(&tdm_add);

	tduf = tduf_nolockok;
	if (!f_noact)
		tduf |= tduf_write | tduf_writeifempty;
	uf = trigdef_update_start(tduf);
	if (uf >= 0) {
		trigdef_parse();
		if (!done_trig)
			trigdef_update_printf("%s %s\n", activate, bypackage);
		trigdef_process_done();
	}

	standard_shutdown();

	return 0;
}
