Blame


1 c23199d9 2002-02-27 alex /*
2 c23199d9 2002-02-27 alex * ngIRCd -- The Next Generation IRC Daemon
3 c23199d9 2002-02-27 alex * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
4 c23199d9 2002-02-27 alex *
5 c23199d9 2002-02-27 alex * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
6 c23199d9 2002-02-27 alex * der GNU General Public License (GPL), wie von der Free Software Foundation
7 c23199d9 2002-02-27 alex * herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
8 c23199d9 2002-02-27 alex * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
9 c23199d9 2002-02-27 alex * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
10 c23199d9 2002-02-27 alex * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
11 c23199d9 2002-02-27 alex *
12 f3c0c7c0 2002-09-08 alex * $Id: irc-mode.c,v 1.14 2002/09/08 17:07:14 alex Exp $
13 c23199d9 2002-02-27 alex *
14 c23199d9 2002-02-27 alex * irc-mode.c: IRC-Befehle zur Mode-Aenderung (MODE, AWAY, ...)
15 c23199d9 2002-02-27 alex */
16 c23199d9 2002-02-27 alex
17 c23199d9 2002-02-27 alex
18 ca33cbda 2002-03-12 alex #include "portab.h"
19 c23199d9 2002-02-27 alex
20 ca33cbda 2002-03-12 alex #include "imp.h"
21 c23199d9 2002-02-27 alex #include <assert.h>
22 c23199d9 2002-02-27 alex #include <string.h>
23 c23199d9 2002-02-27 alex
24 c2f60abe 2002-05-27 alex #include "conn.h"
25 c2f60abe 2002-05-27 alex #include "client.h"
26 c23199d9 2002-02-27 alex #include "channel.h"
27 ca33cbda 2002-03-12 alex #include "defines.h"
28 c23199d9 2002-02-27 alex #include "irc-write.h"
29 19ac723e 2002-09-08 alex #include "lists.h"
30 c23199d9 2002-02-27 alex #include "log.h"
31 c2f60abe 2002-05-27 alex #include "parse.h"
32 c23199d9 2002-02-27 alex #include "messages.h"
33 7e1b3b91 2002-09-02 alex #include "resolve.h"
34 7e1b3b91 2002-09-02 alex #include "conf.h"
35 c23199d9 2002-02-27 alex
36 ca33cbda 2002-03-12 alex #include "exp.h"
37 c23199d9 2002-02-27 alex #include "irc-mode.h"
38 c23199d9 2002-02-27 alex
39 c23199d9 2002-02-27 alex
40 296ddebe 2002-09-08 alex LOCAL BOOLEAN Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
41 296ddebe 2002-09-08 alex LOCAL BOOLEAN Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
42 19ac723e 2002-09-08 alex
43 296ddebe 2002-09-08 alex LOCAL BOOLEAN Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
44 296ddebe 2002-09-08 alex LOCAL BOOLEAN Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
45 19ac723e 2002-09-08 alex
46 296ddebe 2002-09-08 alex LOCAL BOOLEAN Send_ListChange PARAMS(( CHAR *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Mask ));
47 19ac723e 2002-09-08 alex
48 296ddebe 2002-09-08 alex
49 c2f60abe 2002-05-27 alex GLOBAL BOOLEAN
50 c2f60abe 2002-05-27 alex IRC_MODE( CLIENT *Client, REQUEST *Req )
51 c23199d9 2002-02-27 alex {
52 c23199d9 2002-02-27 alex CHAR *mode_ptr, the_modes[CLIENT_MODE_LEN], x[2];
53 c23199d9 2002-02-27 alex CLIENT *cl, *chan_cl, *prefix;
54 7e1b3b91 2002-09-02 alex BOOLEAN set, ok, modeok;
55 c23199d9 2002-02-27 alex CHANNEL *chan;
56 c23199d9 2002-02-27 alex
57 c23199d9 2002-02-27 alex assert( Client != NULL );
58 c23199d9 2002-02-27 alex assert( Req != NULL );
59 c23199d9 2002-02-27 alex
60 c23199d9 2002-02-27 alex cl = chan_cl = prefix = NULL;
61 c23199d9 2002-02-27 alex chan = NULL;
62 c23199d9 2002-02-27 alex
63 c23199d9 2002-02-27 alex /* Valider Client? */
64 c23199d9 2002-02-27 alex if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
65 c23199d9 2002-02-27 alex
66 c23199d9 2002-02-27 alex /* Keine Parameter? */
67 c23199d9 2002-02-27 alex if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
68 c23199d9 2002-02-27 alex
69 c23199d9 2002-02-27 alex /* Ziel suchen: Client bzw. Channel */
70 c23199d9 2002-02-27 alex if( Client_IsValidNick( Req->argv[0] )) cl = Client_Search( Req->argv[0] );
71 c23199d9 2002-02-27 alex if( Channel_IsValidName( Req->argv[0] )) chan = Channel_Search( Req->argv[0] );
72 c23199d9 2002-02-27 alex
73 c23199d9 2002-02-27 alex /* Kein Ziel gefunden? */
74 c23199d9 2002-02-27 alex if(( ! cl ) && ( ! chan )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
75 c23199d9 2002-02-27 alex
76 c23199d9 2002-02-27 alex assert(( cl && chan ) != TRUE );
77 c23199d9 2002-02-27 alex
78 c23199d9 2002-02-27 alex /* Falsche Anzahl Parameter? */
79 c23199d9 2002-02-27 alex if(( cl ) && ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
80 c23199d9 2002-02-27 alex if(( chan ) && ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
81 19ac723e 2002-09-08 alex
82 19ac723e 2002-09-08 alex /* Prefix fuer Antworten etc. ermitteln */
83 19ac723e 2002-09-08 alex if( Client_Type( Client ) == CLIENT_SERVER )
84 19ac723e 2002-09-08 alex {
85 19ac723e 2002-09-08 alex prefix = Client_Search( Req->prefix );
86 19ac723e 2002-09-08 alex if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
87 19ac723e 2002-09-08 alex }
88 19ac723e 2002-09-08 alex else prefix = Client;
89 19ac723e 2002-09-08 alex
90 19ac723e 2002-09-08 alex if(( chan ) && (( Req->argc == 2 ) || ( Req->argc == 3 )))
91 19ac723e 2002-09-08 alex {
92 19ac723e 2002-09-08 alex /* pruefen, ob "Listen-Operation": Invite, Ban */
93 19ac723e 2002-09-08 alex if(( Req->argv[1][0] == '-' ) || ( Req->argv[1][0] == '+' )) mode_ptr = &Req->argv[1][1];
94 19ac723e 2002-09-08 alex else mode_ptr = &Req->argv[1][0];
95 19ac723e 2002-09-08 alex
96 19ac723e 2002-09-08 alex if( Req->argc == 2 )
97 19ac723e 2002-09-08 alex {
98 19ac723e 2002-09-08 alex /* Liste anzeigen */
99 19ac723e 2002-09-08 alex if( *mode_ptr == 'I' ) return Lists_ShowInvites( prefix, chan );
100 19ac723e 2002-09-08 alex if( *mode_ptr == 'b' ) return Lists_ShowBans( prefix, chan );
101 19ac723e 2002-09-08 alex }
102 19ac723e 2002-09-08 alex else
103 19ac723e 2002-09-08 alex {
104 c2aefbb3 2002-09-08 alex /* Listen veraendern */
105 c2aefbb3 2002-09-08 alex
106 c2aefbb3 2002-09-08 alex if( Client_Type( Client ) == CLIENT_USER )
107 c2aefbb3 2002-09-08 alex {
108 c2aefbb3 2002-09-08 alex /* Ist der User Channel-Operator? */
109 c2aefbb3 2002-09-08 alex modeok = FALSE;
110 c2aefbb3 2002-09-08 alex if( strchr( Channel_UserModes( chan, Client ), 'o' )) modeok = TRUE;
111 c2aefbb3 2002-09-08 alex if( Conf_OperCanMode )
112 c2aefbb3 2002-09-08 alex {
113 c2aefbb3 2002-09-08 alex /* auch IRC-Operatoren duerfen MODE verwenden */
114 c2aefbb3 2002-09-08 alex if( Client_OperByMe( Client )) modeok = TRUE;
115 c2aefbb3 2002-09-08 alex }
116 c2aefbb3 2002-09-08 alex
117 c2aefbb3 2002-09-08 alex if( ! modeok )
118 c2aefbb3 2002-09-08 alex {
119 c2aefbb3 2002-09-08 alex Log( LOG_DEBUG, "Can't change modes: \"%s\" is not operator on %s!", Client_ID( Client ), Channel_Name( chan ));
120 c2aefbb3 2002-09-08 alex return IRC_WriteStrClient( Client, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Client ), Channel_Name( chan ));
121 c2aefbb3 2002-09-08 alex }
122 c2aefbb3 2002-09-08 alex }
123 c2aefbb3 2002-09-08 alex
124 19ac723e 2002-09-08 alex if( Req->argv[1][0] == '+' )
125 19ac723e 2002-09-08 alex {
126 19ac723e 2002-09-08 alex /* Listen-Eintrag hinzufuegen */
127 296ddebe 2002-09-08 alex if( *mode_ptr == 'I' ) return Add_Invite( prefix, Client, chan, Req->argv[2] );
128 296ddebe 2002-09-08 alex if( *mode_ptr == 'b' ) return Add_Ban( prefix, Client, chan, Req->argv[2] );
129 19ac723e 2002-09-08 alex }
130 19ac723e 2002-09-08 alex else if( Req->argv[1][0] == '-' )
131 19ac723e 2002-09-08 alex {
132 19ac723e 2002-09-08 alex /* Listen-Eintrag loeschen */
133 296ddebe 2002-09-08 alex if( *mode_ptr == 'I' ) return Del_Invite( prefix, Client, chan, Req->argv[2] );
134 296ddebe 2002-09-08 alex if( *mode_ptr == 'b' ) return Del_Ban( prefix, Client, chan, Req->argv[2] );
135 19ac723e 2002-09-08 alex }
136 19ac723e 2002-09-08 alex }
137 19ac723e 2002-09-08 alex }
138 c23199d9 2002-02-27 alex
139 c23199d9 2002-02-27 alex /* Client ermitteln, wenn bei Channel-Modes mit 3 Parametern */
140 c23199d9 2002-02-27 alex if(( chan ) && (Req->argc == 3 ))
141 c23199d9 2002-02-27 alex {
142 c23199d9 2002-02-27 alex chan_cl = Client_Search( Req->argv[2] );
143 c23199d9 2002-02-27 alex if( ! chan_cl ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
144 c23199d9 2002-02-27 alex }
145 c23199d9 2002-02-27 alex
146 c23199d9 2002-02-27 alex /* Wenn Anfragender ein User ist: Zugriff erlaubt? */
147 c23199d9 2002-02-27 alex if( Client_Type( Client ) == CLIENT_USER )
148 c23199d9 2002-02-27 alex {
149 c23199d9 2002-02-27 alex if( cl )
150 c23199d9 2002-02-27 alex {
151 c23199d9 2002-02-27 alex /* MODE ist nur fuer sich selber zulaessig! */
152 c23199d9 2002-02-27 alex if( cl != Client ) return IRC_WriteStrClient( Client, ERR_USERSDONTMATCH_MSG, Client_ID( Client ));
153 c23199d9 2002-02-27 alex }
154 c23199d9 2002-02-27 alex if( chan )
155 c23199d9 2002-02-27 alex {
156 c23199d9 2002-02-27 alex /* Darf der User die Channel-Modes ermitteln? */
157 c23199d9 2002-02-27 alex }
158 c23199d9 2002-02-27 alex }
159 c23199d9 2002-02-27 alex
160 c23199d9 2002-02-27 alex /* Werden die Modes "nur" erfragt? */
161 c23199d9 2002-02-27 alex if(( cl ) && ( Req->argc == 1 )) return IRC_WriteStrClient( Client, RPL_UMODEIS_MSG, Client_ID( Client ), Client_Modes( cl ));
162 c23199d9 2002-02-27 alex if(( chan ) && ( Req->argc == 1 )) return IRC_WriteStrClient( Client, RPL_CHANNELMODEIS_MSG, Client_ID( Client ), Channel_Name( chan ), Channel_Modes( chan ));
163 c23199d9 2002-02-27 alex
164 c23199d9 2002-02-27 alex mode_ptr = Req->argv[1];
165 c23199d9 2002-02-27 alex
166 c23199d9 2002-02-27 alex /* Sollen Modes gesetzt oder geloescht werden? */
167 c23199d9 2002-02-27 alex if( cl )
168 c23199d9 2002-02-27 alex {
169 c23199d9 2002-02-27 alex if( *mode_ptr == '+' ) set = TRUE;
170 c23199d9 2002-02-27 alex else if( *mode_ptr == '-' ) set = FALSE;
171 c23199d9 2002-02-27 alex else return IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
172 c23199d9 2002-02-27 alex mode_ptr++;
173 c23199d9 2002-02-27 alex }
174 c23199d9 2002-02-27 alex else
175 c23199d9 2002-02-27 alex {
176 c23199d9 2002-02-27 alex if( *mode_ptr == '-' ) set = FALSE;
177 c23199d9 2002-02-27 alex else set = TRUE;
178 c23199d9 2002-02-27 alex if(( *mode_ptr == '-' ) || ( *mode_ptr == '+' )) mode_ptr++;
179 7d30c8ce 2002-08-26 alex }
180 c23199d9 2002-02-27 alex
181 c23199d9 2002-02-27 alex /* Reply-String mit Aenderungen vorbereiten */
182 c23199d9 2002-02-27 alex if( set ) strcpy( the_modes, "+" );
183 c23199d9 2002-02-27 alex else strcpy( the_modes, "-" );
184 c23199d9 2002-02-27 alex
185 c23199d9 2002-02-27 alex ok = TRUE;
186 c23199d9 2002-02-27 alex x[1] = '\0';
187 c23199d9 2002-02-27 alex while( *mode_ptr )
188 c23199d9 2002-02-27 alex {
189 c23199d9 2002-02-27 alex x[0] = '\0';
190 c23199d9 2002-02-27 alex if( Client_Type( Client ) == CLIENT_SERVER )
191 c23199d9 2002-02-27 alex {
192 c23199d9 2002-02-27 alex /* Befehl kommt von einem Server, daher
193 c23199d9 2002-02-27 alex * trauen wir ihm "unbesehen" ... */
194 c23199d9 2002-02-27 alex x[0] = *mode_ptr;
195 c23199d9 2002-02-27 alex }
196 c23199d9 2002-02-27 alex else
197 c23199d9 2002-02-27 alex {
198 c23199d9 2002-02-27 alex /* Modes validieren */
199 c23199d9 2002-02-27 alex if( cl )
200 c23199d9 2002-02-27 alex {
201 c23199d9 2002-02-27 alex /* User-Modes */
202 c23199d9 2002-02-27 alex switch( *mode_ptr )
203 c23199d9 2002-02-27 alex {
204 c23199d9 2002-02-27 alex case 'i':
205 c23199d9 2002-02-27 alex /* invisible */
206 c23199d9 2002-02-27 alex x[0] = 'i';
207 c23199d9 2002-02-27 alex break;
208 c23199d9 2002-02-27 alex case 'o':
209 c23199d9 2002-02-27 alex /* operator (kann nur geloescht werden) */
210 c23199d9 2002-02-27 alex if( ! set )
211 c23199d9 2002-02-27 alex {
212 c23199d9 2002-02-27 alex Client_SetOperByMe( Client, FALSE );
213 c23199d9 2002-02-27 alex x[0] = 'o';
214 c23199d9 2002-02-27 alex }
215 c23199d9 2002-02-27 alex else ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
216 c23199d9 2002-02-27 alex break;
217 c2f60abe 2002-05-27 alex case 'r':
218 c2f60abe 2002-05-27 alex /* restricted (kann nur gesetzt werden) */
219 c2f60abe 2002-05-27 alex if( set ) x[0] = 'r';
220 c2f60abe 2002-05-27 alex else ok = IRC_WriteStrClient( Client, ERR_RESTRICTED_MSG, Client_ID( Client ));
221 c2f60abe 2002-05-27 alex break;
222 d4fca86a 2002-03-25 alex case 's':
223 d4fca86a 2002-03-25 alex /* server messages */
224 d4fca86a 2002-03-25 alex x[0] = 's';
225 d4fca86a 2002-03-25 alex break;
226 c23199d9 2002-02-27 alex default:
227 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ));
228 c23199d9 2002-02-27 alex ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );
229 c23199d9 2002-02-27 alex x[0] = '\0';
230 c23199d9 2002-02-27 alex }
231 c23199d9 2002-02-27 alex }
232 c23199d9 2002-02-27 alex if( chan )
233 c23199d9 2002-02-27 alex {
234 c23199d9 2002-02-27 alex /* Ist der User ein Channel Operator? */
235 7e1b3b91 2002-09-02 alex modeok = FALSE;
236 7e1b3b91 2002-09-02 alex if( strchr( Channel_UserModes( chan, Client ), 'o' )) modeok = TRUE;
237 7e1b3b91 2002-09-02 alex if( Conf_OperCanMode )
238 c23199d9 2002-02-27 alex {
239 7e1b3b91 2002-09-02 alex /* auch IRC-Operatoren duerfen MODE verwenden */
240 7e1b3b91 2002-09-02 alex if( Client_OperByMe( Client )) modeok = TRUE;
241 7e1b3b91 2002-09-02 alex }
242 7e1b3b91 2002-09-02 alex
243 7e1b3b91 2002-09-02 alex if( ! modeok )
244 7e1b3b91 2002-09-02 alex {
245 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "Can't change modes: \"%s\" is not operator on %s!", Client_ID( Client ), Channel_Name( chan ));
246 c23199d9 2002-02-27 alex ok = IRC_WriteStrClient( Client, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Client ), Channel_Name( chan ));
247 c23199d9 2002-02-27 alex break;
248 c23199d9 2002-02-27 alex }
249 c23199d9 2002-02-27 alex
250 c23199d9 2002-02-27 alex /* Channel-Modes oder Channel-User-Modes */
251 c23199d9 2002-02-27 alex if( chan_cl )
252 c23199d9 2002-02-27 alex {
253 c23199d9 2002-02-27 alex /* Channel-User-Modes */
254 c23199d9 2002-02-27 alex switch( *mode_ptr )
255 c23199d9 2002-02-27 alex {
256 c23199d9 2002-02-27 alex case 'o':
257 c23199d9 2002-02-27 alex /* Channel Operator */
258 c23199d9 2002-02-27 alex x[0] = 'o';
259 c23199d9 2002-02-27 alex break;
260 c23199d9 2002-02-27 alex case 'v':
261 c23199d9 2002-02-27 alex /* Voice */
262 c23199d9 2002-02-27 alex x[0] = 'v';
263 c23199d9 2002-02-27 alex break;
264 c23199d9 2002-02-27 alex default:
265 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "Unknown channel-user-mode \"%c%c\" from \"%s\" on \"%s\" at %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ), Client_ID( chan_cl ), Channel_Name( chan ));
266 c23199d9 2002-02-27 alex ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );
267 c23199d9 2002-02-27 alex x[0] = '\0';
268 c23199d9 2002-02-27 alex }
269 c23199d9 2002-02-27 alex }
270 c23199d9 2002-02-27 alex else
271 c23199d9 2002-02-27 alex {
272 c23199d9 2002-02-27 alex /* Channel-Modes */
273 c23199d9 2002-02-27 alex switch( *mode_ptr )
274 c23199d9 2002-02-27 alex {
275 c2f60abe 2002-05-27 alex case 'i':
276 c2f60abe 2002-05-27 alex /* Invite-Only */
277 c2f60abe 2002-05-27 alex x[0] = 'i';
278 c2f60abe 2002-05-27 alex break;
279 c23199d9 2002-02-27 alex case 'm':
280 c23199d9 2002-02-27 alex /* Moderated */
281 c23199d9 2002-02-27 alex x[0] = 'm';
282 c23199d9 2002-02-27 alex break;
283 c23199d9 2002-02-27 alex case 'n':
284 c23199d9 2002-02-27 alex /* kein Schreiben in den Channel von aussen */
285 c23199d9 2002-02-27 alex x[0] = 'n';
286 c23199d9 2002-02-27 alex break;
287 c23199d9 2002-02-27 alex case 't':
288 c23199d9 2002-02-27 alex /* Topic Lock */
289 c23199d9 2002-02-27 alex x[0] = 't';
290 040f5422 2002-05-21 alex break;
291 040f5422 2002-05-21 alex case 'P':
292 040f5422 2002-05-21 alex /* Persistent */
293 040f5422 2002-05-21 alex x[0] = 'P';
294 c23199d9 2002-02-27 alex break;
295 c23199d9 2002-02-27 alex default:
296 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "Unknown channel-mode \"%c%c\" from \"%s\" at %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ), Channel_Name( chan ));
297 c23199d9 2002-02-27 alex ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );
298 c23199d9 2002-02-27 alex x[0] = '\0';
299 c23199d9 2002-02-27 alex }
300 c23199d9 2002-02-27 alex }
301 c23199d9 2002-02-27 alex }
302 c23199d9 2002-02-27 alex }
303 c23199d9 2002-02-27 alex if( ! ok ) break;
304 c23199d9 2002-02-27 alex
305 c23199d9 2002-02-27 alex mode_ptr++;
306 c23199d9 2002-02-27 alex if( ! x[0] ) continue;
307 c23199d9 2002-02-27 alex
308 c23199d9 2002-02-27 alex /* Okay, gueltigen Mode gefunden */
309 c23199d9 2002-02-27 alex if( cl )
310 c23199d9 2002-02-27 alex {
311 c23199d9 2002-02-27 alex /* Es geht um User-Modes */
312 c23199d9 2002-02-27 alex if( set )
313 c23199d9 2002-02-27 alex {
314 c23199d9 2002-02-27 alex /* Mode setzen. Wenn der Client ihn noch nicht hatte: merken */
315 c23199d9 2002-02-27 alex if( Client_ModeAdd( cl, x[0] )) strcat( the_modes, x );
316 802a17b1 2002-03-04 alex
317 c23199d9 2002-02-27 alex }
318 c23199d9 2002-02-27 alex else
319 c23199d9 2002-02-27 alex {
320 c23199d9 2002-02-27 alex /* Modes geloescht. Wenn der Client ihn hatte: merken */
321 c23199d9 2002-02-27 alex if( Client_ModeDel( cl, x[0] )) strcat( the_modes, x );
322 c23199d9 2002-02-27 alex }
323 802a17b1 2002-03-04 alex
324 802a17b1 2002-03-04 alex /* "nachbearbeiten" */
325 802a17b1 2002-03-04 alex if( x[0] == 'a' )
326 802a17b1 2002-03-04 alex {
327 802a17b1 2002-03-04 alex /* away */
328 802a17b1 2002-03-04 alex if( set ) Client_SetAway( cl, DEFAULT_AWAY_MSG );
329 802a17b1 2002-03-04 alex else Client_SetAway( cl, NULL );
330 802a17b1 2002-03-04 alex }
331 c23199d9 2002-02-27 alex }
332 c23199d9 2002-02-27 alex if( chan )
333 c23199d9 2002-02-27 alex {
334 c23199d9 2002-02-27 alex /* Es geht um Channel-Modes oder Channel-User-Modes */
335 c23199d9 2002-02-27 alex if( chan_cl )
336 c23199d9 2002-02-27 alex {
337 c23199d9 2002-02-27 alex /* Channel-User-Modes */
338 c23199d9 2002-02-27 alex if( set )
339 c23199d9 2002-02-27 alex {
340 c23199d9 2002-02-27 alex /* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
341 c23199d9 2002-02-27 alex if( Channel_UserModeAdd( chan, chan_cl, x[0] )) strcat( the_modes, x );
342 c23199d9 2002-02-27 alex }
343 c23199d9 2002-02-27 alex else
344 c23199d9 2002-02-27 alex {
345 c23199d9 2002-02-27 alex /* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
346 c23199d9 2002-02-27 alex if( Channel_UserModeDel( chan, chan_cl, x[0] )) strcat( the_modes, x );
347 c23199d9 2002-02-27 alex }
348 c23199d9 2002-02-27 alex }
349 c23199d9 2002-02-27 alex else
350 c23199d9 2002-02-27 alex {
351 c23199d9 2002-02-27 alex /* Channel-Mode */
352 c23199d9 2002-02-27 alex if( set )
353 c23199d9 2002-02-27 alex {
354 c23199d9 2002-02-27 alex /* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
355 c23199d9 2002-02-27 alex if( Channel_ModeAdd( chan, x[0] )) strcat( the_modes, x );
356 c23199d9 2002-02-27 alex }
357 c23199d9 2002-02-27 alex else
358 c23199d9 2002-02-27 alex {
359 c23199d9 2002-02-27 alex /* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
360 c23199d9 2002-02-27 alex if( Channel_ModeDel( chan, x[0] )) strcat( the_modes, x );
361 c23199d9 2002-02-27 alex }
362 c23199d9 2002-02-27 alex }
363 c23199d9 2002-02-27 alex }
364 c23199d9 2002-02-27 alex }
365 c23199d9 2002-02-27 alex
366 c23199d9 2002-02-27 alex /* Wurden Modes geaendert? */
367 c23199d9 2002-02-27 alex if( the_modes[1] )
368 c23199d9 2002-02-27 alex {
369 c23199d9 2002-02-27 alex if( cl )
370 c23199d9 2002-02-27 alex {
371 c23199d9 2002-02-27 alex /* Client-Mode */
372 c23199d9 2002-02-27 alex if( Client_Type( Client ) == CLIENT_SERVER )
373 c23199d9 2002-02-27 alex {
374 c23199d9 2002-02-27 alex /* Modes an andere Server forwarden */
375 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Client_ID( cl ), the_modes );
376 c23199d9 2002-02-27 alex }
377 c23199d9 2002-02-27 alex else
378 c23199d9 2002-02-27 alex {
379 c23199d9 2002-02-27 alex /* Bestaetigung an Client schicken & andere Server informieren */
380 c23199d9 2002-02-27 alex ok = IRC_WriteStrClientPrefix( Client, prefix, "MODE %s %s", Client_ID( cl ), the_modes );
381 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Client_ID( cl ), the_modes );
382 c23199d9 2002-02-27 alex }
383 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( cl ), Client_Modes( cl ));
384 c23199d9 2002-02-27 alex }
385 c23199d9 2002-02-27 alex if( chan )
386 c23199d9 2002-02-27 alex {
387 c23199d9 2002-02-27 alex /* Channel-Modes oder Channel-User-Mode */
388 c23199d9 2002-02-27 alex if( chan_cl )
389 c23199d9 2002-02-27 alex {
390 c23199d9 2002-02-27 alex /* Channel-User-Mode */
391 c23199d9 2002-02-27 alex if( Client_Type( Client ) == CLIENT_SERVER )
392 c23199d9 2002-02-27 alex {
393 c23199d9 2002-02-27 alex /* Modes an andere Server und Channel-User forwarden */
394 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, prefix, "MODE %s %s :%s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
395 c23199d9 2002-02-27 alex IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s %s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
396 c23199d9 2002-02-27 alex }
397 c23199d9 2002-02-27 alex else
398 c23199d9 2002-02-27 alex {
399 c23199d9 2002-02-27 alex /* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
400 c23199d9 2002-02-27 alex ok = IRC_WriteStrClientPrefix( Client, prefix, "MODE %s %s %s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
401 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, prefix, "MODE %s %s :%s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
402 c23199d9 2002-02-27 alex IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s %s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
403 c23199d9 2002-02-27 alex }
404 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "User \"%s\" on %s: Mode change, now \"%s\".", Client_Mask( chan_cl), Channel_Name( chan ), Channel_UserModes( chan, chan_cl ));
405 c23199d9 2002-02-27 alex }
406 c23199d9 2002-02-27 alex else
407 c23199d9 2002-02-27 alex {
408 c23199d9 2002-02-27 alex /* Channel-Mode */
409 c23199d9 2002-02-27 alex if( Client_Type( Client ) == CLIENT_SERVER )
410 c23199d9 2002-02-27 alex {
411 c23199d9 2002-02-27 alex /* Modes an andere Server und Channel-User forwarden */
412 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Channel_Name( chan ), the_modes );
413 c23199d9 2002-02-27 alex IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s", Channel_Name( chan ), the_modes );
414 c23199d9 2002-02-27 alex }
415 c23199d9 2002-02-27 alex else
416 c23199d9 2002-02-27 alex {
417 c23199d9 2002-02-27 alex /* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
418 c23199d9 2002-02-27 alex ok = IRC_WriteStrClientPrefix( Client, prefix, "MODE %s %s", Channel_Name( chan ), the_modes );
419 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Channel_Name( chan ), the_modes );
420 c23199d9 2002-02-27 alex IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s", Channel_Name( chan ), the_modes );
421 c23199d9 2002-02-27 alex }
422 c23199d9 2002-02-27 alex Log( LOG_DEBUG, "Channel \"%s\": Mode change, now \"%s\".", Channel_Name( chan ), Channel_Modes( chan ));
423 c23199d9 2002-02-27 alex }
424 c23199d9 2002-02-27 alex }
425 c23199d9 2002-02-27 alex }
426 c23199d9 2002-02-27 alex
427 c23199d9 2002-02-27 alex return ok;
428 c23199d9 2002-02-27 alex } /* IRC_MODE */
429 c23199d9 2002-02-27 alex
430 c23199d9 2002-02-27 alex
431 c2f60abe 2002-05-27 alex GLOBAL BOOLEAN
432 c2f60abe 2002-05-27 alex IRC_AWAY( CLIENT *Client, REQUEST *Req )
433 c23199d9 2002-02-27 alex {
434 c23199d9 2002-02-27 alex assert( Client != NULL );
435 c23199d9 2002-02-27 alex assert( Req != NULL );
436 c23199d9 2002-02-27 alex
437 c23199d9 2002-02-27 alex if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
438 c23199d9 2002-02-27 alex
439 c23199d9 2002-02-27 alex /* Falsche Anzahl Parameter? */
440 c23199d9 2002-02-27 alex if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
441 c23199d9 2002-02-27 alex
442 c23199d9 2002-02-27 alex if(( Req->argc == 1 ) && (Req->argv[0][0] ))
443 c23199d9 2002-02-27 alex {
444 c23199d9 2002-02-27 alex /* AWAY setzen */
445 c23199d9 2002-02-27 alex Client_SetAway( Client, Req->argv[0] );
446 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client ));
447 c23199d9 2002-02-27 alex return IRC_WriteStrClient( Client, RPL_NOWAWAY_MSG, Client_ID( Client ));
448 c23199d9 2002-02-27 alex }
449 c23199d9 2002-02-27 alex else
450 c23199d9 2002-02-27 alex {
451 c23199d9 2002-02-27 alex /* AWAY loeschen */
452 c23199d9 2002-02-27 alex Client_SetAway( Client, NULL );
453 c23199d9 2002-02-27 alex IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client ));
454 c23199d9 2002-02-27 alex return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client ));
455 c23199d9 2002-02-27 alex }
456 c23199d9 2002-02-27 alex } /* IRC_AWAY */
457 19ac723e 2002-09-08 alex
458 19ac723e 2002-09-08 alex
459 19ac723e 2002-09-08 alex LOCAL BOOLEAN
460 296ddebe 2002-09-08 alex Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
461 19ac723e 2002-09-08 alex {
462 19ac723e 2002-09-08 alex CHAR *mask;
463 19ac723e 2002-09-08 alex
464 19ac723e 2002-09-08 alex assert( Client != NULL );
465 19ac723e 2002-09-08 alex assert( Channel != NULL );
466 19ac723e 2002-09-08 alex assert( Pattern != NULL );
467 c23199d9 2002-02-27 alex
468 19ac723e 2002-09-08 alex mask = Lists_MakeMask( Pattern );
469 c23199d9 2002-02-27 alex
470 f3c0c7c0 2002-09-08 alex if( ! Lists_AddInvited( Prefix, mask, Channel, FALSE )) return CONNECTED;
471 296ddebe 2002-09-08 alex return Send_ListChange( "+I", Prefix, Client, Channel, mask );
472 19ac723e 2002-09-08 alex } /* Add_Invite */
473 19ac723e 2002-09-08 alex
474 19ac723e 2002-09-08 alex
475 19ac723e 2002-09-08 alex LOCAL BOOLEAN
476 296ddebe 2002-09-08 alex Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
477 19ac723e 2002-09-08 alex {
478 19ac723e 2002-09-08 alex CHAR *mask;
479 19ac723e 2002-09-08 alex
480 19ac723e 2002-09-08 alex assert( Client != NULL );
481 19ac723e 2002-09-08 alex assert( Channel != NULL );
482 19ac723e 2002-09-08 alex assert( Pattern != NULL );
483 19ac723e 2002-09-08 alex
484 19ac723e 2002-09-08 alex mask = Lists_MakeMask( Pattern );
485 19ac723e 2002-09-08 alex
486 f3c0c7c0 2002-09-08 alex if( ! Lists_AddBanned( Prefix, mask, Channel )) return CONNECTED;
487 296ddebe 2002-09-08 alex return Send_ListChange( "+b", Prefix, Client, Channel, mask );
488 19ac723e 2002-09-08 alex } /* Add_Ban */
489 19ac723e 2002-09-08 alex
490 19ac723e 2002-09-08 alex
491 19ac723e 2002-09-08 alex LOCAL BOOLEAN
492 296ddebe 2002-09-08 alex Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
493 19ac723e 2002-09-08 alex {
494 19ac723e 2002-09-08 alex CHAR *mask;
495 19ac723e 2002-09-08 alex
496 19ac723e 2002-09-08 alex assert( Client != NULL );
497 19ac723e 2002-09-08 alex assert( Channel != NULL );
498 19ac723e 2002-09-08 alex assert( Pattern != NULL );
499 19ac723e 2002-09-08 alex
500 19ac723e 2002-09-08 alex mask = Lists_MakeMask( Pattern );
501 19ac723e 2002-09-08 alex Lists_DelInvited( mask, Channel );
502 296ddebe 2002-09-08 alex return Send_ListChange( "-I", Prefix, Client, Channel, mask );
503 19ac723e 2002-09-08 alex } /* Del_Invite */
504 19ac723e 2002-09-08 alex
505 19ac723e 2002-09-08 alex
506 19ac723e 2002-09-08 alex LOCAL BOOLEAN
507 296ddebe 2002-09-08 alex Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
508 19ac723e 2002-09-08 alex {
509 19ac723e 2002-09-08 alex CHAR *mask;
510 19ac723e 2002-09-08 alex
511 19ac723e 2002-09-08 alex assert( Client != NULL );
512 19ac723e 2002-09-08 alex assert( Channel != NULL );
513 19ac723e 2002-09-08 alex assert( Pattern != NULL );
514 19ac723e 2002-09-08 alex
515 19ac723e 2002-09-08 alex mask = Lists_MakeMask( Pattern );
516 19ac723e 2002-09-08 alex Lists_DelBanned( mask, Channel );
517 296ddebe 2002-09-08 alex return Send_ListChange( "-b", Prefix, Client, Channel, mask );
518 296ddebe 2002-09-08 alex } /* Del_Ban */
519 19ac723e 2002-09-08 alex
520 296ddebe 2002-09-08 alex
521 296ddebe 2002-09-08 alex LOCAL BOOLEAN
522 296ddebe 2002-09-08 alex Send_ListChange( CHAR *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Mask )
523 296ddebe 2002-09-08 alex {
524 296ddebe 2002-09-08 alex /* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
525 296ddebe 2002-09-08 alex
526 296ddebe 2002-09-08 alex BOOLEAN ok;
527 296ddebe 2002-09-08 alex
528 19ac723e 2002-09-08 alex if( Client_Type( Client ) == CLIENT_USER )
529 19ac723e 2002-09-08 alex {
530 296ddebe 2002-09-08 alex /* Bestaetigung an Client */
531 296ddebe 2002-09-08 alex ok = IRC_WriteStrClientPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
532 19ac723e 2002-09-08 alex }
533 296ddebe 2002-09-08 alex else ok = TRUE;
534 19ac723e 2002-09-08 alex
535 296ddebe 2002-09-08 alex /* an andere Server */
536 296ddebe 2002-09-08 alex IRC_WriteStrServersPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
537 19ac723e 2002-09-08 alex
538 296ddebe 2002-09-08 alex /* und lokale User im Channel */
539 296ddebe 2002-09-08 alex IRC_WriteStrChannelPrefix( Client, Channel, Prefix, FALSE, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
540 296ddebe 2002-09-08 alex
541 296ddebe 2002-09-08 alex return ok;
542 296ddebe 2002-09-08 alex } /* Send_ListChange */
543 296ddebe 2002-09-08 alex
544 296ddebe 2002-09-08 alex
545 c23199d9 2002-02-27 alex /* -eof- */