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