776fd9f88e0d7c7f32f25b57f0aee6d8b3e5065d
[platform/core/dotnet/launcher.git] / NativeLauncher / src / utils.cc
1
2 #include <dirent.h>
3 #include <sys/stat.h>
4 #include <unistd.h>
5 #include <limits.h>
6 #include <strings.h>
7
8 #include <cstdlib>
9 #include <cstring>
10 #include <algorithm>
11 #include <set>
12 #include <vector>
13 #include <iterator>
14 #include <sstream>
15
16 #include "utils.h"
17
18 std::string ReadSelfPath()
19 {
20   char buff[PATH_MAX];
21   ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
22   if (len != -1) {
23     buff[len] = '\0';
24     return std::string(buff);
25   }
26
27   return "";
28 }
29
30 std::string ConcatPath(const std::string& path1, const std::string& path2)
31 {
32   std::string path(path1);
33   if (path.back() == PATH_SEPARATOR)
34   {
35     path.append(path2);
36   }
37   else
38   {
39     path += PATH_SEPARATOR;
40     path.append(path2);
41   }
42
43   return path;
44 }
45
46 void AppendPath(std::string& path1, const std::string& path2)
47 {
48   if (path1.back() == PATH_SEPARATOR)
49   {
50     path1.append(path2);
51   }
52   else
53   {
54     path1 += PATH_SEPARATOR;
55     path1.append(path2);
56   }
57 }
58
59 std::string AbsolutePath(const std::string& path)
60 {
61   std::string absPath;
62
63   char realPath[PATH_MAX];
64   if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0')
65   {
66     absPath.assign(realPath);
67   }
68
69   return absPath;
70 }
71
72 std::string Basename(const std::string& path)
73 {
74   auto pos = path.find_last_of(PATH_SEPARATOR);
75   if (pos != std::string::npos)
76   {
77     return path.substr(0, pos);
78   }
79   else
80   {
81     return std::string(".");
82   }
83   return path;
84 }
85
86 bool EndWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& filename)
87 {
88   std::string::size_type len1 = str1.length();
89   std::string::size_type len2 = str2.length();
90   if (len2 > len1) return false;
91
92   int i = 0;
93   bool result = std::all_of(str1.cend() - len2, str1.end(),
94         [&i, &str2] (char x) {
95           return std::tolower(x) == std::tolower(str2[i++]);
96         });
97   if (result)
98   {
99     filename = str1.substr(0, len1 - len2);
100   }
101   return result;
102 }
103
104 bool FileNotExist(const std::string& path)
105 {
106   struct stat sb;
107   return (stat(path.c_str(), &sb) != 0) || !S_ISREG(sb.st_mode);
108 }
109
110 static bool ExtCheckAndGetFileNameIfExist(const std::string&  dir, const std::string& ext, struct dirent* entry, std::string& filename)
111 {
112   std::string fname(entry->d_name);
113   if (fname.length() < ext.length() ||
114       fname.compare(fname.length() - ext.length(), ext.length(), ext) != 0)
115   {
116     return false;
117   }
118   std::string fullname = ConcatPath(dir, entry->d_name);
119   switch (entry->d_type)
120   {
121     case DT_REG: break;
122     case DT_LNK:
123     case DT_UNKNOWN:
124       if (FileNotExist(fullname))
125       {
126         return false;
127       }
128     default:
129       return false;
130   }
131
132   filename = fullname;
133
134   return true;
135 }
136
137 std::string StripNIDLL(const std::string& path)
138 {
139   std::string npath(path);
140   if (path.size() < 5) return npath;
141   if (strncasecmp(path.c_str() + path.size() - 4, ".dll", 4))
142   {
143     npath = path.substr(0, path.size()-4);
144   }else if (strncasecmp(path.c_str() + path.size() - 4, ".exe", 4))
145   {
146     npath = path.substr(0, path.size()-4);
147   }
148   if (strncasecmp(npath.c_str() + npath.size() - 3, ".ni", 3))
149   {
150     return npath.substr(0, npath.size()-3);
151   }
152   return npath;
153 }
154
155 std::string JoinStrings(const std::vector<std::string>& strings, const char* const delimeter)
156 {
157   switch (strings.size())
158   {
159     case 0:
160       return "";
161     case 1:
162       return strings[0];
163     default:
164       std::ostringstream os; 
165       std::copy(strings.begin(), strings.end()-1, std::ostream_iterator<std::string>(os, delimeter));
166       os << *strings.rbegin();
167       return os.str();
168   }
169 }
170
171 void AssembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList)
172 {
173   static const std::string tpaExtensions[] =
174   {".ni.dll", ".dll", ".ni.exe", ".exe"};
175
176   std::set<std::string> addedAssemblies;
177
178   DIR* dir = nullptr;
179   struct dirent* entry = nullptr;
180
181   for (auto directory : directories)
182   {
183     dir = opendir(directory.c_str());
184     if (dir == nullptr)
185     {
186       continue;
187     }
188
189     for (auto ext : tpaExtensions)
190     {
191       while ((entry = readdir(dir)) != nullptr)
192       {
193         std::string fullname;
194         if (ExtCheckAndGetFileNameIfExist(directory.c_str(), ext, entry, fullname))
195         {
196           std::string filename = StripNIDLL(fullname);
197           if (addedAssemblies.find(filename) == addedAssemblies.end())
198           {
199             addedAssemblies.insert(filename);
200             tpaList += fullname + ':';
201           }
202         }
203       }
204       rewinddir(dir);
205     }
206     closedir(dir);
207   }
208   if (tpaList.back() == ':')
209     tpaList.pop_back();
210
211 }