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