⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tty.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		strlcpy(devnam, p, sizeof(devnam));		if (stat(devnam, &devstat) < 0)			fatal("Couldn't stat default device %s: %m", devnam);	}	/*	 * Parse the tty options file.	 * The per-tty options file should not change	 * ptycommand, pty_socket, notty or devnam.	 * options_for_tty doesn't override options set on the command line,	 * except for some privileged options.	 */	/*/if (!options_for_tty())		exit(EXIT_OPTION_ERROR);*/}/* * tty_check_options - do consistency checks on the options we were given. */voidtty_check_options(){	struct stat statbuf;	int fdflags;	if (demand && notty) {		option_error("demand-dialling is incompatible with notty");		exit(EXIT_OPTION_ERROR);	}	if (demand && connect_script == 0 && ptycommand == NULL	    && pty_socket == NULL) {		option_error("connect script is required for demand-dialling\n");		exit(EXIT_OPTION_ERROR);	}	/* default holdoff to 0 if no connect script has been given */	if (connect_script == 0 && !holdoff_specified)		holdoff = 0;	if (using_pty) {		if (!default_device) {			option_error("%s option precludes specifying device name",				     pty_socket? "socket": notty? "notty": "pty");			exit(EXIT_OPTION_ERROR);		}		if (ptycommand != NULL && notty) {			option_error("pty option is incompatible with notty option");			exit(EXIT_OPTION_ERROR);		}		if (pty_socket != NULL && (ptycommand != NULL || notty)) {			option_error("socket option is incompatible with pty and notty");			exit(EXIT_OPTION_ERROR);		}		default_device = notty;		lockflag = 0;		modem = 0;		if (notty && log_to_fd <= 1)			log_to_fd = -1;	} else {		/*		 * If the user has specified a device which is the same as		 * the one on stdin, pretend they didn't specify any.		 * If the device is already open read/write on stdin,		 * we assume we don't need to lock it, and we can open it		 * as root.		 */		if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode)		    && statbuf.st_rdev == devstat.st_rdev) {			default_device = 1;			fdflags = fcntl(0, F_GETFL);			if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR)				privopen = 1;		}	}	if (default_device)		nodetach = 1;	/*	 * Don't send log messages to the serial port, it tends to	 * confuse the peer. :-)	 */	if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0	    && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev)		log_to_fd = -1;}/* * connect_tty - get the serial port ready to start doing PPP. * That is, open the serial port, set its speed and mode, and run * the connector and/or welcomer. */int connect_tty(){	char *connector;	int fdflags;#ifndef __linux__	struct stat statbuf;#endif	char numbuf[16];	/*	 * Get a pty master/slave pair if the pty, notty, socket,	 * or record options were specified.	 */	strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));	pty_master = -1;	pty_slave = -1;	real_ttyfd = -1;	if (using_pty || record_file != NULL) {		if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) {			error("Couldn't allocate pseudo-tty");			status = EXIT_FATAL_ERROR;			return -1;		}		set_up_tty(pty_slave, 1);	}	/*	 * Lock the device if we've been asked to.	 */	status = EXIT_LOCK_FAILED;	if (lockflag && !privopen) {		if (lock(devnam) < 0)			goto errret;		locked = 1;	}	/*	 * Open the serial device and set it up to be the ppp interface.	 * First we open it in non-blocking mode so we can set the	 * various termios flags appropriately.  If we aren't dialling	 * out and we want to use the modem lines, we reopen it later	 * in order to wait for the carrier detect signal from the modem.	 */	hungup = 0;	got_sigterm = 0;	connector = doing_callback? callback_script: connect_script;	if (devnam[0] != 0) {		for (;;) {			/* If the user specified the device name, become the			   user before opening it. */			int err, prio;			prio = privopen? OPRIO_ROOT: tty_options[0].priority;			if (prio < OPRIO_ROOT && seteuid(uid) == -1) {				error("Unable to drop privileges before opening %s: %m\n",				      devnam);				status = EXIT_OPEN_FAILED;				goto errret;			}			real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);			err = errno;			if (prio < OPRIO_ROOT && seteuid(0) == -1)				fatal("Unable to regain privileges");			if (real_ttyfd >= 0)				break;			errno = err;			if (err != EINTR) {				error("Failed to open %s: %m", devnam);				status = EXIT_OPEN_FAILED;			}			if (!persist || err != EINTR)				goto errret;		}		ttyfd = real_ttyfd;		if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1		    || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)			warn("Couldn't reset non-blocking mode on device: %m");#ifndef __linux__		/*		 * Linux 2.4 and above blocks normal writes to the tty		 * when it is in PPP line discipline, so this isn't needed.		 */		/*		 * Do the equivalent of `mesg n' to stop broadcast messages.		 */		if (fstat(ttyfd, &statbuf) < 0		    || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {			warn("Couldn't restrict write permissions to %s: %m", devnam);		} else			tty_mode = statbuf.st_mode;#endif /* __linux__ */		/*		 * Set line speed, flow control, etc.		 * If we have a non-null connection or initializer script,		 * on most systems we set CLOCAL for now so that we can talk		 * to the modem before carrier comes up.  But this has the		 * side effect that we might miss it if CD drops before we		 * get to clear CLOCAL below.  On systems where we can talk		 * successfully to the modem with CLOCAL clear and CD down,		 * we could clear CLOCAL at this point.		 */		set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0)				   || initializer != NULL));	}	/*	 * If the pty, socket, notty and/or record option was specified,	 * start up the character shunt now.	 */	status = EXIT_PTYCMD_FAILED;	if (ptycommand != NULL) {		if (record_file != NULL) {			int ipipe[2], opipe[2], ok;			if (pipe(ipipe) < 0 || pipe(opipe) < 0)				fatal("Couldn't create pipes for record option: %m");			/* don't leak these to the ptycommand */			(void) fcntl(ipipe[0], F_SETFD, FD_CLOEXEC);			(void) fcntl(opipe[1], F_SETFD, FD_CLOEXEC);			ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0				&& start_charshunt(ipipe[0], opipe[1]);			close(ipipe[0]);			close(ipipe[1]);			close(opipe[0]);			close(opipe[1]);			if (!ok)				goto errret;		} else {			if (device_script(ptycommand, pty_master, pty_master, 1) < 0)				goto errret;		}	} else if (pty_socket != NULL) {		int fd = open_socket(pty_socket);		if (fd < 0)			goto errret;		if (!start_charshunt(fd, fd))			goto errret;		close(fd);	} else if (notty) {		if (!start_charshunt(0, 1))			goto errret;		dup2(fd_devnull, 0);		dup2(fd_devnull, 1);		if (log_to_fd == 1)			log_to_fd = -1;		if (log_to_fd != 2)			dup2(fd_devnull, 2);	} else if (record_file != NULL) {		int fd = dup(ttyfd);		if (!start_charshunt(fd, fd))			goto errret;	}	if (using_pty || record_file != NULL) {		ttyfd = pty_slave;		close(pty_master);		pty_master = -1;	}	/* run connection script */	if ((connector && connector[0]) || initializer) {		if (real_ttyfd != -1) {			/* XXX do this if doing_callback == CALLBACK_DIALIN? */			if (!default_device && modem) {				setdtr(real_ttyfd, 0);	/* in case modem is off hook */				sleep(1);				setdtr(real_ttyfd, 1);			}		}		if (initializer && initializer[0]) {			if (device_script(initializer, ttyfd, ttyfd, 0) < 0) {				error("Initializer script failed");				status = EXIT_INIT_FAILED;				goto errret;			}			if (got_sigterm) {				disconnect_tty();				goto errret;			}			info("Serial port initialized.");		}		if (connector && connector[0]) {			if (device_script(connector, ttyfd, ttyfd, 0) < 0) {				error("Connect script failed");				status = EXIT_CONNECT_FAILED;				goto errret;			}			if (got_sigterm) {				disconnect_tty();				goto errret;			}			info("Serial connection established.");		}		/* set line speed, flow control, etc.;		   clear CLOCAL if modem option */		if (real_ttyfd != -1)			set_up_tty(real_ttyfd, 0);		if (doing_callback == CALLBACK_DIALIN)			connector = NULL;	}	/* reopen tty if necessary to wait for carrier */	if (connector == NULL && modem && devnam[0] != 0) {		int i;		for (;;) {			if ((i = open(devnam, O_RDWR)) >= 0)				break;			if (errno != EINTR) {				error("Failed to reopen %s: %m", devnam);				status = EXIT_OPEN_FAILED;			}			if (!persist || errno != EINTR || hungup || got_sigterm)				goto errret;		}		close(i);	}	slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);	script_setenv("SPEED", numbuf, 0);	/* run welcome script, if any */	if (welcomer && welcomer[0]) {		if (device_script(welcomer, ttyfd, ttyfd, 0) < 0)			warn("Welcome script failed");	}	/*	 * If we are initiating this connection, wait for a short	 * time for something from the peer.  This can avoid bouncing	 * our packets off his tty before he has it set up.	 */	if (connector != NULL || ptycommand != NULL || pty_socket != NULL)		listen_time = connect_delay;	return ttyfd; errret:	if (pty_master >= 0) {		close(pty_master);		pty_master = -1;	}	ttyfd = -1;	if (got_sigterm)		asked_to_quit = 1;	return -1;}void disconnect_tty(){	if (disconnect_script == NULL || hungup)		return;	if (real_ttyfd >= 0)		set_up_tty(real_ttyfd, 1);	if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) {		warn("disconnect script failed");	} else {		info("Serial link disconnected.");	}	stop_charshunt(NULL, 0);}void tty_close_fds(){	if (pty_slave >= 0)		close(pty_slave);	if (real_ttyfd >= 0) {		close(real_ttyfd);		real_ttyfd = -1;	}	/* N.B. ttyfd will == either pty_slave or real_ttyfd */}void cleanup_tty(){	if (real_ttyfd >= 0)		finish_tty();	tty_close_fds();	if (locked) {		unlock();		locked = 0;	}}/* * tty_do_send_config - set transmit-side PPP configuration. * We set the extended transmit ACCM here as well. */voidtty_do_send_config(mtu, accm, pcomp, accomp)    int mtu;    u_int32_t accm;    int pcomp, accomp;{	tty_set_xaccm(xmit_accm);	tty_send_config(mtu, accm, pcomp, accomp);}/* * finish_tty - restore the terminal device to its original settings */static voidfinish_tty(){	/* drop dtr to hang up */	if (!default_device && modem) {		setdtr(real_ttyfd, 0);		/*		 * This sleep is in case the serial port has CLOCAL set by default,		 * and consequently will reassert DTR when we close the device.		 */		sleep(1);	}	restore_tty(real_ttyfd);#ifndef __linux__	if (tty_mode != (mode_t) -1) {		if (fchmod(real_ttyfd, tty_mode) != 0)			error("Couldn't restore tty permissions");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -