- Merged more OpenBSD changes:
   - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c]
     move atomicio into it's own file.  wrap all socket write()s which
     were doing write(sock, buf, len) != len, with atomicio() calls.
   - [auth-skey.c]
     fd leak
   - [authfile.c]
     properly name fd variable
   - [channels.c]
     display great hatred towards strcpy
   - [pty.c pty.h sshd.c]
     use openpty() if it exists (it does on BSD4_4)
   - [tildexpand.c]
     check for ~ expansion past MAXPATHLEN
 - Modified helper.c to use new atomicio function.
 - Reformat Makefile a little
 - Moved RC4 routines from rc4.[ch] into helper.c
 - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX)
diff --git a/ChangeLog b/ChangeLog
index f475f18..fc6b3f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,24 @@
  - Fixed default SSH_ASKPASS
  - Fix PAM account and session being called multiple times. Problem 
    reported by Adrian Baugh <adrian@merlin.keble.ox.ac.uk>
+ - Merged more OpenBSD changes:
+   - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c]
+     move atomicio into it's own file.  wrap all socket write()s which 
+     were doing write(sock, buf, len) != len, with atomicio() calls.
+   - [auth-skey.c]
+     fd leak
+   - [authfile.c]
+     properly name fd variable
+   - [channels.c]
+     display great hatred towards strcpy
+   - [pty.c pty.h sshd.c]
+     use openpty() if it exists (it does on BSD4_4)
+   - [tildexpand.c]
+     check for ~ expansion past MAXPATHLEN
+ - Modified helper.c to use new atomicio function.
+ - Reformat Makefile a little
+ - Moved RC4 routines from rc4.[ch] into helper.c
+ - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX)
 
 19991204
  - Small cleanup of PAM code in sshd.c
diff --git a/Makefile.in b/Makefile.in
index c2c3261..80b0a6d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -23,25 +23,31 @@
 GNOME_CFLAGS=`gnome-config --cflags gnome gnomeui`
 GNOME_LIBS=`gnome-config --libs gnome gnomeui`
 
-OBJS=	authfd.o authfile.o auth-passwd.o auth-rhosts.o auth-rh-rsa.o \
-		auth-rsa.o auth-skey.o bufaux.o buffer.o canohost.o channels.o \
-		cipher.o clientloop.o compress.o crc32.o deattack.o helper.o \
-		hostfile.o log-client.o login.o log-server.o match.o mpaux.o \
-		packet.o pty.o readconf.o readpass.o rsa.o servconf.o serverloop.o \
-		sshconnect.o tildexpand.o ttymodes.o uidswap.o xmalloc.o \
-		helper.o bsd-mktemp.o bsd-strlcpy.o bsd-strlcat.o bsd-daemon.o \
-		bsd-login.o bsd-snprintf.o rc4.o md5crypt.o
-
+OBJS= atomicio.o authfd.o authfile.o auth-passwd.o auth-rhosts.o \
+  auth-rh-rsa.o auth-rsa.o auth-skey.o bsd-daemon.o bsd-login.o \
+  bsd-mktemp.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o \
+  buffer.o canohost.o channels.o cipher.o clientloop.o compress.o \
+  crc32.o deattack.o helper.o helper.o hostfile.o log-client.o \
+  login.o log-server.o match.o md5crypt.o mpaux.o packet.o pty.o \
+  readconf.o readpass.o rsa.o servconf.o serverloop.o \
+  sshconnect.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 
 all: $(OBJS) $(TARGETS)
 
-libssh.a: authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o hostfile.o match.o mpaux.o nchan.o packet.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o helper.o rc4.o bsd-mktemp.o bsd-strlcpy.o bsd-strlcat.o bsd-snprintf.o bsd-daemon.o log.o fingerprint.o
+libssh.a: atomicio.o authfd.o authfile.o bsd-daemon.o bsd-mktemp.o \
+  bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o \
+  buffer.o canohost.o channels.o cipher.o compat.o \
+  compress.o crc32.o deattack.o fingerprint.o helper.o \
+  hostfile.o log.o match.o mpaux.o nchan.o packet.o \
+  readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 
 	$(AR) rv $@ $^
 	$(RANLIB) $@
 
 ssh: ssh.o sshconnect.o log-client.o readconf.o clientloop.o libssh.a
 	$(CC) -o $@ $^ $(LFLAGS) $(LIBS) 
 
-sshd:	sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o md5crypt.o libssh.a
+sshd:	sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
+  pty.o log-server.o login.o servconf.o serverloop.o bsd-login.o \
+  md5crypt.o libssh.a
 	$(CC) -o $@ $^ $(LFLAGS) $(LIBS) 
 
 scp:	scp.o libssh.a
diff --git a/acconfig.h b/acconfig.h
index 25f4914..29ec078 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -64,6 +64,12 @@
 #undef HAVE_U_INTXX_T
 #undef HAVE_UINTXX_T
 
+/* Define if you have /dev/ptmx */
+#undef HAVE_DEV_PTMX
+
+/* Define if you have /dev/ptc */
+#undef HAVE_DEV_PTS_AND_PTC
+
 @BOTTOM@
 
 /* ******************* Shouldn't need to edit below this line ************** */
diff --git a/atomicio.c b/atomicio.c
new file mode 100644
index 0000000..03d635c
--- /dev/null
+++ b/atomicio.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1999 Theo de Raadt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$Id: atomicio.c,v 1.1 1999/12/07 04:38:31 damien Exp $");
+
+#include "xmalloc.h"
+#include "ssh.h"
+
+/*
+ * ensure all of data on socket comes through. f==read || f==write
+ */
+int
+atomicio(f, fd, s, n)
+	int (*f) ();
+	int fd;
+	void *s;
+	size_t n;
+{
+	int res, pos = 0;
+
+	while (n > pos) {
+		res = (f) (fd, s + pos, n - pos);
+		switch (res) {
+		case -1:
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+		case 0:
+			return (res);
+		default:
+			pos += res;
+		}
+	}
+	return (pos);
+}
diff --git a/auth-skey.c b/auth-skey.c
index cc5f451..8829159 100644
--- a/auth-skey.c
+++ b/auth-skey.c
@@ -1,7 +1,7 @@
 #include "includes.h"
 
 #ifdef SKEY
-RCSID("$Id: auth-skey.c,v 1.4 1999/12/01 16:54:35 markus Exp $");
+RCSID("$Id: auth-skey.c,v 1.5 1999/12/06 19:04:57 deraadt Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -114,6 +114,7 @@
 		    SEEK_SET) != -1 && read(fd, hseed,
 		    SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {
 			close(fd);
+			fd = -1;
 			secret = hseed;
 			secretlen = SKEY_MAX_SEED_LEN;
 			flg = 0;
@@ -123,6 +124,8 @@
 			secretlen = strlen(secret);
 			flg = 0;
 		}
+		if (fd != -1)
+			close(fd);
 	}
 
 	/* Put that in your pipe and smoke it */
diff --git a/authfd.c b/authfd.c
index ee6473d..1a62c3e 100644
--- a/authfd.c
+++ b/authfd.c
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: authfd.c,v 1.8 1999/11/25 00:54:57 damien Exp $");
+RCSID("$Id: authfd.c,v 1.9 1999/12/07 04:38:32 damien Exp $");
 
 #include "ssh.h"
 #include "rsa.h"
@@ -145,7 +145,7 @@
 	msg[2] = 0;
 	msg[3] = 1;
 	msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
-	if (write(auth->fd, msg, 5) != 5) {
+	if (atomicio(write, auth->fd, msg, 5) != 5) {
 		error("write auth->fd: %.100s", strerror(errno));
 		return 0;
 	}
@@ -270,9 +270,9 @@
 	PUT_32BIT(buf, len);
 
 	/* Send the length and then the packet to the agent. */
-	if (write(auth->fd, buf, 4) != 4 ||
-	    write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
-	    buffer_len(&buffer)) {
+	if (atomicio(write, auth->fd, buf, 4) != 4 ||
+	    atomicio(write, auth->fd, buffer_ptr(&buffer),
+	    buffer_len(&buffer)) != buffer_len(&buffer)) {
 		error("Error writing to authentication socket.");
 error_cleanup:
 		buffer_free(&buffer);
@@ -369,9 +369,9 @@
 	PUT_32BIT(buf, len);
 
 	/* Send the length and then the packet to the agent. */
-	if (write(auth->fd, buf, 4) != 4 ||
-	    write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
-	    buffer_len(&buffer)) {
+	if (atomicio(write, auth->fd, buf, 4) != 4 ||
+	    atomicio(write, auth->fd, buffer_ptr(&buffer),
+	    buffer_len(&buffer)) != buffer_len(&buffer)) {
 		error("Error writing to authentication socket.");
 error_cleanup:
 		buffer_free(&buffer);
@@ -450,9 +450,9 @@
 	PUT_32BIT(buf, len);
 
 	/* Send the length and then the packet to the agent. */
-	if (write(auth->fd, buf, 4) != 4 ||
-	    write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
-	    buffer_len(&buffer)) {
+	if (atomicio(write, auth->fd, buf, 4) != 4 ||
+	    atomicio(write, auth->fd, buffer_ptr(&buffer),
+	    buffer_len(&buffer)) != buffer_len(&buffer)) {
 		error("Error writing to authentication socket.");
 error_cleanup:
 		buffer_free(&buffer);
@@ -526,7 +526,7 @@
 	buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES;
 
 	/* Send the length and then the packet to the agent. */
-	if (write(auth->fd, buf, 5) != 5) {
+	if (atomicio(write, auth->fd, buf, 5) != 5) {
 		error("Error writing to authentication socket.");
 		return 0;
 	}
diff --git a/authfile.c b/authfile.c
index 97d0a87..b0e832a 100644
--- a/authfile.c
+++ b/authfile.c
@@ -15,7 +15,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: authfile.c,v 1.5 1999/11/25 00:54:58 damien Exp $");
+RCSID("$Id: authfile.c,v 1.6 1999/12/07 04:38:32 damien Exp $");
 
 #ifdef HAVE_OPENSSL
 #include <openssl/bn.h>
@@ -46,7 +46,7 @@
 {
 	Buffer buffer, encrypted;
 	char buf[100], *cp;
-	int f, i;
+	int fd, i;
 	CipherContext cipher;
 	int cipher_type;
 	u_int32_t rand;
@@ -117,19 +117,19 @@
 	memset(buf, 0, sizeof(buf));
 	buffer_free(&buffer);
 
-	f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-	if (f < 0)
+	fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+	if (fd < 0)
 		return 0;
-	if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
+	if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
 	    buffer_len(&encrypted)) {
 		debug("Write to key file %.200s failed: %.100s", filename,
 		      strerror(errno));
 		buffer_free(&encrypted);
-		close(f);
+		close(fd);
 		remove(filename);
 		return 0;
 	}
-	close(f);
+	close(fd);
 	buffer_free(&encrypted);
 	return 1;
 }
@@ -144,28 +144,28 @@
 load_public_key(const char *filename, RSA * pub,
 		char **comment_return)
 {
-	int f, i;
+	int fd, i;
 	off_t len;
 	Buffer buffer;
 	char *cp;
 
-	f = open(filename, O_RDONLY);
-	if (f < 0)
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
 		return 0;
-	len = lseek(f, (off_t) 0, SEEK_END);
-	lseek(f, (off_t) 0, SEEK_SET);
+	len = lseek(fd, (off_t) 0, SEEK_END);
+	lseek(fd, (off_t) 0, SEEK_SET);
 
 	buffer_init(&buffer);
 	buffer_append_space(&buffer, &cp, len);
 
-	if (read(f, cp, (size_t) len) != (size_t) len) {
+	if (read(fd, cp, (size_t) len) != (size_t) len) {
 		debug("Read from key file %.200s failed: %.100s", filename,
 		      strerror(errno));
 		buffer_free(&buffer);
-		close(f);
+		close(fd);
 		return 0;
 	}
-	close(f);
+	close(fd);
 
 	/* Check that it is at least big enought to contain the ID string. */
 	if (len < strlen(AUTHFILE_ID_STRING) + 1) {
@@ -178,7 +178,7 @@
 	 * from the buffer.
 	 */
 	for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
-		if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
+		if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
 			debug("Bad key file %.200s.", filename);
 			buffer_free(&buffer);
 			return 0;
@@ -213,7 +213,7 @@
 load_private_key(const char *filename, const char *passphrase,
 		 RSA * prv, char **comment_return)
 {
-	int f, i, check1, check2, cipher_type;
+	int fd, i, check1, check2, cipher_type;
 	off_t len;
 	Buffer buffer, decrypted;
 	char *cp;
@@ -222,14 +222,15 @@
 	BIGNUM *aux;
 	struct stat st;
 
-	f = open(filename, O_RDONLY);
-	if (f < 0)
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
 		return 0;
 
 	/* check owner and modes */
-	if (fstat(f, &st) < 0 ||
+	if (fstat(fd, &st) < 0 ||
 	    (st.st_uid != 0 && st.st_uid != getuid()) ||
 	    (st.st_mode & 077) != 0) {
+		close(fd);
 		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
 		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
 		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
@@ -238,20 +239,20 @@
 		error("It is recommended that your private key files are NOT accessible by others.");
 		return 0;
 	}
-	len = lseek(f, (off_t) 0, SEEK_END);
-	lseek(f, (off_t) 0, SEEK_SET);
+	len = lseek(fd, (off_t) 0, SEEK_END);
+	lseek(fd, (off_t) 0, SEEK_SET);
 
 	buffer_init(&buffer);
 	buffer_append_space(&buffer, &cp, len);
 
-	if (read(f, cp, (size_t) len) != (size_t) len) {
+	if (read(fd, cp, (size_t) len) != (size_t) len) {
 		debug("Read from key file %.200s failed: %.100s", filename,
 		      strerror(errno));
 		buffer_free(&buffer);
-		close(f);
+		close(fd);
 		return 0;
 	}
-	close(f);
+	close(fd);
 
 	/* Check that it is at least big enought to contain the ID string. */
 	if (len < strlen(AUTHFILE_ID_STRING) + 1) {
diff --git a/channels.c b/channels.c
index 0138236..6c2fb73 100644
--- a/channels.c
+++ b/channels.c
@@ -16,7 +16,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: channels.c,v 1.9 1999/12/06 00:47:29 damien Exp $");
+RCSID("$Id: channels.c,v 1.10 1999/12/07 04:38:32 damien Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -921,7 +921,7 @@
 	/* Allocate a channel number for the socket. */
 	ch = channel_allocate(SSH_CHANNEL_PORT_LISTENER, sock,
 			      xstrdup("port listener"));
-	strcpy(channels[ch].path, host);
+	strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
 	channels[ch].host_port = host_port;
 	channels[ch].listening_port = port;
 }
@@ -1498,7 +1498,8 @@
 	/* Allocate a channel for the authentication agent socket. */
 	newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock,
 				 xstrdup("auth socket"));
-	strcpy(channels[newch].path, channel_forwarded_auth_socket_name);
+	strlcpy(channels[newch].path, channel_forwarded_auth_socket_name,
+	    sizeof(channels[newch].path));
 }
 
 /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
diff --git a/clientloop.c b/clientloop.c
index 679180f..bfa3019 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -15,7 +15,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: clientloop.c,v 1.6 1999/11/25 00:54:58 damien Exp $");
+RCSID("$Id: clientloop.c,v 1.7 1999/12/07 04:38:32 damien Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -466,13 +466,11 @@
 
 	/* Flush stdout and stderr buffers. */
 	if (buffer_len(&stdout_buffer) > 0)
-		write(fileno(stdout),
-		      buffer_ptr(&stdout_buffer),
-		      buffer_len(&stdout_buffer));
+		atomicio(write, fileno(stdout), buffer_ptr(&stdout_buffer),
+		    buffer_len(&stdout_buffer));
 	if (buffer_len(&stderr_buffer) > 0)
-		write(fileno(stderr),
-		      buffer_ptr(&stderr_buffer),
-		      buffer_len(&stderr_buffer));
+		atomicio(write, fileno(stderr), buffer_ptr(&stderr_buffer),
+		    buffer_len(&stderr_buffer));
 
 	leave_raw_mode();
 
@@ -739,7 +737,7 @@
 	if (FD_ISSET(fileno(stdout), writeset)) {
 		/* Write as much data as possible. */
 		len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
-			    buffer_len(&stdout_buffer));
+		    buffer_len(&stdout_buffer));
 		if (len <= 0) {
 			if (errno == EAGAIN)
 				len = 0;
@@ -762,7 +760,7 @@
 	if (FD_ISSET(fileno(stderr), writeset)) {
 		/* Write as much data as possible. */
 		len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
-			    buffer_len(&stderr_buffer));
+		    buffer_len(&stderr_buffer));
 		if (len <= 0) {
 			if (errno == EAGAIN)
 				len = 0;
@@ -911,7 +909,7 @@
 	/* Output any buffered data for stdout. */
 	while (buffer_len(&stdout_buffer) > 0) {
 		len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
-			    buffer_len(&stdout_buffer));
+		    buffer_len(&stdout_buffer));
 		if (len <= 0) {
 			error("Write failed flushing stdout buffer.");
 			break;
@@ -922,7 +920,7 @@
 	/* Output any buffered data for stderr. */
 	while (buffer_len(&stderr_buffer) > 0) {
 		len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
-			    buffer_len(&stderr_buffer));
+		    buffer_len(&stderr_buffer));
 		if (len <= 0) {
 			error("Write failed flushing stderr buffer.");
 			break;
diff --git a/configure.in b/configure.in
index 86f2dde..62e6831 100644
--- a/configure.in
+++ b/configure.in
@@ -59,7 +59,7 @@
 AC_CHECK_HEADERS(endian.h lastlog.h login.h maillock.h netgroup.h paths.h pty.h shadow.h util.h utmp.h sys/select.h sys/time.h)
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(arc4random mkdtemp openpty setenv setlogin setproctitle snprintf strlcat strlcpy vsnprintf)
+AC_CHECK_FUNCS(arc4random mkdtemp openpty _getpty setenv setlogin setproctitle snprintf strlcat strlcpy vsnprintf)
 
 AC_CHECK_FUNC(login, 
 	[AC_DEFINE(HAVE_LOGIN)],
@@ -221,6 +221,9 @@
 	AC_DEFINE_UNQUOTED(LASTLOG_LOCATION, "$lastlog")
 fi	
 
+AC_CHECK_FILE("/dev/ptmx", AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX))
+AC_CHECK_FILE("/dev/ptc", AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC))
+
 AC_MSG_CHECKING([whether libc defines __progname])
 AC_TRY_LINK([], 
 	[extern char *__progname; printf("%s", __progname);], 
diff --git a/helper.c b/helper.c
index 91a78b5..bf4e145 100644
--- a/helper.c
+++ b/helper.c
@@ -45,7 +45,6 @@
 #include <sys/un.h>
 #include <fcntl.h>
 
-#include "rc4.h"
 #include "xmalloc.h"
 #include "ssh.h"
 #include "config.h"
@@ -57,10 +56,58 @@
 
 #ifndef HAVE_ARC4RANDOM
 
+typedef struct
+{
+	unsigned int s[256];
+	int i;
+	int j;
+} rc4_t;
+
 void get_random_bytes(unsigned char *buf, int len);
+void rc4_key(rc4_t *r, unsigned char *key, int len);
+void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
 
 static rc4_t *rc4 = NULL;
 
+void rc4_key(rc4_t *r, unsigned char *key, int len)
+{
+	int t;
+	
+	for(r->i = 0; r->i < 256; r->i++)
+		r->s[r->i] = r->i;
+
+	r->j = 0;
+	for(r->i = 0; r->i < 256; r->i++)
+	{
+		r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256;
+		t = r->s[r->i];
+		r->s[r->i] = r->s[r->j];
+		r->s[r->j] = t;
+	}
+	r->i = r->j = 0;
+}
+
+void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len)
+{
+	int t;
+	int c;
+
+	c = 0;	
+	while(c < len)
+	{
+		r->i = (r->i + 1) % 256;
+		r->j = (r->j + r->s[r->i]) % 256;
+		t = r->s[r->i];
+		r->s[r->i] = r->s[r->j];
+		r->s[r->j] = t;
+
+		t = (r->s[r->i] + r->s[r->j]) % 256;
+		
+		buffer[c] = r->s[t];
+		c++;
+	}
+}
+
 unsigned int arc4random(void)
 {
 	unsigned int r;
@@ -117,7 +164,8 @@
 	
 	/* Send blocking read request to EGD */
 	egd_message[1] = len;
-	c = write(random_pool, egd_message, sizeof(egd_message));
+
+	c = atomicio(write, random_pool, egd_message, sizeof(egd_message));
 	if (c == -1)
 		fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno));
 
@@ -129,15 +177,9 @@
 
 #endif /* HAVE_EGD */
 
-	do {
-		c = read(random_pool, buf, len);
-
-		if ((c == -1) && (errno != EINTR))
-			fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
-	} while (c == -1);
-
-	if (c != len)
-		fatal("Short read from random pool \"%s\"", RANDOM_POOL);
+	c = atomicio(read, random_pool, buf, len);
+	if (c <= 0)
+		fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
 	
 	close(random_pool);
 }
diff --git a/pty.c b/pty.c
index e468421..4f8fbd2 100644
--- a/pty.c
+++ b/pty.c
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: pty.c,v 1.5 1999/11/25 00:54:59 damien Exp $");
+RCSID("$Id: pty.c,v 1.6 1999/12/07 04:38:32 damien Exp $");
 
 #include "pty.h"
 #include "ssh.h"
@@ -40,17 +40,19 @@
  */
 
 int 
-pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
+pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
 {
-#ifdef HAVE_OPENPTY
+#if defined(HAVE_OPENPTY) || defined(BSD4_4)
 	/* openpty(3) exists in OSF/1 and some other os'es */
+	char buf[64];
 	int i;
 
-	i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL);
+	i = openpty(ptyfd, ttyfd, buf, NULL, NULL);
 	if (i < 0) {
 		error("openpty: %.100s", strerror(errno));
 		return 0;
 	}
+	strlcpy(namebuf, buf, namebuflen);	/* possible truncation */
 	return 1;
 #else /* HAVE_OPENPTY */
 #ifdef HAVE__GETPTY
@@ -65,7 +67,7 @@
 		error("_getpty: %.100s", strerror(errno));
 		return 0;
 	}
-	strcpy(namebuf, slave);
+	strlcpy(namebuf, slave, namebuflen);
 	/* Open the slave side. */
 	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
 	if (*ttyfd < 0) {
@@ -99,7 +101,7 @@
 	pts = ptsname(ptm);
 	if (pts == NULL)
 		error("Slave pty side name could not be obtained.");
-	strcpy(namebuf, pts);
+	strlcpy(namebuf, pts, namebuflen);
 	*ptyfd = ptm;
 
 	/* Open the slave side. */
@@ -130,7 +132,7 @@
 	name = ttyname(*ptyfd);
 	if (!name)
 		fatal("Open of /dev/ptc returns device for which ttyname fails.");
-	strcpy(namebuf, name);
+	strlcpy(namebuf, name, namebuflen);
 	*ttyfd = open(name, O_RDWR | O_NOCTTY);
 	if (*ttyfd < 0) {
 		error("Could not open pty slave side %.100s: %.100s",
@@ -154,8 +156,8 @@
 		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
 		if (*ptyfd < 0)
 			continue;
-		snprintf(namebuf, sizeof buf, "/dev/tty%c%c", ptymajors[i / num_minors],
-			 ptyminors[i % num_minors]);
+		snprintf(namebuf, sizeof namebuflen, "/dev/tty%c%c",
+		    ptymajors[i / num_minors], ptyminors[i % num_minors]);
 
 		/* Open the slave side. */
 		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
diff --git a/pty.h b/pty.h
index 0601e69..186cb3c 100644
--- a/pty.h
+++ b/pty.h
@@ -13,7 +13,7 @@
  * tty.
  */
 
-/* RCSID("$Id: pty.h,v 1.3 1999/11/25 00:54:59 damien Exp $"); */
+/* RCSID("$Id: pty.h,v 1.4 1999/12/07 04:38:32 damien Exp $"); */
 
 #ifndef PTY_H
 #define PTY_H
@@ -24,7 +24,7 @@
  * descriptors for the pty and tty sides and the name of the tty side are
  * returned (the buffer must be able to hold at least 64 characters).
  */
-int     pty_allocate(int *ptyfd, int *ttyfd, char *ttyname);
+int     pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen);
 
 /*
  * Releases the tty.  Its ownership is returned to root, and permissions to
diff --git a/rc4.c b/rc4.c
deleted file mode 100644
index 998a107..0000000
--- a/rc4.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*! \file rc4.c
-    \brief Source file for RC4 stream cipher routines
-	 \author Damien Miller <djm@mindrot.org>
-	 \version 0.0.0
-	 \date 1999
-	 
-	 A simple implementation of the RC4 stream cipher, based on the
-	 description given in _Bruce Schneier's_ "Applied Cryptography"
-	 2nd edition.
-
-	 Copyright 1999 Damien Miller
-
-	 Permission is hereby granted, free of charge, to any person
-	 obtaining a copy of this software and associated documentation
-	 files (the "Software"), to deal in the Software without
-	 restriction, including without limitation the rights to use, copy,
-	 modify, merge, publish, distribute, sublicense, and/or sell copies
-	 of the Software, and to permit persons to whom the Software is
-	 furnished to do so, subject to the following conditions:
-
-	 The above copyright notice and this permission notice shall be
-	 included in all copies or substantial portions of the Software.
-
-	 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-	 KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-	 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-	 AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER BE LIABLE
-	 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-	 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-	 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-	 \warning None of these functions clears its memory after use. It
-	 \warning is the responsability of the calling routines to ensure
-	 \warning that any sensitive data (keystream, key or plaintext) is
-	 \warning properly erased after use.
-	 
-	 \warning The name "RC4" is trademarked in the United States, 
-	 \warning you may need to use "RC4 compatible" or "ARC4" 
-	 \warning (Alleged RC4).
-*/
-
-/* $Id: rc4.c,v 1.1.1.1 1999/10/26 05:48:13 damien Exp $ */
-
-#include "config.h"
-
-#ifndef HAVE_ARC4RANDOM
-#include "rc4.h"
-
-
-void rc4_key(rc4_t *r, unsigned char *key, int len)
-{
-	int t;
-	
-	for(r->i = 0; r->i < 256; r->i++)
-		r->s[r->i] = r->i;
-
-	r->j = 0;
-	for(r->i = 0; r->i < 256; r->i++)
-	{
-		r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256;
-		t = r->s[r->i];
-		r->s[r->i] = r->s[r->j];
-		r->s[r->j] = t;
-	}
-	r->i = r->j = 0;
-}
-
-void rc4_crypt(rc4_t *r, unsigned char *plaintext, int len)
-{
-	int t;
-	int c;
-
-	c = 0;	
-	while(c < len)
-	{
-		r->i = (r->i + 1) % 256;
-		r->j = (r->j + r->s[r->i]) % 256;
-		t = r->s[r->i];
-		r->s[r->i] = r->s[r->j];
-		r->s[r->j] = t;
-
-		t = (r->s[r->i] + r->s[r->j]) % 256;
-
-		plaintext[c] ^= r->s[t];
-		c++;
-	}
-}
-
-void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len)
-{
-	int t;
-	int c;
-
-	c = 0;	
-	while(c < len)
-	{
-		r->i = (r->i + 1) % 256;
-		r->j = (r->j + r->s[r->i]) % 256;
-		t = r->s[r->i];
-		r->s[r->i] = r->s[r->j];
-		r->s[r->j] = t;
-
-		t = (r->s[r->i] + r->s[r->j]) % 256;
-		
-		buffer[c] = r->s[t];
-		c++;
-	}
-}
-#endif /* !HAVE_ARC4RANDOM */
diff --git a/rc4.h b/rc4.h
deleted file mode 100644
index 1be64ac..0000000
--- a/rc4.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*! \file rc4.h
-    \brief Header file for RC4 stream cipher routines
-	 \author Damien Miller <djm@mindrot.org>
-	 \version 0.0.0
-	 \date 1999
-	 
-	 A simple implementation of the RC4 stream cipher, based on the
-	 description given in _Bruce Schneier's_ "Applied Cryptography"
-	 2nd edition.
-
-	 Copyright 1999 Damien Miller
-
-	 Permission is hereby granted, free of charge, to any person
-	 obtaining a copy of this software and associated documentation
-	 files (the "Software"), to deal in the Software without
-	 restriction, including without limitation the rights to use, copy,
-	 modify, merge, publish, distribute, sublicense, and/or sell copies
-	 of the Software, and to permit persons to whom the Software is
-	 furnished to do so, subject to the following conditions:
-
-	 The above copyright notice and this permission notice shall be
-	 included in all copies or substantial portions of the Software.
-
-	 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-	 KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-	 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
-	 AND NONINFRINGEMENT.  IN NO EVENT SHALL DAMIEN MILLER BE LIABLE
-	 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-	 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-	 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-	 \warning None of these functions clears its memory after use. It
-	 \warning is the responsability of the calling routines to ensure
-	 \warning that any sensitive data (keystream, key or plaintext) is
-	 \warning properly erased after use.
-	 
-	 \warning The name "RC4" is trademarked in the United States, 
-	 \warning you may need to use "RC4 compatible" or "ARC4" 
-	 \warning (Alleged RC4).
-*/
-
-/* $Id: rc4.h,v 1.1.1.1 1999/10/26 05:48:13 damien Exp $ */
-
-#ifndef _RC4_H
-#define _RC4_H
-
-#include "config.h"
-#ifndef HAVE_ARC4RANDOM
-
-/*! \struct rc4_t
-    \brief RC4 stream cipher state object
-	 \var s State array
-	 \var i Monotonic index
-	 \var j Randomised index
-	 
-	 \warning This structure should not be accessed directly. To
-	 \warning initialise a rc4_t object, you should use the rc4_key()
-	 \warning function
-	 
-	 This structure holds the current state of the RC4 algorithm.
-*/
-typedef struct
-{
-	unsigned int s[256];
-	int i;
-	int j;
-} rc4_t;
-
-/*! \fn void rc4_key(rc4_t *r, unsigned char *key, int len);
-    \brief Set up key structure of RC4 stream cipher
-	 \param r pointer to RC4 structure to be seeded
-	 \param key pointer to buffer containing raw key
-	 \param len length of key
-	 
-	 This function set the internal state of the RC4 data structure
-	 pointed to by \a r using the specified \a key of length \a len.
-	 
-	 This function can use up to 256 bytes of key, any more are ignored.
-	 
-	 \warning Stream ciphers (such as RC4) can be insecure if the same
-	 \warning key is used repeatedly. Ensure that any key specified has
-	 \warning an reasonably sized Initialisation Vector component.
-*/
-void rc4_key(rc4_t *r, unsigned char *key, int len);
-
-/*! \fn rc4_crypt(rc4_t *r, unsigned char *plaintext, int len);
-    \brief Crypt bytes using RC4 algorithm
-	 \param r pointer to RC4 structure to be used
-	 \param plaintext Pointer to bytes to encrypt
-	 \param len number of bytes to crypt
-
-	 This function encrypts one or more bytes (pointed to by \a plaintext)
-	 using the RC4 algorithm. \a r is a state structure that must be 
-	 initialiased using the rc4_key() function prior to use.
-	 
-	 Since RC4 XORs each byte of plaintext with a byte of keystream,
-	 this function can be used for both encryption and decryption.
-*/
-void rc4_crypt(rc4_t *r, unsigned char *plaintext, int len);
-
-/*! \fn rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
-    \brief Generate key stream using the RC4 stream cipher
-	 \param r pointer to RC4 structure to be used
-	 \param buffer pointer to buffer in which to deposit keystream
-	 \param len number of bytes to deposit
-
-	 This function gives access to the raw RC4 key stream. In this 
-	 consiguration RC4 can be used as a fast, strong pseudo-random 
-	 number generator with a very long period.
-*/
-void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
-
-#endif /* !HAVE_ARC4RANDOM */
-
-#endif /* _RC4_H */
diff --git a/scp.c b/scp.c
index fec2f43..5a3ec44 100644
--- a/scp.c
+++ b/scp.c
@@ -45,7 +45,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: scp.c,v 1.11 1999/11/25 01:31:26 damien Exp $");
+RCSID("$Id: scp.c,v 1.12 1999/12/07 04:38:32 damien Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -974,7 +974,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: scp.c,v 1.11 1999/11/25 01:31:26 damien Exp $
+ *	$Id: scp.c,v 1.12 1999/12/07 04:38:32 damien Exp $
  */
 
 char *
@@ -1065,30 +1065,6 @@
 	exit(1);
 }
 
-/*
- * ensure all of data on socket comes through. f==read || f==write
- */
-int
-atomicio(f, fd, s, n)
-	int (*f) ();
-	char *s;
-{
-	int res, pos = 0;
-
-	while (n > pos) {
-		res = (f) (fd, s + pos, n - pos);
-		switch (res) {
-		case -1:
-			if (errno == EINTR || errno == EAGAIN)
-				continue;
-		case 0:
-			return (res);
-		default:
-			pos += res;
-		}
-	}
-	return (pos);
-}
 
 void
 alarmtimer(int wait)
diff --git a/serverloop.c b/serverloop.c
index 94c2115..a5ecfe9 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -170,7 +170,7 @@
 
 	/* Send buffered stderr data to the client. */
 	while (buffer_len(&stderr_buffer) > 0 &&
-	       packet_not_very_much_data_to_write()) {
+	    packet_not_very_much_data_to_write()) {
 		len = buffer_len(&stderr_buffer);
 		if (packet_is_interactive()) {
 			if (len > 512)
@@ -199,7 +199,7 @@
 
 	/* Send buffered stdout data to the client. */
 	while (buffer_len(&stdout_buffer) > 0 &&
-	       packet_not_very_much_data_to_write()) {
+	    packet_not_very_much_data_to_write()) {
 		len = buffer_len(&stdout_buffer);
 		if (packet_is_interactive()) {
 			if (len > 512)
@@ -364,7 +364,7 @@
 	/* Write buffered data to program stdin. */
 	if (fdin != -1 && FD_ISSET(fdin, writeset)) {
 		len = write(fdin, buffer_ptr(&stdin_buffer),
-			    buffer_len(&stdin_buffer));
+		    buffer_len(&stdin_buffer));
 		if (len <= 0) {
 #ifdef USE_PIPES
 			close(fdin);
diff --git a/ssh.h b/ssh.h
index 0b66264..facd88a 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
  * 
  */
 
-/* RCSID("$Id: ssh.h,v 1.18 1999/12/07 03:54:53 damien Exp $"); */
+/* RCSID("$Id: ssh.h,v 1.19 1999/12/07 04:38:32 damien Exp $"); */
 
 #ifndef SSH_H
 #define SSH_H
@@ -702,9 +702,14 @@
 	struct envstring *next;
 	char   *s;
 };
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==write
+ */
+int	atomicio(int (*f)(), int fd, void *s, size_t n);
+
 #ifdef KRB4
 #include <krb.h>
-
 /*
  * Performs Kerberos v4 mutual authentication with the client. This returns 0
  * if the client could not be authenticated, and 1 if authentication was
diff --git a/sshconnect.c b/sshconnect.c
index 593eade..e6175f1 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: sshconnect.c,v 1.16 1999/12/06 00:47:29 damien Exp $");
+RCSID("$Id: sshconnect.c,v 1.17 1999/12/07 04:38:32 damien Exp $");
 
 #ifdef HAVE_OPENSSL
 #include <openssl/bn.h>
@@ -537,7 +537,7 @@
 	if (!load_private_key(authfile, "", private_key, NULL)) {
 		char buf[300];
 		snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
-			 comment);
+		    comment);
 		if (!options.batch_mode)
 			passphrase = read_passphrase(buf, 0);
 		else {
@@ -1036,8 +1036,8 @@
 
 	/* Send our own protocol version identification. */
 	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
-		 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
-	if (write(connection_out, buf, strlen(buf)) != strlen(buf))
+	    PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
+	if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
 		fatal("write: %.100s", strerror(errno));
 }
 
@@ -1292,10 +1292,10 @@
 			char prompt[1024];
 			char *fp = fingerprint(host_key->e, host_key->n);
 			snprintf(prompt, sizeof(prompt),
-				 "The authenticity of host '%.200s' can't be established.\n"
-				 "Key fingerprint is %d %s.\n"
-				 "Are you sure you want to continue connecting (yes/no)? ",
-			         host, BN_num_bits(host_key->n), fp);
+			    "The authenticity of host '%.200s' can't be established.\n"
+			    "Key fingerprint is %d %s.\n"
+			    "Are you sure you want to continue connecting (yes/no)? ",
+			    host, BN_num_bits(host_key->n), fp);
 			if (!read_yes_or_no(prompt, -1))
 				fatal("Aborted by user!\n");
 		}
@@ -1599,8 +1599,9 @@
 	if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
 	    options.password_authentication && !options.batch_mode) {
 		char prompt[80];
+
 		snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
-			 server_user, host);
+		    server_user, host);
 		if (try_password_authentication(prompt))
 			return;
 	}
diff --git a/sshd.c b/sshd.c
index 60d34d8..0c15e28 100644
--- a/sshd.c
+++ b/sshd.c
@@ -11,7 +11,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: sshd.c,v 1.34 1999/12/07 03:56:27 damien Exp $");
+RCSID("$Id: sshd.c,v 1.35 1999/12/07 04:38:32 damien Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -812,7 +812,7 @@
 		/* Send our protocol version identification. */
 		snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
 			 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
-		if (write(sock_out, buf, strlen(buf)) != strlen(buf))
+		if (atomicio(write, sock_out, buf, strlen(buf)) != strlen(buf))
 			fatal("Could not write ident string to %s.", get_remote_ipaddr());
 
 		/* Read other side\'s version identification. */
@@ -838,9 +838,10 @@
 	 * several versions and set appropriate flags to handle them.
 	 */
 	if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
-		   remote_version) != 3) {
-		const char *s = "Protocol mismatch.\n";
-		(void) write(sock_out, s, strlen(s));
+	    remote_version) != 3) {
+		char *s = "Protocol mismatch.\n";
+
+		(void) atomicio(write, sock_out, s, strlen(s));
 		close(sock_in);
 		close(sock_out);
 		fatal("Bad protocol version identification '%.100s' from %s",
@@ -849,8 +850,9 @@
 	debug("Client protocol version %d.%d; client software version %.100s",
 	      remote_major, remote_minor, remote_version);
 	if (remote_major != PROTOCOL_MAJOR) {
-		const char *s = "Protocol major versions differ.\n";
-		(void) write(sock_out, s, strlen(s));
+		char *s = "Protocol major versions differ.\n";
+
+		(void) atomicio(write, sock_out, s, strlen(s));
 		close(sock_in);
 		close(sock_out);
 		fatal("Protocol major versions differ for %s: %d vs. %d",
@@ -1737,7 +1739,8 @@
 			debug("Allocating pty.");
 
 			/* Allocate a pty and open it. */
-			if (!pty_allocate(&ptyfd, &ttyfd, ttyname)) {
+			if (!pty_allocate(&ptyfd, &ttyfd, ttyname,
+			    sizeof(ttyname))) {
 				error("Failed to allocate pty.");
 				goto fail;
 			}
diff --git a/tildexpand.c b/tildexpand.c
index 8ee551f..f615362 100644
--- a/tildexpand.c
+++ b/tildexpand.c
@@ -6,7 +6,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: tildexpand.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
+RCSID("$Id: tildexpand.c,v 1.4 1999/12/07 04:38:32 damien Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -23,6 +23,7 @@
 	char *expanded;
 	struct passwd *pw;
 	char user[100];
+	int len;
 
 	/* Return immediately if no tilde. */
 	if (filename[0] != '~')
@@ -56,7 +57,10 @@
 		return xstrdup(pw->pw_dir);
 	}
 	/* Build a path combining the specified directory and path. */
-	expanded = xmalloc(strlen(pw->pw_dir) + strlen(cp + 1) + 2);
-	sprintf(expanded, "%s/%s", pw->pw_dir, cp + 1);
+	len = strlen(pw->pw_dir) + strlen(cp + 1) + 2;
+	if (len > MAXPATHLEN)
+		fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1);
+	expanded = xmalloc(len);
+	snprintf(expanded, len, "%s/%s", pw->pw_dir, cp + 1);
 	return expanded;
 }