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

📄 agetty.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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@pld.ORG.PL>   - added Native Language Support   1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net>   - enable hardware flow control before displaying /etc/issue   */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/ioctl.h>#include <termio.h>#include <signal.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdarg.h>#include <ctype.h>#include <utmp.h>#include <getopt.h>#include <time.h>#include <sys/file.h>#include "xstrncpy.h"#include "nls.h"#ifdef __linux__#include "pathnames.h"#include <sys/param.h>#define USE_SYSLOG#endif /* 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 },};#define P_(s) sint main P_((int argc, char **argv));void parse_args P_((int argc, char **argv, struct options *op));void parse_speeds P_((struct options *op, char *arg));void update_utmp P_((char *line));void open_tty P_((char *tty, struct termio *tp, int local));void termio_init P_((struct termio *tp, int speed, struct options *op));void auto_baud P_((struct termio *tp));void do_prompt P_((struct options *op, struct termio *tp));void next_speed P_((struct termio *tp, struct options *op));char *get_logname P_((struct options *op, struct chardata *cp, struct termio *tp));void termio_final P_((struct options *op, struct termio *tp, struct chardata *cp));int caps_lock P_((char *s));int bcode P_((char *s));void usage P_((void));void error P_((const char *, ...));#undef P_/* The following is used for understandable diagnostics. */char *progname;/* Fake hostname for ut_host specified on command line. */char *fakehost = NULL;/* ... */#ifdef DEBUGGING#define debug(s) fprintf(dbf,s); fflush(dbf)FILE *dbf;#else#define debug(s) /* nothing */#endifintmain(argc, argv)     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 */    };       setlocale(LC_ALL, "");       bindtextdomain(PACKAGE, LOCALEDIR);       textdomain(PACKAGE);        /* The BSD-style init command passes us a useless process name. */#ifdef	SYSV_STYLE       {	       char *ptr;	       progname = argv[0];	       if ((ptr = strrchr(argv[0], '/')))		       progname = ++ptr;       }#else       progname = "agetty";#endif#ifdef DEBUGGING	dbf = fopen("/dev/ttyp0", "w");	{	int i;			for(i = 1; i < argc; i++) {			debug(argv[i]);		}	}#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();		(void) ioctl(0, TIOCSPGRP, &iv);	}#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)	  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);    exit(0);  /* quiet GCC */}/* parse-args - parse command-line arguments */voidparse_args(argc, argv, op)     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 = malloc(strlen(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;

⌨️ 快捷键说明

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