1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * Inspire is copyright (C) 2002-2003 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 * the file COPYING for details.
14 * ---------------------------------------------------
17 Revision 1.1 2003/01/23 19:45:58 brain
20 Revision 1.12 2003/01/22 20:49:16 brain
21 Added FileReader file-caching class
22 Changed m_randquote to use FileReader class
24 Revision 1.11 2003/01/21 20:31:24 brain
25 Modified to add documentation
26 Added ConfigReader class for modules
28 Revision 1.10 2003/01/16 20:11:55 brain
29 fixed some ugly pointer bugs (thanks dblack and a|KK|y!)
31 Revision 1.9 2003/01/09 13:05:58 brain
33 Fixed socket lingering problems (is BSD compatible)
35 Revision 1.8 2003/01/07 19:57:56 brain
37 Dynamix module support, preliminary release
39 Revision 1.7 2003/01/06 23:38:29 brain
41 just playing with header tags
44 * ---------------------------------------------------
48 #include "inspircd_io.h"
49 #include "inspircd_util.h"
51 void WriteOpers(char* text, ...);
53 void Exit (int status)
55 send_error("Server shutdown.");
59 void Killed(int status)
61 send_error("Server terminated.");
65 void Rehash(int status)
68 WriteOpers("Rehashing config file %s due to SIGHUP",CONFIG_FILE);
75 printf("\033[1;37mInspire Internet Relay Chat Server, compiled " __DATE__ " at " __TIME__ "\n");
76 printf("(C) ChatSpike Development team.\033[0;37m\n\n");
77 printf("\033[1;37mDevelopers:\033[0;37m Brain, FrostyCoolSlug, Raider, RD\n");
78 printf("\033[1;37mDocumentation:\033[0;37m FrostyCoolSlug\n");
79 printf("\033[1;37mTesters:\033[0;37m MrBOFH, piggles, Lord_Zathras, typobox43, CC\n");
80 printf("\033[1;37mName concept:\033[0;37m Lord_Zathras\n\n");
87 signal (SIGALRM, SIG_IGN);
88 signal (SIGHUP, Rehash);
89 signal (SIGPIPE, SIG_IGN);
90 signal (SIGTERM, Exit);
91 signal (SIGABRT, Exit);
92 signal (SIGSEGV, Error);
93 signal (SIGURG, Exit);
94 signal (SIGKILL, Exit);
95 if ((childpid = fork ()) < 0)
97 else if (childpid > 0)
101 /* close stdout, stdin, stderr */
111 /* Make sure the config file is available */
112 int CheckConfig (void)
116 if ((input = fopen (CONFIG_FILE, "r")) == NULL)
118 printf("ERROR: Cannot open config file: %s\nExiting...\n",CONFIG_FILE);
127 /* Counts the number of tags of a certain type within the config file, e.g. to enumerate opers */
129 int EnumConf(const char* filename, const char* tag)
133 char buffer[MAXBUF], c_tag[MAXBUF], c;
134 int in_token, in_quotes, tptr, j, idx = 0;
137 if ((config = fopen (filename, "r")) == NULL)
146 while (!feof(config))
149 if ((c == '<') && (!in_quotes))
164 in_quotes = (!in_quotes);
166 if ((c == '>') && (!in_quotes))
169 if (!strcmp(c_tag,tag))
171 /* correct tag, but wrong index */
181 if ((in_token) && (c != '\n') && (c != '\r'))
195 int ConfValueEnum(char* tag)
197 EnumConf(CONFIG_FILE,tag);
202 /* Retrieves a value from the config file. If there is more than one value of the specified
203 * key and section (e.g. for opers etc) then the index value specifies which to retreive, e.g.
205 * ConfValue("oper","name",2,result);
208 int ReadConf(const char* filename, const char* tag, const char* var, int index, char *result)
212 char buffer[MAXBUF], c_tag[MAXBUF], c;
213 int in_token, in_quotes, tptr, j, idx = 0;
216 if ((config = fopen (filename, "r")) == NULL)
225 while (!feof(config))
228 if ((c == '<') && (!in_quotes))
243 in_quotes = (!in_quotes);
245 if ((c == '>') && (!in_quotes))
250 if (!strcmp(c_tag,tag))
252 if ((buffer) && (c_tag) && (var))
254 key = strstr(buffer,var);
257 /* value not found in tag */
274 for (j = 0; j < strlen(key); j++)
288 if (!strcmp(c_tag,tag))
290 /* correct tag, but wrong index */
300 if ((in_token) && (c != '\n') && (c != '\r'))
314 int ConfValue(char* tag, char* var, int index, char *result)
316 ReadConf(CONFIG_FILE, tag, var, index, result);
321 /* This will bind a socket to a port. It works for UDP/TCP */
322 int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
324 bzero((char *)&server,sizeof(server));
326 inet_aton(addr,&addy);
328 server.sin_family = AF_INET;
329 if (!strcmp(addr,""))
331 server.sin_addr.s_addr = htonl(INADDR_ANY);
335 server.sin_addr = addy;
338 server.sin_port = htons(port);
340 if (bind(sockfd,(struct sockaddr*)&server,sizeof(server))<0)
352 /* Open a TCP Socket */
353 int OpenTCPSocket (void)
357 struct linger linger = { 0 };
359 if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
363 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
364 /* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */
367 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&linger,sizeof(linger));