]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_helpop.cpp
Merge tag 'v2.0.26' into master.
[user/henk/code/inspircd.git] / src / modules / m_helpop.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2005-2009 Robin Burchell <robin+git@viroteck.net>
6  *   Copyright (C) 2004-2006, 2008 Craig Edwards <craigedwards@brainbox.cc>
7  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
8  *   Copyright (C) 2004-2005 Craig McLure <craig@chatspike.net>
9  *
10  * This file is part of InspIRCd.  InspIRCd is free software: you can
11  * redistribute it and/or modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23
24 #include "inspircd.h"
25 #include "modules/whois.h"
26
27 enum
28 {
29         // From UnrealIRCd.
30         RPL_WHOISHELPOP = 310
31 };
32
33 typedef std::map<std::string, std::string, irc::insensitive_swo> HelpopMap;
34 static HelpopMap helpop_map;
35
36 /** Handles user mode +h
37  */
38 class Helpop : public SimpleUserModeHandler
39 {
40  public:
41         Helpop(Module* Creator) : SimpleUserModeHandler(Creator, "helpop", 'h')
42         {
43                 oper = true;
44         }
45 };
46
47 /** Handles /HELPOP
48  */
49 class CommandHelpop : public Command
50 {
51         const std::string startkey;
52  public:
53         CommandHelpop(Module* Creator)
54                 : Command(Creator, "HELPOP", 0)
55                 , startkey("start")
56         {
57                 syntax = "<any-text>";
58         }
59
60         CmdResult Handle(const std::vector<std::string>& parameters, User* user) CXX11_OVERRIDE
61         {
62                 const std::string& parameter = (!parameters.empty() ? parameters[0] : startkey);
63
64                 if (parameter == "index")
65                 {
66                         /* iterate over all helpop items */
67                         user->WriteNumeric(290, "HELPOP topic index");
68                         for (HelpopMap::const_iterator iter = helpop_map.begin(); iter != helpop_map.end(); iter++)
69                                 user->WriteNumeric(292, InspIRCd::Format("  %s", iter->first.c_str()));
70                         user->WriteNumeric(292, "*** End of HELPOP topic index");
71                 }
72                 else
73                 {
74                         user->WriteNumeric(290, InspIRCd::Format("*** HELPOP for %s", parameter.c_str()));
75                         user->WriteNumeric(292, " -");
76
77                         HelpopMap::const_iterator iter = helpop_map.find(parameter);
78
79                         if (iter == helpop_map.end())
80                         {
81                                 iter = helpop_map.find("nohelp");
82                         }
83
84                         const std::string& value = iter->second;
85                         irc::sepstream stream(value, '\n');
86                         std::string token = "*";
87
88                         while (stream.GetToken(token))
89                         {
90                                 // Writing a blank line will not work with some clients
91                                 if (token.empty())
92                                         user->WriteNumeric(292, ' ');
93                                 else
94                                         user->WriteNumeric(292, token);
95                         }
96
97                         user->WriteNumeric(292, " -");
98                         user->WriteNumeric(292, "*** End of HELPOP");
99                 }
100                 return CMD_SUCCESS;
101         }
102 };
103
104 class ModuleHelpop : public Module, public Whois::EventListener
105 {
106                 CommandHelpop cmd;
107                 Helpop ho;
108
109         public:
110                 ModuleHelpop()
111                         : Whois::EventListener(this)
112                         , cmd(this)
113                         , ho(this)
114                 {
115                 }
116
117                 void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
118                 {
119                         HelpopMap help;
120
121                         ConfigTagList tags = ServerInstance->Config->ConfTags("helpop");
122                         for(ConfigIter i = tags.first; i != tags.second; ++i)
123                         {
124                                 ConfigTag* tag = i->second;
125                                 std::string key = tag->getString("key");
126                                 std::string value;
127                                 tag->readString("value", value, true); /* Linefeeds allowed */
128
129                                 if (key == "index")
130                                 {
131                                         throw ModuleException("m_helpop: The key 'index' is reserved for internal purposes. Please remove it.");
132                                 }
133
134                                 help[key] = value;
135                         }
136
137                         if (help.find("start") == help.end())
138                         {
139                                 // error!
140                                 throw ModuleException("m_helpop: Helpop file is missing important entry 'start'. Please check the example conf.");
141                         }
142                         else if (help.find("nohelp") == help.end())
143                         {
144                                 // error!
145                                 throw ModuleException("m_helpop: Helpop file is missing important entry 'nohelp'. Please check the example conf.");
146                         }
147
148                         helpop_map.swap(help);
149                 }
150
151                 void OnWhois(Whois::Context& whois) CXX11_OVERRIDE
152                 {
153                         if (whois.GetTarget()->IsModeSet(ho))
154                         {
155                                 whois.SendLine(RPL_WHOISHELPOP, "is available for help.");
156                         }
157                 }
158
159                 Version GetVersion() CXX11_OVERRIDE
160                 {
161                         return Version("Provides the /HELPOP command for useful information", VF_VENDOR);
162                 }
163 };
164
165 MODULE_INIT(ModuleHelpop)