Add the option to check Internet privilege in dotnettool for the FOTA
[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 "profile_common.h"
21 #include "privilege_common.h"
22 #include "multi_target_resolver.h"
23 #include "log.h"
24
25 #include <vector>
26 #include <cstring>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <sys/time.h>
30 #include <app_common.h>
31
32 void DisplayUsage() {
33         _SOUT(
34                 "\n"
35                 "Dotnet Tool Version: 1.0\n"
36                 "\n"
37                 "Commands:\n"
38                 "       -h, --help                - Show this help message\n"
39                 "       --ni-system               - Create NI under System DLLs\n"
40                 "       --ni-dll                  - Create NI for DLL\n"
41                 "       --ni-pkg                  - Create NI for package\n"
42                 "                                   (If package is installed under RO area, NI files are generated under RW area)\n"
43                 "       --ni-dir                  - Create NI for directory\n"
44                 "       --ni-reset-system         - Remove System NI files\n"
45                 "       --ni-reset-pkg            - Remove App NI files\n"
46                 "       --ni-reset-dir            - Remove NI for directory\n"
47                 "       --ni-regen-all-app        - Re-generate All App NI files\n"
48                 "       --tac-regen-all           - Re-generate All TAC files\n"
49                 "       --tac-restore-db          - Restore TAC Database\n"
50                 "       --tac-disable-pkg         - Disable TAC for package\n"
51                 "       --tac-enable-pkg          - Enable TAC for package\n"
52                 "       --resolve-all-app         - Remove unused multi-targeting files of all apps\n"
53                 "                                   (this option is used for FOTA script or test)\n"
54                 "       --rm-app-profile          - Remove application profile of given packages for all users\n"
55                 "                                   (this option should be run as root)\n"
56                 "       --rm-all-app-profile      - Remove application profile of all packages for all users\n"
57                 "                                   (this option should be run as root)\n"
58                 "       --check-all-app-privilege - Chcek application privilege of all package\n"
59                 "                                   (this option should be run as root)\n"
60                 "\n"
61                 "Options:\n"
62                 "       --mibc                    - Specify Mibc files. Sepatated with ':'.\n"
63                 "       --verbose                 - Display verbose information\n"
64                 "       --inputbubble             - Compile input assemblies into one bubble with the assemblies described at --inputbubbleref option\n"
65                 "                                   Note!: If you do not have an accurate understanding of Bubble, do not use this option.\n"
66                 "                                          All assemblies in the bubble must be guaranteed to be compiled to the native image before execution.\n"
67                 "                                          If an uncompiled assembly is included in the bubble during execution, an unknown error may occur.\n"
68                 "                                          If --inputbubbleref option doesnot be set, only input files are included to bubble. \n"
69                 "       --inputbubbleref          - Input bubble reference file(s) to be added to bubble (used with --inputbubble option)\n"
70                 "       --ref                     - Reference file(s) for compilation\n"
71                 "                                   (system paths are set automatically.)\n"
72                 "       --no-pipeline             - Compile the dlls individually\n"
73                 "       --print-cmd               - Print command and options\n"
74                 "       --skip-ro-app             - Skip re-generate NI for apps installed RO area\n"
75                 "                                   (This option works with --ni-regen-all-app only)\n"
76                 "\n"
77                 "Usage: dotnettool [options] [command] [arguments]\n"
78                 "\n"
79                 "Example:\n"
80                 "1. Create native image for dlls and exes under platform directories\n"
81                 "   # dotnettool --ni-system\n"
82                 "2. Create native image for dll\n"
83                 "   # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
84                 "3. Create native image under the package's bin and lib directory\n"
85                 "   # dotnettool --ni-pkg org.tizen.FormsGallery\n"
86                 "4. Regenerate native images for all installed .net packages\n"
87                 "   # dotnettool --ni-regen-all-app\n"
88                 "5. Create native image for dll based on the Mibc data\n"
89                 "   # dotnettool --mibc /tmp/ibcdata/in.mibc --ni-dll /usr/bin/Tizen.Runtime.dll\n"
90                 "6. Remove profile for package\n"
91                 "   # dotnettool --rm-app-profile org.tizen.FormsGallery\n"
92                 "\n");
93 }
94
95 int main(int argc, char* argv[])
96 {
97         argc--;
98         argv++;
99
100         long starttime;
101         long endtime;
102         struct timeval tv;
103         gettimeofday(&tv, NULL);
104         starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
105
106         if (argc <= 0) {
107                 DisplayUsage();
108                 return -1;
109         }
110
111         NIOption* opt = getNIOption();
112         if (opt == nullptr) {
113                 _SERR("Fail to create option structure.");
114                 return -1;
115         }
116
117         std::vector<std::string> args;
118         for (int i = 0; i < argc; ++i) {
119                 std::string arg = argv[i];
120
121                 if ((arg == "-?") || (arg == "-h") || (arg == "--h")) {
122                         DisplayUsage();
123                         return 0;
124                 } else if (arg == "--verbose") {
125                         opt->flags |= NI_FLAGS_VERBOSE;
126                 } else if (arg == "--inputbubble") {
127                         opt->flags |= NI_FLAGS_INPUT_BUBBLE;
128                 } else if (arg == "--no-pipeline") {
129                         opt->flags |= NI_FLAGS_NO_PIPELINE;
130                 } else if (arg == "--print-cmd") {
131                         opt->flags |= NI_FLAGS_PRINT_CMD;
132                 } else if (arg == "--skip-ro-app") {
133                         opt->flags |= NI_FLAGS_SKIP_RO_APP;
134                 } else if (arg == "--mibc") {
135                         ++i;
136                         if (i >= argc) {
137                                 _SOUT("File path containing Mibc files should be followed for --mibc option");
138                                 DisplayUsage();
139                                 return 0;
140                         }
141
142                         opt->flags |= NI_FLAGS_MIBC;
143
144                         std::vector<std::string> paths;
145                         splitPath(std::string(argv[i]), paths);
146                         for (const auto &path : paths) {
147                                 if (!isFile(path) || isDirectory(path)) {
148                                         _SERR("Mibc file path is missing or does not exist");
149                                         return -1;
150                                 }
151                                 opt->mibcPath.push_back(path);
152                         }
153                 } else if (arg == "--inputbubbleref") {
154                         ++i;
155                         if (i >= argc) {
156                                 _SOUT("Path for references should be followed for --inputbubbleref option");
157                                 DisplayUsage();
158                                 return 0;
159                         }
160
161                         opt->flags |= NI_FLAGS_INPUT_BUBBLE_REF;
162
163                         std::vector<std::string> files;
164                         splitPath(std::string(argv[i]), files);
165                         for (const auto &f : files) {
166                                 opt->inputBubbleRefFiles.push_back(f);
167                         }
168                 } else if (arg == "--ref") {
169                         ++i;
170                         if (i >= argc) {
171                                 _SOUT("Path for references should be followed for --ref option");
172                                 DisplayUsage();
173                                 return 0;
174                         }
175
176                         std::vector<std::string> files;
177                         splitPath(std::string(argv[i]), files);
178                         for (const auto &f : files) {
179                                 opt->refFiles.push_back(f);
180                         }
181                 } else {
182                         args.push_back(arg);
183                 }
184         }
185
186         if (opt->flags & NI_FLAGS_INPUT_BUBBLE_REF && !(opt->flags & NI_FLAGS_INPUT_BUBBLE)) {
187                 _SERR("--inputbubbleref option should be used with --inputbubble option");
188                 DisplayUsage();
189                 return -1;
190         }
191
192         if (initNICommon() != NI_ERROR_NONE) {
193                 return -1;
194         }
195
196         std::vector<std::string>::iterator it = args.begin();
197         std::string cmd = std::string(*it);
198         it = args.erase(it);
199
200         //sh-3.2# dotnettool --ni-system [AssemblyDirectory] [AssemblyDirectory] ...
201         if (cmd == "--ni-system") {
202                 std::string inputs;
203                 while (it != args.end()) {
204                         const std::string dir = std::string(*it);
205                         inputs = inputs + ":" + dir;
206                         it = args.erase(it);
207                 }
208                 int ret = createNIPlatform(inputs, opt);
209                 if (ret != NI_ERROR_NONE) {
210                         _SERR("Failed to generate system NI");
211                 }
212         }
213         //sh-3.2# dotnettool --ni-dll [assemblyPath] [assemblyPath] ...
214         else if (cmd == "--ni-dll") {
215                 if (args.size() < 1) {
216                         _SERR("DLL path is missing");
217                 }
218                 std::vector<std::string> inputs;
219                 while (it != args.end()) {
220                         std::string dll = std::string(*it);
221                         inputs.push_back(dll);
222                         opt->refFiles.push_back(dll);
223                         if (opt->flags & NI_FLAGS_INPUT_BUBBLE) {
224                                 opt->inputBubbleRefFiles.push_back(dll);
225                         }
226                         it = args.erase(it);
227                 }
228
229                 for (auto &dll : inputs) {
230                         int ret = createNIDll(dll, opt);
231                         if (ret != NI_ERROR_NONE && ret != NI_ERROR_ALREADY_EXIST) {
232                                 _SERR("Failed to generate NI file [%s]", dll.c_str());
233                                 break;
234                         }
235                 }
236         }
237         //sh-3.2# dotnettool --ni-pkg [pkgId] [pkgId] ...
238         else if (cmd == "--ni-pkg") {
239                 if (args.size() < 1) {
240                         _SERR("Package name is missing");
241                 }
242                 while (it != args.end()) {
243                         std::string pkg = std::string(*it);
244                         int ret = createNIUnderPkgRoot(pkg, opt);
245                         if (ret != NI_ERROR_NONE) {
246                                 _SERR("Failed to generate app NI [%s]", pkg.c_str());
247                                 break;
248                         }
249                         it = args.erase(it);
250                 }
251         }
252         //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
253         else if (cmd == "--ni-dir") {
254                 if (args.size() < 1) {
255                         _SERR("Directory path is missing");
256                 }
257                 std::string dir;
258                 while (it != args.end()) {
259                         if (!dir.empty()) {
260                                 dir += std::string(":");
261                         }
262                         dir += std::string(*it);
263                         it = args.erase(it);
264                 }
265                 if (createNIUnderDirs(dir, opt) != NI_ERROR_NONE) {
266                         _SERR("Failed to generate NI directory");
267                 }
268         }
269         //sh-3.2# dotnettool --ni-reset-system
270         else if (cmd == "--ni-reset-system") {
271                 removeNIPlatform();
272         }
273         //sh-3.2# dotnettool --ni-reset-pkg [pkgId] [pkgId] ...
274         else if (cmd == "--ni-reset-pkg") {
275                 if (args.size() < 1) {
276                         _SERR("Package name is missing");
277                 }
278                 while (it != args.end()) {
279                         std::string pkg = std::string(*it);
280                         int ret = removeNIUnderPkgRoot(pkg);
281                         if (ret != NI_ERROR_NONE) {
282                                 _SERR("Failed to remove dlls for given package [%s]", pkg.c_str());
283                                 break;
284                         }
285                         it = args.erase(it);
286                 }
287         }
288         //sh-3.2# dotnettool --ni-reset-dir [AssemblyDirectory] [AssemblyDirectory] ...
289         else if (cmd == "--ni-reset-dir") {
290                 if (args.size() < 1) {
291                         _SERR("Directory path is missing");
292                 }
293                 while (it != args.end()) {
294                         const std::string dir = std::string(*it);
295                         removeNIUnderDirs(dir);
296                         it = args.erase(it);
297                 }
298         }
299         //sh-3.2# dotnettool --ni-regen-all-app
300         else if (cmd == "--ni-regen-all-app") {
301                 int ret = regenerateAppNI(opt);
302                 if (ret != NI_ERROR_NONE) {
303                         _SERR("Failed to regenerate all app NI");
304                 }
305         }
306         //sh-3.2# dotnettool --tac-regen-all
307         else if (cmd == "--tac-regen-all") {
308                 int ret = regenerateTACNI(opt);
309                 if (ret != NI_ERROR_NONE) {
310                         _SERR("Failed to regenerate all TAC");
311                 }
312         }
313         //sh-3.2# dotnettool --tac-restore-db
314         else if (cmd == "--tac-restore-db") {
315                 int ret = tac_restoreDB();
316                 if (ret != TAC_ERROR_NONE) {
317                         _SERR("Failed to restore TAC db");
318                 }
319                 ret = tlc_restoreDB();
320                 if (ret != TAC_ERROR_NONE) {
321                         _SERR("Failed to restore TLC db");
322                 }
323         }
324         //sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
325         else if (cmd == "--tac-enable-pkg") {
326                 if (args.size() < 1) {
327                         _SERR("Package name is missing");
328                 }
329                 while (it != args.end()) {
330                         std::string pkg = std::string(*it);
331                         int ret = enableTACPackage(pkg);
332                         if (ret != TAC_ERROR_NONE) {
333                                 _SERR("Failed to enable tac [%s]", pkg.c_str());
334                                 break;
335                         }
336                         it = args.erase(it);
337                 }
338         }
339         //sh-3.2# dotnettool --tac-disable-pkg [pkgId] [pkgId] ...
340         else if (cmd == "--tac-disable-pkg") {
341                 if (args.size() < 1) {
342                         _SERR("Package name is missing");
343                 }
344                 while (it != args.end()) {
345                         std::string pkg = std::string(*it);
346                         int ret = disableTACPackage(pkg);
347                         if (ret != TAC_ERROR_NONE) {
348                                 _SERR("Failed to disable tac [%s]", pkg.c_str());
349                                 break;
350                         }
351                         it = args.erase(it);
352                 }
353         }
354         //sh-3.2# dotnettool --resolve-all-app
355         else if (cmd == "--resolve-all-app") {
356                 int ret = resolveAllApps();
357                 if (ret != 0) {
358                         _SERR("Failed to remove unused multi-targeting files");
359                 }
360         }
361         //sh-3.2# dotnettool --rm-app-profile [pkgId] [pkgId] ...
362         else if (cmd == "--rm-app-profile") {
363                 if (args.size() < 1) {
364                         _SERR("Package name is missing");
365                 }
366                 while (it != args.end()) {
367                         std::string pkg = std::string(*it);
368                         if (removeAppProfileData(pkg) != PROFILE_ERROR_NONE) {
369                                 _SERR("Failed to remove [%s] profile data", pkg.c_str());
370                         }
371                         it = args.erase(it);
372                 }
373         }
374         //sh-3.2# dotnettool --rm-all-app-profile
375         else if (cmd == "--rm-all-app-profile") {
376                 removeAllAppProfileData();
377         }
378         //sh-3.2# dotnettool --check-all-app-privilege
379         else if (cmd == "--check-all-app-privilege") {
380                 checkAllAppPrivilege();
381         }
382         else {
383                 _SERR("Unknown option [%s]", cmd.c_str());
384                 DisplayUsage();
385         }
386
387         finalizeNICommon();
388
389         gettimeofday(&tv, NULL);
390         endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
391         _SOUT("\nSpend time for dotnettool is [%d]ms", (int)(endtime - starttime));
392
393         return 0;
394 }