/*
 * dpkg - main program for package management
 * archives.c - actions that process archive files, mainly unpack
 *
 * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk>
 * Copyright © 2000 Wichert Akkerman <wakkerma@debian.org>
 * Copyright © 2007-2011 Guillem Jover <guillem@debian.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/time.h>
#include <sys/stat.h>

#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <obstack.h>
#define obstack_chunk_alloc m_malloc
#define obstack_chunk_free free

#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/path.h>
#include <dpkg/fdio.h>
#include <dpkg/buffer.h>
#include <dpkg/subproc.h>
#include <dpkg/command.h>
#include <dpkg/file.h>
#include <dpkg/tarfn.h>
#include <dpkg/options.h>
#include <dpkg/triglib.h>

#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif

#include "filesdb.h"
#include "main.h"
#include "archives.h"
#include "filters.h"

static inline void
fd_writeback_init(int fd)
{
  /* Ignore the return code as it should be considered equivalent to an
   * asynchronous hint for the kernel, we are doing an fsync() later on
   * anyway. */
#if defined(SYNC_FILE_RANGE_WRITE)
  sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
#elif defined(HAVE_POSIX_FADVISE)
  posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
#endif
}

static struct obstack tar_obs;
static bool tarobs_init = false;

/**
 * Ensure the obstack is properly initialized.
 */
static void ensureobstackinit(void) {

  if (!tarobs_init) {
    obstack_init(&tar_obs);
    tarobs_init = true;
  }
}

/**
 * Destroy the obstack.
 */
static void destroyobstack(void) {
  if (tarobs_init) {
    obstack_free(&tar_obs, NULL);
    tarobs_init = false;
  }
}

/**
 * Check if a file or directory will save a package from disappearance.
 *
 * A package can only be saved by a file or directory which is part
 * only of itself - it must be neither part of the new package being
 * installed nor part of any 3rd package (this is important so that
 * shared directories don't stop packages from disappearing).
 */
bool
filesavespackage(struct fileinlist *file,
                 struct pkginfo *pkgtobesaved,
                 struct pkginfo *pkgbeinginstalled)
{
  struct filepackages_iterator *iter;
  struct pkginfo *divpkg, *thirdpkg;

  debug(dbg_eachfiledetail,"filesavespackage file `%s' package %s",
        file->namenode->name,pkgtobesaved->name);

  /* If the file is a contended one and it's overridden by either
   * the package we're considering disappearing or the package
   * we're installing then they're not actually the same file, so
   * we can't disappear the package - it is saved by this file. */
  if (file->namenode->divert && file->namenode->divert->useinstead) {
    divpkg= file->namenode->divert->pkg;
    if (divpkg == pkgtobesaved || divpkg == pkgbeinginstalled) {
      debug(dbg_eachfiledetail,"filesavespackage ... diverted -- save!");
      return true;
    }
  }
  /* Is the file in the package being installed? If so then it can't save. */
  if (file->namenode->flags & fnnf_new_inarchive) {
    debug(dbg_eachfiledetail,"filesavespackage ... in new archive -- no save");
    return false;
  }
  /* Look for a 3rd package which can take over the file (in case
   * it's a directory which is shared by many packages. */
  iter = filepackages_iter_new(file->namenode);
  while ((thirdpkg = filepackages_iter_next(iter))) {
    debug(dbg_eachfiledetail, "filesavespackage ... also in %s",
          thirdpkg->name);

    /* Is this not the package being installed or the one being
     * checked for disappearance? */
    if (thirdpkg == pkgbeinginstalled || thirdpkg == pkgtobesaved)
      continue;

    /* If !fileslistvalid then we've already disappeared this one, so
     * we shouldn't try to make it take over this shared directory. */
    debug(dbg_eachfiledetail,"filesavespackage ...  is 3rd package");

    if (!thirdpkg->clientdata->fileslistvalid) {
      debug(dbg_eachfiledetail, "process_archive ... already disappeared!");
      continue;
    }

    /* We've found a package that can take this file. */
    debug(dbg_eachfiledetail, "filesavespackage ...  taken -- no save");
    return false;
  }
  filepackages_iter_free(iter);

  debug(dbg_eachfiledetail, "filesavespackage ... not taken -- save !");
  return true;
}

void cu_pathname(int argc, void **argv) {
  ensure_pathname_nonexisting((char*)(argv[0]));
}

int tarfileread(void *ud, char *buf, int len) {
  struct tarcontext *tc= (struct tarcontext*)ud;
  int r;

  r = fd_read(tc->backendpipe, buf, len);
  if (r < 0)
    ohshite(_("error reading from dpkg-deb pipe"));
  return r;
}

static void
tarfile_skip_one_forward(struct tarcontext *tc, struct tar_entry *ti)
{
  size_t r;
  char databuf[TARBLKSZ];

  /* We need to advance the tar file to the next object, so read the
   * file data and set it to oblivion. */
  if (ti->type == tar_filetype_file) {
    char fnamebuf[256];

    fd_skip(tc->backendpipe, ti->size,
            _("skipped unpacking file '%.255s' (replaced or excluded?)"),
            path_quote_filename(fnamebuf, ti->name, 256));
    r = ti->size % TARBLKSZ;
    if (r > 0)
      if (fd_read(tc->backendpipe, databuf, TARBLKSZ - r) < 0)
        ohshite(_("error reading from dpkg-deb pipe"));
  }
}

int fnameidlu;
struct varbuf fnamevb;
struct varbuf fnametmpvb;
struct varbuf fnamenewvb;
struct pkg_deconf_list *deconfigure = NULL;

static time_t currenttime;

static int
does_replace(struct pkginfo *newpigp, struct pkgbin *newpifp,
             struct pkginfo *oldpigp, struct pkgbin *oldpifp)
{
  struct dependency *dep;

  debug(dbg_depcon,"does_replace new=%s old=%s (%s)",newpigp->name,
        oldpigp->name, versiondescribe(&oldpifp->version, vdew_always));
  for (dep= newpifp->depends; dep; dep= dep->next) {
    if (dep->type != dep_replaces || dep->list->ed != oldpigp) continue;
    debug(dbg_depcondetail,"does_replace ... found old, version %s",
          versiondescribe(&dep->list->version,vdew_always));
    if (!versionsatisfied(oldpifp, dep->list))
      continue;
    debug(dbg_depcon,"does_replace ... yes");
    return true;
  }
  debug(dbg_depcon,"does_replace ... no");
  return false;
}

static void
tarobject_set_mtime(struct tar_entry *te, const char *path)
{
  struct timeval tv[2];

  tv[0].tv_sec = currenttime;
  tv[0].tv_usec = 0;
  tv[1].tv_sec = te->mtime;
  tv[1].tv_usec = 0;

  if (te->type == tar_filetype_symlink) {
#ifdef HAVE_LUTIMES
    if (lutimes(path, tv) && errno != ENOSYS)
      ohshite(_("error setting timestamps of `%.255s'"), path);
#endif
  } else {
    if (utimes(path, tv))
      ohshite(_("error setting timestamps of `%.255s'"), path);
  }
}

static void
tarobject_set_perms(struct tar_entry *te, const char *path, struct file_stat *st)
{
  if (te->type == tar_filetype_file)
    return; /* Already handled using the file descriptor. */

  if (te->type == tar_filetype_symlink) {
    if (lchown(path, st->uid, st->gid))
      ohshite(_("error setting ownership of symlink `%.255s'"), path);
  } else {
    if (chown(path, st->uid, st->gid))
      ohshite(_("error setting ownership of `%.255s'"), path);
    if (chmod(path, st->mode & ~S_IFMT))
      ohshite(_("error setting permissions of `%.255s'"), path);
  }
}

static void
tarobject_set_se_context(const char *matchpath, const char *path, mode_t mode)
{
#ifdef WITH_SELINUX
  static int selinux_enabled = -1;
  security_context_t scontext = NULL;
  int ret;

  /* If there's no file type, just give up. */
  if ((mode & S_IFMT) == 0)
    return;

  /* Set selinux_enabled if it is not already set (singleton). */
  if (selinux_enabled < 0)
    selinux_enabled = (is_selinux_enabled() > 0);

  /* If SE Linux is not enabled just do nothing. */
  if (!selinux_enabled)
    return;

  /* XXX: Well, we could use set_matchpathcon_printf() to redirect the
   * errors from the following bit, but that seems too much effort. */

  /* Do nothing if we can't figure out what the context is, or if it has
   * no context; in which case the default context shall be applied. */
  ret = matchpathcon(matchpath, mode & S_IFMT, &scontext);
  if (ret == -1 || (ret == 0 && scontext == NULL))
    return;

  if (strcmp(scontext, "<<none>>") != 0) {
    if (lsetfilecon(path, scontext) < 0)
      /* XXX: This might need to be fatal instead!? */
      perror("Error setting security context for next file object:");
  }

  freecon(scontext);
#endif /* WITH_SELINUX */
}

void setupfnamevbs(const char *filename) {
  varbuf_trunc(&fnamevb, fnameidlu);
  varbuf_add_str(&fnamevb, filename);
  varbuf_end_str(&fnamevb);

  varbuf_trunc(&fnametmpvb, fnameidlu);
  varbuf_add_str(&fnametmpvb, filename);
  varbuf_add_str(&fnametmpvb, DPKGTEMPEXT);
  varbuf_end_str(&fnametmpvb);

  varbuf_trunc(&fnamenewvb, fnameidlu);
  varbuf_add_str(&fnamenewvb, filename);
  varbuf_add_str(&fnamenewvb, DPKGNEWEXT);
  varbuf_end_str(&fnamenewvb);

  debug(dbg_eachfiledetail, "setupvnamevbs main=`%s' tmp=`%s' new=`%s'",
        fnamevb.buf, fnametmpvb.buf, fnamenewvb.buf);
}

/**
 * Securely remove a pathname.
 *
 * This is a secure version of remove(3) using secure_unlink() instead of
 * unlink(2).
 *
 * @retval  0 On success.
 * @retval -1 On failure, just like unlink(2) & rmdir(2).
 */
int
secure_remove(const char *filename)
{
  int r, e;

  if (!rmdir(filename)) {
    debug(dbg_eachfiledetail, "secure_remove '%s' rmdir OK", filename);
    return 0;
  }

  if (errno != ENOTDIR) {
    e= errno;
    debug(dbg_eachfiledetail, "secure_remove '%s' rmdir %s", filename,
          strerror(e));
    errno= e; return -1;
  }

  r = secure_unlink(filename);
  e = errno;
  debug(dbg_eachfiledetail, "secure_remove '%s' unlink %s",
        filename, r ? strerror(e) : "OK");
  errno= e; return r;
}

struct fileinlist *addfiletolist(struct tarcontext *tc,
				 struct filenamenode *namenode) {
  struct fileinlist *nifd;

  nifd= obstack_alloc(&tar_obs, sizeof(struct fileinlist));
  nifd->namenode= namenode;
  nifd->next = NULL;
  *tc->newfilesp = nifd;
  tc->newfilesp = &nifd->next;
  return nifd;
}

static void
remove_file_from_list(struct tarcontext *tc, struct tar_entry *ti,
                      struct fileinlist **oldnifd,
                      struct fileinlist *nifd)
{
  obstack_free(&tar_obs, nifd);
  tc->newfilesp = oldnifd;
  *oldnifd = NULL;
}

static bool
linktosameexistingdir(const struct tar_entry *ti, const char *fname,
                      struct varbuf *symlinkfn)
{
  struct stat oldstab, newstab;
  int statr;
  const char *lastslash;

  statr= stat(fname, &oldstab);
  if (statr) {
    if (!(errno == ENOENT || errno == ELOOP || errno == ENOTDIR))
      ohshite(_("failed to stat (dereference) existing symlink `%.250s'"),
              fname);
    return false;
  }
  if (!S_ISDIR(oldstab.st_mode))
    return false;

  /* But is it to the same dir? */
  varbuf_reset(symlinkfn);
  if (ti->linkname[0] == '/') {
    varbuf_add_str(symlinkfn, instdir);
  } else {
    lastslash= strrchr(fname, '/');
    assert(lastslash);
    varbuf_add_buf(symlinkfn, fname, (lastslash - fname) + 1);
  }
  varbuf_add_str(symlinkfn, ti->linkname);
  varbuf_end_str(symlinkfn);

  statr= stat(symlinkfn->buf, &newstab);
  if (statr) {
    if (!(errno == ENOENT || errno == ELOOP || errno == ENOTDIR))
      ohshite(_("failed to stat (dereference) proposed new symlink target"
                " `%.250s' for symlink `%.250s'"), symlinkfn->buf, fname);
    return false;
  }
  if (!S_ISDIR(newstab.st_mode))
    return false;
  if (newstab.st_dev != oldstab.st_dev ||
      newstab.st_ino != oldstab.st_ino)
    return false;
  return true;
}

int
tarobject(void *ctx, struct tar_entry *ti)
{
  static struct varbuf conffderefn, hardlinkfn, symlinkfn;
  static int fd;
  const char *usename;
  struct filenamenode *usenode;
  struct filenamenode *linknode;

  struct conffile *conff;
  struct tarcontext *tc = ctx;
  bool existingdir, keepexisting;
  int statr;
  ssize_t r;
  struct stat stab, stabtmp;
  char databuf[TARBLKSZ];
  struct file_stat *st;
  struct fileinlist *nifd, **oldnifd;
  struct pkginfo *divpkg, *otherpkg;

  ensureobstackinit();

  /* Append to list of files.
   * The trailing ‘/’ put on the end of names in tarfiles has already
   * been stripped by tar_extractor(). */
  oldnifd= tc->newfilesp;
  nifd= addfiletolist(tc, findnamenode(ti->name, 0));
  nifd->namenode->flags |= fnnf_new_inarchive;

  debug(dbg_eachfile,
        "tarobject ti->name='%s' mode=%lo owner=%u.%u type=%d(%c)"
        " ti->linkname='%s' namenode='%s' flags=%o instead='%s'",
        ti->name, (long)ti->stat.mode,
        (unsigned)ti->stat.uid, (unsigned)ti->stat.gid,
        ti->type,
        ti->type >= '0' && ti->type <= '6' ? "-hlcbdp"[ti->type - '0'] : '?',
        ti->linkname,
        nifd->namenode->name, nifd->namenode->flags,
        nifd->namenode->divert && nifd->namenode->divert->useinstead
        ? nifd->namenode->divert->useinstead->name : "<none>");

  if (nifd->namenode->divert && nifd->namenode->divert->camefrom) {
    divpkg= nifd->namenode->divert->pkg;

    if (divpkg) {
      forcibleerr(fc_overwritediverted,
                  _("trying to overwrite `%.250s', which is the "
                    "diverted version of `%.250s' (package: %.100s)"),
                  nifd->namenode->name, nifd->namenode->divert->camefrom->name,
                  divpkg->name);
    } else {
      forcibleerr(fc_overwritediverted,
                  _("trying to overwrite `%.250s', which is the "
                    "diverted version of `%.250s'"),
                  nifd->namenode->name, nifd->namenode->divert->camefrom->name);
    }
  }

  if (nifd->namenode->statoverride)
    st = nifd->namenode->statoverride;
  else
    st = &ti->stat;

  usenode = namenodetouse(nifd->namenode, tc->pkg);
  usename = usenode->name + 1; /* Skip the leading '/'. */

  trig_file_activate(usenode, tc->pkg);

  if (nifd->namenode->flags & fnnf_new_conff) {
    /* If it's a conffile we have to extract it next to the installed
     * version (i.e. we do the usual link-following). */
    if (conffderef(tc->pkg, &conffderefn, usename))
      usename= conffderefn.buf;
    debug(dbg_conff,"tarobject fnnf_new_conff deref=`%s'",usename);
  }

  setupfnamevbs(usename);

  statr= lstat(fnamevb.buf,&stab);
  if (statr) {
    /* The lstat failed. */
    if (errno != ENOENT && errno != ENOTDIR)
      ohshite(_("unable to stat `%.255s' (which I was about to install)"),
              ti->name);
    /* OK, so it doesn't exist.
     * However, it's possible that we were in the middle of some other
     * backup/restore operation and were rudely interrupted.
     * So, we see if we have .dpkg-tmp, and if so we restore it. */
    if (rename(fnametmpvb.buf,fnamevb.buf)) {
      if (errno != ENOENT && errno != ENOTDIR)
        ohshite(_("unable to clean up mess surrounding `%.255s' before "
                  "installing another version"), ti->name);
      debug(dbg_eachfiledetail,"tarobject nonexistent");
    } else {
      debug(dbg_eachfiledetail,"tarobject restored tmp to main");
      statr= lstat(fnamevb.buf,&stab);
      if (statr) ohshite(_("unable to stat restored `%.255s' before installing"
                           " another version"), ti->name);
    }
  } else {
    debug(dbg_eachfiledetail,"tarobject already exists");
  }

  /* Check to see if it's a directory or link to one and we don't need to
   * do anything. This has to be done now so that we don't die due to
   * a file overwriting conflict. */
  existingdir = false;
  switch (ti->type) {
  case tar_filetype_symlink:
    /* If it's already an existing directory, do nothing. */
    if (!statr && S_ISDIR(stab.st_mode)) {
      debug(dbg_eachfiledetail, "tarobject symlink exists as directory");
      existingdir = true;
    } else if (!statr && S_ISLNK(stab.st_mode)) {
      if (linktosameexistingdir(ti, fnamevb.buf, &symlinkfn))
        existingdir = true;
    }
    break;
  case tar_filetype_dir:
    /* If it's already an existing directory, do nothing. */
    if (!stat(fnamevb.buf,&stabtmp) && S_ISDIR(stabtmp.st_mode)) {
      debug(dbg_eachfiledetail, "tarobject directory exists");
      existingdir = true;
    }
    break;
  case tar_filetype_file:
  case tar_filetype_chardev:
  case tar_filetype_blockdev:
  case tar_filetype_fifo:
  case tar_filetype_hardlink:
    break;
  default:
    ohshit(_("archive contained object `%.255s' of unknown type 0x%x"),
           ti->name, ti->type);
  }

  keepexisting = false;
  if (!existingdir) {
    struct filepackages_iterator *iter;

    iter = filepackages_iter_new(nifd->namenode);
    while ((otherpkg = filepackages_iter_next(iter))) {
      if (otherpkg == tc->pkg)
        continue;
      debug(dbg_eachfile, "tarobject ... found in %s", otherpkg->name);

      if (nifd->namenode->divert && nifd->namenode->divert->useinstead) {
        /* Right, so we may be diverting this file. This makes the conflict
         * OK iff one of us is the diverting package (we don't need to
         * check for both being the diverting package, obviously). */
        divpkg = nifd->namenode->divert->pkg;
        debug(dbg_eachfile, "tarobject ... diverted, divpkg=%s",
              divpkg ? divpkg->name : "<none>");
        if (otherpkg == divpkg || tc->pkg == divpkg)
          continue;
      }

      /* If the new object is a directory and the previous object does
       * not exist assume it's also a directory and skip further checks.
       * XXX: Ideally with more information about the installed files we
       * could perform more clever checks. */
      if (statr != 0 && ti->type == tar_filetype_dir) {
        debug(dbg_eachfile, "tarobject ... assuming shared directory");
        continue;
      }

      /* Nope? Hmm, file conflict, perhaps. Check Replaces. */
      switch (otherpkg->clientdata->replacingfilesandsaid) {
      case 2:
        keepexisting = true;
      case 1:
        continue;
      }

      /* Is the package with the conflicting file in the “config files only”
       * state? If so it must be a config file and we can silenty take it
       * over. */
      if (otherpkg->status == stat_configfiles)
        continue;

      /* Perhaps we're removing a conflicting package? */
      if (otherpkg->clientdata->istobe == itb_remove)
        continue;

      /* Is the file an obsolete conffile in the other package
       * and a conffile in the new package? */
      if ((nifd->namenode->flags & fnnf_new_conff) &&
          !statr && S_ISREG(stab.st_mode)) {
        for (conff = otherpkg->installed.conffiles;
             conff;
             conff = conff->next) {
          if (!conff->obsolete)
            continue;
          if (stat(conff->name, &stabtmp)) {
            if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP)
              continue;
            else
              ohshite(_("cannot stat file '%s'"), conff->name);
          }
          if (stabtmp.st_dev == stab.st_dev &&
              stabtmp.st_ino == stab.st_ino)
            break;
        }
        if (conff) {
          debug(dbg_eachfiledetail, "tarobject other's obsolete conffile");
          /* process_archive() will have copied its hash already. */
          continue;
        }
      }

      if (does_replace(tc->pkg, &tc->pkg->available,
                       otherpkg, &otherpkg->installed)) {
        printf(_("Replacing files in old package %s ...\n"),otherpkg->name);
        otherpkg->clientdata->replacingfilesandsaid = 1;
      } else if (does_replace(otherpkg, &otherpkg->installed,
                              tc->pkg, &tc->pkg->available)) {
        printf(_("Replaced by files in installed package %s ...\n"),
               otherpkg->name);
        otherpkg->clientdata->replacingfilesandsaid = 2;
        nifd->namenode->flags &= ~fnnf_new_inarchive;
        keepexisting = true;
      } else {
        /* At this point we are replacing something without a Replaces. */
        if (!statr && S_ISDIR(stab.st_mode)) {
          forcibleerr(fc_overwritedir,
                      _("trying to overwrite directory '%.250s' "
                        "in package %.250s %.250s with nondirectory"),
                      nifd->namenode->name, otherpkg->name,
                      versiondescribe(&otherpkg->installed.version,
                                      vdew_nonambig));
        } else {
          forcibleerr(fc_overwrite,
                      _("trying to overwrite '%.250s', "
                        "which is also in package %.250s %.250s"),
                      nifd->namenode->name, otherpkg->name,
                      versiondescribe(&otherpkg->installed.version,
                                      vdew_nonambig));
        }
      }
    }
    filepackages_iter_free(iter);
  }

  if (keepexisting) {
    remove_file_from_list(tc, ti, oldnifd, nifd);
    tarfile_skip_one_forward(tc, ti);
    return 0;
  }

  if (filter_should_skip(ti)) {
    nifd->namenode->flags &= ~fnnf_new_inarchive;
    nifd->namenode->flags |= fnnf_filtered;
    tarfile_skip_one_forward(tc, ti);

    return 0;
  }

  if (existingdir)
    return 0;

  /* Now, at this stage we want to make sure neither of .dpkg-new and
   * .dpkg-tmp are hanging around. */
  ensure_pathname_nonexisting(fnamenewvb.buf);
  ensure_pathname_nonexisting(fnametmpvb.buf);

  /* Now we start to do things that we need to be able to undo
   * if something goes wrong. Watch out for the CLEANUP comments to
   * keep an eye on what's installed on the disk at each point. */
  push_cleanup(cu_installnew, ~ehflag_normaltidy, NULL, 0, 1, (void *)nifd);

  /*
   * CLEANUP: Now we either have the old file on the disk, or not, in
   * its original filename.
   */

  /* Extract whatever it is as .dpkg-new ... */
  switch (ti->type) {
  case tar_filetype_file:
    /* We create the file with mode 0 to make sure nobody can do anything with
     * it until we apply the proper mode, which might be a statoverride. */
    fd= open(fnamenewvb.buf, (O_CREAT|O_EXCL|O_WRONLY), 0);
    if (fd < 0)
      ohshite(_("unable to create `%.255s' (while processing `%.255s')"),
              fnamenewvb.buf, ti->name);
    push_cleanup(cu_closefd, ehflag_bombout, NULL, 0, 1, &fd);
    debug(dbg_eachfiledetail, "tarobject file open size=%jd",
          (intmax_t)ti->size);
    { char fnamebuf[256];
    fd_fd_copy(tc->backendpipe, fd, ti->size,
               _("backend dpkg-deb during `%.255s'"),
               path_quote_filename(fnamebuf, ti->name, 256));
    }
    r = ti->size % TARBLKSZ;
    if (r > 0)
      if (fd_read(tc->backendpipe, databuf, TARBLKSZ - r) < 0)
        ohshite(_("error reading from dpkg-deb pipe"));

    fd_writeback_init(fd);

    if (nifd->namenode->statoverride)
      debug(dbg_eachfile, "tarobject ... stat override, uid=%d, gid=%d, mode=%04o",
			  nifd->namenode->statoverride->uid,
			  nifd->namenode->statoverride->gid,
			  nifd->namenode->statoverride->mode);
    if (fchown(fd, st->uid, st->gid))
      ohshite(_("error setting ownership of `%.255s'"), ti->name);
    if (fchmod(fd, st->mode & ~S_IFMT))
      ohshite(_("error setting permissions of `%.255s'"), ti->name);

    /* Postpone the fsync, to try to avoid massive I/O degradation. */
    if (!fc_unsafe_io)
      nifd->namenode->flags |= fnnf_deferred_fsync;

    pop_cleanup(ehflag_normaltidy); /* fd = open(fnamenewvb.buf) */
    if (close(fd))
      ohshite(_("error closing/writing `%.255s'"), ti->name);
    break;
  case tar_filetype_fifo:
    if (mkfifo(fnamenewvb.buf,0))
      ohshite(_("error creating pipe `%.255s'"), ti->name);
    debug(dbg_eachfiledetail, "tarobject fifo");
    break;
  case tar_filetype_chardev:
    if (mknod(fnamenewvb.buf, S_IFCHR, ti->dev))
      ohshite(_("error creating device `%.255s'"), ti->name);
    debug(dbg_eachfiledetail, "tarobject chardev");
    break;
  case tar_filetype_blockdev:
    if (mknod(fnamenewvb.buf, S_IFBLK, ti->dev))
      ohshite(_("error creating device `%.255s'"), ti->name);
    debug(dbg_eachfiledetail, "tarobject blockdev");
    break;
  case tar_filetype_hardlink:
    varbuf_reset(&hardlinkfn);
    varbuf_add_str(&hardlinkfn, instdir);
    varbuf_add_char(&hardlinkfn, '/');
    linknode = findnamenode(ti->linkname, 0);
    varbuf_add_str(&hardlinkfn, namenodetouse(linknode, tc->pkg)->name);
    if (linknode->flags & (fnnf_deferred_rename|fnnf_new_conff))
      varbuf_add_str(&hardlinkfn, DPKGNEWEXT);
    varbuf_end_str(&hardlinkfn);
    if (link(hardlinkfn.buf,fnamenewvb.buf))
      ohshite(_("error creating hard link `%.255s'"), ti->name);
    debug(dbg_eachfiledetail, "tarobject hardlink");
    break;
  case tar_filetype_symlink:
    /* We've already checked for an existing directory. */
    if (symlink(ti->linkname, fnamenewvb.buf))
      ohshite(_("error creating symbolic link `%.255s'"), ti->name);
    debug(dbg_eachfiledetail, "tarobject symlink creating");
    break;
  case tar_filetype_dir:
    /* We've already checked for an existing directory. */
    if (mkdir(fnamenewvb.buf,0))
      ohshite(_("error creating directory `%.255s'"), ti->name);
    debug(dbg_eachfiledetail, "tarobject directory creating");
    break;
  default:
    internerr("unknown tar type '%d', but already checked", ti->type);
  }

  tarobject_set_perms(ti, fnamenewvb.buf, st);
  tarobject_set_mtime(ti, fnamenewvb.buf);
  tarobject_set_se_context(fnamevb.buf, fnamenewvb.buf, st->mode);

  /*
   * CLEANUP: Now we have extracted the new object in .dpkg-new (or,
   * if the file already exists as a directory and we were trying to
   * extract a directory or symlink, we returned earlier, so we don't
   * need to worry about that here).
   *
   * The old file is still in the original filename,
   */

  /* First, check to see if it's a conffile. If so we don't install
   * it now - we leave it in .dpkg-new for --configure to take care of. */
  if (nifd->namenode->flags & fnnf_new_conff) {
    debug(dbg_conffdetail,"tarobject conffile extracted");
    nifd->namenode->flags |= fnnf_elide_other_lists;
    return 0;
  }

  /* Now we move the old file out of the way, the backup file will
   * be deleted later. */
  if (statr) {
    /* Don't try to back it up if it didn't exist. */
    debug(dbg_eachfiledetail,"tarobject new - no backup");
  } else {
    if (ti->type == tar_filetype_dir || S_ISDIR(stab.st_mode)) {
      /* One of the two is a directory - can't do atomic install. */
      debug(dbg_eachfiledetail,"tarobject directory, nonatomic");
      nifd->namenode->flags |= fnnf_no_atomic_overwrite;
      if (rename(fnamevb.buf,fnametmpvb.buf))
        ohshite(_("unable to move aside `%.255s' to install new version"),
                ti->name);
    } else if (S_ISLNK(stab.st_mode)) {
      /* We can't make a symlink with two hardlinks, so we'll have to
       * copy it. (Pretend that making a copy of a symlink is the same
       * as linking to it.) */
      varbuf_reset(&symlinkfn);
      varbuf_grow(&symlinkfn, stab.st_size + 1);
      r = readlink(fnamevb.buf, symlinkfn.buf, symlinkfn.size);
      if (r < 0)
        ohshite(_("unable to read link `%.255s'"), ti->name);
      else if (r != stab.st_size)
        ohshit(_("symbolic link '%.250s' size has changed from %jd to %zd"),
               fnamevb.buf, stab.st_size, r);
      varbuf_trunc(&symlinkfn, r);
      varbuf_end_str(&symlinkfn);
      if (symlink(symlinkfn.buf,fnametmpvb.buf))
        ohshite(_("unable to make backup symlink for `%.255s'"), ti->name);
      if (lchown(fnametmpvb.buf,stab.st_uid,stab.st_gid))
        ohshite(_("unable to chown backup symlink for `%.255s'"), ti->name);
      tarobject_set_se_context(fnamevb.buf, fnametmpvb.buf, stab.st_mode);
    } else {
      debug(dbg_eachfiledetail,"tarobject nondirectory, `link' backup");
      if (link(fnamevb.buf,fnametmpvb.buf))
        ohshite(_("unable to make backup link of `%.255s' before installing new version"),
                ti->name);
    }
  }

  /*
   * CLEANUP: Now the old file is in .dpkg-tmp, and the new file is still
   * in .dpkg-new.
   */

  if (ti->type == tar_filetype_file || ti->type == tar_filetype_hardlink ||
      ti->type == tar_filetype_symlink) {
    nifd->namenode->flags |= fnnf_deferred_rename;

    debug(dbg_eachfiledetail, "tarobject done and installation deferred");
  } else {
    if (rename(fnamenewvb.buf, fnamevb.buf))
      ohshite(_("unable to install new version of `%.255s'"), ti->name);

    /*
     * CLEANUP: Now the new file is in the destination file, and the
     * old file is in .dpkg-tmp to be cleaned up later. We now need
     * to take a different attitude to cleanup, because we need to
     * remove the new file.
     */

    nifd->namenode->flags |= fnnf_placed_on_disk;
    nifd->namenode->flags |= fnnf_elide_other_lists;

    debug(dbg_eachfiledetail, "tarobject done and installed");
  }

  return 0;
}

#if defined(SYNC_FILE_RANGE_WAIT_BEFORE)
static void
tar_writeback_barrier(struct fileinlist *files, struct pkginfo *pkg)
{
  struct fileinlist *cfile;

  for (cfile = files; cfile; cfile = cfile->next) {
    struct filenamenode *usenode;
    const char *usename;
    int fd;

    if (!(cfile->namenode->flags & fnnf_deferred_fsync))
      continue;

    usenode = namenodetouse(cfile->namenode, pkg);
    usename = usenode->name + 1; /* Skip the leading '/'. */

    setupfnamevbs(usename);

    fd = open(fnamenewvb.buf, O_WRONLY);
    if (fd < 0)
      ohshite(_("unable to open '%.255s'"), fnamenewvb.buf);
    /* Ignore the return code as it should be considered equivalent to an
     * asynchronous hint for the kernel, we are doing an fsync() later on
     * anyway. */
    sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE);
    if (close(fd))
      ohshite(_("error closing/writing `%.255s'"), fnamenewvb.buf);
  }
}
#else
static void
tar_writeback_barrier(struct fileinlist *files, struct pkginfo *pkg)
{
}
#endif

void
tar_deferred_extract(struct fileinlist *files, struct pkginfo *pkg)
{
  struct fileinlist *cfile;
  struct filenamenode *usenode;
  const char *usename;

  tar_writeback_barrier(files, pkg);

  for (cfile = files; cfile; cfile = cfile->next) {
    debug(dbg_eachfile, "deferred extract of '%.255s'", cfile->namenode->name);

    if (!(cfile->namenode->flags & fnnf_deferred_rename))
      continue;

    usenode = namenodetouse(cfile->namenode, pkg);
    usename = usenode->name + 1; /* Skip the leading '/'. */

    setupfnamevbs(usename);

    if (cfile->namenode->flags & fnnf_deferred_fsync) {
      int fd;

      debug(dbg_eachfiledetail, "deferred extract needs fsync");

      fd = open(fnamenewvb.buf, O_WRONLY);
      if (fd < 0)
        ohshite(_("unable to open '%.255s'"), fnamenewvb.buf);
      if (fsync(fd))
        ohshite(_("unable to sync file '%.255s'"), fnamenewvb.buf);
      if (close(fd))
        ohshite(_("error closing/writing `%.255s'"), fnamenewvb.buf);

      cfile->namenode->flags &= ~fnnf_deferred_fsync;
    }

    debug(dbg_eachfiledetail, "deferred extract needs rename");

    if (rename(fnamenewvb.buf, fnamevb.buf))
      ohshite(_("unable to install new version of `%.255s'"),
              cfile->namenode->name);

    cfile->namenode->flags &= ~fnnf_deferred_rename;

    /*
     * CLEANUP: Now the new file is in the destination file, and the
     * old file is in .dpkg-tmp to be cleaned up later. We now need
     * to take a different attitude to cleanup, because we need to
     * remove the new file.
     */

    cfile->namenode->flags |= fnnf_placed_on_disk;
    cfile->namenode->flags |= fnnf_elide_other_lists;

    debug(dbg_eachfiledetail, "deferred extract done and installed");
  }
}

/**
 * Try if we can deconfigure the package and queue it if so.
 *
 * Also checks whether the pdep is forced, first, according to force_p.
 * force_p may be NULL in which case nothing is considered forced.
 *
 * Action is a string describing the action which causes the
 * deconfiguration:
 *
 *   "removal of <package>"       (due to Conflicts+Depends; removal != NULL)
 *   "installation of <package>"  (due to Breaks;            removal == NULL)
 *
 * @retval 0 Not possible (why is printed).
 * @retval 1 Deconfiguration queued ok (no message printed).
 * @retval 2 Forced (no deconfiguration needed, why is printed).
 */
static int
try_deconfigure_can(bool (*force_p)(struct deppossi *), struct pkginfo *pkg,
                    struct deppossi *pdep, const char *action,
                    struct pkginfo *removal, const char *why)
{
  struct pkg_deconf_list *newdeconf;

  if (force_p && force_p(pdep)) {
    warning(_("ignoring dependency problem with %s:\n%s"), action, why);
    return 2;
  } else if (f_autodeconf) {
    if (pkg->installed.essential) {
      if (fc_removeessential) {
        warning(_("considering deconfiguration of essential\n"
                  " package %s, to enable %s."), pkg->name, action);
      } else {
        fprintf(stderr, _("dpkg: no, %s is essential, will not deconfigure\n"
                          " it in order to enable %s.\n"),
                pkg->name, action);
        return 0;
      }
    }
    pkg->clientdata->istobe= itb_deconfigure;
    newdeconf = m_malloc(sizeof(struct pkg_deconf_list));
    newdeconf->next= deconfigure;
    newdeconf->pkg= pkg;
    newdeconf->pkg_removal = removal;
    deconfigure= newdeconf;
    return 1;
  } else {
    fprintf(stderr, _("dpkg: no, cannot proceed with %s (--auto-deconfigure will help):\n%s"),
            action, why);
    return 0;
  }
}

static int try_remove_can(struct deppossi *pdep,
                          struct pkginfo *fixbyrm,
                          const char *why) {
  char action[512];
  sprintf(action, _("removal of %.250s"), fixbyrm->name);
  return try_deconfigure_can(force_depends, pdep->up->up, pdep,
                             action, fixbyrm, why);
}

void check_breaks(struct dependency *dep, struct pkginfo *pkg,
                  const char *pfilename) {
  struct pkginfo *fixbydeconf;
  struct varbuf why = VARBUF_INIT;
  int ok;

  fixbydeconf = NULL;
  if (depisok(dep, &why, &fixbydeconf, NULL, false)) {
    varbuf_destroy(&why);
    return;
  }

  varbuf_end_str(&why);

  if (fixbydeconf && f_autodeconf) {
    char action[512];

    ensure_package_clientdata(fixbydeconf);
    assert(fixbydeconf->clientdata->istobe == itb_normal);

    sprintf(action, _("installation of %.250s"), pkg->name);
    fprintf(stderr, _("dpkg: considering deconfiguration of %s,"
                      " which would be broken by %s ...\n"),
            fixbydeconf->name, action);

    ok= try_deconfigure_can(force_breaks, fixbydeconf, dep->list,
                            action, NULL, why.buf);
    if (ok == 1) {
      fprintf(stderr, _("dpkg: yes, will deconfigure %s (broken by %s).\n"),
              fixbydeconf->name, pkg->name);
    }
  } else {
    fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"),
            pfilename, pkg->name, why.buf);
    ok= 0;
  }
  varbuf_destroy(&why);
  if (ok > 0) return;

  if (force_breaks(dep->list)) {
    warning(_("ignoring breakage, may proceed anyway!"));
    return;
  }

  if (fixbydeconf && !f_autodeconf) {
    ohshit(_("installing %.250s would break %.250s, and\n"
             " deconfiguration is not permitted (--auto-deconfigure might help)"),
           pkg->name, fixbydeconf->name);
  } else {
    ohshit(_("installing %.250s would break existing software"),
           pkg->name);
  }
}

void check_conflict(struct dependency *dep, struct pkginfo *pkg,
                    const char *pfilename) {
  struct pkginfo *fixbyrm;
  struct deppossi *pdep, flagdeppossi;
  struct varbuf conflictwhy = VARBUF_INIT, removalwhy = VARBUF_INIT;
  struct dependency *providecheck;

  fixbyrm = NULL;
  if (depisok(dep, &conflictwhy, &fixbyrm, NULL, false)) {
    varbuf_destroy(&conflictwhy);
    varbuf_destroy(&removalwhy);
    return;
  }
  if (fixbyrm) {
    ensure_package_clientdata(fixbyrm);
    if (fixbyrm->clientdata->istobe == itb_installnew) {
      fixbyrm= dep->up;
      ensure_package_clientdata(fixbyrm);
    }
    if (((pkg->available.essential && fixbyrm->installed.essential) ||
         (((fixbyrm->want != want_install && fixbyrm->want != want_hold) ||
           does_replace(pkg, &pkg->available, fixbyrm, &fixbyrm->installed)) &&
          (!fixbyrm->installed.essential || fc_removeessential)))) {
      assert(fixbyrm->clientdata->istobe == itb_normal || fixbyrm->clientdata->istobe == itb_deconfigure);
      fixbyrm->clientdata->istobe= itb_remove;
      fprintf(stderr, _("dpkg: considering removing %s in favour of %s ...\n"),
              fixbyrm->name, pkg->name);
      if (!(fixbyrm->status == stat_installed ||
            fixbyrm->status == stat_triggerspending ||
            fixbyrm->status == stat_triggersawaited)) {
        fprintf(stderr,
                _("%s is not properly installed - ignoring any dependencies on it.\n"),
                fixbyrm->name);
        pdep = NULL;
      } else {
        for (pdep= fixbyrm->installed.depended;
             pdep;
             pdep = pdep->rev_next) {
          if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends)
            continue;
          if (depisok(pdep->up, &removalwhy, NULL, NULL, false))
            continue;
          varbuf_end_str(&removalwhy);
          if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
            break;
        }
        if (!pdep) {
          /* If we haven't found a reason not to yet, let's look some more. */
          for (providecheck= fixbyrm->installed.depends;
               providecheck;
               providecheck= providecheck->next) {
            if (providecheck->type != dep_provides) continue;
            for (pdep= providecheck->list->ed->installed.depended;
                 pdep;
                 pdep = pdep->rev_next) {
              if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends)
                continue;
              if (depisok(pdep->up, &removalwhy, NULL, NULL, false))
                continue;
              varbuf_end_str(&removalwhy);
              fprintf(stderr, _("dpkg"
                      ": may have trouble removing %s, as it provides %s ...\n"),
                      fixbyrm->name, providecheck->list->ed->name);
              if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
                goto break_from_both_loops_at_once;
            }
          }
        break_from_both_loops_at_once:;
        }
      }
      if (!pdep && skip_due_to_hold(fixbyrm)) {
        pdep= &flagdeppossi;
      }
      if (!pdep && (fixbyrm->eflag & eflag_reinstreq)) {
        if (fc_removereinstreq) {
          fprintf(stderr, _("dpkg: package %s requires reinstallation, but will"
                  " remove anyway as you requested.\n"), fixbyrm->name);
        } else {
          fprintf(stderr, _("dpkg: package %s requires reinstallation, "
                  "will not remove.\n"), fixbyrm->name);
          pdep= &flagdeppossi;
        }
      }
      if (!pdep) {
        /* This conflict is OK - we'll remove the conflictor. */
        push_conflictor(pkg, fixbyrm);
        varbuf_destroy(&conflictwhy); varbuf_destroy(&removalwhy);
        fprintf(stderr, _("dpkg: yes, will remove %s in favour of %s.\n"),
                fixbyrm->name, pkg->name);
        return;
      }
      /* Put it back. */
      fixbyrm->clientdata->istobe = itb_normal;
    }
  }
  varbuf_end_str(&conflictwhy);
  fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"),
          pfilename, pkg->name, conflictwhy.buf);
  if (!force_conflicts(dep->list))
    ohshit(_("conflicting packages - not installing %.250s"),pkg->name);
  warning(_("ignoring conflict, may proceed anyway!"));
  varbuf_destroy(&conflictwhy);

  return;
}

void cu_cidir(int argc, void **argv) {
  char *cidir= (char*)argv[0];
  char *cidirrest= (char*)argv[1];
  cidirrest[-1] = '\0';
  ensure_pathname_nonexisting(cidir);
}

void cu_fileslist(int argc, void **argv) {
  destroyobstack();
}

int
archivefiles(const char *const *argv)
{
  const char *volatile thisarg;
  const char *const *volatile argp;
  jmp_buf ejbuf;

  trigproc_install_hooks();

  modstatdb_open(f_noact ?                          msdbrw_readonly :
                 (cipaction->arg_int == act_avail ? msdbrw_readonly :
                  fc_nonroot ?                      msdbrw_write :
                                                    msdbrw_needsuperuser) |
                 msdbrw_available_write);

  checkpath();
  log_message("startup archives %s", cipaction->olong);

  if (f_recursive) {
    int pi[2], nfiles, c, i, r;
    pid_t pid;
    FILE *pf;
    static struct varbuf findoutput;
    const char **arglist;
    char *p;

    if (!*argv)
      badusage(_("--%s --recursive needs at least one path argument"),cipaction->olong);

    m_pipe(pi);
    pid = subproc_fork();
    if (pid == 0) {
      struct command cmd;
      const char *const *ap;

      m_dup2(pi[1],1); close(pi[0]); close(pi[1]);

      command_init(&cmd, FIND, _("find for dpkg --recursive"));
      command_add_args(&cmd, FIND, "-L", NULL);

      for (ap = argv; *ap; ap++) {
        if (strchr(FIND_EXPRSTARTCHARS,(*ap)[0])) {
          char *a;

          m_asprintf(&a, "./%s", *ap);
          command_add_arg(&cmd, a);
        } else {
          command_add_arg(&cmd, (const char *)*ap);
        }
      }

      command_add_args(&cmd, "-name", "*.deb", "-type", "f", "-print0", NULL);

      command_exec(&cmd);
    }
    close(pi[1]);

    nfiles= 0;
    pf= fdopen(pi[0],"r");  if (!pf) ohshite(_("failed to fdopen find's pipe"));
    varbuf_reset(&findoutput);
    while ((c= fgetc(pf)) != EOF) {
      varbuf_add_char(&findoutput, c);
      if (!c) nfiles++;
    }
    if (ferror(pf)) ohshite(_("error reading find's pipe"));
    if (fclose(pf)) ohshite(_("error closing find's pipe"));
    r = subproc_wait_check(pid, "find", PROCNOERR);
    if (r != 0)
      ohshit(_("find for --recursive returned unhandled error %i"),r);

    if (!nfiles)
      ohshit(_("searched, but found no packages (files matching *.deb)"));

    arglist= m_malloc(sizeof(char*)*(nfiles+1));
    p = findoutput.buf;
    for (i = 0; i < nfiles; i++) {
      arglist[i] = p;
      while (*p++ != '\0') ;
    }
    arglist[i] = NULL;
    argp= arglist;
  } else {
    if (!*argv) badusage(_("--%s needs at least one package archive file argument"),
                         cipaction->olong);
    argp= argv;
  }

  currenttime = time(NULL);

  /* Initialize fname variables contents. */

  varbuf_reset(&fnamevb);
  varbuf_reset(&fnametmpvb);
  varbuf_reset(&fnamenewvb);

  varbuf_add_str(&fnamevb, instdir);
  varbuf_add_char(&fnamevb, '/');
  varbuf_add_str(&fnametmpvb, instdir);
  varbuf_add_char(&fnametmpvb, '/');
  varbuf_add_str(&fnamenewvb, instdir);
  varbuf_add_char(&fnamenewvb, '/');
  fnameidlu= fnamevb.used;

  ensure_diversions();
  ensure_statoverrides();

  while ((thisarg = *argp++) != NULL) {
    if (setjmp(ejbuf)) {
      pop_error_context(ehflag_bombout);
      if (abort_processing)
        break;
      continue;
    }
    push_error_context_jump(&ejbuf, print_error_perpackage, thisarg);

    process_archive(thisarg);
    onerr_abort++;
    m_output(stdout, _("<standard output>"));
    m_output(stderr, _("<standard error>"));
    onerr_abort--;

    pop_error_context(ehflag_normaltidy);
  }

  switch (cipaction->arg_int) {
  case act_install:
  case act_configure:
  case act_triggers:
  case act_remove:
  case act_purge:
    process_queue();
  case act_unpack:
  case act_avail:
    break;
  default:
    internerr("unknown action '%d'", cipaction->arg_int);
  }

  trigproc_run_deferred();
  modstatdb_shutdown();

  return 0;
}

/**
 * Decide whether we want to install a new version of the package.
 *
 * @param pkg The package with the version we might want to install
 *
 * @retval true  If the package should be skipped.
 * @retval false If the package should be installed.
 */
bool
wanttoinstall(struct pkginfo *pkg)
{
  int r;

  if (pkg->want != want_install && pkg->want != want_hold) {
    if (f_alsoselect) {
      printf(_("Selecting previously unselected package %s.\n"), pkg->name);
      pkg->want = want_install;
      return true;
    } else {
      printf(_("Skipping unselected package %s.\n"), pkg->name);
      return false;
    }
  }

  if (pkg->eflag & eflag_reinstreq)
    return true;
  if (pkg->status < stat_unpacked)
    return true;

  r = versioncompare(&pkg->available.version, &pkg->installed.version);
  if (r > 0) {
    return true;
  } else if (r == 0) {
    /* Same version fully installed. */
    if (f_skipsame) {
      fprintf(stderr, _("Version %.250s of %.250s already installed, "
                        "skipping.\n"),
              versiondescribe(&pkg->installed.version, vdew_nonambig),
              pkg->name);
      return false;
    } else {
      return true;
    }
  } else {
    if (fc_downgrade) {
      warning(_("downgrading %.250s from %.250s to %.250s."), pkg->name,
              versiondescribe(&pkg->installed.version, vdew_nonambig),
              versiondescribe(&pkg->available.version, vdew_nonambig));
      return true;
    } else {
      fprintf(stderr, _("Will not downgrade %.250s from version %.250s "
                        "to %.250s, skipping.\n"), pkg->name,
              versiondescribe(&pkg->installed.version, vdew_nonambig),
              versiondescribe(&pkg->available.version, vdew_nonambig));
      return false;
    }
  }
}

struct fileinlist *newconff_append(struct fileinlist ***newconffileslastp_io,
				   struct filenamenode *namenode) {
  struct fileinlist *newconff;

  newconff= m_malloc(sizeof(struct fileinlist));
  newconff->next = NULL;
  newconff->namenode= namenode;
  **newconffileslastp_io= newconff;
  *newconffileslastp_io= &newconff->next;
  return newconff;
}

/* vi: ts=8 sw=2
 */
