2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
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.
11 * Sending IRC commands over the network
17 static char UNUSED id[] = "$Id: irc-write.c,v 1.18 2005/04/27 07:39:18 alex Exp $";
30 #include "conn-func.h"
35 #include "irc-write.h"
38 #define SEND_TO_USER 1
39 #define SEND_TO_SERVER 2
42 LOCAL char *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client ));
47 IRC_WriteStrClient( CLIENT *Client, char *Format, ... )
50 IRC_WriteStrClient( Client, Format, va_alist )
60 assert( Client != NULL );
61 assert( Format != NULL );
64 va_start( ap, Format );
68 vsnprintf( buffer, 1000, Format, ap );
71 /* an den Client selber */
72 ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
75 } /* IRC_WriteStrClient */
80 IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, char *Format, ... )
83 IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
90 /* Text an Clients, lokal bzw. remote, senden. */
95 assert( Client != NULL );
96 assert( Format != NULL );
97 assert( Prefix != NULL );
100 va_start( ap, Format );
104 vsnprintf( buffer, 1000, Format, ap );
107 return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
108 } /* IRC_WriteStrClientPrefix */
113 IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, bool Remote, char *Format, ... )
116 IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
127 assert( Client != NULL );
128 assert( Format != NULL );
131 va_start( ap, Format );
135 vsnprintf( buffer, 1000, Format, ap );
138 return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, "%s", buffer );
139 } /* IRC_WriteStrChannel */
144 IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, bool Remote, char *Format, ... )
147 IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
163 assert( Client != NULL );
164 assert( Chan != NULL );
165 assert( Prefix != NULL );
166 assert( Format != NULL );
169 va_start( ap, Format );
173 vsnprintf( buffer, 1000, Format, ap );
178 /* An alle Clients, die in den selben Channels sind.
179 * Dabei aber nur einmal je Remote-Server */
180 cl2chan = Channel_FirstMember( Chan );
183 c = Channel_GetClient( cl2chan );
186 if( Client_Conn( c ) <= NONE ) c = NULL;
187 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
189 if( c ) c = Client_NextHop( c );
191 if( c && ( c != Client ))
193 /* Ok, anderer Client */
194 conn = Client_Conn( c );
195 if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
196 else Conn_SetFlag( conn, SEND_TO_USER );
198 cl2chan = Channel_NextMember( Chan, cl2chan );
201 /* Senden: alle Verbindungen durchgehen ... */
202 conn = Conn_First( );
203 while( conn != NONE )
205 /* muessen Daten ueber diese Verbindung verschickt werden? */
206 if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
207 else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
210 /* naechste Verbindung testen */
211 conn = Conn_Next( conn );
215 } /* IRC_WriteStrChannelPrefix */
220 IRC_WriteStrServers( CLIENT *ExceptOf, char *Format, ... )
223 IRC_WriteStrServers( ExceptOf, Format, va_alist )
232 assert( Format != NULL );
235 va_start( ap, Format );
239 vsnprintf( buffer, 1000, Format, ap );
242 /* an den Client selber */
243 IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
244 } /* IRC_WriteStrServers */
249 IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, char *Format, ... )
252 IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
262 assert( Format != NULL );
263 assert( Prefix != NULL );
266 va_start( ap, Format );
270 vsnprintf( buffer, 1000, Format, ap );
273 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
274 } /* IRC_WriteStrServersPrefix */
279 IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, char Flag, char *Format, ... )
282 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
294 assert( Format != NULL );
295 assert( Prefix != NULL );
298 va_start( ap, Format );
302 vsnprintf( buffer, 1000, Format, ap );
308 if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
310 /* Ziel-Server gefunden. Nun noch pruefen, ob Flags stimmen */
311 if(( Flag == '\0' ) || ( strchr( Client_Flags( c ), Flag ) != NULL )) IRC_WriteStrClientPrefix( c, Prefix, "%s", buffer );
313 c = Client_Next( c );
315 } /* IRC_WriteStrServersPrefixFlag */
320 IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, bool Remote, char *Format, ... )
323 IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
332 CL2CHAN *chan_cl2chan, *cl2chan;
339 assert( Client != NULL );
340 assert( Prefix != NULL );
341 assert( Format != NULL );
344 va_start( ap, Format );
348 vsnprintf( buffer, 1000, Format, ap );
354 /* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
355 * den Text schicken. An Remote-Server aber jeweils nur einmal. */
356 chan_cl2chan = Channel_FirstChannelOf( Client );
357 while( chan_cl2chan )
359 /* Channel des Users durchsuchen */
360 chan = Channel_GetChannel( chan_cl2chan );
361 cl2chan = Channel_FirstMember( chan );
364 c = Channel_GetClient( cl2chan );
367 if( Client_Conn( c ) <= NONE ) c = NULL;
368 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
370 if( c ) c = Client_NextHop( c );
372 if( c && ( c != Client ))
374 /* Ok, anderer Client */
375 conn = Client_Conn( c );
376 if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
377 else Conn_SetFlag( conn, SEND_TO_USER );
379 cl2chan = Channel_NextMember( chan, cl2chan );
382 /* naechsten Channel */
383 chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
386 /* Senden: alle Verbindungen durchgehen ... */
387 conn = Conn_First( );
388 while( conn != NONE )
390 /* muessen ueber diese Verbindung Daten gesendet werden? */
391 if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
392 else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
395 /* naechste Verbindung testen */
396 conn = Conn_Next( conn );
399 } /* IRC_WriteStrRelatedPrefix */
403 IRC_SetPenalty( CLIENT *Client, int Seconds )
407 assert( Client != NULL );
408 assert( Seconds > 0 );
410 if( Client_Type( Client ) == CLIENT_SERVER ) return;
412 c = Client_Conn( Client );
413 if( c > NONE ) Conn_SetPenalty( c, Seconds );
414 } /* IRC_SetPenalty */
418 Get_Prefix( CLIENT *Target, CLIENT *Client )
420 assert( Target != NULL );
421 assert( Client != NULL );
423 if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
424 else return Client_Mask( Client );