2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file task_plugin_copy.cpp
18 * @author Marcin Kaminski (marcin.ka@samsung.com)
20 * @brief Copying plugins delivered in widget package.
23 #include "task_plugins_copy.h"
24 #include <dpl/log/log.h>
25 #include <dpl/string.h>
26 #include <dpl/utils/wrt_utility.h>
27 #include <dpl/errno_string.h>
28 #include <widget_install_context.h>
29 #include <widget_install/widget_install_errors.h>
30 #include <dpl/exception.h>
31 /* Headers needed for listing directories */
34 /* Installation expceptions support */
35 #include <dpl/exception.h>
38 /* wrt-installer has to copy plugins for ARM architecture
39 * when running on target or for i586 architecture if launched
42 const std::string plugins_dir = "arm";
44 const std::string plugins_dir = "i586";
48 const std::string PackagePluginsDir = "/plugins/";
49 const std::string InstallationPluginsDir = "/data/.netscape/plugins/";
50 const mode_t InstallationPluginsDirMode = 0755;
54 namespace WidgetInstall {
56 TaskPluginsCopy::TaskPluginsCopy(InstallerContext& context) :
57 DPL::TaskDecl<TaskPluginsCopy>(this),
60 LogDebug("Starting widget plugins copy task");
61 AddStep(&TaskPluginsCopy::StepFindPlugins);
62 AddStep(&TaskPluginsCopy::StepCopyPlugins);
63 AddStep(&TaskPluginsCopy::StepCopyingFinished);
64 LogDebug("Widget plugins copy task ended");
65 m_npsource = m_context.locations->getSourceDir() + PackagePluginsDir
67 m_npdestination = m_context.locations->getPackageInstallationDir()
68 + InstallationPluginsDir;
71 void TaskPluginsCopy::StepFindPlugins()
73 LogDebug("Starting plugins finding step");
74 /* Check whether plugins directory for actual architecture exists
75 * (plugins for other architectures are omitted even they exists). */
76 if(!WrtUtilDirExists(m_npsource)) {
77 LogDebug("Plugins directory (" <<m_npsource
78 <<") does not exists - skipping copy step");
79 SwitchToStep(&TaskPluginsCopy::StepCopyingFinished);
83 /* Find all .so files and store their names in list */
87 LogDebug("Opening plugins directory");
88 dir = opendir(m_npsource.c_str());
90 LogError("Unable to open plugins directory");
91 ThrowMsg(Exceptions::InternalError, "Unable to read plugins directory");
94 const std::string ext(".so");
95 /* Listing directory and checking entries found inside */
96 while ((entry = readdir(dir)) != NULL){
97 tempname = m_npsource + "/" + entry->d_name;
98 if(lstat(tempname.c_str(), &st) != 0) {
99 LogDebug("Failed to call \"lstat\" (errno:" <<errno
100 <<") on entry - skipping");
103 /* Directories other than "." and ".." should not be found*/
104 if(S_ISDIR(st.st_mode)){
105 if(strncmp(entry->d_name, "..", 2)!=0
106 && strncmp(entry->d_name, ".", 1)!=0) {
107 LogError("Directory detected instead of plugin file: "
109 /* Subdirectories inside plugins/ARCH are not supported */
110 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
111 LogError("Failed to close dir: " << m_npsource
112 << " with error: " << DPL::GetErrnoString());
114 ThrowMsg(Exceptions::PluginsSubdirectory,
115 "Subdirectories inside plugins directory are not supported");
122 tempname = std::string(entry->d_name);
123 /* Check whether file extension is ".so" */
124 if(tempname.compare(tempname.size()-ext.size(), ext.size(), ext) == 0) {
125 /* Plugin file found */
126 LogDebug("Plugin file found: " <<tempname);
127 m_nplugins.push_back(tempname);
130 /* Non-.so file found in plugins directory- skipping */
131 LogWarning("Non-plugin file found: " <<tempname);
134 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
135 LogError("Failed to close dir: " << m_npsource << " with error: "
136 << DPL::GetErrnoString());
138 /* If no .so files found (list is empty) abort taks*/
139 if(m_nplugins.empty()) {
140 LogError("No valid plugin files found");
141 ThrowMsg(Exceptions::EmptyPluginsDirectory, "No valid plugin found");
143 LogDebug("Number of detected plugins: " <<m_nplugins.size());
144 LogDebug("Plugins finding step ended");
147 void TaskPluginsCopy::StepCopyPlugins()
149 LogDebug("Starting plugins copying step");
151 std::string destination;
153 /* Create new directory for plugins (data/.netscape/plugins/) */
154 LogDebug("Creating destination plugin directory");
155 if(!WrtUtilMakeDir(m_npdestination, InstallationPluginsDirMode)){
156 LogError("Failed to create directory for plugins");
157 ThrowMsg(Exceptions::InternalError, "Failed to create directory for plugins");
160 LogDebug("Copying plugins to: " <<m_npdestination);
161 /* Copy plugins from widget package into
162 * .netscape/plugins in widget's target directory */
163 for(std::list<std::string>::const_iterator it = m_nplugins.begin();
164 it != m_nplugins.end(); it++) {
165 LogDebug("Copying plugin file: " << (*it));
166 source = m_npsource + "/" + (*it);
167 destination = m_npdestination + (*it);
168 if(rename(source.c_str(), destination.c_str()) != 0) {
169 LogError("Failed to move " <<source <<" to " <<destination);
170 LogError("(errno: " <<errno <<")");
171 ThrowMsg(Exceptions::InternalError, "Failed to copy plugin file");
175 /* Remove last part of path in source directory path
176 * (that is "arm" or "i586" depending on architecture) */
177 size_t position = m_npsource.find_last_of('/');
178 source = m_npsource.substr(0, position);
179 LogDebug("Removing unnecessary directory: " << source);
180 /* Remove source directory with plugins (possibly for multiple
182 if(!WrtUtilRemove(source)){
183 LogError("Failed to plugins source remove directory");
184 ThrowMsg(Exceptions::InternalError, "Failed to plugins source remove directory");
186 LogDebug("Plugins copying step ended");
189 void TaskPluginsCopy::StepCopyingFinished()
191 LogDebug("Plugins copy task finished");
194 } //namespace WidgetInstall