This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  3b099fd3eddbe1775d0cc1360704a0e824532c80 (commit)
       via  8954f8fa8a8d28cb06abdf1630e1229ea818b596 (commit)
       via  437b8acb6c501f736fdba6b26bfa6122581e198e (commit)
       via  5a8e53453a4bef49663723fec57cb22253c7c34f (commit)
      from  41547e3a5d045d4cc549f8e2202bdea1ff002c29 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3b099fd3eddbe1775d0cc1360704a0e824532c80
commit 3b099fd3eddbe1775d0cc1360704a0e824532c80
Merge: 41547e3 8954f8f
Author:     Domen Vrankar <domen.vran...@gmail.com>
AuthorDate: Thu Sep 17 15:09:29 2015 -0400
Commit:     CMake Topic Stage <kwro...@kitware.com>
CommitDate: Thu Sep 17 15:09:29 2015 -0400

    Merge topic 'cpack-deb-fakeroot-removal' into next
    
    8954f8fa CPack/DEB: test preserve extra config file permissions
    437b8acb CPackDeb: use of libarchive and removal of fakeroot
    5a8e5345 cmArchiveWrite: control user/group, permissions and recursive file 
adding


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8954f8fa8a8d28cb06abdf1630e1229ea818b596
commit 8954f8fa8a8d28cb06abdf1630e1229ea818b596
Author:     Domen Vrankar <domen.vran...@gmail.com>
AuthorDate: Mon Sep 14 22:44:00 2015 +0200
Commit:     Domen Vrankar <domen.vran...@gmail.com>
CommitDate: Thu Sep 17 21:05:53 2015 +0200

    CPack/DEB: test preserve extra config file permissions

diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake 
b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
index 78b6114..5f929ff 100644
--- a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
@@ -1,11 +1,17 @@
 set(foo_preinst "^echo default_preinst$")
+set(foo_preinst_permissions_regex "-rwxr-xr-x .*")
 set(foo_prerm "^echo default_prerm$")
+set(foo_prerm_permissions_regex "-rwxr-xr-x .*")
 verifyDebControl("${FOUND_FILE_1}" "foo" "preinst;prerm")
 
 set(bar_preinst "^echo bar_preinst$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
 set(bar_prerm "^echo bar_prerm$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
 verifyDebControl("${FOUND_FILE_2}" "bar" "preinst;prerm")
 
 set(bas_preinst "^echo default_preinst$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
 set(bas_prerm "^echo default_prerm$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
 verifyDebControl("${FOUND_FILE_3}" "bas" "preinst;prerm")
diff --git a/Tests/RunCMake/CPack/DEB/Helpers.cmake 
b/Tests/RunCMake/CPack/DEB/Helpers.cmake
index b6f113b..f490130 100644
--- a/Tests/RunCMake/CPack/DEB/Helpers.cmake
+++ b/Tests/RunCMake/CPack/DEB/Helpers.cmake
@@ -24,6 +24,19 @@ function(verifyDebControl FILE PREFIX VERIFY_FILES)
       message(FATAL_ERROR "Unexpected content in for '${PREFIX}_${FILE_}'!"
           " Content: '${content_}'")
     endif()
+
+    execute_process(COMMAND ls -l 
"${CMAKE_CURRENT_BINARY_DIR}/control_${PREFIX}/${FILE_}"
+          OUTPUT_VARIABLE package_permissions_
+          ERROR_VARIABLE package_permissions_error_
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    if(NOT package_permissions_error_)
+      if(NOT package_permissions_ MATCHES 
"${${PREFIX}_${FILE_}_permissions_regex}")
+        message(FATAL_ERROR "Unexpected file permissions for 
${PREFIX}_${FILE_}: '${package_permissions_}'!")
+      endif()
+    else()
+      message(FATAL_ERROR "Listing file permissions failed 
(${package_permissions_error_})!")
+    endif()
   endforeach()
 endfunction()
 
diff --git a/Tests/RunCMake/CPack/DEB_EXTRA.cmake 
b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
index 46d848d..3c291d5 100644
--- a/Tests/RunCMake/CPack/DEB_EXTRA.cmake
+++ b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
@@ -2,14 +2,32 @@ install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo)
 install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar)
 install(FILES CMakeLists.txt DESTINATION bas COMPONENT bas)
 
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/preinst "echo default_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/prerm "echo default_prerm")
+
+foreach(file_ preinst prerm)
+  file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/${file_}
+    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+    FILE_PERMISSIONS
+      OWNER_READ OWNER_WRITE OWNER_EXECUTE
+      GROUP_READ GROUP_EXECUTE
+      WORLD_READ WORLD_EXECUTE)
+endforeach()
 
 set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
-    "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
+    
"${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm;${CMAKE_CURRENT_BINARY_DIR}/conffiles")
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/preinst "echo bar_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/prerm "echo bar_prerm")
 
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar/preinst "echo bar_preinst")
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar/prerm "echo bar_prerm")
+foreach(file_ preinst prerm)
+  # not acceptable permissions for lintian but we need to check that
+  # permissions are preserved
+  file(COPY ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/${file_}
+    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bar
+    FILE_PERMISSIONS
+      OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+endforeach()
 
 set(CPACK_DEBIAN_BAR_PACKAGE_CONTROL_EXTRA
     
"${CMAKE_CURRENT_BINARY_DIR}/bar/preinst;${CMAKE_CURRENT_BINARY_DIR}/bar/prerm")

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=437b8acb6c501f736fdba6b26bfa6122581e198e
commit 437b8acb6c501f736fdba6b26bfa6122581e198e
Author:     Raffi Enficiaud <raffi.enfici...@mines-paris.org>
AuthorDate: Fri Sep 11 20:58:18 2015 +0200
Commit:     Domen Vrankar <domen.vran...@gmail.com>
CommitDate: Thu Sep 17 21:05:39 2015 +0200

    CPackDeb: use of libarchive and removal of fakeroot

diff --git a/Help/release/dev/cpack-deb-fakeroot-removal.rts 
b/Help/release/dev/cpack-deb-fakeroot-removal.rts
new file mode 100644
index 0000000..e0b97d1
--- /dev/null
+++ b/Help/release/dev/cpack-deb-fakeroot-removal.rts
@@ -0,0 +1,4 @@
+cpack-deb-fakeroot-removal
+--------------------------
+
+* :module:`CPackDeb` no longer uses fakeroot and system tar program for 
packaging.
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake
index 6c94d8e..93d51c3 100644
--- a/Modules/CPackDeb.cmake
+++ b/Modules/CPackDeb.cmake
@@ -326,6 +326,34 @@
 #
 #   set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
 #       "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
+#
+#  .. note::
+#
+#    The original permissions of the files will be used in the final
+#    package unless the variable
+#    :variable:`CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION` is set.
+#    In particular, the scripts should have the proper executable
+#    flag prior to the generation of the package.
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION
+#
+#  This variable indicates if the Debian policy on control files should be
+#  strictly followed.
+#
+#  * Mandatory : NO
+#  * Default   : FALSE
+#
+#  Usage::
+#
+#   set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+#
+#  .. note::
+#
+#    This overrides the permissions on the original files, following the rules
+#    set by Debian policy
+#    
https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+#
 
 
 #=============================================================================
@@ -362,11 +390,6 @@ function(cpack_deb_prepare_package_vars)
     set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
   endif()
 
-  find_program(FAKEROOT_EXECUTABLE fakeroot)
-  if(FAKEROOT_EXECUTABLE)
-    set(CPACK_DEBIAN_FAKEROOT_EXECUTABLE ${FAKEROOT_EXECUTABLE})
-  endif()
-
   set(WDIR 
"${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
 
   # per component automatic discover: some of the component might not have
@@ -635,7 +658,7 @@ function(cpack_deb_prepare_package_vars)
   # Are we packaging components ?
   if(CPACK_DEB_PACKAGE_COMPONENT)
     # override values with per component version if set
-    foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA")
+    foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA" 
"PACKAGE_CONTROL_STRICT_PERMISSION")
       if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_})
         set(CPACK_DEBIAN_${VAR_NAME_} 
"${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}")
       endif()
@@ -657,6 +680,7 @@ function(cpack_deb_prepare_package_vars)
      message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME           = 
${CPACK_PACKAGE_FILE_NAME}")
      message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY   = 
${CPACK_PACKAGE_INSTALL_DIRECTORY}")
      message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = 
${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
+     message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = 
${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}")
   endif()
 
   # For debian source packages:
@@ -682,7 +706,6 @@ function(cpack_deb_prepare_package_vars)
   set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" 
PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION 
"${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" 
PARENT_SCOPE)
-  set(GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE 
"${CPACK_DEBIAN_FAKEROOT_EXECUTABLE}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" 
PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" 
PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" 
PARENT_SCOPE)
@@ -694,6 +717,8 @@ function(cpack_deb_prepare_package_vars)
   set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" 
PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" 
PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA 
"${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE)
+  set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+      "${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE)
   set(GEN_WDIR "${WDIR}" PARENT_SCOPE)
 endfunction()
 
diff --git a/Source/CPack/cmCPackDebGenerator.cxx 
b/Source/CPack/cmCPackDebGenerator.cxx
index 5049a3f..9402689 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -15,6 +15,7 @@
 #include "cmMakefile.h"
 #include "cmGeneratedFileStream.h"
 #include "cmCPackLog.h"
+#include "cmArchiveWrite.h"
 
 #include <cmsys/SystemTools.hxx>
 #include <cmsys/Glob.hxx>
@@ -388,9 +389,9 @@ int cmCPackDebGenerator::createDeb()
     {
       std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
       dirName += '/';
-        for (std::vector<std::string>::const_iterator fileIt =
-              packageFiles.begin();
-              fileIt != packageFiles.end(); ++ fileIt )
+      for (std::vector<std::string>::const_iterator fileIt =
+           packageFiles.begin();
+           fileIt != packageFiles.end(); ++ fileIt )
         {
         totalSize += cmSystemTools::FileLength(*fileIt);
         }
@@ -401,8 +402,9 @@ int cmCPackDebGenerator::createDeb()
     out << std::endl;
     }
 
-  std::string cmd(this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE"));
+  const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
 
+  cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip;
   const char* debian_compression_type =
       this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE");
   if(!debian_compression_type)
@@ -410,102 +412,127 @@ int cmCPackDebGenerator::createDeb()
     debian_compression_type = "gzip";
     }
 
-  std::string cmake_tar = " ", compression_modifier = "a", compression_suffix;
+  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";
-      compression_modifier = "j";
-      cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+      tar_compression_type = cmArchiveWrite::CompressBZip2;
   } else if(!strcmp(debian_compression_type, "gzip")) {
       compression_suffix = ".gz";
-      compression_modifier = "z";
-      cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+      tar_compression_type = cmArchiveWrite::CompressGZip;
   } else if(!strcmp(debian_compression_type, "none")) {
       compression_suffix = "";
-      compression_modifier = "";
-      cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+      tar_compression_type = cmArchiveWrite::CompressNone;
   } else {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "Error unrecognized compression type: "
                     << debian_compression_type << std::endl);
   }
 
-  cmd += cmake_tar + "tar c" + compression_modifier + "f data.tar"
-      + compression_suffix;
 
-  // 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 = std::string(this->GetOption("GEN_WDIR")).length();
-    cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
-          << this->GetOption("GEN_WDIR")
-          << "\", length = " << topLevelLength
+  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);
-  std::set<std::string> installDirs;
+      return 0;
+      }
+    cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type, "paxr");
+
+    // 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::vector<std::string>::const_iterator fileIt =
-        packageFiles.begin();
-        fileIt != packageFiles.end(); ++ fileIt )
-    {
-      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
-          << std::endl);
-    std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
-    std::string relativeDir = fileIt->substr(topLevelLength,
-                                             slashPos - topLevelLength);
-      cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
-      << "\"" << std::endl);
-    if (installDirs.find(relativeDir) == installDirs.end())
+         packageFiles.begin();
+         fileIt != packageFiles.end(); ++ fileIt )
       {
-      installDirs.insert(relativeDir);
-      cmd += " .";
-      cmd += relativeDir;
+      std::string currentPath = *fileIt;
+      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, "..");
+        }
       }
-    }
 
-  std::string output;
-    int retval = -1;
-  int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
-      &retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
 
-    if ( !res || retval )
-    {
-    std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-    tmpFile += "/Deb.log";
-    cmGeneratedFileStream ofs(tmpFile.c_str());
-    ofs << "# Run command: " << cmd << std::endl
-      << "# Working directory: " << toplevel << std::endl
-      << "# Output:" << std::endl
-      << output << std::endl;
-    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
-      << cmd << std::endl
-      << "Please check " << tmpFile << " for errors" << std::endl);
-    return 0;
-    }
+    for (std::set<std::string>::const_iterator fileIt =
+         orderedFiles.begin();
+         fileIt != orderedFiles.end(); ++ fileIt )
+      {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
+                    << std::endl);
+      std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
+      std::string relativeDir = fileIt->substr(topLevelLength,
+                                               slashPos - topLevelLength);
+      cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
+                    << "\"" << std::endl);
 
-  std::string md5filename;
-    md5filename = this->GetOption("GEN_WDIR");
-  md5filename += "/md5sums";
+      // do not recurse because the loop will do it
+      if(!data_tar.Add(*fileIt, topLevelLength, ".", false))
+        {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "Problem adding file to tar:" << std::endl
+                      << "#top level directory: "
+                      << strGenWDIR << std::endl
+                      << "#file: " << *fileIt << std::endl
+                      << "#error:" << data_tar.GetError() << std::endl);
+        return 0;
+        }
+      }
+  } // scope for file generation
 
-    { // the scope is needed for cmGeneratedFileStream
+
+  std::string md5filename = strGenWDIR + "/md5sums";
+  {
+    // the scope is needed for cmGeneratedFileStream
     cmGeneratedFileStream out(md5filename.c_str());
-    std::vector<std::string>::const_iterator fileIt;
-//       std::string topLevelWithTrailingSlash = toplevel;
+
     std::string topLevelWithTrailingSlash =
         this->GetOption("CPACK_TEMPORARY_DIRECTORY");
     topLevelWithTrailingSlash += '/';
-      for ( fileIt = packageFiles.begin();
-            fileIt != packageFiles.end(); ++ fileIt )
+    for (std::vector<std::string>::const_iterator fileIt =
+           packageFiles.begin();
+         fileIt != packageFiles.end(); ++ fileIt )
       {
-      cmd = "\"";
+      std::string cmd = "\"";
       cmd += cmSystemTools::GetCMakeCommand();
       cmd += "\" -E md5sum \"";
       cmd += *fileIt;
       cmd += "\"";
-      //std::string output;
-      //int retVal = -1;
-      res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
+
+      std::string output;
+      int retval = -1;
+      int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
           &retval, toplevel.c_str(), this->GeneratorVerbose, 0);
       if ( !res || retval )
         {
@@ -521,70 +548,116 @@ int cmCPackDebGenerator::createDeb()
       }
     // each line contains a eol.
     // Do not end the md5sum file with yet another (invalid)
-    }
+  }
 
-    // set md5sum file permissins to RW-R--R-- so that deb lintian doesn't warn
-    // about it
-    cmSystemTools::SetPermissions(md5filename.c_str(),
-        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
-    cmd = this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
-    cmd += cmake_tar + "tar czf control.tar.gz ./control ./md5sums";
+
+  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,
+                               tar_compression_type,
+                               "paxr");
+
+    // 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 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+    const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH;
+    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;
+      }
+
+    // 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 )
-    {
-    std::vector<std::string> controlExtraList;
-    cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
-    for(std::vector<std::string>::iterator i =
-          controlExtraList.begin(); i != controlExtraList.end(); ++i)
+    if( controlExtra )
       {
-      std::string filenamename =
-        cmsys::SystemTools::GetFilenameName(*i);
-      std::string localcopy = this->GetOption("GEN_WDIR");
-      localcopy += "/";
-      localcopy += filenamename;
-      // if we can copy the file, it means it does exist, let's add it:
-      if( cmsys::SystemTools::CopyFileIfDifferent(
-            *i, localcopy) )
+      // 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::vector<std::string>::iterator i = controlExtraList.begin();
+          i != controlExtraList.end(); ++i)
         {
-        // debian is picky and need relative to ./ path in the tar.*
-        cmd += " ./";
-        cmd += filenamename;
+        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(), ".");
+          }
         }
       }
-    }
-  res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
-      &retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
+  }
 
-    if ( !res || retval )
-    {
-    std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-    tmpFile += "/Deb.log";
-    cmGeneratedFileStream ofs(tmpFile.c_str());
-    ofs << "# Run command: " << cmd << std::endl
-      << "# Working directory: " << toplevel << std::endl
-      << "# Output:" << std::endl
-      << output << std::endl;
-    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
-      << cmd << std::endl
-      << "Please check " << tmpFile << " for errors" << std::endl);
-    return 0;
-    }
 
   // ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
   // since debian packages require BSD ar (most Linux distros and even
   // FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here.
   std::vector<std::string> arFiles;
-    std::string topLevelString = this->GetOption("GEN_WDIR");
-  topLevelString += "/";
+  std::string topLevelString = strGenWDIR + "/";
   arFiles.push_back(topLevelString + "debian-binary");
   arFiles.push_back(topLevelString + "control.tar.gz");
   arFiles.push_back(topLevelString + "data.tar" + compression_suffix);
-    std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-    outputFileName += "/";
-    outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
-    res = ar_append(outputFileName.c_str(), arFiles);
+  std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+  outputFileName += "/";
+  outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
+  int res = ar_append(outputFileName.c_str(), arFiles);
   if ( res!=0 )
     {
     std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
diff --git a/Tests/CPackComponentsDEB/CMakeLists.txt 
b/Tests/CPackComponentsDEB/CMakeLists.txt
index 5c4eeab..5a5d626 100644
--- a/Tests/CPackComponentsDEB/CMakeLists.txt
+++ b/Tests/CPackComponentsDEB/CMakeLists.txt
@@ -80,6 +80,25 @@ set(CPACK_COMPONENT_HEADERS_DESCRIPTION
 # depend on the libraries component.
 set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
 
+# creates preinst/prerm scripts with specific permissions. Those permissions
+# (especially executable) should be in the final archive
+find_program(CHMOD_PROG chmod)
+if(CHMOD_PROG)
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
+
+  # Those should have 755 permission normally. We mess it up to see if
+  # CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION is able to fix
+  # it.
+  execute_process(COMMAND ${CHMOD_PROG} 640 
${CMAKE_CURRENT_BINARY_DIR}/preinst)
+  execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/prerm)
+
+  set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_EXTRA
+      "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
+
+  set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+endif()
+
 # We may use the CPack specific config file in order
 # to tailor CPack behavior on a CPack generator specific way
 # (Behavior would be different for RPM or TGZ or DEB ...)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5a8e53453a4bef49663723fec57cb22253c7c34f
commit 5a8e53453a4bef49663723fec57cb22253c7c34f
Author:     Raffi Enficiaud <raffi.enfici...@mines-paris.org>
AuthorDate: Fri Sep 11 20:00:50 2015 +0200
Commit:     Domen Vrankar <domen.vran...@gmail.com>
CommitDate: Thu Sep 17 21:05:21 2015 +0200

    cmArchiveWrite: control user/group, permissions and recursive file adding

diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 9f56324..7946950 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -181,7 +181,10 @@ cmArchiveWrite::~cmArchiveWrite()
 }
 
 //----------------------------------------------------------------------------
-bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
+bool cmArchiveWrite::Add(std::string path,
+                         size_t skip,
+                         const char* prefix,
+                         bool recursive)
 {
   if(this->Okay())
     {
@@ -189,20 +192,21 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, 
const char* prefix)
       {
       path.erase(path.size()-1);
       }
-    this->AddPath(path.c_str(), skip, prefix);
+    this->AddPath(path.c_str(), skip, prefix, recursive);
     }
   return this->Okay();
 }
 
 //----------------------------------------------------------------------------
 bool cmArchiveWrite::AddPath(const char* path,
-                             size_t skip, const char* prefix)
+                             size_t skip, const char* prefix,
+                             bool recursive)
 {
   if(!this->AddFile(path, skip, prefix))
     {
     return false;
     }
-  if(!cmSystemTools::FileIsDirectory(path) ||
+  if((!cmSystemTools::FileIsDirectory(path) || !recursive) ||
     cmSystemTools::FileIsSymlink(path))
     {
     return true;
@@ -278,6 +282,33 @@ bool cmArchiveWrite::AddFile(const char* file,
       }
     archive_entry_set_mtime(e, t, 0);
     }
+
+  // manages the uid/guid of the entry (if any)
+  if (this->Uid.IsSet() && this->Gid.IsSet())
+    {
+    archive_entry_set_uid(e, this->Uid.Get());
+    archive_entry_set_gid(e, this->Gid.Get());
+    }
+
+  if (this->Uname.size() && this->Gname.size())
+    {
+    archive_entry_set_uname(e, this->Uname.c_str());
+    archive_entry_set_gname(e, this->Gname.c_str());
+    }
+
+
+  // manages the permissions
+  if (this->Permissions.IsSet())
+    {
+    archive_entry_set_perm(e, this->Permissions.Get());
+    }
+
+  if (this->PermissionsMask.IsSet())
+    {
+    mode_t perm = archive_entry_perm(e);
+    archive_entry_set_perm(e, perm & this->PermissionsMask.Get());
+    }
+
   // Clear acl and xattr fields not useful for distribution.
   archive_entry_acl_clear(e);
   archive_entry_xattr_clear(e);
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index e6f515d..8dbbb83 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -18,6 +18,22 @@
 # error "cmArchiveWrite not allowed during bootstrap build!"
 #endif
 
+template<typename T>
+class cmArchiveWriteOptional
+{
+public:
+  cmArchiveWriteOptional() {this->Clear();}
+  explicit cmArchiveWriteOptional(T val) {this->Set(val);}
+
+  void Set(T val) {this->IsValueSet = true; this->Value=val;}
+  void Clear() {this->IsValueSet = false;}
+  bool IsSet() const {return this->IsValueSet;}
+  T Get() const {return Value;}
+private:
+  T Value;
+  bool IsValueSet;
+};
+
 /** \class cmArchiveWrite
  * \brief Wrapper around libarchive for writing.
  *
@@ -52,7 +68,10 @@ public:
    * skip.  The remaining part of the input path is appended to the
    * "prefix" value to construct the final name in the archive.
    */
-  bool Add(std::string path, size_t skip = 0, const char* prefix = 0);
+  bool Add(std::string path,
+     size_t skip = 0,
+     const char* prefix = 0,
+     bool recursive = true);
 
   /** Returns true if there has been no error.  */
   operator safe_bool() const
@@ -69,9 +88,65 @@ public:
   void SetVerbose(bool v) { this->Verbose = v; }
 
   void SetMTime(std::string const& t) { this->MTime = t; }
+
+  //! Sets the permissions of the added files/folders
+  void SetPermissions(mode_t permissions_)
+    {
+    this->Permissions.Set(permissions_);
+    }
+
+  //! Clears permissions - default is used instead
+  void ClearPermissions() { this->Permissions.Clear(); }
+
+  //! Sets the permissions mask of files/folders
+  //!
+  //! The permissions will be copied from the existing file
+  //! or folder. The mask will then be applied to unset
+  //! some of them
+  void SetPermissionsMask(mode_t permissionsMask_)
+    {
+    this->PermissionsMask.Set(permissionsMask_);
+    }
+
+  //! Clears permissions mask - default is used instead
+  void ClearPermissionsMask()
+    {
+    this->PermissionsMask.Clear();
+    }
+
+  //! Sets UID and GID to be used in the tar file
+  void SetUIDAndGID(int uid_, int gid_)
+    {
+    this->Uid.Set(uid_);
+    this->Gid.Set(gid_);
+    }
+
+  //! Clears UID and GID to be used in the tar file - default is used instead
+  void ClearUIDAndGID()
+    {
+    this->Uid.Clear();
+    this->Gid.Clear();
+    }
+
+  //! Sets UNAME and GNAME to be used in the tar file
+  void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
+    {
+    this->Uname = uname_;
+    this->Gname = gname_;
+    }
+
+  //! Clears UNAME and GNAME to be used in the tar file
+  //! default is used instead
+  void ClearUNAMEAndGNAME()
+    {
+    this->Uname = "";
+    this->Gname = "";
+    }
+
 private:
   bool Okay() const { return this->Error.empty(); }
-  bool AddPath(const char* path, size_t skip, const char* prefix);
+  bool AddPath(const char* path, size_t skip, const char* prefix,
+               bool recursive = true);
   bool AddFile(const char* file, size_t skip, const char* prefix);
   bool AddData(const char* file, size_t size);
 
@@ -87,6 +162,22 @@ private:
   std::string Format;
   std::string Error;
   std::string MTime;
+
+  //! UID of the user in the tar file
+  cmArchiveWriteOptional<int> Uid;
+
+  //! GUID of the user in the tar file
+  cmArchiveWriteOptional<int> Gid;
+
+  //! UNAME/GNAME of the user (does not override UID/GID)
+  //!@{
+  std::string Uname;
+  std::string Gname;
+  //!@}
+
+  //! Permissions on files/folders
+  cmArchiveWriteOptional<mode_t> Permissions;
+  cmArchiveWriteOptional<mode_t> PermissionsMask;
 };
 
 #endif

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
http://public.kitware.com/mailman/listinfo/cmake-commits

Reply via email to