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