]> arthur.barton.de Git - ngircd-alex.git/blob - src/ngircd/irc-write.c
- Dokumentation aktualisiert.
[ngircd-alex.git] / src / ngircd / irc-write.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-write.c,v 1.12 2002/11/04 13:26:00 alex Exp $
13  *
14  * irc-write.c: IRC-Texte und Befehle ueber Netzwerk versenden
15  */
16
17
18 #include "portab.h"
19
20 #include "imp.h"
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "conn.h"
27 #include "client.h"
28 #include "channel.h"
29 #include "defines.h"
30
31 #include "exp.h"
32 #include "irc-write.h"
33
34
35 #define SEND_TO_USER 1
36 #define SEND_TO_SERVER 2
37
38
39 LOCAL CHAR *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client ));
40
41
42 #ifdef PROTOTYPES
43 GLOBAL BOOLEAN
44 IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
45 #else
46 GLOBAL BOOLEAN
47 IRC_WriteStrClient( Client, Format, va_alist )
48 CLIENT *Client;
49 CHAR *Format;
50 va_dcl
51 #endif
52 {
53         CHAR buffer[1000];
54         BOOLEAN ok = CONNECTED;
55         va_list ap;
56
57         assert( Client != NULL );
58         assert( Format != NULL );
59
60 #ifdef PROTOTYPES
61         va_start( ap, Format );
62 #else
63         va_start( ap );
64 #endif
65         vsnprintf( buffer, 1000, Format, ap );
66         va_end( ap );
67
68         /* an den Client selber */
69         ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
70
71         return ok;
72 } /* IRC_WriteStrClient */
73
74
75 #ifdef PROTOTYPES
76 GLOBAL BOOLEAN
77 IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
78 #else
79 GLOBAL BOOLEAN
80 IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
81 CLIENT *Client;
82 CLIENT *Prefix;
83 CHAR *Format;
84 va_dcl
85 #endif
86 {
87         /* Text an Clients, lokal bzw. remote, senden. */
88
89         CHAR buffer[1000];
90         va_list ap;
91
92         assert( Client != NULL );
93         assert( Format != NULL );
94         assert( Prefix != NULL );
95
96 #ifdef PROTOTYPES
97         va_start( ap, Format );
98 #else
99         va_start( ap );
100 #endif
101         vsnprintf( buffer, 1000, Format, ap );
102         va_end( ap );
103
104         return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
105 } /* IRC_WriteStrClientPrefix */
106
107
108 #ifdef PROTOTYPES
109 GLOBAL BOOLEAN
110 IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
111 #else
112 GLOBAL BOOLEAN
113 IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
114 CLIENT *Client;
115 CHANNEL *Chan;
116 BOOLEAN Remote;
117 CHAR *Format;
118 va_dcl
119 #endif
120 {
121         CHAR buffer[1000];
122         va_list ap;
123
124         assert( Client != NULL );
125         assert( Format != NULL );
126
127 #ifdef PROTOTYPES
128         va_start( ap, Format );
129 #else
130         va_start( ap );
131 #endif
132         vsnprintf( buffer, 1000, Format, ap );
133         va_end( ap );
134
135         return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, "%s", buffer );
136 } /* IRC_WriteStrChannel */
137
138
139 #ifdef PROTOTYPES
140 GLOBAL BOOLEAN
141 IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
142 #else
143 GLOBAL BOOLEAN
144 IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
145 CLIENT *Client;
146 CHANNEL *Chan;
147 CLIENT *Prefix;
148 BOOLEAN Remote;
149 CHAR *Format;
150 va_dcl
151 #endif
152 {
153         BOOLEAN ok = CONNECTED;
154         CHAR buffer[1000];
155         CL2CHAN *cl2chan;
156         CONN_ID conn;
157         CLIENT *c;
158         va_list ap;
159
160         assert( Client != NULL );
161         assert( Chan != NULL );
162         assert( Prefix != NULL );
163         assert( Format != NULL );
164
165 #ifdef PROTOTYPES
166         va_start( ap, Format );
167 #else
168         va_start( ap  );
169 #endif
170         vsnprintf( buffer, 1000, Format, ap );
171         va_end( ap );
172
173         Conn_ClearFlags( );
174
175         /* An alle Clients, die in den selben Channels sind.
176          * Dabei aber nur einmal je Remote-Server */
177         cl2chan = Channel_FirstMember( Chan );
178         while( cl2chan )
179         {
180                 c = Channel_GetClient( cl2chan );
181                 if( ! Remote )
182                 {
183                         if( Client_Conn( c ) <= NONE ) c = NULL;
184                         else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
185                 }
186                 if( c ) c = Client_NextHop( c );
187                         
188                 if( c && ( c != Client ))
189                 {
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 );
194                 }
195                 cl2chan = Channel_NextMember( Chan, cl2chan );
196         }
197
198         /* Senden: alle Verbindungen durchgehen ... */
199         conn = Conn_First( );
200         while( conn != NONE )
201         {
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 );
205                 if( ! ok ) break;
206
207                 /* naechste Verbindung testen */
208                 conn = Conn_Next( conn );
209         }
210
211         return ok;
212 } /* IRC_WriteStrChannelPrefix */
213
214
215 #ifdef PROTOTYPES
216 GLOBAL VOID
217 IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... )
218 #else
219 GLOBAL VOID
220 IRC_WriteStrServers( ExceptOf, Format, va_alist )
221 CLIENT *ExceptOf;
222 CHAR *Format;
223 va_dcl
224 #endif
225 {
226         CHAR buffer[1000];
227         va_list ap;
228
229         assert( Format != NULL );
230
231 #ifdef PROTOTYPES
232         va_start( ap, Format );
233 #else
234         va_start( ap );
235 #endif
236         vsnprintf( buffer, 1000, Format, ap );
237         va_end( ap );
238
239         /* an den Client selber */
240         IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
241 } /* IRC_WriteStrServers */
242
243
244 #ifdef PROTOTYPES
245 GLOBAL VOID
246 IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
247 #else
248 GLOBAL VOID
249 IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
250 CLIENT *ExceptOf;
251 CLIENT *Prefix;
252 CHAR *Format;
253 va_dcl
254 #endif
255 {
256         CHAR buffer[1000];
257         va_list ap;
258
259         assert( Format != NULL );
260         assert( Prefix != NULL );
261
262 #ifdef PROTOTYPES
263         va_start( ap, Format );
264 #else
265         va_start( ap );
266 #endif
267         vsnprintf( buffer, 1000, Format, ap );
268         va_end( ap );
269
270         IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
271 } /* IRC_WriteStrServersPrefix */
272         
273
274 #ifdef PROTOTYPES
275 GLOBAL VOID
276 IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... )
277 #else
278 GLOBAL VOID
279 IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
280 CLIENT *ExceptOf;
281 CLIENT *Prefix;
282 CHAR Flag;
283 CHAR *Format;
284 va_dcl
285 #endif
286 {
287         CHAR buffer[1000];
288         CLIENT *c;
289         va_list ap;
290         
291         assert( Format != NULL );
292         assert( Prefix != NULL );
293
294 #ifdef PROTOTYPES
295         va_start( ap, Format );
296 #else
297         va_start( ap );
298 #endif
299         vsnprintf( buffer, 1000, Format, ap );
300         va_end( ap );
301         
302         c = Client_First( );
303         while( c )
304         {
305                 if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
306                 {
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 );
309                 }
310                 c = Client_Next( c );
311         }
312 } /* IRC_WriteStrServersPrefixFlag */
313
314
315 #ifdef PROTOTYPES
316 GLOBAL BOOLEAN
317 IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
318 #else
319 GLOBAL BOOLEAN
320 IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
321 CLIENT *Client;
322 CLIENT *Prefix;
323 BOOLEAN Remote;
324 CHAR *Format;
325 va_dcl
326 #endif
327 {
328         BOOLEAN ok = CONNECTED;
329         CL2CHAN *chan_cl2chan, *cl2chan;
330         CHAR buffer[1000];
331         CHANNEL *chan;
332         CONN_ID conn;
333         va_list ap;
334         CLIENT *c;
335
336         assert( Client != NULL );
337         assert( Prefix != NULL );
338         assert( Format != NULL );
339
340 #ifdef PROTOTYPES
341         va_start( ap, Format );
342 #else
343         va_start( ap );
344 #endif
345         vsnprintf( buffer, 1000, Format, ap );
346         va_end( ap );
347
348         /* initialisieren */
349         Conn_ClearFlags( );
350
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 )
355         {
356                 /* Channel des Users durchsuchen */
357                 chan = Channel_GetChannel( chan_cl2chan );
358                 cl2chan = Channel_FirstMember( chan );
359                 while( cl2chan )
360                 {
361                         c = Channel_GetClient( cl2chan );
362                         if( ! Remote )
363                         {
364                                 if( Client_Conn( c ) <= NONE ) c = NULL;
365                                 else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
366                         }
367                         if( c ) c = Client_NextHop( c );
368
369                         if( c && ( c != Client ))
370                         {
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 );
375                         }
376                         cl2chan = Channel_NextMember( chan, cl2chan );
377                 }
378                 
379                 /* naechsten Channel */
380                 chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
381         }
382
383         /* Senden: alle Verbindungen durchgehen ... */
384         conn = Conn_First( );
385         while( conn != NONE )
386         {
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 );
390                 if( ! ok ) break;
391
392                 /* naechste Verbindung testen */
393                 conn = Conn_Next( conn );
394         }
395         return ok;
396 } /* IRC_WriteStrRelatedPrefix */
397
398
399 LOCAL CHAR *
400 Get_Prefix( CLIENT *Target, CLIENT *Client )
401 {
402         assert( Target != NULL );
403         assert( Client != NULL );
404
405         if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
406         else return Client_Mask( Client );
407 } /* Get_Prefix */
408
409
410 /* -eof- */