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