Exemplo n.º 1
0
static int cli_odebug_loopdetect_packet_tx(void *c_sys, int argc, cli_args_t *args)
{
	oDebug_loopDetect(LOOPDETECT_DEBUG_LEVEL_PACKET_TX);
	int pid = fork();
	if(pid == 0){
		pty_open();
	}
	if(pid > 0)
	{
		return;
	}
}
Exemplo n.º 2
0
static int cli_odebug_loopdetect_packet_interface(void *c_sys, int argc, cli_args_t *args)
{
	oDebug_loopDetect(LOOPDETECT_DEBUG_LEVEL_INTERFACE);
	int pid = fork();
	if(pid == 0){
		pty_open();
	}
	if(pid > 0)
	{
		return;
	}
}
Exemplo n.º 3
0
static int cli_odebug_stp_interface(void *c_sys, int argc, cli_args_t *args)
{
	oDebug_stp(SPANNINGTREE_DEBUG_LEVEL_INTERFACE);
	int pid = fork();
	if(pid == 0){
		pty_open();
	}
	else if(pid > 0)
	{
		return;
	}
}
Exemplo n.º 4
0
static int cli_odebug_all(void *c_sys, int argc, cli_args_t *args)
{      
	oDebug_stp(SPANNINGTREE_DEBUG_LEVEL_ALL);
	int pid = fork();
	if(pid == 0){
		pty_open();
	}
	if(pid > 0)
	{
		return;
	}
}
Exemplo n.º 5
0
static int cli_odebug_stp_tx(void *c_sys, int argc, cli_args_t *args)
{
	oDebug_stp(SPANNINGTREE_DEBUG_LEVEL_PACKET_TX);
	int pid = fork();
	if(pid == 0){
		pty_open();
	}
	else if(pid > 0)
	{
		return;
	}
}
Exemplo n.º 6
0
static int cli_odebug_loopdetect_all(void *c_sys, int argc, cli_args_t *args)
{
	oDebug_loopDetect(LOOPDETECT_DEBUG_LEVEL_ALL);
	int pid = fork();
	if(pid == 0){
		pty_open();
		return;
	}
	if(pid > 0)
	{
		return;
	}
}
Exemplo n.º 7
0
int
main(int argc, char **argv)
{
	pid_t child = 0;
	char c;
	int ret;
	signal(SIGCHLD, sigchld_handler);
	fd = pty_open(&child, 0, NULL,
		      (argc > 1) ? argv[1] : NULL,
		      (argc > 1) ? argv + 1 : NULL,
		      NULL,
		      0, 0,
		      NULL, NULL, NULL);
	if (child == 0) {
		int i;
		for (i = 0; ; i++) {
			switch (i % 3) {
			case 0:
			case 1:
				fprintf(stdout, "%d\n", i);
				break;
			case 2:
				fprintf(stderr, "%d\n", i);
				break;
			default:
				g_assert_not_reached();
				break;
			}
			sleep(1);
		}
	}
	g_print("Child pid is %d.\n", (int)child);
	do {
		ret = n_read(fd, &c, 1);
		if (ret == 0) {
			break;
		}
		if ((ret == -1) && (errno != EAGAIN) && (errno != EINTR)) {
			break;
		}
		if (argc < 2) {
			n_write(STDOUT_FILENO, "[", 1);
		}
		n_write(STDOUT_FILENO, &c, 1);
		if (argc < 2) {
			n_write(STDOUT_FILENO, "]", 1);
		}
	} while (TRUE);
	return 0;
}
Exemplo n.º 8
0
pid_t pty_fork(int* ptrfdm, char* slave_name, struct termios* slave_termios, struct winsize* slave_winsize)
{
	int fdm, fds;
	pid_t pid;
	char pts_name[20];

	if ((fdm = pty_open(pts_name)) < 0)
		die("can't open pty %s\n", pts_name);
	if (slave_name)
		strcpy(slave_name, pts_name);

	if ((pid = fork()) < 0)
		die("fork error\n");
	if (!pid) {
		if (setsid() < 0)
			die("setsid error");
		if ((fds = tty_open(fdm, pts_name)) < 0)
			die("can't open slave pty %s\n", pts_name);
		close(fdm);

		if (slave_termios)
			if (tcsetattr(fds, TCSANOW, slave_termios) < 0)
				die("tcsetattr error on slave pty");
		if (slave_winsize)
			if (ioctl(fds, TIOCSWINSZ, slave_winsize) < 0)
				die("TIOCSWINSZ error on slave pty");
		if (dup2(fds, STDIN_FILENO) != STDIN_FILENO)
			die("dup2 error to stdin");
		if (dup2(fds, STDOUT_FILENO) != STDOUT_FILENO)
			die("dup2 error to stdout");
		if (dup2(fds, STDERR_FILENO) != STDERR_FILENO)
			die("dup2 error to stderr");
		if (fds > STDERR_FILENO)
			close(fds);
		return 0;
	}
	*ptrfdm = fdm;
	return pid;
}
pty_pair_ptr 
pty_pair_create (void)
{
  int val;
  static char local_slavename[SLAVE_SIZE];
  pty_pair_ptr ptr = (pty_pair_ptr)cgdb_malloc (sizeof (struct pty_pair));
  if (!ptr)
    return NULL;

  ptr->masterfd = -1;
  ptr->slavefd = -1;
  ptr->slavename[0] = 0;

  val = pty_open (&(ptr->masterfd), &(ptr->slavefd), local_slavename, SLAVE_SIZE, NULL, NULL);
  if (val == -1) {
    logger_write_pos ( logger, __FILE__, __LINE__, "PTY open");
    return NULL;   
  }

  strncpy(ptr->slavename, local_slavename, SLAVE_SIZE);

  return ptr;
}
Exemplo n.º 10
0
/* pty_fork:  Creates a pseudo terminal and then calls fork. In the parent 
 * process, the slave side of the pseudo terminal is closed. In the child 
 * process, the master side of the pseudo terminal is closed and the slave 
 * side is made the controlling terminal. It is duplicated onto standard 
 * input, output and error and then closed. The master side of the pseudo 
 * terminal is stored in masterfd for the parent process. The device name 
 * of the slave side of the pseudo terminal is stored in the buffer pointed 
 * to by slavename which must be able to hold at least 64 bytes.  
 * slavenamesize is the size of the buffer pointed to by slavename. No
 * more than slavenamesize bytes will be written to slavename, including 
 * the terminating nul byte. If slave_termios is not null, it is passed to 
 * tcsetattr with the command TCSANOW to set the terminal attributes of the 
 * slave device. If slave_winsize is not null, it is passed to ioctl with 
 * the command TIOCSWINSZ to set the window size of the slave device. 
 * On success, returns 0 to the child process and returns the process 
 * id of the child process to the parent process. On error, returns -1 with 
 * errno set appropriately.
 */
pid_t pty_fork(int *masterfd, char *slavename, size_t slavenamesize,
        const struct termios * slave_termios,
        const struct winsize * slave_winsize)
{
    int slavefd = 0;
    pid_t pid = 0;

    /*
     ** Note: we don't use forkpty() because it closes the master in the
     ** child process before making the slave the controlling terminal of the
     ** child proces and this can prevent the slave from becoming the
     ** controlling terminal (but I have no idea why).
     */

    if (pty_open(masterfd, &slavefd, slavename, slavenamesize, slave_termios,
                    slave_winsize) == -1)
        return -1;

    switch (pid = fork()) {
        case -1:
            pty_release(slavename);
            close(slavefd);
            close(*masterfd);
            return -1;

        case 0:
        {
            /* Make the slave our controlling tty */
            if (pty_make_controlling_tty(&slavefd, slavename) == -1)
                _exit(EXIT_FAILURE);

            /* Redirect stdin, stdout and stderr from the pseudo tty */

            if (slavefd != STDIN_FILENO && dup2(slavefd, STDIN_FILENO) == -1)
                _exit(EXIT_FAILURE);

            if (slavefd != STDOUT_FILENO && dup2(slavefd, STDOUT_FILENO) == -1)
                _exit(EXIT_FAILURE);

            if (slavefd != STDERR_FILENO && dup2(slavefd, STDERR_FILENO) == -1)
                _exit(EXIT_FAILURE);

            /* Close the extra descriptor for the pseudo tty */

            if (slavefd != STDIN_FILENO && slavefd != STDOUT_FILENO
                    && slavefd != STDERR_FILENO)
                close(slavefd);

            /* Close the master side of the pseudo tty in the child */

            close(*masterfd);

            return 0;
        }

        default:
        {
            /* Close the slave side of the pseudo tty in the parent */

            close(slavefd);

            return pid;
        }
    }
}
Exemplo n.º 11
0
int stdio_wrap(const char *ifname, const char *ofname)
{
	int master __attribute__((cleanup(close_fd_))) = -1,
	    slave __attribute__((cleanup(close_fd_))) = -1,
	    ifd __attribute__((cleanup(close_fd_))) = -1,
	    ofd __attribute__((cleanup(close_fd_))) = -1,
	    listen_sock __attribute__((cleanup(close_fd_))) = -1,
	    sock = -1;
	fd_set rfd_set;
	struct termios termios;
	int nfds = 0;

	if (ifname &&
	    (ifd = mfifo(ifname, O_RDWR)) == -1)
		say_error("can't open `%s': %m", ifname);

	if (ofname &&
	    (ofd = open(ofname, O_WRONLY | O_CREAT | O_TRUNC)) == -1)
		say_error("can't open `%s': %m", ofname);

	if (config.debug_port != 0 &&
	    (listen_sock = listen_port(config.debug_ipaddr, config.debug_port)) == -1)
		say_error("can't create debug socket");

	if (pty_open(&master, &slave) != 0) {
		say_error("can't open pty: %m");

		return -1;
	}

	switch (fork()) {
	case -1:
		say_error("can't fork: %m");

		return -1;
	case 0:
		close(master);

		(void)login_tty(slave);

		(void)setvbuf(stdout, NULL, _IOLBF, 0);
		(void)setvbuf(stderr, NULL, _IONBF, 0);

		return 0;
	default:
		close(slave);

		if (isatty(STDIN_FILENO)) {
			(void)tcgetattr(STDIN_FILENO, &termios);
			cfmakeraw(&termios);
			(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios);
		}

		break;
	}

	FD_ZERO(&rfd_set);
	FD_SET(master, &rfd_set);
	FD_SET(STDIN_FILENO, &rfd_set);
	if (ifd != -1)
		FD_SET(ifd, &rfd_set);
	if (listen_sock != -1)
		FD_SET(listen_sock, &rfd_set);
	nfds = MAX(master, MAX(ifd, listen_sock));

	while (true) {
		fd_set rfd_;
		int n;
		char buf[4096];
		int r;
		int i = -1,
		    o[3] = {-1, -1, -1};

		rfd_ = rfd_set;
		n = select(nfds + 1, &rfd_, NULL, NULL, NULL);
		if (n < 0 && errno != EINTR) {
			say_error("select failed: %m");

			_exit(EXIT_FAILURE);
		}
		for (; n > 0; n--) {
			if (listen_sock != -1 &&
			    FD_ISSET(listen_sock, &rfd_)) {
				if ((sock = accept(listen_sock, NULL, NULL)) == -1) {
					say_error("can't accept connection: %m");

					continue;
				}

				// Force client into `raw' mode
				if (telnet_client_force_raw(sock) != 0) {
					say_error("failed to force client into `raw' mode:"
						  " disconnecting");

					close(sock);

					continue;
				}

				FD_CLR(listen_sock, &rfd_set);
				FD_SET(sock, &rfd_set);
				nfds = MAX(nfds, sock);

				continue;
			} else if (sock != -1 &&
				   FD_ISSET(sock, &rfd_)) {
				i = sock;
				o[0] = master;
			} else if (FD_ISSET(STDIN_FILENO, &rfd_)) {
				i = STDIN_FILENO;
				o[0] = master;
			} else if (ifd != -1 &&
				   FD_ISSET(ifd, &rfd_)) {
				i = ifd;
				o[0] = master;
			} else if (FD_ISSET(master, &rfd_)) {
				i = master;
				o[0] = sock;
				o[1] = STDOUT_FILENO;
				o[2] = ofd;
			} else
				// not reacheable
				assert(0);

			FD_CLR(i, &rfd_);

			if ((r = read(i, buf, sizeof(buf))) <= 0) {
				if (r < 0)
					say_error("couldn't read from %d: %m", i);

				if (i == master)
					_exit(EXIT_FAILURE);

				FD_CLR(i, &rfd_set);

				close(i);

				if (i == sock) {
					sock = -1;
					FD_SET(listen_sock, &rfd_set);
				}

				continue;
			}
			if (buf[r - 1] == '\0')
				// telnet client sent <CR><NUL>
				r -= 1;

			for (unsigned j = 0; j < 3; j++) {
				if (o[j] != -1 &&
				    write(o[j], buf, r) == -1 && errno != EBADF) {
					say_error("couldn't write to %d: %m", o[j]);

					if (o[j] == master)
						_exit(EXIT_FAILURE);

					close(o[j]);

					if (o[j] == sock) {
						sock = -1;
						FD_SET(listen_sock, &rfd_set);
					}
				}
			}
		}
	}

	_exit(EXIT_SUCCESS);
}
Exemplo n.º 12
0
int main (int argc, char **argv)
{
	char call[20];
	char buf[2048];
	int i, k, cnt, digits, letters, invalid, ssid, ssidcnt;
	unsigned int addrlen;
	int fdmaster;
	int identify = TRUE;
	pid_t pid = -1;
	fd_set fds_read;
	int chargc;
	char *chargv[20];
	int envc;
	char *envp[20];
	struct winsize win = {24, 80, 0, 0};
	union
	{
		struct full_sockaddr_ax25 fsax25;
		struct full_sockaddr_rose rose;
	}
	sockaddr;
	char *protocol;
	cfg_t cfg;

	if ((argc > 1) && (strcmp(argv[1], "-n") == 0))
	{
		identify = FALSE;
		--argc;
		++argv;
	}
		
	digits = letters = invalid = ssid = ssidcnt = 0;

	openlog ("fpacshell", LOG_PID, LOG_DAEMON);

	addrlen = sizeof (struct full_sockaddr_ax25);

	memset(&sockaddr.rose, 0x00, sizeof(struct full_sockaddr_rose));

	k = getpeername (0, (struct sockaddr *) &sockaddr, &addrlen);

	if (k == 0)
	{
	switch (sockaddr.fsax25.fsa_ax25.sax25_family)
	{
	case AF_AX25:
		strcpy (call, ax25_ntoa (&sockaddr.fsax25.fsa_ax25.sax25_call));
		protocol = "AX.25";
		paclen = AX_PACLEN;
		break;

	case AF_NETROM:
		strcpy (call, ax25_ntoa (&sockaddr.fsax25.fsa_ax25.sax25_call));
		protocol = "NET/ROM";
		paclen = NETROM_PACLEN;
		break;

	case AF_ROSE:
		strcpy (call, ax25_ntoa (&sockaddr.rose.srose_call));
		protocol = "Rose";
		paclen = ROSE_PACLEN;
		break;

	default:
/*		syslog (LOG_NOTICE, "peer is not an AX.25, NET/ROM or Rose socket\n"); */
		strcpy (call, "UNKNOWN");
		protocol = "SHELL";
		crlf = 0;
		paclen = AX_PACLEN;
		break;
	}
	}
	else
	{
		strcpy (call, "UNKNOWN");
		protocol = "SHELL";
		crlf = 0;
		paclen = AX_PACLEN;
	}

	/* Get FPAC configuration */
	if (cfg_open (&cfg) != 0)
	{
		write_ax25 (MSG_NOCFG, sizeof (MSG_NOCFG));
		syslog (LOG_NOTICE, "FPAC configuration file not found\n");
		sleep (EXITDELAY);
		return 1;
	}

	/* Check for MD password */
	if ((identify) && (!md_check (&cfg)))
		return 2;

	if (argc == 1)
	{
		chargc = 0;
		chargv[chargc++] = user_shell;
	}
	else
	{
/*		int i;*/
		for (i = 0 ; i < (argc-1) ; i++)
		{
			if (i == 20)
				break;
			chargv[i] = argv[i+1];
		}
		chargc = argc-1;
	}
	chargv[chargc] = NULL;

	envc = 0;
	envp[envc] = (char *) malloc (30);
	sprintf (envp[envc++], "AXCALL=%s", call);
	envp[envc] = (char *) malloc (30);
	sprintf (envp[envc++], "PROTOCOL=%s", protocol);
		/* envp[envc] = (char *) malloc (30);
		sprintf (envp[envc++], "TERM=linux"); */
	envp[envc] = NULL;

	fdmaster = pty_open(&pid, &win, chargv, envp);

	if (fdmaster == -1)
		return 4;
		
	if (pid != -1)
	{
		child_pid = 0;
		signal (SIGHUP, signal_handler);
		signal (SIGTERM, signal_handler);
		signal (SIGINT, signal_handler);
		signal (SIGQUIT, signal_handler);

		while (1)
		{
			FD_ZERO (&fds_read);
			FD_SET (0, &fds_read);
			FD_SET (fdmaster, &fds_read);

			k = select (fdmaster + 1, &fds_read, NULL, NULL, NULL);

			if (k > 0)
			{
				if (FD_ISSET (0, &fds_read))
				{
					cnt = read_ax25 (buf, sizeof (buf));
					if (cnt < 0)	/* Connection died */
					{
						break;
					}
					else
						write (fdmaster, buf, cnt);
				}

				if (FD_ISSET (fdmaster, &fds_read))
				{
					cnt = read (fdmaster, buf, sizeof (buf));
					if (cnt < 0)
					{
						break;
					}
					write_ax25 (buf, cnt);
				}
			}
			else if (k < 0 && errno != EINTR)
			{
				break;
			}
		}
	}
	else
	{
		syslog (LOG_ERR, "cannot fork %m, closing connection to %s\n", call);
		write_ax25 (MSG_CANNOTFORK, sizeof (MSG_CANNOTFORK));
		sleep (EXITDELAY);
		return 1;
	}

	sleep (EXITDELAY);

	return 0;
}