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

📄 getty.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vi: set sw=4 ts=4: *//* agetty.c - another getty program for Linux. By W. Z. Venema 1989   Ported to Linux by Peter Orbaek <poe@daimi.aau.dk>   This program is freely distributable. The entire man-page used to   be here. Now read the real man-page agetty.8 instead.   -f option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95      1999-02-22 Arkadiusz Mi秌iewicz <misiek@misiek.eu.org>   - added Native Language Support   1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net>   - enable hardware flow control before displaying /etc/issue   */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/ioctl.h>#include <errno.h>#include <sys/stat.h>#include <sys/signal.h>#include <fcntl.h>#include <stdarg.h>#include <ctype.h>#include <utmp.h>#include <getopt.h>#include <termios.h>#include "busybox.h"#define _PATH_LOGIN     "/bin/login"#ifdef linux#include <sys/param.h>#define USE_SYSLOG#endifextern void updwtmp(const char *filename, const struct utmp *ut); /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */#ifdef	USE_SYSLOG#include <syslog.h>#endif /*  * Some heuristics to find out what environment we are in: if it is not  * System V, assume it is SunOS 4.  */#ifdef LOGIN_PROCESS			/* defined in System V utmp.h */#define	SYSV_STYLE				/* select System V style getty */#endif /*  * Things you may want to modify.  *   * If ISSUE is not defined, agetty will never display the contents of the  * /etc/issue file. You will not want to spit out large "issue" files at the  * wrong baud rate. Relevant for System V only.  *   * You may disagree with the default line-editing etc. characters defined  * below. Note, however, that DEL cannot be used for interrupt generation  * and for line editing at the same time.  */#ifdef	SYSV_STYLE#define	ISSUE "/etc/issue"		/* displayed before the login prompt */#include <sys/utsname.h>#include <time.h>#endif#define LOGIN " login: "		/* login prompt *//* Some shorthands for control characters. */#define CTL(x)		(x ^ 0100)	/* Assumes ASCII dialect */#define	CR		CTL('M')		/* carriage return */#define	NL		CTL('J')		/* line feed */#define	BS		CTL('H')		/* back space */#define	DEL		CTL('?')		/* delete *//* Defaults for line-editing etc. characters; you may want to change this. */#define DEF_ERASE	DEL			/* default erase character */#define DEF_INTR	CTL('C')	/* default interrupt character */#define DEF_QUIT	CTL('\\')	/* default quit char */#define DEF_KILL	CTL('U')	/* default kill char */#define DEF_EOF		CTL('D')	/* default EOF char */#define DEF_EOL		0#define DEF_SWITCH	0			/* default switch char */ /*  * SunOS 4.1.1 termio is broken. We must use the termios stuff instead,  * because the termio -> termios translation does not clear the termios  * CIBAUD bits. Therefore, the tty driver would sometimes report that input  * baud rate != output baud rate. I did not notice that problem with SunOS  * 4.1. We will use termios where available, and termio otherwise.  *//* linux 0.12 termio is broken too, if we use it c_cc[VERASE] isn't set   properly, but all is well if we use termios?! */#ifdef	TCGETS#undef	TCGETA#undef	TCSETA#undef	TCSETAW#define	termio	termios#define	TCGETA	TCGETS#define	TCSETA	TCSETS#define	TCSETAW	TCSETSW#endif /*  * This program tries to not use the standard-i/o library.  This keeps the  * executable small on systems that do not have shared libraries (System V  * Release <3).  */#ifndef BUFSIZ#define	BUFSIZ		1024#endif /*  * When multiple baud rates are specified on the command line, the first one  * we will try is the first one specified.  */#define	FIRST_SPEED	0/* Storage for command-line options. */#define	MAX_SPEED	10			/* max. nr. of baud rates */struct options {	int flags;					/* toggle switches, see below */	int timeout;				/* time-out period */	char *login;				/* login program */	char *tty;					/* name of tty */	char *initstring;			/* modem init string */	char *issue;				/* alternative issue file */	int numspeed;				/* number of baud rates to try */	int speeds[MAX_SPEED];		/* baud rates to be tried */};#define	F_PARSE		(1<<0)		/* process modem status messages */#define	F_ISSUE		(1<<1)		/* display /etc/issue */#define	F_RTSCTS	(1<<2)		/* enable RTS/CTS flow control */#define F_LOCAL		(1<<3)		/* force local */#define F_INITSTRING    (1<<4)	/* initstring is set */#define F_WAITCRLF	(1<<5)		/* wait for CR or LF */#define F_CUSTISSUE	(1<<6)		/* give alternative issue file */#define F_NOPROMPT	(1<<7)		/* don't ask for login name! *//* Storage for things detected while the login name was read. */struct chardata {	int erase;					/* erase character */	int kill;					/* kill character */	int eol;					/* end-of-line character */	int parity;					/* what parity did we see */	int capslock;				/* upper case without lower case */};/* Initial values for the above. */struct chardata init_chardata = {	DEF_ERASE,					/* default erase character */	DEF_KILL,					/* default kill character */	13,							/* default eol char */	0,							/* space parity */	0,							/* no capslock */};struct Speedtab {	long speed;	int code;};static struct Speedtab speedtab[] = {	{50, B50},	{75, B75},	{110, B110},	{134, B134},	{150, B150},	{200, B200},	{300, B300},	{600, B600},	{1200, B1200},	{1800, B1800},	{2400, B2400},	{4800, B4800},	{9600, B9600},#ifdef	B19200	{19200, B19200},#endif#ifdef	B38400	{38400, B38400},#endif#ifdef	EXTA	{19200, EXTA},#endif#ifdef	EXTB	{38400, EXTB},#endif#ifdef B57600	{57600, B57600},#endif#ifdef B115200	{115200, B115200},#endif#ifdef B230400	{230400, B230400},#endif	{0, 0},};static void parse_args(int argc, char **argv, struct options *op);static void parse_speeds(struct options *op, char *arg);static void update_utmp(char *line);static void open_tty(char *tty, struct termio *tp, int local);static void termio_init(struct termio *tp, int speed, struct options *op);static void auto_baud(struct termio *tp);static void do_prompt(struct options *op, struct termio *tp);static void next_speed(struct termio *tp, struct options *op);static char *get_logname(struct options *op, struct chardata *cp,				  struct termio *tp);static void termio_final(struct options *op, struct termio *tp,				  struct chardata *cp);static int caps_lock(const char *s);static int bcode(const char *s);static void error(const char *fmt, ...);/* The following is used for understandable diagnostics. *//* Fake hostname for ut_host specified on command line. */static char *fakehost = NULL;/* ... */#ifdef DEBUGGING#define debug(s) fprintf(dbf,s); fflush(dbf)#define DEBUGTERM "/dev/ttyp0"FILE *dbf;#else#define debug(s)				/* nothing */#endifint getty_main(int argc, char **argv){	char *logname = NULL;		/* login name, given to /bin/login */	struct chardata chardata;	/* set by get_logname() */	struct termio termio;		/* terminal mode bits */	static struct options options = {		F_ISSUE,				/* show /etc/issue (SYSV_STYLE) */		0,						/* no timeout */		_PATH_LOGIN,			/* default login program */		"tty1",					/* default tty line */		"",						/* modem init string */		ISSUE,					/* default issue file */		0,						/* no baud rates known yet */	};#ifdef DEBUGGING	dbf = xfopen(DEBUGTERM, "w");	{		int i;		for (i = 1; i < argc; i++) {			debug(argv[i]);			debug("\n");		}	}#endif	/* Parse command-line arguments. */	parse_args(argc, argv, &options);#ifdef __linux__	setsid();#endif	/* Update the utmp file. */#ifdef	SYSV_STYLE	update_utmp(options.tty);#endif	debug("calling open_tty\n");	/* Open the tty as standard { input, output, error }. */	open_tty(options.tty, &termio, options.flags & F_LOCAL);#ifdef __linux__	{		int iv;		iv = getpid();		if (ioctl(0, TIOCSPGRP, &iv) < 0)			perror_msg("ioctl() TIOCSPGRP call failed");	}#endif	/* Initialize the termio settings (raw mode, eight-bit, blocking i/o). */	debug("calling termio_init\n");	termio_init(&termio, options.speeds[FIRST_SPEED], &options);	/* write the modem init string and DON'T flush the buffers */	if (options.flags & F_INITSTRING) {		debug("writing init string\n");		write(1, options.initstring, strlen(options.initstring));	}	if (!(options.flags & F_LOCAL)) {		/* go to blocking write mode unless -L is specified */		fcntl(1, F_SETFL, fcntl(1, F_GETFL, 0) & ~O_NONBLOCK);	}	/* Optionally detect the baud rate from the modem status message. */	debug("before autobaud\n");	if (options.flags & F_PARSE)		auto_baud(&termio);	/* Set the optional timer. */	if (options.timeout)		(void) alarm((unsigned) options.timeout);	/* optionally wait for CR or LF before writing /etc/issue */	if (options.flags & F_WAITCRLF) {		char ch;		debug("waiting for cr-lf\n");		while (read(0, &ch, 1) == 1) {			ch &= 0x7f;			/* strip "parity bit" */#ifdef DEBUGGING			fprintf(dbf, "read %c\n", ch);#endif			if (ch == '\n' || ch == '\r')				break;		}	}	chardata = init_chardata;	if (!(options.flags & F_NOPROMPT)) {		/* Read the login name. */		debug("reading login name\n");		/* while ((logname = get_logname(&options, &chardata, &termio)) == 0) */		while ((logname = get_logname(&options, &chardata, &termio)) ==			   NULL) next_speed(&termio, &options);	}	/* Disable timer. */	if (options.timeout)		(void) alarm(0);	/* Finalize the termio settings. */	termio_final(&options, &termio, &chardata);	/* Now the newline character should be properly written. */	(void) write(1, "\n", 1);	/* Let the login program take care of password validation. */	(void) execl(options.login, options.login, "--", logname, (char *) 0);	error("%s: can't exec %s: %m", options.tty, options.login);	return (0);					/* quiet GCC */}/* parse-args - parse command-line arguments */static void parse_args(int argc, char **argv, struct options *op){	extern char *optarg;		/* getopt */	extern int optind;			/* getopt */	int c;	while (isascii(c = getopt(argc, argv, "I:LH:f:hil:mt:wn"))) {		switch (c) {		case 'I':			if (!(op->initstring = strdup(optarg))) {				error("can't malloc initstring");				break;			}			{				char ch, *p, *q;				int i;				/* copy optarg into op->initstring decoding \ddd				   octal codes into chars */				q = op->initstring;				p = optarg;				while (*p) {					if (*p == '\\') {	/* know \\ means \ */						p++;						if (*p == '\\') {							ch = '\\';							p++;						} else {	/* handle \000 - \177 */							ch = 0;							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:			show_usage();		}	}	debug("after getopt loop\n");	if (argc < optind + 2)		/* check parameter count */		show_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);	debug("exiting parseargs\n");}/* parse_speeds - parse alternate baud rates */static void parse_speeds(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 */static void update_utmp(char *line){	struct utmp ut;	struct utmp *utp;	time_t t;	int mypid = getpid();#if ! (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1))	struct flock lock;#endif	/*	 * 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();	while ((utp = getutent())		   && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid))	/* nothing */		;	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));	}	/*endutent(); */	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();	{		updwtmp(_PATH_WTMP, &ut);	}}#endif/* open_tty - set up tty as standard { input, output, error } */static void open_tty(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 */

⌨️ 快捷键说明

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