2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * Please read the file COPYING, README and AUTHORS for more information.
16 * Handler for IRC capability ("CAP") commands
26 #include "client-cap.h"
27 #include "irc-write.h"
36 bool Handle_CAP_LS PARAMS((CLIENT *Client, char *Arg));
37 bool Handle_CAP_LIST PARAMS((CLIENT *Client, char *Arg));
38 bool Handle_CAP_REQ PARAMS((CLIENT *Client, char *Arg));
39 bool Handle_CAP_ACK PARAMS((CLIENT *Client, char *Arg));
40 bool Handle_CAP_CLEAR PARAMS((CLIENT *Client));
41 bool Handle_CAP_END PARAMS((CLIENT *Client));
43 void Set_CAP_Negotiation PARAMS((CLIENT *Client));
47 * Handler for the IRCv3 "CAP" command.
49 * @param Client The client from which this command has been received.
50 * @param Req Request structure with prefix and all parameters.
51 * @returns CONNECTED or DISCONNECTED.
54 IRC_CAP(CLIENT *Client, REQUEST *Req)
56 assert(Client != NULL);
59 /* Bad number of prameters? */
60 if (Req->argc < 1 || Req->argc > 2)
61 return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
62 Client_ID(Client), Req->command);
64 LogDebug("Got \"%s %s\" command from \"%s\" ...",
65 Req->command, Req->argv[0], Client_ID(Client));
68 if (strcasecmp(Req->argv[0], "CLEAR") == 0)
69 return Handle_CAP_CLEAR(Client);
70 if (strcasecmp(Req->argv[0], "END") == 0)
71 return Handle_CAP_END(Client);
73 if (Req->argc >= 1 && Req->argc <= 2) {
74 if (strcasecmp(Req->argv[0], "LS") == 0)
75 return Handle_CAP_LS(Client, Req->argv[1]);
76 if (strcasecmp(Req->argv[0], "LIST") == 0)
77 return Handle_CAP_LIST(Client, Req->argv[1]);
80 if (strcasecmp(Req->argv[0], "REQ") == 0)
81 return Handle_CAP_REQ(Client, Req->argv[1]);
82 if (strcasecmp(Req->argv[0], "ACK") == 0)
83 return Handle_CAP_ACK(Client, Req->argv[1]);
86 return IRC_WriteStrClient(Client, ERR_INVALIDCAP_MSG,
87 Client_ID(Client), Req->argv[0]);
91 * Handler for the "CAP LS" command.
93 * @param Client The client from which this command has been received.
94 * @param Arg Command argument or NULL.
95 * @returns CONNECTED or DISCONNECTED.
98 Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
100 assert(Client != NULL);
102 Set_CAP_Negotiation(Client);
104 return IRC_WriteStrClient(Client, "CAP %s LS :", Client_ID(Client));
108 * Handler for the "CAP LIST" command.
110 * @param Client The client from which this command has been received.
111 * @param Arg Command argument or NULL.
112 * @returns CONNECTED or DISCONNECTED.
115 Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
117 assert(Client != NULL);
119 return IRC_WriteStrClient(Client, "CAP %s LIST :", Client_ID(Client));
123 * Handler for the "CAP REQ" command.
125 * @param Client The client from which this command has been received.
126 * @param Arg Command argument.
127 * @returns CONNECTED or DISCONNECTED.
130 Handle_CAP_REQ(CLIENT *Client, char *Arg)
132 assert(Client != NULL);
135 Set_CAP_Negotiation(Client);
137 return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
138 Client_ID(Client), Arg);
142 * Handler for the "CAP ACK" command.
144 * @param Client The client from which this command has been received.
145 * @param Arg Command argument.
146 * @returns CONNECTED or DISCONNECTED.
149 Handle_CAP_ACK(CLIENT *Client, char *Arg)
151 assert(Client != NULL);
158 * Handler for the "CAP CLEAR" command.
160 * @param Client The client from which this command has been received.
161 * @returns CONNECTED or DISCONNECTED.
164 Handle_CAP_CLEAR(CLIENT *Client)
166 assert(Client != NULL);
168 return IRC_WriteStrClient(Client, "CAP %s ACK :", Client_ID(Client));
172 * Handler for the "CAP END" command.
174 * @param Client The client from which this command has been received.
175 * @returns CONNECTED or DISCONNECTED.
178 Handle_CAP_END(CLIENT *Client)
180 assert(Client != NULL);
182 if (Client_Type(Client) != CLIENT_USER) {
183 /* User is still logging in ... */
184 Client_CapDel(Client, CLIENT_CAP_PENDING);
186 if (Client_Type(Client) == CLIENT_WAITCAPEND) {
187 /* Only "CAP END" was missing: log in! */
188 return Login_User(Client);
196 * Set CAP negotiation status and mark client as "supports capabilities".
198 * @param Client The client to handle.
201 Set_CAP_Negotiation(CLIENT *Client)
203 assert(Client != NULL);
205 if (Client_Type(Client) != CLIENT_USER)
206 Client_CapAdd(Client, CLIENT_CAP_PENDING);
207 Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);