# HG changeset patch # User Matti Hamalainen # Date 1246802140 -10800 # Node ID 7c9538e71c894653781231213ae18450db29d342 # Parent 69f9c46e4a9472acb579ddcbdd927d0ac93f760e Add connection keepalive by sending /listallusers every 15 minutes, due to NN server booting after about 30 minutes of inactivity; Improve handling of error messages; Add handling for "" protocol token. diff -r 69f9c46e4a94 -r 7c9538e71c89 nnchat.c --- a/nnchat.c Sat Jun 20 01:45:09 2009 +0300 +++ b/nnchat.c Sun Jul 05 16:55:40 2009 +0300 @@ -1,7 +1,7 @@ /* * NNChat - Custom chat client for NewbieNudes.com chatrooms * Written by Matti 'ccr' Hämäläinen - * (C) Copyright 2008 Tecnic Software productions (TNSP) + * (C) Copyright 2008-2009 Tecnic Software productions (TNSP) */ #include "libnnchat.h" #include @@ -20,13 +20,14 @@ #define SET_MAX_HISTORY (16) #define SET_DELAY (15) #define SET_DELAY_USEC (SET_DELAY * 1000) +#define SET_KEEPALIVE (15*60) /* Ping/keepalive period in seconds */ /* Options */ int optPort = 8005; int optUserColor = 0x006080; -char *optServer = "www11.servemedata.com", +char *optServer = "chat.newbienudes.com", *optUserName = NULL, *optUserName2 = NULL, *optPassword = NULL, @@ -311,6 +312,20 @@ } +void errorMsg(char *fmt, ...) +{ + char buf[8192]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + printMsg(buf); + THERR(buf); +} + + int handleUser(int sock, char *str) { const char *msg = ""; @@ -430,6 +445,14 @@ } +int handleBoot(int sock, char *str) +{ + (void) sock; (void) str; + errorMsg("Booted by server.\n"); + return -1; +} + + typedef struct { char *cmd; int (*handler)(int, char *); @@ -442,6 +465,7 @@ { "", handleDeleteUser }, { "", handleAddUser }, { "", handleFoo }, + { "", handleBoot }, }; const int nprotoCmds = (sizeof(protoCmds) / sizeof(protoCmds[0])); @@ -565,7 +589,8 @@ cursesInit = FALSE, networkInit = FALSE, insertMode = TRUE; - struct timeval tv; + time_t prevTime; + struct timeval socktv; fd_set sockfds; char *tmpStr; nn_editbuf_t *editBuf = newBuf(SET_BUFSIZE); @@ -575,7 +600,7 @@ memset(histBuf, 0, sizeof(histBuf)); /* Initialize */ - th_init("NNChat", "Newbie Nudes chat client", "0.7.1", + th_init("NNChat", "Newbie Nudes chat client", "0.7.2", "Written and designed by Anonymous Finnish Guy (C) 2008-2009", "This software is freeware, use and distribute as you wish."); th_verbosityLevel = 0; @@ -621,18 +646,18 @@ THMSG(2, "True hostname: %s\n", tmpHost->h_name); -#if 0 +#if 1 /* To emulate the official client, we first make a request for * policy file, even though we don't use it for anything... */ - if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) { + if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, 843)) < 0) { THERR("Policy file request connection setup failed!\n"); goto err_exit; } tmpStr = ""; if (sendToSocket(tmpSocket, tmpStr, strlen(tmpStr) + 1) == FALSE) { - THERR("Failed to send fakeprobe.\n"); + THERR("Failed to send policy file request.\n"); goto err_exit; } else { ssize_t gotBuf; @@ -701,6 +726,7 @@ } /* Enter mainloop */ + prevTime = time(NULL); FD_ZERO(&sockfds); FD_SET(tmpSocket, &sockfds); @@ -709,13 +735,13 @@ fd_set tmpfds; /* Check for incoming data from the server */ - tv.tv_sec = 0; - tv.tv_usec = SET_DELAY_USEC; + socktv.tv_sec = 0; + socktv.tv_usec = SET_DELAY_USEC; tmpfds = sockfds; - if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &tv)) == -1) { + if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &socktv)) == -1) { int res = getSocketErrno(); if (res != EINTR) { - printMsg("Error occured in select(sockfds): %d, %s\n", + errorMsg("Error occured in select(sockfds): %d, %s\n", res, getSocketErrStr(res)); isError = TRUE; } @@ -727,10 +753,10 @@ if (gotBuf < 0) { int res = getSocketErrno(); - printMsg("Error in recv: %d, %s\n", res, getSocketErrStr(res)); + errorMsg("Error in recv: %d, %s\n", res, getSocketErrStr(res)); isError = TRUE; } else if (gotBuf == 0) { - printMsg("Server closed connection.\n"); + errorMsg("Server closed connection.\n"); isError = TRUE; } else { /* Handle protocol data */ @@ -744,7 +770,7 @@ printMsg("Could not handle: %s\n", tmpBuf); } else if (result < 0) { /* Fatal error, quit */ - printMsg("Fatal error with message: %s\n", tmpBuf); + errorMsg("Fatal error with message: %s\n", tmpBuf); isError = TRUE; } @@ -785,7 +811,7 @@ #ifdef KEY_RESIZE case KEY_RESIZE: if (!initializeWindows()) { - THERR("Error resizing ncurses windows\n"); + errorMsg("Error resizing ncurses windows\n"); isError = TRUE; } break; @@ -813,7 +839,7 @@ clearBuf(editBuf); if (result < 0) { - printMsg("Fatal error handling user input: %s\n", editBuf->data); + errorMsg("Fatal error handling user input: %s\n", editBuf->data); isError = TRUE; } @@ -938,17 +964,24 @@ } /* !optDaemon */ if (++updateCount > 10) { + time_t tmpTime = time(NULL); + if (tmpTime - prevTime > SET_KEEPALIVE) { + sendUserMsg(tmpSocket, optUserName2, "/listallusers"); + prevTime = tmpTime; + } + + if (!colorSet) { + colorSet = TRUE; + printMsg("%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); + printMsg("%s\n", th_prog_author); + printMsg("%s\n", th_prog_license); + sendUserMsg(tmpSocket, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); + } + updateStatus(insertMode); updateCount = 0; } - if (!colorSet) { - colorSet = TRUE; - printMsg("%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); - printMsg("%s\n", th_prog_author); - printMsg("%s\n", th_prog_license); - sendUserMsg(tmpSocket, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); - } } /* Shutdown */