changeset 13:86fe5f0d1a85

Cleanups; Added probing connection (requesting some policy crap) to emulate the official client.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 24 Mar 2008 08:02:05 +0000
parents df23968f0c6a
children 6badfa3eb10e
files nnchat.c
diffstat 1 files changed, 78 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/nnchat.c	Sat Mar 22 03:24:04 2008 +0000
+++ b/nnchat.c	Mon Mar 24 08:02:05 2008 +0000
@@ -44,9 +44,6 @@
 	{ 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, 'p', "plaintext",	"Use plaintext logging", OPT_NONE },
-*/
 };
 
 const int optListN = (sizeof(optList) / sizeof(optarg_t));
@@ -484,7 +481,7 @@
 		return -2;
 	} else if (!strncmp(str, "SUCCESS", 7)) {
 		printMsg("Login success.\n");
-		sendUserMsg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor);
+		sendUserMsg(sock, optUserName2, "%%2FRequestUserList");
 		return 0;
 	} else
 		return 1;
@@ -621,12 +618,55 @@
 }
 
 
+int openConnection(struct in_addr *addr, 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(int sock)
+{
+	if (sock >= 0) {
+#ifdef __WIN32
+		closesocket(sock);
+#else
+		close(sock);
+#endif
+	}
+}
+
+
 int main(int argc, char *argv[])
 {
 	int tmpSocket;
 	struct hostent *tmpHost;
-	struct sockaddr_in tmpAddr;
-	BOOL exitProg = FALSE;
+	BOOL exitProg = FALSE, colorSet = FALSE;
+	struct timeval tv;
+	fd_set sockfds;
+	fd_set inputfds;
+	char *tmpStr;
 
 	/* Initialize */
 	th_init("NNChat", "Newbie Nudes chat client", "0.3",
@@ -674,38 +714,38 @@
 	}
 	THMSG(2, "True hostname: %s\n", tmpHost->h_name);
 	
-	tmpAddr.sin_family = AF_INET;
-	tmpAddr.sin_port = htons(optPort);
-	tmpAddr.sin_addr = *((struct in_addr *) tmpHost->h_addr);
-
-	THMSG(1, "Connecting to %s:%d ...\n",
-		inet_ntoa(tmpAddr.sin_addr), optPort);
-
-	if ((tmpSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
-		THERR("Could not open socket: %s\n", strerror(errno));
-		return -2;
+	/* To emulate the official client, we first make a fake connection ... */
+	if ((tmpSocket = openConnection((struct in_addr *) tmpHost->h_addr, optPort)) < 0) {
+		THERR("Fakeprobe connection setup failed!\n");
+		goto err_exit;
 	}
 	
-	THMSG(2, "Using socket %d.\n", tmpSocket);
-	
-	if (connect(tmpSocket, (struct sockaddr *) &tmpAddr, sizeof(tmpAddr)) == -1) {
-		THERR("Could not connect: %s\n", strerror(errno));
-		return -5;
+	tmpStr = "<policy-file-request/>";
+	if (sendToSocket(tmpSocket, tmpStr, strlen(tmpStr) + 1) < 0) {
+		THERR("Failed to send fakeprobe.\n");
+		goto err_exit;
+	} else {
+		ssize_t gotBuf;
+		char tmpBuf[4096];
+		gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0);
+		tmpBuf[gotBuf-1] = 0;
+		THMSG(2, "Probe got: %s\n", tmpBuf);
+		closeConnection(tmpSocket);
 	}
 	
+	/* 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'.\n", optUserName);
 	optUserName2 = encodeStr1(optUserName);
 	
 	sendUserMsg(tmpSocket, optUserName2, "%%2Flogin%%20%%2Dsite%%20NN%%20%%2Dpassword%%20%s", optPassword);
 	
-	struct timeval tv;
-	fd_set sockfds;
-	fd_set inputfds;
-	
-	
 	FD_ZERO(&inputfds);
 	FD_SET(0, &inputfds);
-	
 	FD_ZERO(&sockfds);
 	FD_SET(tmpSocket, &sockfds);
 
@@ -771,26 +811,32 @@
 			}
 		}
 		
+		if (!colorSet) {
+			colorSet = TRUE;
+			sendUserMsg(tmpSocket, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor);
+		}
+		
 		fflush(stdout);
 		fflush(stderr);
 	}
 	
-	/* .. */
+	/* Shotdiwn */
+err_exit:
 	th_free(optUserName2);
 
+	closeConnection(tmpSocket);
+	
 #ifdef __WIN32
-	closesocket(tmpSocket);
 	WSACleanup();
-#else
-	close(tmpSocket);
 #endif
+
+	THMSG(1, "Connection terminated.\n");
 	
 	if (optLogFile) {
 		THMSG(1, "Closing logfile.\n");
 		fclose(optLogFile);
 	}
 	
-	THMSG(1, "Connection terminated.\n");
 	
 	return 0;
 }