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