From 93d007481e25c9db88e8b16117b0378d51951bb6 Mon Sep 17 00:00:00 2001 From: Natanael Copa 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