Ignore case file extension on search TPA.
authorpius.lee <pius.lee@samsung.com>
Thu, 4 Aug 2016 04:17:20 +0000 (13:17 +0900)
committerpius.lee <pius.lee@samsung.com>
Thu, 4 Aug 2016 04:17:20 +0000 (13:17 +0900)
Now ignore case on searching trusted platform assemblies.
Launching path (App path) include "lib" direcotry under application
root.

src/launcher.cc
src/launcher.h
src/waiter.cc
src/waiter.h

index 088f1be..ba15bb2 100644 (file)
@@ -8,6 +8,7 @@
 #include <sstream>
 #include <fstream>
 #include <memory>
+#include <algorithm>
 
 #include <dirent.h>
 #include <sys/stat.h>
@@ -38,6 +39,38 @@ static const std::string LauncherConfig(LAUNCHER_CONFIG);
 #undef LAUNCHER_PATH
 #endif
 
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+static std::string ConcatPath(const std::string& path1, const std::string& path2)
+{
+  std::string path(path1);
+  if (path.back() == PATH_SEPARATOR)
+  {
+    path.append(path2);
+  }
+  else
+  {
+    path += PATH_SEPARATOR;
+    path.append(path2);
+  }
+
+  return path;
+}
+static void AppendPath(std::string& path1, const std::string& path2)
+{
+  if (path1.back() == PATH_SEPARATOR)
+  {
+    path1.append(path2);
+  }
+  else
+  {
+    path1 += PATH_SEPARATOR;
+    path1.append(path2);
+  }
+}
+
 static std::string AbsolutePath(const std::string& path)
 {
   std::string absPath;
@@ -53,7 +86,7 @@ static std::string AbsolutePath(const std::string& path)
 
 static std::string Basename(const std::string& path)
 {
-  auto pos = path.find_last_of('/');
+  auto pos = path.find_last_of(PATH_SEPARATOR);
   if (pos != std::string::npos)
   {
     return path.substr(0, pos);
@@ -61,12 +94,31 @@ static std::string Basename(const std::string& path)
   return path;
 }
 
+static bool EndWithIC(const std::string& str1, const std::string& str2, std::string& filename)
+{
+  std::string::size_type len1 = str1.length();
+  std::string::size_type len2 = str2.length();
+  if (len2 > len1) return false;
+
+  int i = 0;
+  bool result = std::all_of(str1.cend() - len2, str1.end(),
+        [&i, &str2] (char x) {
+          return std::tolower(x) == std::tolower(str2[i++]);
+        });
+  if (result)
+  {
+    filename = str1.substr(0, len1 - len2);
+  }
+  return result;
+}
+
 static std::string AssembliesInDirectory(const char *directory)
 {
-  const char * const nativeImageExtension = ".ni";
-  const char * const tpaExtensions[] = {".dll", ".exe"};
-  int niExtensionSize = strlen(nativeImageExtension);
-  int directoryPathSize = strlen(directory);
+  const std::string ni = ".ni";
+  const std::string tpaExtensions[] =
+  {".ni.dll", ".dll", ".ni.exe", ".exe"};
+  const bool tpaExtensions_ni[] =
+  {true, false, true, false};
 
   std::string tpaList;
 
@@ -78,85 +130,64 @@ static std::string AssembliesInDirectory(const char *directory)
     return std::string();
   }
 
-  std::map<std::pair<std::string, std::string>, bool> addedAssemblies;
+  std::set<std::string> addedAssemblies;
 
   struct dirent *entry;
-  while ((entry = readdir(dir)) != nullptr)
+
+  int tpaCount = sizeof(tpaExtensions) / sizeof(tpaExtensions[0]);
+  for (int i=0; i<tpaCount; i++)
   {
-    switch (entry->d_type)
-    {
-      case DT_REG: break;
-      case DT_LNK:
-      case DT_UNKNOWN:
-        {
-          std::string fullname;
-          fullname.append(directory);
-          fullname.append("/");
-          fullname.append(entry->d_name);
-
-          struct stat sb;
-          if (stat(fullname.c_str(), &sb) == -1)
-            continue;
-
-          if (!S_ISREG(sb.st_mode))
-            continue;
-        }
-        break;
-      default:
-        continue;
-    }
+    const std::string& ext = tpaExtensions[i];
+    bool isNativeExt = tpaExtensions_ni[i];
 
-    // Check the extension.
-    std::string filename(entry->d_name);
-    int extPos = filename.find_last_of('.');
-    if (extPos <= 0) continue;
-    bool notUsedExtension = true;
-    for (auto ext : tpaExtensions)
+    while ((entry = readdir(dir)) != nullptr)
     {
-      int extLength = strlen(ext);
-
-      if (filename.compare(extPos, extLength, ext) == 0)
+      switch (entry->d_type)
       {
-        notUsedExtension = false;
-        break;
+        case DT_REG: break;
+        case DT_LNK:
+        case DT_UNKNOWN:
+          {
+            std::string fullname;
+            fullname.append(directory);
+            fullname += PATH_SEPARATOR;
+            fullname.append(entry->d_name);
+
+            struct stat sb;
+            if (stat(fullname.c_str(), &sb) == -1)
+              continue;
+
+            if (!S_ISREG(sb.st_mode))
+              continue;
+          }
+          break;
+        default:
+          continue;
       }
-    }
-    if (notUsedExtension) continue;
 
-    std::string filenameWithoutExt;
-    bool isNativeImage = extPos > niExtensionSize ?
-      filename.compare(extPos-niExtensionSize, niExtensionSize, nativeImageExtension) == 0 : false;
-    if (isNativeImage)
-    {
-      filenameWithoutExt = filename.substr(0, extPos-niExtensionSize);
-    }
-    else
-    {
-      filenameWithoutExt = filename.substr(0, extPos);
-    }
-    std::string ext = filename.substr(extPos);
+      // Check the extension.
+      std::string filename(entry->d_name);
+      std::string filenameWithoutExt;
+      if (!EndWithIC(filename, ext, filenameWithoutExt))
+        continue;
 
-    std::pair<std::string, std::string> key(filenameWithoutExt, ext);
-    if (addedAssemblies.count(key))
-    {
-      isNativeImage = isNativeImage || addedAssemblies[key];
-    }
-    addedAssemblies[key] = isNativeImage;
-  }
+      if (!isNativeExt)
+      {
+        EndWithIC(filenameWithoutExt, ni, filenameWithoutExt);
+      }
 
-  for (auto pair : addedAssemblies)
-  {
-    tpaList.append(directory);
-    if (directory[directoryPathSize-1] != '/')
-      tpaList.append("/");
-    tpaList.append(pair.first.first);
-    if (pair.second)
-    {
-      tpaList.append(nativeImageExtension);
+      if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
+      {
+        addedAssemblies.insert(filenameWithoutExt);
+        std::string assembly;
+        assembly.append(directory);
+        assembly += PATH_SEPARATOR;
+        assembly.append(filename);
+        _DBG("TPA : %s", assembly.c_str());
+        tpaList += assembly + ':';
+      }
     }
-    tpaList.append(pair.first.second);
-    tpaList.append(":");
-    _DBG("TPA : %s/%s%s", directory, pair.first.first.c_str(), pair.first.second.c_str());
+    rewinddir(dir);
   }
 
   closedir(dir);
@@ -239,11 +270,10 @@ void Launcher::Initialize()
   }
 }
 
-void Launcher::Launch(const string& exe_path, int argc, char *argv[])
+void Launcher::Launch(const string& exe_path, const string& app_root, int argc, char *argv[])
 {
   std::string bin_path = Basename(AbsolutePath(exe_path));
-  std::string app_home = Basename(bin_path);
-  std::string lib_path = app_home + "/lib";
+  std::string lib_path = ConcatPath(AbsolutePath(app_root), "lib");
   std::string app_path = bin_path + ":" + lib_path;
   std::string app_ni_path = app_path;
   std::string nativeDllSearchDirectories = NativeDllSearchDirectories + app_path;
@@ -339,10 +369,10 @@ int main(int argc, char *argv[])
   auto on_requested = [&launcher]()
   {
   };
-  auto on_executed = [&launcher](const std::string& path, int argc, char *argv[])
+  auto on_executed = [&launcher](const std::string& path, const std::string& app_root, int argc, char *argv[])
   {
     _DBG("EXECUTE %s", path.c_str());
-    launcher->Launch(path, argc, argv);
+    launcher->Launch(path, app_root, argc, argv);
   };
   std::unique_ptr<Waiter> waiter(new Waiter(on_prepare, on_requested, on_executed));
   waiter->WaitToLaunching(argc, argv);
index 7030f85..acba908 100644 (file)
@@ -34,7 +34,7 @@ class Launcher
     Launcher();
     ~Launcher();
     void Initialize();
-    void Launch(const string& exe_path, int argc, char *argv[]);
+    void Launch(const string& exe_path, const string& app_root, int argc, char *argv[]);
 
   private:
     coreclr_initialize_ptr initializeCoreCLR;
index 7f6eeef..6f83482 100644 (file)
@@ -3,6 +3,7 @@
 
 #ifndef NO_TIZEN
 #include <launchpad.h>
+#include <aul.h>
 #endif
 
 #include <memory>
@@ -145,8 +146,10 @@ int Waiter::WaitToLaunching(int argc, char *argv[])
   auto on_terminate = [](int argc, char **argv, void *user_data) -> int
   {
     _DBG("on_terminate..."); // XXX
+    
+    string app_root(aul_get_app_root_path());
     Waiter* waiter = static_cast<Waiter*>(user_data);
-    waiter->executor_(argv[0], argc, argv);
+    waiter->executor_(argv[0], app_root, argc, argv);
     return 0;
   };
 
@@ -195,6 +198,14 @@ int Waiter::WaitToLaunching(int argc, char *argv[])
   return launchpad_loader_main(argc, argv, &callbacks, &adapter, this);
 #else
   if (argc < 2) return -1;
+  std::string app_path(argv[1]);
+  std::string app_root;
+  auto pos = app_path.find_last_of('/');
+  if (pos != std::string::npos)
+    app_root = app_path.substr(0, pos);
+  else
+    app_root = ".";
+
   this->OnPrepare();
     AppInfo info = {
       AppPath : argv[1],
@@ -203,7 +214,7 @@ int Waiter::WaitToLaunching(int argc, char *argv[])
       PkgType : ""
     };
   this->OnLaunchRequested(info);
-  this->executor_(argv[1], argc, argv);
+  this->executor_(app_path, app_root, argc, argv);
 #endif
 }
 
index 5fa9dd3..f233317 100644 (file)
@@ -19,7 +19,7 @@ class Waiter
       string PkgType;
     };
     using Action = std::function<void(void)>;
-    using Executor = std::function<void(const string&, int, char**)>;
+    using Executor = std::function<void(const string&, const string&, int, char**)>;
 
     Waiter(Action prepare, Action requested, Executor executor);
     ~Waiter();