]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_namedmodes.cpp
Change lockserv emergency unlock procedure, and add one for jumpserver [jackmcbarn]
[user/henk/code/inspircd.git] / src / modules / m_namedmodes.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15
16 static void DisplayList(User* user, Channel* channel)
17 {
18         std::stringstream items;
19         for(char letter = 'A'; letter <= 'z'; letter++)
20         {
21                 ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
22                 if (!mh || mh->IsListMode())
23                         continue;
24                 if (!channel->IsModeSet(letter))
25                         continue;
26                 items << " +" << mh->name;
27                 if (mh->GetNumParams(true))
28                         items << " " << channel->GetModeParameter(letter);
29         }
30         char pfx[MAXBUF];
31         snprintf(pfx, MAXBUF, ":%s 961 %s %s", ServerInstance->Config->ServerName.c_str(), user->nick.c_str(), channel->name.c_str());
32         user->SendText(std::string(pfx), items);
33         user->WriteNumeric(960, "%s %s :End of mode list", user->nick.c_str(), channel->name.c_str());
34 }
35
36 class CommandProp : public Command
37 {
38  public:
39         CommandProp(Module* parent) : Command(parent, "PROP", 1)
40         {
41                 syntax = "<user|channel> {[+-]<mode> [<value>]}*";
42         }
43
44         CmdResult Handle(const std::vector<std::string> &parameters, User *src)
45         {
46                 if (parameters.size() == 1)
47                 {
48                         Channel* chan = ServerInstance->FindChan(parameters[0]);
49                         if (chan)
50                                 DisplayList(src, chan);
51                         return CMD_SUCCESS;
52                 }
53                 unsigned int i = 1;
54                 std::vector<std::string> modes;
55                 modes.push_back(parameters[0]);
56                 modes.push_back("");
57                 while (i < parameters.size())
58                 {
59                         std::string prop = parameters[i++];
60                         bool plus = prop[0] != '-';
61                         if (prop[0] == '+' || prop[0] == '-')
62                                 prop.erase(prop.begin());
63
64                         for(char letter = 'A'; letter <= 'z'; letter++)
65                         {
66                                 ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
67                                 if (mh && mh->name == prop)
68                                 {
69                                         modes[1].append((plus ? "+" : "-") + std::string(1, letter));
70                                         if (mh->GetNumParams(plus))
71                                         {
72                                                 if (i != parameters.size())
73                                                         modes.push_back(parameters[i++]);
74                                         }
75                                 }
76                         }
77                 }
78                 ServerInstance->SendGlobalMode(modes, src);
79                 return CMD_SUCCESS;
80         }
81 };
82
83 class DummyZ : public ModeHandler
84 {
85  public:
86         DummyZ(Module* parent) : ModeHandler(parent, "namebase", 'Z', PARAM_ALWAYS, MODETYPE_CHANNEL)
87         {
88                 list = true;
89         }
90 };
91
92 class ModuleNamedModes : public Module
93 {
94         CommandProp cmd;
95         DummyZ dummyZ;
96  public:
97         ModuleNamedModes() : cmd(this), dummyZ(this)
98         {
99         }
100
101         void init()
102         {
103                 ServerInstance->Modules->AddService(cmd);
104                 ServerInstance->Modules->AddService(dummyZ);
105
106                 Implementation eventlist[] = { I_OnPreMode };
107                 ServerInstance->Modules->Attach(eventlist, this, 1);
108         }
109
110         Version GetVersion()
111         {
112                 return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
113         }
114
115         void Prioritize()
116         {
117                 ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
118         }
119
120         ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters)
121         {
122                 if (!channel)
123                         return MOD_RES_PASSTHRU;
124                 if (parameters[1].find('Z') == std::string::npos)
125                         return MOD_RES_PASSTHRU;
126                 if (parameters.size() <= 2)
127                 {
128                         DisplayList(source, channel);
129                         return MOD_RES_DENY;
130                 }
131
132                 std::vector<std::string> newparms;
133                 newparms.push_back(parameters[0]);
134                 newparms.push_back(parameters[1]);
135
136                 std::string modelist = newparms[1];
137                 bool adding = true;
138                 unsigned int param_at = 2;
139                 for(unsigned int i = 0; i < modelist.length(); i++)
140                 {
141                         unsigned char modechar = modelist[i];
142                         if (modechar == '+' || modechar == '-')
143                         {
144                                 adding = (modechar == '+');
145                                 continue;
146                         }
147                         ModeHandler *mh = ServerInstance->Modes->FindMode(modechar, MODETYPE_CHANNEL);
148                         if (modechar == 'Z')
149                         {
150                                 modechar = 0;
151                                 std::string name, value;
152                                 if (param_at < parameters.size())
153                                         name = parameters[param_at++];
154                                 std::string::size_type eq = name.find('=');
155                                 if (eq != std::string::npos)
156                                 {
157                                         value = name.substr(eq + 1);
158                                         name = name.substr(0, eq);
159                                 }
160                                 for(char letter = 'A'; modechar == 0 && letter <= 'z'; letter++)
161                                 {
162                                         mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
163                                         if (mh && mh->name == name)
164                                         {
165                                                 if (mh->GetNumParams(adding))
166                                                 {
167                                                         if (!value.empty())
168                                                         {
169                                                                 newparms.push_back(value);
170                                                                 modechar = letter;
171                                                                 break;
172                                                         }
173                                                 }
174                                                 else
175                                                 {
176                                                         modechar = letter;
177                                                         break;
178                                                 }
179                                         }
180                                 }
181                                 if (modechar)
182                                         modelist[i] = modechar;
183                                 else
184                                         modelist.erase(i--, 1);
185                         }
186                         else if (mh && mh->GetNumParams(adding) && param_at < parameters.size())
187                         {
188                                 newparms.push_back(parameters[param_at++]);
189                         }
190                 }
191                 newparms[1] = modelist;
192                 ServerInstance->Modes->Process(newparms, source, false);
193                 return MOD_RES_DENY;
194         }
195 };
196
197 MODULE_INIT(ModuleNamedModes)