1 /*
2 * ----------------------------------------------------------------
3 * ircproxy - Connection Configuration Functions
4 * ----------------------------------------------------------------
5 * Copyright (C) 1997-2009 Jonas Kvinge
6 *
7 * This file is part of ircproxy.
8 *
9 * ircproxy is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * ircproxy is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ircproxy. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * Additional permission under GNU GPL version 3 section 7
23 *
24 * If you modify ircproxy, or any covered work, by linking or
25 * combining it with openssl (or a modified version of that library),
26 * containing parts covered by the terms of the OpenSSL License and the
27 * SSLeay License, the licensors of ircproxy grant you additional
28 * permission to convey the resulting work.
29 *
30 * $Id: conn_conf.c 54 2009-03-18 18:23:29Z jonasio $
31 *
32 */
33
34 #define CONN_CONF_C
35
36 #define NEED_SYS_TYPES_H 1 /* Extra types */
37 #define NEED_SYS_PARAM_H 1 /* Some systems need this */
38 #define NEED_LIMITS_H 0 /* Kernel limits */
39 #define NEED_STDARG_H 1 /* va_list, etc */
40 #define NEED_ERRNO_H 1 /* errno */
41 #define NEED_CTYPE_H 1 /* isdigit(), etc */
42 #define NEED_NETINET_IN_H 1 /* in_addr, sockaddr_in, etc */
43 #define NEED_ARPA_INET_H 0 /* inet_ntoa(), inet_aton(), etc */
44 #define NEED_STDIO_H 1 /* Standard C UNIX functions */
45 #define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */
46 #define NEED_TIME_H 1 /* time(), etc */
47 #define NEED_SYSCTL_H 0 /* sysctl(), etc */
48 #define NEED_SYS_STAT_H 0 /* chmod(), mkdir(), etc */
49 #define NEED_SYS_UIO_H 0 /* iovec, etc */
50 #define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */
51 #define NEED_SYS_IOCTL_H 0 /* ioctl(), etc */
52 #define NEED_SYS_FILIO_H 0 /* Solaris need this for ioctl(), etc */
53 #define NEED_UNISTD_H 1 /* Unix standard functions */
54 #define NEED_STRING_H 1 /* C string functions */
55 #define NEED_SIGNAL_H 0 /* Signal functions */
56 #define NEED_SYS_SOCKET_H 0 /* Socket functions */
57 #define NEED_NETDB_H 0 /* Network database functions */
58 #define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */
59 #define NEED_GETUSERPW_HEADERS 0 /* Functions to retrive system passwords */
60 #define NEED_ARES 0 /* Functions needed for ares */
61 #define NEED_SSL 1 /* Needed for SSL support */
62
63 #include "includes.h"
64 #include "irc.h"
65
66 #include "conf.h"
67
68 #include "conn_conf.h"
69 #include "conn.h"
70
71 /* VARIABLES - JONAS (31.07.2001) */
72
73 unsigned long int ConnConfs = 0;
74
75 struct ConnConf_Struct *ConnConf_Head = NULL;
76 struct ConnConf_Struct *ConnConf_Tail = NULL;
77
78 extern struct Conf_Struct ConfS;
79 extern unsigned short int Root;
80
81 /* CONN_CONF_READ FUNCTION - JONAS (31.07.2001) */
82
conn_conf_read(void)83 signed long int conn_conf_read(void) {
84
85 char File[FILELEN+1] = "";
86 FILE *FilePT = NULL;
87
88 char *TempPT = NULL;
89
90 char Line[LINELEN+1] = "";
91 char *LinePT = NULL;
92
93 unsigned short int Count = 0;
94
95 char *EntryPT = NULL;
96
97 struct ConnConf_Struct *ConnConf = NULL;
98 struct ConnConfServer_Struct *ConnConfServer = NULL;
99
100 struct Conn_Struct *ConnS = NULL;
101
102 unsigned short int NextLineIsAServer = 0;
103 unsigned short int UnsignedShortInt = 0;
104
105 DEBUGPRINT(BITMASK_DEBUG_CONF, "Reading connection configuration file.");
106
107 if (ConfS.ConnConfFile[0] != '/') {
108 strncat(File, ConfS.DataPath, FILELEN);
109 if (ConfS.DataPath[strlen(ConfS.DataPath)] != '/') { strncat(File, "/", (FILELEN - strlen(File))); }
110 }
111 strncat(File, ConfS.ConnConfFile, (FILELEN - strlen(File)));
112
113 FilePT = fopen(File, "r");
114 if (FilePT == NULL) {
115 sysprint(BITMASK_ERROR, "Unable to open connection configuration file %s: [%d] %s", File, errno, strerror(errno));
116 return(ERROR);
117 }
118
119 conn_conf_destroy();
120
121 FOREVERLOOP {
122
123 memset(&Line, 0, LINELEN+1);
124 TempPT = fgets(Line, LINELEN, FilePT);
125 if (TempPT == NULL) { break; }
126 ++Count;
127 LinePT = Line;
128
129 while ((TempPT = strchr(LinePT, '\r')) != NULL) { *TempPT = '\0'; }
130 while ((TempPT = strchr(LinePT, '\n')) != NULL) { *TempPT = '\0'; }
131 while ((TempPT = strchr(LinePT, '\t')) != NULL) { *TempPT = ' '; }
132
133 while ((LinePT[0] == ' ') || (LinePT[0] == '\t')) { ++LinePT; }
134 if ((LinePT[0] == '#') || (LinePT[0] == ';') || (LinePT[0] == '\0')) { continue; }
135
136 EntryPT = LinePT;
137 StrMovePastToken(LinePT, ' ');
138
139 if (NextLineIsAServer == TRUE) {
140
141 char *HostPT = CONN_CONF_SERVERHOST_DEFAULT;
142 char *PortPT = CONN_CONF_SERVERPORT_DEFAULT;
143 char *PassPT = CONN_CONF_SERVERPASS_DEFAULT;
144
145 if (EntryPT[0] == '}') { /* End of server list */
146 NextLineIsAServer = FALSE;
147 continue;
148 }
149
150 HostPT = EntryPT;
151 StrMovePastToken(EntryPT, ':');
152
153 if (EntryPT != NULL) {
154 PortPT = EntryPT;
155 StrMovePastToken(EntryPT, ':');
156 }
157
158 if (LinePT != NULL) {
159 PassPT = LinePT;
160 StrMovePastToken(EntryPT, ':');
161 }
162
163 if (ConnConf != NULL) conn_conf_addserver(ConnConf, HostPT, strtoul(PortPT, NULL, 0), PassPT);
164 continue;
165 }
166
167 if (strcasecmp(EntryPT, "CONNECTION") == FALSE) {
168
169 char *NamePT = NULL;
170
171 if (LinePT == NULL) {
172 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Expecting connection name for \"CONNECTION\" definition.", File, Count);
173 continue;
174 }
175 NamePT = LinePT;
176 StrMovePastToken(LinePT, ' ');
177 ConnConf = conn_conf_add(NamePT);
178 assert(ConnConf != NULL);
179 continue;
180 }
181 if (EntryPT[0] == '}') { ConnConf = NULL; continue; } /* End of connection */
182
183 if (ConnConf == NULL) {
184 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Entry \"%s\" is invalid before a \"CONNECTION <Name> {\" definition.", File, Count, EntryPT);
185 continue;
186 }
187
188 if (strcasecmp(EntryPT, "NICK") == FALSE) {
189 if (LinePT == NULL) {
190 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in NICK definition.", File, Count);
191 continue;
192 }
193 ConnConf->Nick = strrealloc(ConnConf->Nick, LinePT);
194 continue;
195 }
196 else if (strcasecmp(EntryPT, "AWAYNICK") == FALSE) {
197 if (LinePT == NULL) {
198 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in AWAYNICK definition.", File, Count);
199 continue;
200 }
201 ConnConf->AwayNick = strrealloc(ConnConf->AwayNick, LinePT);
202 continue;
203 }
204 else if (strcasecmp(EntryPT, "USER") == FALSE) {
205 if (LinePT == NULL) {
206 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in USER definition.", File, Count);
207 continue;
208 }
209 ConnConf->User = strrealloc(ConnConf->User, LinePT);
210 continue;
211 }
212 else if (strcasecmp(EntryPT, "HOST") == FALSE) {
213 if (LinePT == NULL) {
214 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in HOST definition.", File, Count);
215 continue;
216 }
217 ConnConf->Host = strrealloc(ConnConf->Host, LinePT);
218 continue;
219 }
220 else if (strcasecmp(EntryPT, "SERVERS") == FALSE) {
221 if (LinePT == NULL) {
222 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing \"{\" in SERVERS definition.", File, Count);
223 continue;
224 }
225 if (LinePT[0] == '{') { NextLineIsAServer = TRUE; continue; }
226 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Invalid SERVERS definition.", File, Count);
227 continue;
228 }
229 else if ((strcasecmp(EntryPT, "MODE") == FALSE) || (strcasecmp(EntryPT, "USERMODE") == FALSE)) {
230 if (LinePT == NULL) {
231 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in USERMODE definition.", File, Count);
232 continue;
233 }
234 ConnConf->Mode = strrealloc(ConnConf->Mode, LinePT);
235 continue;
236 }
237 else if ((strcasecmp(EntryPT, "INFO") == FALSE) || (strcasecmp(EntryPT, "USERINFO") == FALSE)) {
238 if (LinePT == NULL) {
239 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in USERINFO definition.", File, Count);
240 continue;
241 }
242 ConnConf->Info = strrealloc(ConnConf->Info, LinePT);
243 continue;
244 }
245 else if ((strcasecmp(EntryPT, "CHANS") == FALSE) || (strcasecmp(EntryPT, "CHANNELS") == FALSE)) {
246 if (LinePT == NULL) {
247 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in CHANNELS definition.", File, Count);
248 continue;
249 }
250 ConnConf->Chans = strrealloc(ConnConf->Chans, LinePT);
251 continue;
252 }
253 else if (strcasecmp(EntryPT, "IPV6") == FALSE) {
254 if (LinePT == NULL) {
255 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for IPV6 definition.", File, Count);
256 continue;
257 }
258 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_IPV6; }
259 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_IPV6; }
260 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: IPV6 definition must be yes/no or 1/0.", File, Count); }
261 continue;
262 }
263 else if (strcasecmp(EntryPT, "SSL") == FALSE) {
264 if (LinePT == NULL) {
265 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for SSL definition.", File, Count);
266 continue;
267 }
268 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_SSL; }
269 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_SSL; }
270 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: SSL definition must be yes/no or 1/0.", File, Count); }
271 continue;
272 }
273 else if (strcasecmp(EntryPT, "AUTOCONNECT") == FALSE) {
274 if (LinePT == NULL) {
275 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for AUTOCONNECT definition.", File, Count);
276 continue;
277 }
278 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_AUTOCONNECT; }
279 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_AUTOCONNECT; }
280 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: AUTOCONNECT definition must be yes/no or 1/0.", File, Count); }
281 continue;
282 }
283 else if (strcasecmp(EntryPT, "LOGGING") == FALSE) {
284 if (LinePT == NULL) {
285 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for LOGGING definition.", File, Count);
286 continue;
287 }
288 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_LOGGING; }
289 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_LOGGING; }
290 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: LOGGING definition must be yes/no or 1/0.", File, Count); }
291 continue;
292 }
293 else if (strcasecmp(EntryPT, "AUTOAWAY") == FALSE) {
294 if (LinePT == NULL) {
295 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for AUTOAWAY definition.", File, Count);
296 continue;
297 }
298 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_AUTOAWAY; }
299 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_AUTOAWAY; }
300 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: AUTOAWAY definition must be yes/no or 1/0.", File, Count); }
301 continue;
302 }
303 else if (strcasecmp(EntryPT, "PUBLICAWAY") == FALSE) {
304 if (LinePT == NULL) {
305 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for PUBLICAWAY definition.", File, Count);
306 continue;
307 }
308 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_PUBLICAWAY; }
309 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_PUBLICAWAY; }
310 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: PUBLICAWAY definition must be yes/no or 1/0.", File, Count); }
311 continue;
312 }
313 else if (strcasecmp(EntryPT, "REGAINNICK") == FALSE) {
314 if (LinePT == NULL) {
315 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for REGAINNICK definition.", File, Count);
316 continue;
317 }
318 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_REGAINNICK; }
319 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_REGAINNICK; }
320 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: REGAINNICK definition must be yes/no or 1/0.", File, Count); }
321 continue;
322 }
323 else if ((strcasecmp(EntryPT, "MAXCLIENTS") == FALSE) || (strcasecmp(EntryPT, "MAXUSERS") == FALSE)) {
324 if (LinePT == NULL) {
325 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing numeric for MAXUSERS definition.", File, Count);
326 continue;
327 }
328 UnsignedShortInt = atoi(LinePT);
329 ConnConf->MaxClients = UnsignedShortInt;
330 continue;
331 }
332 else if (strcasecmp(EntryPT, "MAXSENDLINES") == FALSE) {
333 char *SendMaxLinesPT = NULL;
334 char *SendLineTimePT = NULL;
335 if (LinePT == NULL) {
336 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: The MAXSENDLINES definition must be followed by an \"Lines:Time\" entry.", File, Count);
337 continue;
338 }
339 SendMaxLinesPT = LinePT;
340 StrMovePastToken(LinePT, ':');
341 if (LinePT == NULL) {
342 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: The MAXSENDLINES definition must be followed by an \"Lines:Time\" entry.", File, Count);
343 continue;
344 }
345 SendLineTimePT = LinePT;
346 ConnConf->SendMaxLines = atoi(SendMaxLinesPT);
347 ConnConf->SendLineTime = atoi(SendLineTimePT);
348 continue;
349 }
350 else if (strcasecmp(EntryPT, "MAXSENDBUFFER") == FALSE) {
351 char *SendMaxBufferPT = NULL;
352 char *SendBufferTimePT = NULL;
353 if (LinePT == NULL) {
354 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: The MAXSENDBUFFER definition must be followed by an \"Buffer:Time\" entry.", File, Count);
355 continue;
356 }
357 SendMaxBufferPT = LinePT;
358 StrMovePastToken(LinePT, ':');
359 if (LinePT == NULL) {
360 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: The MAXSENDBUFFER definition must be followed by an \"Buffer:Time\" entry.", File, Count);
361 continue;
362 }
363 SendBufferTimePT = LinePT;
364 ConnConf->SendMaxBuffer = atoi(SendMaxBufferPT);
365 ConnConf->SendBufferTime = atoi(SendBufferTimePT);
366 continue;
367 }
368 else if (strcasecmp(EntryPT, "AWAYMSG") == FALSE) {
369 if (LinePT == NULL) {
370 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in AWAYMSG definition.", File, Count);
371 continue;
372 }
373 ConnConf->AwayMsg = strrealloc(ConnConf->AwayMsg, LinePT);
374 continue;
375 }
376 else if ((strcasecmp(EntryPT, "PUBLICDETACHMSG") == FALSE) || (strcasecmp(EntryPT, "PUBLICAWAYMSG") == FALSE)) {
377 if (LinePT == NULL) {
378 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in PUBLICDETACHMSG definition.", File, Count);
379 continue;
380 }
381 ConnConf->PublicDetachMsg = strrealloc(ConnConf->PublicDetachMsg, LinePT);
382 continue;
383 }
384 else if ((strcasecmp(EntryPT, "PUBLICATTACHMSG") == FALSE) || (strcasecmp(EntryPT, "PUBLICBACKMSG") == FALSE)) {
385 if (LinePT == NULL) {
386 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in PUBLICATTACHMSG definition.", File, Count);
387 continue;
388 }
389 ConnConf->PublicAttachMsg = strrealloc(ConnConf->PublicAttachMsg, LinePT);
390 continue;
391 }
392 else if (strcasecmp(EntryPT, "CHANCYCLE") == FALSE) {
393 if (LinePT == NULL) {
394 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for CHANCYCLE definition.", File, Count);
395 continue;
396 }
397 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_CHANCYCLE; }
398 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_CHANCYCLE; }
399 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: CHANCYCLE definition must be yes/no or 1/0.", File, Count); }
400 continue;
401 }
402 else if (strcasecmp(EntryPT, "NICKSERVNUH") == FALSE) {
403 if (LinePT == NULL) {
404 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in NICKSERVNUH definition.", File, Count);
405 continue;
406 }
407 ConnConf->NickServNUH = strrealloc(ConnConf->NickServNUH, LinePT);
408 continue;
409 }
410 else if (strcasecmp(EntryPT, "NICKSERVPASS") == FALSE) {
411 if (LinePT == NULL) {
412 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in NICKSERVPASS definition.", File, Count);
413 continue;
414 }
415 ConnConf->NickServPass = strrealloc(ConnConf->NickServPass, LinePT);
416 continue;
417 }
418 else if (strcasecmp(EntryPT, "NICKSERVTEXT") == FALSE) {
419 if (LinePT == NULL) {
420 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in NICKSERVTEXT definition.", File, Count);
421 continue;
422 }
423 ConnConf->NickServText = strrealloc(ConnConf->NickServText, LinePT);
424 continue;
425 }
426 else if (strcasecmp(EntryPT, "AUTOATTACH") == FALSE) {
427 if (LinePT == NULL) {
428 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for AUTOATTACH definition.", File, Count);
429 continue;
430 }
431 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_AUTOATTACH; }
432 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_AUTOATTACH; }
433 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: AUTOATTACH definition must be yes/no or 1/0.", File, Count); }
434 continue;
435 }
436
437 else if (strcasecmp(EntryPT, "RAWLOG") == FALSE) {
438 if (LinePT == NULL) {
439 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing 0 or 1 for RAWLOG definition.", File, Count);
440 continue;
441 }
442 if ((strcasecmp(LinePT, "y") == FALSE) || (strcasecmp(LinePT, "yes") == FALSE) || (strcasecmp(LinePT, "1") == FALSE)) { ConnConf->ConfFlags |= CONN_CONF_BITMASK_RAWLOG; }
443 else if ((strcasecmp(LinePT, "n") == FALSE) || (strcasecmp(LinePT, "no") == FALSE) || (strcasecmp(LinePT, "0") == FALSE)) { ConnConf->ConfFlags &= ~CONN_CONF_BITMASK_RAWLOG; }
444 else { sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: RAWLOG definition must be yes/no or 1/0.", File, Count); }
445 continue;
446 }
447
448
449
450 else if (strcasecmp(EntryPT, "CHANLOG") == FALSE) {
451 if (LinePT == NULL) {
452 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Missing data in CHANLOG definition.", File, Count);
453 continue;
454 }
455 for (; *LinePT != '\0' ; LinePT++) {
456 switch(*LinePT) {
457 case IRC_EVENT_PRIVMSG:
458 ConnConf->ChanLogFlags |= IRC_BITMASK_PRIVMSG;
459 break;
460 case IRC_EVENT_ACTION:
461 ConnConf->ChanLogFlags |= IRC_BITMASK_ACTION;
462 break;
463 case IRC_EVENT_CTCP:
464 ConnConf->ChanLogFlags |= IRC_BITMASK_CTCP;
465 break;
466 case IRC_EVENT_NOTICE:
467 ConnConf->ChanLogFlags |= IRC_BITMASK_NOTICE;
468 break;
469 case IRC_EVENT_NICK:
470 ConnConf->ChanLogFlags |= IRC_BITMASK_NICK;
471 break;
472 case IRC_EVENT_QUIT:
473 ConnConf->ChanLogFlags |= IRC_BITMASK_QUIT;
474 break;
475 case IRC_EVENT_MODE:
476 ConnConf->ChanLogFlags |= IRC_BITMASK_MODE;
477 break;
478 case IRC_EVENT_JOIN:
479 ConnConf->ChanLogFlags |= IRC_BITMASK_JOIN;
480 break;
481 case IRC_EVENT_PART:
482 ConnConf->ChanLogFlags |= IRC_BITMASK_PART;
483 break;
484 case IRC_EVENT_KICK:
485 ConnConf->ChanLogFlags |= IRC_BITMASK_KICK;
486 break;
487 case IRC_EVENT_TOPIC:
488 ConnConf->ChanLogFlags |= IRC_BITMASK_TOPIC;
489 break;
490 case '*':
491 ConnConf->ChanLogFlags |= IRC_BITMASK_PRIVMSG;
492 ConnConf->ChanLogFlags |= IRC_BITMASK_ACTION;
493 ConnConf->ChanLogFlags |= IRC_BITMASK_CTCP;
494 ConnConf->ChanLogFlags |= IRC_BITMASK_NOTICE;
495 ConnConf->ChanLogFlags |= IRC_BITMASK_NICK;
496 ConnConf->ChanLogFlags |= IRC_BITMASK_QUIT;
497 ConnConf->ChanLogFlags |= IRC_BITMASK_MODE;
498 ConnConf->ChanLogFlags |= IRC_BITMASK_JOIN;
499 ConnConf->ChanLogFlags |= IRC_BITMASK_PART;
500 ConnConf->ChanLogFlags |= IRC_BITMASK_KICK;
501 ConnConf->ChanLogFlags |= IRC_BITMASK_TOPIC;
502 break;
503 default:
504 break;
505 }
506 }
507 continue;
508 }
509
510
511 #if 0
512 sysprint(BITMASK_ERROR, "Connection configuration error, file %s line %d: Unknown entry \"%s\" for CONNECTION definition.", File, Count, EntryPT);
513 #endif
514
515 }
516 fclose(FilePT);
517
518 for (ConnConf = ConnConf_Head ; ConnConf != NULL ; ConnConf = ConnConf->Next) {
519 DEBUGPRINT(BITMASK_DEBUG_CONF, "Adding connection: Name: %s - Nick: %s - Away Nick: %s - User: %s - Host: %s - Mode: %s - Info: %s - Chans: %s - Max Users: %d - Send Max Lines: %d - Send Line Time: %d - Send Max Buffer: %d - Send Buffer Time: %d.", ConnConf->Name, ConnConf->Nick, ConnConf->AwayNick, ConnConf->User, ConnConf->Host, ConnConf->Mode, ConnConf->Info, ConnConf->Chans, ConnConf->MaxClients, ConnConf->SendMaxLines, ConnConf->SendLineTime, ConnConf->SendMaxBuffer, ConnConf->SendBufferTime);
520 if ((ConfS.UnixPasswd == TRUE) && (Root == TRUE)) {
521 sysgetuidfromuser(ConnConf->User);
522 if (aerrno != AESUCCESS) {
523 sysprint(BITMASK_ERROR, "Connection configuration error, connection %s: Owner of connection user \"%s\" does not exist in %s.", ConnConf->Name, ConnConf->User, PASSWD_FILE);
524 }
525 }
526 ConnS = conn_add(ConnConf);
527 assert(ConnS != NULL);
528 for (ConnConfServer = ConnConf->Server_Head ; ConnConfServer != NULL ; ConnConfServer = ConnConfServer->Next) {
529 DEBUGPRINT(BITMASK_DEBUG_CONF, "Adding connection %s server: Host: %s - Port: %ld -.", ConnConf->Name, ConnConfServer->Host, ConnConfServer->Port);
530 conn_addserver(ConnS, ConnConfServer->Host, ConnConfServer->Port, ConnConfServer->Pass);
531 }
532 }
533
534 return(ConnConfs);
535
536 }
537
538 /* CONN_CONF_ADD - JONAS (31.07.2001) */
539
conn_conf_add(const char * const NamePT)540 struct ConnConf_Struct *conn_conf_add(const char *const NamePT) {
541
542 struct ConnConf_Struct *ConnConf = NULL;
543 struct ConnConf_Struct *ConnConf_NEW = NULL;
544
545 assert(NamePT != NULL);
546
547 ConnConf = conn_conf_get(NamePT);
548 if (ConnConf != NULL) {
549 aerrno = AEEXISTS;
550 return(ConnConf);
551 }
552
553 ConnConf_NEW = malloc(sizeof(struct ConnConf_Struct));
554 if (ConnConf_NEW == NULL) {
555 aerrno = AEMALLOC;
556 return(NULL);
557 }
558
559 memset(ConnConf_NEW, 0, sizeof(struct ConnConf_Struct));
560
561 ConnConf_NEW->Name = strdup(NamePT);
562 ConnConf_NEW->Nick = strdup(CONN_CONF_NICK_DEFAULT);
563 ConnConf_NEW->AwayNick = strdup(CONN_CONF_AWAYNICK_DEFAULT);
564 ConnConf_NEW->User = strdup(CONN_CONF_USER_DEFAULT);
565 ConnConf_NEW->Host = strdup(CONN_CONF_HOST_DEFAULT);
566 ConnConf_NEW->Mode = strdup(CONN_CONF_USERMODE_DEFAULT);
567 ConnConf_NEW->Info = strdup(CONN_CONF_USERINFO_DEFAULT);
568 ConnConf_NEW->Chans = strdup(CONN_CONF_CHANS_DEFAULT);
569 ConnConf_NEW->AwayMsg = strdup(CONN_CONF_AWAYMSG_DEFAULT);
570 ConnConf_NEW->PublicDetachMsg = strdup(CONN_CONF_PUBLICAWAYMSG_DEFAULT);
571 ConnConf_NEW->PublicAttachMsg = strdup(CONN_CONF_PUBLICBACKMSG_DEFAULT);
572 ConnConf_NEW->NickServNUH = strdup(CONN_CONF_NICKSERVNUH_DEFAULT);
573 ConnConf_NEW->NickServPass = strdup(CONN_CONF_NICKSERVPASS_DEFAULT);
574 ConnConf_NEW->NickServText = strdup(CONN_CONF_NICKSERVTEXT_DEFAULT);
575
576 if (
577 (ConnConf_NEW->Name == NULL) ||
578 (ConnConf_NEW->Nick == NULL) ||
579 (ConnConf_NEW->AwayNick == NULL) ||
580 (ConnConf_NEW->User == NULL) ||
581 (ConnConf_NEW->Host == NULL) ||
582 (ConnConf_NEW->Mode == NULL) ||
583 (ConnConf_NEW->Info == NULL) ||
584 (ConnConf_NEW->Chans == NULL) ||
585 (ConnConf_NEW->AwayMsg == NULL) ||
586 (ConnConf_NEW->PublicDetachMsg == NULL) ||
587 (ConnConf_NEW->PublicAttachMsg == NULL) ||
588 (ConnConf_NEW->NickServNUH == NULL) ||
589 (ConnConf_NEW->NickServPass == NULL) ||
590 (ConnConf_NEW->NickServText == NULL)
591 ) {
592 free(ConnConf_NEW->Name);
593 free(ConnConf_NEW->Nick);
594 free(ConnConf_NEW->AwayNick);
595 free(ConnConf_NEW->User);
596 free(ConnConf_NEW->Host);
597 free(ConnConf_NEW->Mode);
598 free(ConnConf_NEW->Info);
599 free(ConnConf_NEW->Chans);
600 free(ConnConf_NEW->AwayMsg);
601 free(ConnConf_NEW->PublicDetachMsg);
602 free(ConnConf_NEW->PublicAttachMsg);
603 free(ConnConf_NEW->NickServNUH);
604 free(ConnConf_NEW->NickServPass);
605 free(ConnConf_NEW->NickServText);
606 free(ConnConf_NEW);
607 aerrno = AEMALLOC;
608 return(NULL);
609 }
610
611 ConnConf_NEW->MaxClients = CONN_CONF_MAXCLIENTS_DEFAULT;
612 ConnConf_NEW->SendMaxLines = CONN_CONF_SENDMAXLINES_DEFAULT;
613 ConnConf_NEW->SendLineTime = CONN_CONF_SENDLINETIME_DEFAULT;
614 ConnConf_NEW->SendMaxBuffer = CONN_CONF_SENDMAXBUFFER_DEFAULT;
615 ConnConf_NEW->SendBufferTime = CONN_CONF_SENDBUFFERTIME_DEFAULT;
616
617 if (ConnConf_Head == NULL) {
618 ConnConf_Head = ConnConf_NEW;
619 ConnConf_Tail = ConnConf_NEW;
620 }
621 else {
622 ConnConf = ConnConf_Tail;
623 ConnConf->Next = ConnConf_NEW;
624 ConnConf_NEW->Prev = ConnConf;
625 ConnConf_Tail = ConnConf_NEW;
626 }
627
628 ConnConfs++;
629
630 aerrno = AESUCCESS;
631 return(ConnConf_NEW);
632
633 }
634
635 /* CONN_CONF_REM FUNCTION - JONAS (31.07.2001) */
636
conn_conf_rem(struct ConnConf_Struct * ConnConf)637 void conn_conf_rem(struct ConnConf_Struct *ConnConf) {
638
639 assert(ConnConf != NULL);
640
641 if (ConnConf->Prev == NULL) { ConnConf_Head = ConnConf->Next; }
642 else { ConnConf->Prev->Next = ConnConf->Next; }
643
644 if (ConnConf->Next == NULL) { ConnConf_Tail = ConnConf->Prev; }
645 else { ConnConf->Next->Prev = ConnConf->Prev; }
646
647 conn_conf_remservers(ConnConf);
648
649 free(ConnConf->Name);
650 free(ConnConf->Nick);
651 free(ConnConf->AwayNick);
652 free(ConnConf->User);
653 free(ConnConf->Host);
654 free(ConnConf->Mode);
655 free(ConnConf->Info);
656 free(ConnConf->Chans);
657 free(ConnConf->AwayMsg);
658 free(ConnConf->PublicDetachMsg);
659 free(ConnConf->PublicAttachMsg);
660 free(ConnConf->NickServNUH);
661 free(ConnConf->NickServPass);
662 free(ConnConf->NickServText);
663 free(ConnConf);
664
665 ConnConfs--;
666
667 }
668
669 /* CONN_CONF_GET FUNCTION - JONAS (31.07.2001) */
670
conn_conf_get(const char * const NamePT)671 struct ConnConf_Struct *conn_conf_get(const char *const NamePT) {
672
673 struct ConnConf_Struct *ConnConf = NULL;
674
675 assert(NamePT != NULL);
676
677 for (ConnConf = ConnConf_Head ; ConnConf != NULL ; ConnConf = ConnConf->Next) {
678 if (strcasecmp(ConnConf->Name, NamePT) == FALSE) {
679 aerrno = AESUCCESS;
680 return(ConnConf);
681 }
682 }
683 aerrno = AENOMATCH;
684 return(NULL);
685
686 }
687
688 /* CONN_CONF_DESTROY FUNCTION - JONAS (31.07.2001) */
689
conn_conf_destroy(void)690 void conn_conf_destroy(void) {
691
692 while (ConnConf_Head != NULL) { conn_conf_rem(ConnConf_Head); }
693
694 }
695
696 /* CONN_CONF_ADDSERVER - JONAS (31.07.2001) */
697
conn_conf_addserver(struct ConnConf_Struct * ConnConf,const char * const HostPT,const unsigned long int Port,const char * const PassPT)698 struct ConnConfServer_Struct *conn_conf_addserver(struct ConnConf_Struct *ConnConf, const char *const HostPT, const unsigned long int Port, const char *const PassPT) {
699
700 struct ConnConfServer_Struct *ConnConfServer = NULL;
701 struct ConnConfServer_Struct *ConnConfServer_NEW = NULL;
702
703 assert(ConnConf != NULL);
704 assert(HostPT != NULL);
705 assert(PassPT != NULL);
706
707 ConnConfServer = conn_conf_getserver(ConnConf, HostPT);
708 if (ConnConfServer != NULL) {
709 aerrno = AEEXISTS;
710 return(ConnConfServer);
711 }
712
713 ConnConfServer_NEW = malloc(sizeof(struct ConnConfServer_Struct));
714 if (ConnConfServer_NEW == NULL) {
715 aerrno = AEMALLOC;
716 return(NULL);
717 }
718
719 memset(ConnConfServer_NEW, 0, sizeof(struct ConnConfServer_Struct));
720
721 ConnConfServer_NEW->Host = strdup(HostPT);
722 ConnConfServer_NEW->Pass = strdup(PassPT);
723 ConnConfServer_NEW->Port = Port;
724
725 if ((ConnConfServer_NEW->Host == NULL) || (ConnConfServer_NEW->Pass == NULL)) {
726 free(ConnConfServer_NEW->Host);
727 free(ConnConfServer_NEW->Pass);
728 free(ConnConfServer_NEW);
729 aerrno = AEMALLOC;
730 return(NULL);
731 }
732
733 if (ConnConf->Server_Head == NULL) {
734 ConnConf->Server_Head = ConnConfServer_NEW;
735 ConnConf->Server_Tail = ConnConfServer_NEW;
736 }
737 else {
738 ConnConfServer = ConnConf->Server_Tail;
739 ConnConfServer->Next = ConnConfServer_NEW;
740 ConnConfServer_NEW->Prev = ConnConfServer;
741 ConnConf->Server_Tail = ConnConfServer_NEW;
742 }
743
744 ConnConf->Servers++;
745
746 aerrno = AESUCCESS;
747 return(ConnConfServer_NEW);
748
749 }
750
751 /* CONN_CONF_REMSERVER FUNCTION - JONAS (31.07.2001) */
752
conn_conf_remserver(struct ConnConf_Struct * ConnConf,struct ConnConfServer_Struct * ConnConfServer)753 void conn_conf_remserver(struct ConnConf_Struct *ConnConf, struct ConnConfServer_Struct *ConnConfServer) {
754
755 assert(ConnConf != NULL);
756 assert(ConnConfServer != NULL);
757
758 if (ConnConfServer->Prev == NULL) { ConnConf->Server_Head = ConnConfServer->Next; }
759 else { ConnConfServer->Prev->Next = ConnConfServer->Next; }
760
761 if (ConnConfServer->Next == NULL) { ConnConf->Server_Tail = ConnConfServer->Prev; }
762 else { ConnConfServer->Next->Prev = ConnConfServer->Prev; }
763
764 free(ConnConfServer->Pass);
765 free(ConnConfServer->Host);
766 free(ConnConfServer);
767 ConnConf->Servers--;
768
769 }
770
771 /* CONN_CONF_GET FUNCTION - JONAS (31.07.2001) */
772
conn_conf_getserver(struct ConnConf_Struct * ConnConf,const char * const HostPT)773 struct ConnConfServer_Struct *conn_conf_getserver(struct ConnConf_Struct *ConnConf, const char *const HostPT) {
774
775 struct ConnConfServer_Struct *ConnConfServer = NULL;
776
777 assert(ConnConf != NULL);
778 assert(HostPT != NULL);
779
780 for (ConnConfServer = ConnConf->Server_Head ; ConnConfServer != NULL ; ConnConfServer = ConnConfServer->Next) {
781 if (strcasecmp(ConnConfServer->Host, HostPT) == FALSE) {
782 aerrno = AESUCCESS;
783 return(ConnConfServer);
784 }
785 }
786 aerrno = AENOMATCH;
787 return(NULL);
788
789 }
790
791 /* CONN_CONF_REMSERVERS FUNCTION - JONAS (31.07.2001) */
792
conn_conf_remservers(struct ConnConf_Struct * ConnConf)793 void conn_conf_remservers(struct ConnConf_Struct *ConnConf) {
794
795 while (ConnConf->Server_Head != NULL) { conn_conf_remserver(ConnConf, ConnConf->Server_Head); }
796
797 }
798