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