irc_exit();
xmpp_exit();
- for (int i = 0; i < history; i++)
+ for (int i = 0; i < history; i++) {
+ free((void*)messages[i].from);
free((void*)messages[i].text);
+ }
release(&msg_buf);
}
--track-origins=yes \
--leak-check=full \
--leak-resolution=high \
+ --show-leak-kinds=all \
./$(PROG)
# Rules
#include <fcntl.h>
#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
#include <openssl/bio.h>
#include <openssl/ssl.h>
socklen_t elen = sizeof(err);
if (getsockopt(net->poll.fd, SOL_SOCKET, SO_ERROR, &err, &elen))
error("Error getting socket opt");
- if (err)
+ if (err) {
+ debug("Socket error: %s", strerror(err));
net_close(net);
+ }
/* State machine */
if (net->state == NET_CONNECT) {
struct addrinfo *addrs = NULL;
struct addrinfo hints = {};
char service[16];
+ int yes = 1, idle = 60;
net->host = strcopy(host);
net->port = port;
if (fcntl(sock, F_SETFL, flags|O_NONBLOCK) < 0)
error("Error setting net socket non-blocking");
+ if (setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)) < 0)
+ error("Error setting net socket keepidle");
+
+ if (setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &yes, sizeof(yes)) < 0)
+ error("Error setting net socket keepintvl");
+
+ if (setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &yes, sizeof(yes)) < 0)
+ error("Error setting net socket keepcnt");
+
+ if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) < 0)
+ error("Error setting net socket keepalive");
+
if (connect(sock, addrs->ai_addr, addrs->ai_addrlen) < 0)
if (errno != EINPROGRESS)
error("Error connecting socket");
static int sig_fd;
static int running;
static int theme;
+static int draw;
static char cmd_buf[512];
static int cmd_pos;
start_color();
timeout(0);
use_default_colors();
- mousemask(ALL_MOUSE_EVENTS, NULL);
color_title = color(COLOR_WHITE, COLOR_BLUE);
color_date = color(COLOR_BROWN, -1);
/* View event */
void view_sync(void)
{
- MEVENT btn;
int chr = getch();
/* Misc ncurses */
if (chr == ERR) {
- return;
- }
- if (chr == KEY_MOUSE) {
- if (getmouse(&btn) != OK)
- return;
+ goto redraw;
}
/* Window management */
chr, chr, chr, chr);
}
- /* Flush output to screen */
- refresh();
-}
-
-void view_draw(void)
-{
- if (!running)
- return;
-
+redraw:
+ /* Redraw screen */
update_windows();
draw_header();
draw_chat();
draw_status();
draw_cmdline();
+
+ refresh();
+}
+
+void view_draw(void)
+{
+ draw = 1;
}
void view_exit(void)
if (srv->state == XMPP_RECV_JID) {
if (match(start, "jid")) {
debug("xmpp: jid -> presence");
+ //net_print(&srv->net,
+ // "<iq id='ping' type='get' from='%s' to='%s'>"
+ // "<ping xmlns='urn:xmpp:ping'/>"
+ // "</iq>",
+ // srv->jid, srv->host);
srv->state = XMPP_SEND_PRESENCE;
}
}
if (srv->state == XMPP_SEND_PRESENCE) {
+ net_print(&srv->net, "<presence/>");
for (channel_t *cur = channels; cur; cur = cur->next) {
xmpp_channel_t *chan = (xmpp_channel_t*)cur;
if (cur->server != &srv->server || !chan->join)
match(start, "presence") ? XMPP_IN_PRESENCE :
XMPP_READY;
if (srv->state != XMPP_READY) {
- strncpy(srv->msg_jid, find_attr(attrs, "from"), JID_LEN);
+ const char *from = find_attr(attrs, "from") ?: "";
+ strncpy(srv->msg_jid, from, JID_LEN);
split_jid(srv->msg_jid, srv->msg_usr,
srv->msg_srv, srv->msg_res);
srv->msg_res[0] = '\0';
srv->msg_from = NULL;
srv->msg_chan = NULL;
+
+ static time_t due = 0;
+ static time_t now = 0;
+ now = time(NULL);
+ if (now > due) {
+ net_print(&srv->net, "<presence/>");
+ due = now + 30;
+ }
}
}
/* Error handling */