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