channel_stop_listening();
channel_close_all();
process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len){	char string[1024];	pid_t pid;	int bytes = 0;	u_int i;	u_char ch;	char *s;	for (i = 0; i < len; i++) {		/* Get one character at a time. */		ch = buf[i];		if (escape_pending) {			/* We have previously seen an escape character. */			/* Clear the flag now. */			escape_pending = 0;			/* Process the escaped character. */			switch (ch) {			case '.':				/* Terminate the connection. */				snprintf(string, sizeof string, "%c.\r\n", escape_char);				buffer_append(berr, string, strlen(string));				quit_pending = 1;				return -1;			case 'Z' - 64:				/* Suspend the program. */				/* Print a message to that effect to the user. */				snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char);				buffer_append(berr, string, strlen(string));				/* Restore terminal modes and suspend. */				client_suspend_self(bin, bout, berr);				/* We have been continued. */				continue;			case 'R':				if (compat20) {					if (datafellows & SSH_BUG_NOREKEY)						log("Server does not support re-keying");					else						need_rekeying = 1;				}				continue;			case '&':				/* XXX does not work yet with proto 2 */				if (compat20)					continue;				/*				 * Detach the program (continue to serve connections,				 * but put in background and no more new connections).				 */				if (!stdin_eof) {					/*					 * Sending SSH_CMSG_EOF alone does not always appear					 * to be enough.  So we try to send an EOF character					 * first.					 */					packet_start(SSH_CMSG_STDIN_DATA);					packet_put_string("\004", 1);					packet_send();					/* Close stdin. */					stdin_eof = 1;					if (buffer_len(bin) == 0) {						packet_start(SSH_CMSG_EOF);						packet_send();					}				}				/* Restore tty modes. */				leave_raw_mode();				/* Stop listening for new connections. */				channel_stop_listening();				printf("%c& [backgrounded]\n", escape_char);				/* Fork into background. */				pid = fork();				if (pid < 0) {					error("fork: %.100s", strerror(errno));					continue;				}				if (pid != 0) {	/* This is the parent. */					/* The parent just exits. */					exit(0);				}				/* The child continues serving connections. */				continue; /*XXX ? */			case '?':				snprintf(string, sizeof string,"%c?\r\n\Supported escape sequences:\r\n\~.  - terminate connection\r\n\~R  - Request rekey (SSH protocol 2 only)\r\n\~^Z - suspend ssh\r\n\~#  - list forwarded connections\r\n\~&  - background ssh (when waiting for connections to terminate)\r\n\~?  - this message\r\n\~~  - send the escape character by typing it twice\r\n\(Note that escapes are only recognized immediately after newline.)\r\n",					 escape_char);				buffer_append(berr, string, strlen(string));				continue;			case '#':				snprintf(string, sizeof string, "%c#\r\n", escape_char);				buffer_append(berr, string, strlen(string));				s = channel_open_message();				buffer_append(berr, s, strlen(s));				xfree(s);				continue;			default:				if (ch != escape_char) {					buffer_put_char(bin, escape_char);					bytes++;				}				/* Escaped characters fall through here */				break;			}		} else {			/*			 * The previous character was not an escape char. Check if this			 * is an escape.			 */			if (last_was_cr && ch == escape_char) {				/* It is. Set the flag and continue to next character. */				escape_pending = 1;				continue;			}		}		/*		 * Normal character.  Record whether it was a newline,		 * and append it to the buffer.		 */		last_was_cr = (ch == '\r' || ch == '\n');		buffer_put_char(bin, ch);		bytes++;	}	return bytes;}