#include "compat.h"
#include "negcache.h"
#include "malloc.h"
+#include "main.h"
static void irc_init(void);
static void irc_connect(void);
static void m_perform(char **, unsigned int, char *, struct UserInfo *);
static void m_userhost(char **, unsigned int, char *, struct UserInfo *);
static void m_cannot_join(char **, unsigned int, char *, struct UserInfo *);
+static void m_kill(char **, unsigned int, char *, struct UserInfo *);
extern struct cnode *nc_head;
char IRC_CHANNELS[MSGLENMAX]; /* Stores comma delim list of channels */
int IRC_RAW_LEN = 0; /* Position of IRC_RAW */
-int IRC_FD = -1; /* File descriptor for IRC client */
+int IRC_FD = 0; /* File descriptor for IRC client */
struct bopm_sockaddr IRC_SVR; /* Sock Address Struct for IRC server */
struct bopm_ircaddr IRC_LOCAL; /* Sock Address Struct for Bind */
time_t IRC_LAST = 0; /* Last full line of data from irc server*/
time_t IRC_LASTRECONNECT = 0; /* Time of last reconnection */
+
/* Table should be ordered with most occuring (or priority)
commands at the top of the list. */
{"473", m_cannot_join },
{"474", m_cannot_join },
{"475", m_cannot_join },
+ {"KILL", m_kill }
};
/* irc_cycle
exit(EXIT_FAILURE);
}
- IRC_FD = socket(AF_INET, SOCK_STREAM, 0);
-
/* Request file desc for IRC client socket */
+ IRC_FD = socket(AF_INET, SOCK_STREAM, 0);
if (IRC_FD == -1)
{
irc_send("%s", channel->invite);
}
+
+/* m_kill
+ *
+ * parv[0] = source
+ * parv[1] = numeric
+ * parv[2] = target (bopm)
+ * parv[3] = channel
+ * parv[4] = error text
+ *
+ */
+
+static void m_kill(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
+{
+ /* Restart bopm to rehash */
+ main_restart();
+}
#include <netdb.h>
#include <signal.h>
#include <unistd.h>
+#include <errno.h>
+#include <sys/resource.h> /* getrlimit */
+#include <fcntl.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
static RETSIGTYPE do_signal(int signum);
-int ALARMED = 0;
-unsigned int OPT_DEBUG = 0;
+int RESTART = 0; /* Flagged to restart on next cycle */
+int ALARMED = 0; /* Flagged to call timer functions on next cycle */
+unsigned int OPT_DEBUG = 0; /* Debug level */
char *CONFNAME = DEFAULTNAME;
char *CONFDIR = BOPM_ETCDIR;
char spid[16];
pid_t pid;
int c, lenc, lenl, lenp;
- unsigned int nc_counter;
+ unsigned int nc_counter, i;
FILE *pidout;
+ struct rlimit rlim;
nc_counter = 0;
while (1)
{
+
+
+ /* Main cycles */
irc_cycle();
scan_cycle();
- if (ALARMED)
+
+ /* Restart bopm if main_restart() was called (usually happens by m_kill in irc.c) */
+ if(RESTART)
+ {
+ log("MAIN -> Restarting process");
+
+ /* Get upper file descriptor limit */
+ if(getrlimit(RLIMIT_NOFILE, &rlim) == -1)
+ {
+ log("MAIN RESTART -> getrlimit() error retrieving RLIMIT_NOFILE (%s)", strerror(errno));
+ return;
+ }
+
+ if(OPT_DEBUG)
+ log("MAIN RESTART -> Setting file descriptors %d-%d F_SETFL", STDERR_FILENO + 1,
+ rlim.rlim_cur);
+
+ /* Set file descriptors strderr-rlim_cur close on exec */
+ for(i = STDERR_FILENO + 1; i < rlim.rlim_cur; i++)
+ fcntl(i, F_SETFD, FD_CLOEXEC);
+
+ /* execute new process */
+ if(execve(argv[0], argv, NULL) == -1)
+ log("MAIN RESTART -> Execution of \"%s\" failed. ERROR: %s", strerror(errno));
+
+ /* Should only get here if execve failed */
+ RESTART = 0;
+ }
+
+
+ /* Call 1 second timers */
+ if(ALARMED)
{
irc_timer();
scan_timer();
ALARMED = 0;
}
+
+
}
if (!OPT_DEBUG)
break;
}
}
+
+
+void main_restart()
+{
+ RESTART = 1;
+}