changeset 62:ff5d74f0d428

Moved some functions to "libnnchat".
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 11 Nov 2008 21:57:51 +0200
parents b802a799c31a
children afd90bbb3af6
files Makefile.gen libnnchat.c libnnchat.h nnchat.c
diffstat 4 files changed, 379 insertions(+), 337 deletions(-) [+]
line wrap: on
line diff
--- 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
 
 #
--- /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[] = {
+	{ '<', "&lt;" },
+	{ '>', "&gt;" },
+};
+
+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),
+		"<USER>%s</USER><MESSAGE>%s</MESSAGE>",
+		user, tmpBuf);
+	
+	return sendToSocket(sock, tmpBuf2, strlen(tmpBuf2) + 1);
+}
+
--- /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 <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <errno.h>
+#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
--- 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 <sys/socket.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <netdb.h>
-
-#include <unistd.h>
+#include "libnnchat.h"
 #include <stdlib.h>
-#include <stdio.h>
 #include "th_args.h"
-#include "th_string.h"
 #include <string.h>
 #include <errno.h>
 #include <time.h>
@@ -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[] = {
-	{ '<', "&lt;" },
-	{ '>', "&gt;" },
-};
-
-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),
-		"<USER>%s</USER><MESSAGE>%s</MESSAGE>",
-		user, tmpBuf);
-	
-	return sendToSocket(sock, tmpBuf2, strlen(tmpBuf2) + 1);
-}
-
-
 int handleUser(int sock, char *str)
 {
 	const char *msg = "</USER><MESSAGE>";
@@ -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;
 	}