[Archive] Resolved TODOs
authorPiotr Kosko <p.kosko@samsung.com>
Tue, 6 Oct 2015 08:49:58 +0000 (10:49 +0200)
committerPiotr Kosko <p.kosko@samsung.com>
Tue, 6 Oct 2015 08:51:27 +0000 (10:51 +0200)
[Feature]
 Resolved:
  - permissions of zipped files
  - in-zip paths problem

[Verification] Code compiles without errors.
  In-zip paths are correct.
  Correct file permissions are passed while zipping and unzipping.
  TCT passrate is 100%.

Change-Id: Iabd9372b753be740e0011b29f40cc2c86384ddf9
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
src/archive/archive_callback_data.cc
src/archive/archive_utils.cc
src/archive/archive_utils.h
src/archive/filesystem_file.cc
src/archive/filesystem_file.h
src/archive/filesystem_node.cc
src/archive/filesystem_node.h
src/archive/un_zip.cc
src/archive/un_zip.h
src/archive/un_zip_extract_request.cc
src/archive/un_zip_extract_request.h

index dcb210ffca6f2f638964d3b07abc1d81c26c3234..2efbaefb2a829e37ff5646164b7c1cadf17c5275 100755 (executable)
@@ -535,7 +535,7 @@ void AddProgressCallback::setBasePath(const std::string& path)
 {
     LoggerD("Entered");
     m_base_path = path;
-    m_base_virt_path = filesystem::External::toVirtualPath(m_base_path);
+    m_base_virt_path = filesystem::External::cutVirtualRoot(m_base_path);
     std::string::size_type pos = m_base_virt_path.find(filesystem::Path::getSeparator());
     if (pos != std::string::npos)
     {
index 1ce2c703e0235c7da649da483da992bbbfebeaa2..b0414d55fcc05a1c9789df70f57b70f1849e2e18 100755 (executable)
@@ -19,9 +19,6 @@
 #include <iomanip>
 #include "common/logger.h"
 
-//TODO:
-//#include <FilesystemExternalUtils.h>
-
 using namespace common;
 
 namespace extension {
@@ -96,34 +93,6 @@ PlatformResult stringToFileMode(std::string fmString, FileMode* fm)
     return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalid FileMode");
 }
 
-// FilePtr fileReferenceToFile(JSContextRef context, JSValueRef fileReference)
-// {
-//     auto g_ctx = GlobalContextManager::getInstance()->getGlobalContext(context);
-//
-//     FilePtr file_ptr;
-//     try {
-//         file_ptr = JSFile::getPrivateObject(context, fileReference);
-//     } catch (const TypeMismatchException &tme) {
-//         LOGD("Use virtual path.");
-//         std::string virtual_path =
-//             JSUtil::JSValueToString(context, fileReference);
-//         if (!External::isVirtualPath(virtual_path)) {
-//             LOGE("FileReference can be File object or a virtual path");
-//             throw TypeMismatchException(
-//                 "FileReference can be File object or a virtual path");
-//         }
-//         std::string string_path =
-//             External::fromVirtualPath(virtual_path, g_ctx);
-//         LOGD("Path: %s", string_path.c_str());
-//
-//         PathPtr path = Path::create(string_path);
-//         NodePtr node_ptr = Node::resolve(path);
-//         file_ptr = FilePtr(new File(node_ptr, File::PermissionList()));
-//     }
-//
-//     return file_ptr;
-// }
-
 void getBasePathAndName(const std::string& filepath,
         std::string& out_basepath,
         std::string& out_name)
index 541822e1b4b1d1e7e42ed1f2277ae9caf2a69f84..1b9dcb3db83a96b058918d36cdfbf30f65e207d1 100755 (executable)
@@ -30,9 +30,6 @@ std::string bytesToReadableString(const size_t num_bytes);
 common::PlatformResult fileModeToString(FileMode fm, std::string* fm_str);
 common::PlatformResult stringToFileMode(std::string fmString, FileMode* fm);
 
-//extern Filesystem::FilePtr fileReferenceToFile(
-//    JSContextRef context, JSValueRef fileReference);
-
 /**
  * Gets base path and name from full path string, example cases:
  * full path             |  base path        | name
index cbd8de7e64feebcf9c99878f765c4d45719e9907..d5e9df514bce69175ba8f296c319d166d5732467 100755 (executable)
@@ -21,6 +21,11 @@ using namespace common;
 namespace extension {
 namespace filesystem {
 
+namespace {
+const std::string kVirtualRootsDirectory = "/opt/usr/media/";
+const std::string kSlash = "/";
+}
+
 File::File(NodePtr node, const File::PermissionList &parentPermissions,
         const std::string& original_location) :
     m_node(node),
@@ -65,11 +70,11 @@ const std::string& File::getOriginalFullPath() const
     return m_original_fullpath;
 }
 
-std::string External::toVirtualPath(const std::string& path)
+std::string External::cutVirtualRoot(const std::string& path)
 {
-    //TODO::implement this method
-    LoggerW("Just STUB");
-    return path;
+    LoggerD("Enter path %s", path.c_str());
+    std::string tmp_path = path.substr(kVirtualRootsDirectory.length());
+    return tmp_path.substr(tmp_path.find(kSlash));
 }
 
 } // filesystem
index 26401f29fcaddc050e6fac155d6e1fcd4da572bf..b764bbdd645a273b5b2d04adec611a05b4b38490 100755 (executable)
@@ -58,7 +58,7 @@ private:
 
 class External {
 public:
-    static std::string toVirtualPath(const std::string& path);
+    static std::string cutVirtualRoot(const std::string& path);
 };
 
 
index 4e2744b50006e73f9217492e01026742637798cf..918b0c1721e5bacae5c789808d46fff3e3f6de41 100755 (executable)
@@ -429,7 +429,6 @@ PlatformResult Node::getModified(std::time_t* time) const
     return PlatformResult(ErrorCode::NO_ERROR);
 }
 
-// TODO Optimize it, maybe store a flag indicating that node is a root.
 PlatformResult Node::getParent(NodePtr* node) const
 {
     LoggerD("Enter");
@@ -638,13 +637,6 @@ PlatformResult Node::removeAsDirectory(const PathPtr& path, bool recursive)
     return PlatformResult(ErrorCode::NO_ERROR);
 }
 
-std::string Node::toUri(int /*widgetId*/) const
-{
-    LoggerD("Enter");
-    // TODO I believe moving this feature to WrtWrapper would make more sense.
-    return "file://" + m_path->getFullPath();
-}
-
 bool Node::isSubPath(std::string aDirPath, PathPtr aFilePath)
 {
     LoggerD("Enter");
index 9cc9b5227987d507023ea9b9e6710374f0a4bb44..a8b529952734b83d246d208ab8cf07a929347f1f 100755 (executable)
@@ -226,8 +226,6 @@ public:
     //! - OPT_RECURSIVE - remove node recursively.
     common::PlatformResult remove(int options);
 
-    std::string toUri(int widgetId) const;
-
     static bool isSubPath(std::string aDirPath, PathPtr aFilePath);
 
 private:
index cc5616c2f830888f918b50191ba6ea83a2e65332..b961e0e9e839d00a320d3fbb47265e82c8cee010 100755 (executable)
@@ -26,6 +26,7 @@
 
 #include "common/logger.h"
 #include "common/platform_exception.h"
+#include "common/tools.h"
 #include "filesystem_file.h"
 
 #include "archive_file.h"
@@ -36,6 +37,7 @@ namespace extension {
 namespace archive {
 
 using namespace common;
+using common::tools::GetErrorString;
 
 UnZip::UnZip(const std::string& filename) :
         m_zipfile_name(filename),
@@ -50,6 +52,13 @@ UnZip::UnZip(const std::string& filename) :
 UnZip::~UnZip()
 {
     LoggerD("Enter");
+    for (auto& x: path_access_map) {
+      LoggerD("Setting permission for path: %s  [%d] ", x.first.c_str(), x.second);
+      if(chmod(x.first.c_str(), x.second) == -1) {
+        LoggerE("Couldn't set permissions for: [%s] errno: %s", x.first.c_str(),
+                GetErrorString(errno).c_str());
+      }
+    }
     close();
 }
 
index 187d9c5b1c1b1f5ab6b5d0a89091344ba71e7e0e..68a30272bf81f9a8ad6857c1fc038f093dc2743c 100755 (executable)
@@ -90,6 +90,13 @@ private:
     size_t m_default_buffer_size;
     bool m_is_open;
 
+    struct ComparePaths : public std::binary_function <bool, std::string, std::string> {
+      bool operator() (const std::string& lhs, const std::string& rhs) {
+        return lhs.length() > rhs.length();
+      }
+    };
+    std::map<std::string, __mode_t, ComparePaths> path_access_map;
+
     friend class UnZipExtractRequest;
 };
 
index 2498d6e11ffe8df0cc62d8bb558ccaa72a60cf63..197d6b5d4269bbf40a44e8baddbf53ecd91236c4 100755 (executable)
@@ -95,13 +95,11 @@ void createMissingDirectories(const std::string& path, bool check_first = true)
             //LoggerD("left_part: [%s] status:%d", left_part.c_str(), status);
 
             if(FPS_DIRECTORY != status) {
-                //TODO investigate 0775 (mode) - filesystem assumed that file should have parent mode
+                // permissions would be changed after extract process would be finished,
+                // for now using default 0775
                 if(mkdir(left_part.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
                     LoggerE("Couldn't create new directory: %s errno: %s",
                             left_part.c_str(), GetErrorString(errno).c_str());
-               //TODO check why mkdir return -1 but directory is successfully created
-               //     throw UnknownException(
-               //             "Could not create new directory");
                 }
             }
         }
@@ -321,6 +319,8 @@ PlatformResult UnZipExtractRequest::handleDirectoryEntry()
             m_file_info.tmu_date.tm_min,
             m_file_info.tmu_date.tm_sec);
 
+    // change modify date and store permission for later update
+    storePermissions();
     // Directory already exists we only need to update time
     changeFileAccessAndModifyDate(m_new_dir_path, m_file_info.tmu_date);
 
@@ -341,14 +341,11 @@ PlatformResult UnZipExtractRequest::prepareOutputSubdirectory()
                                   "output path is invalid");
         }
 
-        //Try to create new directory in output directory
-        //TODO investigate 0775 (mode) - filesystem assumed that file should have parent mode
+        // permissions would be changed after extract process would be finished,
+        // for now using default 0775
         if(mkdir(m_new_dir_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
             LoggerW("couldn't create new directory: %s errno: %s",
                     m_new_dir_path.c_str(), GetErrorString(errno).c_str());
-            //TODO check why mkdir return -1 but directory is successfully created
-            //     throw UnknownException(
-            //     "Could not create new directory in extract output directory");
         }
     }
 
@@ -363,8 +360,6 @@ PlatformResult UnZipExtractRequest::prepareOutputSubdirectory()
             LoggerW("%s exists at output path: [%s], overwrite is set to FALSE",
                     (FPS_DIRECTORY == output_fstatus ? "Directory" : "File"),
                     m_output_filepath.c_str());
-
-            //Just skip this file - TODO: this should be documented in WIDL
             return PlatformResult(ErrorCode::INVALID_MODIFICATION_ERR, "file already exists.");
         } else {
             if(FPS_DIRECTORY == output_fstatus) {
@@ -511,10 +506,23 @@ PlatformResult UnZipExtractRequest::handleFileEntry()
         m_output_file = NULL;
     }
 
+    // change modify date and store permission for later update
+    storePermissions();
     changeFileAccessAndModifyDate(m_output_filepath, m_file_info.tmu_date);
 
     return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+void UnZipExtractRequest::storePermissions() {
+  // hold access information for later set
+  // The high 16 bits of the external file attributes seem to be used for OS-specific permissions
+  __mode_t mode = m_file_info.external_fa >> 16;
+  // check if proper permission mode is provided, if not use default 0775
+  if (mode == 0) {
+    mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
+  }
+  m_owner.path_access_map[m_output_filepath.c_str()] = mode;
+}
+
 } //namespace archive
 } //namespace extension
index 6c12f7bcc80964e78ead36ceb07bcb773a457748..ee7fabb728dc385c76e4940f3883f74d43eeda29 100755 (executable)
@@ -50,6 +50,7 @@ private:
     PlatformResult handleDirectoryEntry();
     PlatformResult handleFileEntry();
     PlatformResult prepareOutputSubdirectory();
+    void storePermissions();
 
     //-----------------------------------------------------------------------------
     //Input request variables