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