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));
44 * Handler for the IRCv3 "CAP" command.
46 * @param Client The client from which this command has been received.
47 * @param Req Request structure with prefix and all parameters.
48 * @returns CONNECTED or DISCONNECTED.
51 IRC_CAP(CLIENT *Client, REQUEST *Req)
53 assert(Client != NULL);
56 /* Bad number of prameters? */
57 if (Req->argc < 1 || Req->argc > 2)
58 return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
59 Client_ID(Client), Req->command);
61 LogDebug("Got \"%s %s\" command from \"%s\" ...",
62 Req->command, Req->argv[0], Client_ID(Client));
65 if (strcasecmp(Req->argv[0], "CLEAR") == 0)
66 return Handle_CAP_CLEAR(Client);
67 if (strcasecmp(Req->argv[0], "END") == 0)
68 return Handle_CAP_END(Client);
70 if (Req->argc >= 1 && Req->argc <= 2) {
71 if (strcasecmp(Req->argv[0], "LS") == 0)
72 return Handle_CAP_LS(Client, Req->argv[1]);
73 if (strcasecmp(Req->argv[0], "LIST") == 0)
74 return Handle_CAP_LIST(Client, Req->argv[1]);
77 if (strcasecmp(Req->argv[0], "REQ") == 0)
78 return Handle_CAP_REQ(Client, Req->argv[1]);
79 if (strcasecmp(Req->argv[0], "ACK") == 0)
80 return Handle_CAP_ACK(Client, Req->argv[1]);
83 return IRC_WriteStrClient(Client, ERR_INVALIDCAP_MSG,
84 Client_ID(Client), Req->argv[0]);
88 * Handler for the "CAP LS" command.
90 * @param Client The client from which this command has been received.
91 * @param Arg Command argument or NULL.
92 * @returns CONNECTED or DISCONNECTED.
95 Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
97 assert(Client != NULL);
99 if (Client_Type(Client) != CLIENT_USER)
100 Client_CapAdd(Client, CLIENT_CAP_PENDING);
102 Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);
103 return IRC_WriteStrClient(Client, "CAP %s LS :", Client_ID(Client));
107 * Handler for the "CAP LIST" command.
109 * @param Client The client from which this command has been received.
110 * @param Arg Command argument or NULL.
111 * @returns CONNECTED or DISCONNECTED.
114 Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
116 assert(Client != NULL);
118 return IRC_WriteStrClient(Client, "CAP %s LIST :", Client_ID(Client));
122 * Handler for the "CAP REQ" command.
124 * @param Client The client from which this command has been received.
125 * @param Arg Command argument.
126 * @returns CONNECTED or DISCONNECTED.
129 Handle_CAP_REQ(CLIENT *Client, char *Arg)
131 assert(Client != NULL);
134 return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
135 Client_ID(Client), Arg);
139 * Handler for the "CAP ACK" command.
141 * @param Client The client from which this command has been received.
142 * @param Arg Command argument.
143 * @returns CONNECTED or DISCONNECTED.
146 Handle_CAP_ACK(CLIENT *Client, char *Arg)
148 assert(Client != NULL);
155 * Handler for the "CAP CLEAR" command.
157 * @param Client The client from which this command has been received.
158 * @returns CONNECTED or DISCONNECTED.
161 Handle_CAP_CLEAR(CLIENT *Client)
163 assert(Client != NULL);
165 return IRC_WriteStrClient(Client, "CAP %s ACK :", Client_ID(Client));
169 * Handler for the "CAP END" command.
171 * @param Client The client from which this command has been received.
172 * @returns CONNECTED or DISCONNECTED.
175 Handle_CAP_END(CLIENT *Client)
177 assert(Client != NULL);
179 if (Client_Type(Client) != CLIENT_USER) {
180 /* User is still logging in ... */
181 Client_CapDel(Client, CLIENT_CAP_PENDING);
183 if (Client_Type(Client) == CLIENT_GOTUSER) {
184 /* Only "CAP END" was missing: log in! */
185 return Login_User(Client);