Blame


1 38b9cb88 2001-12-14 alex /*
2 38b9cb88 2001-12-14 alex * ngIRCd -- The Next Generation IRC Daemon
3 1547f76c 2002-01-02 alex * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
4 38b9cb88 2001-12-14 alex *
5 38b9cb88 2001-12-14 alex * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
6 38b9cb88 2001-12-14 alex * der GNU General Public License (GPL), wie von der Free Software Foundation
7 38b9cb88 2001-12-14 alex * herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
8 38b9cb88 2001-12-14 alex * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
9 38b9cb88 2001-12-14 alex * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
10 804b1ec4 2001-12-31 alex * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
11 38b9cb88 2001-12-14 alex *
12 95a4b1b1 2002-03-25 alex * $Id: client.c,v 1.52 2002/03/25 19:11:01 alex Exp $
13 38b9cb88 2001-12-14 alex *
14 38b9cb88 2001-12-14 alex * client.c: Management aller Clients
15 38b9cb88 2001-12-14 alex *
16 38b9cb88 2001-12-14 alex * Der Begriff "Client" ist in diesem Fall evtl. etwas verwirrend: Clients sind
17 38b9cb88 2001-12-14 alex * alle Verbindungen, die im gesamten(!) IRC-Netzwerk bekannt sind. Das sind IRC-
18 38b9cb88 2001-12-14 alex * Clients (User), andere Server und IRC-Services.
19 38b9cb88 2001-12-14 alex * Ueber welchen IRC-Server die Verbindung nun tatsaechlich in das Netzwerk her-
20 38b9cb88 2001-12-14 alex * gestellt wurde, muss der jeweiligen Struktur entnommen werden. Ist es dieser
21 38b9cb88 2001-12-14 alex * Server gewesen, so existiert eine entsprechende CONNECTION-Struktur.
22 38b9cb88 2001-12-14 alex */
23 38b9cb88 2001-12-14 alex
24 38b9cb88 2001-12-14 alex
25 f7551900 2002-01-04 alex #define __client_c__
26 f7551900 2002-01-04 alex
27 f7551900 2002-01-04 alex
28 ca33cbda 2002-03-12 alex #include "portab.h"
29 38b9cb88 2001-12-14 alex
30 ca33cbda 2002-03-12 alex #include "imp.h"
31 38b9cb88 2001-12-14 alex #include <assert.h>
32 d0ac1e9c 2001-12-23 alex #include <unistd.h>
33 118adda8 2001-12-27 alex #include <stdio.h>
34 b20fa7c6 2002-01-01 alex #include <stdlib.h>
35 d0ac1e9c 2001-12-23 alex #include <string.h>
36 c57a4645 2001-12-27 alex #include <netdb.h>
37 38b9cb88 2001-12-14 alex
38 ca33cbda 2002-03-12 alex #include "exp.h"
39 08cf5607 2001-12-26 alex #include "client.h"
40 08cf5607 2001-12-26 alex
41 08cf5607 2001-12-26 alex #include <imp.h>
42 79809118 2002-01-06 alex #include "ngircd.h"
43 38b9cb88 2001-12-14 alex #include "channel.h"
44 9856253d 2001-12-30 alex #include "conf.h"
45 38b9cb88 2001-12-14 alex #include "conn.h"
46 b5c16c22 2002-03-25 alex #include "hash.h"
47 ff54198f 2002-02-27 alex #include "irc-write.h"
48 38b9cb88 2001-12-14 alex #include "log.h"
49 08cf5607 2001-12-26 alex #include "messages.h"
50 38b9cb88 2001-12-14 alex
51 38b9cb88 2001-12-14 alex #include <exp.h>
52 38b9cb88 2001-12-14 alex
53 38b9cb88 2001-12-14 alex
54 f7551900 2002-01-04 alex LOCAL CLIENT *This_Server, *My_Clients;
55 118adda8 2001-12-27 alex LOCAL CHAR GetID_Buffer[CLIENT_ID_LEN];
56 08cf5607 2001-12-26 alex
57 08cf5607 2001-12-26 alex
58 b9d701db 2002-01-16 alex LOCAL INT Count( CLIENT_TYPE Type );
59 b9d701db 2002-01-16 alex LOCAL INT MyCount( CLIENT_TYPE Type );
60 b9d701db 2002-01-16 alex
61 38b9cb88 2001-12-14 alex LOCAL CLIENT *New_Client_Struct( VOID );
62 a53857b4 2002-01-07 alex LOCAL VOID Generate_MyToken( CLIENT *Client );
63 38b9cb88 2001-12-14 alex
64 38b9cb88 2001-12-14 alex
65 38b9cb88 2001-12-14 alex GLOBAL VOID Client_Init( VOID )
66 38b9cb88 2001-12-14 alex {
67 c57a4645 2001-12-27 alex struct hostent *h;
68 c57a4645 2001-12-27 alex
69 38b9cb88 2001-12-14 alex This_Server = New_Client_Struct( );
70 38b9cb88 2001-12-14 alex if( ! This_Server )
71 38b9cb88 2001-12-14 alex {
72 38b9cb88 2001-12-14 alex Log( LOG_EMERG, "Can't allocate client structure for server! Going down." );
73 9856253d 2001-12-30 alex Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
74 38b9cb88 2001-12-14 alex exit( 1 );
75 38b9cb88 2001-12-14 alex }
76 38b9cb88 2001-12-14 alex
77 38b9cb88 2001-12-14 alex /* Client-Struktur dieses Servers */
78 38b9cb88 2001-12-14 alex This_Server->next = NULL;
79 38b9cb88 2001-12-14 alex This_Server->type = CLIENT_SERVER;
80 38b9cb88 2001-12-14 alex This_Server->conn_id = NONE;
81 38b9cb88 2001-12-14 alex This_Server->introducer = This_Server;
82 8f7e7d66 2002-01-09 alex This_Server->mytoken = 1;
83 4fe7e9d6 2002-01-11 alex This_Server->hops = 0;
84 c57a4645 2001-12-27 alex
85 d0ac1e9c 2001-12-23 alex gethostname( This_Server->host, CLIENT_HOST_LEN );
86 c57a4645 2001-12-27 alex h = gethostbyname( This_Server->host );
87 c57a4645 2001-12-27 alex if( h ) strcpy( This_Server->host, h->h_name );
88 c57a4645 2001-12-27 alex
89 b5c16c22 2002-03-25 alex Client_SetID( This_Server, Conf_ServerName );
90 b5c16c22 2002-03-25 alex Client_SetInfo( This_Server, Conf_ServerInfo );
91 d0ac1e9c 2001-12-23 alex
92 38b9cb88 2001-12-14 alex My_Clients = This_Server;
93 38b9cb88 2001-12-14 alex } /* Client_Init */
94 38b9cb88 2001-12-14 alex
95 38b9cb88 2001-12-14 alex
96 38b9cb88 2001-12-14 alex GLOBAL VOID Client_Exit( VOID )
97 38b9cb88 2001-12-14 alex {
98 d0ac1e9c 2001-12-23 alex CLIENT *c, *next;
99 d0ac1e9c 2001-12-23 alex INT cnt;
100 d0ac1e9c 2001-12-23 alex
101 50ec7a56 2002-03-11 alex Client_Destroy( This_Server, "Server going down.", NULL, FALSE );
102 d0ac1e9c 2001-12-23 alex
103 d0ac1e9c 2001-12-23 alex cnt = 0;
104 d0ac1e9c 2001-12-23 alex c = My_Clients;
105 d0ac1e9c 2001-12-23 alex while( c )
106 d0ac1e9c 2001-12-23 alex {
107 d0ac1e9c 2001-12-23 alex cnt++;
108 95a4b1b1 2002-03-25 alex next = (CLIENT *)c->next;
109 d0ac1e9c 2001-12-23 alex free( c );
110 d0ac1e9c 2001-12-23 alex c = next;
111 d0ac1e9c 2001-12-23 alex }
112 d4a60bd4 2001-12-25 alex if( cnt ) Log( LOG_INFO, "Freed %d client structure%s.", cnt, cnt == 1 ? "" : "s" );
113 79809118 2002-01-06 alex } /* Client_Exit */
114 38b9cb88 2001-12-14 alex
115 38b9cb88 2001-12-14 alex
116 f7551900 2002-01-04 alex GLOBAL CLIENT *Client_ThisServer( VOID )
117 d0ac1e9c 2001-12-23 alex {
118 f7551900 2002-01-04 alex return This_Server;
119 f7551900 2002-01-04 alex } /* Client_ThisServer */
120 f7551900 2002-01-04 alex
121 f7551900 2002-01-04 alex
122 904d5e5b 2002-01-05 alex GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented )
123 f7551900 2002-01-04 alex {
124 f7551900 2002-01-04 alex /* Neuen lokalen Client erzeugen: Wrapper-Funktion fuer Client_New(). */
125 1ab92bb9 2002-01-29 alex return Client_New( Idx, This_Server, NULL, Type, NULL, NULL, Hostname, NULL, 0, 0, NULL, Idented );
126 f7551900 2002-01-04 alex } /* Client_NewLocal */
127 f7551900 2002-01-04 alex
128 f7551900 2002-01-04 alex
129 1ab92bb9 2002-01-29 alex GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented )
130 f7551900 2002-01-04 alex {
131 f7551900 2002-01-04 alex /* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
132 1ab92bb9 2002-01-29 alex return Client_New( NONE, Introducer, TopServer, CLIENT_SERVER, Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented );
133 f7551900 2002-01-04 alex } /* Client_NewRemoteServer */
134 f7551900 2002-01-04 alex
135 f7551900 2002-01-04 alex
136 904d5e5b 2002-01-05 alex GLOBAL CLIENT *Client_NewRemoteUser( CLIENT *Introducer, CHAR *Nick, INT Hops, CHAR *User, CHAR *Hostname, INT Token, CHAR *Modes, CHAR *Info, BOOLEAN Idented )
137 f7551900 2002-01-04 alex {
138 f7551900 2002-01-04 alex /* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
139 1ab92bb9 2002-01-29 alex return Client_New( NONE, Introducer, NULL, CLIENT_USER, Nick, User, Hostname, Info, Hops, Token, Modes, Idented );
140 f7551900 2002-01-04 alex } /* Client_NewRemoteUser */
141 f7551900 2002-01-04 alex
142 f7551900 2002-01-04 alex
143 1ab92bb9 2002-01-29 alex GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented )
144 f7551900 2002-01-04 alex {
145 d0ac1e9c 2001-12-23 alex CLIENT *client;
146 d0ac1e9c 2001-12-23 alex
147 f7551900 2002-01-04 alex assert( Idx >= NONE );
148 f7551900 2002-01-04 alex assert( Introducer != NULL );
149 b7a18e9f 2001-12-24 alex assert( Hostname != NULL );
150 f7551900 2002-01-04 alex
151 d0ac1e9c 2001-12-23 alex client = New_Client_Struct( );
152 d0ac1e9c 2001-12-23 alex if( ! client ) return NULL;
153 d0ac1e9c 2001-12-23 alex
154 2c5da58d 2001-12-29 alex /* Initialisieren */
155 d0ac1e9c 2001-12-23 alex client->conn_id = Idx;
156 f7551900 2002-01-04 alex client->introducer = Introducer;
157 1ab92bb9 2002-01-29 alex client->topserver = TopServer;
158 f7551900 2002-01-04 alex client->type = Type;
159 f7551900 2002-01-04 alex if( ID ) Client_SetID( client, ID );
160 904d5e5b 2002-01-05 alex if( User ) Client_SetUser( client, User, Idented );
161 f7551900 2002-01-04 alex if( Hostname ) Client_SetHostname( client, Hostname );
162 f7551900 2002-01-04 alex if( Info ) Client_SetInfo( client, Info );
163 f7551900 2002-01-04 alex client->hops = Hops;
164 f7551900 2002-01-04 alex client->token = Token;
165 f7551900 2002-01-04 alex if( Modes ) Client_SetModes( client, Modes );
166 a53857b4 2002-01-07 alex if( Type == CLIENT_SERVER ) Generate_MyToken( client );
167 d0ac1e9c 2001-12-23 alex
168 a1a3e67d 2002-03-04 alex /* ist der User away? */
169 a1a3e67d 2002-03-04 alex if( strchr( client->modes, 'a' )) strcpy( client->away, DEFAULT_AWAY_MSG );
170 a1a3e67d 2002-03-04 alex
171 d0ac1e9c 2001-12-23 alex /* Verketten */
172 95a4b1b1 2002-03-25 alex client->next = (POINTER *)My_Clients;
173 d0ac1e9c 2001-12-23 alex My_Clients = client;
174 f7551900 2002-01-04 alex
175 d0ac1e9c 2001-12-23 alex return client;
176 f7551900 2002-01-04 alex } /* Client_New */
177 d0ac1e9c 2001-12-23 alex
178 d0ac1e9c 2001-12-23 alex
179 50ec7a56 2002-03-11 alex GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN SendQuit )
180 d0ac1e9c 2001-12-23 alex {
181 d0ac1e9c 2001-12-23 alex /* Client entfernen. */
182 d0ac1e9c 2001-12-23 alex
183 d0ac1e9c 2001-12-23 alex CLIENT *last, *c;
184 dce77559 2002-03-10 alex CHAR msg[LINE_LEN], *txt;
185 d0ac1e9c 2001-12-23 alex
186 b7a18e9f 2001-12-24 alex assert( Client != NULL );
187 c4854470 2002-01-04 alex
188 79809118 2002-01-06 alex if( LogMsg ) txt = LogMsg;
189 79809118 2002-01-06 alex else txt = FwdMsg;
190 79809118 2002-01-06 alex if( ! txt ) txt = "Reason unknown.";
191 dce77559 2002-03-10 alex
192 03c3f3c9 2002-03-12 alex /* Netz-Split-Nachricht vorbereiten (noch nicht optimal) */
193 9146fa25 2002-03-12 alex if( Client->type == CLIENT_SERVER ) sprintf( msg, "%s: lost server %s", This_Server->id, Client->id );
194 79809118 2002-01-06 alex
195 d0ac1e9c 2001-12-23 alex last = NULL;
196 d0ac1e9c 2001-12-23 alex c = My_Clients;
197 d0ac1e9c 2001-12-23 alex while( c )
198 d0ac1e9c 2001-12-23 alex {
199 c4854470 2002-01-04 alex if(( Client->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c != Client ))
200 c4854470 2002-01-04 alex {
201 dce77559 2002-03-10 alex /* der Client, der geloescht wird ist ein Server. Der Client, den wir gerade
202 dce77559 2002-03-10 alex * pruefen, ist ein Child von diesem und muss daher auch entfernt werden */
203 50ec7a56 2002-03-11 alex Client_Destroy( c, NULL, msg, FALSE );
204 c4854470 2002-01-04 alex last = NULL;
205 c4854470 2002-01-04 alex c = My_Clients;
206 c4854470 2002-01-04 alex continue;
207 c4854470 2002-01-04 alex }
208 d0ac1e9c 2001-12-23 alex if( c == Client )
209 d0ac1e9c 2001-12-23 alex {
210 dce77559 2002-03-10 alex /* Wir haben den Client gefunden: entfernen */
211 d0ac1e9c 2001-12-23 alex if( last ) last->next = c->next;
212 95a4b1b1 2002-03-25 alex else My_Clients = (CLIENT *)c->next;
213 15764f98 2001-12-27 alex
214 c4854470 2002-01-04 alex if( c->type == CLIENT_USER )
215 c4854470 2002-01-04 alex {
216 db58d347 2002-01-05 alex if( c->conn_id != NONE )
217 db58d347 2002-01-05 alex {
218 50ec7a56 2002-03-11 alex /* Ein lokaler User */
219 b89c3108 2002-01-07 alex Log( LOG_NOTICE, "User \"%s\" unregistered (connection %d): %s", Client_Mask( c ), c->conn_id, txt );
220 79809118 2002-01-06 alex
221 50ec7a56 2002-03-11 alex if( SendQuit )
222 50ec7a56 2002-03-11 alex {
223 50ec7a56 2002-03-11 alex /* Alle andere Server informieren! */
224 50ec7a56 2002-03-11 alex if( FwdMsg ) IRC_WriteStrServersPrefix( NULL, c, "QUIT :%s", FwdMsg );
225 50ec7a56 2002-03-11 alex else IRC_WriteStrServersPrefix( NULL, c, "QUIT :" );
226 50ec7a56 2002-03-11 alex }
227 db58d347 2002-01-05 alex }
228 79809118 2002-01-06 alex else
229 79809118 2002-01-06 alex {
230 50ec7a56 2002-03-11 alex /* Remote User */
231 b89c3108 2002-01-07 alex Log( LOG_DEBUG, "User \"%s\" unregistered: %s", Client_Mask( c ), txt );
232 50ec7a56 2002-03-11 alex
233 50ec7a56 2002-03-11 alex if( SendQuit )
234 50ec7a56 2002-03-11 alex {
235 50ec7a56 2002-03-11 alex /* Andere Server informieren, ausser denen, die "in
236 50ec7a56 2002-03-11 alex * Richtung dem liegen", auf dem der User registriert
237 50ec7a56 2002-03-11 alex * ist. Von denen haben wir das QUIT ja wohl bekommen. */
238 50ec7a56 2002-03-11 alex if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :%s", FwdMsg );
239 50ec7a56 2002-03-11 alex else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :" );
240 50ec7a56 2002-03-11 alex }
241 79809118 2002-01-06 alex }
242 fc3c82f7 2002-01-21 alex Channel_RemoveClient( c, FwdMsg ? FwdMsg : c->id );
243 c4854470 2002-01-04 alex }
244 79809118 2002-01-06 alex else if( c->type == CLIENT_SERVER )
245 79809118 2002-01-06 alex {
246 28d58986 2002-02-27 alex if( c != This_Server )
247 28d58986 2002-02-27 alex {
248 28d58986 2002-02-27 alex if( c->conn_id != NONE ) Log( LOG_NOTICE, "Server \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
249 28d58986 2002-02-27 alex else Log( LOG_NOTICE, "Server \"%s\" unregistered: %s", c->id, txt );
250 28d58986 2002-02-27 alex }
251 8f7e7d66 2002-01-09 alex
252 8f7e7d66 2002-01-09 alex /* andere Server informieren */
253 8f7e7d66 2002-01-09 alex if( ! NGIRCd_Quit )
254 8f7e7d66 2002-01-09 alex {
255 8f7e7d66 2002-01-09 alex if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :%s", c->id, FwdMsg );
256 8f7e7d66 2002-01-09 alex else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :", c->id );
257 8f7e7d66 2002-01-09 alex }
258 79809118 2002-01-06 alex }
259 28d58986 2002-02-27 alex else
260 28d58986 2002-02-27 alex {
261 28d58986 2002-02-27 alex if( c->conn_id != NONE )
262 28d58986 2002-02-27 alex {
263 28d58986 2002-02-27 alex if( c->id[0] ) Log( LOG_NOTICE, "Client \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
264 28d58986 2002-02-27 alex else Log( LOG_NOTICE, "Client unregistered (connection %d): %s", c->conn_id, txt );
265 28d58986 2002-02-27 alex }
266 28d58986 2002-02-27 alex else
267 28d58986 2002-02-27 alex {
268 28d58986 2002-02-27 alex if( c->id[0] ) Log( LOG_WARNING, "Unregistered unknown client \"%s\": %s", c->id, txt );
269 28d58986 2002-02-27 alex else Log( LOG_WARNING, "Unregistered unknown client: %s", c->id, txt );
270 28d58986 2002-02-27 alex }
271 28d58986 2002-02-27 alex }
272 15764f98 2001-12-27 alex
273 d0ac1e9c 2001-12-23 alex free( c );
274 d0ac1e9c 2001-12-23 alex break;
275 d0ac1e9c 2001-12-23 alex }
276 d0ac1e9c 2001-12-23 alex last = c;
277 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
278 d0ac1e9c 2001-12-23 alex }
279 d0ac1e9c 2001-12-23 alex } /* Client_Destroy */
280 d0ac1e9c 2001-12-23 alex
281 d0ac1e9c 2001-12-23 alex
282 2c5da58d 2001-12-29 alex GLOBAL VOID Client_SetHostname( CLIENT *Client, CHAR *Hostname )
283 2c5da58d 2001-12-29 alex {
284 2c5da58d 2001-12-29 alex /* Hostname eines Clients setzen */
285 2c5da58d 2001-12-29 alex
286 2c5da58d 2001-12-29 alex assert( Client != NULL );
287 c68c092c 2002-03-06 alex assert( Hostname != NULL );
288 c68c092c 2002-03-06 alex
289 10363b39 2002-03-03 alex strncpy( Client->host, Hostname, CLIENT_HOST_LEN - 1 );
290 804b1ec4 2001-12-31 alex Client->host[CLIENT_HOST_LEN - 1] = '\0';
291 2c5da58d 2001-12-29 alex } /* Client_SetHostname */
292 f7551900 2002-01-04 alex
293 f7551900 2002-01-04 alex
294 f7551900 2002-01-04 alex GLOBAL VOID Client_SetID( CLIENT *Client, CHAR *ID )
295 f7551900 2002-01-04 alex {
296 b5c16c22 2002-03-25 alex /* Hostname eines Clients setzen, Hash-Wert berechnen */
297 f7551900 2002-01-04 alex
298 f7551900 2002-01-04 alex assert( Client != NULL );
299 c68c092c 2002-03-06 alex assert( ID != NULL );
300 c68c092c 2002-03-06 alex
301 10363b39 2002-03-03 alex strncpy( Client->id, ID, CLIENT_ID_LEN - 1 );
302 f7551900 2002-01-04 alex Client->id[CLIENT_ID_LEN - 1] = '\0';
303 b5c16c22 2002-03-25 alex
304 b5c16c22 2002-03-25 alex /* Hash */
305 b5c16c22 2002-03-25 alex Client->hash = Hash( Client->id );
306 f7551900 2002-01-04 alex } /* Client_SetID */
307 f7551900 2002-01-04 alex
308 f7551900 2002-01-04 alex
309 904d5e5b 2002-01-05 alex GLOBAL VOID Client_SetUser( CLIENT *Client, CHAR *User, BOOLEAN Idented )
310 f7551900 2002-01-04 alex {
311 f7551900 2002-01-04 alex /* Username eines Clients setzen */
312 f7551900 2002-01-04 alex
313 f7551900 2002-01-04 alex assert( Client != NULL );
314 c68c092c 2002-03-06 alex assert( User != NULL );
315 c68c092c 2002-03-06 alex
316 10363b39 2002-03-03 alex if( Idented ) strncpy( Client->user, User, CLIENT_USER_LEN - 1 );
317 904d5e5b 2002-01-05 alex else
318 904d5e5b 2002-01-05 alex {
319 904d5e5b 2002-01-05 alex Client->user[0] = '~';
320 10363b39 2002-03-03 alex strncpy( Client->user + 1, User, CLIENT_USER_LEN - 2 );
321 904d5e5b 2002-01-05 alex }
322 f7551900 2002-01-04 alex Client->user[CLIENT_USER_LEN - 1] = '\0';
323 f7551900 2002-01-04 alex } /* Client_SetUser */
324 f7551900 2002-01-04 alex
325 f7551900 2002-01-04 alex
326 f7551900 2002-01-04 alex GLOBAL VOID Client_SetInfo( CLIENT *Client, CHAR *Info )
327 f7551900 2002-01-04 alex {
328 f7551900 2002-01-04 alex /* Hostname eines Clients setzen */
329 f7551900 2002-01-04 alex
330 f7551900 2002-01-04 alex assert( Client != NULL );
331 c68c092c 2002-03-06 alex assert( Info != NULL );
332 c68c092c 2002-03-06 alex
333 10363b39 2002-03-03 alex strncpy( Client->info, Info, CLIENT_INFO_LEN - 1 );
334 f7551900 2002-01-04 alex Client->info[CLIENT_INFO_LEN - 1] = '\0';
335 f7551900 2002-01-04 alex } /* Client_SetInfo */
336 f7551900 2002-01-04 alex
337 f7551900 2002-01-04 alex
338 f7551900 2002-01-04 alex GLOBAL VOID Client_SetModes( CLIENT *Client, CHAR *Modes )
339 f7551900 2002-01-04 alex {
340 f7551900 2002-01-04 alex /* Hostname eines Clients setzen */
341 f7551900 2002-01-04 alex
342 f7551900 2002-01-04 alex assert( Client != NULL );
343 c68c092c 2002-03-06 alex assert( Modes != NULL );
344 c68c092c 2002-03-06 alex
345 10363b39 2002-03-03 alex strncpy( Client->modes, Modes, CLIENT_MODE_LEN - 1 );
346 49ed223c 2002-01-18 alex Client->modes[CLIENT_MODE_LEN - 1] = '\0';
347 f7551900 2002-01-04 alex } /* Client_SetModes */
348 f7551900 2002-01-04 alex
349 f7551900 2002-01-04 alex
350 f7551900 2002-01-04 alex GLOBAL VOID Client_SetPassword( CLIENT *Client, CHAR *Pwd )
351 f7551900 2002-01-04 alex {
352 f7551900 2002-01-04 alex /* Von einem Client geliefertes Passwort */
353 f7551900 2002-01-04 alex
354 f7551900 2002-01-04 alex assert( Client != NULL );
355 c68c092c 2002-03-06 alex assert( Pwd != NULL );
356 c68c092c 2002-03-06 alex
357 10363b39 2002-03-03 alex strncpy( Client->pwd, Pwd, CLIENT_PASS_LEN - 1 );
358 f7551900 2002-01-04 alex Client->pwd[CLIENT_PASS_LEN - 1] = '\0';
359 f7551900 2002-01-04 alex } /* Client_SetPassword */
360 c4850124 2002-02-27 alex
361 c4850124 2002-02-27 alex
362 c4850124 2002-02-27 alex GLOBAL VOID Client_SetAway( CLIENT *Client, CHAR *Txt )
363 c4850124 2002-02-27 alex {
364 c4850124 2002-02-27 alex /* Von einem Client gelieferte AWAY-Nachricht */
365 c4850124 2002-02-27 alex
366 c4850124 2002-02-27 alex assert( Client != NULL );
367 c4850124 2002-02-27 alex
368 c4850124 2002-02-27 alex if( Txt )
369 c4850124 2002-02-27 alex {
370 c4850124 2002-02-27 alex /* Client AWAY setzen */
371 10363b39 2002-03-03 alex strncpy( Client->away, Txt, CLIENT_AWAY_LEN - 1 );
372 c4850124 2002-02-27 alex Client->away[CLIENT_AWAY_LEN - 1] = '\0';
373 c4850124 2002-02-27 alex Client_ModeAdd( Client, 'a' );
374 c4850124 2002-02-27 alex Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
375 c4850124 2002-02-27 alex }
376 c4850124 2002-02-27 alex else
377 c4850124 2002-02-27 alex {
378 c4850124 2002-02-27 alex /* AWAY loeschen */
379 c4850124 2002-02-27 alex Client_ModeDel( Client, 'a' );
380 c4850124 2002-02-27 alex Log( LOG_DEBUG, "User \"%s\" is no longer away.", Client_Mask( Client ));
381 c4850124 2002-02-27 alex }
382 c4850124 2002-02-27 alex } /* Client_SetAway */
383 f7551900 2002-01-04 alex
384 f7551900 2002-01-04 alex
385 f7551900 2002-01-04 alex GLOBAL VOID Client_SetType( CLIENT *Client, INT Type )
386 f7551900 2002-01-04 alex {
387 f7551900 2002-01-04 alex assert( Client != NULL );
388 f7551900 2002-01-04 alex Client->type = Type;
389 a53857b4 2002-01-07 alex if( Type == CLIENT_SERVER ) Generate_MyToken( Client );
390 f7551900 2002-01-04 alex } /* Client_SetType */
391 f7551900 2002-01-04 alex
392 f7551900 2002-01-04 alex
393 f7551900 2002-01-04 alex GLOBAL VOID Client_SetHops( CLIENT *Client, INT Hops )
394 f7551900 2002-01-04 alex {
395 f7551900 2002-01-04 alex assert( Client != NULL );
396 f7551900 2002-01-04 alex Client->hops = Hops;
397 f7551900 2002-01-04 alex } /* Client_SetHops */
398 f7551900 2002-01-04 alex
399 f7551900 2002-01-04 alex
400 f7551900 2002-01-04 alex GLOBAL VOID Client_SetToken( CLIENT *Client, INT Token )
401 f7551900 2002-01-04 alex {
402 f7551900 2002-01-04 alex assert( Client != NULL );
403 f7551900 2002-01-04 alex Client->token = Token;
404 f7551900 2002-01-04 alex } /* Client_SetToken */
405 f7551900 2002-01-04 alex
406 f7551900 2002-01-04 alex
407 f7551900 2002-01-04 alex GLOBAL VOID Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer )
408 f7551900 2002-01-04 alex {
409 f7551900 2002-01-04 alex assert( Client != NULL );
410 c68c092c 2002-03-06 alex assert( Introducer != NULL );
411 f7551900 2002-01-04 alex Client->introducer = Introducer;
412 f7551900 2002-01-04 alex } /* Client_SetIntroducer */
413 f7551900 2002-01-04 alex
414 f7551900 2002-01-04 alex
415 f7551900 2002-01-04 alex GLOBAL VOID Client_SetOperByMe( CLIENT *Client, BOOLEAN OperByMe )
416 f7551900 2002-01-04 alex {
417 f7551900 2002-01-04 alex assert( Client != NULL );
418 f7551900 2002-01-04 alex Client->oper_by_me = OperByMe;
419 f7551900 2002-01-04 alex } /* Client_SetOperByMe */
420 f7551900 2002-01-04 alex
421 f7551900 2002-01-04 alex
422 f7551900 2002-01-04 alex GLOBAL BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode )
423 f7551900 2002-01-04 alex {
424 f7551900 2002-01-04 alex /* Mode soll gesetzt werden. TRUE wird geliefert, wenn der
425 f7551900 2002-01-04 alex * Mode neu gesetzt wurde, FALSE, wenn der Client den Mode
426 f7551900 2002-01-04 alex * bereits hatte. */
427 f7551900 2002-01-04 alex
428 f7551900 2002-01-04 alex CHAR x[2];
429 f7551900 2002-01-04 alex
430 f7551900 2002-01-04 alex assert( Client != NULL );
431 f7551900 2002-01-04 alex
432 f7551900 2002-01-04 alex x[0] = Mode; x[1] = '\0';
433 f7551900 2002-01-04 alex if( ! strchr( Client->modes, x[0] ))
434 f7551900 2002-01-04 alex {
435 f7551900 2002-01-04 alex /* Client hat den Mode noch nicht -> setzen */
436 f7551900 2002-01-04 alex strcat( Client->modes, x );
437 f7551900 2002-01-04 alex return TRUE;
438 f7551900 2002-01-04 alex }
439 f7551900 2002-01-04 alex else return FALSE;
440 f7551900 2002-01-04 alex } /* Client_ModeAdd */
441 f7551900 2002-01-04 alex
442 f7551900 2002-01-04 alex
443 f7551900 2002-01-04 alex GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode )
444 f7551900 2002-01-04 alex {
445 f7551900 2002-01-04 alex /* Mode soll geloescht werden. TRUE wird geliefert, wenn der
446 f7551900 2002-01-04 alex * Mode entfernt wurde, FALSE, wenn der Client den Mode
447 f7551900 2002-01-04 alex * ueberhaupt nicht hatte. */
448 f7551900 2002-01-04 alex
449 f7551900 2002-01-04 alex CHAR x[2], *p;
450 f7551900 2002-01-04 alex
451 f7551900 2002-01-04 alex assert( Client != NULL );
452 f7551900 2002-01-04 alex
453 f7551900 2002-01-04 alex x[0] = Mode; x[1] = '\0';
454 2c5da58d 2001-12-29 alex
455 f7551900 2002-01-04 alex p = strchr( Client->modes, x[0] );
456 f7551900 2002-01-04 alex if( ! p ) return FALSE;
457 2c5da58d 2001-12-29 alex
458 f7551900 2002-01-04 alex /* Client hat den Mode -> loeschen */
459 f7551900 2002-01-04 alex while( *p )
460 f7551900 2002-01-04 alex {
461 f7551900 2002-01-04 alex *p = *(p + 1);
462 f7551900 2002-01-04 alex p++;
463 f7551900 2002-01-04 alex }
464 f7551900 2002-01-04 alex return TRUE;
465 f7551900 2002-01-04 alex } /* Client_ModeDel */
466 f7551900 2002-01-04 alex
467 f7551900 2002-01-04 alex
468 d0ac1e9c 2001-12-23 alex GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx )
469 d0ac1e9c 2001-12-23 alex {
470 804b1ec4 2001-12-31 alex /* Client-Struktur, die zur lokalen Verbindung Idx gehoert,
471 d0ac1e9c 2001-12-23 alex * liefern. Wird keine gefunden, so wird NULL geliefert. */
472 d0ac1e9c 2001-12-23 alex
473 d0ac1e9c 2001-12-23 alex CLIENT *c;
474 d0ac1e9c 2001-12-23 alex
475 b7a18e9f 2001-12-24 alex assert( Idx >= 0 );
476 b7a18e9f 2001-12-24 alex
477 d0ac1e9c 2001-12-23 alex c = My_Clients;
478 d0ac1e9c 2001-12-23 alex while( c )
479 d0ac1e9c 2001-12-23 alex {
480 d0ac1e9c 2001-12-23 alex if( c->conn_id == Idx ) return c;
481 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
482 d0ac1e9c 2001-12-23 alex }
483 d0ac1e9c 2001-12-23 alex return NULL;
484 d0ac1e9c 2001-12-23 alex } /* Client_GetFromConn */
485 d0ac1e9c 2001-12-23 alex
486 d0ac1e9c 2001-12-23 alex
487 b5c16c22 2002-03-25 alex GLOBAL CLIENT *Client_Search( CHAR *Nick )
488 90676129 2001-12-26 alex {
489 10363b39 2002-03-03 alex /* Client-Struktur, die den entsprechenden Nick hat, liefern.
490 10363b39 2002-03-03 alex * Wird keine gefunden, so wird NULL geliefert. */
491 804b1ec4 2001-12-31 alex
492 b5c16c22 2002-03-25 alex CHAR search_id[CLIENT_ID_LEN], *ptr;
493 40c9fd26 2002-01-27 alex CLIENT *c = NULL;
494 b5c16c22 2002-03-25 alex UINT32 search_hash;
495 804b1ec4 2001-12-31 alex
496 804b1ec4 2001-12-31 alex assert( Nick != NULL );
497 d17748e9 2002-01-27 alex
498 40c9fd26 2002-01-27 alex /* Nick kopieren und ggf. Host-Mask abschneiden */
499 b5c16c22 2002-03-25 alex strncpy( search_id, Nick, CLIENT_ID_LEN - 1 );
500 b5c16c22 2002-03-25 alex search_id[CLIENT_ID_LEN - 1] = '\0';
501 b5c16c22 2002-03-25 alex ptr = strchr( search_id, '!' );
502 d17748e9 2002-01-27 alex if( ptr ) *ptr = '\0';
503 804b1ec4 2001-12-31 alex
504 b5c16c22 2002-03-25 alex search_hash = Hash( search_id );
505 b5c16c22 2002-03-25 alex
506 804b1ec4 2001-12-31 alex c = My_Clients;
507 804b1ec4 2001-12-31 alex while( c )
508 804b1ec4 2001-12-31 alex {
509 b5c16c22 2002-03-25 alex if( c->hash == search_hash )
510 b5c16c22 2002-03-25 alex {
511 b5c16c22 2002-03-25 alex /* lt. Hash-Wert: Treffer! */
512 b5c16c22 2002-03-25 alex if( strcasecmp( c->id, search_id ) == 0 ) return c;
513 b5c16c22 2002-03-25 alex }
514 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
515 804b1ec4 2001-12-31 alex }
516 804b1ec4 2001-12-31 alex return NULL;
517 b5c16c22 2002-03-25 alex } /* Client_Search */
518 804b1ec4 2001-12-31 alex
519 804b1ec4 2001-12-31 alex
520 f7551900 2002-01-04 alex GLOBAL CLIENT *Client_GetFromToken( CLIENT *Client, INT Token )
521 804b1ec4 2001-12-31 alex {
522 f7551900 2002-01-04 alex /* Client-Struktur, die den entsprechenden Introducer (=Client)
523 f7551900 2002-01-04 alex * und das gegebene Token hat, liefern. Wird keine gefunden,
524 f7551900 2002-01-04 alex * so wird NULL geliefert. */
525 f7551900 2002-01-04 alex
526 f7551900 2002-01-04 alex CLIENT *c;
527 f7551900 2002-01-04 alex
528 90676129 2001-12-26 alex assert( Client != NULL );
529 f7551900 2002-01-04 alex assert( Token > 0 );
530 90676129 2001-12-26 alex
531 f7551900 2002-01-04 alex c = My_Clients;
532 f7551900 2002-01-04 alex while( c )
533 f7551900 2002-01-04 alex {
534 f7551900 2002-01-04 alex if(( c->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c->token == Token )) return c;
535 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
536 f7551900 2002-01-04 alex }
537 f7551900 2002-01-04 alex return NULL;
538 f7551900 2002-01-04 alex } /* Client_GetFromToken */
539 f7551900 2002-01-04 alex
540 f7551900 2002-01-04 alex
541 f7551900 2002-01-04 alex GLOBAL INT Client_Type( CLIENT *Client )
542 f7551900 2002-01-04 alex {
543 f7551900 2002-01-04 alex assert( Client != NULL );
544 f7551900 2002-01-04 alex return Client->type;
545 f7551900 2002-01-04 alex } /* Client_Type */
546 f7551900 2002-01-04 alex
547 f7551900 2002-01-04 alex
548 f7551900 2002-01-04 alex GLOBAL CONN_ID Client_Conn( CLIENT *Client )
549 f7551900 2002-01-04 alex {
550 f7551900 2002-01-04 alex assert( Client != NULL );
551 f7551900 2002-01-04 alex return Client->conn_id;
552 f7551900 2002-01-04 alex } /* Client_Conn */
553 f7551900 2002-01-04 alex
554 f7551900 2002-01-04 alex
555 f7551900 2002-01-04 alex GLOBAL CHAR *Client_ID( CLIENT *Client )
556 f7551900 2002-01-04 alex {
557 f7551900 2002-01-04 alex assert( Client != NULL );
558 f7551900 2002-01-04 alex
559 c68c092c 2002-03-06 alex #ifdef DEBUG
560 c68c092c 2002-03-06 alex if( Client->type == CLIENT_USER ) assert( strlen( Client->id ) < CLIENT_NICK_LEN );
561 c68c092c 2002-03-06 alex #endif
562 c68c092c 2002-03-06 alex
563 f7551900 2002-01-04 alex if( Client->id[0] ) return Client->id;
564 90676129 2001-12-26 alex else return "*";
565 f7551900 2002-01-04 alex } /* Client_ID */
566 90676129 2001-12-26 alex
567 90676129 2001-12-26 alex
568 f7551900 2002-01-04 alex GLOBAL CHAR *Client_Info( CLIENT *Client )
569 f7551900 2002-01-04 alex {
570 f7551900 2002-01-04 alex assert( Client != NULL );
571 f7551900 2002-01-04 alex return Client->info;
572 f7551900 2002-01-04 alex } /* Client_Info */
573 f7551900 2002-01-04 alex
574 f7551900 2002-01-04 alex
575 f7551900 2002-01-04 alex GLOBAL CHAR *Client_User( CLIENT *Client )
576 f7551900 2002-01-04 alex {
577 f7551900 2002-01-04 alex assert( Client != NULL );
578 95a4b1b1 2002-03-25 alex if( Client->user[0] ) return Client->user;
579 f7551900 2002-01-04 alex else return "~";
580 f7551900 2002-01-04 alex } /* Client_User */
581 f7551900 2002-01-04 alex
582 f7551900 2002-01-04 alex
583 f7551900 2002-01-04 alex GLOBAL CHAR *Client_Hostname( CLIENT *Client )
584 f7551900 2002-01-04 alex {
585 f7551900 2002-01-04 alex assert( Client != NULL );
586 f7551900 2002-01-04 alex return Client->host;
587 f7551900 2002-01-04 alex } /* Client_Hostname */
588 f7551900 2002-01-04 alex
589 f7551900 2002-01-04 alex
590 f7551900 2002-01-04 alex GLOBAL CHAR *Client_Password( CLIENT *Client )
591 f7551900 2002-01-04 alex {
592 f7551900 2002-01-04 alex assert( Client != NULL );
593 f7551900 2002-01-04 alex return Client->pwd;
594 f7551900 2002-01-04 alex } /* Client_Password */
595 f7551900 2002-01-04 alex
596 f7551900 2002-01-04 alex
597 f7551900 2002-01-04 alex GLOBAL CHAR *Client_Modes( CLIENT *Client )
598 f7551900 2002-01-04 alex {
599 f7551900 2002-01-04 alex assert( Client != NULL );
600 f7551900 2002-01-04 alex return Client->modes;
601 f7551900 2002-01-04 alex } /* Client_Modes */
602 f7551900 2002-01-04 alex
603 f7551900 2002-01-04 alex
604 f7551900 2002-01-04 alex GLOBAL BOOLEAN Client_OperByMe( CLIENT *Client )
605 f7551900 2002-01-04 alex {
606 f7551900 2002-01-04 alex assert( Client != NULL );
607 f7551900 2002-01-04 alex return Client->oper_by_me;
608 f7551900 2002-01-04 alex } /* Client_OperByMe */
609 f7551900 2002-01-04 alex
610 f7551900 2002-01-04 alex
611 f7551900 2002-01-04 alex GLOBAL INT Client_Hops( CLIENT *Client )
612 f7551900 2002-01-04 alex {
613 f7551900 2002-01-04 alex assert( Client != NULL );
614 f7551900 2002-01-04 alex return Client->hops;
615 f7551900 2002-01-04 alex } /* Client_Hops */
616 f7551900 2002-01-04 alex
617 f7551900 2002-01-04 alex
618 f7551900 2002-01-04 alex GLOBAL INT Client_Token( CLIENT *Client )
619 f7551900 2002-01-04 alex {
620 f7551900 2002-01-04 alex assert( Client != NULL );
621 f7551900 2002-01-04 alex return Client->token;
622 f7551900 2002-01-04 alex } /* Client_Token */
623 a53857b4 2002-01-07 alex
624 a53857b4 2002-01-07 alex
625 a53857b4 2002-01-07 alex GLOBAL INT Client_MyToken( CLIENT *Client )
626 a53857b4 2002-01-07 alex {
627 a53857b4 2002-01-07 alex assert( Client != NULL );
628 a53857b4 2002-01-07 alex return Client->mytoken;
629 a53857b4 2002-01-07 alex } /* Client_MyToken */
630 f7551900 2002-01-04 alex
631 f7551900 2002-01-04 alex
632 e7be3a01 2002-01-05 alex GLOBAL CLIENT *Client_NextHop( CLIENT *Client )
633 e7be3a01 2002-01-05 alex {
634 e7be3a01 2002-01-05 alex CLIENT *c;
635 e7be3a01 2002-01-05 alex
636 e7be3a01 2002-01-05 alex assert( Client != NULL );
637 e7be3a01 2002-01-05 alex
638 e7be3a01 2002-01-05 alex c = Client;
639 e7be3a01 2002-01-05 alex while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server )) c = c->introducer;
640 e7be3a01 2002-01-05 alex return c;
641 e7be3a01 2002-01-05 alex } /* Client_NextHop */
642 e7be3a01 2002-01-05 alex
643 e7be3a01 2002-01-05 alex
644 f7551900 2002-01-04 alex GLOBAL CHAR *Client_Mask( CLIENT *Client )
645 f7551900 2002-01-04 alex {
646 f7551900 2002-01-04 alex /* Client-"ID" liefern, wie sie z.B. fuer
647 f7551900 2002-01-04 alex * Prefixe benoetigt wird. */
648 f7551900 2002-01-04 alex
649 f7551900 2002-01-04 alex assert( Client != NULL );
650 f7551900 2002-01-04 alex
651 f7551900 2002-01-04 alex if( Client->type == CLIENT_SERVER ) return Client->id;
652 f7551900 2002-01-04 alex
653 f7551900 2002-01-04 alex sprintf( GetID_Buffer, "%s!%s@%s", Client->id, Client->user, Client->host );
654 f7551900 2002-01-04 alex return GetID_Buffer;
655 f7551900 2002-01-04 alex } /* Client_Mask */
656 f7551900 2002-01-04 alex
657 f7551900 2002-01-04 alex
658 f7551900 2002-01-04 alex GLOBAL CLIENT *Client_Introducer( CLIENT *Client )
659 f7551900 2002-01-04 alex {
660 f7551900 2002-01-04 alex assert( Client != NULL );
661 f7551900 2002-01-04 alex return Client->introducer;
662 f7551900 2002-01-04 alex } /* Client_Introducer */
663 f7551900 2002-01-04 alex
664 f7551900 2002-01-04 alex
665 1ab92bb9 2002-01-29 alex GLOBAL CLIENT *Client_TopServer( CLIENT *Client )
666 1ab92bb9 2002-01-29 alex {
667 1ab92bb9 2002-01-29 alex assert( Client != NULL );
668 1ab92bb9 2002-01-29 alex return Client->topserver;
669 1ab92bb9 2002-01-29 alex } /* Client_TopServer */
670 1ab92bb9 2002-01-29 alex
671 1ab92bb9 2002-01-29 alex
672 f7551900 2002-01-04 alex GLOBAL BOOLEAN Client_HasMode( CLIENT *Client, CHAR Mode )
673 f7551900 2002-01-04 alex {
674 f7551900 2002-01-04 alex assert( Client != NULL );
675 f7551900 2002-01-04 alex return strchr( Client->modes, Mode ) != NULL;
676 f7551900 2002-01-04 alex } /* Client_HasMode */
677 c4850124 2002-02-27 alex
678 c4850124 2002-02-27 alex
679 c4850124 2002-02-27 alex GLOBAL CHAR *Client_Away( CLIENT *Client )
680 c4850124 2002-02-27 alex {
681 c4850124 2002-02-27 alex /* AWAY-Text liefern */
682 c4850124 2002-02-27 alex
683 c4850124 2002-02-27 alex assert( Client != NULL );
684 c4850124 2002-02-27 alex return Client->away;
685 c4850124 2002-02-27 alex } /* Client_Away */
686 f7551900 2002-01-04 alex
687 f7551900 2002-01-04 alex
688 08cf5607 2001-12-26 alex GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
689 08cf5607 2001-12-26 alex {
690 08cf5607 2001-12-26 alex /* Nick ueberpruefen */
691 08cf5607 2001-12-26 alex
692 08cf5607 2001-12-26 alex assert( Client != NULL );
693 08cf5607 2001-12-26 alex assert( Nick != NULL );
694 08cf5607 2001-12-26 alex
695 33944e8c 2002-02-06 alex /* Nick ungueltig? */
696 9f3a9df2 2002-02-17 alex if( ! Client_IsValidNick( Nick ))
697 9f3a9df2 2002-02-17 alex {
698 9f3a9df2 2002-02-17 alex IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
699 9f3a9df2 2002-02-17 alex return FALSE;
700 9f3a9df2 2002-02-17 alex }
701 08cf5607 2001-12-26 alex
702 08cf5607 2001-12-26 alex /* Nick bereits vergeben? */
703 b5c16c22 2002-03-25 alex if( Client_Search( Nick ))
704 08cf5607 2001-12-26 alex {
705 b5c16c22 2002-03-25 alex /* den Nick gibt es bereits */
706 b5c16c22 2002-03-25 alex IRC_WriteStrClient( Client, ERR_NICKNAMEINUSE_MSG, Client_ID( Client ), Nick );
707 b5c16c22 2002-03-25 alex return FALSE;
708 08cf5607 2001-12-26 alex }
709 08cf5607 2001-12-26 alex
710 08cf5607 2001-12-26 alex return TRUE;
711 08cf5607 2001-12-26 alex } /* Client_CheckNick */
712 07903baa 2002-01-03 alex
713 07903baa 2002-01-03 alex
714 07903baa 2002-01-03 alex GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID )
715 07903baa 2002-01-03 alex {
716 07903baa 2002-01-03 alex /* Nick ueberpruefen */
717 07903baa 2002-01-03 alex
718 07903baa 2002-01-03 alex CHAR str[COMMAND_LEN];
719 07903baa 2002-01-03 alex CLIENT *c;
720 07903baa 2002-01-03 alex
721 07903baa 2002-01-03 alex assert( Client != NULL );
722 07903baa 2002-01-03 alex assert( Client->conn_id > NONE );
723 07903baa 2002-01-03 alex assert( ID != NULL );
724 07903baa 2002-01-03 alex
725 07903baa 2002-01-03 alex /* Nick zu lang? */
726 9f3a9df2 2002-02-17 alex if( strlen( ID ) > CLIENT_ID_LEN )
727 9f3a9df2 2002-02-17 alex {
728 9f3a9df2 2002-02-17 alex IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID );
729 9f3a9df2 2002-02-17 alex return FALSE;
730 9f3a9df2 2002-02-17 alex }
731 08cf5607 2001-12-26 alex
732 07903baa 2002-01-03 alex /* ID bereits vergeben? */
733 07903baa 2002-01-03 alex c = My_Clients;
734 07903baa 2002-01-03 alex while( c )
735 07903baa 2002-01-03 alex {
736 f7551900 2002-01-04 alex if( strcasecmp( c->id, ID ) == 0 )
737 07903baa 2002-01-03 alex {
738 07903baa 2002-01-03 alex /* die Server-ID gibt es bereits */
739 07903baa 2002-01-03 alex sprintf( str, "ID \"%s\" already registered!", ID );
740 79809118 2002-01-06 alex Log( LOG_ERR, "%s (on connection %d)", str, Client->conn_id );
741 79809118 2002-01-06 alex Conn_Close( Client->conn_id, str, str, TRUE );
742 07903baa 2002-01-03 alex return FALSE;
743 07903baa 2002-01-03 alex }
744 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
745 07903baa 2002-01-03 alex }
746 08cf5607 2001-12-26 alex
747 07903baa 2002-01-03 alex return TRUE;
748 07903baa 2002-01-03 alex } /* Client_CheckID */
749 07903baa 2002-01-03 alex
750 07903baa 2002-01-03 alex
751 fb9d6ce1 2001-12-31 alex GLOBAL CLIENT *Client_First( VOID )
752 fb9d6ce1 2001-12-31 alex {
753 fb9d6ce1 2001-12-31 alex /* Ersten Client liefern. */
754 fb9d6ce1 2001-12-31 alex
755 fb9d6ce1 2001-12-31 alex return My_Clients;
756 fb9d6ce1 2001-12-31 alex } /* Client_First */
757 15764f98 2001-12-27 alex
758 15764f98 2001-12-27 alex
759 fb9d6ce1 2001-12-31 alex GLOBAL CLIENT *Client_Next( CLIENT *c )
760 fb9d6ce1 2001-12-31 alex {
761 fb9d6ce1 2001-12-31 alex /* Naechsten Client liefern. Existiert keiner,
762 fb9d6ce1 2001-12-31 alex * so wird NULL geliefert. */
763 fb9d6ce1 2001-12-31 alex
764 fb9d6ce1 2001-12-31 alex assert( c != NULL );
765 95a4b1b1 2002-03-25 alex return (CLIENT *)c->next;
766 fb9d6ce1 2001-12-31 alex } /* Client_Next */
767 b9d701db 2002-01-16 alex
768 b9d701db 2002-01-16 alex
769 b9d701db 2002-01-16 alex GLOBAL INT Client_UserCount( VOID )
770 b9d701db 2002-01-16 alex {
771 b9d701db 2002-01-16 alex return Count( CLIENT_USER );
772 b9d701db 2002-01-16 alex } /* Client_UserCount */
773 b9d701db 2002-01-16 alex
774 b9d701db 2002-01-16 alex
775 b9d701db 2002-01-16 alex GLOBAL INT Client_ServiceCount( VOID )
776 b9d701db 2002-01-16 alex {
777 b9d701db 2002-01-16 alex return Count( CLIENT_SERVICE );;
778 b9d701db 2002-01-16 alex } /* Client_ServiceCount */
779 b9d701db 2002-01-16 alex
780 b9d701db 2002-01-16 alex
781 b9d701db 2002-01-16 alex GLOBAL INT Client_ServerCount( VOID )
782 b9d701db 2002-01-16 alex {
783 b9d701db 2002-01-16 alex return Count( CLIENT_SERVER );
784 b9d701db 2002-01-16 alex } /* Client_ServerCount */
785 b9d701db 2002-01-16 alex
786 b9d701db 2002-01-16 alex
787 b9d701db 2002-01-16 alex GLOBAL INT Client_MyUserCount( VOID )
788 b9d701db 2002-01-16 alex {
789 b9d701db 2002-01-16 alex return MyCount( CLIENT_USER );
790 b9d701db 2002-01-16 alex } /* Client_MyUserCount */
791 b9d701db 2002-01-16 alex
792 b9d701db 2002-01-16 alex
793 b9d701db 2002-01-16 alex GLOBAL INT Client_MyServiceCount( VOID )
794 b9d701db 2002-01-16 alex {
795 b9d701db 2002-01-16 alex return MyCount( CLIENT_SERVICE );
796 b9d701db 2002-01-16 alex } /* Client_MyServiceCount */
797 b9d701db 2002-01-16 alex
798 b9d701db 2002-01-16 alex
799 b9d701db 2002-01-16 alex GLOBAL INT Client_MyServerCount( VOID )
800 b9d701db 2002-01-16 alex {
801 b9d701db 2002-01-16 alex return MyCount( CLIENT_SERVER );
802 b9d701db 2002-01-16 alex } /* Client_MyServerCount */
803 b9d701db 2002-01-16 alex
804 b9d701db 2002-01-16 alex
805 b9d701db 2002-01-16 alex GLOBAL INT Client_OperCount( VOID )
806 b9d701db 2002-01-16 alex {
807 b9d701db 2002-01-16 alex CLIENT *c;
808 b9d701db 2002-01-16 alex INT cnt;
809 b9d701db 2002-01-16 alex
810 b9d701db 2002-01-16 alex cnt = 0;
811 b9d701db 2002-01-16 alex c = My_Clients;
812 b9d701db 2002-01-16 alex while( c )
813 b9d701db 2002-01-16 alex {
814 b9d701db 2002-01-16 alex if( c && ( c->type == CLIENT_USER ) && ( strchr( c->modes, 'o' ))) cnt++;
815 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
816 b9d701db 2002-01-16 alex }
817 b9d701db 2002-01-16 alex return cnt;
818 b9d701db 2002-01-16 alex } /* Client_OperCount */
819 fb9d6ce1 2001-12-31 alex
820 fb9d6ce1 2001-12-31 alex
821 b9d701db 2002-01-16 alex GLOBAL INT Client_UnknownCount( VOID )
822 b9d701db 2002-01-16 alex {
823 b9d701db 2002-01-16 alex CLIENT *c;
824 b9d701db 2002-01-16 alex INT cnt;
825 b9d701db 2002-01-16 alex
826 b9d701db 2002-01-16 alex cnt = 0;
827 b9d701db 2002-01-16 alex c = My_Clients;
828 b9d701db 2002-01-16 alex while( c )
829 b9d701db 2002-01-16 alex {
830 b9d701db 2002-01-16 alex if( c && ( c->type != CLIENT_USER ) && ( c->type != CLIENT_SERVICE ) && ( c->type != CLIENT_SERVER )) cnt++;
831 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
832 b9d701db 2002-01-16 alex }
833 b9d701db 2002-01-16 alex return cnt;
834 b9d701db 2002-01-16 alex } /* Client_UnknownCount */
835 b9d701db 2002-01-16 alex
836 b9d701db 2002-01-16 alex
837 33944e8c 2002-02-06 alex GLOBAL BOOLEAN Client_IsValidNick( CHAR *Nick )
838 33944e8c 2002-02-06 alex {
839 33944e8c 2002-02-06 alex /* Ist der Nick gueltig? */
840 7157d936 2002-03-02 alex
841 96585575 2002-03-10 alex CHAR *ptr, goodchars[] = ";0123456789-";
842 33944e8c 2002-02-06 alex
843 33944e8c 2002-02-06 alex assert( Nick != NULL );
844 33944e8c 2002-02-06 alex
845 33944e8c 2002-02-06 alex if( Nick[0] == '#' ) return FALSE;
846 7157d936 2002-03-02 alex if( strchr( goodchars, Nick[0] )) return FALSE;
847 7157d936 2002-03-02 alex if( strlen( Nick ) >= CLIENT_NICK_LEN ) return FALSE;
848 7157d936 2002-03-02 alex
849 7157d936 2002-03-02 alex ptr = Nick;
850 7157d936 2002-03-02 alex while( *ptr )
851 7157d936 2002-03-02 alex {
852 7157d936 2002-03-02 alex if(( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return FALSE;
853 7157d936 2002-03-02 alex if(( *ptr > '}' ) && ( ! strchr( goodchars, *ptr ))) return FALSE;
854 7157d936 2002-03-02 alex ptr++;
855 7157d936 2002-03-02 alex }
856 7157d936 2002-03-02 alex
857 33944e8c 2002-02-06 alex return TRUE;
858 33944e8c 2002-02-06 alex } /* Client_IsValidNick */
859 33944e8c 2002-02-06 alex
860 33944e8c 2002-02-06 alex
861 b9d701db 2002-01-16 alex LOCAL INT Count( CLIENT_TYPE Type )
862 b9d701db 2002-01-16 alex {
863 b9d701db 2002-01-16 alex CLIENT *c;
864 b9d701db 2002-01-16 alex INT cnt;
865 b9d701db 2002-01-16 alex
866 b9d701db 2002-01-16 alex cnt = 0;
867 b9d701db 2002-01-16 alex c = My_Clients;
868 b9d701db 2002-01-16 alex while( c )
869 b9d701db 2002-01-16 alex {
870 b9d701db 2002-01-16 alex if( c && ( c->type == Type )) cnt++;
871 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
872 b9d701db 2002-01-16 alex }
873 b9d701db 2002-01-16 alex return cnt;
874 b9d701db 2002-01-16 alex } /* Count */
875 b9d701db 2002-01-16 alex
876 b9d701db 2002-01-16 alex
877 b9d701db 2002-01-16 alex LOCAL INT MyCount( CLIENT_TYPE Type )
878 b9d701db 2002-01-16 alex {
879 b9d701db 2002-01-16 alex CLIENT *c;
880 b9d701db 2002-01-16 alex INT cnt;
881 b9d701db 2002-01-16 alex
882 b9d701db 2002-01-16 alex cnt = 0;
883 b9d701db 2002-01-16 alex c = My_Clients;
884 b9d701db 2002-01-16 alex while( c )
885 b9d701db 2002-01-16 alex {
886 b9d701db 2002-01-16 alex if( c && ( c->introducer == This_Server ) && ( c->type == Type )) cnt++;
887 95a4b1b1 2002-03-25 alex c = (CLIENT *)c->next;
888 b9d701db 2002-01-16 alex }
889 b9d701db 2002-01-16 alex return cnt;
890 b9d701db 2002-01-16 alex } /* MyCount */
891 b9d701db 2002-01-16 alex
892 b9d701db 2002-01-16 alex
893 38b9cb88 2001-12-14 alex LOCAL CLIENT *New_Client_Struct( VOID )
894 38b9cb88 2001-12-14 alex {
895 d0ac1e9c 2001-12-23 alex /* Neue CLIENT-Struktur pre-initialisieren */
896 d0ac1e9c 2001-12-23 alex
897 38b9cb88 2001-12-14 alex CLIENT *c;
898 38b9cb88 2001-12-14 alex
899 38b9cb88 2001-12-14 alex c = malloc( sizeof( CLIENT ));
900 38b9cb88 2001-12-14 alex if( ! c )
901 38b9cb88 2001-12-14 alex {
902 38b9cb88 2001-12-14 alex Log( LOG_EMERG, "Can't allocate memory!" );
903 38b9cb88 2001-12-14 alex return NULL;
904 38b9cb88 2001-12-14 alex }
905 38b9cb88 2001-12-14 alex
906 38b9cb88 2001-12-14 alex c->next = NULL;
907 b5c16c22 2002-03-25 alex c->hash = 0;
908 38b9cb88 2001-12-14 alex c->type = CLIENT_UNKNOWN;
909 38b9cb88 2001-12-14 alex c->conn_id = NONE;
910 38b9cb88 2001-12-14 alex c->introducer = NULL;
911 1ab92bb9 2002-01-29 alex c->topserver = NULL;
912 f7551900 2002-01-04 alex strcpy( c->id, "" );
913 f7551900 2002-01-04 alex strcpy( c->pwd, "" );
914 d0ac1e9c 2001-12-23 alex strcpy( c->host, "" );
915 d0ac1e9c 2001-12-23 alex strcpy( c->user, "" );
916 804b1ec4 2001-12-31 alex strcpy( c->info, "" );
917 f0dacce9 2001-12-29 alex strcpy( c->modes, "" );
918 804b1ec4 2001-12-31 alex c->oper_by_me = FALSE;
919 f7551900 2002-01-04 alex c->hops = -1;
920 f7551900 2002-01-04 alex c->token = -1;
921 a53857b4 2002-01-07 alex c->mytoken = -1;
922 c4850124 2002-02-27 alex strcpy( c->away, "" );
923 d0ac1e9c 2001-12-23 alex
924 38b9cb88 2001-12-14 alex return c;
925 38b9cb88 2001-12-14 alex } /* New_Client */
926 38b9cb88 2001-12-14 alex
927 38b9cb88 2001-12-14 alex
928 a53857b4 2002-01-07 alex LOCAL VOID Generate_MyToken( CLIENT *Client )
929 a53857b4 2002-01-07 alex {
930 a53857b4 2002-01-07 alex CLIENT *c;
931 a53857b4 2002-01-07 alex INT token;
932 a53857b4 2002-01-07 alex
933 a53857b4 2002-01-07 alex c = My_Clients;
934 a53857b4 2002-01-07 alex token = 2;
935 a53857b4 2002-01-07 alex while( c )
936 a53857b4 2002-01-07 alex {
937 a53857b4 2002-01-07 alex if( c->mytoken == token )
938 a53857b4 2002-01-07 alex {
939 a53857b4 2002-01-07 alex /* Das Token wurde bereits vergeben */
940 a53857b4 2002-01-07 alex token++;
941 a53857b4 2002-01-07 alex c = My_Clients;
942 a53857b4 2002-01-07 alex continue;
943 a53857b4 2002-01-07 alex }
944 95a4b1b1 2002-03-25 alex else c = (CLIENT *)c->next;
945 a53857b4 2002-01-07 alex }
946 a53857b4 2002-01-07 alex Client->mytoken = token;
947 a53857b4 2002-01-07 alex Log( LOG_DEBUG, "Assigned token %d to server \"%s\".", token, Client->id );
948 a53857b4 2002-01-07 alex } /* Generate_MyToken */
949 a53857b4 2002-01-07 alex
950 a53857b4 2002-01-07 alex
951 38b9cb88 2001-12-14 alex /* -eof- */