]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/inspircd_io.cpp
Added first part of server linking code
[user/henk/code/inspircd.git] / src / inspircd_io.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2003 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #include "inspircd.h"
18 #include "inspircd_io.h"
19 #include "inspircd_util.h"
20
21 void WriteOpers(char* text, ...);
22
23 void Exit (int status)
24 {
25   send_error("Server shutdown.");
26   exit (status);
27 }
28
29 void Killed(int status)
30 {
31   send_error("Server terminated.");
32   exit(status);
33 }
34
35 void Rehash(int status)
36 {
37   ReadConfig();
38   WriteOpers("Rehashing config file %s due to SIGHUP",CONFIG_FILE);
39 }
40
41
42
43 void Start (void)
44 {
45   printf("\033[1;37mInspire Internet Relay Chat Server, compiled " __DATE__ " at " __TIME__ "\n");
46   printf("(C) ChatSpike Development team.\033[0;37m\n\n");
47   printf("\033[1;37mDevelopers:\033[0;37m     Brain, FrostyCoolSlug, Raider, RD\n");
48   printf("\033[1;37mDocumentation:\033[0;37m  FrostyCoolSlug\n");
49   printf("\033[1;37mTesters:\033[0;37m        MrBOFH, piggles, Lord_Zathras, typobox43, CC\n");
50   printf("\033[1;37mName concept:\033[0;37m   Lord_Zathras\n\n");
51 }
52
53
54 void DeadPipe(int status)
55 {
56   signal (SIGPIPE, DeadPipe);
57 }
58
59 int DaemonSeed (void)
60 {
61   int childpid;
62   signal (SIGALRM, SIG_IGN);
63   signal (SIGHUP, Rehash);
64   signal (SIGPIPE, DeadPipe);
65   signal (SIGTERM, Exit);
66   signal (SIGABRT, Exit);
67   signal (SIGSEGV, Error);
68   signal (SIGURG, Exit);
69   signal (SIGKILL, Exit);
70   if ((childpid = fork ()) < 0)
71     return (ERROR);
72   else if (childpid > 0)
73     exit (0);
74   setsid ();
75   umask (077);
76   /* close stdout, stdin, stderr */
77   close(0);
78   close(1);
79   close(2);
80   return (TRUE);
81 }
82
83
84
85
86 /* Make sure the config file is available */
87 int CheckConfig (void)
88 {
89   FILE *input;
90
91   if ((input = fopen (CONFIG_FILE, "r")) == NULL)
92     {
93       printf("ERROR: Cannot open config file: %s\nExiting...\n",CONFIG_FILE);
94       return(FALSE);
95     }
96   else
97     fclose (input);
98
99 return(TRUE);
100 }
101
102 /* Counts the number of tags of a certain type within the config file, e.g. to enumerate opers */
103
104 int EnumConf(const char* filename, const char* tag)
105 {
106         FILE *config;
107         int ptr = 0;
108         char buffer[MAXBUF], c_tag[MAXBUF], c;
109         int in_token, in_quotes, tptr, j, idx = 0;
110         char* key;
111
112         if ((config = fopen (filename, "r")) == NULL)
113         {
114                 return 0;
115         }
116         else
117         {
118                 ptr = 0;
119                 in_token = 0;
120                 in_quotes = 0;
121                 while (!feof(config))
122                 {
123                         c = fgetc(config);
124                         if ((c == '<') && (!in_quotes))
125                         {
126                                 tptr = 0;
127                                 in_token = 1;
128                                 do {
129                                         c = fgetc(config);
130                                         if (c != ' ')
131                                         {
132                                                 c_tag[tptr++] = c;
133                                                 c_tag[tptr] = '\0';
134                                         }
135                                 } while (c != ' ');
136                         }
137                         if (c == '"')
138                         {
139                                 in_quotes = (!in_quotes);
140                         }
141                         if ((c == '>') && (!in_quotes))
142                         {
143                                 in_token = 0;
144                                 if (!strcmp(c_tag,tag))
145                                 {
146                                         /* correct tag, but wrong index */
147                                         idx++;
148                                 }
149                                 c_tag[0] = '\0';
150                                 buffer[0] = '\0';
151                                 ptr = 0;
152                                 tptr = 0;
153                         }
154                         if (c != '>')
155                         {
156                                 if ((in_token) && (c != '\n') && (c != '\r'))
157                                 {
158                                         buffer[ptr++] = c;
159                                         buffer[ptr] = '\0';
160                                 }
161                         }
162                 }
163         }
164         fclose(config);
165         return idx;
166 }
167
168
169
170 int ConfValueEnum(char* tag)
171 {
172         EnumConf(CONFIG_FILE,tag);
173 }
174
175
176
177 /* Retrieves a value from the config file. If there is more than one value of the specified
178  * key and section (e.g. for opers etc) then the index value specifies which to retreive, e.g.
179  *
180  * ConfValue("oper","name",2,result);
181  */
182
183 int ReadConf(const char* filename, const char* tag, const char* var, int index, char *result)
184 {
185         FILE *config;
186         int ptr = 0;
187         char buffer[MAXBUF], c_tag[MAXBUF], c;
188         int in_token, in_quotes, tptr, j, idx = 0;
189         char* key;
190
191         if ((config = fopen (filename, "r")) == NULL)
192         {
193                 return 0;
194         }
195         else
196         {
197                 ptr = 0;
198                 in_token = 0;
199                 in_quotes = 0;
200                 while (!feof(config))
201                 {
202                         c = fgetc(config);
203                         if ((c == '<') && (!in_quotes))
204                         {
205                                 tptr = 0;
206                                 in_token = 1;
207                                 do {
208                                         c = fgetc(config);
209                                         if (c != ' ')
210                                         {
211                                                 c_tag[tptr++] = c;
212                                                 c_tag[tptr] = '\0';
213                                         }
214                                 } while (c != ' ');
215                         }
216                         if (c == '"')
217                         {
218                                 in_quotes = (!in_quotes);
219                         }
220                         if ((c == '>') && (!in_quotes))
221                         {
222                                 in_token = 0;
223                                 if (idx == index)
224                                 {
225                                         if (!strcmp(c_tag,tag))
226                                         {
227                                                 if ((buffer) && (c_tag) && (var))
228                                                 {
229                                                         key = strstr(buffer,var);
230                                                         if (!key)
231                                                         {
232                                                                 /* value not found in tag */
233                                                                 fclose(config);
234                                                                 return 0;
235                                                         }
236                                                         else
237                                                         {
238                                                                 key+=strlen(var);
239                                                                 while (key[0] !='"')
240                                                                 {
241                                                                         if (!strlen(key))
242                                                                         {
243                                                                                 /* missing quote */
244                                                                                 return 0;
245                                                                         }
246                                                                         key++;
247                                                                 }
248                                                                 key++;
249                                                                 for (j = 0; j < strlen(key); j++)
250                                                                 {
251                                                                         if (key[j] == '"')
252                                                                         {
253                                                                                 key[j] = '\0';
254                                                                         }
255                                                                 }
256                                                                 fclose(config);
257                                                                 strcpy(result,key);
258                                                                 return 1;
259                                                         }
260                                                 }
261                                         }
262                                 }
263                                 if (!strcmp(c_tag,tag))
264                                 {
265                                         /* correct tag, but wrong index */
266                                         idx++;
267                                 }
268                                 c_tag[0] = '\0';
269                                 buffer[0] = '\0';
270                                 ptr = 0;
271                                 tptr = 0;
272                         }
273                         if (c != '>')
274                         {
275                                 if ((in_token) && (c != '\n') && (c != '\r'))
276                                 {
277                                         buffer[ptr++] = c;
278                                         buffer[ptr] = '\0';
279                                 }
280                         }
281                 }
282         }
283         fclose(config);
284         return 0;
285 }
286
287
288
289 int ConfValue(char* tag, char* var, int index, char *result)
290 {
291         ReadConf(CONFIG_FILE, tag, var, index, result);
292 }
293
294
295
296 /* This will bind a socket to a port. It works for UDP/TCP */
297 int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
298 {
299   bzero((char *)&server,sizeof(server));
300   struct in_addr addy;
301   inet_aton(addr,&addy);
302
303   server.sin_family = AF_INET;
304   if (!strcmp(addr,""))
305   {
306           server.sin_addr.s_addr = htonl(INADDR_ANY);
307   }
308   else
309   {
310           server.sin_addr = addy;
311   }
312
313   server.sin_port = htons(port);
314
315   if (bind(sockfd,(struct sockaddr*)&server,sizeof(server))<0)
316   {
317     return(ERROR);
318   }
319   else
320   {
321     listen(sockfd,5);
322     return(TRUE);
323   }
324 }
325
326
327 /* Open a TCP Socket */
328 int OpenTCPSocket (void)
329 {
330   int sockfd;
331   int on = 0;
332   struct linger linger = { 0 };
333   
334   if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
335     return (ERROR);
336   else
337   {
338     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
339     /* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */
340     linger.l_onoff = 1;
341     linger.l_linger = 0;
342     setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&linger,sizeof(linger));
343     return (sockfd);
344   }
345 }
346