diff --git a/loginrec.c b/loginrec.c
index af10d95..9e5c3aa 100644
--- a/loginrec.c
+++ b/loginrec.c
@@ -239,6 +239,13 @@ logininfo *login_alloc_entry(int pid, const char *username,
 
 	newli = (struct logininfo *) m_malloc (sizeof(*newli));
 	(void)login_init_entry(newli, pid, username, hostname, line);
+#ifdef HAVE_STRUCT_SOCKADDR_IN6
+	if (inet_pton(AF_INET6, hostname, newli->hostaddr.sa_in6.sin6_addr.s6_addr) > 0)
+		newli->hostaddr.sa_in6.sin6_family = AF_INET6;
+	else
+#endif
+	if (inet_pton(AF_INET, hostname, &newli->hostaddr.sa_in.sin_addr.s_addr) > 0)
+		newli->hostaddr.sa_in.sin_family = AF_INET;
 	return newli;
 }
 
@@ -473,9 +480,6 @@ void
 construct_utmp(struct logininfo *li,
 		    struct utmp *ut)
 {
-# ifdef HAVE_ADDR_V6_IN_UTMP
-	struct sockaddr_in6 *sa6;
-#  endif
 	memset(ut, '\0', sizeof(*ut));
 
 	/* First fill out fields used for both logins and logouts */
@@ -528,12 +532,11 @@ construct_utmp(struct logininfo *li,
 	if (li->hostaddr.sa.sa_family == AF_INET)
 		ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;
 # endif
-# ifdef HAVE_ADDR_V6_IN_UTMP
+# if defined(HAVE_STRUCT_UTMP_UT_ADDR_V6) && defined(HAVE_STRUCT_SOCKADDR_IN6)
 	/* this is just a 128-bit IPv6 address */
 	if (li->hostaddr.sa.sa_family == AF_INET6) {
-		sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa);
-		memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16);
-		if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) {
+		memcpy(ut->ut_addr_v6, li->hostaddr.sa_in6.sin6_addr.s6_addr, 16);
+		if (IN6_IS_ADDR_V4MAPPED(&li->hostaddr.sa_in6.sin6_addr)) {
 			ut->ut_addr_v6[0] = ut->ut_addr_v6[3];
 			ut->ut_addr_v6[1] = 0;
 			ut->ut_addr_v6[2] = 0;
@@ -569,9 +572,6 @@ set_utmpx_time(struct logininfo *li, struct utmpx *utx)
 void
 construct_utmpx(struct logininfo *li, struct utmpx *utx)
 {
-# ifdef HAVE_ADDR_V6_IN_UTMP
-	struct sockaddr_in6 *sa6;
-#  endif
 	memset(utx, '\0', sizeof(*utx));
 # ifdef HAVE_STRUCT_UTMPX_UT_ID
 	line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id));
@@ -589,8 +589,6 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
 	line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line));
 	set_utmpx_time(li, utx);
 	utx->ut_pid = li->pid;
-	/* strncpy(): Don't necessarily want null termination */
-	strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
 
 	if (li->type == LTYPE_LOGOUT)
 		return;
@@ -600,6 +598,9 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
 	 * for logouts.
 	 */
 
+	/* strncpy(): Don't necessarily want null termination */
+	strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
+
 # ifdef HAVE_STRUCT_UTMPX_UT_HOST
 	strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname));
 # endif
@@ -608,16 +609,15 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
 	if (li->hostaddr.sa.sa_family == AF_INET)
 		utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;
 # endif
-# ifdef HAVE_ADDR_V6_IN_UTMP
+# if defined(HAVE_STRUCT_UTMPX_UT_ADDR_V6) && defined(HAVE_STRUCT_SOCKADDR_IN6)
 	/* this is just a 128-bit IPv6 address */
 	if (li->hostaddr.sa.sa_family == AF_INET6) {
-		sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa);
-		memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16);
-		if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) {
-			ut->ut_addr_v6[0] = ut->ut_addr_v6[3];
-			ut->ut_addr_v6[1] = 0;
-			ut->ut_addr_v6[2] = 0;
-			ut->ut_addr_v6[3] = 0;
+		memcpy(utx->ut_addr_v6, li->hostaddr.sa_in6.sin6_addr.s6_addr, 16);
+		if (IN6_IS_ADDR_V4MAPPED(&li->hostaddr.sa_in6.sin6_addr)) {
+			utx->ut_addr_v6[0] = utx->ut_addr_v6[3];
+			utx->ut_addr_v6[1] = 0;
+			utx->ut_addr_v6[2] = 0;
+			utx->ut_addr_v6[3] = 0;
 		}
 	}
 # endif
@@ -1047,30 +1047,12 @@ wtmp_get_entry(struct logininfo *li)
  **/
 
 #ifdef USE_WTMPX
-/* write a wtmpx entry direct to the end of the file */
-/* This is a slight modification of code in OpenBSD's logwtmp.c */
+/* write a wtmpx entry via updwtmpx() */
 static int
 wtmpx_write(struct logininfo *li, struct utmpx *utx)
 {
-	struct stat buf;
-	int fd, ret = 1;
-
-	if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
-		dropbear_log(LOG_WARNING, "wtmpx_write: problem opening %s: %s",
-		    WTMPX_FILE, strerror(errno));
-		return 0;
-	}
-
-	if (fstat(fd, &buf) == 0)
-		if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
-			ftruncate(fd, buf.st_size);
-			dropbear_log(LOG_WARNING, "wtmpx_write: problem writing %s: %s",
-			    WTMPX_FILE, strerror(errno));
-			ret = 0;
-		}
-	(void)close(fd);
-
-	return ret;
+	updwtmpx(WTMPX_FILE, utx);
+	return 1;
 }
 
 
diff --git a/loginrec.h b/loginrec.h
index b2e3778..f594ad7 100644
--- a/loginrec.h
+++ b/loginrec.h
@@ -105,6 +105,9 @@
 union login_netinfo {
 	struct sockaddr sa;
 	struct sockaddr_in sa_in;
+#ifdef HAVE_STRUCT_SOCKADDR_IN6
+	struct sockaddr_in6 sa_in6;
+#endif
 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
 	struct sockaddr_storage sa_storage;
 #endif
diff --git a/svr-chansession.c b/svr-chansession.c
index 656a968..bb4536c 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -850,6 +850,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
 		 * terminal used for stdout with the dup2 above, otherwise
 		 * the wtmp login will not be recorded */
 		li = chansess_login_alloc(chansess);
+		li->pid = getpid();
 		login_login(li);
 		login_free_entry(li);
 
