Popup removal 2
[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_MENU_ICON_NOT_FOUND:
749                 This->m_returnStatus = 1; //this status is specific
750                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
751                         "menu icon could not find\n",
752                         tizenId.c_str(), printMsg.c_str());
753                 break;
754
755             case WRT_INSTALLER_ERROR_FATAL_ERROR:
756                 This->m_returnStatus = 1; //this status is specific
757                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
758                         "fatal error\n",
759                         tizenId.c_str(), printMsg.c_str());
760                 break;
761
762             case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
763                 This->m_returnStatus = 1; //this status is specific
764                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
765                         "out of storage\n",
766                         tizenId.c_str(), printMsg.c_str());
767                 break;
768
769             case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
770                 This->m_returnStatus = 1; //this status is specific
771                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
772                         "out of memory\n",
773                         tizenId.c_str(), printMsg.c_str());
774                 break;
775
776             case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
777                 This->m_returnStatus = 1; //this status is specific
778                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
779                         "package already installed\n",
780                         tizenId.c_str(), printMsg.c_str());
781                 break;
782
783             case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
784                 This->m_returnStatus = 1; //this status is specific
785                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
786                         "ace check failure\n",
787                         tizenId.c_str(), printMsg.c_str());
788                 break;
789
790             case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
791                 This->m_returnStatus = 1; //this status is specific
792                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
793                         "to create manifest failed\n",
794                         tizenId.c_str(), printMsg.c_str());
795                 break;
796
797             case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
798                 This->m_returnStatus = 1; //this status is specific
799                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
800                         "encryption of resource failed\n",
801                         tizenId.c_str(), printMsg.c_str());
802                 break;
803
804             case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
805                 This->m_returnStatus = 1; //this status is specific
806                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
807                         "installation of osp service failed\n",
808                         tizenId.c_str(), printMsg.c_str());
809                 break;
810
811             case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
812                 This->m_returnStatus = 1; //this status is specific
813                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
814                         "widget uninstallation failed\n",
815                         tizenId.c_str(), printMsg.c_str());
816                 break;
817
818
819             case WRT_INSTALLER_ERROR_UNKNOWN:
820                 fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
821                         tizenId.c_str(), printMsg.c_str());
822                 break;
823
824             default:
825                 break;
826         }
827     } else {
828         fprintf(stderr,
829                 "## wrt-installer : %s %s was successful.\n",
830                 tizenId.c_str(),
831                 printMsg.c_str());
832         LogDebug("Status succesfull");
833         This->m_returnStatus = 0;
834         resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_END_SUCCESS);
835
836         if (This->m_installMode == WRT_INSTALL_MODE_INSTALL_PRELOAD &&
837                 !This->m_packagePath.empty()) {
838             LogDebug("This widget is preloaded so it will be removed : "
839                     << This->m_packagePath);
840             if (!WrtUtilRemove(This->m_packagePath)) {
841                 LogError("Failed to remove " << This->m_packagePath);
842             }
843         }
844
845         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
846                                                      NextStepEvent>
847             ::PostEvent(WRTInstallerNS::NextStepEvent());
848     }
849 }
850
851 void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status,
852                                                        void* userdata)
853 {
854     Assert(userdata);
855
856     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
857
858     WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller);
859
860     std::string path = std::string(data->pluginPath);
861     delete data;
862
863     This->m_numPluginsToInstall--;
864     LogDebug("Plugins to install: " << This->m_numPluginsToInstall);
865
866     if (This->m_numPluginsToInstall < 1) {
867         LogDebug("All plugins installation completed");
868         fprintf(stderr, "All plugins installation completed.\n");
869
870         //remove installation request
871         if (!PluginUtils::removeInstallationRequiredFlag()) {
872             LogInfo("Failed to remove file initializing plugin installation");
873         }
874
875         //remove lock file
876         if (!PluginUtils::unlockPluginInstallation(This->m_installMode ==
877                 WRT_INSTALL_MODE_INSTALL_PRELOAD)) {
878             LogInfo("Failed to remove installation lock");
879         }
880
881         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
882             ::PostEvent(WRTInstallerNS::NextStepEvent());
883     } else {
884         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
885                                                      InstallPluginEvent>::
886             PostEvent(
887             WRTInstallerNS::InstallPluginEvent());
888     }
889
890     if (WRT_SUCCESS == status) {
891         This->m_returnStatus = 0;
892         fprintf(stderr,
893                 "## wrt-installer : plugin installation successfull [%s]\n",
894                 path.c_str());
895         LogDebug("One plugin Installation succesfull: " << path);
896         return;
897     }
898
899     // Failure
900     LogWarning("One of the plugins installation failed!: " << path);
901
902     switch (status) {
903     case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
904         LogError("failed: plugin installation failed\n");
905         break;
906
907     case WRT_INSTALLER_ERROR_UNKNOWN:
908         LogError("failed: unknown error\n");
909         break;
910
911     default:
912         break;
913     }
914 }
915
916 void WrtInstaller::staticWrtPluginInstallProgressCb(float percent,
917                                                     const char* description,
918                                                     void* userdata)
919 {
920     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
921
922     std::string path = std::string(data->pluginPath);
923
924     LogInfo("Plugin Installation: " << path <<
925             " progress: " << percent <<
926             "description " << description);
927 }
928
929 void WrtInstaller::staticWrtInstallProgressCallback(float percent,
930                                                     const char* description,
931                                                     void* /*userdata*/)
932 {
933     //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
934     LogInfo(" progress: " << percent <<
935             " description: " << description);
936 }
937 void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
938                                                       const char* description,
939                                                       void* /*userdata*/)
940 {
941     //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
942     LogInfo(" progress: " << percent <<
943             " description: " << description);
944 }
945
946 void WrtInstaller::showResultCallback(void *data, Evas_Object* /*obj*/,
947                                       void* /*event_info*/)
948 {
949     WrtInstaller *This = static_cast<WrtInstaller*>(data);
950     Assert(This);
951
952     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
953         ::PostEvent(WRTInstallerNS::NextStepEvent());
954 }
955
956 void WrtInstaller::failResultCallback(void *data, Evas_Object* /*obj*/,
957                                       void* /*event_info*/)
958 {
959     WrtInstaller *This = static_cast<WrtInstaller*>(data);
960     Assert(This);
961
962     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
963         ::PostEvent(WRTInstallerNS::QuitEvent());
964 }
965
966 void WrtInstaller::installNewPlugins()
967 {
968     LogDebug("Install new plugins");
969
970     if (!PluginUtils::lockPluginInstallation(m_installMode ==
971                 WRT_INSTALL_MODE_INSTALL_PRELOAD)) {
972         LogInfo("Lock NOT created");
973         return;
974     }
975
976     if (!PluginUtils::checkPluginInstallationRequired()) {
977         LogDebug("Plugin installation not required");
978         PluginUtils::unlockPluginInstallation(m_installMode ==
979             WRT_INSTALL_MODE_INSTALL_PRELOAD);
980         return;
981     }
982
983     m_startupPluginInstallation = true;
984     AddStep(&WrtInstaller::installPluginsStep);
985 }
986
987 CSCConfiguration::dataMap WrtInstaller::parseCSCConfiguration(
988     std::string str)
989 {
990     // path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true
991     // parsing CSC configuration string
992     LogDebug("parseConfiguration");
993     CSCConfiguration::dataMap result;
994
995     if (str.empty()) {
996         LogDebug("Input argument is empty");
997         return result;
998     }
999
1000     char* buf = strdup(str.c_str());
1001     const char* ptr = strtok(buf,":");
1002     while (ptr != NULL) {
1003         std::string string = ptr;
1004         size_t pos = string.find('=');
1005         if (pos == std::string::npos) {
1006             continue;
1007         }
1008         result.insert(
1009             CSCConfiguration::dataPair(string.substr(0, pos),
1010                                         string.substr(pos+1)));
1011         ptr = strtok (NULL, ":");
1012     }
1013      return result;
1014 }
1015
1016 int main(int argc, char *argv[])
1017 {
1018     UNHANDLED_EXCEPTION_HANDLER_BEGIN
1019     {
1020         // Output on stdout will be flushed after every newline character,
1021         // even if it is redirected to a pipe. This is useful for running
1022         // from a script and parsing output.
1023         // (Standard behavior of stdlib is to use full buffering when
1024         // redirected to a pipe, which means even after an end of line
1025         // the output may not be flushed).
1026         setlinebuf(stdout);
1027
1028         // Check and re-set the file open limitation
1029         struct rlimit rlim;
1030         if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
1031             LogDebug("RLIMIT_NOFILE sft(" << rlim.rlim_cur << ")");
1032             LogDebug("RLIMIT_NOFILE hrd(" << rlim.rlim_max << ")");
1033
1034             if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
1035                 rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
1036                 rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
1037                 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
1038                     LogError("setrlimit is fail!!");
1039                 }
1040             }
1041         } else {
1042             LogError("getrlimit is fail!!");
1043         }
1044
1045         // set evas backend type for emulator
1046         // popup isn't showed in the emulator,
1047         // if backend isn't set to SW backend
1048         if (GlobalSettings::IsEmulator()) {
1049             if (setenv("ELM_ENGINE", "x11", 1)) {
1050                 LogDebug("Enable backend");
1051             }
1052         }
1053
1054         WrtInstaller app(argc, argv);
1055         int ret = app.Exec();
1056         LogDebug("App returned: " << ret);
1057         ret = app.getReturnStatus();
1058         LogDebug("WrtInstaller returned: " << ret);
1059         return ret;
1060     }
1061     UNHANDLED_EXCEPTION_HANDLER_END
1062 }