]> arthur.barton.de Git - ngircd-alex.git/blob - src/ngircd/conf.c
- Handling von "--version" und "--help" nochmal geaendert ...
[ngircd-alex.git] / src / ngircd / conf.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: conf.c,v 1.16 2002/03/10 17:50:48 alex Exp $
13  *
14  * conf.h: Konfiguration des ngircd
15  *
16  * $Log: conf.c,v $
17  * Revision 1.16  2002/03/10 17:50:48  alex
18  * - Handling von "--version" und "--help" nochmal geaendert ...
19  *
20  * Revision 1.15  2002/03/06 15:35:19  alex
21  * - Dateinamen und Pfad sind nun in Konstanten definiert.
22  *
23  * Revision 1.14  2002/03/03 17:17:01  alex
24  * - strncpy() und vsnprintf() kopieren nun etwas "optimierter" (1 Byte weniger) :-)
25  *
26  * Revision 1.13  2002/01/18 15:51:44  alex
27  * - Server-Verbinungen werden beim Start erst nach kurzer Pause aufgebaut.
28  *
29  * Revision 1.12  2002/01/05 23:26:24  alex
30  * - Fehlermeldungen korrigiert.
31  *
32  * Revision 1.11  2002/01/05 16:51:49  alex
33  * - Bug bei Remote-Server-Namen entfernt: diese wurden falsch gekuerzt.
34  *
35  * Revision 1.10  2002/01/03 02:27:20  alex
36  * - das Server-Passwort kann nun konfiguriert werden.
37  *
38  * Revision 1.9  2002/01/02 02:49:15  alex
39  * - Konfigurationsdatei "Samba like" umgestellt.
40  * - es koennen nun mehrere Server und Oprtatoren konfiguriert werden.
41  *
42  * Revision 1.7  2002/01/01 18:25:44  alex
43  * - #include's fuer stdlib.h ergaenzt.
44  *
45  * Revision 1.6  2001/12/31 02:18:51  alex
46  * - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
47  * - neuen Header "defines.h" mit (fast) allen Konstanten.
48  * - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
49  *
50  * Revision 1.5  2001/12/30 19:26:11  alex
51  * - Unterstuetzung fuer die Konfigurationsdatei eingebaut.
52  *
53  * Revision 1.4  2001/12/26 22:48:53  alex
54  * - MOTD-Datei ist nun konfigurierbar und wird gelesen.
55  *
56  * Revision 1.3  2001/12/26 14:45:37  alex
57  * - "Code Cleanups".
58  *
59  * Revision 1.2  2001/12/26 03:19:57  alex
60  * - erste Konfigurations-Variablen definiert: PING/PONG-Timeout.
61  *
62  * Revision 1.1  2001/12/12 17:18:20  alex
63  * - Modul fuer Server-Konfiguration begonnen.
64  */
65
66
67 #include <portab.h>
68 #include "global.h"
69
70 #include <imp.h>
71 #include <assert.h>
72 #include <errno.h>
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <string.h>
76
77 #include "client.h"
78 #include "log.h"
79 #include "tool.h"
80
81 #include <exp.h>
82 #include "conf.h"
83
84
85 LOCAL VOID Read_Config( VOID );
86
87 GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg );
88 GLOBAL VOID Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg );
89 GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg );
90
91 LOCAL VOID Validate_Config( VOID );
92
93
94 GLOBAL VOID Conf_Init( VOID )
95 {
96         /* Konfigurationsvariablen initialisieren: zunaechst Default-
97          * Werte setzen, dann Konfigurationsdtaei einlesen. */
98
99         strcpy( Conf_File, CONFIG_FILE );
100
101         strcpy( Conf_ServerName, "" );
102         strcpy( Conf_ServerInfo, PACKAGE" "VERSION );
103         strcpy( Conf_ServerPwd, "" );
104
105         strcpy( Conf_MotdFile, MOTD_FILE );
106
107         Conf_ListenPorts_Count = 0;
108         
109         Conf_PingTimeout = 120;
110         Conf_PongTimeout = 10;
111
112         Conf_ConnectRetry = 60;
113
114         Conf_Oper_Count = 0;
115
116         Conf_Server_Count = 0;
117
118         /* Konfigurationsdatei einlesen und validieren */
119         Read_Config( );
120         Validate_Config( );
121 } /* Config_Init */
122
123
124 GLOBAL VOID Conf_Exit( VOID )
125 {
126         /* ... */
127 } /* Config_Exit */
128
129
130 LOCAL VOID Read_Config( VOID )
131 {
132         /* Konfigurationsdatei einlesen. */
133
134         CHAR section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
135         INT line;
136         FILE *fd;
137
138         fd = fopen( Conf_File, "r" );
139         if( ! fd )
140         {
141                 /* Keine Konfigurationsdatei gefunden */
142                 Log( LOG_ALERT, "Can't read configuration \"%s\": %s", Conf_File, strerror( errno ));
143                 Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
144                 exit( 1 );
145         }
146
147         line = 0;
148         strcpy( section, "" );
149         while( TRUE )
150         {
151                 if( ! fgets( str, LINE_LEN, fd )) break;
152                 ngt_TrimStr( str );
153                 line++;
154
155                 /* Kommentarzeilen und leere Zeilen ueberspringen */
156                 if( str[0] == ';' || str[0] == '#' || str[0] == '\0' ) continue;
157
158                 /* Anfang eines Abschnittes? */
159                 if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' ))
160                 {
161                         strcpy( section, str );
162                         if( strcasecmp( section, "[GLOBAL]" ) == 0 ) continue;
163                         if( strcasecmp( section, "[OPERATOR]" ) == 0 )
164                         {
165                                 if( Conf_Oper_Count + 1 > MAX_OPERATORS ) Log( LOG_ERR, "Too many operators configured." );
166                                 else
167                                 {
168                                         /* neuen Operator initialisieren */
169                                         strcpy( Conf_Oper[Conf_Oper_Count].name, "" );
170                                         strcpy( Conf_Oper[Conf_Oper_Count].pwd, "" );
171                                         Conf_Oper_Count++;
172                                 }
173                                 continue;
174                         }
175                         if( strcasecmp( section, "[SERVER]" ) == 0 )
176                         {
177                                 if( Conf_Server_Count + 1 > MAX_SERVERS ) Log( LOG_ERR, "Too many servers configured." );
178                                 else
179                                 {
180                                         /* neuen Server ("Peer") initialisieren */
181                                         strcpy( Conf_Server[Conf_Server_Count].host, "" );
182                                         strcpy( Conf_Server[Conf_Server_Count].ip, "" );
183                                         strcpy( Conf_Server[Conf_Server_Count].name, "" );
184                                         strcpy( Conf_Server[Conf_Server_Count].pwd, "" );
185                                         Conf_Server[Conf_Server_Count].port = 0;
186                                         Conf_Server[Conf_Server_Count].group = -1;
187                                         Conf_Server[Conf_Server_Count].lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY;
188                                         Conf_Server[Conf_Server_Count].res_stat = NULL;
189                                         Conf_Server_Count++;
190                                 }
191                                 continue;
192                         }
193                         Log( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", Conf_File, line, section );
194                         section[0] = 0x1;
195                 }
196                 if( section[0] == 0x1 ) continue;
197
198                 /* In Variable und Argument zerlegen */
199                 ptr = strchr( str, '=' );
200                 if( ! ptr )
201                 {
202                         Log( LOG_ERR, "%s, line %d: Syntax error!", Conf_File, line );
203                         continue;
204                 }
205                 *ptr = '\0';
206                 var = str; ngt_TrimStr( var );
207                 arg = ptr + 1; ngt_TrimStr( arg );
208
209                 if( strcasecmp( section, "[GLOBAL]" ) == 0 ) Handle_GLOBAL( line, var, arg );
210                 else if( strcasecmp( section, "[OPERATOR]" ) == 0 ) Handle_OPERATOR( line, var, arg );
211                 else if( strcasecmp( section, "[SERVER]" ) == 0 ) Handle_SERVER( line, var, arg );
212                 else Log( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", Conf_File, line, var );
213         }
214         
215         fclose( fd );
216 } /* Read_Config */
217
218
219 GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
220 {
221         CHAR *ptr;
222         INT port;
223         
224         assert( Line > 0 );
225         assert( Var != NULL );
226         assert( Arg != NULL );
227         
228         if( strcasecmp( Var, "Name" ) == 0 )
229         {
230                 /* Der Server-Name */
231                 strncpy( Conf_ServerName, Arg, CLIENT_ID_LEN - 1 );
232                 Conf_ServerName[CLIENT_ID_LEN - 1] = '\0';
233                 return;
234         }
235         if( strcasecmp( Var, "Info" ) == 0 )
236         {
237                 /* Server-Info-Text */
238                 strncpy( Conf_ServerInfo, Arg, CLIENT_INFO_LEN - 1 );
239                 Conf_ServerInfo[CLIENT_INFO_LEN - 1] = '\0';
240                 return;
241         }
242         if( strcasecmp( Var, "Password" ) == 0 )
243         {
244                 /* Server-Passwort */
245                 strncpy( Conf_ServerPwd, Arg, CLIENT_PASS_LEN - 1 );
246                 Conf_ServerPwd[CLIENT_PASS_LEN - 1] = '\0';
247                 return;
248         }
249         if( strcasecmp( Var, "Ports" ) == 0 )
250         {
251                 /* Ports, durch "," getrennt, auf denen der Server
252                 * Verbindungen annehmen soll */
253                 ptr = strtok( Arg, "," );
254                 while( ptr )
255                 {
256                         ngt_TrimStr( ptr );
257                         port = atol( ptr );
258                         if( Conf_ListenPorts_Count + 1 > MAX_LISTEN_PORTS ) Log( LOG_ERR, "Too many listen ports configured. Port %ld ignored.", port );
259                         else
260                         {
261                                 if( port > 0 && port < 0xFFFF ) Conf_ListenPorts[Conf_ListenPorts_Count++] = port;
262                                 else Log( LOG_ERR, "%s, line %d (section \"Global\"): Illegal port number %ld!", Conf_File, Line, port );
263                         }
264                         ptr = strtok( NULL, "," );
265                 }
266                 return;
267         }
268         if( strcasecmp( Var, "MotdFile" ) == 0 )
269         {
270                 /* Datei mit der "message of the day" (MOTD) */
271                 strncpy( Conf_MotdFile, Arg, FNAME_LEN - 1 );
272                 Conf_MotdFile[FNAME_LEN - 1] = '\0';
273                 return;
274         }
275         if( strcasecmp( Var, "PingTimeout" ) == 0 )
276         {
277                 /* PING-Timeout */
278                 Conf_PingTimeout = atoi( Arg );
279                 if(( Conf_PingTimeout ) < 5 ) Conf_PingTimeout = 5;
280                 return;
281         }
282         if( strcasecmp( Var, "PongTimeout" ) == 0 )
283         {
284                 /* PONG-Timeout */
285                 Conf_PongTimeout = atoi( Arg );
286                 if(( Conf_PongTimeout ) < 5 ) Conf_PongTimeout = 5;
287                 return;
288         }
289         if( strcasecmp( Var, "ConnectRetry" ) == 0 )
290         {
291                 /* Sekunden zwischen Verbindungsversuchen zu anderen Servern */
292                 Conf_ConnectRetry = atoi( Arg );
293                 if(( Conf_ConnectRetry ) < 5 ) Conf_ConnectRetry = 5;
294                 return;
295         }
296                 
297         Log( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
298 } /* Handle_GLOBAL */
299
300
301 GLOBAL VOID Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
302 {
303         assert( Line > 0 );
304         assert( Var != NULL );
305         assert( Arg != NULL );
306         assert( Conf_Oper_Count > 0 );
307
308         if( strcasecmp( Var, "Name" ) == 0 )
309         {
310                 /* Name des IRC Operator */
311                 strncpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, CLIENT_ID_LEN - 1 );
312                 Conf_Oper[Conf_Oper_Count - 1].name[CLIENT_ID_LEN - 1] = '\0';
313                 return;
314         }
315         if( strcasecmp( Var, "Password" ) == 0 )
316         {
317                 /* Passwort des IRC Operator */
318                 strncpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, CLIENT_PASS_LEN - 1 );
319                 Conf_Oper[Conf_Oper_Count - 1].pwd[CLIENT_PASS_LEN - 1] = '\0';
320                 return;
321         }
322         
323         Log( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
324 } /* Handle_OPERATOR */
325
326
327 GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
328 {
329         INT32 port;
330         
331         assert( Line > 0 );
332         assert( Var != NULL );
333         assert( Arg != NULL );
334
335         if( strcasecmp( Var, "Host" ) == 0 )
336         {
337                 /* Hostname des Servers */
338                 strncpy( Conf_Server[Conf_Server_Count - 1].host, Arg, HOST_LEN - 1 );
339                 Conf_Server[Conf_Server_Count - 1].host[HOST_LEN - 1] = '\0';
340                 return;
341         }
342         if( strcasecmp( Var, "Name" ) == 0 )
343         {
344                 /* Name des Servers ("Nick") */
345                 strncpy( Conf_Server[Conf_Server_Count - 1].name, Arg, CLIENT_ID_LEN - 1 );
346                 Conf_Server[Conf_Server_Count - 1].name[CLIENT_ID_LEN - 1] = '\0';
347                 return;
348         }
349         if( strcasecmp( Var, "Password" ) == 0 )
350         {
351                 /* Passwort des Servers */
352                 strncpy( Conf_Server[Conf_Server_Count - 1].pwd, Arg, CLIENT_PASS_LEN - 1 );
353                 Conf_Server[Conf_Server_Count - 1].pwd[CLIENT_PASS_LEN - 1] = '\0';
354                 return;
355         }
356         if( strcasecmp( Var, "Port" ) == 0 )
357         {
358                 /* Port, zu dem Verbunden werden soll */
359                 port = atol( Arg );
360                 if( port > 0 && port < 0xFFFF ) Conf_Server[Conf_Server_Count - 1].port = (INT)port;
361                 else Log( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", Conf_File, Line, port );
362                 return;
363         }
364         if( strcasecmp( Var, "Group" ) == 0 )
365         {
366                 /* Server-Gruppe */
367                 Conf_Server[Conf_Server_Count - 1].group = atoi( Arg );
368                 return;
369         }
370         
371         Log( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
372 } /* Handle_SERVER */
373
374
375 LOCAL VOID Validate_Config( VOID )
376 {
377         /* Konfiguration ueberpruefen */
378         
379         if( ! Conf_ServerName[0] )
380         {
381                 /* Kein Servername konfiguriert */
382                 Log( LOG_ALERT, "No server name configured in \"%s\"!", Conf_File );
383                 Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
384                 exit( 1 );
385         }
386 } /* Validate_Config */
387
388 /* -eof- */