/*
 * dpkg - main program for package management
 * enquiry.c - status enquiry and listing options
 *
 * Copyright © 1995,1996 Ian Jackson <ian@chiark.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/>.
 */

/* FIXME: per-package audit. */

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

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

#include <assert.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>

#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/pkg-show.h>
#include <dpkg/options.h>

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

struct badstatinfo {
  bool (*yesno)(struct pkginfo *, const struct badstatinfo *bsi);
  int value;
  const char *explanation;
};

static bool
bsyn_reinstreq(struct pkginfo *pkg, const struct badstatinfo *bsi)
{
  return pkg->eflag &= eflag_reinstreq;
}

static bool
bsyn_status(struct pkginfo *pkg, const struct badstatinfo *bsi)
{
  if (pkg->eflag &= eflag_reinstreq)
    return false;
  return (int)pkg->status == bsi->value;
}

static const struct badstatinfo badstatinfos[]= {
  {
    .yesno = bsyn_reinstreq,
    .value = 0,
    .explanation = N_(
    "The following packages are in a mess due to serious problems during\n"
    "installation.  They must be reinstalled for them (and any packages\n"
    "that depend on them) to function properly:\n")
  }, {
    .yesno = bsyn_status,
    .value = stat_unpacked,
    .explanation = N_(
    "The following packages have been unpacked but not yet configured.\n"
    "They must be configured using dpkg --configure or the configure\n"
    "menu option in dselect for them to work:\n")
  }, {
    .yesno = bsyn_status,
    .value = stat_halfconfigured,
    .explanation = N_(
    "The following packages are only half configured, probably due to problems\n"
    "configuring them the first time.  The configuration should be retried using\n"
    "dpkg --configure <package> or the configure menu option in dselect:\n")
  }, {
    .yesno = bsyn_status,
    .value = stat_halfinstalled,
    .explanation = N_(
    "The following packages are only half installed, due to problems during\n"
    "installation.  The installation can probably be completed by retrying it;\n"
    "the packages can be removed using dselect or dpkg --remove:\n")
  }, {
    .yesno = bsyn_status,
    .value = stat_triggersawaited,
    .explanation = N_(
    "The following packages are awaiting processing of triggers that they\n"
    "have activated in other packages.  This processing can be requested using\n"
    "dselect or dpkg --configure --pending (or dpkg --triggers-only):\n")
  }, {
    .yesno = bsyn_status,
    .value = stat_triggerspending,
    .explanation = N_(
    "The following packages have been triggered, but the trigger processing\n"
    "has not yet been done.  Trigger processing can be requested using\n"
    "dselect or dpkg --configure --pending (or dpkg --triggers-only):\n")
  }, {
    .yesno = NULL
  }
};

static void describebriefly(struct pkginfo *pkg) {
  int maxl, l;
  const char *pdesc;

  maxl= 57;
  l= strlen(pkg->name);
  if (l>20) maxl -= (l-20);

  pdesc = pkg_summary(pkg, &l);
  l = min(l, maxl);

  printf(" %-20s %.*s\n",pkg->name,l,pdesc);
}

int
audit(const char *const *argv)
{
  const struct badstatinfo *bsi;
  bool head_running = false;

  if (*argv)
    badusage(_("--%s takes no arguments"), cipaction->olong);

  modstatdb_open(msdbrw_readonly);

  for (bsi= badstatinfos; bsi->yesno; bsi++) {
    struct pkgiterator *it;
    struct pkginfo *pkg;
    bool head = false;

    it = pkg_db_iter_new();
    while ((pkg = pkg_db_iter_next(it))) {
      if (!bsi->yesno(pkg,bsi)) continue;
      if (!head_running) {
        if (modstatdb_is_locked())
          puts(_(
"Another process has locked the database for writing, and might currently be\n"
"modifying it, some of the following problems might just be due to that.\n"));
        head_running = true;
      }
      if (!head) {
        fputs(gettext(bsi->explanation),stdout);
        head = true;
      }
      describebriefly(pkg);
    }
    pkg_db_iter_free(it);
    if (head) putchar('\n');
  }

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

  return 0;
}

struct sectionentry {
  struct sectionentry *next;
  const char *name;
  int count;
};

static bool
yettobeunpacked(struct pkginfo *pkg, const char **thissect)
{
  if (pkg->want != want_install)
    return false;

  switch (pkg->status) {
  case stat_unpacked: case stat_installed: case stat_halfconfigured:
  case stat_triggerspending:
  case stat_triggersawaited:
    return false;
  case stat_notinstalled: case stat_halfinstalled: case stat_configfiles:
    if (thissect)
      *thissect = pkg->section && *pkg->section ? pkg->section :
                                                  C_("section", "<unknown>");
    return true;
  default:
    internerr("unknown package status '%d'", pkg->status);
  }
  return false;
}

int
unpackchk(const char *const *argv)
{
  int totalcount, sects;
  struct sectionentry *sectionentries, *se, **sep;
  struct pkgiterator *it;
  struct pkginfo *pkg;
  const char *thissect;
  char buf[20];
  int width;

  if (*argv)
    badusage(_("--%s takes no arguments"), cipaction->olong);

  modstatdb_open(msdbrw_readonly);

  totalcount= 0;
  sectionentries = NULL;
  sects= 0;
  it = pkg_db_iter_new();
  while ((pkg = pkg_db_iter_next(it))) {
    if (!yettobeunpacked(pkg, &thissect)) continue;
    for (se= sectionentries; se && strcasecmp(thissect,se->name); se= se->next);
    if (!se) {
      se= nfmalloc(sizeof(struct sectionentry));
      for (sep= &sectionentries;
           *sep && strcasecmp(thissect,(*sep)->name) > 0;
           sep= &(*sep)->next);
      se->name= thissect;
      se->count= 0;
      se->next= *sep;
      *sep= se;
      sects++;
    }
    se->count++; totalcount++;
  }
  pkg_db_iter_free(it);

  if (totalcount == 0)
    return 0;

  if (totalcount <= 12) {
    it = pkg_db_iter_new();
    while ((pkg = pkg_db_iter_next(it))) {
      if (!yettobeunpacked(pkg, NULL))
        continue;
      describebriefly(pkg);
    }
    pkg_db_iter_free(it);
  } else if (sects <= 12) {
    for (se= sectionentries; se; se= se->next) {
      sprintf(buf,"%d",se->count);
      printf(_(" %d in %s: "),se->count,se->name);
      width= 70-strlen(se->name)-strlen(buf);
      while (width > 59) { putchar(' '); width--; }
      it = pkg_db_iter_new();
      while ((pkg = pkg_db_iter_next(it))) {
        if (!yettobeunpacked(pkg,&thissect)) continue;
        if (strcasecmp(thissect,se->name)) continue;
        width -= strlen(pkg->name); width--;
        if (width < 4) { printf(" ..."); break; }
        printf(" %s",pkg->name);
      }
      pkg_db_iter_free(it);
      putchar('\n');
    }
  } else {
    printf(P_(" %d package, from the following section:",
              " %d packages, from the following sections:", totalcount),
           totalcount);
    width= 0;
    for (se= sectionentries; se; se= se->next) {
      sprintf(buf,"%d",se->count);
      width -= (6 + strlen(se->name) + strlen(buf));
      if (width < 0) { putchar('\n'); width= 73 - strlen(se->name) - strlen(buf); }
      printf("   %s (%d)",se->name,se->count);
    }
    putchar('\n');
  }

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

  return 0;
}

static int
assert_version_support(const char *const *argv,
                       struct versionrevision *version,
                       const char *feature_name)
{
  struct pkginfo *pkg;

  if (*argv)
    badusage(_("--%s takes no arguments"), cipaction->olong);

  modstatdb_open(msdbrw_readonly);

  pkg = pkg_db_find("dpkg");
  switch (pkg->status) {
  case stat_installed:
  case stat_triggerspending:
    return 0;
  case stat_unpacked: case stat_halfconfigured: case stat_halfinstalled:
  case stat_triggersawaited:
    if (versionsatisfied3(&pkg->configversion, version, dvr_laterequal))
      return 0;
    printf(_("Version of dpkg with working %s support not yet configured.\n"
             " Please use 'dpkg --configure dpkg', and then try again.\n"),
           feature_name);
    return 1;
  default:
    printf(_("dpkg not recorded as installed, cannot check for %s support!\n"),
           feature_name);
    return 1;
  }
}

int
assertpredep(const char *const *argv)
{
  struct versionrevision version = { 0, "1.1.0", NULL };

  return assert_version_support(argv, &version, _("Pre-Depends field"));
}

int
assertepoch(const char *const *argv)
{
  struct versionrevision version = { 0, "1.4.0.7", NULL };

  return assert_version_support(argv, &version, _("epoch"));
}

int
assertlongfilenames(const char *const *argv)
{
  struct versionrevision version = { 0, "1.4.1.17", NULL };

  return assert_version_support(argv, &version, _("long filenames"));
}

int
assertmulticonrep(const char *const *argv)
{
  struct versionrevision version = { 0, "1.4.1.19", NULL };

  return assert_version_support(argv, &version,
                                _("multiple Conflicts and Replaces"));
}

/**
 * Print a single package which:
 *  (a) is the target of one or more relevant predependencies.
 *  (b) has itself no unsatisfied pre-dependencies.
 *
 * If such a package is present output is the Packages file entry,
 * which can be massaged as appropriate.
 *
 * Exit status:
 *  0 = a package printed, OK
 *  1 = no suitable package available
 *  2 = error
 */
int
predeppackage(const char *const *argv)
{
  static struct varbuf vb;

  struct pkgiterator *it;
  struct pkginfo *pkg = NULL, *startpkg, *trypkg;
  struct dependency *dep;
  struct deppossi *possi, *provider;

  if (*argv)
    badusage(_("--%s takes no arguments"), cipaction->olong);

  modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  /* We use clientdata->istobe to detect loops. */
  clear_istobes();

  dep = NULL;
  it = pkg_db_iter_new();
  while (!dep && (pkg = pkg_db_iter_next(it))) {
    /* Ignore packages user doesn't want. */
    if (pkg->want != want_install)
      continue;
    /* Ignore packages not available. */
    if (!pkg->files)
      continue;
    pkg->clientdata->istobe= itb_preinstall;
    for (dep= pkg->available.depends; dep; dep= dep->next) {
      if (dep->type != dep_predepends) continue;
      if (depisok(dep, &vb, NULL, NULL, true))
        continue;
      /* This will leave dep non-NULL, and so exit the loop. */
      break;
    }
    pkg->clientdata->istobe= itb_normal;
    /* If dep is NULL we go and get the next package. */
  }
  pkg_db_iter_free(it);

  if (!dep)
    return 1; /* Not found. */
  assert(pkg);
  startpkg= pkg;
  pkg->clientdata->istobe= itb_preinstall;

  /* OK, we have found an unsatisfied predependency.
   * Now go and find the first thing we need to install, as a first step
   * towards satisfying it. */
  do {
    /* We search for a package which would satisfy dep, and put it in pkg. */
    for (possi = dep->list, pkg = NULL;
         !pkg && possi;
         possi=possi->next) {
      trypkg= possi->ed;
      if (trypkg->files && versionsatisfied(&trypkg->available,possi)) {
        if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; }
      }
      if (possi->verrel != dvr_none) continue;
      for (provider=possi->ed->available.depended;
           !pkg && provider;
           provider=provider->next) {
        if (provider->up->type != dep_provides) continue;
        trypkg= provider->up->up;
        if (!trypkg->files)
          continue;
        if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; }
      }
    }
    if (!pkg) {
      varbuf_reset(&vb);
      describedepcon(&vb,dep);
      varbuf_end_str(&vb);
      fprintf(stderr, _("dpkg: cannot see how to satisfy pre-dependency:\n %s\n"),vb.buf);
      ohshit(_("cannot satisfy pre-dependencies for %.250s (wanted due to %.250s)"),
             dep->up->name,startpkg->name);
    }
    pkg->clientdata->istobe= itb_preinstall;
    for (dep= pkg->available.depends; dep; dep= dep->next) {
      if (dep->type != dep_predepends) continue;
      if (depisok(dep, &vb, NULL, NULL, true))
        continue;
      /* This will leave dep non-NULL, and so exit the loop. */
      break;
    }
  } while (dep);

  /* OK, we've found it - pkg has no unsatisfied pre-dependencies! */
  writerecord(stdout, _("<standard output>"), pkg, &pkg->available);

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

  return 0;
}

int
printarch(const char *const *argv)
{
  if (*argv)
    badusage(_("--%s takes no arguments"), cipaction->olong);

  printf("%s\n", native_arch);

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

  return 0;
}

int
printinstarch(const char *const *argv)
{
  warning(_("obsolete option '--%s', please use '--%s' instead."),
          "print-installation-architecture", "print-architecture");
  return printarch(argv);
}

int
cmpversions(const char *const *argv)
{
  struct relationinfo {
    const char *string;
    /* These values are exit status codes, so 0 = true, 1 = false. */
    int if_lesser, if_equal, if_greater;
    int if_none_a, if_none_both, if_none_b;
  };

  static const struct relationinfo relationinfos[]= {
    /*             < = > !a!2!b  */
    { "le",        0,0,1, 0,0,1  },
    { "lt",        0,1,1, 0,1,1  },
    { "eq",        1,0,1, 1,0,1  },
    { "ne",        0,1,0, 0,1,0  },
    { "ge",        1,0,0, 1,0,0  },
    { "gt",        1,1,0, 1,1,0  },

    /* These treat an empty version as later than any version. */
    { "le-nl",     0,0,1, 1,0,0  },
    { "lt-nl",     0,1,1, 1,1,0  },
    { "ge-nl",     1,0,0, 0,0,1  },
    { "gt-nl",     1,1,0, 0,1,1  },

    /* For compatibility with dpkg control file syntax. */
    { "<",         0,0,1, 0,0,1  },
    { "<=",        0,0,1, 0,0,1  },
    { "<<",        0,1,1, 0,1,1  },
    { "=",         1,0,1, 1,0,1  },
    { ">",         1,0,0, 1,0,0  },
    { ">=",        1,0,0, 1,0,0  },
    { ">>",        1,1,0, 1,1,0  },
    { NULL                       }
  };

  const struct relationinfo *rip;
  struct versionrevision a, b;
  struct dpkg_error err;
  int r;

  if (!argv[0] || !argv[1] || !argv[2] || argv[3])
    badusage(_("--compare-versions takes three arguments:"
             " <version> <relation> <version>"));

  for (rip=relationinfos; rip->string && strcmp(rip->string,argv[1]); rip++);

  if (!rip->string) badusage(_("--compare-versions bad relation"));

  if (*argv[0] && strcmp(argv[0],"<unknown>")) {
    if (parseversion(&a, argv[0], &err) < 0) {
      if (err.type == DPKG_MSG_WARN)
        warning(_("version '%s' has bad syntax: %s"), argv[0], err.str);
      else
        ohshit(_("version '%s' has bad syntax: %s"), argv[0], err.str);
      dpkg_error_destroy(&err);
    }
  } else {
    blankversion(&a);
  }
  if (*argv[2] && strcmp(argv[2],"<unknown>")) {
    if (parseversion(&b, argv[2], &err) < 0) {
      if (err.type == DPKG_MSG_WARN)
        warning(_("version '%s' has bad syntax: %s"), argv[2], err.str);
      else
        ohshit(_("version '%s' has bad syntax: %s"), argv[2], err.str);
      dpkg_error_destroy(&err);
    }
  } else {
    blankversion(&b);
  }
  if (!informativeversion(&a)) {
    return informativeversion(&b) ? rip->if_none_a : rip->if_none_both;
  } else if (!informativeversion(&b)) {
    return rip->if_none_b;
  }
  r= versioncompare(&a,&b);
  debug(dbg_general,"cmpversions a=`%s' b=`%s' r=%d",
        versiondescribe(&a,vdew_always),
        versiondescribe(&b,vdew_always),
        r);
  if (r > 0)
    return rip->if_greater;
  else if (r < 0)
    return rip->if_lesser;
  else
    return rip->if_equal;
}
