diff options
-rw-r--r-- | Makefile.plugins | 2 | ||||
-rw-r--r-- | include/media/mediaManager.h | 2 | ||||
-rw-r--r-- | include/pluginManager.h | 3 | ||||
-rw-r--r-- | media/mediaManager.cpp | 12 | ||||
-rw-r--r-- | media/pluginManager.cpp | 25 | ||||
-rw-r--r-- | plugins/provider/fileProvider/fileProvider.cpp | 69 |
6 files changed, 88 insertions, 25 deletions
diff --git a/Makefile.plugins b/Makefile.plugins index 34de307..595acfc 100644 --- a/Makefile.plugins +++ b/Makefile.plugins @@ -30,8 +30,6 @@ SUBPLUGVERSION = $(shell grep 'static const char \*VERSION *=' $(SUBPLUGIN)$(CAT DEFINES += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -LIBS += -L$(LIBDIR) -Wl,-R$(LIBDIR) $(VDRPLUGINLIBDIR)/libvdr-upnp.so.$(APIVERSION) - # Dependencies: MAKEDEP = g++ -MM -MG diff --git a/include/media/mediaManager.h b/include/media/mediaManager.h index f7d803c..40aa49f 100644 --- a/include/media/mediaManager.h +++ b/include/media/mediaManager.h @@ -57,7 +57,6 @@ public: cMediaManager(); virtual ~cMediaManager(); - void SetPluginDirectory(const string& directory); void SetDatabaseDir(const string& file); bool Initialise(); @@ -95,7 +94,6 @@ private: IdList eventedContainerUpdateIDs; StringList scanTargets; string databaseFile; - string pluginDirectory; tntdb::Connection connection; upnp::cPluginManager* pluginManager; diff --git a/include/pluginManager.h b/include/pluginManager.h index 563d4fb..f495a5d 100644 --- a/include/pluginManager.h +++ b/include/pluginManager.h @@ -25,7 +25,7 @@ public: cPluginManager(); virtual ~cPluginManager(); - bool LoadPlugins(const std::string& directory); + bool LoadPlugins(); int Count() const; @@ -64,6 +64,7 @@ private: ProviderMap providerFactory; ProfilerList profilers; ProviderList providers; + void* selfhandle; }; diff --git a/media/mediaManager.cpp b/media/mediaManager.cpp index 7064daa..670a158 100644 --- a/media/mediaManager.cpp +++ b/media/mediaManager.cpp @@ -21,8 +21,6 @@ namespace upnp { -#define DEFAULTPLUGINDIR PLUGINDIR - static const char* DIDLFragment = "<DIDL-Lite " "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " @@ -107,7 +105,6 @@ void cResourceStreamer::Close(){ cMediaManager::cMediaManager() : systemUpdateID(0) -, pluginDirectory(DEFAULTPLUGINDIR) , pluginManager(NULL) { SetDatabaseDir(string()); @@ -597,8 +594,8 @@ bool cMediaManager::Initialise(){ dsyslog("UPnP\tLoading Plugins..."); pluginManager = new upnp::cPluginManager(); - if(!pluginManager->LoadPlugins(pluginDirectory)){ - esyslog("UPnP\tError while loading upnp plugin directory '%s'", pluginDirectory.c_str()); + if(!pluginManager->LoadPlugins()){ + esyslog("UPnP\tError while loading upnp plugins"); return false; } else { dsyslog("UPnP\tFound %d plugins", pluginManager->Count()); @@ -721,11 +718,6 @@ void cMediaManager::SetDatabaseDir(const string& file){ databaseFile += "/metadata.db"; } -void cMediaManager::SetPluginDirectory(const string& directory){ - if(directory.empty()) pluginDirectory = DEFAULTPLUGINDIR; - else pluginDirectory = directory; -} - void cMediaManager::Action(){ string uri; while(!scanTargets.empty()){ diff --git a/media/pluginManager.cpp b/media/pluginManager.cpp index 38be5d4..cd31be3 100644 --- a/media/pluginManager.cpp +++ b/media/pluginManager.cpp @@ -312,9 +312,13 @@ void cUPnPResourceProvider::OnContainerUpdate(const string& uri, long int cUID, void cUPnPResourceProvider::Action(){} upnp::cPluginManager::cPluginManager() +: selfhandle(NULL) {} -upnp::cPluginManager::~cPluginManager(){} +upnp::cPluginManager::~cPluginManager(){ + if(selfhandle) + dlclose(selfhandle); +} const cPluginManager::ProfilerList& upnp::cPluginManager::GetProfilers() const { return profilers; @@ -338,10 +342,27 @@ cUPnPResourceProvider* upnp::cPluginManager::CreateProvider(const string& schema #define UPNPPLUGIN_PREFIX "libupnp-" #define SO_INDICATOR ".so." -bool upnp::cPluginManager::LoadPlugins(const string& directory){ +bool upnp::cPluginManager::LoadPlugins(){ + + Dl_info info; + static int marker=0; + if(!dladdr((void *)&marker,&info)) { + esyslog("UPnP\tError while getting information about myself: %s", dlerror()); + return false; + } + + selfhandle = dlopen(info.dli_fname,RTLD_NOW|RTLD_GLOBAL); + if(!selfhandle) { + esyslog("Error while opening myself: %s",dlerror()); + return false; + } DIR* dirHandle; struct dirent* dirEntry; + string library = info.dli_fname; + string directory = library.substr(0, library.find_last_of('/')); + + dsyslog("UPnP\tScanning %s for plugins.", directory.c_str()); if((dirHandle = opendir(directory.c_str())) == NULL){ return false; diff --git a/plugins/provider/fileProvider/fileProvider.cpp b/plugins/provider/fileProvider/fileProvider.cpp index 89e6f43..d1e68c5 100644 --- a/plugins/provider/fileProvider/fileProvider.cpp +++ b/plugins/provider/fileProvider/fileProvider.cpp @@ -6,6 +6,7 @@ */ #include <plugin.h> +#include <fstream> using namespace std; @@ -17,6 +18,25 @@ private: StringMap directoryMap; FILE* fileFD; + bool Load(const string& filename) + { + bool result = false; + if (access(filename.c_str(), F_OK) == 0) { + isyslog("loading %s", filename.c_str()); + ifstream file; + file.open(filename.c_str(), ifstream::in); + string line; int pos; + while(getline(file, line)){ + if(line.length() > 0 && line[0] != '#'){ + if((pos = line.find_first_of(':')) != string::npos){ + directoryMap[line.substr(0,pos)] = line.substr(pos+1); + } + } + } + } + return result; + } + string GetFile(const string& uri){ string mountPoint = uri.substr(6, uri.find_first_of('/',6) - 7); @@ -28,6 +48,16 @@ private: return file; } + bool GetFileStat(const string& uri, struct stat& fileStat){ + struct stat s; + if(stat(GetFile(uri).c_str(), &s) == 0){ + fileStat = s; + return true; + } + + return false; + } + public: virtual string ProvidesSchema() { return "file"; } @@ -36,26 +66,49 @@ public: return ProvidesSchema() + "://"; } - virtual StringList GetContainerEntries(const string& uri) { - StringList list; - - return list; - } - virtual bool IsContainer(const string& uri) { + struct stat fileStat; + if(GetFileStat(uri, fileStat) && S_ISDIR(fileStat.st_mode)) return true; + return false; } virtual bool IsLink(const string& uri, string& target) { + struct stat fileStat; + if(GetFileStat(uri, fileStat) && S_ISLNK(fileStat.st_mode)) return true; + return false; } virtual long GetContainerUpdateId(const string& uri) { + struct stat fileStat; + if(GetFileStat(uri, fileStat)){ + return std::max<time_t>(fileStat.st_ctim.tv_sec, fileStat.st_mtim.tv_sec); + } + return 0; } - virtual bool GetMetadata(const string& uri, cMetadata& metadata) { - return false; + virtual StringList GetContainerEntries(const string& uri) { + StringList list; + + DIR* dirHandle; + struct dirent* dirEntry; + + if((dirHandle = opendir(GetFile(uri).c_str())) == NULL){ + return false; + } + + string filename; + while ((dirEntry = readdir(dirHandle)) != NULL) { + filename = dirEntry->d_name; + if(filename.compare(".") || filename.compare("..")){ + list.push_back(filename); + } + } + closedir(dirHandle); + + return list; } virtual bool Seekable() const { |