diff --git a/buffer.c b/buffer.c
index dff861f15a5f1d775b224d5a4fd044ce9c2c9a20..97045ffcfc3acba3f05b86c9a7bd452e1197effb 100644
--- a/buffer.c
+++ b/buffer.c
@@ -160,6 +160,16 @@ unsigned char buf_getbyte(buffer* buf) {
 	return buf->data[buf->pos++];
 }
 
+/* Get a bool from the buffer and increment the pos */
+unsigned char buf_getbool(buffer* buf) {
+
+	unsigned char b;
+	b = buf_getbyte(buf);
+	if (b != 0)
+		b = 1;
+	return b;
+}
+
 /* put a byte, incrementing the length if required */
 void buf_putbyte(buffer* buf, unsigned char val) {
 
diff --git a/buffer.h b/buffer.h
index e1031a1b70aef9c67f66452f9f38defe75697429..f9aa6fa28dbeeb395c6cab7a790e8c31afacb001 100644
--- a/buffer.h
+++ b/buffer.h
@@ -50,6 +50,7 @@ void buf_setpos(buffer* buf, unsigned int pos);
 void buf_incrpos(buffer* buf, int incr); /* -ve is ok, to go backwards */
 void buf_incrwritepos(buffer* buf, unsigned int incr);
 unsigned char buf_getbyte(buffer* buf);
+unsigned char buf_getbool(buffer* buf);
 void buf_putbyte(buffer* buf, unsigned char val);
 unsigned char* buf_getptr(buffer* buf, unsigned int len);
 unsigned char* buf_getwriteptr(buffer* buf, unsigned int len);
diff --git a/channel.h b/channel.h
index 225fafb69a0c0ac4fcb017d0bbf0cc54bddc5e5d..a2fe87adbfb3a17daee4c8909375d371023da1e8 100644
--- a/channel.h
+++ b/channel.h
@@ -100,7 +100,7 @@ void chaninitialise();
 void chancleanup();
 void setchannelfds(fd_set *readfd, fd_set *writefd);
 void channelio(fd_set *readfd, fd_set *writefd);
-struct Channel* getchannel(unsigned int chan);
+struct Channel* getchannel();
 struct Channel* newchannel(unsigned int remotechan, 
 		const struct ChanType *type, 
 		unsigned int transwindow, unsigned int transmaxpacket);
diff --git a/cli-auth.c b/cli-auth.c
index dfd9bbb008fbbcd543adda5efac12a74f0b668ad..fc51061a515a833cc79c88ebb9096dc0616b4ae1 100644
--- a/cli-auth.c
+++ b/cli-auth.c
@@ -127,7 +127,7 @@ void recv_msg_userauth_failure() {
 
 	methods = buf_getstring(ses.payload, &methlen);
 
-	partial = buf_getbyte(ses.payload);
+	partial = buf_getbool(ses.payload);
 
 	if (partial) {
 		dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required");
diff --git a/cli-channel.c b/cli-channel.c
index 42e165b5e14896b30740a68bfa5714861822cb4a..1bd49abcf79bd9a67db158d7ebbdb42741e3f436 100644
--- a/cli-channel.c
+++ b/cli-channel.c
@@ -33,15 +33,12 @@
 /* We receive channel data - only used by the client chansession code*/
 void recv_msg_channel_extended_data() {
 
-	unsigned int chan;
 	struct Channel *channel;
 	unsigned int datatype;
 
 	TRACE(("enter recv_msg_channel_extended_data"))
 
-	chan = buf_getint(ses.payload);
-	channel = getchannel(chan);
-
+	channel = getchannel();
 	if (channel == NULL) {
 		dropbear_exit("Unknown channel");
 	}
diff --git a/cli-chansession.c b/cli-chansession.c
index 76e9dfae536c5b18c7d0686d27eaa7aab88be8f0..a8363ac8d5cc25a6512358ec165f8abc74337334 100644
--- a/cli-chansession.c
+++ b/cli-chansession.c
@@ -62,7 +62,7 @@ static void cli_chansessreq(struct Channel *channel) {
 	TRACE(("enter cli_chansessreq"))
 
 	type = buf_getstring(ses.payload, NULL);
-	wantreply = buf_getbyte(ses.payload);
+	wantreply = buf_getbool(ses.payload);
 
 	if (strcmp(type, "exit-status") != 0) {
 		TRACE(("unknown request '%s'", type))
diff --git a/cli-runopts.c b/cli-runopts.c
index 3ac5c2b24249cbcbd5f13c0e66a3aadb2382562b..0f5c67c4c969316c7523f15574623b8008b65098 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -53,7 +53,7 @@ static void printhelp() {
 					"-i <identityfile>   (multiple allowed)\n"
 #endif
 #ifdef ENABLE_CLI_LOCALTCPFWD
-					"-L <listenport:remotehsot:reportport> Local port forwarding\n"
+					"-L <listenport:remotehost:remoteport> Local port forwarding\n"
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
 					"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
diff --git a/cli-session.c b/cli-session.c
index 4d6a6458c247e768cc46ee10cd1e7e0b7b72eba1..0ac120e40ecc3cf057d966513ce526db2856c7cd 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -113,10 +113,14 @@ static void cli_session_init() {
 	cli_ses.tty_raw_mode = 0;
 	cli_ses.winchange = 0;
 
-	/* We store stdin's flags, so we can set them back on exit (otherwise
-	 * busybox's ash isn't happy */
+	/* We store std{in,out,err}'s flags, so we can set them back on exit
+	 * (otherwise busybox's ash isn't happy */
 	cli_ses.stdincopy = dup(STDIN_FILENO);
 	cli_ses.stdinflags = fcntl(STDIN_FILENO, F_GETFL, 0);
+	cli_ses.stdoutcopy = dup(STDOUT_FILENO);
+	cli_ses.stdoutflags = fcntl(STDOUT_FILENO, F_GETFL, 0);
+	cli_ses.stderrcopy = dup(STDERR_FILENO);
+	cli_ses.stderrflags = fcntl(STDERR_FILENO, F_GETFL, 0);
 
 	cli_ses.retval = EXIT_SUCCESS; /* Assume it's clean if we don't get a
 									  specific exit status */
@@ -250,9 +254,11 @@ void cli_session_cleanup() {
 		return;
 	}
 
-	/* Set stdin back to non-blocking - busybox ash dies nastily
-	 * if we don't revert the flags */
+	/* Set std{in,out,err} back to non-blocking - busybox ash dies nastily if
+	 * we don't revert the flags */
 	fcntl(cli_ses.stdincopy, F_SETFL, cli_ses.stdinflags);
+	fcntl(cli_ses.stdoutcopy, F_SETFL, cli_ses.stdoutflags);
+	fcntl(cli_ses.stderrcopy, F_SETFL, cli_ses.stderrflags);
 
 	cli_tty_cleanup();
 
diff --git a/common-channel.c b/common-channel.c
index 6f73fab8b0c8c2f7961ddf0adda9ef4cc82f8a76..bb7928ce48cf85ec8a61f0d6d2f219bbf190da84 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -162,8 +162,13 @@ struct Channel* newchannel(unsigned int remotechan,
 	return newchan;
 }
 
-/* Get the channel structure corresponding to a channel number */
-struct Channel* getchannel(unsigned int chan) {
+/* Returns the channel structure corresponding to the channel in the current
+ * data packet (ses.payload must be positioned appropriately) */
+struct Channel* getchannel() {
+
+	unsigned int chan;
+
+	chan = buf_getint(ses.payload);
 	if (chan >= ses.chansize || ses.channels[chan] == NULL) {
 		return NULL;
 	}
@@ -474,14 +479,11 @@ void setchannelfds(fd_set *readfd, fd_set *writefd) {
  * etc) FD is also EOF */
 void recv_msg_channel_eof() {
 
-	unsigned int chan;
 	struct Channel * channel;
 
 	TRACE(("enter recv_msg_channel_eof"))
 
-	chan = buf_getint(ses.payload);
-	channel = getchannel(chan);
-
+	channel = getchannel();
 	if (channel == NULL) {
 		dropbear_exit("EOF for unknown channel");
 	}
@@ -500,15 +502,11 @@ void recv_msg_channel_eof() {
 /* Handle channel closure(), respond in kind and close the channels */
 void recv_msg_channel_close() {
 
-	unsigned int chan;
 	struct Channel * channel;
 
 	TRACE(("enter recv_msg_channel_close"))
 
-	chan = buf_getint(ses.payload);
-	TRACE(("close channel = %d", chan))
-	channel = getchannel(chan);
-
+	channel = getchannel();
 	if (channel == NULL) {
 		/* disconnect ? */
 		dropbear_exit("Close for unknown channel");
@@ -567,14 +565,11 @@ static void deletechannel(struct Channel *channel) {
  * such as chansession or x11fwd */
 void recv_msg_channel_request() {
 
-	unsigned int chan;
 	struct Channel *channel;
 
 	TRACE(("enter recv_msg_channel_request"))
 	
-	chan = buf_getint(ses.payload);
-	channel = getchannel(chan);
-
+	channel = getchannel();
 	if (channel == NULL) {
 		/* disconnect ? */
 		dropbear_exit("Unknown channel");
@@ -666,12 +661,9 @@ static void send_msg_channel_data(struct Channel *channel, int isextended,
 /* We receive channel data */
 void recv_msg_channel_data() {
 
-	unsigned int chan;
 	struct Channel *channel;
 
-	chan = buf_getint(ses.payload);
-	channel = getchannel(chan);
-
+	channel = getchannel();
 	if (channel == NULL) {
 		dropbear_exit("Unknown channel");
 	}
@@ -738,13 +730,10 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
  * as data is sent, and incremented upon receiving window-adjust messages */
 void recv_msg_channel_window_adjust() {
 
-	unsigned int chan;
 	struct Channel * channel;
 	unsigned int incr;
 	
-	chan = buf_getint(ses.payload);
-	channel = getchannel(chan);
-
+	channel = getchannel();
 	if (channel == NULL) {
 		dropbear_exit("Unknown channel");
 	}
@@ -961,14 +950,12 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) {
  * successful*/
 void recv_msg_channel_open_confirmation() {
 
-	unsigned int chan;
 	struct Channel * channel;
 	int ret;
 
 	TRACE(("enter recv_msg_channel_open_confirmation"))
-	chan = buf_getint(ses.payload);
 
-	channel = getchannel(chan);
+	channel = getchannel();
 	if (channel == NULL) {
 		dropbear_exit("Unknown channel");
 	}
@@ -995,11 +982,9 @@ void recv_msg_channel_open_confirmation() {
 /* Notification that our channel open request failed */
 void recv_msg_channel_open_failure() {
 
-	unsigned int chan;
 	struct Channel * channel;
-	chan = buf_getbyte(ses.payload);
 
-	channel = getchannel(chan);
+	channel = getchannel();
 	if (channel == NULL) {
 		dropbear_exit("Unknown channel");
 	}
diff --git a/common-kex.c b/common-kex.c
index 97e341dfbf59251cb4bc1c2caf61d1437ba78575..a2336c5a52dfc5e05e9e70d9979fb2e7da110ad7 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -457,7 +457,6 @@ void recv_msg_kexinit() {
 	/* the rest of ses.kexhashbuf will be done after DH exchange */
 
 	ses.kexstate.recvkexinit = 1;
-//	ses.expecting = 0; // client matt
 
 	TRACE(("leave recv_msg_kexinit"))
 }
@@ -683,7 +682,7 @@ static void read_kex_algos() {
 	buf_eatstring(ses.payload);
 
 	/* first_kex_packet_follows */
-	if (buf_getbyte(ses.payload)) {
+	if (buf_getbool(ses.payload)) {
 		ses.kexstate.firstfollows = 1;
 		/* if the guess wasn't good, we ignore the packet sent */
 		if (!allgood) {
diff --git a/debug.h b/debug.h
index 7b1e2b57de4aebc4337189c86e1b3b31c938c576..93cb89178b6be47fe612a1e32a7083215aaebfd3 100644
--- a/debug.h
+++ b/debug.h
@@ -39,7 +39,7 @@
  * Caution: Don't use this in an unfriendly environment (ie unfirewalled),
  * since the printing may not sanitise strings etc. This will add a reasonable
  * amount to your executable size. */
- //#define DEBUG_TRACE 
+/*#define DEBUG_TRACE */
 
 /* All functions writing to the cleartext payload buffer call
  * CHECKCLEARTOWRITE() before writing. This is only really useful if you're
diff --git a/dropbear.8 b/dropbear.8
index a574ff2d86c04aa9bf12b5d9cb675d4085be2d0d..1cf5c115e1b2c78f97aa30c977bc1230db91c81f 100644
--- a/dropbear.8
+++ b/dropbear.8
@@ -76,6 +76,6 @@ Matt Johnston (matt@ucc.asn.au).
 .br
 Gerrit Pape (pape@smarden.org) wrote this manual page.
 .SH SEE ALSO
-dropbearkey(8)
+dropbearkey(8), dbclient(1)
 .P
 http://matt.ucc.asn.au/dropbear/dropbear.html
diff --git a/dropbearkey.8 b/dropbearkey.8
index 3128007da84a109e178be10bda2d130aa7e37a77..a093d85ea7f6b317a294e1950d5839f1139f80a0 100644
--- a/dropbearkey.8
+++ b/dropbearkey.8
@@ -42,6 +42,6 @@ Matt Johnston (matt@ucc.asn.au).
 .br
 Gerrit Pape (pape@smarden.org) wrote this manual page.
 .SH SEE ALSO
-dropbear(8)
+dropbear(8), dbclient(1)
 .P
 http://matt.ucc.asn.au/dropbear/dropbear.html
diff --git a/dss.c b/dss.c
index 6429ede1e575a762704f56ac43dbde8f41cc40c8..7b3d9d485b9542f52b27603bd9595645d5f4decc 100644
--- a/dss.c
+++ b/dss.c
@@ -261,6 +261,7 @@ out:
 }
 #endif /* DROPBEAR_SIGNKEY_VERIFY */
 
+#ifdef DSS_PROTOK	
 /* convert an unsigned mp into an array of bytes, malloced.
  * This array must be freed after use, len contains the length of the array,
  * if len != NULL */
@@ -279,6 +280,7 @@ static unsigned char* mptobytes(mp_int *mp, int *len) {
 	}
 	return ret;
 }
+#endif
 
 /* Sign the data presented with key, writing the signature contents
  * to the buffer
diff --git a/kex.h b/kex.h
index 01626ed1dc23fc88f0840bddf7f6be0c17ef0a4a..92b6c4282f005d7a3ced06cef312175b808343cb 100644
--- a/kex.h
+++ b/kex.h
@@ -37,10 +37,10 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv);
 void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
 		sign_key *hostkey);
 
-void recv_msg_kexdh_init(); // server
+void recv_msg_kexdh_init(); /* server */
 
-void send_msg_kexdh_init(); // client
-void recv_msg_kexdh_reply(); // client
+void send_msg_kexdh_init(); /* client */
+void recv_msg_kexdh_reply(); /* client */
 
 extern const unsigned char dh_p_val[];
 #define DH_P_LEN 128 /* The length of the dh_p_val array */
diff --git a/scp.c b/scp.c
index e356b8b040440f6c154bd71f1c92fc4b4eae841e..ccb6c2a36e23e0822df6bf188092ad3b8958c178 100644
--- a/scp.c
+++ b/scp.c
@@ -244,9 +244,6 @@ main(int argc, char **argv)
 	extern char *optarg;
 	extern int optind;
 
-	/* hack, seems to work */
-//	__progname = argv[0];
-
 	args.list = NULL;
 	addargs(&args, "ssh");		/* overwritten with ssh_program */
 	addargs(&args, "-x");
diff --git a/session.h b/session.h
index 1d5ebb4aa68016d4d4572f6a707c1d1cb63fbf82..90efb0778ebd785610dbc6fe1f79565b5b825776 100644
--- a/session.h
+++ b/session.h
@@ -218,6 +218,10 @@ struct clientsession {
 	struct termios saved_tio;
 	int stdincopy;
 	int stdinflags;
+	int stdoutcopy;
+	int stdoutflags;
+	int stderrcopy;
+	int stderrflags;
 
 	int winchange; /* Set to 1 when a windowchange signal happens */
 
diff --git a/svr-authpam.c b/svr-authpam.c
index e045b74eb2b45b0ce7c6ea7deb7f49278ecb02d7..fe1f123c8ed179f8fc592dba92abeeaef773bc4c 100644
--- a/svr-authpam.c
+++ b/svr-authpam.c
@@ -155,7 +155,7 @@ void svr_auth_pam() {
 	unsigned char changepw;
 
 	/* check if client wants to change password */
-	changepw = buf_getbyte(ses.payload);
+	changepw = buf_getbool(ses.payload);
 	if (changepw) {
 		/* not implemented by this server */
 		send_msg_userauth_failure(0, 1);
diff --git a/svr-authpasswd.c b/svr-authpasswd.c
index 43488173aad57f3229bb56e0f23449b0773d16f6..5be1e2ad584e975d61a84ea9a4095d0029a3e22d 100644
--- a/svr-authpasswd.c
+++ b/svr-authpasswd.c
@@ -71,7 +71,7 @@ void svr_auth_password() {
 	}
 
 	/* check if client wants to change password */
-	changepw = buf_getbyte(ses.payload);
+	changepw = buf_getbool(ses.payload);
 	if (changepw) {
 		/* not implemented by this server */
 		send_msg_userauth_failure(0, 1);
diff --git a/svr-authpubkey.c b/svr-authpubkey.c
index 5daba0f0e65e6a4168d9a04b86e0ad03e3436852..dcd59f0b1345c917f07526149a1949d247076e60 100644
--- a/svr-authpubkey.c
+++ b/svr-authpubkey.c
@@ -64,7 +64,7 @@ void svr_auth_pubkey() {
 
 	/* 0 indicates user just wants to check if key can be used, 1 is an
 	 * actual attempt*/
-	testkey = (buf_getbyte(ses.payload) == 0);
+	testkey = (buf_getbool(ses.payload) == 0);
 
 	algo = buf_getstring(ses.payload, &algolen);
 	keybloblen = buf_getint(ses.payload);
diff --git a/svr-chansession.c b/svr-chansession.c
index c04d592d80694de34e757bba91a30ea935525766..90c82a708d44728eb5bbd7cd5924652508f58601 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -305,7 +305,7 @@ static void chansessionrequest(struct Channel *channel) {
 	TRACE(("enter chansessionrequest"))
 
 	type = buf_getstring(ses.payload, &typelen);
-	wantreply = buf_getbyte(ses.payload);
+	wantreply = buf_getbool(ses.payload);
 
 	if (typelen > MAX_NAME_LEN) {
 		TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/
diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c
index 7fbc609bb51e2494f9947c30e5dc2690fc2fb7a2..3acc4ffb7a621b48431d96579c86c9002576bed4 100644
--- a/svr-tcpfwd.c
+++ b/svr-tcpfwd.c
@@ -78,7 +78,7 @@ void recv_msg_global_request_remotetcp() {
 	}
 
 	reqname = buf_getstring(ses.payload, &namelen);
-	wantreply = buf_getbyte(ses.payload);
+	wantreply = buf_getbool(ses.payload);
 
 	if (namelen > MAXNAMLEN) {
 		TRACE(("name len is wrong: %d", namelen))
diff --git a/svr-x11fwd.c b/svr-x11fwd.c
index e15fb82758a1c157562be7ae9f50dbb89716337f..cbc8a799be061b50b04ce471e3e8fea7f225160d 100644
--- a/svr-x11fwd.c
+++ b/svr-x11fwd.c
@@ -52,7 +52,7 @@ int x11req(struct ChanSess * chansess) {
 		return DROPBEAR_FAILURE;
 	}
 
-	chansess->x11singleconn = buf_getbyte(ses.payload);
+	chansess->x11singleconn = buf_getbool(ses.payload);
 	chansess->x11authprot = buf_getstring(ses.payload, NULL);
 	chansess->x11authcookie = buf_getstring(ses.payload, NULL);
 	chansess->x11screennum = buf_getint(ses.payload);