mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2026-01-08 18:22:30 +01:00
195 lines
4.9 KiB
Diff
195 lines
4.9 KiB
Diff
From 93d007481e25c9db88e8b16117b0378d51951bb6 Mon Sep 17 00:00:00 2001
|
|
From: Natanael Copa <ncopa@alpinelinux.org>
|
|
Date: Thu, 07 Mar 2013 15:20:22 +0000
|
|
Subject: fix segfault when IRC server does disconnect
|
|
|
|
and fix lots of whitespace damage
|
|
---
|
|
diff --git a/irc.c b/irc.c
|
|
index 92a925e..5832421 100644
|
|
--- a/irc.c
|
|
+++ b/irc.c
|
|
@@ -14,11 +14,11 @@ static int tcp_connect(const char *host, int port)
|
|
struct sockaddr_in addr;
|
|
struct hostent *h;
|
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
- if (sock < 0)
|
|
+ if (sock < 0)
|
|
return sock;
|
|
|
|
h = gethostbyname(host);
|
|
- if (h == NULL)
|
|
+ if (h == NULL)
|
|
return -1;
|
|
|
|
memset(&addr, 0, sizeof(addr));
|
|
@@ -38,17 +38,17 @@ struct irc_session *irc_connect(const char* server, int port, const char *nick,
|
|
{
|
|
char buf[256];
|
|
struct irc_session *sess;
|
|
-
|
|
+
|
|
sess = malloc(sizeof(struct irc_session));
|
|
if (sess == NULL)
|
|
return NULL;
|
|
-
|
|
+
|
|
sess->nick = nick;
|
|
sess->server = server;
|
|
sess->fd = tcp_connect(server, port);
|
|
- if (sess->fd < 0)
|
|
+ if (sess->fd < 0)
|
|
return NULL;
|
|
-
|
|
+
|
|
/* login */
|
|
if (pass)
|
|
irc_send(sess, "PASS", pass);
|
|
@@ -79,7 +79,9 @@ int irc_send_ping(struct irc_session *s)
|
|
|
|
int irc_close(struct irc_session *s, const char *msg)
|
|
{
|
|
- irc_send(s, "QUIT", msg ? msg : "");
|
|
- close(s->fd);
|
|
+ if (s->fd > 0) {
|
|
+ irc_send(s, "QUIT", msg ? msg : "");
|
|
+ close(s->fd);
|
|
+ }
|
|
free(s);
|
|
}
|
|
diff --git a/sircbot.c b/sircbot.c
|
|
index b85d7d0..7d9c1a3 100644
|
|
--- a/sircbot.c
|
|
+++ b/sircbot.c
|
|
@@ -56,8 +56,8 @@ struct sircbot_socket_callback {
|
|
int (*callback)(struct sircbot_session *sb, struct pollfd *fds,
|
|
void *ctx);
|
|
};
|
|
-
|
|
-
|
|
+
|
|
+
|
|
static int foreground = 0;
|
|
static int sigterm = 0;
|
|
static int flush_rate = 2;
|
|
@@ -90,7 +90,7 @@ int daemonize(const char *pidfile, const char *logfile)
|
|
/* exit parent */
|
|
if (pid > 0)
|
|
exit(0);
|
|
-
|
|
+
|
|
/* detatch to controling terminal */
|
|
setsid();
|
|
|
|
@@ -220,10 +220,10 @@ int run_hooks(char *user, char *rcpt, char* data)
|
|
/* exit parent */
|
|
if (pid > 0)
|
|
exit(0);
|
|
-
|
|
+
|
|
snprintf(dir, sizeof(dir), "/etc/" PROGNAME ".d/%s", rcpt);
|
|
printf("DEBUG: running scripts in %s\n", dir);
|
|
- execlp("/bin/run-parts", "/bin/run-parts", "-a", user,
|
|
+ execlp("/bin/run-parts", "/bin/run-parts", "-a", user,
|
|
"-a", data, "-a", rcpt, dir, NULL);
|
|
log_err("run-parts");
|
|
exit(1);
|
|
@@ -302,17 +302,21 @@ int parse_irc_data(struct sircbot_session *sb, char *buf)
|
|
}
|
|
|
|
/* callback functions */
|
|
-static int irc_server_cb(struct sircbot_session *sb, struct pollfd *fds,
|
|
+static int irc_server_cb(struct sircbot_session *sb, struct pollfd *fds,
|
|
void *ctx)
|
|
{
|
|
char buf[4096];
|
|
int r;
|
|
struct irc_session *sess = (struct irc_session *) ctx;
|
|
|
|
- if (fds->revents & POLLHUP)
|
|
+ if (fds->revents & POLLHUP) {
|
|
/* server hang up on us */
|
|
+ printf("DEBUG: %s: connection closed\n", sess ? sess->server : "null");
|
|
+ close(sess->fd);
|
|
+ sess->fd = -1;
|
|
return 0;
|
|
-
|
|
+ }
|
|
+
|
|
if (fds->revents & POLLERR) {
|
|
log_err(sess->server);
|
|
return -1;
|
|
@@ -340,7 +344,7 @@ int channel_extend_fd_array(struct sircbot_channel *chan)
|
|
chan->fd_array[i] = -1;
|
|
return 0;
|
|
}
|
|
-
|
|
+
|
|
|
|
void channel_add_connection(struct sircbot_channel *chan, int fd)
|
|
{
|
|
@@ -428,7 +432,7 @@ static int irc_reset_pollfds(struct sircbot_session *sb, struct pollfd *fds,
|
|
fds[n].fd = sb->sess->fd;
|
|
fds[n].events = POLLIN;
|
|
fds[n].revents = 0;
|
|
- cb[n].context = NULL;
|
|
+ cb[n].context = sb->sess;
|
|
cb[n].callback = &irc_server_cb;
|
|
n++;
|
|
|
|
@@ -474,18 +478,24 @@ static int send_fifo_queue(struct irc_session *sess,
|
|
return r;
|
|
}
|
|
|
|
-static void join_channels(struct sircbot_session *sb)
|
|
+static int join_channels(struct sircbot_session *sb)
|
|
{
|
|
time_t now = time(NULL);
|
|
int i;
|
|
/* wait atleast 5 secs before we join a channel */
|
|
for (i = 0; i < sb->numchan; i++)
|
|
- if ((now - sb->chan[i].last_closetime) > 5
|
|
- && sb->chan[i].listen_fd < 0) {
|
|
+ if ((now - sb->chan[i].last_closetime) > 5
|
|
+ && sb->chan[i].listen_fd < 0 && sb->sess != NULL) {
|
|
+ int r = 0;
|
|
printf("DEBUG: joining %s\n", sb->chan[i].name);
|
|
sb->chan[i].last_closetime = now;
|
|
- irc_send(sb->sess, "JOIN", sb->chan[i].name);
|
|
+ r = irc_send(sb->sess, "JOIN", sb->chan[i].name);
|
|
+ if (r < 0) {
|
|
+ printf("DEBUG: error %s: %s\n", sb->sess->server, strerror(r));
|
|
+ return r;
|
|
+ }
|
|
}
|
|
+ return 0;
|
|
}
|
|
|
|
static int irc_loop(struct sircbot_session *sb)
|
|
@@ -504,7 +514,8 @@ static int irc_loop(struct sircbot_session *sb)
|
|
tv.tv_sec = 1;
|
|
tv.tv_nsec = 0;
|
|
while (!sigterm) {
|
|
- join_channels(sb);
|
|
+ if (join_channels(sb) < 0)
|
|
+ goto ret_err;
|
|
n = irc_reset_pollfds(sb, fds, cbs, maxfds);
|
|
r = ppoll(fds, n, &tv, &sigmask);
|
|
if (r < 0) {
|
|
@@ -633,11 +644,11 @@ int main(int argc, char *argv[])
|
|
sleep(10);
|
|
continue;
|
|
}
|
|
-
|
|
+
|
|
irc_loop(&sb);
|
|
irc_close(sb.sess, "bye");
|
|
/* reset channel sockets */
|
|
- for (i = 0; i < argc; i++)
|
|
+ for (i = 0; i < argc; i++)
|
|
close_channel_socket(&sb.chan[i], 0);
|
|
if (sigterm)
|
|
break;
|
|
--
|
|
cgit v0.9.0.3
|