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

📄 getty.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 2 页
字号:
		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.	 */#ifdef DEBIAN	{		/* tty to root.dialout 660 */		struct group *gr;		int id;		id = (gr = getgrnam("dialout")) ? gr->gr_gid : 0;		chown(tty, 0, id);		chmod(tty, 0660);		/* vcs,vcsa to root.sys 600 */		if (!strncmp(tty, "tty", 3) && isdigit(tty[3])) {			char *vcs, *vcsa;			if (!(vcs = strdup(tty)))				error("Can't malloc for vcs");			if (!(vcsa = malloc(strlen(tty) + 2)))				error("Can't malloc for vcsa");			strcpy(vcs, "vcs");			strcpy(vcs + 3, tty + 3);			strcpy(vcsa, "vcsa");			strcpy(vcsa + 4, tty + 3);			id = (gr = getgrnam("sys")) ? gr->gr_gid : 0;			chown(vcs, 0, id);			chmod(vcs, 0600);			chown(vcsa, 0, id);			chmod(vcs, 0600);			free(vcs);			free(vcsa);		}	}#else	(void) chown(tty, 0, 0);	/* root, sys */	(void) chmod(tty, 0622);	/* crw--w--w- */	errno = 0;					/* ignore above errors */#endif}/* termio_init - initialize termio settings */static void termio_init(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 */static void auto_baud(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 */static void do_prompt(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) {				case 's':					(void) printf("%s", uts.sysname);					break;				case 'n':					(void) printf("%s", uts.nodename);					break;				case 'r':					(void) printf("%s", uts.release);					break;				case 'v':					(void) printf("%s", uts.version);					break;				case 'm':					(void) printf("%s", uts.machine);					break;				case 'o':				{					char domainname[256];					getdomainname(domainname, sizeof(domainname));					domainname[sizeof(domainname) - 1] = '\0';					printf("%s", domainname);				}					break;				case 'd':				case 't':				{					char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu",						"Fri", "Sat"					};					char *month[] = { "Jan", "Feb", "Mar", "Apr", "May",						"Jun", "Jul", "Aug", "Sep", "Oct",						"Nov", "Dec"					};					time_t now;					struct tm *tm;					(void) time(&now);					tm = localtime(&now);					if (c == 'd')						(void) printf("%s %s %d  %d",									  weekday[tm->tm_wday],									  month[tm->tm_mon], tm->tm_mday,									  tm->tm_year <									  70 ? tm->tm_year +									  2000 : tm->tm_year + 1900);					else						(void) printf("%02d:%02d:%02d", tm->tm_hour,									  tm->tm_min, tm->tm_sec);					break;				}				case 'l':					(void) printf("%s", op->tty);					break;				case 'b':				{					int i;					for (i = 0; speedtab[i].speed; i++) {						if (speedtab[i].code == (tp->c_cflag & CBAUD)) {							printf("%ld", speedtab[i].speed);							break;						}					}					break;				}				case 'u':				case 'U':				{					int users = 0;					struct utmp *ut;					setutent();					while ((ut = getutent()))						if (ut->ut_type == USER_PROCESS)							users++;					endutent();					printf("%d ", users);					if (c == 'U')						printf((users == 1) ? "user" : "users");					break;				}				default:					(void) putchar(c);				}			} else				(void) putchar(c);		}		fflush(stdout);		tp->c_oflag = oflag;	/* restore settings */		(void) ioctl(0, TCSETAW, tp);	/* wait till output is gone */		(void) fclose(fd);	}#endif#ifdef __linux__	{		char hn[MAXHOSTNAMELEN + 1];		(void) gethostname(hn, MAXHOSTNAMELEN);		write(1, hn, strlen(hn));	}#endif	(void) write(1, LOGIN, sizeof(LOGIN) - 1);	/* always show login prompt */}/* next_speed - select next baud rate */static void next_speed(struct termio *tp, struct options *op){	static int baud_index = FIRST_SPEED;	/* current speed index */	baud_index = (baud_index + 1) % op->numspeed;	tp->c_cflag &= ~CBAUD;	tp->c_cflag |= op->speeds[baud_index];	(void) ioctl(0, TCSETA, tp);}/* get_logname - get user name, establish parity, speed, erase, kill, eol *//* return NULL on failure, logname on success */static char *get_logname(struct options *op, struct chardata *cp, struct termio *tp){	static char logname[BUFSIZ];	char *bp;	char c;						/* input character, full eight bits */	char ascval;				/* low 7 bits of input character */	int bits;					/* # of "1" bits per character */	int mask;					/* mask with 1 bit up */	static char *erase[] = {	/* backspace-space-backspace */		"\010\040\010",			/* space parity */		"\010\040\010",			/* odd parity */		"\210\240\210",			/* even parity */		"\210\240\210",			/* no parity */	};	/* Initialize kill, erase, parity etc. (also after switching speeds). */	*cp = init_chardata;	/* Flush pending input (esp. after parsing or switching the baud rate). */	(void) sleep(1);	(void) ioctl(0, TCFLSH, TCIFLUSH);	/* Prompt for and read a login name. */	for (*logname = 0; *logname == 0; /* void */ ) {		/* Write issue file and prompt, with "parity" bit == 0. */		do_prompt(op, tp);		/* Read name, watch for break, parity, erase, kill, end-of-line. */		for (bp = logname, cp->eol = 0; cp->eol == 0; /* void */ ) {			/* Do not report trivial EINTR/EIO errors. */			if (read(0, &c, 1) < 1) {				if (errno == EINTR || errno == EIO)					exit(0);				error("%s: read: %m", op->tty);			}			/* Do BREAK handling elsewhere. */			if ((c == 0) && op->numspeed > 1)				/* return (0); */				return NULL;			/* Do parity bit handling. */			if (c != (ascval = (c & 0177))) {	/* "parity" bit on ? */				for (bits = 1, mask = 1; mask & 0177; mask <<= 1)					if (mask & ascval)						bits++;	/* count "1" bits */				cp->parity |= ((bits & 1) ? 1 : 2);			}			/* Do erase, kill and end-of-line processing. */			switch (ascval) {			case CR:			case NL:				*bp = 0;		/* terminate logname */				cp->eol = ascval;	/* set end-of-line char */				break;			case BS:			case DEL:			case '#':				cp->erase = ascval;	/* set erase character */				if (bp > logname) {					(void) write(1, erase[cp->parity], 3);					bp--;				}				break;			case CTL('U'):			case '@':				cp->kill = ascval;	/* set kill character */				while (bp > logname) {					(void) write(1, erase[cp->parity], 3);					bp--;				}				break;			case CTL('D'):				exit(0);			default:				if (!isascii(ascval) || !isprint(ascval)) {					/* ignore garbage characters */ ;				} else if (bp - logname >= sizeof(logname) - 1) {					error("%s: input overrun", op->tty);				} else {					(void) write(1, &c, 1);	/* echo the character */					*bp++ = ascval;	/* and store it */				}				break;			}		}	}	/* Handle names with upper case and no lower case. */	if ((cp->capslock = caps_lock(logname))) {		for (bp = logname; *bp; bp++)			if (isupper(*bp))				*bp = tolower(*bp);	/* map name to lower case */	}	return (logname);}/* termio_final - set the final tty mode bits */static void termio_final(struct options *op, struct termio *tp, struct chardata *cp){	/* General terminal-independent stuff. */	tp->c_iflag |= IXON | IXOFF;	/* 2-way flow control */	tp->c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE;	/* no longer| ECHOCTL | ECHOPRT */	tp->c_oflag |= OPOST;	/* tp->c_cflag = 0; */	tp->c_cc[VINTR] = DEF_INTR;	/* default interrupt */	tp->c_cc[VQUIT] = DEF_QUIT;	/* default quit */	tp->c_cc[VEOF] = DEF_EOF;	/* default EOF character */	tp->c_cc[VEOL] = DEF_EOL;#ifdef __linux__	tp->c_cc[VSWTC] = DEF_SWITCH;	/* default switch character */#else	tp->c_cc[VSWTCH] = DEF_SWITCH;	/* default switch character */#endif	/* Account for special characters seen in input. */	if (cp->eol == CR) {		tp->c_iflag |= ICRNL;	/* map CR in input to NL */		tp->c_oflag |= ONLCR;	/* map NL in output to CR-NL */	}	tp->c_cc[VERASE] = cp->erase;	/* set erase character */	tp->c_cc[VKILL] = cp->kill;	/* set kill character */	/* Account for the presence or absence of parity bits in input. */	switch (cp->parity) {	case 0:					/* space (always 0) parity */		break;	case 1:					/* odd parity */		tp->c_cflag |= PARODD;		/* FALLTHROUGH */	case 2:					/* even parity */		tp->c_cflag |= PARENB;		tp->c_iflag |= INPCK | ISTRIP;		/* FALLTHROUGH */	case (1 | 2):				/* no parity bit */		tp->c_cflag &= ~CSIZE;		tp->c_cflag |= CS7;		break;	}	/* Account for upper case without lower case. */	if (cp->capslock) {		tp->c_iflag |= IUCLC;		tp->c_lflag |= XCASE;		tp->c_oflag |= OLCUC;	}	/* Optionally enable hardware flow control */#ifdef	CRTSCTS	if (op->flags & F_RTSCTS)		tp->c_cflag |= CRTSCTS;#endif	/* Finally, make the new settings effective */	if (ioctl(0, TCSETA, tp) < 0)		error("%s: ioctl: TCSETA: %m", op->tty);}/* caps_lock - string contains upper case without lower case *//* returns 1 if true, 0 if false */static int caps_lock(const char *s){	int capslock;	for (capslock = 0; *s; s++) {		if (islower(*s))			return (0);		if (capslock == 0)			capslock = isupper(*s);	}	return (capslock);}/* bcode - convert speed string to speed code; return 0 on failure */static int bcode(const char *s){	struct Speedtab *sp;	long speed = atol(s);	for (sp = speedtab; sp->speed; sp++)		if (sp->speed == speed)			return (sp->code);	return (0);}/* error - report errors to console or syslog; only understands %s and %m */#define	str2cpy(b,s1,s2)	strcat(strcpy(b,s1),s2)/* * output error messages */static void error(const char *fmt, ...){	va_list va_alist;	char buf[256], *bp;#ifndef	USE_SYSLOG	int fd;#endif#ifdef USE_SYSLOG	buf[0] = '\0';	bp = buf;#else	strncpy(buf, applet_name, 256);	strncat(buf, ": ", 256);	buf[255] = 0;	bp = buf + strlen(buf);#endif	va_start(va_alist, fmt);	vsnprintf(bp, 256 - strlen(buf), fmt, va_alist);	buf[255] = 0;	va_end(va_alist);#ifdef	USE_SYSLOG	syslog_msg(LOG_AUTH, LOG_ERR, buf);#else	strncat(bp, "\r\n", 256 - strlen(buf));	buf[255] = 0;	if ((fd = open("/dev/console", 1)) >= 0) {		write(fd, buf, strlen(buf));		close(fd);	}#endif	(void) sleep((unsigned) 10);	/* be kind to init(8) */	exit(1);}

⌨️ 快捷键说明

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