/*
 * dpkg - main program for package management
 * configure.c - configure packages
 *
 * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
 * Copyright © 1999, 2002 Wichert Akkerman <wichert@deephackmode.org>
 *
 * 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/stat.h>
#include <sys/wait.h>
#include <sys/termios.h>

#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <dpkg/macros.h>
#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/string.h>
#include <dpkg/buffer.h>
#include <dpkg/file.h>
#include <dpkg/path.h>
#include <dpkg/subproc.h>
#include <dpkg/command.h>
#include <dpkg/triglib.h>

#include "filesdb.h"
#include "main.h"

static int conffoptcells[2][2] = {
	/* Distro !edited. */	/* Distro edited. */
	{ cfo_keep,		cfo_install },		/* User !edited. */
	{ cfo_keep,		cfo_prompt_keep },	/* User edited. */
};

static void md5hash(struct pkginfo *pkg, char *hashbuf, const char *fn);
static void showdiff(const char *old, const char *new);
static enum conffopt promptconfaction(struct pkginfo *pkg, const char *cfgfile,
                                      const char *realold, const char *realnew,
                                      int useredited, int distedited,
                                      enum conffopt what);

static void
deferred_configure_conffile(struct pkginfo *pkg, struct conffile *conff)
{
	struct filenamenode *usenode;
	static const char EMPTY_HASH[] = "-";
	char currenthash[MD5HASHLEN + 1], newdisthash[MD5HASHLEN + 1];
	int useredited, distedited;
	enum conffopt what;
	struct stat stab;
	struct varbuf cdr = VARBUF_INIT, cdr2 = VARBUF_INIT;
	char *cdr2rest;
	int r;

	usenode = namenodetouse(findnamenode(conff->name, fnn_nocopy), pkg);

	r = conffderef(pkg, &cdr, usenode->name);
	if (r == -1) {
		conff->hash = EMPTY_HASH;
		return;
	}
	md5hash(pkg, currenthash, cdr.buf);

	varbuf_reset(&cdr2);
	varbuf_add_str(&cdr2, cdr.buf);
	varbuf_end_str(&cdr2);
	/* XXX: Make sure there's enough room for extensions. */
	varbuf_grow(&cdr2, 50);
	cdr2rest = cdr2.buf + strlen(cdr.buf);
	/* From now on we can just strcpy(cdr2rest, extension); */

	strcpy(cdr2rest, DPKGNEWEXT);
	/* If the .dpkg-new file is no longer there, ignore this one. */
	if (lstat(cdr2.buf, &stab)) {
		if (errno == ENOENT)
			return;
		ohshite(_("unable to stat new distributed conffile '%.250s'"),
		        cdr2.buf);
	}
	md5hash(pkg, newdisthash, cdr2.buf);

	/* Copy the permissions from the installed version to the new
	 * distributed version. */
	if (!stat(cdr.buf, &stab))
		file_copy_perms(cdr.buf, cdr2.buf);
	else if (errno != ENOENT)
		ohshite(_("unable to stat current installed conffile `%.250s'"),
		        cdr.buf);

	/* Select what to do. */
	if (!strcmp(currenthash, newdisthash)) {
		/* They're both the same so there's no point asking silly
		 * questions. */
		useredited = -1;
		distedited = -1;
		what = cfo_identical;
	} else if (!strcmp(currenthash, NONEXISTENTFLAG) && fc_conff_miss) {
		fprintf(stderr,
		        _("\n"
		          "Configuration file `%s', does not exist on system.\n"
		          "Installing new config file as you requested.\n"),
		        usenode->name);
		what = cfo_newconff;
		useredited = -1;
		distedited = -1;
	} else if (!strcmp(conff->hash, NEWCONFFILEFLAG)) {
		if (!strcmp(currenthash, NONEXISTENTFLAG)) {
			what = cfo_newconff;
			useredited = -1;
			distedited = -1;
		} else {
			useredited = 1;
			distedited = 1;
			what = conffoptcells[useredited][distedited] |
			       cfof_isnew;
		}
	} else {
		useredited = strcmp(conff->hash, currenthash) != 0;
		distedited = strcmp(conff->hash, newdisthash) != 0;

		if (fc_conff_ask && useredited)
			what = cfo_prompt_keep;
		else
			what = conffoptcells[useredited][distedited];

		if (!strcmp(currenthash, NONEXISTENTFLAG))
			what |= cfof_userrmd;
	}

	debug(dbg_conff,
	      "deferred_configure '%s' (= '%s') useredited=%d distedited=%d what=%o",
	      usenode->name, cdr.buf, useredited, distedited, what);

	what = promptconfaction(pkg, usenode->name, cdr.buf, cdr2.buf,
	                        useredited, distedited, what);

	switch (what & ~(cfof_isnew | cfof_userrmd)) {
	case cfo_keep | cfof_backup:
		strcpy(cdr2rest, DPKGOLDEXT);
		if (unlink(cdr2.buf) && errno != ENOENT)
			warning(_("%s: failed to remove old backup '%.250s': %s"),
			        pkg->name, cdr2.buf, strerror(errno));

		varbuf_add_str(&cdr, DPKGDISTEXT);
		varbuf_end_str(&cdr);
		strcpy(cdr2rest, DPKGNEWEXT);
		trig_file_activate(usenode, pkg);
		if (rename(cdr2.buf, cdr.buf))
			warning(_("%s: failed to rename '%.250s' to '%.250s': %s"),
			        pkg->name, cdr2.buf, cdr.buf, strerror(errno));
		break;
	case cfo_keep:
		strcpy(cdr2rest, DPKGNEWEXT);
		if (unlink(cdr2.buf))
			warning(_("%s: failed to remove '%.250s': %s"),
			        pkg->name, cdr2.buf, strerror(errno));
		break;
	case cfo_install | cfof_backup:
		strcpy(cdr2rest, DPKGDISTEXT);
		if (unlink(cdr2.buf) && errno != ENOENT)
			warning(_("%s: failed to remove old distributed version '%.250s': %s"),
			        pkg->name, cdr2.buf, strerror(errno));
		strcpy(cdr2rest, DPKGOLDEXT);
		if (unlink(cdr2.buf) && errno != ENOENT)
			warning(_("%s: failed to remove '%.250s' (before overwrite): %s"),
			        pkg->name, cdr2.buf, strerror(errno));
		if (!(what & cfof_userrmd))
			if (link(cdr.buf, cdr2.buf))
				warning(_("%s: failed to link '%.250s' to '%.250s': %s"),
				        pkg->name, cdr.buf, cdr2.buf, strerror(errno));
		/* Fall through. */
	case cfo_install:
		printf(_("Installing new version of config file %s ...\n"),
		       usenode->name);
	case cfo_newconff:
		strcpy(cdr2rest, DPKGNEWEXT);
		trig_file_activate(usenode, pkg);
		if (rename(cdr2.buf, cdr.buf))
			ohshite(_("unable to install `%.250s' as `%.250s'"),
			        cdr2.buf, cdr.buf);
		break;
	default:
		internerr("unknown conffopt '%d'", what);
	}

	conff->hash = nfstrsave(newdisthash);
	modstatdb_note(pkg);

	varbuf_destroy(&cdr);
	varbuf_destroy(&cdr2);
}

/**
 * Process the deferred configure package.
 *
 * The algorithm for deciding what to configure first is as follows:
 * Loop through all packages doing a ‘try 1’ until we've been round
 * and nothing has been done, then do ‘try 2’ and ‘try 3’ likewise.
 * The incrementing of ‘dependtry’ is done by process_queue().
 *
 * Try 1:
 *   Are all dependencies of this package done? If so, do it.
 *   Are any of the dependencies missing or the wrong version?
 *     If so, abort (unless --force-depends, in which case defer).
 *   Will we need to configure a package we weren't given as an
 *     argument? If so, abort ─ except if --force-configure-any,
 *     in which case we add the package to the argument list.
 *   If none of the above, defer the package.
 *
 * Try 2:
 *   Find a cycle and break it (see above).
 *   Do as for try 1.
 *
 * Try 3 (only if --force-depends-version):
 *   Same as for try 2, but don't mind version number in dependencies.
 *
 * Try 4 (only if --force-depends):
 *   Do anyway.
 *
 * @param pkg The package to act on.
 */
void
deferred_configure(struct pkginfo *pkg)
{
	struct varbuf aemsgs = VARBUF_INIT;
	struct conffile *conff;
	int ok;

	if (pkg->status == stat_notinstalled)
		ohshit(_("no package named `%s' is installed, cannot configure"),
		       pkg->name);
	if (pkg->status == stat_installed)
		ohshit(_("package %.250s is already installed and configured"),
		       pkg->name);
	if (pkg->status != stat_unpacked && pkg->status != stat_halfconfigured)
		ohshit(_("package %.250s is not ready for configuration\n"
		         " cannot configure (current status `%.250s')"),
		       pkg->name, statusinfos[pkg->status].name);

	if (dependtry > 1)
		if (findbreakcycle(pkg))
			sincenothing = 0;

	ok = dependencies_ok(pkg, NULL, &aemsgs);
	if (ok == 1) {
		varbuf_destroy(&aemsgs);
		pkg->clientdata->istobe = itb_installnew;
		add_to_queue(pkg);
		return;
	}

	trigproc_reset_cycle();

	/*
	 * At this point removal from the queue is confirmed. This
	 * represents irreversible progress wrt trigger cycles. Only
	 * packages in stat_unpacked are automatically added to the
	 * configuration queue, and during configuration and trigger
	 * processing new packages can't enter into unpacked.
	 */

	ok = breakses_ok(pkg, &aemsgs) ? ok : 0;
	if (ok == 0) {
		sincenothing = 0;
		varbuf_end_str(&aemsgs);
		fprintf(stderr,
		        _("dpkg: dependency problems prevent configuration of %s:\n%s"),
		        pkg->name, aemsgs.buf);
		varbuf_destroy(&aemsgs);
		ohshit(_("dependency problems - leaving unconfigured"));
	} else if (aemsgs.used) {
		varbuf_end_str(&aemsgs);
		fprintf(stderr,
		        _("dpkg: %s: dependency problems, but configuring anyway as you requested:\n%s"),
		        pkg->name, aemsgs.buf);
	}
	varbuf_destroy(&aemsgs);
	sincenothing = 0;

	if (pkg->eflag & eflag_reinstreq)
		forcibleerr(fc_removereinstreq,
		            _("Package is in a very bad inconsistent state - you should\n"
		              " reinstall it before attempting configuration."));

	printf(_("Setting up %s (%s) ...\n"), pkg->name,
	       versiondescribe(&pkg->installed.version, vdew_nonambig));
	log_action("configure", pkg);

	trig_activate_packageprocessing(pkg);

	if (f_noact) {
		pkg->status = stat_installed;
		pkg->clientdata->istobe = itb_normal;
		return;
	}

	if (pkg->status == stat_unpacked) {
		debug(dbg_general, "deferred_configure updating conffiles");
		/* This will not do at all the right thing with overridden
		 * conffiles or conffiles that are the ‘target’ of an override;
		 * all the references here would be to the ‘contested’
		 * filename, and in any case there'd only be one hash for both
		 * ‘versions’ of the conffile.
		 *
		 * Overriding conffiles is a silly thing to do anyway :-). */

		modstatdb_note(pkg);

		/* On entry, the ‘new’ version of each conffile has been
		 * unpacked as ‘*.dpkg-new’, and the ‘installed’ version is
		 * as-yet untouched in ‘*’. The hash of the ‘old distributed’
		 * version is in the conffiles data for the package. If
		 * ‘*.dpkg-new’ no longer exists we assume that we've
		 * already processed this one. */
		for (conff = pkg->installed.conffiles; conff; conff = conff->next)
			deferred_configure_conffile(pkg, conff);

		pkg->status = stat_halfconfigured;
	}

	assert(pkg->status == stat_halfconfigured);

	modstatdb_note(pkg);

	maintainer_script_postinst(pkg, "configure",
	                           informativeversion(&pkg->configversion) ?
	                           versiondescribe(&pkg->configversion,
	                                           vdew_nonambig) : "",
	                           NULL);

	pkg->eflag = eflag_ok;
	pkg->trigpend_head = NULL;
	post_postinst_tasks(pkg, stat_installed);
}

/**
 * Dereference a file by following all possibly used symlinks.
 *
 * @param[in] pkg The package to act on.
 * @param[out] result The dereference conffile path.
 * @param[in] in The conffile path to dereference.
 *
 * @return An error code for the operation.
 * @retval 0 Everything went ok.
 * @retval -1 Otherwise.
 */
int
conffderef(struct pkginfo *pkg, struct varbuf *result, const char *in)
{
	static struct varbuf target = VARBUF_INIT;
	struct stat stab;
	ssize_t r;
	int loopprotect;

	varbuf_reset(result);
	varbuf_add_str(result, instdir);
	if (*in != '/')
		varbuf_add_char(result, '/');
	varbuf_add_str(result, in);
	varbuf_end_str(result);

	loopprotect = 0;

	for (;;) {
		debug(dbg_conffdetail, "conffderef in='%s' current working='%s'",
		      in, result->buf);
		if (lstat(result->buf, &stab)) {
			if (errno != ENOENT)
				warning(_("%s: unable to stat config file '%s'\n"
				          " (= '%s'): %s"),
				        pkg->name, in, result->buf, strerror(errno));
			debug(dbg_conffdetail, "conffderef nonexistent");
			return 0;
		} else if (S_ISREG(stab.st_mode)) {
			debug(dbg_conff, "conffderef in='%s' result='%s'",
			      in, result->buf);
			return 0;
		} else if (S_ISLNK(stab.st_mode)) {
			debug(dbg_conffdetail, "conffderef symlink loopprotect=%d",
			      loopprotect);
			if (loopprotect++ >= 25) {
				warning(_("%s: config file '%s' is a circular link\n"
				          " (= '%s')"), pkg->name, in, result->buf);
				return -1;
			}

			varbuf_reset(&target);
			varbuf_grow(&target, stab.st_size + 1);
			r = readlink(result->buf, target.buf, target.size);
			if (r < 0) {
				warning(_("%s: unable to readlink conffile '%s'\n"
				          " (= '%s'): %s"),
				        pkg->name, in, result->buf, strerror(errno));
				return -1;
			} else if (r != stab.st_size) {
				warning(_("symbolic link '%.250s' size has "
				          "changed from %jd to %zd"),
				        result->buf, stab.st_size, r);
				return -1;
			}
			varbuf_trunc(&target, r);
			varbuf_end_str(&target);

			debug(dbg_conffdetail,
			      "conffderef readlink gave %zd, '%s'",
			      r, target.buf);

			if (target.buf[0] == '/') {
				varbuf_reset(result);
				varbuf_add_str(result, instdir);
				debug(dbg_conffdetail,
				      "conffderef readlink absolute");
			} else {
				for (r = result->used - 1; r > 0 && result->buf[r] != '/'; r--)
					;
				if (r < 0) {
					warning(_("%s: conffile '%.250s' resolves to degenerate filename\n"
					          " ('%s' is a symlink to '%s')"),
					        pkg->name, in, result->buf,
					        target.buf);
					return -1;
				}
				if (result->buf[r] == '/')
					r++;
				varbuf_trunc(result, r);
				debug(dbg_conffdetail,
				      "conffderef readlink relative to '%.*s'",
				      (int)result->used, result->buf);
			}
			varbuf_add_buf(result, target.buf, target.used);
			varbuf_end_str(result);
		} else {
			warning(_("%s: conffile '%.250s' is not a plain file or symlink (= '%s')"),
			        pkg->name, in, result->buf);
			return -1;
		}
	}
}

/**
 * Generate a file contents MD5 hash.
 *
 * The caller is responsible for providing a buffer for the hash result
 * at least MD5HASHLEN + 1 characters long.
 *
 * @param[in] pkg The package to act on.
 * @param[out] hashbuf The buffer to store the generated hash.
 * @param[in] fn The filename.
 */
static void
md5hash(struct pkginfo *pkg, char *hashbuf, const char *fn)
{
	static int fd;

	fd = open(fn, O_RDONLY);

	if (fd >= 0) {
		push_cleanup(cu_closefd, ehflag_bombout, NULL, 0, 1, &fd);
		fd_md5(fd, hashbuf, -1, _("md5hash"));
		pop_cleanup(ehflag_normaltidy); /* fd = open(cdr.buf) */
		close(fd);
	} else if (errno == ENOENT) {
		strcpy(hashbuf, NONEXISTENTFLAG);
	} else {
		warning(_("%s: unable to open conffile %s for hash: %s"),
		        pkg->name, fn, strerror(errno));
		strcpy(hashbuf, "-");
	}
}

/**
 * Show a diff between two files.
 *
 * @param old The path to the old file.
 * @param new The path to the new file.
 */
static void
showdiff(const char *old, const char *new)
{
	pid_t pid;

	pid = subproc_fork();
	if (!pid) {
		/* Child process. */
		const char *pager;
		char cmdbuf[1024];

		pager = getenv("PAGER");
		if (!pager || !*pager)
			pager = DEFAULTPAGER;

		sprintf(cmdbuf, DIFF " -Nu %.250s %.250s | %.250s",
		        str_quote_meta(old), str_quote_meta(new), pager);

		command_shell(cmdbuf, _("conffile difference visualizer"));
	}

	/* Parent process. */
	subproc_wait(pid, _("conffile difference visualizer"));
}

/**
 * Spawn a new shell.
 *
 * Create a subprocess and execute a shell to allow the user to manually
 * solve the conffile conflict.
 *
 * @param confold The path to the old conffile.
 * @param confnew The path to the new conffile.
 */
static void
spawn_shell(const char *confold, const char *confnew)
{
	pid_t pid;

	fputs(_("Type `exit' when you're done.\n"), stderr);

	pid = subproc_fork();
	if (!pid) {
		/* Set useful variables for the user. */
		setenv("DPKG_SHELL_REASON", "conffile-prompt", 1);
		setenv("DPKG_CONFFILE_OLD", confold, 1);
		setenv("DPKG_CONFFILE_NEW", confnew, 1);

		command_shell(NULL, _("conffile shell"));
	}

	/* Parent process. */
	subproc_wait(pid, _("conffile shell"));
}

/**
 * Prompt the user for how to resolve a conffile conflict.
 *
 * When encountering a conffile conflict during configuration, the user will
 * normally be presented with a textual menu of possible actions. This
 * behavior is modified via various --force flags and perhaps on whether
 * or not a terminal is available to do the prompting.
 *
 * @param pkg The package owning the conffile.
 * @param cfgfile The path to the old conffile.
 * @param realold The path to the old conffile, dereferenced in case of a
 *        symlink, otherwise equal to cfgfile.
 * @param realnew The path to the new conffile, dereferenced in case of a
 *        symlink).
 * @param useredited A flag to indicate whether the file has been edited
 *        locally. Set to nonzero to indicate that the file has been modified.
 * @param distedited A flag to indicate whether the file has been updated
 *        between package versions. Set to nonzero to indicate that the file
 *        has been updated.
 * @param what Hints on what action should be taken by defualt.
 *
 * @return The action which should be taken based on user input and/or the
 *         default actions as configured by cmdline/configuration options.
 */
static enum conffopt
promptconfaction(struct pkginfo *pkg, const char *cfgfile,
                 const char *realold, const char *realnew,
                 int useredited, int distedited, enum conffopt what)
{
	const char *s;
	int c, cc;

	if (!(what & cfof_prompt))
		return what;

	statusfd_send("status: %s : %s : '%s' '%s' %i %i ",
	              cfgfile, "conffile-prompt",
	              realold, realnew, useredited, distedited);

	do {
		/* Flush the terminal's input in case the user involuntarily
		 * typed some characters. */
		tcflush(STDIN_FILENO, TCIFLUSH);
		fprintf(stderr, _("\nConfiguration file `%s'"), cfgfile);
		if (strcmp(cfgfile, realold))
			fprintf(stderr, _(" (actually `%s')"), realold);

		if (what & cfof_isnew) {
			fprintf(stderr,
			        _("\n"
			          " ==> File on system created by you or by a script.\n"
			          " ==> File also in package provided by package maintainer.\n"));
		} else {
			fprintf(stderr, !useredited ?
			        _("\n     Not modified since installation.\n") :
			        !(what & cfof_userrmd) ?
			        _("\n ==> Modified (by you or by a script) since installation.\n") :
			        _("\n ==> Deleted (by you or by a script) since installation.\n"));

			fprintf(stderr, distedited ?
			        _(" ==> Package distributor has shipped an updated version.\n") :
			        _("     Version in package is the same as at last installation.\n"));
		}

		/* No --force-confdef but a forcible situtation. */
		/* TODO: check if this condition can not be simplified to
		 *       just !fc_conff_def */
		if (!(fc_conff_def && (what & (cfof_install | cfof_keep)))) {
			if (fc_conff_new) {
				fprintf(stderr, _(" ==> Using new file as you requested.\n"));
				cc = 'y';
				break;
			} else if (fc_conff_old) {
				fprintf(stderr, _(" ==> Using current old file as you requested.\n"));
				cc = 'n';
				break;
			}
		}

		/* Force the default action (if there is one. */
		if (fc_conff_def) {
			if (what & cfof_keep) {
				fprintf(stderr, _(" ==> Keeping old config file as default.\n"));
				cc = 'n';
				break;
			} else if (what & cfof_install) {
				fprintf(stderr, _(" ==> Using new config file as default.\n"));
				cc = 'y';
				break;
			}
		}

		fprintf(stderr,
		        _("   What would you like to do about it ?  Your options are:\n"
		          "    Y or I  : install the package maintainer's version\n"
		          "    N or O  : keep your currently-installed version\n"
		          "      D     : show the differences between the versions\n"
		          "      Z     : start a shell to examine the situation\n"));

		if (what & cfof_keep)
			fprintf(stderr, _(" The default action is to keep your current version.\n"));
		else if (what & cfof_install)
			fprintf(stderr, _(" The default action is to install the new version.\n"));

		s = path_basename(cfgfile);
		fprintf(stderr, "*** %s (Y/I/N/O/D/Z) %s ? ",
		        s,
		        (what & cfof_keep) ? _("[default=N]") :
		        (what & cfof_install) ? _("[default=Y]") :
		        _("[no default]"));

		if (ferror(stderr))
			ohshite(_("error writing to stderr, discovered before conffile prompt"));

		cc = 0;
		while ((c = getchar()) != EOF && c != '\n')
			if (!isspace(c) && !cc)
				cc = tolower(c);

		if (c == EOF) {
			if (ferror(stdin))
				ohshite(_("read error on stdin at conffile prompt"));
			ohshit(_("EOF on stdin at conffile prompt"));
		}

		if (!cc) {
			if (what & cfof_keep) {
				cc = 'n';
				break;
			} else if (what & cfof_install) {
				cc = 'y';
				break;
			}
		}

		/* FIXME: Say something if silently not install. */
		if (cc == 'd')
			showdiff(realold, realnew);

		if (cc == 'z')
			spawn_shell(realold, realnew);
	} while (!strchr("yino", cc));

	log_message("conffile %s %s", cfgfile,
	            (cc == 'i' || cc == 'y') ? "install" : "keep");

	what &= cfof_userrmd;

	switch (cc) {
	case 'i':
	case 'y':
		what |= cfof_install | cfof_backup;
		break;

	case 'n':
	case 'o':
		what |= cfof_keep | cfof_backup;
		break;

	default:
		internerr("unknown response '%d'", cc);
	}

	return what;
}
