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