void ClientThread::SubProcess(const char *ttyName) {
	struct termios termbuf;
	//子进程开始执行
	setenv("TERM", this->type.c_str(), 1);
	setsid();
	close(0);
	int ttyfd = open(ttyName, O_RDWR, 0666);
	dup2(0, 1);
	dup2(0, 2);
	int pid = getpid();
	tcsetpgrp(0, pid); /* switch this tty's process group to us */
	tcgetattr(0, &termbuf);
	termbuf.c_lflag |= ECHO;
	termbuf.c_oflag |= ONLCR | XTABS;
	termbuf.c_iflag |= ICRNL;
	termbuf.c_iflag &= ~IXOFF;
	/*termbuf.c_lflag &= ~ICANON;*/
	tcsetattr(STDIN_FILENO, TCSANOW, &termbuf);
	print_login_issue("/etc/issue.net", ttyName);
	//启动登陆程序
	char login[] = "/bin/login";
	char *login_argv[2] = { login, NULL };
	execvp("/bin/login", (char**) (login_argv));
}
Exemple #2
0
	/* We rely on that there is space in the buffer for now.  */
	char *b = ts->buf2 + ts->rdidx2;
	*b++ = IAC;
	*b++ = command;
	*b++ = option;
	ts->rdidx2 += 3;
	ts->size2 += 3;
}


static struct tsession *
#ifdef CONFIG_FEATURE_TELNETD_INETD
make_new_session(void)
#else /* CONFIG_FEATURE_TELNETD_INETD */
make_new_session(int sockfd)
#endif /* CONFIG_FEATURE_TELNETD_INETD */
{
	struct termios termbuf;
	int pty, pid;
	char tty_name[32];
	struct tsession *ts = malloc(sizeof(struct tsession) + BUFSIZE * 2);

	ts->buf1 = (char *)(&ts[1]);
	ts->buf2 = ts->buf1 + BUFSIZE;

#ifdef CONFIG_FEATURE_TELNETD_INETD
	ts->sockfd_read = 0;
	ts->sockfd_write = 1;
#else /* CONFIG_FEATURE_TELNETD_INETD */
	ts->sockfd = sockfd;
#endif /* CONFIG_FEATURE_TELNETD_INETD */

	ts->rdidx1 = ts->wridx1 = ts->size1 = 0;
	ts->rdidx2 = ts->wridx2 = ts->size2 = 0;

#ifdef CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT
	/* initialize it with the timeout value*/
	ts->timeout_time = time(NULL) + TIMEOUT;
#endif /* CONFIG_FEATURE_TELNETD_INACTIVE_TIMEOUT */	

	/* Got a new connection, set up a tty and spawn a shell.  */

	pty = getpty(tty_name);

	if (pty < 0) {
		syslog(LOG_ERR, "All network ports in use!");
		return 0;
	}

	if (pty > maxfd)
		maxfd = pty;

	ts->ptyfd = pty;

	/* Make the telnet client understand we will echo characters so it
	 * should not do it locally. We don't tell the client to run linemode,
	 * because we want to handle line editing and tab completion and other
	 * stuff that requires char-by-char support.
	 */

	send_iac(ts, DO, TELOPT_ECHO);
	send_iac(ts, DO, TELOPT_NAWS);
	send_iac(ts, DO, TELOPT_LFLOW);
	send_iac(ts, WILL, TELOPT_ECHO);
	send_iac(ts, WILL, TELOPT_SGA);


	if ((pid = fork()) < 0) {
		syslog(LOG_ERR, "Can`t forking");
	}
	if (pid == 0) {
		/* In child, open the child's side of the tty.  */
		int i;

		for(i = 0; i <= maxfd; i++)
			close(i);
		/* make new process group */
		setsid();

		if (open(tty_name, O_RDWR /*| O_NOCTTY*/) < 0) {
			syslog(LOG_ERR, "Could not open tty");
			exit(1);
			}
		dup(0);
		dup(0);

		tcsetpgrp(0, getpid());

		/* The pseudo-terminal allocated to the client is configured to operate in
		 * cooked mode, and with XTABS CRMOD enabled (see tty(4)).
		 */

		tcgetattr(0, &termbuf);
		termbuf.c_lflag |= ECHO; /* if we use readline we dont want this */
		termbuf.c_oflag |= ONLCR|XTABS;
		termbuf.c_iflag |= ICRNL;
		termbuf.c_iflag &= ~IXOFF;
		/*termbuf.c_lflag &= ~ICANON;*/
		tcsetattr(0, TCSANOW, &termbuf);

		print_login_issue(issuefile, NULL);

		/* exec shell, with correct argv and env */
		execv(loginpath, (char *const *)argv_init);

		/* NOT REACHED */
		syslog(LOG_ERR, "execv error");
		exit(1);
	}

	ts->shell_pid = pid;

	return ts;
}