# HG changeset patch # User Matti Hamalainen # Date 1226433471 -7200 # Node ID ff5d74f0d428026188050f7cde806daa0297aad1 # Parent b802a799c31ad4485e5b4157af5ae24bbc86e567 Moved some functions to "libnnchat". diff -r b802a799c31a -r ff5d74f0d428 Makefile.gen --- a/Makefile.gen Tue Nov 11 21:33:41 2008 +0200 +++ b/Makefile.gen Tue Nov 11 21:57:51 2008 +0200 @@ -17,7 +17,7 @@ %.o: %.c %.h $(COMP) -c -o $@ $< -$(NNCHAT_BIN): nnchat.c th_util.o th_string.o th_args.o +$(NNCHAT_BIN): nnchat.c libnnchat.o th_util.o th_string.o th_args.o $(COMP) -o $@ $+ $(LDFLAGS) -lcurses # diff -r b802a799c31a -r ff5d74f0d428 libnnchat.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libnnchat.c Tue Nov 11 21:57:51 2008 +0200 @@ -0,0 +1,334 @@ +/* + * NNChat - Custom chat client for NewbieNudes.com chatrooms + * Written by Matti 'ccr' Hämäläinen + * (C) Copyright 2008 Tecnic Software productions (TNSP) + */ +#include "libnnchat.h" + + +typedef struct { + char c; + char *ent; +} html_entity_t; + + +html_entity_t HTMLEntities[] = { + { '<', "<" }, + { '>', ">" }, +}; + +const int numHTMLEntities = (sizeof(HTMLEntities) / sizeof(HTMLEntities[0])); + + +int openConnection(struct in_addr *addr, const int port) +{ + struct sockaddr_in tmpAddr; + int sock = -1; + + tmpAddr.sin_family = AF_INET; + tmpAddr.sin_port = htons(port); + tmpAddr.sin_addr = *addr; + + THMSG(1, "Connecting to %s:%d ...\n", + inet_ntoa(tmpAddr.sin_addr), port); + + if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + THERR("Could not open socket: %s\n", strerror(errno)); + return -2; + } + + THMSG(2, "Using socket %d.\n", sock); + + if (connect(sock, (struct sockaddr *) &tmpAddr, sizeof(tmpAddr)) == -1) { + THERR("Could not connect: %s\n", strerror(errno)); + return -5; + } + + return sock; +} + + +void closeConnection(const int sock) +{ + if (sock >= 0) { + close(sock); + } +} + + +BOOL sendToSocket(const int sock, char *buf, const size_t bufLen) +{ + size_t bufLeft = bufLen; + char *bufPtr = buf; + + while (bufLeft > 0) { + ssize_t bufSent; + bufSent = send(sock, bufPtr, bufLeft, 0); + if (bufSent < 0) return FALSE; + bufLeft -= bufSent; + bufPtr += bufSent; + } + return TRUE; +} + + +BOOL bufRealloc(char **buf, size_t *size, size_t add) +{ + return ((*buf = th_realloc(*buf, *size + add)) != NULL); +} + +#define PUSHCHAR(x) bufPushChar(&result, &resSize, &resPos, x) +BOOL bufPushChar(char **buf, size_t *size, size_t *pos, char ch) +{ + if (*pos >= *size && !bufRealloc(buf, size, SET_ALLOC_SIZE)) + return FALSE; + + (*buf)[*pos] = ch; + (*pos)++; + return TRUE; +} + +#define PUSHSTR(x) bufPushStr(&result, &resSize, &resPos, x) +BOOL bufPushStr(char **buf, size_t *size, size_t *pos, char *str) +{ + size_t tmpLen; + + if (!str) return FALSE; + tmpLen = strlen(str); + + if ((*pos + tmpLen) >= *size && !bufRealloc(buf, size, tmpLen + SET_ALLOC_SIZE)) + return FALSE; + + strcpy(*buf + *pos, str); + (*pos) += tmpLen; + return TRUE; +} + + +char *encodeStr1(const char *str) +{ + const char *s = str; + char *result; + size_t resSize, resPos = 0; + + if (!str) return NULL; + + resSize = strlen(str) + SET_ALLOC_SIZE; + if ((result = th_malloc(resSize)) == NULL) + return NULL; + + while (*s) { + switch (*s) { + case 32: + PUSHCHAR('+'); + break; + + default: + if (th_isalnum(*s)) + PUSHCHAR(*s); + else { + char tmpStr[4]; + sprintf(tmpStr, "%2X", (unsigned char) *s); + PUSHCHAR('%'); + PUSHSTR(tmpStr); + } + break; + } + s++; + } + PUSHCHAR(0); + + return result; +} + + +static int getHexDigit(const int c, const int shift) +{ + int i; + + if (c >= 'A' && c <= 'F') + i = c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + i = c - 'a' + 10; + else if (c >= '0' && c <= '9') + i = c - '0'; + else + return -1; + + return i << shift; +} + + +char *decodeStr1(const char *str) +{ + const char *s = str; + char *result; + size_t resSize, resPos = 0; + int c; + + if (!str) return NULL; + + resSize = strlen(str) + SET_ALLOC_SIZE; + if ((result = th_malloc(resSize)) == NULL) + return NULL; + + while (*s) { + switch (*s) { + case '+': + PUSHCHAR(' '); + s++; + break; + + case '½': + /* Escape these .. */ + PUSHCHAR('½'); + PUSHCHAR('½'); + s++; + break; + + case '\r': + PUSHCHAR(' '); + s++; + break; + + case '%': + s++; + if (*s == '%') + PUSHCHAR('%'); + else if ((c = getHexDigit(*s, 4)) >= 0) { + int i = getHexDigit(*(++s), 0); + if (i >= 0) { + PUSHCHAR(c | i); + } else { + PUSHCHAR('§'); + PUSHCHAR(*s); + } + } else { + PUSHCHAR('§'); + PUSHCHAR(*s); + } + s++; + break; + + default: + PUSHCHAR(*s); + s++; + } + } + PUSHCHAR(0); + + return result; +} + + +char *stripXMLTags(const char *str) +{ + const char *s = str; + char *result; + size_t resSize, resPos = 0; + + if (!str) return NULL; + + resSize = strlen(str) + SET_ALLOC_SIZE; + if ((result = th_malloc(resSize)) == NULL) + return NULL; + + while (*s) { + if (*s == '<') { + while (*s && *s != '>') s++; + if (*s == '>') s++; + } else + PUSHCHAR(*s++); + } + PUSHCHAR(0); + + return result; +} + + +char *encodeStr2(const char *str) +{ + const char *s = str; + char *result; + size_t resSize, resPos = 0; + + if (!str) return NULL; + + resSize = strlen(str) + SET_ALLOC_SIZE; + if ((result = th_malloc(resSize)) == NULL) + return NULL; + + while (*s) { + int i; + BOOL found = FALSE; + for (i = 0; i < numHTMLEntities; i++) + if (HTMLEntities[i].c == *s) { + PUSHSTR(HTMLEntities[i].ent); + found = TRUE; + break; + } + if (!found) PUSHCHAR(*s); + + s++; + } + PUSHCHAR(0); + + return result; +} + + +char *decodeStr2(const char *str) +{ + const char *s = str; + char *result; + size_t resSize, resPos = 0; + + if (!str) return NULL; + + resSize = strlen(str); + if ((result = th_malloc(resSize)) == NULL) + return NULL; + + while (*s) { + if (*s == '&') { + int i; + BOOL found = FALSE; + for (i = 0; i < numHTMLEntities; i++) { + html_entity_t *ent = &HTMLEntities[i]; + int len = strlen(ent->ent); + if (!strncmp(s, ent->ent, len)) { + PUSHCHAR(ent->c); + s += len; + found = TRUE; + break; + } + } + if (!found) PUSHCHAR(*s++); + } else + PUSHCHAR(*s++); + } + PUSHCHAR(0); + + return result; +} + + +BOOL sendUserMsg(const int sock, const char *user, const char *fmt, ...) +{ + char tmpBuf[SET_BUFSIZE], tmpBuf2[SET_BUFSIZE + 256]; + int n; + va_list ap; + + va_start(ap, fmt); + n = vsnprintf(tmpBuf, sizeof(tmpBuf), fmt, ap); + va_end(ap); + + if (n < 0) return FALSE; + + snprintf(tmpBuf2, sizeof(tmpBuf2), + "%s%s", + user, tmpBuf); + + return sendToSocket(sock, tmpBuf2, strlen(tmpBuf2) + 1); +} + diff -r b802a799c31a -r ff5d74f0d428 libnnchat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libnnchat.h Tue Nov 11 21:57:51 2008 +0200 @@ -0,0 +1,35 @@ +/* + * NNChat - Custom chat client for NewbieNudes.com chatrooms + * Written by Matti 'ccr' Hämäläinen + * (C) Copyright 2008 Tecnic Software productions (TNSP) + */ +#ifndef LIBNNCHAT_H +#define LIBNNCHAT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "th_string.h" + +#define SET_BUFSIZE (4096) +#define SET_ALLOC_SIZE (128) + +int openConnection(struct in_addr *addr, const int port); +void closeConnection(const int sock); +BOOL sendToSocket(const int sock, char *buf, const size_t bufLen); +BOOL sendUserMsg(const int sock, const char *user, const char *fmt, ...); + + +char *encodeStr1(const char *str); +char *decodeStr1(const char *str); +char *encodeStr2(const char *str); +char *decodeStr2(const char *str); +char *stripXMLTags(const char *str); + + +#endif diff -r b802a799c31a -r ff5d74f0d428 nnchat.c --- a/nnchat.c Tue Nov 11 21:33:41 2008 +0200 +++ b/nnchat.c Tue Nov 11 21:57:51 2008 +0200 @@ -3,17 +3,9 @@ * Written by Matti 'ccr' Hämäläinen * (C) Copyright 2008 Tecnic Software productions (TNSP) */ -#include -#include -#include -#include -#include - -#include +#include "libnnchat.h" #include -#include #include "th_args.h" -#include "th_string.h" #include #include #include @@ -22,26 +14,10 @@ #define SET_MAX_BACKBUF (1024) #define SET_MAX_HISTORY (16) -#define SET_BUFSIZE (4096) -#define SET_ALLOC_SIZE (128) #define SET_DELAY (15) #define SET_DELAY_USEC (SET_DELAY * 1000) -typedef struct { - char c; - char *ent; -} html_entity_t; - - -html_entity_t HTMLEntities[] = { - { '<', "<" }, - { '>', ">" }, -}; - -const int numHTMLEntities = (sizeof(HTMLEntities) / sizeof(HTMLEntities[0])); - - /* Options */ int optPort = 8005; @@ -384,57 +360,6 @@ wrefresh(editWin); } -int openConnection(struct in_addr *addr, const int port) -{ - struct sockaddr_in tmpAddr; - int sock = -1; - - tmpAddr.sin_family = AF_INET; - tmpAddr.sin_port = htons(port); - tmpAddr.sin_addr = *addr; - - THMSG(1, "Connecting to %s:%d ...\n", - inet_ntoa(tmpAddr.sin_addr), port); - - if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { - THERR("Could not open socket: %s\n", strerror(errno)); - return -2; - } - - THMSG(2, "Using socket %d.\n", sock); - - if (connect(sock, (struct sockaddr *) &tmpAddr, sizeof(tmpAddr)) == -1) { - THERR("Could not connect: %s\n", strerror(errno)); - return -5; - } - - return sock; -} - - -void closeConnection(const int sock) -{ - if (sock >= 0) { - close(sock); - } -} - - -BOOL sendToSocket(const int sock, char *buf, const size_t bufLen) -{ - size_t bufLeft = bufLen; - char *bufPtr = buf; - - while (bufLeft > 0) { - ssize_t bufSent; - bufSent = send(sock, bufPtr, bufLeft, 0); - if (bufSent < 0) return FALSE; - bufLeft -= bufSent; - bufPtr += bufSent; - } - return TRUE; -} - int printWin(WINDOW *win, const char *fmt) { const char *s = fmt; @@ -470,6 +395,7 @@ return 0; } + int printFile(FILE *outFile, const char *fmt) { const char *s = fmt; @@ -494,6 +420,7 @@ return 0; } + void printMsg(char *fmt, ...) { char tmpStr[128] = "", buf[8192]; @@ -524,262 +451,6 @@ } -BOOL bufRealloc(char **buf, size_t *size, size_t add) -{ - return ((*buf = th_realloc(*buf, *size + add)) != NULL); -} - -#define PUSHCHAR(x) bufPushChar(&result, &resSize, &resPos, x) -BOOL bufPushChar(char **buf, size_t *size, size_t *pos, char ch) -{ - if (*pos >= *size && !bufRealloc(buf, size, SET_ALLOC_SIZE)) - return FALSE; - - (*buf)[*pos] = ch; - (*pos)++; - return TRUE; -} - -#define PUSHSTR(x) bufPushStr(&result, &resSize, &resPos, x) -BOOL bufPushStr(char **buf, size_t *size, size_t *pos, char *str) -{ - size_t tmpLen; - - if (!str) return FALSE; - tmpLen = strlen(str); - - if ((*pos + tmpLen) >= *size && !bufRealloc(buf, size, tmpLen + SET_ALLOC_SIZE)) - return FALSE; - - strcpy(*buf + *pos, str); - (*pos) += tmpLen; - return TRUE; -} - - -char *encodeStr1(char *str) -{ - char *result, *s = str; - size_t resSize, resPos = 0; - - if (!str) return NULL; - - resSize = strlen(str) + SET_ALLOC_SIZE; - if ((result = th_malloc(resSize)) == NULL) - return NULL; - - while (*s) { - switch (*s) { - case 32: - PUSHCHAR('+'); - break; - - default: - if (th_isalnum(*s)) - PUSHCHAR(*s); - else { - char tmpStr[4]; - sprintf(tmpStr, "%2X", (unsigned char) *s); - PUSHCHAR('%'); - PUSHSTR(tmpStr); - } - break; - } - s++; - } - PUSHCHAR(0); - - return result; -} - - -int getxdigit(int c, int shift) -{ - int i; - - if (c >= 'A' && c <= 'F') - i = c - 'A' + 10; - else if (c >= 'a' && c <= 'f') - i = c - 'a' + 10; - else if (c >= '0' && c <= '9') - i = c - '0'; - else - return -1; - - return i << shift; -} - - -char *decodeStr1(char *str) -{ - char *result, *s = str; - size_t resSize, resPos = 0; - int c; - - if (!str) return NULL; - - resSize = strlen(str) + SET_ALLOC_SIZE; - if ((result = th_malloc(resSize)) == NULL) - return NULL; - - while (*s) { - switch (*s) { - case '+': - PUSHCHAR(' '); - s++; - break; - - case '½': - /* Escape these .. */ - PUSHCHAR('½'); - PUSHCHAR('½'); - s++; - break; - - case '\r': - PUSHCHAR(' '); - s++; - break; - - case '%': - s++; - if (*s == '%') - PUSHCHAR('%'); - else if ((c = getxdigit(*s, 4)) >= 0) { - int i = getxdigit(*(++s), 0); - if (i >= 0) { - PUSHCHAR(c | i); - } else { - PUSHCHAR('§'); - PUSHCHAR(*s); - } - } else { - PUSHCHAR('§'); - PUSHCHAR(*s); - } - s++; - break; - - default: - PUSHCHAR(*s); - s++; - } - } - PUSHCHAR(0); - - return result; -} - - -char *stripTags(char *str) -{ - char *result, *s = str; - size_t resSize, resPos = 0; - - if (!str) return NULL; - - resSize = strlen(str) + SET_ALLOC_SIZE; - if ((result = th_malloc(resSize)) == NULL) - return NULL; - - while (*s) { - if (*s == '<') { - while (*s && *s != '>') s++; - if (*s == '>') s++; - } else - PUSHCHAR(*s++); - } - PUSHCHAR(0); - - return result; -} - - -char *encodeStr2(char *str) -{ - char *result, *s = str; - size_t resSize, resPos = 0; - - if (!str) return NULL; - - resSize = strlen(str) + SET_ALLOC_SIZE; - if ((result = th_malloc(resSize)) == NULL) - return NULL; - - while (*s) { - int i; - BOOL found = FALSE; - for (i = 0; i < numHTMLEntities; i++) - if (HTMLEntities[i].c == *s) { - PUSHSTR(HTMLEntities[i].ent); - found = TRUE; - break; - } - if (!found) PUSHCHAR(*s); - - s++; - } - PUSHCHAR(0); - - return result; -} - - -char *decodeStr2(char *str) -{ - char *result, *s = str; - size_t resSize, resPos = 0; - - if (!str) return NULL; - - resSize = strlen(str); - if ((result = th_malloc(resSize)) == NULL) - return NULL; - - while (*s) { - if (*s == '&') { - int i; - BOOL found = FALSE; - for (i = 0; i < numHTMLEntities; i++) { - html_entity_t *ent = &HTMLEntities[i]; - int len = strlen(ent->ent); - if (!strncmp(s, ent->ent, len)) { - PUSHCHAR(ent->c); - s += len; - found = TRUE; - break; - } - } - if (!found) PUSHCHAR(*s++); - } else - PUSHCHAR(*s++); - } - PUSHCHAR(0); - - return result; -} - - -BOOL sendUserMsg(int sock, char *user, char *fmt, ...) -{ - char tmpBuf[4096], tmpBuf2[4096+256]; - int n; - va_list ap; - - va_start(ap, fmt); - n = vsnprintf(tmpBuf, sizeof(tmpBuf), fmt, ap); - va_end(ap); - - if (n < 0) return FALSE; - - snprintf(tmpBuf2, sizeof(tmpBuf2), - "%s%s", - user, tmpBuf); - - return sendToSocket(sock, tmpBuf2, strlen(tmpBuf2) + 1); -} - - int handleUser(int sock, char *str) { const char *msg = ""; @@ -807,7 +478,7 @@ if (*s == '/') { - t = stripTags(s + 1); + t = stripXMLTags(s + 1); if (!strncmp(t, "BPRV", 4)) { h = decodeStr2(t + 1); printMsg("½11½%s½0½\n", h); @@ -818,7 +489,7 @@ th_free(h); th_free(t); } else { - t = stripTags(s); + t = stripXMLTags(s); h = decodeStr2(t); printMsg("½5½<½%d½%s½5½>½0½ %s\n", strcmp(p, optUserName) ? 15 : 14, p, h); th_free(h); @@ -1090,9 +761,11 @@ THMSG(2, "True hostname: %s\n", tmpHost->h_name); #if 0 - /* To emulate the official client, we first make a fake connection ... */ + /* 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("Fakeprobe connection setup failed!\n"); + THERR("Policy file request connection setup failed!\n"); goto err_exit; }