1 // extension.cpp: Read and enable plug-in extensions to Flash, for Gnash.
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "gnashconfig.h"
25 #if defined(WIN32) || defined(_WIN32)
26 #define LIBLTDL_DLL_IMPORT 1
30 #include <sys/types.h>
34 #include "sharedlib.h"
35 #include "extension.h"
41 #if defined(WIN32) || defined(_WIN32)
42 int lt_dlsetsearchpath (const char *search_path
);
44 void * lt_dlsym (lt_dlhandle handle
, const char *name
);
45 const char *lt_dlerror (void);
46 int lt_dlclose (lt_dlhandle handle
);
47 int lt_dlmakeresident (lt_dlhandle handle
);
48 lt_dlhandle
lt_dlopenext (const char *filename
);
51 #if HAVE_DIRENT_H || WIN32==1 // win32 hack
53 # define NAMLEN(dirent) std::strlen((dirent)->d_name)
55 # define dirent direct
56 # define NAMLEN(dirent) (dirent)->d_namlen
58 # include <sys/ndir.h>
70 Extension::Extension()
72 // GNASH_REPORT_FUNCTION;
74 // return lt_dlmutex_register (gnash_mutex_lock, gnash_mutex_unlock,
75 // gnash_mutex_seterror, gnash_mutex_geterror);
77 char *env
= std::getenv("GNASH_PLUGINS");
79 _pluginsdir
= PLUGINSDIR
;
85 log_debug("Plugins path: %s", _pluginsdir
);
87 lt_dlsetsearchpath(_pluginsdir
.c_str());
91 Extension::Extension(const std::string
& dir
)
93 // GNASH_REPORT_FUNCTION;
95 // return lt_dlmutex_register (gnash_mutex_lock, gnash_mutex_unlock,
96 // gnash_mutex_seterror, gnash_mutex_geterror);
100 lt_dlsetsearchpath(_pluginsdir
.c_str());
104 Extension::~Extension()
106 // GNASH_REPORT_FUNCTION;
110 Extension::scanAndLoad(const std::string
& dir
, as_object
&obj
)
112 // GNASH_REPORT_FUNCTION;
115 lt_dlsetsearchpath(_pluginsdir
.c_str());
119 return scanAndLoad(obj
);
123 Extension::scanAndLoad(as_object
& where
)
125 // GNASH_REPORT_FUNCTION;
127 if (_modules
.empty()) {
128 scanDir(_pluginsdir
);
131 std::vector
<std::string
>::iterator it
;
132 for (it
= _modules
.begin(); it
!= _modules
.end(); it
++) {
133 const std::string
& mod
= *it
;
134 log_security(_("Loading module: %s from %s"), mod
, _pluginsdir
);
135 initModule(mod
, where
);
141 Extension::initModule(const std::string
& module
, as_object
&where
)
145 std::string
symbol(module
);
147 log_security(_("Initializing module: \"%s\" from %s"), symbol
, _pluginsdir
);
149 if (_plugins
[module
] == 0) {
150 sl
= new SharedLib(_pluginsdir
+ "/" + module
, "GNASH_PLUGINS");
152 _plugins
[module
] = sl
;
154 sl
= _plugins
[module
];
157 symbol
.append("_class_init");
159 SharedLib::initentry
*symptr
= sl
->getInitEntry(symbol
);
164 log_error(_("Couldn't get class_init symbol"));
171 Extension::initModuleWithFunc(const std::string
& module
,
172 const std::string
& func
, as_object
&obj
)
174 GNASH_REPORT_FUNCTION
;
178 log_security(_("Initializing module: \"%s\""), module
);
180 if (_plugins
[module
] == 0) {
181 sl
= new SharedLib(module
);
183 _plugins
[module
] = sl
;
185 sl
= _plugins
[module
];
188 SharedLib::initentry
*symptr
= sl
->getInitEntry(func
);
193 log_error(_("Couldn't get class_init symbol: \"%s\""), func
);
202 // GNASH_REPORT_FUNCTION;
203 scanDir(_pluginsdir
);
208 Extension::scanDir(const std::string
& dirlist
)
210 GNASH_REPORT_FUNCTION
;
212 Tok
t(dirlist
, Sep(":"));
213 for (Tok::iterator i
= t
.begin(), e
= t
.end(); i
!= e
; ++i
) {
215 const std::string
& dir
= *i
;
217 log_debug(_("Scanning directory \"%s\" for plugins"), dir
);
218 DIR *libdir
= opendir(dir
.c_str());
221 log_error(_("Can't open directory %s"), dir
);
225 struct dirent
*entry
;
227 while ((entry
= readdir(libdir
)) != NULL
) {
228 // We only want shared libraries that end with the suffix, otherwise
229 // we get all the duplicates.
230 std::string
name(entry
->d_name
);
233 if (name
.at(0) == '.') {
237 const std::string::size_type pos
= name
.find_last_of('.');
239 if (pos
== std::string::npos
) continue;
241 const std::string suffix
= name
.substr(pos
);
244 if (suffix
== ".so") {
245 log_debug(_("Gnash Plugin name: %s"), name
);
246 _modules
.push_back(name
);
253 if (closedir(libdir
) != 0) {
261 Extension::dumpModules()
263 GNASH_REPORT_FUNCTION
;
265 std::cerr
<< _modules
.size() << " plugin(s) for Gnash installed" << std::endl
;
266 std::vector
<std::string
>::iterator it
;
267 for (it
= _modules
.begin(); it
!= _modules
.end(); it
++) {
268 std::cerr
<< "Module name is: \"" << *(it
) << "\"" << std::endl
;
272 } // end of gnash namespace