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