# HG changeset patch # User Matti Hamalainen # Date 1226645292 -7200 # Node ID 5228ad7b4f57eb56e542d9ce85d453af38abd202 # Parent 79982b0aad979858a0be00cc2dacf69755897250 Remove tabs from indentation. diff -r 79982b0aad97 -r 5228ad7b4f57 nnchat.c --- a/nnchat.c Fri Nov 14 08:46:16 2008 +0200 +++ b/nnchat.c Fri Nov 14 08:48:12 2008 +0200 @@ -28,30 +28,30 @@ int optPort = 8005; int optUserColor = 0x006080; char *optServer = "www11.servemedata.com", - *optUserName = NULL, - *optUserName2 = NULL, - *optPassword = NULL, - *optLogFilename = NULL, - *setTarget = NULL, - *optSite = "NN"; -BOOL optDaemon = FALSE; -FILE *optLogFile = NULL; + *optUserName = NULL, + *optUserName2 = NULL, + *optPassword = NULL, + *optLogFilename = NULL, + *setTarget = NULL, + *optSite = "NN"; +BOOL optDaemon = FALSE; +FILE *optLogFile = NULL; WINDOW *mainWin = NULL, - *statusWin = NULL, - *editWin = NULL; + *statusWin = NULL, + *editWin = NULL; BOOL setPrvMode = FALSE; /* Arguments */ optarg_t optList[] = { - { 0, '?', "help", "Show this help", OPT_NONE }, - { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, - { 2, 'p', "port", "Connect to port", OPT_ARGREQ }, - { 3, 's', "server", "Server to connect to", OPT_ARGREQ }, - { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ }, - { 5, 'l', "logfile", "Log filename", OPT_ARGREQ }, - { 6, 'D', "daemon", "A pseudo-daemon mode for logging", OPT_NONE }, - { 7, 'S', "site", "Site (default: NN)", OPT_ARGREQ }, + { 0, '?', "help", "Show this help", OPT_NONE }, + { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, + { 2, 'p', "port", "Connect to port", OPT_ARGREQ }, + { 3, 's', "server", "Server to connect to", OPT_ARGREQ }, + { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ }, + { 5, 'l', "logfile", "Log filename", OPT_ARGREQ }, + { 6, 'D', "daemon", "A pseudo-daemon mode for logging", OPT_NONE }, + { 7, 'S', "site", "Site (default: NN)", OPT_ARGREQ }, }; const int optListN = (sizeof(optList) / sizeof(optList[0])); @@ -59,419 +59,419 @@ int getColor(char *str) { - char *p = str; - int len, val = 0; - - for (len = 0; *p && len < 6; p++, len++) { - if (*p >= '0' && *p <= '9') { - val *= 16; val += (*p - '0'); - } else if (*p >= 'A' && *p <= 'F') { - val *= 16; val += (*p - 'A') + 10; - } else if (*p >= 'a' && *p <= 'f') { - val *= 16; val += (*p - 'a') + 10; - } else - return -1; - } - - return (len == 6) ? val : -1; + char *p = str; + int len, val = 0; + + for (len = 0; *p && len < 6; p++, len++) { + if (*p >= '0' && *p <= '9') { + val *= 16; val += (*p - '0'); + } else if (*p >= 'A' && *p <= 'F') { + val *= 16; val += (*p - 'A') + 10; + } else if (*p >= 'a' && *p <= 'f') { + val *= 16; val += (*p - 'a') + 10; + } else + return -1; + } + + return (len == 6) ? val : -1; } void argShowHelp() { - th_args_help(stdout, optList, optListN, th_prog_name, - "[options] "); + th_args_help(stdout, optList, optListN, th_prog_name, + "[options] "); } BOOL argHandleOpt(const int optN, char *optArg, char *currArg) { - switch (optN) { - case 0: - argShowHelp(); - exit(0); - break; + switch (optN) { + case 0: + argShowHelp(); + exit(0); + break; - case 1: - th_verbosityLevel++; - break; - - case 2: - optPort = atoi(optArg); - break; + case 1: + th_verbosityLevel++; + break; + + case 2: + optPort = atoi(optArg); + break; - case 3: - optServer = optArg; - break; - - case 4: - if ((optUserColor = getColor(optArg)) < 0) { - THERR("Invalid color argument '%s', should be a RGB hex triplet '000000'.\n", - optArg); - return FALSE; - } - THMSG(1, "Using color #%06x\n", optUserColor); - break; + case 3: + optServer = optArg; + break; + + case 4: + if ((optUserColor = getColor(optArg)) < 0) { + THERR("Invalid color argument '%s', should be a RGB hex triplet '000000'.\n", + optArg); + return FALSE; + } + THMSG(1, "Using color #%06x\n", optUserColor); + break; - case 5: - optLogFilename = optArg; - break; + case 5: + optLogFilename = optArg; + break; - case 7: - optSite = optArg; - break; + case 7: + optSite = optArg; + break; - case 6: - optDaemon = TRUE; - THMSG(1, "Running in pseudo-daemon mode.\n"); - break; + case 6: + optDaemon = TRUE; + THMSG(1, "Running in pseudo-daemon mode.\n"); + break; - default: - THERR("Unknown option '%s'.\n", currArg); - return FALSE; - } - - return TRUE; + default: + THERR("Unknown option '%s'.\n", currArg); + return FALSE; + } + + return TRUE; } BOOL argHandleFile(char *currArg) { - if (!optUserName) - optUserName = currArg; - else if (!optPassword) - optPassword = currArg; - else { - THERR("Username '%s' already specified on commandline!\n", optUserName); - return FALSE; - } - - return TRUE; + if (!optUserName) + optUserName = currArg; + else if (!optPassword) + optPassword = currArg; + else { + THERR("Username '%s' already specified on commandline!\n", optUserName); + return FALSE; + } + + return TRUE; } #ifdef __WIN32 const char *hstrerror(int err) { - static char buf[64]; - snprintf(buf, sizeof(buf), "Error #%d", err); - return buf; + static char buf[64]; + snprintf(buf, sizeof(buf), "Error #%d", err); + return buf; } int getSocketErrno(void) { - return WSAGetLastError(); + return WSAGetLastError(); } const char *getSocketErrStr(int err) { - static char buf[64]; - snprintf(buf, sizeof(buf), "Error #%d", err); - return buf; + static char buf[64]; + snprintf(buf, sizeof(buf), "Error #%d", err); + return buf; } #else int getSocketErrno(void) { - return errno; + return errno; } const char *getSocketErrStr(int err) { - return strerror(err); + return strerror(err); } #endif void updateStatus(BOOL insertMode) { - char tmpStr[128] = ""; - time_t timeStamp; - struct tm *tmpTime;; - - if (statusWin == NULL) return; - - timeStamp = time(NULL); - if ((tmpTime = localtime(&timeStamp)) != NULL) { - strftime(tmpStr, sizeof(tmpStr), "%H:%M:%S", tmpTime); - } - - wbkgdset(statusWin, 0x0d00); - werase(statusWin); - - wattrset(statusWin, A_BOLD); - mvwaddstr(statusWin, 0, 1, tmpStr); - - waddstr(statusWin, " | "); - wattrset(statusWin, A_BOLD | COLOR_PAIR(16)); - waddstr(statusWin, optUserName); - wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); + char tmpStr[128] = ""; + time_t timeStamp; + struct tm *tmpTime;; + + if (statusWin == NULL) return; + + timeStamp = time(NULL); + if ((tmpTime = localtime(&timeStamp)) != NULL) { + strftime(tmpStr, sizeof(tmpStr), "%H:%M:%S", tmpTime); + } + + wbkgdset(statusWin, 0x0d00); + werase(statusWin); + + wattrset(statusWin, A_BOLD); + mvwaddstr(statusWin, 0, 1, tmpStr); + + waddstr(statusWin, " | "); + wattrset(statusWin, A_BOLD | COLOR_PAIR(16)); + waddstr(statusWin, optUserName); + wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | "); - wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - waddstr(statusWin, insertMode ? "INS" : "DEL"); - - wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | Prv: "); + waddstr(statusWin, " | "); + wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); + waddstr(statusWin, insertMode ? "INS" : "DEL"); + + wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); + waddstr(statusWin, " | Prv: "); - wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - waddstr(statusWin, setTarget != NULL ? setTarget : "-"); + wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); + waddstr(statusWin, setTarget != NULL ? setTarget : "-"); - wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | P/C: "); - wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - snprintf(tmpStr, sizeof(tmpStr), "%d / #%06x", optPort, optUserColor); - waddstr(statusWin, tmpStr); + wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); + waddstr(statusWin, " | P/C: "); + wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); + snprintf(tmpStr, sizeof(tmpStr), "%d / #%06x", optPort, optUserColor); + waddstr(statusWin, tmpStr); - wrefresh(statusWin); + wrefresh(statusWin); } void printEditBuf(char *str, editbuf_t *buf) { - if (statusWin == NULL || buf == NULL) return; + if (statusWin == NULL || buf == NULL) return; - buf->data[buf->len] = 0; - werase(editWin); - - wattrset(editWin, A_BOLD); - mvwaddstr(editWin, 0, 0, str); - waddstr(editWin, "> "); - wattrset(editWin, A_NORMAL); - - if (buf->pos < buf->len) { - waddnstr(editWin, buf->data, buf->pos); - wattrset(editWin, A_REVERSE); - waddch(editWin, buf->data[buf->pos]); - wattrset(editWin, A_NORMAL); - waddnstr(editWin, buf->data + buf->pos + 1, buf->len - buf->pos - 1); - } else { - waddnstr(editWin, buf->data, buf->len); - wattrset(editWin, A_REVERSE); - waddch(editWin, ' '); - wattrset(editWin, A_NORMAL); - } - wrefresh(editWin); + buf->data[buf->len] = 0; + werase(editWin); + + wattrset(editWin, A_BOLD); + mvwaddstr(editWin, 0, 0, str); + waddstr(editWin, "> "); + wattrset(editWin, A_NORMAL); + + if (buf->pos < buf->len) { + waddnstr(editWin, buf->data, buf->pos); + wattrset(editWin, A_REVERSE); + waddch(editWin, buf->data[buf->pos]); + wattrset(editWin, A_NORMAL); + waddnstr(editWin, buf->data + buf->pos + 1, buf->len - buf->pos - 1); + } else { + waddnstr(editWin, buf->data, buf->len); + wattrset(editWin, A_REVERSE); + waddch(editWin, ' '); + wattrset(editWin, A_NORMAL); + } + wrefresh(editWin); } int printWin(WINDOW *win, const char *fmt) { - const char *s = fmt; - int col = 0; - - while (*s) { - if (*s == '½') { - int val = 0; - s++; - if (*s == '½') { - waddch(win, ((unsigned char) *s) | col); - s++; - } else { - while (*s && isdigit(*s)) { - val *= 10; - val += (*s - '0'); - s++; - } - if (*s != '½') return -1; - s++; - - if (val < 9) { - col = A_DIM | COLOR_PAIR(val); - } else if (val < 30) { - col = A_BOLD | COLOR_PAIR(val - 9); - } - } - } else { - waddch(win, ((unsigned char) *s) | col); - s++; - } - } - return 0; + const char *s = fmt; + int col = 0; + + while (*s) { + if (*s == '½') { + int val = 0; + s++; + if (*s == '½') { + waddch(win, ((unsigned char) *s) | col); + s++; + } else { + while (*s && isdigit(*s)) { + val *= 10; + val += (*s - '0'); + s++; + } + if (*s != '½') return -1; + s++; + + if (val < 9) { + col = A_DIM | COLOR_PAIR(val); + } else if (val < 30) { + col = A_BOLD | COLOR_PAIR(val - 9); + } + } + } else { + waddch(win, ((unsigned char) *s) | col); + s++; + } + } + return 0; } int printFile(FILE *outFile, const char *fmt) { - const char *s = fmt; - - while (*s) { - if (*s == '½') { - s++; - if (*s == '½') { - fputc((unsigned char) *s, outFile); - s++; - } else { - while (*s && isdigit(*s)) s++; - if (*s != '½') return -1; - s++; - } - } else { - fputc((unsigned char) *s, outFile); - s++; - } - } - - return 0; + const char *s = fmt; + + while (*s) { + if (*s == '½') { + s++; + if (*s == '½') { + fputc((unsigned char) *s, outFile); + s++; + } else { + while (*s && isdigit(*s)) s++; + if (*s != '½') return -1; + s++; + } + } else { + fputc((unsigned char) *s, outFile); + s++; + } + } + + return 0; } void printMsg(char *fmt, ...) { - char tmpStr[128] = "", buf[8192]; - va_list ap; - time_t timeStamp; - struct tm *tmpTime;; - - timeStamp = time(NULL); - if ((tmpTime = localtime(&timeStamp)) != NULL) { - strftime(tmpStr, sizeof(tmpStr), "½17½[½11½%H:%M:%S½17½]½0½ ", tmpTime); - } - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - if (optLogFile) { - printFile(optLogFile, tmpStr); - printFile(optLogFile, buf); - fflush(optLogFile); - } - - if (!optDaemon) { - printWin(mainWin, tmpStr); - printWin(mainWin, buf); - wrefresh(mainWin); - } + char tmpStr[128] = "", buf[8192]; + va_list ap; + time_t timeStamp; + struct tm *tmpTime;; + + timeStamp = time(NULL); + if ((tmpTime = localtime(&timeStamp)) != NULL) { + strftime(tmpStr, sizeof(tmpStr), "½17½[½11½%H:%M:%S½17½]½0½ ", tmpTime); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if (optLogFile) { + printFile(optLogFile, tmpStr); + printFile(optLogFile, buf); + fflush(optLogFile); + } + + if (!optDaemon) { + printWin(mainWin, tmpStr); + printWin(mainWin, buf); + wrefresh(mainWin); + } } int handleUser(int sock, char *str) { - const char *msg = ""; - char *p = str, *q, *s, *t, *h; - - (void) sock; - - s = strstr(str, msg); - if (!s) return 1; - *s = 0; - s += strlen(msg); - - q = strstr(s, ""); - if (!q) return 3; - *q = 0; - - s = decodeStr1(s); - if (!s) return -1; - - p = decodeStr1(p); - if (!p) { - th_free(s); - return -2; - } - - - if (*s == '/') { - t = stripXMLTags(s + 1); - if (!strncmp(t, "BPRV", 4)) { - h = decodeStr2(t + 1); - printMsg("½11½%s½0½\n", h); - } else { - h = decodeStr2(t); - printMsg("½9½* %s½0½\n", h); - } - th_free(h); - th_free(t); - } else { - BOOL isMine = strcmp(p, optUserName) == 0; - t = stripXMLTags(s); - h = decodeStr2(t); - printMsg("½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, p, h); - th_free(h); - th_free(t); - } - - th_free(s); - th_free(p); - return 0; + const char *msg = ""; + char *p = str, *q, *s, *t, *h; + + (void) sock; + + s = strstr(str, msg); + if (!s) return 1; + *s = 0; + s += strlen(msg); + + q = strstr(s, ""); + if (!q) return 3; + *q = 0; + + s = decodeStr1(s); + if (!s) return -1; + + p = decodeStr1(p); + if (!p) { + th_free(s); + return -2; + } + + + if (*s == '/') { + t = stripXMLTags(s + 1); + if (!strncmp(t, "BPRV", 4)) { + h = decodeStr2(t + 1); + printMsg("½11½%s½0½\n", h); + } else { + h = decodeStr2(t); + printMsg("½9½* %s½0½\n", h); + } + th_free(h); + th_free(t); + } else { + BOOL isMine = strcmp(p, optUserName) == 0; + t = stripXMLTags(s); + h = decodeStr2(t); + printMsg("½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, p, h); + th_free(h); + th_free(t); + } + + th_free(s); + th_free(p); + return 0; } int handleLogin(int sock, char *str) { - char tmpStr[256] = ""; - time_t timeStamp; - struct tm *tmpTime;; - - timeStamp = time(NULL); - if ((tmpTime = localtime(&timeStamp)) != NULL) { - strftime(tmpStr, sizeof(tmpStr), "%c", tmpTime); - } - - if (!strncmp(str, "FAILURE", 7)) { - printMsg("½1½Login failure½0½ - ½3½%s½0½\n", tmpStr); - return -2; - } else if (!strncmp(str, "SUCCESS", 7)) { - printMsg("½2½Login success½0½ - ½3½%s½0½\n", tmpStr); - sendUserMsg(sock, optUserName2, "%%2FRequestUserList"); - return 0; - } else - return 1; + char tmpStr[256] = ""; + time_t timeStamp; + struct tm *tmpTime;; + + timeStamp = time(NULL); + if ((tmpTime = localtime(&timeStamp)) != NULL) { + strftime(tmpStr, sizeof(tmpStr), "%c", tmpTime); + } + + if (!strncmp(str, "FAILURE", 7)) { + printMsg("½1½Login failure½0½ - ½3½%s½0½\n", tmpStr); + return -2; + } else if (!strncmp(str, "SUCCESS", 7)) { + printMsg("½2½Login success½0½ - ½3½%s½0½\n", tmpStr); + sendUserMsg(sock, optUserName2, "%%2FRequestUserList"); + return 0; + } else + return 1; } int handleAddUser(int sock, char *str) { - char *p, *s = strstr(str, ""); + char *p, *s = strstr(str, ""); - (void) sock; + (void) sock; - if (!s) return 1; - *s = 0; - - p = decodeStr1(str); - if (!p) return -1; - - printMsg("! ½3½%s½0½ ½2½ADDED.½0½\n", p); - th_free(p); - return 0; + if (!s) return 1; + *s = 0; + + p = decodeStr1(str); + if (!p) return -1; + + printMsg("! ½3½%s½0½ ½2½ADDED.½0½\n", p); + th_free(p); + return 0; } int handleDeleteUser(int sock, char *str) { - char *p, *s = strstr(str, ""); + char *p, *s = strstr(str, ""); - (void) sock; + (void) sock; - if (!s) return 1; - *s = 0; - - p = decodeStr1(str); - if (!p) return -1; - - printMsg("! ½3½%s½0½ ½1½DELETED.½0½\n", p); - th_free(p); - return 0; + if (!s) return 1; + *s = 0; + + p = decodeStr1(str); + if (!p) return -1; + + printMsg("! ½3½%s½0½ ½1½DELETED.½0½\n", p); + th_free(p); + return 0; } int handleFoo(int sock, char *str) { - (void) sock; (void) str; - - return 0; + (void) sock; (void) str; + + return 0; } typedef struct { - char *cmd; - int (*handler)(int, char *); + char *cmd; + int (*handler)(int, char *); } protocmd_t; protocmd_t protoCmds[] = { - { "", handleUser }, - { "", handleDeleteUser }, - { "", handleAddUser }, - { "", handleFoo }, + { "", handleUser }, + { "", handleDeleteUser }, + { "", handleAddUser }, + { "", handleFoo }, }; const int nprotoCmds = (sizeof(protoCmds) / sizeof(protoCmds[0])); @@ -479,536 +479,536 @@ int handleProtocol(const int sock, char *buf, size_t bufLen) { - int i; - - for (i = 0; i < nprotoCmds; i++) { - size_t cmdLen = strlen(protoCmds[i].cmd); - if (cmdLen < bufLen && !strncmp(buf, protoCmds[i].cmd, cmdLen)) { - return protoCmds[i].handler(sock, buf + cmdLen); - } - } - - return 1; + int i; + + for (i = 0; i < nprotoCmds; i++) { + size_t cmdLen = strlen(protoCmds[i].cmd); + if (cmdLen < bufLen && !strncmp(buf, protoCmds[i].cmd, cmdLen)) { + return protoCmds[i].handler(sock, buf + cmdLen); + } + } + + return 1; } int handleUserInput(const int sock, char *buf, size_t bufLen) { - char *tmpStr, *tmpStr2, tmpBuf[4096]; - BOOL result; - - /* Trim right */ - buf[--bufLen] = 0; - while (bufLen > 0 && (buf[bufLen] == '\n' || buf[bufLen] == '\r' || th_isspace(buf[bufLen]))) - buf[bufLen--] = 0; - - /* Check command */ - if (*buf == 0) { - return 1; - } else if (!strncmp(buf, "/color ", 7)) { - int tmpInt; - if ((tmpInt = getColor(buf+7)) < 0) { - printMsg("Invalid color value '%s'\n", buf+7); - return 1; - } - optUserColor = tmpInt; - printMsg("Setting color to #%06x\n", optUserColor); - sendUserMsg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); - return 0; - } else if (!strncmp(buf, "/flood ", 7)) { - int i; - - snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg . .", - buf+7); - - tmpStr = encodeStr2(tmpBuf); - if (!tmpStr) return -2; - tmpStr2 = encodeStr1(tmpStr); - if (!tmpStr2) { - th_free(tmpStr); - return -3; - } - - result = TRUE; - for (i = 0; i < 50 && result; i++) { - result = sendUserMsg(sock, optUserName2, "%s", tmpStr2); - usleep(250); - } - - th_free(tmpStr); - th_free(tmpStr2); - return 0; - } else if (!strncmp(buf, "/to ", 4)) { - th_free(setTarget); - setTarget = strdup(buf + 4); - printMsg("Set prv target to '%s'\n", setTarget); - return 0; - } else if (!strncmp(buf, "/who", 4)) { - snprintf(tmpBuf, sizeof(tmpBuf), "/listallusers"); - buf = tmpBuf; - } else if (setPrvMode) { - if (setTarget != NULL) { - snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", setTarget, buf); - buf = tmpBuf; - } else { - printMsg("No target set, exiting prv mode.\n"); - setPrvMode = FALSE; - return 1; - } - } - - - /* Send double-encoded */ - tmpStr = encodeStr2(buf); - if (!tmpStr) return -2; - tmpStr2 = encodeStr1(tmpStr); - if (!tmpStr2) { - th_free(tmpStr); - return -3; - } - - result = sendUserMsg(sock, optUserName2, "%s", tmpStr2); - th_free(tmpStr); - th_free(tmpStr2); - if (result) - return 0; - else - return -1; + char *tmpStr, *tmpStr2, tmpBuf[4096]; + BOOL result; + + /* Trim right */ + buf[--bufLen] = 0; + while (bufLen > 0 && (buf[bufLen] == '\n' || buf[bufLen] == '\r' || th_isspace(buf[bufLen]))) + buf[bufLen--] = 0; + + /* Check command */ + if (*buf == 0) { + return 1; + } else if (!strncmp(buf, "/color ", 7)) { + int tmpInt; + if ((tmpInt = getColor(buf+7)) < 0) { + printMsg("Invalid color value '%s'\n", buf+7); + return 1; + } + optUserColor = tmpInt; + printMsg("Setting color to #%06x\n", optUserColor); + sendUserMsg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); + return 0; + } else if (!strncmp(buf, "/flood ", 7)) { + int i; + + snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg . .", + buf+7); + + tmpStr = encodeStr2(tmpBuf); + if (!tmpStr) return -2; + tmpStr2 = encodeStr1(tmpStr); + if (!tmpStr2) { + th_free(tmpStr); + return -3; + } + + result = TRUE; + for (i = 0; i < 50 && result; i++) { + result = sendUserMsg(sock, optUserName2, "%s", tmpStr2); + usleep(250); + } + + th_free(tmpStr); + th_free(tmpStr2); + return 0; + } else if (!strncmp(buf, "/to ", 4)) { + th_free(setTarget); + setTarget = strdup(buf + 4); + printMsg("Set prv target to '%s'\n", setTarget); + return 0; + } else if (!strncmp(buf, "/who", 4)) { + snprintf(tmpBuf, sizeof(tmpBuf), "/listallusers"); + buf = tmpBuf; + } else if (setPrvMode) { + if (setTarget != NULL) { + snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", setTarget, buf); + buf = tmpBuf; + } else { + printMsg("No target set, exiting prv mode.\n"); + setPrvMode = FALSE; + return 1; + } + } + + + /* Send double-encoded */ + tmpStr = encodeStr2(buf); + if (!tmpStr) return -2; + tmpStr2 = encodeStr1(tmpStr); + if (!tmpStr2) { + th_free(tmpStr); + return -3; + } + + result = sendUserMsg(sock, optUserName2, "%s", tmpStr2); + th_free(tmpStr); + th_free(tmpStr2); + if (result) + return 0; + else + return -1; } BOOL initializeWindows(void) { - if (mainWin) delwin(mainWin); - if (statusWin) delwin(statusWin); - if (editWin) delwin(editWin); - - mainWin = newwin(LINES - 4, COLS, 0, 0); - statusWin = newwin(1, COLS, LINES - 4, 0); - editWin = newwin(3, COLS, LINES - 3, 0); - - if (mainWin == NULL || statusWin == NULL || editWin == NULL) { - THERR("Could not create ncurses windows!\n"); - return FALSE; - } - scrollok(mainWin, 1); - - return TRUE; + if (mainWin) delwin(mainWin); + if (statusWin) delwin(statusWin); + if (editWin) delwin(editWin); + + mainWin = newwin(LINES - 4, COLS, 0, 0); + statusWin = newwin(1, COLS, LINES - 4, 0); + editWin = newwin(3, COLS, LINES - 3, 0); + + if (mainWin == NULL || statusWin == NULL || editWin == NULL) { + THERR("Could not create ncurses windows!\n"); + return FALSE; + } + scrollok(mainWin, 1); + + return TRUE; } int main(int argc, char *argv[]) { - int tmpSocket, curVis, updateCount = 0; - struct hostent *tmpHost; - BOOL argsOK, isError = FALSE, - exitProg = FALSE, - colorSet = FALSE, - cursesInit = FALSE, + int tmpSocket, curVis, updateCount = 0; + struct hostent *tmpHost; + BOOL argsOK, isError = FALSE, + exitProg = FALSE, + colorSet = FALSE, + cursesInit = FALSE, #if __WIN32 - networkInit = FALSE, + networkInit = FALSE, #endif - insertMode = TRUE; - struct timeval tv; - fd_set sockfds; - char *tmpStr; - editbuf_t *editBuf = newBuf(SET_BUFSIZE); - editbuf_t *histBuf[SET_MAX_HISTORY+2]; - int histPos = 0, histMax = 0; - - memset(histBuf, 0, sizeof(histBuf)); - - /* Initialize */ - th_init("NNChat", "Newbie Nudes chat client", "0.6.5", - "Written and designed by Anonymous Finnish Guy (C) 2008", - "This software is freeware, use and distribute as you wish."); - th_verbosityLevel = 0; - - /* Parse arguments */ - argsOK = th_args_process(argc, argv, optList, optListN, - argHandleOpt, argHandleFile, FALSE); + insertMode = TRUE; + struct timeval tv; + fd_set sockfds; + char *tmpStr; + editbuf_t *editBuf = newBuf(SET_BUFSIZE); + editbuf_t *histBuf[SET_MAX_HISTORY+2]; + int histPos = 0, histMax = 0; + + memset(histBuf, 0, sizeof(histBuf)); + + /* Initialize */ + th_init("NNChat", "Newbie Nudes chat client", "0.6.5", + "Written and designed by Anonymous Finnish Guy (C) 2008", + "This software is freeware, use and distribute as you wish."); + th_verbosityLevel = 0; + + /* Parse arguments */ + argsOK = th_args_process(argc, argv, optList, optListN, + argHandleOpt, argHandleFile, FALSE); - /* Check the mode and arguments */ - if (optUserName == NULL || optPassword == NULL) { - THERR("User/pass not specified, get some --help\n"); - return -1; - } - - if (!argsOK) - return -2; + /* Check the mode and arguments */ + if (optUserName == NULL || optPassword == NULL) { + THERR("User/pass not specified, get some --help\n"); + return -1; + } + + if (!argsOK) + return -2; - /* Open logfile */ - if (optLogFilename) { - THMSG(1, "Opening logfile '%s'\n", optLogFilename); - - if ((optLogFile = fopen(optLogFilename, "a")) == NULL) { - THERR("Could not open logfile for appending!\n"); - return -9; - } - } - + /* Open logfile */ + if (optLogFilename) { + THMSG(1, "Opening logfile '%s'\n", optLogFilename); + + if ((optLogFile = fopen(optLogFilename, "a")) == NULL) { + THERR("Could not open logfile for appending!\n"); + return -9; + } + } + #ifdef __WIN32 - { - /* Initialize WinSock, if needed */ - WSADATA wsaData; - int err = WSAStartup(0x0101, &wsaData); - if (err != 0) { - THERR("Could not initialize WinSock DLL: %d\n", err); - goto err_exit; - } - networkInit = TRUE; + { + /* Initialize WinSock, if needed */ + WSADATA wsaData; + int err = WSAStartup(0x0101, &wsaData); + if (err != 0) { + THERR("Could not initialize WinSock DLL: %d\n", err); + goto err_exit; + } + networkInit = TRUE; } #endif - /* Okay ... */ - THMSG(1, "Trying to resolve host '%s' ...\n", optServer); - tmpHost = gethostbyname(optServer); - if (tmpHost == NULL) { - THERR("Could not resolve hostname: %s.\n", - hstrerror(h_errno)); - goto err_exit; - } - THMSG(2, "True hostname: %s\n", tmpHost->h_name); + /* Okay ... */ + THMSG(1, "Trying to resolve host '%s' ...\n", optServer); + tmpHost = gethostbyname(optServer); + if (tmpHost == NULL) { + THERR("Could not resolve hostname: %s.\n", + hstrerror(h_errno)); + goto err_exit; + } + THMSG(2, "True hostname: %s\n", tmpHost->h_name); #if 0 - /* 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) { - 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"); - 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); - closeConnection(tmpSocket); - } + /* 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) { + 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"); + 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); + closeConnection(tmpSocket); + } #endif - /* Okay, now do the proper connection ... */ - if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) { - THERR("Main connection setup failed!\n"); - goto err_exit; - } - - THMSG(1, "Connected, logging in as '%s', site '%s'.\n", optUserName, optSite); - optUserName2 = encodeStr1(optUserName); - tmpStr = encodeStr1(optSite); - sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); - th_free(tmpStr); - - /* Initialize NCurses */ - if (!optDaemon) { - if (LINES < 0 || LINES > 1000) LINES = 24; - if (COLS < 0 || COLS > 1000) COLS = 80; - LINES=24; - initscr(); - raw(); - keypad(stdscr, TRUE); - noecho(); - meta(stdscr, TRUE); - timeout(SET_DELAY); - curVis = curs_set(0); - if (has_colors()) { - start_color(); - - init_pair(1, COLOR_RED, COLOR_BLACK); - init_pair(2, COLOR_GREEN, COLOR_BLACK); - init_pair(3, COLOR_YELLOW, COLOR_BLACK); - init_pair(4, COLOR_BLUE, COLOR_BLACK); - init_pair(5, COLOR_MAGENTA, COLOR_BLACK); - init_pair(6, COLOR_CYAN, COLOR_BLACK); - init_pair(7, COLOR_WHITE, COLOR_BLACK); - init_pair(8, COLOR_BLACK, COLOR_BLACK); + /* Okay, now do the proper connection ... */ + if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) { + THERR("Main connection setup failed!\n"); + goto err_exit; + } + + THMSG(1, "Connected, logging in as '%s', site '%s'.\n", optUserName, optSite); + optUserName2 = encodeStr1(optUserName); + tmpStr = encodeStr1(optSite); + sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); + th_free(tmpStr); + + /* Initialize NCurses */ + if (!optDaemon) { + if (LINES < 0 || LINES > 1000) LINES = 24; + if (COLS < 0 || COLS > 1000) COLS = 80; + LINES=24; + initscr(); + raw(); + keypad(stdscr, TRUE); + noecho(); + meta(stdscr, TRUE); + timeout(SET_DELAY); + curVis = curs_set(0); + if (has_colors()) { + start_color(); + + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_YELLOW, COLOR_BLACK); + init_pair(4, COLOR_BLUE, COLOR_BLACK); + init_pair(5, COLOR_MAGENTA, COLOR_BLACK); + init_pair(6, COLOR_CYAN, COLOR_BLACK); + init_pair(7, COLOR_WHITE, COLOR_BLACK); + init_pair(8, COLOR_BLACK, COLOR_BLACK); - init_pair(10, COLOR_BLACK, COLOR_RED); - init_pair(11, COLOR_WHITE, COLOR_RED); - init_pair(12, COLOR_GREEN, COLOR_RED); - init_pair(13, COLOR_YELLOW, COLOR_RED); - init_pair(14, COLOR_BLUE, COLOR_RED); - init_pair(15, COLOR_MAGENTA, COLOR_RED); - init_pair(16, COLOR_CYAN, COLOR_RED); - - } - - cursesInit = TRUE; - - if (!initializeWindows()) - goto err_exit; - - clearBuf(editBuf); - printEditBuf("", editBuf); - updateStatus(insertMode); - } - - /* Enter mainloop */ - FD_ZERO(&sockfds); - FD_SET(tmpSocket, &sockfds); + init_pair(10, COLOR_BLACK, COLOR_RED); + init_pair(11, COLOR_WHITE, COLOR_RED); + init_pair(12, COLOR_GREEN, COLOR_RED); + init_pair(13, COLOR_YELLOW, COLOR_RED); + init_pair(14, COLOR_BLUE, COLOR_RED); + init_pair(15, COLOR_MAGENTA, COLOR_RED); + init_pair(16, COLOR_CYAN, COLOR_RED); + + } + + cursesInit = TRUE; + + if (!initializeWindows()) + goto err_exit; + + clearBuf(editBuf); + printEditBuf("", editBuf); + updateStatus(insertMode); + } + + /* Enter mainloop */ + FD_ZERO(&sockfds); + FD_SET(tmpSocket, &sockfds); - while (!isError && !exitProg) { - int result; - fd_set tmpfds; - - /* Check for incoming data from the server */ - tv.tv_sec = 0; - tv.tv_usec = SET_DELAY_USEC; - tmpfds = sockfds; - if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &tv)) == -1) { - int res = getSocketErrno(); - if (res != EINTR) { - printMsg("Error occured in select(sockfds): %d, %s\n", - res, getSocketErrStr(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 = getSocketErrno(); - printMsg("Error in recv: %d, %s\n", res, getSocketErrStr(res)); - isError = TRUE; - } else if (gotBuf == 0) { - printMsg("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 */ - printMsg("Fatal error with message: %s\n", tmpBuf); - isError = TRUE; - } - - gotBuf -= bufLen; - bufPtr += bufLen; - } while (gotBuf > 0 && !isError); - updateStatus(insertMode); - } - } - - /* Handle user input */ - if (!optDaemon) { - int c, cnt = 0; - BOOL update = FALSE; - - /* Handle several buffered keypresses at once */ - do { - c = wgetch(stdscr); - switch (c) { - case KEY_RESIZE: - if (!initializeWindows()) { - THERR("Error resizing ncurses windows\n"); - isError = TRUE; - } - break; - - case KEY_ENTER: - case '\n': - case '\r': - /* Call the user input handler */ - if (editBuf->len > 0) { - - if (histMax > 0) { - freeBuf(histBuf[SET_MAX_HISTORY+1]); - histBuf[SET_MAX_HISTORY+1] = NULL; - memmove(&histBuf[2], &histBuf[1], histMax * sizeof(histBuf[0])); - } - - histPos = 0; - histBuf[1] = copyBuf(editBuf); - if (histMax < SET_MAX_HISTORY) histMax++; - - insertBuf(editBuf, editBuf->len, 0); - result = handleUserInput(tmpSocket, editBuf->data, editBuf->len); - - clearBuf(editBuf); - - if (result < 0) { - printMsg("Fatal error handling user input: %s\n", editBuf->data); - isError = TRUE; - } - - update = TRUE; - } - break; - - case 0x09: /* Tab = switch between PRV */ - if (setPrvMode) - setPrvMode = FALSE; - else { - if (setTarget != NULL) - setPrvMode = TRUE; - } - update = TRUE; - break; - - case KEY_UP: /* Backwards in input history */ - if (histPos == 0) { - freeBuf(histBuf[0]); - histBuf[0] = copyBuf(editBuf); - } - if (histPos < histMax) { - histPos++; - freeBuf(editBuf); - editBuf = copyBuf(histBuf[histPos]); - update = TRUE; - } - break; - - case KEY_DOWN: /* Forwards in input history */ - if (histPos > 0) { - histPos--; - freeBuf(editBuf); - editBuf = copyBuf(histBuf[histPos]); - update = TRUE; - } - break; - - case 0x204: /* ctrl+left = Skip words left */ - while (editBuf->pos > 0 && isspace(editBuf->data[editBuf->pos - 1])) - editBuf->pos--; - while (editBuf->pos > 0 && !isspace(editBuf->data[editBuf->pos - 1])) - editBuf->pos--; - update = TRUE; - break; - - case 0x206: /* ctrl+right = Skip words right */ - while (editBuf->pos < editBuf->len && isspace(editBuf->data[editBuf->pos])) - editBuf->pos++; - while (editBuf->pos < editBuf->len && !isspace(editBuf->data[editBuf->pos])) - editBuf->pos++; - if (editBuf->pos > editBuf->len) - editBuf->pos = editBuf->len; - update = TRUE; - break; - - case 0x111: /* F9 = Quit */ - printMsg("Quitting per user request.\n"); - exitProg = TRUE; - break; - - case 0x109: /* F1 = Toggle insert / overwrite mode */ - insertMode = !insertMode; - update = TRUE; - break; - - case 0x10a: /* F2 = Clear editbuffer */ - clearBuf(editBuf); - update = TRUE; - break; - - case KEY_HOME: setBufPos(editBuf, 0); update = TRUE; break; - case KEY_END: setBufPos(editBuf, editBuf->len); update = TRUE; break; - case KEY_LEFT: setBufPos(editBuf, editBuf->pos - 1); update = TRUE; break; - case KEY_RIGHT: setBufPos(editBuf, editBuf->pos + 1); update = TRUE; break; - - case KEY_BACKSPACE: - deleteBuf(editBuf, editBuf->pos - 1); - setBufPos(editBuf, editBuf->pos - 1); - update = TRUE; - break; - - case 0x14a: - /* Delete */ - deleteBuf(editBuf, editBuf->pos); - update = TRUE; - break; - - case 0x0c: - /* ctrl+l */ - redrawwin(mainWin); - redrawwin(statusWin); - redrawwin(editWin); - break; - - case ERR: - /* Ignore */ - break; - - default: - if (isprint(c) || c == 0xe4 || c == 0xf6 || c == 0xc4 || c == 0xd6) { - if (insertMode) - insertBuf(editBuf, editBuf->pos, c); - else - writeBuf(editBuf, editBuf->pos, c); - setBufPos(editBuf, editBuf->pos + 1); - update = TRUE; - } else { - printMsg("Unhandled key: %02x\n", c); - } - break; - } - } while (c != ERR && !exitProg && ++cnt < 10); - - if (update) { - /* Update edit line */ - printEditBuf(setPrvMode ? setTarget : "", editBuf); - updateStatus(insertMode); - } - } /* !optDaemon */ - - if (++updateCount > 10) { - 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 */ + while (!isError && !exitProg) { + int result; + fd_set tmpfds; + + /* Check for incoming data from the server */ + tv.tv_sec = 0; + tv.tv_usec = SET_DELAY_USEC; + tmpfds = sockfds; + if ((result = select(tmpSocket+1, &tmpfds, NULL, NULL, &tv)) == -1) { + int res = getSocketErrno(); + if (res != EINTR) { + printMsg("Error occured in select(sockfds): %d, %s\n", + res, getSocketErrStr(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 = getSocketErrno(); + printMsg("Error in recv: %d, %s\n", res, getSocketErrStr(res)); + isError = TRUE; + } else if (gotBuf == 0) { + printMsg("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 */ + printMsg("Fatal error with message: %s\n", tmpBuf); + isError = TRUE; + } + + gotBuf -= bufLen; + bufPtr += bufLen; + } while (gotBuf > 0 && !isError); + updateStatus(insertMode); + } + } + + /* Handle user input */ + if (!optDaemon) { + int c, cnt = 0; + BOOL update = FALSE; + + /* Handle several buffered keypresses at once */ + do { + c = wgetch(stdscr); + switch (c) { + case KEY_RESIZE: + if (!initializeWindows()) { + THERR("Error resizing ncurses windows\n"); + isError = TRUE; + } + break; + + case KEY_ENTER: + case '\n': + case '\r': + /* Call the user input handler */ + if (editBuf->len > 0) { + + if (histMax > 0) { + freeBuf(histBuf[SET_MAX_HISTORY+1]); + histBuf[SET_MAX_HISTORY+1] = NULL; + memmove(&histBuf[2], &histBuf[1], histMax * sizeof(histBuf[0])); + } + + histPos = 0; + histBuf[1] = copyBuf(editBuf); + if (histMax < SET_MAX_HISTORY) histMax++; + + insertBuf(editBuf, editBuf->len, 0); + result = handleUserInput(tmpSocket, editBuf->data, editBuf->len); + + clearBuf(editBuf); + + if (result < 0) { + printMsg("Fatal error handling user input: %s\n", editBuf->data); + isError = TRUE; + } + + update = TRUE; + } + break; + + case 0x09: /* Tab = switch between PRV */ + if (setPrvMode) + setPrvMode = FALSE; + else { + if (setTarget != NULL) + setPrvMode = TRUE; + } + update = TRUE; + break; + + case KEY_UP: /* Backwards in input history */ + if (histPos == 0) { + freeBuf(histBuf[0]); + histBuf[0] = copyBuf(editBuf); + } + if (histPos < histMax) { + histPos++; + freeBuf(editBuf); + editBuf = copyBuf(histBuf[histPos]); + update = TRUE; + } + break; + + case KEY_DOWN: /* Forwards in input history */ + if (histPos > 0) { + histPos--; + freeBuf(editBuf); + editBuf = copyBuf(histBuf[histPos]); + update = TRUE; + } + break; + + case 0x204: /* ctrl+left = Skip words left */ + while (editBuf->pos > 0 && isspace(editBuf->data[editBuf->pos - 1])) + editBuf->pos--; + while (editBuf->pos > 0 && !isspace(editBuf->data[editBuf->pos - 1])) + editBuf->pos--; + update = TRUE; + break; + + case 0x206: /* ctrl+right = Skip words right */ + while (editBuf->pos < editBuf->len && isspace(editBuf->data[editBuf->pos])) + editBuf->pos++; + while (editBuf->pos < editBuf->len && !isspace(editBuf->data[editBuf->pos])) + editBuf->pos++; + if (editBuf->pos > editBuf->len) + editBuf->pos = editBuf->len; + update = TRUE; + break; + + case 0x111: /* F9 = Quit */ + printMsg("Quitting per user request.\n"); + exitProg = TRUE; + break; + + case 0x109: /* F1 = Toggle insert / overwrite mode */ + insertMode = !insertMode; + update = TRUE; + break; + + case 0x10a: /* F2 = Clear editbuffer */ + clearBuf(editBuf); + update = TRUE; + break; + + case KEY_HOME: setBufPos(editBuf, 0); update = TRUE; break; + case KEY_END: setBufPos(editBuf, editBuf->len); update = TRUE; break; + case KEY_LEFT: setBufPos(editBuf, editBuf->pos - 1); update = TRUE; break; + case KEY_RIGHT: setBufPos(editBuf, editBuf->pos + 1); update = TRUE; break; + + case KEY_BACKSPACE: + deleteBuf(editBuf, editBuf->pos - 1); + setBufPos(editBuf, editBuf->pos - 1); + update = TRUE; + break; + + case 0x14a: + /* Delete */ + deleteBuf(editBuf, editBuf->pos); + update = TRUE; + break; + + case 0x0c: + /* ctrl+l */ + redrawwin(mainWin); + redrawwin(statusWin); + redrawwin(editWin); + break; + + case ERR: + /* Ignore */ + break; + + default: + if (isprint(c) || c == 0xe4 || c == 0xf6 || c == 0xc4 || c == 0xd6) { + if (insertMode) + insertBuf(editBuf, editBuf->pos, c); + else + writeBuf(editBuf, editBuf->pos, c); + setBufPos(editBuf, editBuf->pos + 1); + update = TRUE; + } else { + printMsg("Unhandled key: %02x\n", c); + } + break; + } + } while (c != ERR && !exitProg && ++cnt < 10); + + if (update) { + /* Update edit line */ + printEditBuf(setPrvMode ? setTarget : "", editBuf); + updateStatus(insertMode); + } + } /* !optDaemon */ + + if (++updateCount > 10) { + 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 */ err_exit: - if (cursesInit) { - if (curVis != ERR) - curs_set(curVis); - endwin(); - THMSG(1, "NCurses deinitialized.\n"); - } - - if (isError) { - THMSG(1, "Error exit.\n"); - } - - th_free(optUserName2); + if (cursesInit) { + if (curVis != ERR) + curs_set(curVis); + endwin(); + THMSG(1, "NCurses deinitialized.\n"); + } + + if (isError) { + THMSG(1, "Error exit.\n"); + } + + th_free(optUserName2); - closeConnection(tmpSocket); - + closeConnection(tmpSocket); + #ifdef __WIN32 - if (networkInit) - WSACleanup(); + if (networkInit) + WSACleanup(); #endif - THMSG(1, "Connection terminated.\n"); - - if (optLogFile) { - THMSG(1, "Closing logfile.\n"); - fclose(optLogFile); - } - - return 0; + THMSG(1, "Connection terminated.\n"); + + if (optLogFile) { + THMSG(1, "Closing logfile.\n"); + fclose(optLogFile); + } + + return 0; }