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

📄 agetty.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
			    for (i = 1; i <= 3; i++) {				if (*p >= '0' && *p <= '7') {				    ch <<= 3;				    ch += *p - '0';				    p++;				} else 				  break;			    }			}			*q++ = ch;		    } else {			*q++ = *p++;		    }		}		*q = '\0';	    }	    op->flags |= F_INITSTRING;	    break;	case 'L':				/* force local */ 	    op->flags |= F_LOCAL; 	    break;	case 'H':                               /* fake login host */	    fakehost = optarg;	    break;	case 'f':				/* custom issue file */	    op->flags |= F_CUSTISSUE;	    op->issue = optarg;	    break;	case 'h':				/* enable h/w flow control */	    op->flags |= F_RTSCTS;	    break;	case 'i':				/* do not show /etc/issue */	    op->flags &= ~F_ISSUE;	    break;	case 'l':	    op->login = optarg;			/* non-default login program */	    break;	case 'm':				/* parse modem status message */	    op->flags |= F_PARSE;	    break;	case 'n':	    op->flags |= F_NOPROMPT;	    break;	case 't':				/* time out */	    if ((op->timeout = atoi(optarg)) <= 0)		error(_("bad timeout value: %s"), optarg);	    break;	case 'w':	    op->flags |= F_WAITCRLF;	    break;	default:	    usage();	}    } 	debug(_("after getopt loop\n"));    if (argc < optind + 2)			/* check parameter count */	usage();    /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */    if('0' <= argv[optind][0] && argv[optind][0] <= '9') {	/* a number first, assume it's a speed (BSD style) */	parse_speeds(op, argv[optind++]);	/* baud rate(s) */	op->tty = argv[optind];			/* tty name */    } else {	op->tty = argv[optind++];		/* tty name */	parse_speeds(op, argv[optind]);		/* baud rate(s) */    }    optind++;    if (argc > optind && argv[optind])	setenv ("TERM", argv[optind], 1);#ifdef DO_DEVFS_FIDDLING    /*     * some devfs junk, following Goswin Brederlow:     *   turn ttyS<n> into tts/<n>     *   turn tty<n> into vc/<n>     */    if (op->tty && strlen(op->tty) < 90) {	    char dev_name[100];	    struct stat st;	    if (strncmp(op->tty, "ttyS", 4) == 0) {		    strcpy(dev_name, "/dev/");		    strcat(dev_name, op->tty);		    if (stat(dev_name, &st) < 0) {			    strcpy(dev_name, "/dev/tts/");			    strcat(dev_name, op->tty + 4);			    if (stat(dev_name, &st) == 0)				    op->tty = strdup(dev_name + 5);		    }	    } else if (strncmp(op->tty, "tty", 3) == 0) {		    strcpy(dev_name, "/dev/");		    strncat(dev_name, op->tty, 90);		    if (stat(dev_name, &st) < 0) {			    strcpy(dev_name, "/dev/vc/");			    strcat(dev_name, op->tty + 3);			    if (stat(dev_name, &st) == 0)				    op->tty = strdup(dev_name + 5);		    }	    }    }#endif    debug(_("exiting parseargs\n"));}/* parse_speeds - parse alternate baud rates */voidparse_speeds(op, arg)     struct options *op;     char   *arg;{    char   *cp;	debug(_("entered parse_speeds\n"));    for (cp = strtok(arg, ","); cp != 0; cp = strtok((char *) 0, ",")) {	if ((op->speeds[op->numspeed++] = bcode(cp)) <= 0)	    error(_("bad speed: %s"), cp);	if (op->numspeed >= MAX_SPEED)	    error(_("too many alternate speeds"));    }    debug(_("exiting parsespeeds\n"));}#ifdef	SYSV_STYLE/* update_utmp - update our utmp entry */voidupdate_utmp(line)     char   *line;{    struct  utmp ut;    time_t  t;    int     mypid = getpid();    struct  utmp *utp;    /*     * The utmp file holds miscellaneous information about things started by     * /sbin/init and other system-related events. Our purpose is to update     * the utmp entry for the current process, in particular the process type     * and the tty line we are listening to. Return successfully only if the     * utmp file can be opened for update, and if we are able to find our     * entry in the utmp file.     */    utmpname(_PATH_UTMP);    setutent();    /* Find mypid in utmp. Earlier code here tested only       utp->ut_type != INIT_PROCESS, so maybe the >= here should be >.       The present code is taken from login.c, so if this is changed,       maybe login has to be changed as well. */    while ((utp = getutent()))	    if (utp->ut_pid == mypid		&& utp->ut_type >= INIT_PROCESS		&& utp->ut_type <= DEAD_PROCESS)		    break;    if (utp) {	memcpy(&ut, utp, sizeof(ut));    } else {	/* some inits don't initialize utmp... */	memset(&ut, 0, sizeof(ut));	strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));    }	    strncpy(ut.ut_user, "LOGIN", sizeof(ut.ut_user));    strncpy(ut.ut_line, line, sizeof(ut.ut_line));    if (fakehost)	strncpy(ut.ut_host, fakehost, sizeof(ut.ut_host));    time(&t);    ut.ut_time = t;    ut.ut_type = LOGIN_PROCESS;    ut.ut_pid = mypid;    pututline(&ut);    endutent();    {#ifdef HAVE_updwtmp	updwtmp(_PATH_WTMP, &ut);#else	int ut_fd;	int lf;	if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {	    flock(lf, LOCK_EX);	    if ((ut_fd = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {		write(ut_fd, &ut, sizeof(ut));		close(ut_fd);	    }	    flock(lf, LOCK_UN);	    close(lf);	}#endif    }}#endif/* open_tty - set up tty as standard { input, output, error } */voidopen_tty(tty, tp, local)     char   *tty;     struct termio *tp;     int    local;{    /* Get rid of the present standard { output, error} if any. */    (void) close(1);    (void) close(2);    errno = 0;					/* ignore above errors */    /* Set up new standard input, unless we are given an already opened port. */    if (strcmp(tty, "-")) {	struct stat st;	/* Sanity checks... */	if (chdir("/dev"))	    error(_("/dev: chdir() failed: %m"));	if (stat(tty, &st) < 0)	    error("/dev/%s: %m", tty);	if ((st.st_mode & S_IFMT) != S_IFCHR)	    error(_("/dev/%s: not a character device"), tty);	/* Open the tty as standard input. */	(void) close(0);	errno = 0;				/* ignore close(2) errors */	debug(_("open(2)\n"));	if (open(tty, O_RDWR|O_NONBLOCK, 0) != 0)	    error(_("/dev/%s: cannot open as standard input: %m"), tty);    } else {	/*	 * Standard input should already be connected to an open port. Make	 * sure it is open for read/write.	 */	if ((fcntl(0, F_GETFL, 0) & O_RDWR) != O_RDWR)	    error(_("%s: not open for read/write"), tty);    }    /* Set up standard output and standard error file descriptors. */    debug(_("duping\n"));    if (dup(0) != 1 || dup(0) != 2)		/* set up stdout and stderr */	error(_("%s: dup problem: %m"), tty);	/* we have a problem */    /*     * The following ioctl will fail if stdin is not a tty, but also when     * there is noise on the modem control lines. In the latter case, the     * common course of action is (1) fix your cables (2) give the modem more     * time to properly reset after hanging up. SunOS users can achieve (2)     * by patching the SunOS kernel variable "zsadtrlow" to a larger value;     * 5 seconds seems to be a good value.     */    if (ioctl(0, TCGETA, tp) < 0)	error("%s: ioctl: %m", tty);    /*     * It seems to be a terminal. Set proper protections and ownership. Mode     * 0622 is suitable for SYSV <4 because /bin/login does not change     * protections. SunOS 4 login will change the protections to 0620 (write     * access for group tty) after the login has succeeded.     */    /*     * Let us use 0600 for Linux for the period between getty and login     */    (void) chown(tty, 0, 0);			/* root, sys */    (void) chmod(tty, 0600);			/* 0622: crw--w--w- */    errno = 0;					/* ignore above errors */}/* termio_init - initialize termio settings */char gbuf[1024];char area[1024];voidtermio_init(tp, speed, op)     struct termio *tp;     int     speed;     struct options *op;{    /*     * Initial termio settings: 8-bit characters, raw-mode, blocking i/o.     * Special characters are set after we have read the login name; all     * reads will be done in raw mode anyway. Errors will be dealt with     * lateron.     */#ifdef __linux__    /* flush input and output queues, important for modems! */    (void) ioctl(0, TCFLSH, TCIOFLUSH);#endif    tp->c_cflag = CS8 | HUPCL | CREAD | speed;    if (op->flags & F_LOCAL) {	tp->c_cflag |= CLOCAL;    }    tp->c_iflag = tp->c_lflag = tp->c_oflag = tp->c_line = 0;    tp->c_cc[VMIN] = 1;    tp->c_cc[VTIME] = 0;    /* Optionally enable hardware flow control */#ifdef	CRTSCTS    if (op->flags & F_RTSCTS)	tp->c_cflag |= CRTSCTS;#endif    (void) ioctl(0, TCSETA, tp);    /* go to blocking input even in local mode */    fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NONBLOCK);    debug(_("term_io 2\n"));}/* auto_baud - extract baud rate from modem status message */voidauto_baud(tp)     struct termio *tp;{    int     speed;    int     vmin;    unsigned iflag;    char    buf[BUFSIZ];    char   *bp;    int     nread;    /*     * This works only if the modem produces its status code AFTER raising     * the DCD line, and if the computer is fast enough to set the proper     * baud rate before the message has gone by. We expect a message of the     * following format:     *      * <junk><number><junk>     *      * The number is interpreted as the baud rate of the incoming call. If the     * modem does not tell us the baud rate within one second, we will keep     * using the current baud rate. It is advisable to enable BREAK     * processing (comma-separated list of baud rates) if the processing of     * modem status messages is enabled.     */    /*     * Use 7-bit characters, don't block if input queue is empty. Errors will     * be dealt with lateron.     */    iflag = tp->c_iflag;    tp->c_iflag |= ISTRIP;			/* enable 8th-bit stripping */    vmin = tp->c_cc[VMIN];    tp->c_cc[VMIN] = 0;				/* don't block if queue empty */    (void) ioctl(0, TCSETA, tp);    /*     * Wait for a while, then read everything the modem has said so far and     * try to extract the speed of the dial-in call.     */    (void) sleep(1);    if ((nread = read(0, buf, sizeof(buf) - 1)) > 0) {	buf[nread] = '\0';	for (bp = buf; bp < buf + nread; bp++) {	    if (isascii(*bp) && isdigit(*bp)) {		if ((speed = bcode(bp))) {		    tp->c_cflag &= ~CBAUD;		    tp->c_cflag |= speed;		}		break;	    }	}    }    /* Restore terminal settings. Errors will be dealt with lateron. */    tp->c_iflag = iflag;    tp->c_cc[VMIN] = vmin;    (void) ioctl(0, TCSETA, tp);}/* do_prompt - show login prompt, optionally preceded by /etc/issue contents */voiddo_prompt(op, tp)     struct options *op;     struct termio *tp;{#ifdef	ISSUE    FILE    *fd;    int     oflag;    int     c;    struct utsname uts;    (void) uname(&uts);#endif    (void) write(1, "\r\n", 2);			/* start a new line */#ifdef	ISSUE					/* optional: show /etc/issue */    if ((op->flags & F_ISSUE) && (fd = fopen(op->issue, "r"))) {	oflag = tp->c_oflag;			/* save current setting */	tp->c_oflag |= (ONLCR | OPOST);		/* map NL in output to CR-NL */	(void) ioctl(0, TCSETAW, tp);	while ((c = getc(fd)) != EOF)	{	    if (c == '\\')	      {		c = getc(fd);				switch (c)		  {

⌨️ 快捷键说明

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