Fix for svace issue
[platform/core/dotnet/launcher.git] / NativeLauncher / tool / dotnettool.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "utils.h"
18 #include "ni_common.h"
19 #include "tac_common.h"
20 #include "multi_target_resolver.h"
21 #include "log.h"
22
23 #include <vector>
24 #include <cstring>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <sys/time.h>
28 #include <app_common.h>
29
30 void DisplayUsage() {
31         _SOUT(
32                 "\n"
33                 "Dotnet Tool Version: 1.0\n"
34                 "\n"
35                 "Commands:\n"
36                 "       -h, --help                - Show this help message\n"
37                 "       --ni-system               - Create NI under System DLLs\n"
38                 "       --ni-dll                  - Create NI for DLL\n"
39                 "       --ni-pkg                  - Create NI for package\n"
40                 "                                   (If package is installed under RO area, NI files are generated under RW area)\n"
41                 "       --ni-dir                  - Create NI for directory\n"
42                 "       --ni-reset-system         - Remove System NI files\n"
43                 "       --ni-reset-pkg            - Remove App NI files\n"
44                 "       --ni-reset-dir            - Remove NI for directory\n"
45                 "       --ni-regen-all-app        - Re-generate All App NI files\n"
46                 "       --tac-regen-all           - Re-generate All TAC files\n"
47                 "       --tac-restore-db          - Restore TAC Database\n"
48                 "       --tac-disable-pkg         - Disable TAC for package\n"
49                 "       --tac-enable-pkg          - Enable TAC for package\n"
50                 "       --ibc-dir                 - Specify a directory containing IBC files\n"
51                 "       --resolve-all-app         - Remove unused multi-targeting files of all apps\n"
52                 "                                   (this option is used for FOTA script or test)\n"
53                 "       --rm-app-profile          - Remove application profile for all users\n"
54                 "                                   (this option should be run as root)\n"
55                 "\n"
56                 "Options:\n"
57                 "       --r2r                     - Generate a Ready-To-Run image (disable: /FragileNonVersionable)\n"
58                 "       --compatibility           - Compatibility mode for older versions of crossgen\n"
59                 "                                   (replaces /r with /Trusted_Platform_Assemblies)\n"
60                 "       --verbose                 - Display verbose information\n"
61                 "       --instrument              - Generate an instrumented image for profiling (enable: /Tuning)\n"
62                 "\n"
63                 "Usage: dotnettool [options] [command] [arguments]\n"
64                 "\n"
65                 "Example:\n"
66                 "1. Create native image for dlls and exes under platform directories\n"
67                 "   # dotnettool --ni-system\n"
68                 "2. Create native image for dll\n"
69                 "   # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
70                 "3. Create native image under the package's bin and lib directory\n"
71                 "   # dotnettool --ni-pkg org.tizen.FormsGallery\n"
72                 "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
73                 "   # dotnettool --r2r --ni-regen-all-app\n"
74                 "5. Create native image for dll based on the IBC data\n"
75                 "   # dotnettool --ibc-dir /tmp/ibcdata/ --ni-dll /usr/bin/Tizen.Runtime.dll\n"
76                 "6. Remove profile for package\n"
77                 "   # dotnettool --rm-app-profile org.tizen.FormsGallery\n"
78                 "\n");
79 }
80
81 int main(int argc, char* argv[])
82 {
83         argc--;
84         argv++;
85
86         long starttime;
87         long endtime;
88         struct timeval tv;
89         gettimeofday(&tv, NULL);
90         starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
91
92         if (argc <= 0) {
93                 DisplayUsage();
94                 return -1;
95         }
96
97         //sh-3.2# dotnettool --[r2r|compatibility|instrument|verbose]
98         DWORD flags = 0;
99         std::vector<std::string> args;
100         for (char** it = argv; it != argv+argc; it++) {
101                 if (!strncmp(*it, "-?", 2) || !strncmp(*it, "-h", 2) || !strncmp(*it, "--help", 6)) {
102                         DisplayUsage();
103                         return 0;
104                 } else if (!strncmp(*it, "--r2r", 5)) {
105                         flags |= NI_FLAGS_ENABLER2R;
106                 } else if (!strncmp(*it, "--compatibility", 15)) {
107                         flags |= NI_FLAGS_COMPATIBILITY;
108                 } else if (!strncmp(*it, "--instrument", 12)) {
109                         flags |= NI_FLAGS_INSTRUMENT;
110                 } else if (!strncmp(*it, "--verbose", 9)) {
111                         flags |= NI_FLAGS_VERBOSE;
112                 } else {
113                         args.push_back(*it);
114                 }
115         }
116
117         //sh-3.2# dotnettool --ibc-dir [ibcDirectory]
118         for (auto it = args.begin(); it != args.end(); ) {
119                 if (*it == "--ibc-dir") {
120                         it = args.erase(it);
121
122                         std::string ibcFilePath = std::string(*it);
123                         if (!isDirectory(ibcFilePath)) {
124                                 _SERR("IBC path is missing or not exist");
125                                 return -1;
126                         }
127
128                         setenv("COMPlus_IBCFileDir", const_cast<char *>(ibcFilePath.c_str()), 1);
129                         setenv("COMPlus_UseIBCFile", const_cast<char *>("1"), 1);
130                         it = args.erase(it);
131                 } else {
132                         ++it;
133                 }
134         }
135
136         if (initNICommon() != NI_ERROR_NONE) {
137                 return -1;
138         }
139
140         std::vector<std::string>::iterator it = args.begin();
141         std::string cmd = std::string(*it);
142         it = args.erase(it);
143
144         //sh-3.2# dotnettool --ni-system
145         if (cmd == "--ni-system") {
146                 int ret = createNIPlatform(flags);
147                 if (ret != NI_ERROR_NONE) {
148                         _SERR("Failed to generate system NI");
149                 }
150         }
151         //sh-3.2# dotnettool --ni-dll [assemblyPath] [assemblyPath] ...
152         else if (cmd == "--ni-dll") {
153                 if (args.size() < 1) {
154                         _SERR("DLL path is missing");
155                 }
156                 while (it != args.end()) {
157                         std::string dll = std::string(*it);
158                         int ret = createNIDll(dll, flags);
159                         if (ret != NI_ERROR_NONE) {
160                                 _SERR("Failed to generate NI file [%s]", dll.c_str());
161                                 break;
162                         }
163                         it = args.erase(it);
164                 }
165         }
166         //sh-3.2# dotnettool --ni-pkg [pkgId] [pkgId] ...
167         else if (cmd == "--ni-pkg") {
168                 if (args.size() < 1) {
169                         _SERR("Package name is missing");
170                 }
171                 while (it != args.end()) {
172                         std::string pkg = std::string(*it);
173                         int ret = createNIUnderPkgRoot(pkg, flags);
174                         if (ret != NI_ERROR_NONE) {
175                                 _SERR("Failed to generate app NI [%s]", pkg.c_str());
176                                 break;
177                         }
178                         it = args.erase(it);
179                 }
180         }
181         //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
182         else if (cmd == "--ni-dir") {
183                 if (args.size() < 1) {
184                         _SERR("Directory path is missing");
185                 }
186                 while (it != args.end()) {
187                         const std::string dir = std::string(*it);
188                         int ret = createNIUnderDirs(dir, flags);
189                         if (ret != NI_ERROR_NONE) {
190                                 _SERR("Failed to generate NI directory");
191                                 break;
192                         }
193                         it = args.erase(it);
194                 }
195         }
196         //sh-3.2# dotnettool --ni-reset-system
197         else if (cmd == "--ni-reset-system") {
198                 removeNIPlatform();
199         }
200         //sh-3.2# dotnettool --ni-reset-pkg [pkgId] [pkgId] ...
201         else if (cmd == "--ni-reset-pkg") {
202                 if (args.size() < 1) {
203                         _SERR("Package name is missing");
204                 }
205                 while (it != args.end()) {
206                         std::string pkg = std::string(*it);
207                         int ret = removeNIUnderPkgRoot(pkg);
208                         if (ret != NI_ERROR_NONE) {
209                                 _SERR("Failed to remove dlls for given package [%s]", pkg.c_str());
210                                 break;
211                         }
212                         it = args.erase(it);
213                 }
214         }
215         //sh-3.2# dotnettool --ni-reset-dir [AssemblyDirectory] [AssemblyDirectory] ...
216         else if (cmd == "--ni-reset-dir") {
217                 if (args.size() < 1) {
218                         _SERR("Directory path is missing");
219                 }
220                 while (it != args.end()) {
221                         const std::string dir = std::string(*it);
222                         removeNIUnderDirs(dir);
223                         it = args.erase(it);
224                 }
225         }
226         //sh-3.2# dotnettool --ni-regen-all-app
227         else if (cmd == "--ni-regen-all-app") {
228                 int ret = regenerateAppNI(flags);
229                 if (ret != NI_ERROR_NONE) {
230                         _SERR("Failed to regenerate all app NI");
231                 }
232         }
233         //sh-3.2# dotnettool --tac-regen-all
234         else if (cmd == "--tac-regen-all") {
235                 int ret = regenerateTACNI(flags);
236                 if (ret != NI_ERROR_NONE) {
237                         _SERR("Failed to regenerate all TAC");
238                 }
239         }
240         //sh-3.2# dotnettool --tac-restore-db
241         else if (cmd == "--tac-restore-db") {
242                 int ret = tac_restoreDB();
243                 if (ret != TAC_ERROR_NONE) {
244                         _SERR("Failed to restore TAC db");
245                 }
246                 ret = tlc_restoreDB();
247                 if (ret != TAC_ERROR_NONE) {
248                         _SERR("Failed to restore TLC db");
249                 }
250         }
251         //sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
252         else if (cmd == "--tac-enable-pkg") {
253                 if (args.size() < 1) {
254                         _SERR("Package name is missing");
255                 }
256                 while (it != args.end()) {
257                         std::string pkg = std::string(*it);
258                         int ret = enableTACPackage(pkg);
259                         if (ret != TAC_ERROR_NONE) {
260                                 _SERR("Failed to enable tac [%s]", pkg.c_str());
261                                 break;
262                         }
263                         it = args.erase(it);
264                 }
265         }
266         //sh-3.2# dotnettool --tac-disable-pkg [pkgId] [pkgId] ...
267         else if (cmd == "--tac-disable-pkg") {
268                 if (args.size() < 1) {
269                         _SERR("Package name is missing");
270                 }
271                 while (it != args.end()) {
272                         std::string pkg = std::string(*it);
273                         int ret = disableTACPackage(pkg);
274                         if (ret != TAC_ERROR_NONE) {
275                                 _SERR("Failed to disable tac [%s]", pkg.c_str());
276                                 break;
277                         }
278                         it = args.erase(it);
279                 }
280         }
281         //sh-3.2# dotnettool --resolve-all-app
282         else if (cmd == "--resolve-all-app") {
283                 int ret = resolveAllApps();
284                 if (ret != 0) {
285                         _SERR("Failed to remove unused multi-targeting files");
286                 }
287         }
288         //sh-3.2# dotnettool --rm-app-profile [pkgId] [pkgId] ...
289         else if (cmd == "--rm-app-profile") {
290                 if (args.size() < 1) {
291                         _SERR("Package name is missing");
292                 }
293                 char *home = getenv("HOME"); // /root
294                 if (home == NULL) {
295                         _SERR("Fail to get Home path from env");
296                 } else {
297                         while (it != args.end()) {
298                                 std::string pkg = std::string(*it);
299                                 setenv("AUL_APPID", pkg.c_str(), 1);
300                                 char *localDataPath = app_get_data_path(); // /root/apps_rw/<app_id>/data/
301                                 if (localDataPath != NULL) {
302                                         std::string pDataFile = "/home/*";
303                                         pDataFile.append(localDataPath + strlen(home)); // /home/*/apps_rw/<app_id>/data/
304                                         pDataFile.append(PROFILE_BASENAME); // /home/*/apps_rw/<app_id>/data/.__tizen_specific_profile_data
305                                         if (!removeFile(pDataFile)) {
306                                                 _SERR("Fail to remove file (%s)", pDataFile.c_str());
307                                         }
308                                         free(localDataPath);
309                                 } else {
310                                         _SERR("Application not found [%s], skip to remove profile", pkg.c_str());
311                                 }
312                                 it = args.erase(it);
313                         }
314                 }
315         }
316         else {
317                 _SERR("Unknown option [%s]", cmd.c_str());
318                 DisplayUsage();
319         }
320
321         finalizeNICommon();
322
323         gettimeofday(&tv, NULL);
324         endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
325         _SOUT("\nSpend time for dotnettool is [%d]ms", (int)(endtime - starttime));
326
327         return 0;
328 }