1/*2Maddy Mail Server - Composable all-in-one email server.3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors45This program is free software: you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation, either version 3 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program. If not, see <https://www.gnu.org/licenses/>.17*/1819package module2021import (22 "sync"2324 "github.com/foxcpp/maddy/framework/log"25)2627var (28 // NoRun makes sure modules do not start any bacground tests.29 //30 // If it set - modules should not perform any actual work and should stop31 // once the configuration is read and verified to be correct.32 // TODO: Replace it with separation of Init and Run at interface level.33 NoRun = false3435 modules = make(map[string]FuncNewModule)36 endpoints = make(map[string]FuncNewEndpoint)37 modulesLock sync.RWMutex38)3940// Register adds module factory function to global registry.41//42// name must be unique. Register will panic if module with specified name43// already exists in registry.44//45// You probably want to call this function from func init() of module package.46func Register(name string, factory FuncNewModule) {47 modulesLock.Lock()48 defer modulesLock.Unlock()4950 if _, ok := modules[name]; ok {51 panic("Register: module with specified name is already registered: " + name)52 }5354 modules[name] = factory55}5657// RegisterDeprecated adds module factory function to global registry.58//59// It prints warning to the log about name being deprecated and suggests using60// a new name.61func RegisterDeprecated(name, newName string, factory FuncNewModule) {62 Register(name, func(modName, instName string, aliases, inlineArgs []string) (Module, error) {63 log.Printf("module initialized via deprecated name %s, %s should be used instead; deprecated name may be removed in the next version", name, newName)64 return factory(modName, instName, aliases, inlineArgs)65 })66}6768// Get returns module from global registry.69//70// This function does not return endpoint-type modules, use GetEndpoint for71// that.72// Nil is returned if no module with specified name is registered.73func Get(name string) FuncNewModule {74 modulesLock.RLock()75 defer modulesLock.RUnlock()7677 return modules[name]78}7980// GetEndpoints returns an endpoint module from global registry.81//82// Nil is returned if no module with specified name is registered.83func GetEndpoint(name string) FuncNewEndpoint {84 modulesLock.RLock()85 defer modulesLock.RUnlock()8687 return endpoints[name]88}8990// RegisterEndpoint registers an endpoint module.91//92// See FuncNewEndpoint for information about93// differences of endpoint modules from regular modules.94func RegisterEndpoint(name string, factory FuncNewEndpoint) {95 modulesLock.Lock()96 defer modulesLock.Unlock()9798 if _, ok := endpoints[name]; ok {99 panic("Register: module with specified name is already registered: " + name)100 }101102 endpoints[name] = factory103}