Initialize Tizen 2.3
[framework/web/wrt-installer.git] / src_mobile / wrt-installer / wrt-installer.cpp
1 /*
2  * Copyright (c) 2011 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 /* @file    wrt-installer.cpp
17  * @version 1.0
18  * @brief   Implementation file for installer
19  */
20
21 #include "wrt-installer.h"
22 #include "plugin_utils.h"
23
24 #include <map>
25 #include <cstring>
26 #include <cstdlib>
27 #include <dirent.h>
28 #include <sys/resource.h>
29
30 #include <dpl/optional_typedefs.h>
31 #include <dpl/wrt-dao-ro/global_config.h>
32 #include <dpl/wrt-dao-ro/config_parser_data.h>
33 #include <dpl/abstract_waitable_input_adapter.h>
34 #include <dpl/abstract_waitable_output_adapter.h>
35 #include <dpl/zip_input.h>
36 #include <dpl/binary_queue.h>
37 #include <dpl/copy.h>
38 #include <dpl/errno_string.h>
39 #include <dpl/utils/wrt_global_settings.h>
40 #include <dpl/utils/wrt_utility.h>
41 #include <parser_runner.h>
42 #include <widget_parser.h>
43 #include <root_parser.h>
44 #include <pkgmgr-info.h>
45
46 #include <Elementary.h>
47
48 #include <pkg-manager/pkgmgr_signal_dummy.h>
49 #include <pkg-manager/pkgmgr_signal.h>
50 #include <installer_log.h>
51
52 using namespace WrtDB;
53
54 namespace { // anonymous
55 const char * const PKGMGR_INSTALL_MSG = "Install widget";
56 const char * const PKGMGR_UNINSTALL_MSG = "Uninstall widget";
57
58 const char * const CONFIG_XML = "config.xml";
59 const char * const HYBRID_CONFIG_XML = "res/wgt/config.xml";
60
61 const unsigned int NOFILE_CNT_FOR_INSTALLER = 9999;
62
63 struct free_deleter
64 {
65     void operator()(void* x)
66     {
67         free(x);
68     }
69 };
70
71 struct PluginInstallerData
72 {
73     void* wrtInstaller;
74     std::string pluginPath;
75 };
76 } // namespace anonymous
77
78 WrtInstaller::WrtInstaller(int argc, char **argv) :
79     Application(argc, argv, "backend", false),
80     DPL::TaskDecl<WrtInstaller>(this),
81     m_packagePath(),
82     m_initialized(false),
83     m_numPluginsToInstall(0),
84     m_totalPlugins(0),
85     m_returnStatus(-1),
86     m_installByPkgmgr(false),
87     m_startupPluginInstallation(false)
88 {
89     Touch();
90     _D("App Created");
91 }
92
93 WrtInstaller::~WrtInstaller()
94 {
95     _D("App Finished");
96 }
97
98 int WrtInstaller::getReturnStatus() const
99 {
100     return m_returnStatus;
101 }
102
103 void WrtInstaller::OnStop()
104 {
105     _D("Stopping Dummy Client");
106 }
107
108 void WrtInstaller::OnCreate()
109 {
110     _D("Creating DummyClient");
111     showArguments();
112
113     AddStep(&WrtInstaller::initStep);
114
115     std::string arg = m_argv[0];
116
117     pkgmgrSignalInterface =
118         std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
119             std::shared_ptr<PackageManager::PkgmgrSignalDummy>(
120                 new PackageManager::PkgmgrSignalDummy()
121                 )
122             );
123
124     if (arg.empty()) {
125         return showHelpAndQuit();
126     }
127
128     installNewPlugins();
129
130     if (arg.find("wrt-installer") != std::string::npos) {
131         if (m_argc <= 1) {
132             return showHelpAndQuit();
133         }
134
135         arg = m_argv[1];
136         if (arg == "-h" || arg == "--help") {
137             if (m_argc != 2) {
138                 return showHelpAndQuit();
139             }
140
141             // Just show help
142             return showHelpAndQuit();
143         } else if (arg == "-p" || arg == "--install-plugins") {
144             if (m_argc != 2) {
145                 return showHelpAndQuit();
146             }
147
148             if (!m_startupPluginInstallation) {
149                 AddStep(&WrtInstaller::installPluginsStep);
150             } else {
151                 _D("Plugin installation alredy started");
152             }
153         } else if (arg == "-i" || arg == "--install") {
154             if (m_argc != 3) {
155                 return showHelpAndQuit();
156             }
157
158             struct stat info;
159             if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) {
160                 _D("Installing package directly from directory");
161                 m_installMode.extension = InstallMode::ExtensionType::DIR;
162             } else {
163                 _D("Installing from regular location");
164                 m_installMode.extension = InstallMode::ExtensionType::WGT;
165             }
166             m_packagePath = m_argv[2];
167
168             AddStep(&WrtInstaller::installStep);
169         } else if (arg == "-ip" || arg == "--install-preload") {
170             _D("Install preload web app");
171             if (m_argc != 3) {
172                 return showHelpAndQuit();
173             }
174             m_packagePath = m_argv[2];
175             m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
176             m_installMode.rootPath = InstallMode::RootPath::RO;
177             AddStep(&WrtInstaller::installStep);
178         } else if (arg == "-ipw" || arg == "--install-preload-writable") {
179             _D("Install preload web application to writable storage");
180             if (m_argc != 3) {
181                 return showHelpAndQuit();
182             }
183             m_packagePath = m_argv[2];
184             m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
185             m_installMode.rootPath = InstallMode::RootPath::RW;
186             AddStep(&WrtInstaller::installStep);
187         } else if (arg == "-c" || arg == "--csc-update") {
188             // "path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true"
189             _D("Install & uninstall by csc configuration");
190             if (m_argc != 3) {
191                 return showHelpAndQuit();
192             }
193             m_installMode.installTime = InstallMode::InstallTime::CSC;
194             std::string configuration = m_argv[2];
195             m_CSCconfigurationMap = parseCSCConfiguration(configuration);
196
197             CSCConfiguration::dataMap::iterator it;
198             it = m_CSCconfigurationMap.find(CSCConfiguration::KEY_OP);
199             if (it == m_CSCconfigurationMap.end()) {
200                 return showHelpAndQuit();
201             }
202
203             if (it->second == CSCConfiguration::VALUE_INSTALL) {
204                 _D("operation = %s", it->second.c_str());
205                 m_installMode.extension = InstallMode::ExtensionType::WGT;
206                 it = m_CSCconfigurationMap.find(CSCConfiguration::KEY_PATH);
207                 if (it == m_CSCconfigurationMap.end()) {
208                     return showHelpAndQuit();
209                 }
210                 m_packagePath = it->second;
211
212                 it = m_CSCconfigurationMap.find(
213                         CSCConfiguration::KEY_REMOVABLE);
214                 if (it == m_CSCconfigurationMap.end()) {
215                     return showHelpAndQuit();
216                 }
217
218                 m_installMode.removable =
219                     (it->second.compare(CSCConfiguration::VALUE_FALSE) == 0)
220                     ? false : true;
221
222                 AddStep(&WrtInstaller::installStep);
223                 _D("path      = %s", m_packagePath.c_str());
224             } else if (it->second == CSCConfiguration::VALUE_UNINSTALL) {
225                 _D("operation = %s", it->second.c_str());
226                 // uninstall command isn't confirmed yet
227                 it = m_CSCconfigurationMap.find(CSCConfiguration::KEY_PATH);
228                 if (it == m_CSCconfigurationMap.end()) {
229                     return showHelpAndQuit();
230                 }
231                 m_packagePath = it->second;
232                 AddStep(&WrtInstaller::unistallWgtFileStep);
233                 _D("operation = uninstall");
234                 _D("path      = %s", m_packagePath.c_str());
235             } else {
236                 _E("Unknown operation : %s", it->second.c_str());
237                 _D("operation = %s", it->second.c_str());
238                 return showHelpAndQuit();
239             }
240         } else if (arg == "-un" || arg == "--uninstall-name") {
241             if (m_argc != 3) {
242                 return showHelpAndQuit();
243             }
244             m_name = m_argv[2];
245             AddStep(&WrtInstaller::uninstallPkgNameStep);
246         } else if (arg == "-up" || arg == "--uninstall-packagepath") {
247             if (m_argc != 3) {
248                 return showHelpAndQuit();
249             }
250             m_packagePath = m_argv[2];
251             AddStep(&WrtInstaller::unistallWgtFileStep);
252         } else if (arg == "-r" || arg == "--reinstall") {
253             if (m_argc != 3) {
254                 return showHelpAndQuit();
255             }
256             _D("Installing package directly from directory");
257             m_installMode.command = InstallMode::Command::REINSTALL;
258             m_installMode.extension = InstallMode::ExtensionType::DIR;
259             m_packagePath = m_argv[2];
260             AddStep(&WrtInstaller::installStep);
261         } else {
262             return showHelpAndQuit();
263         }
264     } else if (arg.find("backend") != std::string::npos) {
265         using namespace PackageManager;
266         m_installByPkgmgr = true;
267
268         auto pkgmgrSignal = std::shared_ptr<PackageManager::PkgmgrSignal>(
269                 new PackageManager::PkgmgrSignal()
270                 );
271
272         pkgmgrSignal->initialize(m_argc, m_argv);
273
274         PackageManager::PkgmgrSignal::RequestType reqType = pkgmgrSignal->getRequestedType();
275
276         pkgmgrSignalInterface =
277             std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
278                 pkgmgrSignal);
279         switch (reqType) {
280         case PackageManager::PkgmgrSignal::RequestType::INSTALL:
281             m_packagePath = m_argv[4];
282             if (6 < m_argc) {
283                 m_name = std::string(m_argv[6]);
284             }
285
286             struct stat info;
287             if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) {
288                 _D("Installing package directly from directory");
289                 m_installMode.extension = InstallMode::ExtensionType::DIR;
290             } else {
291                 _D("Installing from regular location");
292                 m_installMode.extension = InstallMode::ExtensionType::WGT;
293             }
294             AddStep(&WrtInstaller::installStep);
295             break;
296         case PackageManager::PkgmgrSignal::RequestType::UNINSTALL:
297             {
298                 m_name = m_argv[4];
299                 pkgmgrinfo_pkginfo_h handle = NULL;
300                 bool system_app = false; // system app is preloaded and unremovable.
301                 bool update = false;
302
303                 if (0 == pkgmgrinfo_pkginfo_get_pkginfo(m_name.c_str(), &handle)) {
304                     if (0 > pkgmgrinfo_pkginfo_is_system(handle, &system_app)) {
305                         _E("Can't get package information : %s", m_name.c_str());
306                     }
307                     if (0 > pkgmgrinfo_pkginfo_is_update(handle, &update)) {
308                         _E("Can't get package information about update : %s", m_name.c_str());
309                     }
310                 }
311
312                 _D("system app : %d", system_app);
313                 _D("update : %d", update);
314
315                 if (system_app && update) {
316                     AddStep(&WrtInstaller::removeUpdateStep);
317                 } else {
318                     AddStep(&WrtInstaller::uninstallPkgNameStep);
319                 }
320                 break;
321             }
322         case PackageManager::PkgmgrSignal::RequestType::REINSTALL:
323             m_packagePath = m_argv[4];
324             m_installMode.command = InstallMode::Command::REINSTALL;
325             m_installMode.extension = InstallMode::ExtensionType::DIR;
326             AddStep(&WrtInstaller::installStep);
327             break;
328         default:
329             _D("Not available type");
330             break;
331         }
332     }
333
334     AddStep(&WrtInstaller::shutdownStep);
335     DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
336         PostEvent(
337         WRTInstallerNS::NextStepEvent());
338 }
339
340 void WrtInstaller::OnReset(bundle* /*b*/)
341 {
342     _D("OnReset");
343 }
344
345 void WrtInstaller::OnTerminate()
346 {
347     _D("Wrt Shutdown now");
348     PluginUtils::unlockPluginInstallation(
349         m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
350     if (m_initialized) {
351         wrt_installer_shutdown();
352     }
353 }
354
355 void WrtInstaller::showHelpAndQuit()
356 {
357     printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/PATH]...\n"
358            "Operate with WebRuntime daemon: install, uninstall"
359            " and launch widgets.\n"
360            "Query list of installed widgets and setup up debugging support.\n"
361            "\n"
362            "Exactly one option must be selected.\n"
363            "Mandatory arguments to long options are mandatory for short "
364            "options too.\n"
365            "  -h,    --help                                 show this help\n"
366            "  -p,    --install-plugins                      install plugins\n"
367            "  -i,    --install                              "
368            "install or update widget package for given path\n"
369            "  -c,    --csc-update                           "
370            "install or uninstall by CSC configuration \n"
371            "  -un,   --uninstall-name                       "
372            "uninstall widget for given package name\n"
373            "  -up,   --uninstall-packagepath                "
374            "uninstall widget for given package file path\n"
375            "  -r,    --reinstall                            "
376            "reinstall web application\n"
377            "\n");
378
379     Quit();
380 }
381
382 void WrtInstaller::showArguments()
383 {
384     fprintf(stderr,
385             "===========================================================\n");
386     fprintf(stderr, "# wrt-installer #\n");
387     fprintf(stderr, "# argc [%d]\n", m_argc);
388     for (int i = 0; i < m_argc; i++) {
389         fprintf(stderr, "# argv[%d] = [%s]\n", i, m_argv[i]);
390     }
391     fprintf(stderr,
392             "===========================================================\n");
393     // for dlog
394     _D("===========================================================");
395     _D("# wrt-installer #");
396     _D("# argc %d", m_argc);
397     for (int i = 0; i < m_argc; i++) {
398         _D("# argv[%d] = %s", i, m_argv[i]);
399     }
400     _D("===========================================================");
401
402 }
403
404 void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/)
405 {
406     _D("Quiting");
407
408     if (m_initialized) {
409         _D("Wrt Shutdown now");
410         SwitchToStep(&WrtInstaller::shutdownStep);
411         DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
412             PostEvent(
413             WRTInstallerNS::NextStepEvent());
414     } else {
415         _D("Quiting application");
416         return Quit();
417     }
418 }
419
420 void WrtInstaller::OnEventReceived(
421     const WRTInstallerNS::NextStepEvent& /*event*/)
422 {
423     _D("Executing next step");
424     NextStep();
425 }
426
427 void WrtInstaller::OnEventReceived(
428     const WRTInstallerNS::InstallPluginEvent& /*event*/)
429 {
430     PluginInstallerData* privateData = new PluginInstallerData;
431     privateData->wrtInstaller = this;
432
433     if (!(*m_pluginsPaths).empty()) {
434         privateData->pluginPath = (*m_pluginsPaths).front();
435         (*m_pluginsPaths).pop_front();
436
437         wrt_install_plugin(privateData->pluginPath.c_str(),
438                            static_cast<void*>(privateData),
439                            &staticWrtPluginInstallationCallback,
440                            &staticWrtPluginInstallProgressCb);
441     } else {
442         delete privateData;
443     }
444 }
445
446 void WrtInstaller::initStep()
447 {
448     wrt_installer_init(this, staticWrtInitCallback);
449 }
450
451 void WrtInstaller::installStep()
452 {
453     _D("Installing widget ...");
454     std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
455                                                         m_packagePath.c_str()));
456
457     wrt_install_widget(packagePath ? packagePath.get() : m_packagePath.c_str(),
458                        m_name.c_str(), this, &staticWrtStatusCallback,
459                        (m_installByPkgmgr)
460                        ? &staticWrtInstallProgressCallback : NULL,
461                        m_installMode,
462                        pkgmgrSignalInterface);
463 }
464
465 void WrtInstaller::installPluginsStep()
466 {
467     _D("Installing plugins ...");
468     fprintf(stderr, "Installing plugins ...\n");
469
470     if (m_startupPluginInstallation) {
471         _D("Plugin installation started because new plugin package found");
472     } else if (!PluginUtils::lockPluginInstallation(
473         m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
474     {
475         _E("Failed to open plugin installation lock file"
476                  " Plugins are currently installed by other process");
477         staticWrtPluginInstallationCallback(WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
478                                             this);
479         return;
480     }
481
482     std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
483
484     DIR *dir;
485     dir = opendir(PLUGIN_PATH.c_str());
486
487     if (!dir) {
488         return;
489     }
490
491     _D("Plugin DIRECTORY IS %s", PLUGIN_PATH.c_str());
492
493     std::list<std::string> pluginsPaths;
494     struct dirent libdir;
495     struct dirent *result;
496     int return_code;
497     errno = 0;
498     for (return_code = readdir_r(dir, &libdir, &result);
499             result != NULL && return_code == 0;
500             return_code = readdir_r(dir, &libdir, &result))
501     {
502         if (strcmp(libdir.d_name, ".") == 0 ||
503             strcmp(libdir.d_name, "..") == 0)
504         {
505             continue;
506         }
507
508         std::string path = PLUGIN_PATH;
509         path += "/";
510         path += libdir.d_name;
511
512         struct stat tmp;
513
514         if (stat(path.c_str(), &tmp) == -1) {
515             _E("Failed to open file %s", path.c_str());
516             continue;
517         }
518
519         if (!S_ISDIR(tmp.st_mode)) {
520             _E("Not a directory %s", path.c_str());
521             continue;
522         }
523
524         pluginsPaths.push_back(path);
525     }
526
527     if (return_code != 0 || errno != 0) {
528         _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
529     }
530
531     //set nb of plugins to install
532     //this value indicate how many callbacks are expected
533     m_numPluginsToInstall = pluginsPaths.size();
534     _D("Plugins to install: %d", m_numPluginsToInstall);
535     m_pluginsPaths = pluginsPaths;
536
537     m_totalPlugins = m_numPluginsToInstall;
538     DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
539         ::PostEvent(WRTInstallerNS::InstallPluginEvent());
540
541     if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
542         _E("Failed to close dir: %s with error: %s", PLUGIN_PATH.c_str(), DPL::GetErrnoString().c_str());
543     }
544 }
545
546 void WrtInstaller::uninstallPkgNameStep()
547 {
548     _D("Uninstalling widget ...");
549     _D("Package name : %s", m_name.c_str());
550
551     wrt_uninstall_widget(m_name.c_str(), this,
552             &staticWrtStatusCallback,
553             (m_installByPkgmgr)
554             ? &staticWrtUninstallProgressCallback : NULL,
555             pkgmgrSignalInterface);
556 }
557
558 void WrtInstaller::removeUpdateStep()
559 {
560     _D("This web app need to initialize preload app");
561     _D("Package name : %s", m_name.c_str());
562
563     wrt_uninstall_widget(m_name.c_str(), this,
564             &staticWrtInitializeToPreloadCallback,
565             (m_installByPkgmgr)
566             ? &staticWrtUninstallProgressCallback : NULL,
567             pkgmgrSignalInterface);
568
569 }
570
571 void WrtInstaller::unistallWgtFileStep()
572 {
573     _D("Uninstalling widget ...");
574
575     Try {
576         // Parse config
577         ParserRunner parser;
578         ConfigParserData configInfo;
579
580         // Open zip file
581         std::unique_ptr<DPL::ZipInput> zipFile(
582             new DPL::ZipInput(m_packagePath));
583         std::unique_ptr<DPL::ZipInput::File> configFile;
584
585         Try {
586             // Open config.xml file
587             configFile.reset(zipFile->OpenFile(CONFIG_XML));
588         }
589         Catch(DPL::ZipInput::Exception::OpenFileFailed)
590         {
591             // Open config.xml file for hybrid
592             configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
593         }
594
595         // Extract config
596         DPL::BinaryQueue buffer;
597         DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
598         DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
599         DPL::Copy(&inputAdapter, &outputAdapter);
600         parser.Parse(&buffer,
601                      ElementParserPtr(
602                          new RootParser<WidgetParser>(configInfo,
603                                                       DPL::FromUTF32String(
604                                                           L"widget"))));
605
606         DPL::OptionalString pkgId = configInfo.tizenPkgId;
607         if (!pkgId.IsNull()) {
608             _D("Pkgid from packagePath : %ls", (*pkgId).c_str());
609             wrt_uninstall_widget(
610                 DPL::ToUTF8String(*pkgId).c_str(), this, &staticWrtStatusCallback,
611                 !m_installByPkgmgr ? &staticWrtUninstallProgressCallback
612                 : NULL,
613                 pkgmgrSignalInterface);
614         } else {
615             _E("Fail to uninstalling widget... ");
616             m_returnStatus = -1;
617             DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
618                 PostEvent(
619                 WRTInstallerNS::QuitEvent());
620         }
621     }
622     Catch(DPL::ZipInput::Exception::OpenFailed)
623     {
624         _E("Failed to open widget package");
625         printf("failed: widget package does not exist\n");
626         m_returnStatus = -1;
627         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
628             PostEvent(
629             WRTInstallerNS::QuitEvent());
630     }
631     Catch(DPL::ZipInput::Exception::OpenFileFailed)
632     {
633         printf("failed: widget config file does not exist\n");
634         _E("Failed to open config.xml file");
635         m_returnStatus = -1;
636         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
637             PostEvent(
638             WRTInstallerNS::QuitEvent());
639     }
640     Catch(ElementParser::Exception::ParseError)
641     {
642         printf("failed: can not parse config file\n");
643         _E("Failed to parse config.xml file");
644         m_returnStatus = -1;
645         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
646             PostEvent(
647             WRTInstallerNS::QuitEvent());
648     }
649 }
650
651 void WrtInstaller::shutdownStep()
652 {
653     _D("Closing Wrt connection ...");
654     if (m_initialized) {
655         wrt_installer_shutdown();
656         m_initialized = false;
657         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
658             PostEvent(
659             WRTInstallerNS::QuitEvent());
660     }
661 }
662
663 void WrtInstaller::staticWrtInitCallback(WrtErrStatus status,
664                                          void* userdata)
665 {
666     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
667     Assert(This);
668
669     if (status == WRT_SUCCESS) {
670         _D("Init succesfull");
671         This->m_initialized = true;
672         This->m_returnStatus = 0;
673
674         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
675             ::PostEvent(WRTInstallerNS::NextStepEvent());
676     } else {
677         _E("Init unsuccesfull");
678         This->m_returnStatus = -1;
679         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
680             PostEvent(
681             WRTInstallerNS::QuitEvent());
682     }
683 }
684
685 void WrtInstaller::staticWrtInitializeToPreloadCallback(std::string tizenId, WrtErrStatus
686         status, void* userdata)
687 {
688     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
689     Assert(This);
690
691     std::string printMsg = "uninstallation";
692
693     if (WRT_SUCCESS != status) {
694         // Failure
695         _E("Step failed");
696         This->m_returnStatus = 1;
697
698         This->showErrorMsg(status, tizenId, printMsg);
699
700         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
701             ::PostEvent(WRTInstallerNS::QuitEvent());
702     } else {
703         InstallMode mode;
704         mode.extension = InstallMode::ExtensionType::DIR;
705         mode.installTime = InstallMode::InstallTime::PRELOAD;
706         mode.rootPath = InstallMode::RootPath::RO;
707         std::string packagePath =
708             std::string(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath()) + "/" +
709             This->m_name;
710
711         wrt_install_widget(packagePath.c_str(), tizenId.c_str(),
712                 This, &staticWrtInitPreloadStatusCallback,
713                 NULL,
714                 mode,
715                 This->pkgmgrSignalInterface);
716     }
717 }
718
719 void WrtInstaller::staticWrtInitPreloadStatusCallback(std::string tizenId,
720                                            WrtErrStatus status,
721                                            void* userdata)
722 {
723     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
724     Assert(This);
725
726     std::string printMsg = "initialization";
727
728     if (WRT_SUCCESS != status) {
729         // Failure
730         _E("Step failed");
731         This->m_returnStatus = status;
732
733         This->showErrorMsg(status, tizenId, printMsg);
734
735         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
736             ::PostEvent(WRTInstallerNS::QuitEvent());
737     } else {
738         fprintf(stderr,
739                 "## wrt-installer : %s %s was successful.\n",
740                 tizenId.c_str(),
741                 printMsg.c_str());
742         _D("Status succesfull");
743         This->m_returnStatus = 0;
744
745         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
746                                                      NextStepEvent>
747             ::PostEvent(WRTInstallerNS::NextStepEvent());
748     }
749 }
750
751 void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
752                                            WrtErrStatus status,
753                                            void* userdata)
754 {
755     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
756     Assert(This);
757
758     Step current = This->GetCurrentStep();
759     std::string printMsg;
760
761     if (current == &WrtInstaller::installStep) {
762         printMsg = "installation";
763     } else if (current == &WrtInstaller::uninstallPkgNameStep ||
764                current == &WrtInstaller::unistallWgtFileStep)
765     {
766         printMsg = "uninstallation";
767     }
768
769     if (WRT_SUCCESS != status) {
770         // Failure
771         _E("Step failed");
772         This->m_returnStatus = status;
773
774         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
775             ::PostEvent(WRTInstallerNS::QuitEvent());
776
777         This->showErrorMsg(status, tizenId, printMsg);
778     } else {
779         fprintf(stderr,
780                 "## wrt-installer : %s %s was successful.\n",
781                 tizenId.c_str(),
782                 printMsg.c_str());
783         _D("Status succesfull");
784         This->m_returnStatus = 0;
785
786         if (This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD &&
787                 !This->m_packagePath.empty())
788         {
789             _D("This widget is preloaded so it will be removed : %s", This->m_packagePath.c_str());
790             if (!WrtUtilRemove(This->m_packagePath)) {
791                 _E("Failed to remove %s", This->m_packagePath.c_str());
792             }
793         }
794
795         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
796                                                      NextStepEvent>
797             ::PostEvent(WRTInstallerNS::NextStepEvent());
798     }
799 }
800
801 void WrtInstaller::showErrorMsg(WrtErrStatus status, std::string tizenId,
802         std::string printMsg)
803 {
804     switch (status) {
805         case WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND:
806             fprintf(stderr, "## wrt-installer : %s %s has failed - widget package does not exist\n",
807                     tizenId.c_str(), printMsg.c_str());
808             break;
809
810         case WRT_INSTALLER_ERROR_PACKAGE_INVALID:
811             fprintf(stderr, "## wrt-installer : %s %s has failed - invalid widget package\n",
812                     tizenId.c_str(), printMsg.c_str());
813             break;
814
815         case WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
816             fprintf(stderr, "## wrt-installer : %s %s has failed - given"
817                     " version is lower than existing version\n",
818                     tizenId.c_str(), printMsg.c_str());
819             break;
820
821         case WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND:
822             fprintf(stderr, "## wrt-installer : %s %s has failed - manifest"
823                     " file doesn't find in package.\n",
824                     tizenId.c_str(), printMsg.c_str());
825             break;
826
827         case WRT_INSTALLER_ERROR_MANIFEST_INVALID:
828             fprintf(stderr, "## wrt-installer : %s %s has failed - "
829                     "invalid manifestx.xml\n",
830                     tizenId.c_str(), printMsg.c_str());
831             break;
832
833         case WRT_INSTALLER_CONFIG_NOT_FOUND:
834             fprintf(stderr, "## wrt-installer : %s %s has failed - "
835                     "config.xml does not exist\n",
836                     tizenId.c_str(), printMsg.c_str());
837             break;
838
839         case WRT_INSTALLER_ERROR_CONFIG_INVALID:
840             fprintf(stderr, "## wrt-installer : %s %s has failed - "
841                     "invalid config.xml\n",
842                     tizenId.c_str(), printMsg.c_str());
843             break;
844
845         case WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
846             fprintf(stderr, "## wrt-installer : %s %s has failed - "
847                     "signature doesn't exist in package.\n",
848                     tizenId.c_str(), printMsg.c_str());
849             break;
850
851         case WRT_INSTALLER_ERROR_SIGNATURE_INVALID:
852             fprintf(stderr, "## wrt-installer : %s %s has failed - "
853                     "invalid signature.\n",
854                     tizenId.c_str(), printMsg.c_str());
855             break;
856
857         case WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
858             fprintf(stderr, "## wrt-installer : %s %s has failed - "
859                     "signature verification failed.\n",
860                     tizenId.c_str(), printMsg.c_str());
861             break;
862
863         case WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
864             fprintf(stderr, "## wrt-installer : %s %s has failed - "
865                     "root certificate could not find.\n",
866                     tizenId.c_str(), printMsg.c_str());
867             break;
868
869         case WRT_INSTALLER_ERROR_CERTIFICATION_INVAID:
870             fprintf(stderr, "## wrt-installer : %s %s has failed - "
871                     "invalid certification.\n",
872                     tizenId.c_str(), printMsg.c_str());
873             break;
874
875         case WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
876             fprintf(stderr, "## wrt-installer : %s %s has failed - "
877                     "certificate chain verification failed.\n",
878                     tizenId.c_str(), printMsg.c_str());
879             break;
880
881         case WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED:
882             fprintf(stderr, "## wrt-installer : %s %s has failed - "
883                     "certificate expired.\n",
884                     tizenId.c_str(), printMsg.c_str());
885             break;
886
887         case WRT_INSTALLER_ERROR_INVALID_PRIVILEGE:
888             fprintf(stderr, "## wrt-installer : %s %s has failed - "
889                     "invalid privilege\n",
890                     tizenId.c_str(), printMsg.c_str());
891             break;
892
893         case WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION:
894             fprintf(stderr, "## wrt-installer : %s %s has failed - "
895                     "privilege level violation\n",
896                     tizenId.c_str(), printMsg.c_str());
897             break;
898
899         case WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
900             fprintf(stderr, "## wrt-installer : %s %s has failed - "
901                     "menu icon could not find\n",
902                     tizenId.c_str(), printMsg.c_str());
903             break;
904
905         case WRT_INSTALLER_ERROR_FATAL_ERROR:
906             fprintf(stderr, "## wrt-installer : %s %s has failed - "
907                     "fatal error\n",
908                     tizenId.c_str(), printMsg.c_str());
909             break;
910
911         case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
912             fprintf(stderr, "## wrt-installer : %s %s has failed - "
913                     "out of storage\n",
914                     tizenId.c_str(), printMsg.c_str());
915             break;
916
917         case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
918             fprintf(stderr, "## wrt-installer : %s %s has failed - "
919                     "out of memory\n",
920                     tizenId.c_str(), printMsg.c_str());
921             break;
922
923         case WRT_INSTALLER_ERROR_ARGUMENT_INVALID:
924             fprintf(stderr, "## wrt-installer : %s %s has failed - "
925                     "invalid argument\n",
926                     tizenId.c_str(), printMsg.c_str());
927             break;
928
929         case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
930             fprintf(stderr, "## wrt-installer : %s %s has failed - "
931                     "package already installed\n",
932                     tizenId.c_str(), printMsg.c_str());
933             break;
934
935         case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
936             fprintf(stderr, "## wrt-installer : %s %s has failed - "
937                     "ace check failure\n",
938                     tizenId.c_str(), printMsg.c_str());
939             break;
940
941         case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
942             fprintf(stderr, "## wrt-installer : %s %s has failed - "
943                     "to create manifest failed\n",
944                     tizenId.c_str(), printMsg.c_str());
945             break;
946
947         case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
948             fprintf(stderr, "## wrt-installer : %s %s has failed - "
949                     "encryption of resource failed\n",
950                     tizenId.c_str(), printMsg.c_str());
951             break;
952
953         case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
954             fprintf(stderr, "## wrt-installer : %s %s has failed - "
955                     "installation of osp service failed\n",
956                     tizenId.c_str(), printMsg.c_str());
957             break;
958
959         case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
960             fprintf(stderr, "## wrt-installer : %s %s has failed - "
961                     "widget uninstallation failed\n",
962                     tizenId.c_str(), printMsg.c_str());
963             break;
964
965
966         case WRT_INSTALLER_ERROR_UNKNOWN:
967             fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
968                     tizenId.c_str(), printMsg.c_str());
969             break;
970
971         default:
972             break;
973     }
974
975 }
976
977 void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status,
978                                                        void* userdata)
979 {
980     Assert(userdata);
981
982     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
983
984     WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller);
985
986     std::string path = std::string(data->pluginPath);
987     delete data;
988
989     This->m_numPluginsToInstall--;
990     _D("Plugins to install: %d", This->m_numPluginsToInstall);
991
992     if (This->m_numPluginsToInstall < 1) {
993         _D("All plugins installation completed");
994         fprintf(stderr, "All plugins installation completed.\n");
995
996         //remove installation request
997         if (!PluginUtils::removeInstallationRequiredFlag()) {
998             _D("Failed to remove file initializing plugin installation");
999         }
1000
1001         //remove lock file
1002         if (!PluginUtils::unlockPluginInstallation(
1003             This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
1004         {
1005             _D("Failed to remove installation lock");
1006         }
1007
1008         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
1009             ::PostEvent(WRTInstallerNS::NextStepEvent());
1010     } else {
1011         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
1012                                                      InstallPluginEvent>::
1013             PostEvent(
1014             WRTInstallerNS::InstallPluginEvent());
1015     }
1016
1017     if (WRT_SUCCESS == status) {
1018         This->m_returnStatus = 0;
1019         fprintf(stderr,
1020                 "## wrt-installer : plugin installation successfull [%s]\n",
1021                 path.c_str());
1022         _D("One plugin Installation succesfull: %s", path.c_str());
1023         return;
1024     }
1025
1026     // Failure
1027     _W("One of the plugins installation failed!: %s", path.c_str());
1028
1029     switch (status) {
1030     case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
1031         _E("failed: plugin installation failed\n");
1032         break;
1033
1034     case WRT_INSTALLER_ERROR_UNKNOWN:
1035         _E("failed: unknown error\n");
1036         break;
1037
1038     default:
1039         break;
1040     }
1041 }
1042
1043 void WrtInstaller::staticWrtPluginInstallProgressCb(float percent,
1044                                                     const char* description,
1045                                                     void* userdata)
1046 {
1047     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
1048
1049     std::string path = std::string(data->pluginPath);
1050
1051     _D("Plugin Installation: %s progress: %2.0f description: %s", path.c_str(), percent, description);
1052 }
1053
1054 void WrtInstaller::staticWrtInstallProgressCallback(float percent,
1055                                                     const char* description,
1056                                                     void* /*userdata*/)
1057 {
1058     //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
1059     _D(" progress: %2.0f description: %s", percent, description);
1060 }
1061 void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
1062                                                       const char* description,
1063                                                       void* /*userdata*/)
1064 {
1065     //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
1066     _D(" progress: %2.0f description: %s", percent, description);
1067 }
1068
1069 void WrtInstaller::installNewPlugins()
1070 {
1071     _D("Install new plugins");
1072
1073     if (!PluginUtils::lockPluginInstallation(
1074         m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
1075     {
1076         _D("Lock NOT created");
1077         return;
1078     }
1079
1080     if (!PluginUtils::checkPluginInstallationRequired()) {
1081         _D("Plugin installation not required");
1082         PluginUtils::unlockPluginInstallation(
1083             m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
1084         return;
1085     }
1086
1087     m_startupPluginInstallation = true;
1088     AddStep(&WrtInstaller::installPluginsStep);
1089 }
1090
1091 CSCConfiguration::dataMap WrtInstaller::parseCSCConfiguration(
1092     std::string str)
1093 {
1094     // path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true
1095     // parsing CSC configuration string
1096     _D("parseConfiguration");
1097     CSCConfiguration::dataMap result;
1098
1099     if (str.empty()) {
1100         _D("Input argument is empty");
1101         return result;
1102     }
1103
1104     char* buf = strdup(str.c_str());
1105     const char* ptr = strtok(buf,":");
1106     while (ptr != NULL) {
1107         std::string string = ptr;
1108         ptr = strtok (NULL, ":");
1109         size_t pos = string.find('=');
1110         if (pos == std::string::npos) {
1111             continue;
1112         }
1113         result.insert(
1114             CSCConfiguration::dataPair(string.substr(0, pos),
1115                                        string.substr(pos+1)));
1116     }
1117     free(buf);
1118     return result;
1119 }
1120
1121 int main(int argc, char *argv[])
1122 {
1123     UNHANDLED_EXCEPTION_HANDLER_BEGIN
1124     {
1125         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_INSTALLER");
1126
1127         // Output on stdout will be flushed after every newline character,
1128         // even if it is redirected to a pipe. This is useful for running
1129         // from a script and parsing output.
1130         // (Standard behavior of stdlib is to use full buffering when
1131         // redirected to a pipe, which means even after an end of line
1132         // the output may not be flushed).
1133         setlinebuf(stdout);
1134
1135         // Check and re-set the file open limitation
1136         struct rlimit rlim;
1137         if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
1138             _D("RLIMIT_NOFILE sft(%d)", rlim.rlim_cur);
1139             _D("RLIMIT_NOFILE hrd(%d)", rlim.rlim_max);
1140
1141             if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
1142                 rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
1143                 rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
1144                 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
1145                     _E("setrlimit is fail!!");
1146                 }
1147             }
1148         } else {
1149             _E("getrlimit is fail!!");
1150         }
1151
1152         WrtInstaller app(argc, argv);
1153         int ret = app.Exec();
1154         _D("App returned: %d", ret);
1155         ret = app.getReturnStatus();
1156         _D("WrtInstaller returned: %d", ret);
1157         return ret;
1158     }
1159     UNHANDLED_EXCEPTION_HANDLER_END
1160 }