changeset 1099:4416ead31db7

[gaim-migrate @ 1109] updated hacking to reflect mid's changes, and applied mid's libyahoo patch committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Thu, 16 Nov 2000 07:35:58 +0000
parents b335c0ce305e
children f168625b63fe
files HACKING plugins/yay/libyahoo.c
diffstat 2 files changed, 325 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- a/HACKING	Thu Nov 16 07:30:15 2000 +0000
+++ b/HACKING	Thu Nov 16 07:35:58 2000 +0000
@@ -35,7 +35,7 @@
 of the information that's printed is useless anyway though; so the
 --enable-debug option really doesn't do a whole lot.
 
-This file was last modified by $Author: warmenhoven $ on $Date: 2000-11-03 22:08:54 -0500 (Fri, 03 Nov 2000) $.
+This file was last modified by $Author: warmenhoven $ on $Date: 2000-11-16 02:35:58 -0500 (Thu, 16 Nov 2000) $.
 
 
 PROGRAM FLOW
@@ -184,12 +184,6 @@
   reference to this function (there are only two - one in aim.c and one
   in buddy.c). Or you could just run ./configure --disable-multi.
 
-network.c:
-  This has two functions: get_address and connect_address, both of which
-  call proxy functions. If you want to see how these are used, look at
-  toc.c and/or rvous.c. These are really just front-ends to the proxy
-  stuff; use these instead of calling the proxy functions.
-
 oscar.c:
   One big hack of copied code. This is supposed to be the libfaim tie-in
   in gaim. Most of it is just copied straight from faimtest, the small
@@ -226,9 +220,11 @@
   all of the protocols. It's a pretty simple file actually.
 
 proxy.c:
-  This is where the bulk of the actual networking code is done. The big
-  function here is proxy_connect, which will connect through the proxy
-  setup you've chosen (most of which don't work...) or just regularly.
+  Adam (of libfaim glory) got bored one day and rewrote this file, so now
+  everything actually works. The main function is proxy_connect, which
+  figures out which proxy you want to use (if you want to use one at all)
+  and passes off the data to the appropriate function. This file should be
+  pretty straight-forward.
 
 rvous.c:
   This was originally going to be the stuff for all of the Buddy Icon
--- a/plugins/yay/libyahoo.c	Thu Nov 16 07:30:15 2000 +0000
+++ b/plugins/yay/libyahoo.c	Thu Nov 16 07:35:58 2000 +0000
@@ -190,6 +190,50 @@
 	{0, NULL}
 };
 
+static int readall(int fd, void *buf, size_t count)
+{
+  int left, ret, cur = 0;
+
+  left = count;
+
+  while (left) {
+    ret = read(fd, ((unsigned char *)buf)+cur, left);
+    if ((ret == -1) && (errno != EINTR)) {
+      return -1;
+    }
+    if (ret == 0)
+      return cur;
+
+    if (ret != -1) {
+      cur += ret;
+      left -= ret;
+    }
+  }
+  return cur;
+}
+
+static int writeall(int fd, void *buf, size_t count)
+{
+  int left, ret, cur = 0;
+
+  left = count;
+
+  while (left) {
+    ret = write(fd, ((unsigned char *)buf)+cur, left);
+    if ((ret == -1) && (errno != EINTR)) {
+      return -1;
+    }
+    if (ret == 0)
+      return cur;
+    if (ret != -1) {
+      cur += ret;
+      left -= ret;
+    }
+  }
+
+  return cur;
+}
+
 /* Take a 4-byte character string in little-endian format and return
    a unsigned integer */
 unsigned int yahoo_makeint(unsigned char *data)
@@ -208,14 +252,14 @@
 	unsigned int tmp = val;
 	int i;
 
-	if (data)
-	{
-		for (i = 0; i < 4; i++)
-		{
-			data[i] = tmp % 256;
-			tmp >>= 8;
-		}
-	}
+	if (!data)
+                return;
+
+	for (i = 0; i < 4; i++)
+        {
+                data[i] = tmp % 256;
+                tmp >>= 8;
+        }
 }
 
 /*
@@ -242,8 +286,8 @@
 	if (0 == buff)
 		return 0;
 
-	buffer = strdup(buff);		/* play with a copy */
-	ptr_buffer = buffer;
+	if (!(ptr_buffer = buffer = strdup(buff)))      /* play with a copy */
+                return NULL;
 
 	/* count the number of users (commas + 1) */
 	for (i = 0; i < strlen(buffer); i++)
@@ -264,14 +308,21 @@
 
 	/* allocate the array to hold the list of buddys */
 	/* null terminated array of pointers */
-	tmp_array = (char **) malloc(sizeof(char *) * (cnt + 1));
+	if (!(tmp_array = (char **) malloc(sizeof(char *) * (cnt + 1)))) {
+                FREE(buffer);
+                return NULL;
+        }
 
 	memset(tmp_array, 0, (sizeof(char *) * (cnt + 1)));
 
 	/* Parse through the list and get all the entries */
 	while ((ptr_buffer[sublen] != ',') && (ptr_buffer[sublen] != '\0'))
 		sublen++;
-	tmp = (char *) malloc(sizeof(char) * (sublen + 1));
+	if (!(tmp = (char *) malloc(sizeof(char) * (sublen + 1)))) {
+                FREE(buffer);
+                FREE(tmp_array);
+                return NULL;
+        }
 
 	memcpy(tmp, ptr_buffer, sublen);
 	tmp[sublen] = '\0';
@@ -297,7 +348,11 @@
 
 		while ((ptr_buffer[sublen] != ',') && (ptr_buffer[sublen] != '\0'))
 			sublen++;
-		tmp = (char *) malloc(sizeof(char) * (sublen + 1));
+		if (!(tmp = (char *) malloc(sizeof(char) * (sublen + 1)))) {
+                        FREE(buffer);
+                        FREE(tmp_array);
+                        return NULL;
+                }
 
 		memcpy(tmp, ptr_buffer, sublen);
 		tmp[sublen] = '\0';
@@ -329,10 +384,10 @@
 
 	while (array[nxtelem] != NULL)
 	{
-		free(array[nxtelem++]);
+		FREE(array[nxtelem++]);
 	}
 
-	free(array);
+	FREE(array);
 }								/* yahoo_arraykill() */
 
 /*
@@ -361,7 +416,8 @@
 	/* allocate at least one - for NULL list - and to
 	   allow my strcat to write past the end for the
 	   last comma which gets converted to NULL */
-	list = (char *) malloc(sizeof(char) * (arraylength + 1));
+	if (!(list = (char *) malloc(sizeof(char) * (arraylength + 1))))
+                return NULL;
 
 	memset(list, 0, (arraylength + 1));
 
@@ -446,7 +502,10 @@
 
 	/* Copy the packet so we can don't duplicate it next time. */
 	last_datalen = datalen;
-	last_data = (unsigned char *) malloc(datalen);
+	if (!(last_data = (unsigned char *) malloc(datalen))) {
+                FREE(last_data);
+                return;
+        }
 	memcpy(last_data, data, datalen);
 
 	/* Handle printing the full entry out */
@@ -537,23 +596,26 @@
 	{
 		yahoo_dbg_Print("libyahoo",
 			"[libyahoo] yahoo_socket_connect - nulls\n");
-		return 0;
+		return -1;
 	}
 
-	server = gethostbyname(host);
-	if (!server)
+	if (!(server = gethostbyname(host)))
 	{
-		printf("[libyahoo] failed to look up server (%s:%d)\n", host, port);
-		return (0);
+		printf("[libyahoo] failed to look up server (%s:%d): %s\n", host, port, hstrerror(h_errno));
+		return -1;
 	}
 
-	servfd = socket(AF_INET, SOCK_STREAM, 0);
-
-	bzero(&serv_addr, sizeof(serv_addr));
+	if ((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+        {
+                return -1;
+        }
+
+	memset(&serv_addr, 0, sizeof(serv_addr));
 	serv_addr.sin_family = AF_INET;
-	bcopy(server->h_addr, &serv_addr.sin_addr.s_addr, server->h_length);
+	memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
 	serv_addr.sin_port = htons(port);
 
+        /* XXX should put timeouts on the connect()'s -mid */
 	res = -1;
 	if (ctx->connect_mode == YAHOO_CONNECT_SOCKS4)
 	{
@@ -580,16 +642,16 @@
 	{
 		printf("[libyahoo] unhandled connect mode (%d).\n",
 			ctx->connect_mode);
-		return (0);
+                close(servfd);
+		return -1;
 	}
 
 	if (res < 0)
 	{
+		printf("[libyahoo] failed to connect to server (%s:%d): %s\n",
+                       host, port, strerror(errno));
 		close(servfd);
-		servfd = 0;
-		printf("[libyahoo] failed to connect to server (%s:%d)\n", host,
-			port);
-		return (0);
+		return -1;
 	}
 
 	yahoo_dbg_Print("libyahoo",
@@ -607,16 +669,16 @@
 
 	len = 3 * strlen(data) + 1;
 
-	FREE(tmp);
+        if (tmp)
+                FREE(tmp);
 
 	if (!data)
-	{
 		return NULL;
-	}
 
 	/* change this at some point to re-use the buffer, no sense
 	   allocating repeatedly */
-	tmp = (char *) malloc(len);
+	if (!(tmp = (char *) malloc(len)))
+                return NULL;
 	tmp[0] = 0;
 
 	for (i = 0; i < strlen(data); i++)
@@ -638,7 +700,7 @@
 	return tmp;
 }
 
-static void yahoo_addtobuffer(struct yahoo_context *ctx, char *data,
+static int yahoo_addtobuffer(struct yahoo_context *ctx, char *data,
 	int datalen)
 {
 	//yahoo_hexdump("yahoo_addtobuffer", data, datalen);
@@ -657,7 +719,8 @@
 		{
 			ctx->io_buf_maxlen += datalen;
 		}
-		new_io_buf = (char *) malloc(ctx->io_buf_maxlen);
+		if (!(new_io_buf = (char *) malloc(ctx->io_buf_maxlen)))
+                        return 0;
 
 		if (ctx->io_buf)
 		{
@@ -670,6 +733,8 @@
 
 	memcpy(ctx->io_buf + ctx->io_buf_curlen, data, datalen);
 	ctx->io_buf_curlen += datalen;
+
+        return 1;
 }
 
 static int yahoo_tcp_readline(char *ptr, int maxlen, int fd)
@@ -681,7 +746,7 @@
 	{
 	  again:
 
-		if ((rc = read(fd, &c, 1)) == 1)
+		if ((rc = readall(fd, &c, 1)) == 1)
 		{
 			*ptr++ = c;
 			if (c == '\n')
@@ -699,8 +764,8 @@
 			if (errno == EINTR)
 				goto again;
 			printf
-				("Yahoo: Error reading from socket in yahoo_tcp_readline.\n");
-			exit(1);
+				("Yahoo: Error reading from socket in yahoo_tcp_readline: %s.\n", strerror(errno));
+			return -1;
 		}
 	}
 
@@ -725,14 +790,24 @@
 	}
 
 	/* Allocate a new context */
-	tmp = (struct yahoo_context *) calloc(1, sizeof(*tmp));
+	if (!(tmp = (struct yahoo_context *) calloc(1, sizeof(*tmp))))
+                return NULL;
 
 	/* Fill in any available info */
-	tmp->user = strdup(user);
-	tmp->password = strdup(password);
+	if (!(tmp->user = strdup(user))) {
+                yahoo_free_context(tmp);
+                return NULL;
+        }
+	if (!(tmp->password = strdup(password))) {
+                yahoo_free_context(tmp);
+                return NULL;
+        }
 	if (options->proxy_host)
 	{
-		tmp->proxy_host = strdup(options->proxy_host);
+		if (!(tmp->proxy_host = strdup(options->proxy_host))) {
+                        yahoo_free_context(tmp);
+                        return NULL;
+                }
 	}
 	tmp->proxy_port = options->proxy_port;
 	tmp->connect_mode = options->connect_mode;
@@ -861,10 +936,10 @@
 	{
 		servfd = yahoo_socket_connect(ctx, YAHOO_AUTH_HOST, YAHOO_AUTH_PORT);
 	}
-	if (!servfd)
+	if (servfd < 0)
 	{
 		printf("[libyahoo] failed to connect to pager auth server.\n");
-		return (0);
+		return 0;
 	}
 
 	strcpy(buffer, "GET ");
@@ -888,7 +963,11 @@
 	strcat(buffer, "Host: " YAHOO_AUTH_HOST "\r\n");
 	strcat(buffer, "\r\n");
 
-	write(servfd, buffer, strlen(buffer));
+	if (writeall(servfd, buffer, strlen(buffer)) < strlen(buffer)) 
+        {
+                close(servfd);
+                return 0;
+        }
 
 	yahoo_dbg_Print("libyahoo",
 		"[libyahoo] yahoo_fetchcookies: writing buffer '%s'\n", buffer);
@@ -986,7 +1065,7 @@
 			"[libyahoo] yahoo_add_buddy - connecting\n");
 		servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT);
 	}
-	if (!servfd)
+	if (servfd < 0)
 	{
 		yahoo_dbg_Print("libyahoo",
 			"[libyahoo] yahoo_add_buddy: failed to connect\n");
@@ -1017,7 +1096,12 @@
 	strcat(buffer, "\r\n");
 	strcat(buffer, "\r\n");
 
-	write(servfd, buffer, strlen(buffer));
+	if (writeall(servfd, buffer, strlen(buffer)) < strlen(buffer))
+        {
+                close(servfd);
+                return 0;
+        }
+
 	while (yahoo_tcp_readline(buffer, 5000, servfd) > 0)
 	{
 		/* just dump the output, I don't care about errors at the moment */
@@ -1027,7 +1111,7 @@
 
 	/* indicate success for now with 0 */
 	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_add_buddy: finished\n");
-	return 0;
+	return 1;
 }
 
 /* Remove a buddy from your buddy list */
@@ -1053,7 +1137,7 @@
 		yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_add_buddy - connecting\n");
 		servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT);
 	}
-	if (!servfd)
+	if (servfd < 0)
 	{
 		yahoo_dbg_Print("libyahoo",
 			"[libyahoo] yahoo_add_buddy: failed to connect\n");
@@ -1084,7 +1168,12 @@
 	strcat(buffer, "\r\n");
 	strcat(buffer, "\r\n");
 
-	write(servfd, buffer, strlen(buffer));
+	if (writeall(servfd, buffer, strlen(buffer)) < strlen(buffer))
+        {
+                close(servfd);
+                return 0;
+        }
+
 	while (yahoo_tcp_readline(buffer, 5000, servfd) > 0)
 	{
 		/* just dump the output, I don't care about errors at the moment */
@@ -1092,8 +1181,8 @@
 	close(servfd);
 	servfd = 0;
 
-	/* indicate success for now with 0 */
-	return 0;
+	/* indicate success for now with 1 */
+	return 1;
 }
 
 /* Retrieve the configuration from the server */
@@ -1124,7 +1213,7 @@
 	{
 		servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT);
 	}
-	if (!servfd)
+	if (servfd < 0)
 	{
 		yahoo_dbg_Print("libyahoo",
 			"[libyahoo] yahoo_get_config: failed to connect\n");
@@ -1142,7 +1231,12 @@
 	strcat(buffer, "\r\n");
 	strcat(buffer, "\r\n");
 
-	write(servfd, buffer, strlen(buffer));
+	if (writeall(servfd, buffer, strlen(buffer)) < strlen(buffer))
+        {
+                close(servfd);
+                return 0;
+        }
+
 	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config: sending '%s'\n",
 		buffer);
 
@@ -1328,7 +1422,7 @@
 		yahoo_dbg_Print("libyahoo",
 			"[libyahoo] yahoo_cmd_logon: logon called without "
 			"context and/or cookie.\n");
-		exit(1);
+                return 0;
 	}
 
 	strcpy(login_string, ctx->login_cookie);
@@ -1356,8 +1450,9 @@
 		}
 	}
 
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGON, ctx->user, login_string,
-		initial_status);
+	if(!yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGON, ctx->user, login_string,
+                          initial_status))
+                return 0;
 
 	/* something that the windows one sends, not sure what it is */
 #if 0
@@ -1369,7 +1464,7 @@
 		0);
 #endif
 
-	return 0;
+	return 1;
 }
 
 int yahoo_connect(struct yahoo_context *ctx)
@@ -1390,7 +1485,7 @@
 				"[libyahoo] yahoo_connect - establishing socket connection\n");
 			ctx->sockfd =
 				yahoo_socket_connect(ctx, YAHOO_PAGER_HOST, YAHOO_PAGER_PORT);
-			if (!ctx->sockfd)
+			if (ctx->sockfd < 0)
 			{
 				printf("[libyahoo] couldn't connect to pager host\n");
 				return (0);
@@ -1440,7 +1535,7 @@
 		sockfd = yahoo_socket_connect(ctx, YAHOO_PAGER_HTTP_HOST,
 			YAHOO_PAGER_HTTP_PORT);
 	}
-	if (!sockfd)
+	if (sockfd < 0)
 	{
 		printf("[libyahoo] failed to connect to pager http server.\n");
 		return (0);
@@ -1465,28 +1560,35 @@
 	strcat(buffer, "\r\n");
 	strcat(buffer, "\r\n");
 
-	write(sockfd, buffer, strlen(buffer));
-	write(sockfd, pkt, size);
-	write(sockfd, "\r\n", 2);
+	if ((writeall(sockfd, buffer, strlen(buffer)) < strlen(buffer)) ||
+            (writeall(sockfd, pkt, size) < size) ||
+            (writeall(sockfd, "\r\n", 2) < 2))
+        {
+                close(sockfd);
+                return 0;
+        }
 
 	/* now we need to read the results */
 	/* I'm taking the cheat approach and just dumping them onto the
 	   buffer, headers and all, the _skip_to_YHOO_ code will handle it
 	   for now */
 
-	while ((res = read(sockfd, buffer, 5000)) > 0)
+	while ((res = readall(sockfd, buffer, sizeof(buffer))) > 0)
 	{
 		if (res == -1)
 		{
 			printf("[libyahoo] Error reading data from server.\n");
-			exit(1);
+                        return 0;
 		}
-		yahoo_addtobuffer(ctx, buffer, res);
+		if (!yahoo_addtobuffer(ctx, buffer, res))
+                {
+                        close(sockfd);
+                        return 0;
+                }
 	}
 	close(sockfd);
-	sockfd = 0;
-
-	return (0);
+
+	return (1);
 }
 
 /* Send a packet to the server, called by all routines that want to issue
@@ -1501,7 +1603,8 @@
 	/* why the )&*@#$( did they hardwire the packet size that gets sent
 	   when the size of the packet is included in what is sent, bizarre */
 	size = 4 * 256 + YAHOO_PACKET_HEADER_SIZE;
-	pkt = (struct yahoo_rawpacket *) calloc(1, size);
+	if (!(pkt = (struct yahoo_rawpacket *) calloc(1, size)))
+                return 0;
 
 	/* figure out max content length, including trailing null */
 	maxcontentsize = size - sizeof(struct yahoo_rawpacket);
@@ -1527,28 +1630,37 @@
 		case YAHOO_CONNECT_SOCKS4:
 		case YAHOO_CONNECT_SOCKS5:
 		case YAHOO_CONNECT_NORMAL:
-			write(ctx->sockfd, pkt, size);
+			if (writeall(ctx->sockfd, pkt, size) < size) 
+                        {
+                                printf("sendcmd: writeall failed\n");
+                                close(ctx->sockfd);
+                                FREE(pkt);
+                                return 0;
+                        }
 			break;
 		case YAHOO_CONNECT_HTTP:
 		case YAHOO_CONNECT_HTTPPROXY:
-			yahoo_sendcmd_http(ctx, pkt);
+			if (!yahoo_sendcmd_http(ctx, pkt)) 
+                        {
+                                printf("sendcmd_http failed\n");
+                                FREE(pkt);
+                                return 0;
+                        }
 			break;
 	}
 
 	FREE(pkt);
-	return (0);
+	return (1);
 }
 
 int yahoo_cmd_ping(struct yahoo_context *ctx)
 {
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0);
-	return (0);
+	return yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0);
 }
 
 int yahoo_cmd_idle(struct yahoo_context *ctx)
 {
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_IDLE, ctx->user, "", 0);
-	return (0);
+	return yahoo_sendcmd(ctx, YAHOO_SERVICE_IDLE, ctx->user, "", 0);
 }
 
 int yahoo_cmd_sendfile(struct yahoo_context *ctx, char *active_user,
@@ -1563,16 +1675,21 @@
 {
 	char *content;
 
-	content = (char *) malloc(strlen(touser) + strlen(msg) + 5);
+	if (!(content = (char *) malloc(strlen(touser) + strlen(msg) + 5)))
+                return 0;
 
 	if (strlen(touser))
 	{
 		sprintf(content, "%s,%s", touser, msg);
-		yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content, 0);
+		if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content, 0)) 
+                {
+                        FREE(content);
+                        return 0;
+                }
 	}
 
 	FREE(content);
-	return (0);
+	return (1);
 }
 
 int yahoo_cmd_msg_offline(struct yahoo_context *ctx, char *active_user,
@@ -1580,17 +1697,22 @@
 {
 	char *content;
 
-	content = (char *) malloc(strlen(touser) + strlen(msg) + 5);
+	if (!(content = (char *) malloc(strlen(touser) + strlen(msg) + 5)))
+                return 0;
 
 	if (strlen(touser))
 	{
 		sprintf(content, "%s,%s", touser, msg);
-		yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content,
-			YAHOO_MSGTYPE_KNOWN_USER);
+		if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, 
+                                   content, YAHOO_MSGTYPE_KNOWN_USER))
+                {
+                        FREE(content);
+                        return 0;
+                }
 	}
 
 	FREE(content);
-	return (0);
+	return (1);
 }
 
 /* appended the " " so that won't trigger yahoo bug - hack for the moment */
@@ -1617,9 +1739,7 @@
 	{
 		snprintf(statusstring, 500, "%d", status);
 	}
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_ISAWAY, ctx->user, statusstring, 0);
-
-	return 0;
+	return yahoo_sendcmd(ctx, YAHOO_SERVICE_ISAWAY, ctx->user, statusstring, 0);
 }
 
 int yahoo_cmd_set_back_mode(struct yahoo_context *ctx, int status, char *msg)
@@ -1631,30 +1751,24 @@
 		status, yahoo_dbg_NullCheck(msg));
 
 	snprintf(statusstring, 500, "%d%c%s ", status, 1, msg ? msg : "");
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_ISBACK, ctx->user, statusstring, 0);
-
-	return 0;
+	return yahoo_sendcmd(ctx, YAHOO_SERVICE_ISBACK, ctx->user, statusstring, 0);
 }
 
 int yahoo_cmd_activate_id(struct yahoo_context *ctx, char *newid)
 {
 	if (strlen(newid))
-	{
-		yahoo_sendcmd(ctx, YAHOO_SERVICE_IDACT, newid, newid, 0);
-	}
-	return (0);
+		return yahoo_sendcmd(ctx, YAHOO_SERVICE_IDACT, newid, newid, 0);
+	return 0;
 }
 
 int yahoo_cmd_user_status(struct yahoo_context *ctx)
 {
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_USERSTAT, ctx->user, "", 0);
-	return (0);
+	return yahoo_sendcmd(ctx, YAHOO_SERVICE_USERSTAT, ctx->user, "", 0);
 }
 
 int yahoo_cmd_logoff(struct yahoo_context *ctx)
 {
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGOFF, ctx->user, ctx->user, 0);
-	return (0);
+	return yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGOFF, ctx->user, ctx->user, 0);
 }
 
 /*
@@ -1689,7 +1803,8 @@
 
 	int size = strlen(conf_id) + strlen(msg) + 8 + strlen(new_userlist);
 
-	content = (char *) malloc(size);
+	if (!(content = (char *) malloc(size)))
+                return 0;
 	memset(content, 0, size);
 
 	cont_len = snprintf(content,
@@ -1698,16 +1813,23 @@
 		conf_id, ctrlb, new_userlist, ctrlb, msg, ctrlb, type);
 
 #ifdef ENABLE_LIBYAHOO_DEBUG
-	unraw_msg = yahoo_unraw_buffer(content, cont_len);
-	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_start_conf: %s\n",
-		unraw_msg);
-	free(unraw_msg);
+	if ((unraw_msg = yahoo_unraw_buffer(content, cont_len)))
+        {
+                yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_start_conf: %s\n",
+                                unraw_msg);
+                FREE(unraw_msg);
+        }
 #endif /* def ENABLE_LIBYAHOO_DEBUG */
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFINVITE, ctx->user, content, 0);
+	if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFINVITE, ctx->user, content, 0))
+        {
+                FREE(new_userlist);
+                FREE(content);
+                return 0;
+        }
 
 	FREE(new_userlist);
 	FREE(content);
-	return (0);
+	return 1;
 }
 
 /*
@@ -1741,23 +1863,31 @@
 
 	int size = strlen(conf_id) + strlen(host) + 8 + strlen(new_userlist);
 
-	content = (char *) malloc(size);
+	if (!(content = (char *) malloc(size)))
+                return 0;
 	memset(content, 0, size);
 
 	cont_len =
 		sprintf(content, "%s%c%s,%s", conf_id, ctrlb, host, new_userlist);
 
 #ifdef ENABLE_LIBYAHOO_DEBUG
-	unraw_msg = yahoo_unraw_buffer(content, cont_len);
-	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logon: %s\n",
-		unraw_msg);
-	free(unraw_msg);
+	if ((unraw_msg = yahoo_unraw_buffer(content, cont_len)))
+        {
+                yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logon: %s\n",
+                                unraw_msg);
+                FREE(unraw_msg);
+        }
 #endif /* def ENABLE_LIBYAHOO_DEBUG */
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGON, ctx->user, content, 0);
+	if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGON, ctx->user, content, 0))
+        {
+                FREE(new_userlist);
+                FREE(content);
+                return 0;
+        }
 
 	FREE(new_userlist);
 	FREE(content);
-	return (0);
+	return 1;
 }
 
 /*
@@ -1788,11 +1918,11 @@
 	char *new_userlist = yahoo_array2list(userlist);
 
 	int size =
-
 		strlen(conf_id) + strlen(host) + strlen(msg) + 8 +
 		strlen(new_userlist);
 
-	content = (char *) malloc(size);
+	if (!(content = (char *) malloc(size)))
+                return 0;
 	memset(content, 0, size);
 
 	sprintf(content, "%s%c%s,%s%c%s", conf_id, ctrlb, host, new_userlist,
@@ -1800,11 +1930,16 @@
 
 	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_decline_conf: %s\n",
 		content);
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFDECLINE, ctx->user, content, 0);
+	if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFDECLINE, ctx->user, content, 0))
+        {
+                FREE(new_userlist);
+                FREE(content);
+                return 0;
+        }
 
 	FREE(new_userlist);
 	FREE(content);
-	return (0);
+	return 1;
 }
 
 /*
@@ -1839,22 +1974,30 @@
 
 	int size = strlen(conf_id) + strlen(new_userlist) + 8;
 
-	content = (char *) malloc(size);
+	if (!(content = (char *) malloc(size)))
+                return 0;
 	memset(content, 0, size);
 
 	cont_len =
 		snprintf(content, size, "%s%c%s", conf_id, ctrlb, new_userlist);
 #ifdef ENABLE_LIBYAHOO_DEBUG
-	unraw_msg = yahoo_unraw_buffer(content, cont_len);
-	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logoff: %s\n",
-		unraw_msg);
-	free(unraw_msg);
+	if ((unraw_msg = yahoo_unraw_buffer(content, cont_len)))
+        {
+                yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logoff: %s\n",
+                                unraw_msg);
+                FREE(unraw_msg);
+        }
 #endif /* def ENABLE_LIBYAHOO_DEBUG */
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGOFF, ctx->user, content, 0);
+	if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGOFF, ctx->user, content, 0)) 
+        {
+                FREE(new_userlist);
+                FREE(content);
+                return 0;
+        }
 
 	FREE(new_userlist);
 	FREE(content);
-	return (0);
+	return 1;
 }
 
 /*
@@ -1887,7 +2030,8 @@
 	int size = strlen(conf_id) + strlen(invited_user)
 		+ (2 * strlen(new_userlist)) + strlen(msg) + 7;
 
-	content = (char *) malloc(size);
+	if (!(content = (char *) malloc(size)))
+                return 0;
 	memset(content, 0, size);
 
 	sprintf(content, "%s%c%s%c%s%c%s%c%s%c0", conf_id, ctrlb,
@@ -1895,11 +2039,16 @@
 		new_userlist, ctrlb, msg, ctrlb);
 	yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_invite: %s\n",
 		content);
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFADDINVITE, ctx->user, content, 0);
+	if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFADDINVITE, ctx->user, content, 0))
+        {
+                FREE(new_userlist);
+                FREE(content);
+                return 0;
+        }
 
 	FREE(new_userlist);
 	FREE(content);
-	return (0);
+	return 1;
 }
 
 /*
@@ -1934,22 +2083,30 @@
 
 	int size = strlen(conf_id) + strlen(new_userlist) + strlen(msg) + 8;
 
-	content = (char *) malloc(size);
+	if (!(content = (char *) malloc(size)))
+                return 0;
 	memset(content, 0, size);
 
 	cont_len =
 		snprintf(content, size, "%s%c%s%c%s", conf_id, ctrlb, new_userlist,
 		ctrlb, msg);
 #ifdef ENABLE_LIBYAHOO_DEBUG
-	unraw_msg = yahoo_unraw_buffer(content, cont_len);
-	yahoo_dbg_Print("libyahoo", "yahoo_cmd_conf_msg: %s\n", unraw_msg);
-	free(unraw_msg);
+	if ((unraw_msg = yahoo_unraw_buffer(content, cont_len)))
+        {
+                yahoo_dbg_Print("libyahoo", "yahoo_cmd_conf_msg: %s\n", unraw_msg);
+                FREE(unraw_msg);
+        }
 #endif /* def ENABLE_LIBYAHOO_DEBUG */
-	yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFMSG, ctx->user, content, 0);
+	if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFMSG, ctx->user, content, 0))
+        {
+                FREE(new_userlist);
+                FREE(content);
+                return 0;
+        }
 
 	FREE(new_userlist);
 	FREE(content);
-	return (0);
+	return 1;
 }
 
 /*
@@ -2005,9 +2162,7 @@
 void yahoo_free_idstatus(struct yahoo_idstatus *idstatus)
 {
 	if (!idstatus)
-	{
 		return;
-	}
 
 	FREE(idstatus->id);
 	FREE(idstatus->connection_id);
@@ -2022,12 +2177,11 @@
 
 	/* If no valid inpkt passed, return */
 	if (!inpkt)
-	{
 		return NULL;
-	}
 
 	/* Allocate the packet structure, zeroed out */
-	pkt = (struct yahoo_packet *) calloc(sizeof(*pkt), 1);
+	if (!(pkt = (struct yahoo_packet *) calloc(sizeof(*pkt), 1)))
+                return NULL;
 
 	/* Pull out the standard data */
 	pkt->service = yahoo_makeint(inpkt->service);
@@ -2131,9 +2285,7 @@
 
 	pkt->msg = NULL;
 	if (content)
-	{
 		pkt->msg = strdup(content);
-	}
 
 	return 0;
 }
@@ -3210,26 +3362,26 @@
 	if (ctx->connect_mode == YAHOO_CONNECT_HTTP ||
 		ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
 	{
-		yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0);
+		if (!yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0))
+                        return 0;
 		return (1);
 	}
 
-	/* this assumes that data is ready */
-	/* Read from the connection to the server and get any new data */
-	res = read(ctx->sockfd, buf, 1000);
+        /* Read as much data as is available. */
+        /* XXX: doesnt the protocol contain header information with lengths? */
+	do {
+                res = read(ctx->sockfd, buf, sizeof(buf));
+                if ((res == -1) && (errno == EINTR))
+                        continue;
+                break;
+        } while (1);
+
 	if (res == -1)
 	{
-		yahoo_dbg_Print("io",
-			"yahoo_getdata: error reading data from server\n");
+		printf("yahoo_getdata: error reading data from server: %s\n",
+                       strerror(errno));
 		return (0);
 	}
-	if (res > 0)
-	{
-		yahoo_addtobuffer(ctx, buf, res);
-		yahoo_dbg_Print("io", "[libyahoo] yahoo_getdata: read (%d) bytes\n",
-			res);
-		return 1;
-	}
 	else if (res == 0)
 	{
 		yahoo_dbg_Print("io",
@@ -3237,7 +3389,10 @@
 		return 0;
 	}
 
-	return (1);
+        yahoo_addtobuffer(ctx, buf, res);
+        yahoo_dbg_Print("io", "[libyahoo] yahoo_getdata: read (%d) bytes\n", res);
+
+	return 1;
 }
 
 struct yahoo_rawpacket *yahoo_getpacket(struct yahoo_context *ctx)
@@ -3295,12 +3450,14 @@
 
 	/* Determine the content size specified by the header */
 	contentlen = yahoo_makeint(pkt->len) - YAHOO_PACKET_HEADER_SIZE;
-// printf("contentlen = %d\n", contentlen);
+#if 0
+        printf("contentlen = %d\n", contentlen);
+#endif
 
 	/* Don't continue if buffer doesn't have full content in it */
 	if (*buflen < (YAHOO_PACKET_HEADER_SIZE + contentlen))
 	{
-// printf("buffer not big enough for contentlen\n");
+                printf("buffer not big enough for contentlen\n");
 		return NULL;
 	}
 
@@ -3508,7 +3665,7 @@
 		servfd = yahoo_socket_connect(ctx, YAHOO_ADDRESS_HOST, YAHOO_ADDRESS_PORT);
 	}
 
-	if (!servfd)
+	if (servfd < 0)
 	{
 		printf("[libyahoo] failed to connect to address book server.\n");
 		return (0);
@@ -3528,7 +3685,10 @@
 	strcat(buffer, "\r\n");
 	strcat(buffer, "\r\n");
 
-	write(servfd, buffer, strlen(buffer));
+	if (writeall(servfd, buffer, strlen(buffer)) < strlen(buffer)) {
+                close(servfd);
+                return 0;
+        }
 
 	yahoo_dbg_Print("addressbook",
 		"[libyahoo] yahoo_fetchaddressbook: writing buffer '%s'\n", buffer);