]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_cap.cpp
Remove InspIRCd* parameters and fields
[user/henk/code/inspircd.git] / src / modules / m_cap.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 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 #include "m_cap.h"
16
17 /* $ModDesc: Provides the CAP negotiation mechanism seen in ratbox-derived ircds */
18
19 /*
20 CAP LS
21 :alfred.staticbox.net CAP * LS :multi-prefix sasl
22 CAP REQ :multi-prefix
23 :alfred.staticbox.net CAP * ACK :multi-prefix
24 CAP CLEAR
25 :alfred.staticbox.net CAP * ACK :-multi-prefix
26 CAP REQ :multi-prefix
27 :alfred.staticbox.net CAP * ACK :multi-prefix
28 CAP LIST
29 :alfred.staticbox.net CAP * LIST :multi-prefix
30 CAP END
31 */
32
33 /** Handle /CAP
34  */
35 class CommandCAP : public Command
36 {
37  public:
38         LocalIntExt reghold;
39         CommandCAP (Module* mod) : Command(mod, "CAP", 1),
40                 reghold("CAP_REGHOLD", mod)
41         {
42                 works_before_reg = true;
43         }
44
45         CmdResult Handle (const std::vector<std::string> &parameters, User *user)
46         {
47                 irc::string subcommand = parameters[0].c_str();
48
49                 if (subcommand == "REQ")
50                 {
51                         CapData Data;
52
53                         Data.type = subcommand;
54                         Data.user = user;
55                         Data.creator = this->creator;
56
57                         if (parameters.size() < 2)
58                                 return CMD_FAILURE;
59
60                         // tokenize the input into a nice list of requested caps
61                         std::string param = parameters[1];
62                         std::string cap_;
63                         irc::spacesepstream cap_stream(param);
64
65                         while (cap_stream.GetToken(cap_))
66                         {
67                                 Data.wanted.push_back(cap_);
68                         }
69
70                         reghold.set(user, 1);
71                         Event event((char*) &Data, this->creator, "cap_req");
72                         event.Send();
73
74                         if (Data.ack.size() > 0)
75                         {
76                                 std::string AckResult = irc::stringjoiner(" ", Data.ack, 0, Data.ack.size() - 1).GetJoined();
77                                 user->WriteServ("CAP * ACK :%s", AckResult.c_str());
78                         }
79
80                         if (Data.wanted.size() > 0)
81                         {
82                                 std::string NakResult = irc::stringjoiner(" ", Data.wanted, 0, Data.wanted.size() - 1).GetJoined();
83                                 user->WriteServ("CAP * NAK :%s", NakResult.c_str());
84                         }
85                 }
86                 else if (subcommand == "END")
87                 {
88                         reghold.set(user, 0);
89                 }
90                 else if ((subcommand == "LS") || (subcommand == "LIST"))
91                 {
92                         CapData Data;
93
94                         Data.type = subcommand;
95                         Data.user = user;
96                         Data.creator = this->creator;
97
98                         reghold.set(user, 1);
99                         Event event((char*) &Data, this->creator, subcommand == "LS" ? "cap_ls" : "cap_list");
100                         event.Send();
101
102                         std::string Result;
103                         if (Data.wanted.size() > 0)
104                                 Result = irc::stringjoiner(" ", Data.wanted, 0, Data.wanted.size() - 1).GetJoined();
105                         else
106                                 Result = "";
107
108                         user->WriteServ("CAP * %s :%s", subcommand.c_str(), Result.c_str());
109                 }
110                 else if (subcommand == "CLEAR")
111                 {
112                         CapData Data;
113
114                         Data.type = subcommand;
115                         Data.user = user;
116                         Data.creator = this->creator;
117
118                         reghold.set(user, 1);
119                         Event event((char*) &Data, this->creator, "cap_clear");
120                         event.Send();
121
122                         std::string Result = irc::stringjoiner(" ", Data.ack, 0, Data.ack.size() - 1).GetJoined();
123                         user->WriteServ("CAP * ACK :%s", Result.c_str());
124                 }
125                 else
126                 {
127                         user->WriteNumeric(ERR_INVALIDCAPSUBCOMMAND, "* %s :Invalid CAP subcommand", subcommand.c_str());
128                 }
129
130                 return CMD_FAILURE;
131         }
132 };
133
134 class ModuleCAP : public Module
135 {
136         CommandCAP cmd;
137  public:
138         ModuleCAP()
139                 : cmd(this)
140         {
141                 ServerInstance->AddCommand(&cmd);
142                 Extensible::Register(&cmd.reghold);
143
144                 Implementation eventlist[] = { I_OnCheckReady };
145                 ServerInstance->Modules->Attach(eventlist, this, 1);
146         }
147
148         ModResult OnCheckReady(User* user)
149         {
150                 /* Users in CAP state get held until CAP END */
151                 if (cmd.reghold.get(user))
152                         return MOD_RES_DENY;
153
154                 return MOD_RES_PASSTHRU;
155         }
156
157         ~ModuleCAP()
158         {
159         }
160
161         Version GetVersion()
162         {
163                 return Version("Client CAP extension support", VF_VENDOR);
164         }
165 };
166
167 MODULE_INIT(ModuleCAP)
168