/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmCPackDebGenerator.h"

#include "cmArchiveWrite.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
#include "cm_sys_stat.h"

#include "cmsys/Glob.hxx"
#include <ostream>
#include <set>
#include <string.h>
#include <utility>

cmCPackDebGenerator::cmCPackDebGenerator()
{
}

cmCPackDebGenerator::~cmCPackDebGenerator()
{
}

int cmCPackDebGenerator::InitializeInternal()
{
  this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
  if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) {
    this->SetOption("CPACK_SET_DESTDIR", "I_ON");
  }
  return this->Superclass::InitializeInternal();
}

int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
                                        std::string const& packageName)
{
  int retval = 1;
  // Begin the archive for this pack
  std::string localToplevel(initialTopLevel);
  std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel));
  std::string outputFileName(
    std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + "-" +
    packageName + this->GetOutputExtension());

  localToplevel += "/" + packageName;
  /* replace the TEMP DIRECTORY with the component one */
  this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel.c_str());
  packageFileName += "/" + outputFileName;
  /* replace proposed CPACK_OUTPUT_FILE_NAME */
  this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName.c_str());
  /* replace the TEMPORARY package file name */
  this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
                  packageFileName.c_str());
  // Tell CPackDeb.cmake the name of the component GROUP.
  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT", packageName.c_str());
  // Tell CPackDeb.cmake the path where the component is.
  std::string component_path = "/";
  component_path += packageName;
  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH",
                  component_path.c_str());
  if (!this->ReadListFile("CPackDeb.cmake")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackDeb.cmake"
                    << std::endl);
    retval = 0;
    return retval;
  }

  cmsys::Glob gl;
  std::string findExpr(this->GetOption("GEN_WDIR"));
  findExpr += "/*";
  gl.RecurseOn();
  gl.SetRecurseListDirs(true);
  if (!gl.FindFiles(findExpr)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot find any files in the installed directory"
                    << std::endl);
    return 0;
  }
  packageFiles = gl.GetFiles();

  int res = createDeb();
  if (res != 1) {
    retval = 0;
  }
  // add the generated package to package file names list
  packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  packageFileName += "/";
  packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
  packageFileNames.push_back(std::move(packageFileName));
  return retval;
}

int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
{
  int retval = 1;
  /* Reset package file name list it will be populated during the
   * component packaging run*/
  packageFileNames.clear();
  std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));

  // The default behavior is to have one package by component group
  // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
  if (!ignoreGroup) {
    for (auto const& compG : this->ComponentGroups) {
      cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                    "Packaging component group: " << compG.first << std::endl);
      // Begin the archive for this group
      retval &= PackageOnePack(initialTopLevel, compG.first);
    }
    // Handle Orphan components (components not belonging to any groups)
    for (auto const& comp : this->Components) {
      // Does the component belong to a group?
      if (comp.second.Group == nullptr) {
        cmCPackLogger(
          cmCPackLog::LOG_VERBOSE, "Component <"
            << comp.second.Name
            << "> does not belong to any group, package it separately."
            << std::endl);
        // Begin the archive for this orphan component
        retval &= PackageOnePack(initialTopLevel, comp.first);
      }
    }
  }
  // CPACK_COMPONENTS_IGNORE_GROUPS is set
  // We build 1 package per component
  else {
    for (auto const& comp : this->Components) {
      retval &= PackageOnePack(initialTopLevel, comp.first);
    }
  }
  return retval;
}

//----------------------------------------------------------------------
int cmCPackDebGenerator::PackageComponentsAllInOne(
  const std::string& compInstDirName)
{
  int retval = 1;
  /* Reset package file name list it will be populated during the
   * component packaging run*/
  packageFileNames.clear();
  std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));

  cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                "Packaging all groups in one package..."
                "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
                  << std::endl);

  // The ALL GROUPS in ONE package case
  std::string localToplevel(initialTopLevel);
  std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel));
  std::string outputFileName(
    std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) +
    this->GetOutputExtension());
  // all GROUP in one vs all COMPONENT in one
  // if must be here otherwise non component paths have a trailing / while
  // components don't
  if (!compInstDirName.empty()) {
    localToplevel += "/" + compInstDirName;
  }

  /* replace the TEMP DIRECTORY with the component one */
  this->SetOption("CPACK_TEMPORARY_DIRECTORY", localToplevel.c_str());
  packageFileName += "/" + outputFileName;
  /* replace proposed CPACK_OUTPUT_FILE_NAME */
  this->SetOption("CPACK_OUTPUT_FILE_NAME", outputFileName.c_str());
  /* replace the TEMPORARY package file name */
  this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
                  packageFileName.c_str());

  if (!compInstDirName.empty()) {
    // Tell CPackDeb.cmake the path where the component is.
    std::string component_path = "/";
    component_path += compInstDirName;
    this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH",
                    component_path.c_str());
  }
  if (!this->ReadListFile("CPackDeb.cmake")) {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackDeb.cmake"
                    << std::endl);
    retval = 0;
    return retval;
  }

  cmsys::Glob gl;
  std::string findExpr(this->GetOption("GEN_WDIR"));
  findExpr += "/*";
  gl.RecurseOn();
  gl.SetRecurseListDirs(true);
  if (!gl.FindFiles(findExpr)) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Cannot find any files in the installed directory"
                    << std::endl);
    return 0;
  }
  packageFiles = gl.GetFiles();

  int res = createDeb();
  if (res != 1) {
    retval = 0;
  }
  // add the generated package to package file names list
  packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  packageFileName += "/";
  packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
  packageFileNames.push_back(std::move(packageFileName));
  return retval;
}

int cmCPackDebGenerator::PackageFiles()
{
  /* Are we in the component packaging case */
  if (WantsComponentInstallation()) {
    // CASE 1 : COMPONENT ALL-IN-ONE package
    // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
    // then the package file is unique and should be open here.
    if (componentPackageMethod == ONE_PACKAGE) {
      return PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE");
    }
    // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
    // There will be 1 package for each component group
    // however one may require to ignore component group and
    // in this case you'll get 1 package for each component.
    return PackageComponents(componentPackageMethod ==
                             ONE_PACKAGE_PER_COMPONENT);
  }
  // CASE 3 : NON COMPONENT package.
  return PackageComponentsAllInOne("");
}

int cmCPackDebGenerator::createDeb()
{
  // debian-binary file
  const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
  const std::string dbfilename = strGenWDIR + "/debian-binary";
  { // the scope is needed for cmGeneratedFileStream
    cmGeneratedFileStream out(dbfilename.c_str());
    out << "2.0";
    out << std::endl; // required for valid debian package
  }

  // control file
  std::string ctlfilename = strGenWDIR + "/control";

  // debian policy enforce lower case for package name
  // mandatory entries:
  std::string debian_pkg_name = cmsys::SystemTools::LowerCase(
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME"));
  const char* debian_pkg_version =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION");
  const char* debian_pkg_section =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SECTION");
  const char* debian_pkg_priority =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PRIORITY");
  const char* debian_pkg_arch =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE");
  const char* maintainer =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER");
  const char* desc = this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION");

  // optional entries
  const char* debian_pkg_dep =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS");
  const char* debian_pkg_rec =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS");
  const char* debian_pkg_sug =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS");
  const char* debian_pkg_url =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE");
  const char* debian_pkg_predep =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS");
  const char* debian_pkg_enhances =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES");
  const char* debian_pkg_breaks =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS");
  const char* debian_pkg_conflicts =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS");
  const char* debian_pkg_provides =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
  const char* debian_pkg_replaces =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
  const char* debian_pkg_source =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");

  { // the scope is needed for cmGeneratedFileStream
    cmGeneratedFileStream out(ctlfilename.c_str());
    out << "Package: " << debian_pkg_name << "\n";
    out << "Version: " << debian_pkg_version << "\n";
    out << "Section: " << debian_pkg_section << "\n";
    out << "Priority: " << debian_pkg_priority << "\n";
    out << "Architecture: " << debian_pkg_arch << "\n";
    if (debian_pkg_source && *debian_pkg_source) {
      out << "Source: " << debian_pkg_source << "\n";
    }
    if (debian_pkg_dep && *debian_pkg_dep) {
      out << "Depends: " << debian_pkg_dep << "\n";
    }
    if (debian_pkg_rec && *debian_pkg_rec) {
      out << "Recommends: " << debian_pkg_rec << "\n";
    }
    if (debian_pkg_sug && *debian_pkg_sug) {
      out << "Suggests: " << debian_pkg_sug << "\n";
    }
    if (debian_pkg_url && *debian_pkg_url) {
      out << "Homepage: " << debian_pkg_url << "\n";
    }
    if (debian_pkg_predep && *debian_pkg_predep) {
      out << "Pre-Depends: " << debian_pkg_predep << "\n";
    }
    if (debian_pkg_enhances && *debian_pkg_enhances) {
      out << "Enhances: " << debian_pkg_enhances << "\n";
    }
    if (debian_pkg_breaks && *debian_pkg_breaks) {
      out << "Breaks: " << debian_pkg_breaks << "\n";
    }
    if (debian_pkg_conflicts && *debian_pkg_conflicts) {
      out << "Conflicts: " << debian_pkg_conflicts << "\n";
    }
    if (debian_pkg_provides && *debian_pkg_provides) {
      out << "Provides: " << debian_pkg_provides << "\n";
    }
    if (debian_pkg_replaces && *debian_pkg_replaces) {
      out << "Replaces: " << debian_pkg_replaces << "\n";
    }
    unsigned long totalSize = 0;
    {
      std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
      dirName += '/';
      for (std::string const& file : packageFiles) {
        totalSize += cmSystemTools::FileLength(file);
      }
    }
    out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
    out << "Maintainer: " << maintainer << "\n";
    out << "Description: " << desc << "\n";
    out << std::endl;
  }

  const std::string shlibsfilename = strGenWDIR + "/shlibs";

  const char* debian_pkg_shlibs =
    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SHLIBS");
  const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
    debian_pkg_shlibs && *debian_pkg_shlibs;
  if (gen_shibs) {
    cmGeneratedFileStream out(shlibsfilename.c_str());
    out << debian_pkg_shlibs;
    out << std::endl;
  }

  const std::string postinst = strGenWDIR + "/postinst";
  const std::string postrm = strGenWDIR + "/postrm";
  if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) {
    cmGeneratedFileStream out(postinst.c_str());
    out << "#!/bin/sh\n\n"
           "set -e\n\n"
           "if [ \"$1\" = \"configure\" ]; then\n"
           "\tldconfig\n"
           "fi\n";
  }
  if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) {
    cmGeneratedFileStream out(postrm.c_str());
    out << "#!/bin/sh\n\n"
           "set -e\n\n"
           "if [ \"$1\" = \"remove\" ]; then\n"
           "\tldconfig\n"
           "fi\n";
  }

  cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip;
  const char* debian_compression_type =
    this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE");
  if (!debian_compression_type) {
    debian_compression_type = "gzip";
  }

  std::string compression_suffix;
  if (!strcmp(debian_compression_type, "lzma")) {
    compression_suffix = ".lzma";
    tar_compression_type = cmArchiveWrite::CompressLZMA;
  } else if (!strcmp(debian_compression_type, "xz")) {
    compression_suffix = ".xz";
    tar_compression_type = cmArchiveWrite::CompressXZ;
  } else if (!strcmp(debian_compression_type, "bzip2")) {
    compression_suffix = ".bz2";
    tar_compression_type = cmArchiveWrite::CompressBZip2;
  } else if (!strcmp(debian_compression_type, "gzip")) {
    compression_suffix = ".gz";
    tar_compression_type = cmArchiveWrite::CompressGZip;
  } else if (!strcmp(debian_compression_type, "none")) {
    compression_suffix.clear();
    tar_compression_type = cmArchiveWrite::CompressNone;
  } else {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "Error unrecognized compression type: "
                    << debian_compression_type << std::endl);
  }

  const char* debian_archive_type =
    this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE");
  if (!debian_archive_type) {
    debian_archive_type = "paxr";
  }

  std::string filename_data_tar =
    strGenWDIR + "/data.tar" + compression_suffix;

  // atomic file generation for data.tar
  {
    cmGeneratedFileStream fileStream_data_tar;
    fileStream_data_tar.Open(filename_data_tar.c_str(), false, true);
    if (!fileStream_data_tar) {
      cmCPackLogger(cmCPackLog::LOG_ERROR, "Error opening the file \""
                      << filename_data_tar << "\" for writing" << std::endl);
      return 0;
    }
    cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type,
                            debian_archive_type);

    // uid/gid should be the one of the root user, and this root user has
    // always uid/gid equal to 0.
    data_tar.SetUIDAndGID(0u, 0u);
    data_tar.SetUNAMEAndGNAME("root", "root");

    // now add all directories which have to be compressed
    // collect all top level install dirs for that
    // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
    // give /usr and /opt
    size_t topLevelLength = strGenWDIR.length();
    cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
                    << strGenWDIR << "\", length = " << topLevelLength
                    << std::endl);
    std::set<std::string> orderedFiles;

    // we have to reconstruct the parent folders as well

    for (std::string currentPath : packageFiles) {
      while (currentPath != strGenWDIR) {
        // the last one IS strGenWDIR, but we do not want this one:
        // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
        // should not add XXX/application
        orderedFiles.insert(currentPath);
        currentPath = cmSystemTools::CollapseCombinedPath(currentPath, "..");
      }
    }

    for (std::string const& file : orderedFiles) {
      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << file << "\""
                                                        << std::endl);
      std::string::size_type slashPos = file.find('/', topLevelLength + 1);
      std::string relativeDir =
        file.substr(topLevelLength, slashPos - topLevelLength);
      cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \""
                      << relativeDir << "\"" << std::endl);

#ifdef WIN32
      std::string mode_t_adt_filename = file + ":cmake_mode_t";
      cmsys::ifstream permissionStream(mode_t_adt_filename.c_str());

      mode_t permissions = 0;

      if (permissionStream) {
        permissionStream >> std::oct >> permissions;
      }

      if (permissions != 0) {
        data_tar.SetPermissions(permissions);
      } else if (cmSystemTools::FileIsDirectory(file)) {
        data_tar.SetPermissions(0755);
      } else {
        data_tar.ClearPermissions();
      }
#endif

      // do not recurse because the loop will do it
      if (!data_tar.Add(file, topLevelLength, ".", false)) {
        cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem adding file to tar:"
                        << std::endl
                        << "#top level directory: " << strGenWDIR << std::endl
                        << "#file: " << file << std::endl
                        << "#error:" << data_tar.GetError() << std::endl);
        return 0;
      }
    }
  } // scope for file generation

  std::string md5filename = strGenWDIR + "/md5sums";
  {
    // the scope is needed for cmGeneratedFileStream
    cmGeneratedFileStream out(md5filename.c_str());

    std::string topLevelWithTrailingSlash =
      this->GetOption("CPACK_TEMPORARY_DIRECTORY");
    topLevelWithTrailingSlash += '/';
    for (std::string const& file : packageFiles) {
      // hash only regular files
      if (cmSystemTools::FileIsDirectory(file) ||
          cmSystemTools::FileIsSymlink(file)) {
        continue;
      }

      std::string output =
        cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5);
      if (output.empty()) {
        cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem computing the md5 of "
                        << file << std::endl);
      }

      output += "  " + file + "\n";
      // debian md5sums entries are like this:
      // 014f3604694729f3bf19263bac599765  usr/bin/ccmake
      // thus strip the full path (with the trailing slash)
      cmSystemTools::ReplaceString(output, topLevelWithTrailingSlash.c_str(),
                                   "");
      out << output;
    }
    // each line contains a eol.
    // Do not end the md5sum file with yet another (invalid)
  }

  std::string filename_control_tar = strGenWDIR + "/control.tar.gz";
  // atomic file generation for control.tar
  {
    cmGeneratedFileStream fileStream_control_tar;
    fileStream_control_tar.Open(filename_control_tar.c_str(), false, true);
    if (!fileStream_control_tar) {
      cmCPackLogger(cmCPackLog::LOG_ERROR, "Error opening the file \""
                      << filename_control_tar << "\" for writing"
                      << std::endl);
      return 0;
    }
    cmArchiveWrite control_tar(fileStream_control_tar,
                               cmArchiveWrite::CompressGZip,
                               debian_archive_type);

    // sets permissions and uid/gid for the files
    control_tar.SetUIDAndGID(0u, 0u);
    control_tar.SetUNAMEAndGNAME("root", "root");

    /* permissions are set according to
    https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
    and
    https://lintian.debian.org/tags/control-file-has-bad-permissions.html
    */
    const mode_t permission644 = 0644;
    const mode_t permissionExecute = 0111;
    const mode_t permission755 = permission644 | permissionExecute;

    // for md5sum and control (that we have generated here), we use 644
    // (RW-R--R--)
    // so that deb lintian doesn't warn about it
    control_tar.SetPermissions(permission644);

    // adds control and md5sums
    if (!control_tar.Add(md5filename, strGenWDIR.length(), ".") ||
        !control_tar.Add(strGenWDIR + "/control", strGenWDIR.length(), ".")) {
      cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:"
                      << std::endl
                      << "#top level directory: " << strGenWDIR << std::endl
                      << "#file: \"control\" or \"md5sums\"" << std::endl
                      << "#error:" << control_tar.GetError() << std::endl);
      return 0;
    }

    // adds generated shlibs file
    if (gen_shibs) {
      if (!control_tar.Add(shlibsfilename, strGenWDIR.length(), ".")) {
        cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:"
                        << std::endl
                        << "#top level directory: " << strGenWDIR << std::endl
                        << "#file: \"shlibs\"" << std::endl
                        << "#error:" << control_tar.GetError() << std::endl);
        return 0;
      }
    }

    // adds LDCONFIG related files
    if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) {
      control_tar.SetPermissions(permission755);
      if (!control_tar.Add(postinst, strGenWDIR.length(), ".")) {
        cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:"
                        << std::endl
                        << "#top level directory: " << strGenWDIR << std::endl
                        << "#file: \"postinst\"" << std::endl
                        << "#error:" << control_tar.GetError() << std::endl);
        return 0;
      }
      control_tar.SetPermissions(permission644);
    }

    if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) {
      control_tar.SetPermissions(permission755);
      if (!control_tar.Add(postrm, strGenWDIR.length(), ".")) {
        cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:"
                        << std::endl
                        << "#top level directory: " << strGenWDIR << std::endl
                        << "#file: \"postinst\"" << std::endl
                        << "#error:" << control_tar.GetError() << std::endl);
        return 0;
      }
      control_tar.SetPermissions(permission644);
    }

    // for the other files, we use
    // -either the original permission on the files
    // -either a permission strictly defined by the Debian policies
    const char* controlExtra =
      this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA");
    if (controlExtra) {
      // permissions are now controlled by the original file permissions

      const bool permissionStrictPolicy =
        this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION");

      static const char* strictFiles[] = { "config", "postinst", "postrm",
                                           "preinst", "prerm" };
      std::set<std::string> setStrictFiles(
        strictFiles,
        strictFiles + sizeof(strictFiles) / sizeof(strictFiles[0]));

      // default
      control_tar.ClearPermissions();

      std::vector<std::string> controlExtraList;
      cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
      for (std::string const& i : controlExtraList) {
        std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
        std::string localcopy = strGenWDIR + "/" + filenamename;

        if (permissionStrictPolicy) {
          control_tar.SetPermissions(setStrictFiles.count(filenamename)
                                       ? permission755
                                       : permission644);
        }

        // if we can copy the file, it means it does exist, let's add it:
        if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) {
          control_tar.Add(localcopy, strGenWDIR.length(), ".");
        }
      }
    }
  }

  // ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
  // A debian package .deb is simply an 'ar' archive. The only subtle
  // difference is that debian uses the BSD ar style archive whereas most
  // Linux distro have a GNU ar.
  // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info
  std::string const outputDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  std::string const outputName = this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
  std::string const outputPath = outputDir + "/" + outputName;
  std::string const tlDir = strGenWDIR + "/";
  cmGeneratedFileStream debStream;
  debStream.Open(outputPath.c_str(), false, true);
  cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
  if (!deb.Add(tlDir + "debian-binary", tlDir.length()) ||
      !deb.Add(tlDir + "control.tar.gz", tlDir.length()) ||
      !deb.Add(tlDir + "data.tar" + compression_suffix, tlDir.length())) {
    cmCPackLogger(cmCPackLog::LOG_ERROR, "Error creating debian package:"
                    << std::endl
                    << "#top level directory: " << outputDir << std::endl
                    << "#file: " << outputName << std::endl
                    << "#error:" << deb.GetError() << std::endl);
    return 0;
  }
  return 1;
}

bool cmCPackDebGenerator::SupportsComponentInstallation() const
{
  return IsOn("CPACK_DEB_COMPONENT_INSTALL");
}

std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
  const std::string& componentName)
{
  if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
    return componentName;
  }

  if (componentPackageMethod == ONE_PACKAGE) {
    return std::string("ALL_COMPONENTS_IN_ONE");
  }
  // We have to find the name of the COMPONENT GROUP
  // the current COMPONENT belongs to.
  std::string groupVar =
    "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP";
  if (nullptr != GetOption(groupVar)) {
    return std::string(GetOption(groupVar));
  }
  return componentName;
}
