2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001,2002 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.14 2002/12/30 17:15:42 alex Exp $";
25 #include "conn-func.h"
31 #include "irc-write.h"
34 #define SEND_TO_USER 1
35 #define SEND_TO_SERVER 2
38 LOCAL CHAR *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client ));
43 IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
46 IRC_WriteStrClient( Client, Format, va_alist )
53 BOOLEAN ok = CONNECTED;
56 assert( Client != NULL );
57 assert( Format != NULL );
60 va_start( ap, Format );
64 vsnprintf( buffer, 1000, Format, ap );
67 /* an den Client selber */
68 ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
71 } /* IRC_WriteStrClient */
76 IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
79 IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
86 /* Text an Clients, lokal bzw. remote, senden. */
91 assert( Client != NULL );
92 assert( Format != NULL );
93 assert( Prefix != NULL );
96 va_start( ap, Format );
100 vsnprintf( buffer, 1000, Format, ap );
103 return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
104 } /* IRC_WriteStrClientPrefix */
109 IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
112 IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
123 assert( Client != NULL );
124 assert( Format != NULL );
127 va_start( ap, Format );
131 vsnprintf( buffer, 1000, Format, ap );
134 return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, "%s", buffer );
135 } /* IRC_WriteStrChannel */
140 IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
143 IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
152 BOOLEAN ok = CONNECTED;
159 assert( Client != NULL );
160 assert( Chan != NULL );
161 assert( Prefix != NULL );
162 assert( Format != NULL );
165 va_start( ap, Format );
169 vsnprintf( buffer, 1000, Format, ap );
174 /* An alle Clients, die in den selben Channels sind.
175 * Dabei aber nur einmal je Remote-Server */
176 cl2chan = Channel_FirstMember( Chan );
179 c = Channel_GetClient( cl2chan );
182 if( Client_Conn( c ) <= NONE ) c = NULL;
183 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
185 if( c ) c = Client_NextHop( c );
187 if( c && ( c != Client ))
189 /* Ok, anderer Client */
190 conn = Client_Conn( c );
191 if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
192 else Conn_SetFlag( conn, SEND_TO_USER );
194 cl2chan = Channel_NextMember( Chan, cl2chan );
197 /* Senden: alle Verbindungen durchgehen ... */
198 conn = Conn_First( );
199 while( conn != NONE )
201 /* muessen Daten ueber diese Verbindung verschickt werden? */
202 if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
203 else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
206 /* naechste Verbindung testen */
207 conn = Conn_Next( conn );
211 } /* IRC_WriteStrChannelPrefix */
216 IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... )
219 IRC_WriteStrServers( ExceptOf, Format, va_alist )
228 assert( Format != NULL );
231 va_start( ap, Format );
235 vsnprintf( buffer, 1000, Format, ap );
238 /* an den Client selber */
239 IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
240 } /* IRC_WriteStrServers */
245 IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
248 IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
258 assert( Format != NULL );
259 assert( Prefix != NULL );
262 va_start( ap, Format );
266 vsnprintf( buffer, 1000, Format, ap );
269 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
270 } /* IRC_WriteStrServersPrefix */
275 IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... )
278 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
290 assert( Format != NULL );
291 assert( Prefix != NULL );
294 va_start( ap, Format );
298 vsnprintf( buffer, 1000, Format, ap );
304 if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
306 /* Ziel-Server gefunden. Nun noch pruefen, ob Flags stimmen */
307 if(( Flag == '\0' ) || ( strchr( Client_Flags( c ), Flag ) != NULL )) IRC_WriteStrClientPrefix( c, Prefix, "%s", buffer );
309 c = Client_Next( c );
311 } /* IRC_WriteStrServersPrefixFlag */
316 IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
319 IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
327 BOOLEAN ok = CONNECTED;
328 CL2CHAN *chan_cl2chan, *cl2chan;
335 assert( Client != NULL );
336 assert( Prefix != NULL );
337 assert( Format != NULL );
340 va_start( ap, Format );
344 vsnprintf( buffer, 1000, Format, ap );
350 /* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
351 * den Text schicken. An Remote-Server aber jeweils nur einmal. */
352 chan_cl2chan = Channel_FirstChannelOf( Client );
353 while( chan_cl2chan )
355 /* Channel des Users durchsuchen */
356 chan = Channel_GetChannel( chan_cl2chan );
357 cl2chan = Channel_FirstMember( chan );
360 c = Channel_GetClient( cl2chan );
363 if( Client_Conn( c ) <= NONE ) c = NULL;
364 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
366 if( c ) c = Client_NextHop( c );
368 if( c && ( c != Client ))
370 /* Ok, anderer Client */
371 conn = Client_Conn( c );
372 if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
373 else Conn_SetFlag( conn, SEND_TO_USER );
375 cl2chan = Channel_NextMember( chan, cl2chan );
378 /* naechsten Channel */
379 chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
382 /* Senden: alle Verbindungen durchgehen ... */
383 conn = Conn_First( );
384 while( conn != NONE )
386 /* muessen ueber diese Verbindung Daten gesendet werden? */
387 if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
388 else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
391 /* naechste Verbindung testen */
392 conn = Conn_Next( conn );
395 } /* IRC_WriteStrRelatedPrefix */
399 Get_Prefix( CLIENT *Target, CLIENT *Client )
401 assert( Target != NULL );
402 assert( Client != NULL );
404 if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
405 else return Client_Mask( Client );