reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
Plugin.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
5#ifdef DSO_PLUGINS
6
7// This is the UNIX way of doing DSO, an alternative implementation
8// for Windows needs to include the relevant Windows headers here
9// and implement the loader code further below
10#include <dlfcn.h>
11
12#endif
13
14
15#include "rutil/Logger.hxx"
16
17#include "rutil/Plugin.hxx"
18
19#define RESIPROCATE_SUBSYSTEM resip::Subsystem::NONE
20
21using namespace resip;
22
24 const Data& defaultDirectory,
25 const Data& symbolName,
26 const int pluginApiVersion)
27 : mConfigParse(configParse),
28 mDefaultDirectory(defaultDirectory),
29 mSymbolName(symbolName),
30 mPluginApiVersion(pluginApiVersion)
31{
32}
33
37
38bool
39PluginManager::loadPlugins(const std::vector<Data>& pluginNames)
40{
41#ifdef DSO_PLUGINS
42 if(pluginNames.empty())
43 {
44 DebugLog(<<"LoadPlugins not specified, not attempting to load any plugins");
45 return true;
46 }
47
48 const Data& pluginDirectory = mConfigParse.getConfigData("PluginDirectory", mDefaultDirectory, true);
49 if(pluginDirectory.empty())
50 {
51 ErrLog(<<"LoadPlugins specified but PluginDirectory not specified, can't load plugins");
52 return false;
53 }
54 for(auto pluginName : pluginNames)
55 {
56 void *dlib;
57 // FIXME:
58 // - not all platforms use the .so extension
59 // - detect and use correct directory separator charactor
60 // - do we need to support relative paths here?
61 // - should we use the filename prefix 'lib', 'mod' or something else?
62 Data name = pluginDirectory + '/' + "lib" + pluginName + ".so";
63 dlib = dlopen(name.c_str(), RTLD_NOW | RTLD_GLOBAL);
64 if(!dlib)
65 {
66 ErrLog(<< "Failed to load plugin " << pluginName << " (" << name << "): " << dlerror());
67 return false;
68 }
69 PluginDescriptor* desc = (PluginDescriptor*)dlsym(dlib, mSymbolName.c_str());
70 if(!desc)
71 {
72 ErrLog(<< "Failed to find " << mSymbolName << " in plugin " << pluginName << " (" << name << "): " << dlerror());
73 return false;
74 }
75 if(!(desc->mPluginApiVersion == mPluginApiVersion))
76 {
77 ErrLog(<< "Failed to load plugin " << pluginName << " (" << name << "): found version " << desc->mPluginApiVersion << ", expecting version " << mPluginApiVersion);
78 }
79 DebugLog(<<"Trying to instantiate plugin " << pluginName);
80 // Instantiate the plugin object and add it to our runtime environment
81 std::shared_ptr<resip::Plugin> plugin = desc->creationFunc();
82 if(!plugin)
83 {
84 ErrLog(<< "Failed to instantiate plugin " << pluginName << " (" << name << ")");
85 return false;
86 }
87 onPluginLoaded(plugin);
88 mPlugins.push_back(plugin);
89 }
90 return true;
91#else
92 if(!pluginNames.empty())
93 {
94 ErrLog(<<"LoadPlugins specified but repro not compiled with plugin DSO support");
95 return false;
96 }
97 DebugLog(<<"Not compiled with plugin DSO support");
98 return true;
99#endif
100
101}
102
103void
105{
106 for(auto plugin : mPlugins)
107 {
108 plugin->onReload();
109 }
110}
111
112/* ====================================================================
113
114 Copyright (c) 2022, Software Freedom Institute https://softwarefreedom.institute
115 Copyright (c) 2022, Daniel Pocock https://danielpocock.com
116 All rights reserved.
117
118 Redistribution and use in source and binary forms, with or without
119 modification, are permitted provided that the following conditions are
120 met:
121
122 1. Redistributions of source code must retain the above copyright
123 notice, this list of conditions and the following disclaimer.
124
125 2. Redistributions in binary form must reproduce the above copyright
126 notice, this list of conditions and the following disclaimer in the
127 documentation and/or other materials provided with the distribution.
128
129 3. Neither the name of Plantronics nor the names of its contributors
130 may be used to endorse or promote products derived from this
131 software without specific prior written permission.
132
133 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
134 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
135 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
136 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
137 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
138 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
139 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
140 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
141 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
143 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144
145 ==================================================================== */
#define DebugLog(args_)
Definition Logger.hxx:128
#define ErrLog(args_)
Definition Logger.hxx:137
resip::Data getConfigData(const resip::Data &name, const resip::Data &defaultValue, bool useDefaultIfEmpty=false) const
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
virtual bool onPluginLoaded(std::shared_ptr< Plugin > plugin)=0
PluginManager(const ConfigParse &configParse, const Data &defaultDirectory, const Data &symbolName, const int pluginApiVersion)
Definition Plugin.cxx:23
virtual ~PluginManager()
Definition Plugin.cxx:34
virtual void onReload()
Definition Plugin.cxx:104
virtual bool loadPlugins(const std::vector< Data > &pluginNames)
Definition Plugin.cxx:39
dcm! – add UnusedChecking(_enum) below;
PluginCreationFunc creationFunc
Definition Plugin.hxx:54
int mPluginApiVersion
Definition Plugin.hxx:53