* ---------------------------------------------------
*/
+using namespace std;
+
+#include "inspircd_config.h"
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include "inspircd_io.h"
#include "inspircd_util.h"
#include "inspstring.h"
-
-using namespace std;
+#include "helperfuncs.h"
extern FILE *log_file;
extern int boundPortCount;
extern int openSockfd[MAXSOCKS];
+extern time_t TIME;
+extern bool unlimitcore;
+extern int MaxConn;
+std::vector<std::string> include_stack;
void WriteOpers(char* text, ...);
if (log_file)
fclose(log_file);
send_error("Server shutdown.");
-
- // close down all listening sockets
- for (int count = 0; count < boundPortCount; count++)
- {
- shutdown(openSockfd[count], 2);
- }
-
exit (status);
}
if (log_file)
fclose(log_file);
send_error("Server terminated.");
- // close down all listening sockets
- for (int count = 0; count < boundPortCount; count++)
- {
- shutdown(openSockfd[count], 2);
- }
exit(status);
}
void Start (void)
{
- printf("\033[1;37mInspire Internet Relay Chat Server, compiled " __DATE__ " at " __TIME__ "\n");
- printf("(C) ChatSpike Development team.\033[0;37m\n\n");
- printf("\033[1;37mDevelopers:\033[0;37m Brain, FrostyCoolSlug\n");
- printf("\033[1;37mDocumentation:\033[0;37m FrostyCoolSlug, w00t\n");
- printf("\033[1;37mTesters:\033[0;37m typobox43, piggles, Lord_Zathras, CC\n");
- printf("\033[1;37mName concept:\033[0;37m Lord_Zathras\n\n");
+ printf("\033[1;32mInspire Internet Relay Chat Server, compiled %s at %s\n",__DATE__,__TIME__);
+ printf("(C) ChatSpike Development team.\033[0m\n\n");
+ printf("Developers:\033[1;32m Brain, FrostyCoolSlug\033[0m\n");
+ printf("Documentation:\033[1;32m FrostyCoolSlug, w00t\033[0m\n");
+ printf("Testers:\033[1;32m typobox43, piggles, Lord_Zathras, CC\033[0m\n");
+ printf("Name concept:\033[1;32m Lord_Zathras\033[0m\n\n");
}
void WritePID(std::string filename)
}
}
-void DeadPipe(int status)
-{
- signal (SIGPIPE, DeadPipe);
-}
int DaemonSeed (void)
{
int childpid;
signal (SIGALRM, SIG_IGN);
signal (SIGHUP, Rehash);
- signal (SIGPIPE, DeadPipe);
+ signal (SIGPIPE, SIG_IGN);
signal (SIGTERM, Exit);
- signal (SIGABRT, Exit);
signal (SIGSEGV, Error);
- signal (SIGURG, Exit);
- signal (SIGKILL, Exit);
if ((childpid = fork ()) < 0)
return (ERROR);
else if (childpid > 0)
exit (0);
setsid ();
umask (007);
- /* close stdout, stdin, stderr */
- close(0);
- close(1);
- close(2);
+ printf("InspIRCd Process ID: \033[1;32m%lu\033[0m\n",(unsigned long)getpid());
+ freopen("/dev/null","w",stdout);
+ freopen("/dev/null","w",stderr);
+
+ setpriority(PRIO_PROCESS,(int)getpid(),15);
- setpriority(PRIO_PROCESS,(int)getpid(),15); /* ircd sets to low process priority so it doesnt hog the box */
+ if (unlimitcore)
+ {
+ rlimit rl;
+ if (getrlimit(RLIMIT_CORE, &rl) == -1)
+ {
+ log(DEFAULT,"Failed to getrlimit()!");
+ return(FALSE);
+ }
+ else
+ {
+ rl.rlim_cur = rl.rlim_max;
+ if (setrlimit(RLIMIT_CORE, &rl) == -1)
+ log(DEFAULT,"setrlimit() failed, cannot increase coredump size.");
+ }
+ }
return (TRUE);
}
return "";
}
// firstly clean up the line by stripping spaces from the start and end and converting tabs to spaces
- for (int d = 0; d < strlen(buffer); d++)
+ for (unsigned int d = 0; d < strlen(buffer); d++)
if ((buffer[d]) == 9)
buffer[d] = ' ';
while ((buffer[0] == ' ') && (strlen(buffer)>0)) buffer++;
while ((buffer[strlen(buffer)-1] == ' ') && (strlen(buffer)>0)) buffer[strlen(buffer)-1] = '\0';
- // empty lines are syntactically valid
- if (!strcmp(buffer,""))
- return "";
- else if (buffer[0] == '#')
+
+ // empty lines are syntactically valid, as are comments
+ if (!(*buffer) || buffer[0] == '#')
return "";
- for (int c = 0; c < strlen(buffer); c++)
+
+ for (unsigned int c = 0; c < strlen(buffer); c++)
{
// convert all spaces that are OUTSIDE quotes into hardspace (0xA0) as this will make them easier to
// search and replace later :)
}
// turn our hardspace back into softspace
- for (int d = 0; d < parsedata.length(); d++)
+ for (unsigned int d = 0; d < parsedata.length(); d++)
{
if (parsedata[d] == '\xA0')
parsedata[d] = ' ';
return parsedata;
}
+int fgets_safe(char* buffer, size_t maxsize, FILE* &file)
+{
+ char c_read = '\0';
+ unsigned int bufptr = 0;
+ while ((!feof(file)) && (c_read != '\n') && (c_read != '\r') && (bufptr < maxsize))
+ {
+ c_read = fgetc(file);
+ if ((c_read != '\n') && (c_read != '\r'))
+ buffer[bufptr++] = c_read;
+ }
+ buffer[bufptr] = '\0';
+ return bufptr;
+}
+
bool LoadConf(const char* filename, std::stringstream *target, std::stringstream* errorstream)
{
target->str("");
}
// Fix the chmod of the file to restrict it to the current user and group
chmod(filename,0600);
+ for (unsigned int t = 0; t < include_stack.size(); t++)
+ {
+ if (std::string(filename) == include_stack[t])
+ {
+ *errorstream << "File " << filename << " is included recursively (looped inclusion)." << endl;
+ return false;
+ }
+ }
+ include_stack.push_back(filename);
// now open it
FILE* conf = fopen(filename,"r");
char buffer[MAXBUF];
{
while (!feof(conf))
{
- if (fgets(buffer, MAXBUF, conf))
+ if (fgets_safe(buffer, MAXBUF, conf))
{
if ((!feof(conf)) && (buffer) && (strlen(buffer)))
{
if ((buffer[0] != '#') && (buffer[0] != '\r') && (buffer[0] != '\n'))
{
- bool error = false;
- std::string data = ConfProcess(buffer,linenumber++,errorstream,error,filename);
- if (error)
+ if (!strncmp(buffer,"<include file=\"",15))
+ {
+ char* buf = buffer;
+ char confpath[10240],newconf[10240];
+ // include file directive
+ buf += 15; // advance to filename
+ for (unsigned int j = 0; j < strlen(buf); j++)
+ {
+ if (buf[j] == '\\')
+ buf[j] = '/';
+ if (buf[j] == '"')
+ {
+ buf[j] = '\0';
+ break;
+ }
+ }
+ log(DEFAULT,"Opening included file '%s'",buf);
+ if (*buf != '/')
+ {
+ strlcpy(confpath,CONFIG_FILE,10240);
+ if (strstr(confpath,"/inspircd.conf"))
+ {
+ // leaves us with just the path
+ *(strstr(confpath,"/inspircd.conf")) = '\0';
+ }
+ snprintf(newconf,10240,"%s/%s",confpath,buf);
+ }
+ else snprintf(newconf,10240,"%s",buf);
+ std::stringstream merge(stringstream::in | stringstream::out);
+ // recursively call LoadConf and get the new data, use the same errorstream
+ if (LoadConf(newconf, &merge, errorstream))
+ {
+ // append to the end of the file
+ std::string newstuff = merge.str();
+ *target << newstuff;
+ }
+ else
+ {
+ // the error propogates up to its parent recursively
+ // causing the config reader to bail at the top level.
+ fclose(conf);
+ return false;
+ }
+ }
+ else
{
- return false;
+ bool error = false;
+ std::string data = ConfProcess(buffer,linenumber++,errorstream,error,filename);
+ if (error)
+ {
+ return false;
+ }
+ *target << data;
}
- *target << data;
}
else linenumber++;
}
{
int ptr = 0;
char buffer[MAXBUF], c_tag[MAXBUF], c, lastc;
- int in_token, in_quotes, tptr, j, idx = 0;
- char* key;
+ int in_token, in_quotes, tptr, idx = 0;
const char* buf = config->str().c_str();
long bptr = 0;
{
int ptr = 0;
char buffer[MAXBUF], c_tag[MAXBUF], c, lastc;
- int in_token, in_quotes, tptr, j, idx = 0;
- char* key;
+ int in_token, in_quotes, tptr, idx = 0;
bool correct_tag = false;
int num_items = 0;
{
int ptr = 0;
char buffer[65535], c_tag[MAXBUF], c, lastc;
- int in_token, in_quotes, tptr, j, idx = 0;
+ int in_token, in_quotes, tptr, idx = 0;
char* key;
const char* buf = config->str().c_str();
long bptr = 0;
- long len = strlen(buf);
+ long len = config->str().length();
ptr = 0;
in_token = 0;
key++;
}
key++;
- for (j = 0; j < strlen(key); j++)
+ for (unsigned j = 0; j < strlen(key); j++)
{
if (key[j] == '"')
{
// This will bind a socket to a port. It works for UDP/TCP
int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
{
- bzero((char *)&server,sizeof(server));
+ memset((char *)&server,0,sizeof(server));
struct in_addr addy;
inet_aton(addr,&addy);
server.sin_family = AF_INET;
}
else
{
- listen(sockfd,5);
+ listen(sockfd, MaxConn);
return(TRUE);
}
}
int OpenTCPSocket (void)
{
int sockfd;
- int on = 0;
+ int on = 1;
struct linger linger = { 0 };
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
/* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */
linger.l_onoff = 1;
- linger.l_linger = 0;
+ linger.l_linger = 1;
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&linger,sizeof(linger));
return (sockfd);
}
}
-