2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
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.
12 * $Id: irc-write.c,v 1.12 2002/11/04 13:26:00 alex Exp $
14 * irc-write.c: IRC-Texte und Befehle ueber Netzwerk versenden
32 #include "irc-write.h"
35 #define SEND_TO_USER 1
36 #define SEND_TO_SERVER 2
39 LOCAL CHAR *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client ));
44 IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
47 IRC_WriteStrClient( Client, Format, va_alist )
54 BOOLEAN ok = CONNECTED;
57 assert( Client != NULL );
58 assert( Format != NULL );
61 va_start( ap, Format );
65 vsnprintf( buffer, 1000, Format, ap );
68 /* an den Client selber */
69 ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
72 } /* IRC_WriteStrClient */
77 IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
80 IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
87 /* Text an Clients, lokal bzw. remote, senden. */
92 assert( Client != NULL );
93 assert( Format != NULL );
94 assert( Prefix != NULL );
97 va_start( ap, Format );
101 vsnprintf( buffer, 1000, Format, ap );
104 return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
105 } /* IRC_WriteStrClientPrefix */
110 IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
113 IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
124 assert( Client != NULL );
125 assert( Format != NULL );
128 va_start( ap, Format );
132 vsnprintf( buffer, 1000, Format, ap );
135 return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, "%s", buffer );
136 } /* IRC_WriteStrChannel */
141 IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
144 IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
153 BOOLEAN ok = CONNECTED;
160 assert( Client != NULL );
161 assert( Chan != NULL );
162 assert( Prefix != NULL );
163 assert( Format != NULL );
166 va_start( ap, Format );
170 vsnprintf( buffer, 1000, Format, ap );
175 /* An alle Clients, die in den selben Channels sind.
176 * Dabei aber nur einmal je Remote-Server */
177 cl2chan = Channel_FirstMember( Chan );
180 c = Channel_GetClient( cl2chan );
183 if( Client_Conn( c ) <= NONE ) c = NULL;
184 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
186 if( c ) c = Client_NextHop( c );
188 if( c && ( c != Client ))
190 /* Ok, anderer Client */
191 conn = Client_Conn( c );
192 if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
193 else Conn_SetFlag( conn, SEND_TO_USER );
195 cl2chan = Channel_NextMember( Chan, cl2chan );
198 /* Senden: alle Verbindungen durchgehen ... */
199 conn = Conn_First( );
200 while( conn != NONE )
202 /* muessen Daten ueber diese Verbindung verschickt werden? */
203 if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
204 else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
207 /* naechste Verbindung testen */
208 conn = Conn_Next( conn );
212 } /* IRC_WriteStrChannelPrefix */
217 IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... )
220 IRC_WriteStrServers( ExceptOf, Format, va_alist )
229 assert( Format != NULL );
232 va_start( ap, Format );
236 vsnprintf( buffer, 1000, Format, ap );
239 /* an den Client selber */
240 IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
241 } /* IRC_WriteStrServers */
246 IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
249 IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
259 assert( Format != NULL );
260 assert( Prefix != NULL );
263 va_start( ap, Format );
267 vsnprintf( buffer, 1000, Format, ap );
270 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
271 } /* IRC_WriteStrServersPrefix */
276 IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... )
279 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
291 assert( Format != NULL );
292 assert( Prefix != NULL );
295 va_start( ap, Format );
299 vsnprintf( buffer, 1000, Format, ap );
305 if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
307 /* Ziel-Server gefunden. Nun noch pruefen, ob Flags stimmen */
308 if(( Flag == '\0' ) || ( strchr( Client_Flags( c ), Flag ) != NULL )) IRC_WriteStrClientPrefix( c, Prefix, "%s", buffer );
310 c = Client_Next( c );
312 } /* IRC_WriteStrServersPrefixFlag */
317 IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
320 IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
328 BOOLEAN ok = CONNECTED;
329 CL2CHAN *chan_cl2chan, *cl2chan;
336 assert( Client != NULL );
337 assert( Prefix != NULL );
338 assert( Format != NULL );
341 va_start( ap, Format );
345 vsnprintf( buffer, 1000, Format, ap );
351 /* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
352 * den Text schicken. An Remote-Server aber jeweils nur einmal. */
353 chan_cl2chan = Channel_FirstChannelOf( Client );
354 while( chan_cl2chan )
356 /* Channel des Users durchsuchen */
357 chan = Channel_GetChannel( chan_cl2chan );
358 cl2chan = Channel_FirstMember( chan );
361 c = Channel_GetClient( cl2chan );
364 if( Client_Conn( c ) <= NONE ) c = NULL;
365 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
367 if( c ) c = Client_NextHop( c );
369 if( c && ( c != Client ))
371 /* Ok, anderer Client */
372 conn = Client_Conn( c );
373 if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
374 else Conn_SetFlag( conn, SEND_TO_USER );
376 cl2chan = Channel_NextMember( chan, cl2chan );
379 /* naechsten Channel */
380 chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
383 /* Senden: alle Verbindungen durchgehen ... */
384 conn = Conn_First( );
385 while( conn != NONE )
387 /* muessen ueber diese Verbindung Daten gesendet werden? */
388 if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
389 else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
392 /* naechste Verbindung testen */
393 conn = Conn_Next( conn );
396 } /* IRC_WriteStrRelatedPrefix */
400 Get_Prefix( CLIENT *Target, CLIENT *Client )
402 assert( Target != NULL );
403 assert( Client != NULL );
405 if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
406 else return Client_Mask( Client );