/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2008-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include "plugin.h" #include "misc.h" #include "system.h" #include "sessionmanager.h" #include "functions/functions.h" #include "templates/templates.h" #include "winixrequest.h" namespace Winix { void Plugin::UnloadPlugins() { size_t i; slots.clear(); for(i=0 ; icur = cur; } void Plugin::SetFunctions(Functions * pfunctions) { functions = pfunctions; } void Plugin::SetTemplates(Templates * ptemplates) { templates = ptemplates; } void Plugin::SetSessionManager(SessionManager * psession_manager) { session_manager = psession_manager; } void Plugin::SetWinixRequest(WinixRequest * winix_request) { this->winix_request = winix_request; } void Plugin::Lock() { if( synchro ) synchro->Lock(); } void Plugin::Unlock() { if( synchro ) synchro->Unlock(); } bool Plugin::SetDependencyForPluginInfo(morm::ModelConnector * pmodel_connector, Log * plog, Cur * pcur, PluginInfo & info) { // for safety we call a plugin function only when all our pointers are not null bool res = (pmodel_connector && plog && pcur && db && config && system && functions && templates && synchro && session_manager && winix_request); if( !res ) { log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend; } info.db = db; info.config = config; info.cur = pcur; info.system = system; info.functions = functions; info.templates = templates; info.synchro = synchro; info.session_manager = session_manager; info.plugin = this; info.model_connector = pmodel_connector;; info.log.set_log_buffer(plog->get_log_buffer()); info.log.set_file_log(plog->get_file_log()); return res; } void Plugin::LoadPlugins(const std::wstring & plugins_dir, const std::vector & plugins) { for(size_t i=0 ; i(info.p1); plugins.push_back(item); current_plugin = old_current_plugin; } void Plugin::LoadPlugin(const std::wstring & filename) { LoadPlugin(filename.c_str()); } bool Plugin::HasPlugin(const wchar_t * name) { if( *name == 0 ) return false; for(size_t i=0 ; isecond.index; info.plugin_id = current_plugin; if( current_plugin != -1 && cur->session && !cur->session->is_temporary_session() ) info.plugin_data_base = cur->session->plugin_data.Get(current_plugin); else info.plugin_data_base = nullptr; if( !slot->second.is_running ) { if( config->log_plugin_call ) { log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend; } slot->second.is_running = true; if( slot->second.fun1 ) slot->second.fun1(info); if( slot->second.fun2 ) slot->second.fun2(); slot->second.is_running = false; if( config->log_plugin_call ) { log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message << ", result: " << (info.res? "true" : "false") << logend; } } else { log << log1 << "Plugin: id: " << slot->second.index << ", message: " << message << ", recurrences are not allowed" << logend; } } PluginRes Plugin::Call(morm::ModelConnector * model_connector, Log * plog, Cur * cur, int message, void * p1, void * p2, long l1, long l2) { PluginRes res; int old_current_plugin = current_plugin; PluginInfo info; Cur local_cur; if( !cur ) cur = &local_cur; Slots::iterator i = slots.lower_bound(message); for( ; i!=slots.end() && i->first==message ; ++i ) { info.Clear(); info.p1 = p1; info.p2 = p2; info.l1 = l1; info.l2 = l2; Call(model_connector, plog, cur, message, i, info); if( info.res ) ++res.res_true; else ++res.res_false; } current_plugin = old_current_plugin; return res; } PluginRes Plugin::Call(morm::ModelConnector * model_connector, Log * plog, Session * session, Request * request, Mount * mount, int message, void * p1, void * p2, long l1, long l2) { Cur local_cur; local_cur.session = session; local_cur.request = request; local_cur.mount = mount; return Call(model_connector, plog, &local_cur, message, p1, p2, l1, l2); } PluginRes Plugin::Call(int message) { return Call(model_connector, &log, cur, message, 0, 0, 0, 0); } PluginRes Plugin::Call(int message, void * p1_) { return Call(model_connector, &log, cur, message, p1_, 0, 0, 0); } PluginRes Plugin::Call(int message, void * p1_, void * p2_) { return Call(model_connector, &log, cur, message, p1_, p2_, 0, 0); } PluginRes Plugin::Call(int message, long l1_) { return Call(model_connector, &log, cur, message, 0, 0, l1_, 0); } PluginRes Plugin::Call(int message, long l1_, long l2_) { return Call(model_connector, &log, cur, message, 0, 0, l1_, l2_); } PluginRes Plugin::Call(int message, void * p1_, long l1_) { return Call(model_connector, &log, cur, message, p1_, 0, l1_, 0); } PluginRes Plugin::Call(int message, void * p1_, long l1_, long l2_) { return Call(model_connector, &log, cur, message, p1_, 0, l1_, l2_); } PluginRes Plugin::Call(int message, void * p1_, void * p2_, long l1_) { return Call(model_connector, &log, cur, message, p1_, p2_, l1_, 0); } size_t Plugin::Size() { return plugins.size(); } /* !! IMPROVE ME Assign() can work only if other threads are not started we can add some barrier/flag so when other threads starts then we cannot use Assign() method */ void Plugin::Assign(int message, Fun1 fun1) { Slot s; if( current_plugin == -1 ) return; s.fun1 = fun1; s.index = current_plugin; slots.insert( std::make_pair(message, s) ); log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend; } void Plugin::Assign(int message, Fun2 fun2) { Slot s; if( current_plugin == -1 ) return; s.fun2 = fun2; s.index = current_plugin; slots.insert( std::make_pair(message, s) ); log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend; } const Plugin::Plugins * Plugin::GetPlugins() { return &plugins; } } // namespace Winix