]> arthur.barton.de Git - ngircd-alex.git/blob - src/ngircd/irc-cap.c
Implement core IRC capability handling and "CAP" command
[ngircd-alex.git] / src / ngircd / irc-cap.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
4  *
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.
10  */
11
12 #include "portab.h"
13
14 /**
15  * @file
16  * Handler for IRC capability ("CAP") commands
17  */
18
19 #include "imp.h"
20 #include <assert.h>
21 #include <string.h>
22
23 #include "defines.h"
24 #include "conn.h"
25 #include "channel.h"
26 #include "client-cap.h"
27 #include "irc-write.h"
28 #include "log.h"
29 #include "login.h"
30 #include "messages.h"
31 #include "parse.h"
32
33 #include "exp.h"
34 #include "irc-cap.h"
35
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));
42
43 /**
44  * Handler for the IRCv3 "CAP" command.
45  *
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.
49  */
50 GLOBAL bool
51 IRC_CAP(CLIENT *Client, REQUEST *Req)
52 {
53         assert(Client != NULL);
54         assert(Req != NULL);
55
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);
60
61         LogDebug("Got \"%s %s\" command from \"%s\" ...",
62                  Req->command, Req->argv[0], Client_ID(Client));
63
64         if (Req->argc == 1) {
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);
69         }
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]);
75         }
76         if (Req->argc == 2) {
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]);
81         }
82
83         return IRC_WriteStrClient(Client, ERR_INVALIDCAP_MSG,
84                                   Client_ID(Client), Req->argv[0]);
85 }
86
87 /**
88  * Handler for the "CAP LS" command.
89  *
90  * @param Client The client from which this command has been received.
91  * @param Arg Command argument or NULL.
92  * @returns CONNECTED or DISCONNECTED.
93  */
94 bool
95 Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
96 {
97         assert(Client != NULL);
98
99         if (Client_Type(Client) != CLIENT_USER)
100                 Client_CapAdd(Client, CLIENT_CAP_PENDING);
101
102         Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);
103         return IRC_WriteStrClient(Client, "CAP %s LS :", Client_ID(Client));
104 }
105
106 /**
107  * Handler for the "CAP LIST" command.
108  *
109  * @param Client The client from which this command has been received.
110  * @param Arg Command argument or NULL.
111  * @returns CONNECTED or DISCONNECTED.
112  */
113 bool
114 Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
115 {
116         assert(Client != NULL);
117
118         return IRC_WriteStrClient(Client, "CAP %s LIST :", Client_ID(Client));
119 }
120
121 /**
122  * Handler for the "CAP REQ" command.
123  *
124  * @param Client The client from which this command has been received.
125  * @param Arg Command argument.
126  * @returns CONNECTED or DISCONNECTED.
127  */
128 bool
129 Handle_CAP_REQ(CLIENT *Client, char *Arg)
130 {
131         assert(Client != NULL);
132         assert(Arg != NULL);
133
134         return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
135                                   Client_ID(Client), Arg);
136 }
137
138 /**
139  * Handler for the "CAP ACK" command.
140  *
141  * @param Client The client from which this command has been received.
142  * @param Arg Command argument.
143  * @returns CONNECTED or DISCONNECTED.
144  */
145 bool
146 Handle_CAP_ACK(CLIENT *Client, char *Arg)
147 {
148         assert(Client != NULL);
149         assert(Arg != NULL);
150
151         return CONNECTED;
152 }
153
154 /**
155  * Handler for the "CAP CLEAR" command.
156  *
157  * @param Client The client from which this command has been received.
158  * @returns CONNECTED or DISCONNECTED.
159  */
160 bool
161 Handle_CAP_CLEAR(CLIENT *Client)
162 {
163         assert(Client != NULL);
164
165         return IRC_WriteStrClient(Client, "CAP %s ACK :", Client_ID(Client));
166 }
167
168 /**
169  * Handler for the "CAP END" command.
170  *
171  * @param Client The client from which this command has been received.
172  * @returns CONNECTED or DISCONNECTED.
173  */
174 bool
175 Handle_CAP_END(CLIENT *Client)
176 {
177         assert(Client != NULL);
178
179         if (Client_Type(Client) != CLIENT_USER) {
180                 /* User is still logging in ... */
181                 Client_CapDel(Client, CLIENT_CAP_PENDING);
182
183                 if (Client_Type(Client) == CLIENT_GOTUSER) {
184                         /* Only "CAP END" was missing: log in! */
185                         return Login_User(Client);
186                 }
187         }
188
189         return CONNECTED;
190 }
191
192 /* -eof- */