Mercurial > hg > nnchat
diff nnchat.c @ 168:2e4850ece456
Partially re-factor connection handling.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 14 Nov 2010 22:08:08 +0200 |
parents | f2f0b6f9281b |
children | 8d4cdbeae606 |
line wrap: on
line diff
--- a/nnchat.c Sat Nov 06 18:00:22 2010 +0200 +++ b/nnchat.c Sun Nov 14 22:08:08 2010 +0200 @@ -29,7 +29,6 @@ #define SET_MIN_BACKBUF (1024) /* Backbuffer size (in lines) */ #define SET_MAX_HISTORY (16) /* Command history length */ #define SET_DELAY (15) -#define SET_DELAY_USEC (SET_DELAY * 250) #define SET_KEEPALIVE (15*60) /* Ping/keepalive period in seconds */ @@ -360,12 +359,12 @@ } -int handleUser(int sock, const char *str) +int handleUser(nn_conn_t *conn, const char *str) { const char *msg = "</USER><MESSAGE>", *p = str; char *q, *s, *t, *h, *p2; - (void) sock; + (void) conn; s = strstr(str, msg); if (!s) return 1; @@ -428,7 +427,7 @@ } -int handleLogin(int sock, const char *str) +int handleLogin(nn_conn_t *conn, const char *str) { char tmpStr[256]; @@ -439,18 +438,18 @@ return -2; } else if (!strncmp(str, "SUCCESS", 7)) { printMsg("½2½Login success½0½ - ½3½%s½0½\n", tmpStr); - nn_send_msg(sock, optUserName2, "%%2FRequestUserList"); + nn_conn_send_msg(conn, optUserName2, "%%2FRequestUserList"); return 0; } else return 1; } -int handleAddUser(int sock, const char *str) +int handleAddUser(nn_conn_t *conn, const char *str) { char *p, *s = strstr(str, "</ADD_USER>"); - (void) sock; + (void) conn; if (!s) return 1; *s = 0; @@ -466,11 +465,11 @@ } -int handleDeleteUser(int sock, const char *str) +int handleDeleteUser(nn_conn_t *conn, const char *str) { char *p, *s = strstr(str, "</DELETE_USER>"); - (void) sock; + (void) conn; if (!s) return 1; *s = 0; @@ -486,17 +485,17 @@ } -int handleFoo(int sock, const char *str) +int handleFoo(nn_conn_t *conn, const char *str) { - (void) sock; (void) str; + (void) conn; (void) str; return 0; } -int handleBoot(int sock, const char *str) +int handleBoot(nn_conn_t *conn, const char *str) { - (void) sock; (void) str; + (void) conn; (void) str; errorMsg("Booted by server.\n"); return -1; } @@ -505,7 +504,7 @@ typedef struct { char *cmd; ssize_t len; - int (*handler)(int, const char *); + int (*handler)(nn_conn_t *, const char *); } protocmd_t; @@ -521,7 +520,7 @@ static const int nprotoCmds = sizeof(protoCmds) / sizeof(protoCmds[0]); -int handleProtocol(const int sock, const char *buf, const ssize_t bufLen) +int handleProtocol(nn_conn_t *conn, const char *buf, const ssize_t bufLen) { static BOOL protoCmdsInit = FALSE; int i; @@ -535,7 +534,7 @@ for (i = 0; i < nprotoCmds; i++) { ssize_t cmdLen = protoCmds[i].len; if (cmdLen < bufLen && !strncmp(buf, protoCmds[i].cmd, cmdLen)) - return protoCmds[i].handler(sock, buf + cmdLen); + return protoCmds[i].handler(conn, buf + cmdLen); } if (optDebug) { @@ -556,7 +555,7 @@ return strcasecmp((char *) s1, (char *) s2); } -int handleUserInput(const int sock, char *buf, size_t bufLen) +int handleUserInput(nn_conn_t *conn, char *buf, size_t bufLen) { char *tmpStr, tmpBuf[4096]; BOOL result; @@ -579,7 +578,7 @@ } optUserColor = tmpInt; printMsg("Setting color to #%06x\n", optUserColor); - nn_send_msg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); + nn_conn_send_msg(conn, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); return 0; } else if (!strncasecmp(buf, "/ignore", 7)) { char *name = trimLeft(buf + 7); @@ -675,7 +674,7 @@ /* Send double-encoded */ tmpStr = nn_dblencode_str(buf); if (tmpStr == 0) return -2; - result = nn_send_msg(sock, optUserName2, "%s", tmpStr); + result = nn_conn_send_msg(conn, optUserName2, "%s", tmpStr); th_free(tmpStr); return result ? 0 : -1; @@ -804,9 +803,11 @@ return FALSE; } + int main(int argc, char *argv[]) { - int tmpSocket = -1, curVis = ERR, updateCount = 0; + nn_conn_t *conn = NULL; + int curVis = ERR, updateCount = 0; struct hostent *tmpHost; BOOL argsOK, isError = FALSE, exitProg = FALSE, @@ -815,10 +816,8 @@ networkInit = FALSE, insertMode = TRUE; time_t prevTime; - struct timeval socktv; - fd_set sockfds; char *tmpStr; - nn_editbuf_t *editBuf = nn_editbuf_new(SET_BUFSIZE); + nn_editbuf_t *editBuf = nn_editbuf_new(NN_TMPBUF_SIZE); nn_editbuf_t *histBuf[SET_MAX_HISTORY+2]; int histPos = 0, histMax = 0; @@ -926,34 +925,39 @@ /* To emulate the official client, we first make a request for * policy file, even though we don't use it for anything... */ - if ((tmpSocket = nn_open_connection((struct in_addr *) tmpHost->h_addr, 843)) < 0) { + if ((conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, 843)) == NULL) { THERR("Policy file request connection setup failed!\n"); goto err_exit; } - + if (!nn_conn_check(conn)) + goto err_exit; + tmpStr = "<policy-file-request/>"; - if (nn_send_to_socket(tmpSocket, tmpStr, strlen(tmpStr) + 1) == FALSE) { + if (nn_conn_send_buf(conn, tmpStr, strlen(tmpStr) + 1) == FALSE) { THERR("Failed to send policy file request.\n"); goto err_exit; } else { - ssize_t gotBuf; - char tmpBuf[SET_BUFSIZE]; - gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0); - tmpBuf[gotBuf-1] = 0; - THMSG(2, "Probe got: %s\n", tmpBuf); - nn_close_connection(tmpSocket); + int cres = nn_conn_pull(conn); + if (cres == 0) { + THMSG(2, "Probe got: %s\n", conn->buf); + } else { + THMSG(2, "Could not get policy probe.\n"); + } } + nn_conn_close(conn); /* Okay, now do the proper connection ... */ - if ((tmpSocket = nn_open_connection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) { + if ((conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, optPort)) == NULL) { THERR("Main connection setup failed!\n"); goto err_exit; } + if (!nn_conn_check(conn)) + goto err_exit; THMSG(1, "Connected, logging in as '%s', site '%s'.\n", optUserName, optSite); optUserName2 = nn_dblencode_str(optUserName); tmpStr = nn_dblencode_str(optSite); - nn_send_msg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); + nn_conn_send_msg(conn, optUserName2, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); th_free(tmpStr); /* Initialize NCurses */ @@ -1001,60 +1005,30 @@ /* Enter mainloop */ prevTime = time(NULL); - FD_ZERO(&sockfds); - FD_SET(tmpSocket, &sockfds); while (!isError && !exitProg) { - int result; - fd_set tmpfds; - - /* Check for incoming data from the server */ - socktv.tv_sec = 0; - socktv.tv_usec = SET_DELAY_USEC; - tmpfds = sockfds; - if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &socktv)) == -1) { - int res = nn_get_socket_errno(); - if (res != EINTR) { - errorMsg("Error occured in select(sockfds): %d, %s\n", - res, nn_get_socket_errstr(res)); - isError = TRUE; - } - } else if (FD_ISSET(tmpSocket, &tmpfds)) { - ssize_t gotBuf; - char tmpBuf[8192]; - char *bufPtr = tmpBuf; - gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0); - - if (gotBuf < 0) { - int res = nn_get_socket_errno(); - errorMsg("Error in recv: %d, %s\n", res, nn_get_socket_errstr(res)); - isError = TRUE; - } else if (gotBuf == 0) { - errorMsg("Server closed connection.\n"); - isError = TRUE; - } else { - /* Handle protocol data */ - tmpBuf[gotBuf] = 0; - do { - size_t bufLen = strlen(bufPtr) + 1; - result = handleProtocol(tmpSocket, bufPtr, bufLen); - - if (result > 0) { - /* Couldn't handle the message for some reason */ - printMsg("Could not handle: %s\n", tmpBuf); - } else if (result < 0) { - /* Fatal error, quit */ - errorMsg("Fatal error with message: %s\n", tmpBuf); - isError = TRUE; - } - - gotBuf -= bufLen; - bufPtr += bufLen; - } while (gotBuf > 0 && !isError); - updateStatus(insertMode); - } + int cres = nn_conn_pull(conn); + if (cres == 0) { + do { + size_t bufLen = strlen(conn->ptr) + 1; + int result = handleProtocol(conn, conn->ptr, bufLen); + + if (result > 0) { + /* Couldn't handle the message for some reason */ + printMsg("Could not handle: %s\n", conn->ptr); + } else if (result < 0) { + /* Fatal error, quit */ + errorMsg("Fatal error with message: %s\n", conn->ptr); + isError = TRUE; + } + + conn->got -= bufLen; + conn->ptr += bufLen; + } while (conn->got > 0 && !isError); } - + if (!nn_conn_check(conn)) + isError = TRUE; + /* Handle user input */ if (!optDaemon) { int c, cnt = 0; @@ -1103,6 +1077,7 @@ case '\r': /* Call the user input handler */ if (editBuf->len > 0) { + int result; if (histMax > 0) { nn_editbuf_free(histBuf[SET_MAX_HISTORY+1]); @@ -1115,7 +1090,7 @@ if (histMax < SET_MAX_HISTORY) histMax++; nn_editbuf_insert(editBuf, editBuf->len, 0); - result = handleUserInput(tmpSocket, editBuf->data, editBuf->len); + result = handleUserInput(conn, editBuf->data, editBuf->len); nn_editbuf_clear(editBuf); @@ -1261,7 +1236,7 @@ if (++updateCount > 10) { time_t tmpTime = time(NULL); if (tmpTime - prevTime > SET_KEEPALIVE) { - nn_send_msg(tmpSocket, optUserName2, "/listallusers"); + nn_conn_send_msg(conn, optUserName2, "/listallusers"); prevTime = tmpTime; } @@ -1270,7 +1245,7 @@ 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); - nn_send_msg(tmpSocket, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); + nn_conn_send_msg(conn, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); } updateStatus(insertMode); @@ -1301,7 +1276,7 @@ th_free(optUserName2); - nn_close_connection(tmpSocket); + nn_conn_close(conn); if (networkInit) nn_network_close();