[PATCH 8/8] Four options more and code cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Added four options to be abel to delay agetty after start,
to change the working directory, to change the root directory,
and to modified scheduling priority.  Do some code cleanup,
e.g. use only one termios structure.

Signed-off-by: Werner Fink <werner@xxxxxxx>
---
 term-utils/agetty.8 |   14 ++++
 term-utils/agetty.c |  172 +++++++++++++++++++++++++++++++--------------------
 2 files changed, 119 insertions(+), 67 deletions(-)

diff --git a/term-utils/agetty.8 b/term-utils/agetty.8
index 8b29ad0..7529103 100644
--- a/term-utils/agetty.8
+++ b/term-utils/agetty.8
@@ -99,6 +99,12 @@ with \fB\-\-autologin\fP to save memory by lazily spawning shells.
 Don't reset terminal cflags (control modes). See \fItermios(3)\fP for more
 details.
 .TP
+\-C, \-\-chdir \fIdirectory\fP
+Change working \fIdirectory\fP before executing the login program.
+.TP
+\d, \-\-delay  \fIseconds\fP
+Sleep this many \fIseconds\fP after startup of agetty.
+.TP
 \-f, \-\-issue\-file \fIissue_file\fP
 Display the contents of \fIissue_file\fP instead of \fI/etc/issue\fP.
 This allows custom messages to be displayed on different terminals.
@@ -162,12 +168,20 @@ space parity, 7 bit characters, and ASCII CR (13) end-of-line character.
 Beware that the program that \fBagetty\fR starts (usually /bin/login)
 is run as root.
 .TP
+\-N, \-\-nice \fIlevel\fP
+Change the priority by calling \fBnice(2)\fP with specified \fIlevel\fP
+before calling the login progam.
+.TP
 \-o, \-\-login\-options \fI"login_options"\fP
 Options  that  are passed to the login program.  \\u is replaced
 by the login name. Defaults to "\-\- \\u", which is suitable for
 \fB/bin/login\fP.  Please read the SECURITY NOTICE below if
 you want to use this.
 .TP
+\-r, \-\-chroot \fIdirectory\fP
+Call chroot() with \fIdirectory\fP name before calling the
+login program.
+.TP
 \-s, \-\-keep\-baud
 Try to keep the existing baud rate. The baud rates from
 the command line are used when agetty receives a BREAK character.
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index 00bfda2..5f2fc9f 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -134,6 +134,8 @@ struct options {
 	int flags;			/* toggle switches, see below */
 	int timeout;			/* time-out period */
 	char *autolog;			/* login the user automatically */
+	char *chdir;			/* Chdir before the login */
+	char *chroot;			/* Chroot before the login */
 	char *login;			/* login program */
 	char *logopt;			/* options for login program */
 	char *tty;			/* name of tty */
@@ -141,6 +143,8 @@ struct options {
 	char *term;			/* terminal type */
 	char *initstring;		/* modem init string */
 	char *issue;			/* alternative issue file */
+	int delay;			/* Sleep seconds before prompt */
+	int nice;			/* Run login with this priority */
 	int numspeed;			/* number of baud rates to try */
 	speed_t speeds[MAX_SPEED];	/* baud rates to be tried */
 };
@@ -235,7 +239,7 @@ static void parse_speeds(struct options *op, char *arg);
 static void update_utmp(struct options *op);
 static void open_tty(char *tty, struct termios *tp, struct options *op);
 static void termio_init(struct options *op, struct termios *tp);
-static void reset_vc (const struct options *op);
+static void reset_vc (const struct options *op, struct termios *tp);
 static void auto_baud(struct termios *tp);
 static void output_special_char (unsigned char c, struct options *op, struct termios *tp);
 static void do_prompt(struct options *op, struct termios *tp);
@@ -307,6 +311,9 @@ int main(int argc, char **argv)
 	update_utmp(&options);
 #endif
 
+	if (options.delay)
+		sleep(options.delay);
+
 	debug("calling open_tty\n");
 
 	/* Open the tty as standard { input, output, error }. */
@@ -368,7 +375,7 @@ int main(int argc, char **argv)
 			/* Do the auto login */
 			debug("doing auto login\n");
 			do_prompt(&options, &termios);
-			printf ("%s%s (automatic login)\n", LOGIN, options.autolog);
+			printf ("%s%s (automatic login)\r\n", LOGIN, options.autolog);
 			logname = options.autolog;
 			options.logopt = "-f \\u";
 		} else {
@@ -390,7 +397,7 @@ int main(int argc, char **argv)
 		termio_final(&options, &termios, &chardata);
 
 		/* Now the newline character should be properly written. */
-		safe_write(STDOUT_FILENO, "\r\n", 1);
+		safe_write(STDOUT_FILENO, "\r\n", 2);
 	}
 
 	sigaction (SIGQUIT, &sa_quit, NULL);
@@ -404,6 +411,13 @@ int main(int argc, char **argv)
 	mkarray(logarr, logcmd);
 	replacename(logarr, logname);
 
+	if (options.chroot)
+		chroot(options.chroot);
+	if (options.chdir)
+		chdir(options.chdir);
+	if (options.nice)
+		nice(options.nice);
+
 	/* Let the login program take care of password validation. */
 	execv(options.login, logarr);
 	warn(_("%s: can't exec %s: %m"), options.tty, options.login);
@@ -434,6 +448,8 @@ static void parse_args(int argc, char **argv, struct options *op)
 		{  "8bits",	     no_argument,	 0,  '8'  },
 		{  "autologin",      required_argument,  0,  'a'  },
 		{  "noreset",	     no_argument,	 0,  'c'  },
+		{  "chdir",          required_argument,  0,  'C'  },
+		{  "delay",          required_argument,  0,  'd'  },
 		{  "issue-file",     required_argument,  0,  'f'  },
 		{  "flow-control",   no_argument,	 0,  'h'  },
 		{  "host",	     required_argument,  0,  'H'  },
@@ -445,9 +461,11 @@ static void parse_args(int argc, char **argv, struct options *op)
 		{  "local-line",     no_argument,	 0,  'L'  },
 		{  "extract-baud",   no_argument,	 0,  'm'  },
 		{  "skip-login",     no_argument,	 0,  'n'  },
+		{  "nice",           required_argument,  0,  'N'  },
 		{  "login-options",  required_argument,  0,  'o'  },
 		{  "loginopts",      required_argument,  0,  'o'  },  /* compat option */
 		{  "logopts",        required_argument,  0,  'o'  },  /* compat option */
+		{  "chroot",         required_argument,  0,  'r'  },
 		{  "keep-baud",      no_argument,	 0,  's'  },
 		{  "timeout",	     required_argument,  0,  't'  },
 		{  "detect-case",    no_argument,	 0,  'U'  },
@@ -457,7 +475,7 @@ static void parse_args(int argc, char **argv, struct options *op)
 		{ NULL, 0, 0, 0 }
 	};
 
-	while ((c = getopt_long(argc, argv, "8a:cf:hH:iI:l:Lmno:st:Uw", longopts,
+	while ((c = getopt_long(argc, argv, "8a:cC:d:f:hH:iI:l:LmNno:r:st:Uw", longopts,
 			    &index)) != -1) {
 		switch (c) {
 		case 0:
@@ -472,6 +490,12 @@ static void parse_args(int argc, char **argv, struct options *op)
 		case 'c':
 			op->flags |= F_KEEPCFLAGS;
 			break;
+		case 'C':
+			op->chdir = optarg;
+			break;
+		case 'd':
+			op->delay = atoi(optarg);
+			break;
 		case 'f':
 			op->flags |= F_CUSTISSUE;
 			op->issue = optarg;
@@ -501,9 +525,15 @@ static void parse_args(int argc, char **argv, struct options *op)
 		case 'n':
 			op->flags |= F_NOPROMPT;
 			break;
+		case 'N':
+			op->nice = atoi(optarg);
+			break;
 		case 'o':
 			op->logopt = optarg;
 			break;
+		case 'r':
+			op->chroot = optarg;
+			break;
 		case 's':
 			op->flags |= F_KEEPSPEED;
 			break;
@@ -782,7 +812,7 @@ static void open_tty(char *tty, struct termios *tp, struct options *op)
 		if (open(buf, O_RDWR|O_NOCTTY|O_NONBLOCK, 0) != 0)
 			error(_("/dev/%s: cannot open as standard input: %m"), tty);
 		if (((tid = tcgetsid(0)) < 0) || (pid != tid)) {
-			if (ioctl (0, TIOCSCTTY, 1) == -1)
+			if (ioctl (STDIN_FILENO, TIOCSCTTY, 1) == -1)
 				error("/dev/%s: cannot get controlling tty: %m", tty);
 		}
 
@@ -823,6 +853,7 @@ static void open_tty(char *tty, struct termios *tp, struct options *op)
 	 * "zsadtrlow" to a larger value; 5 seconds seems to be a good value.
 	 * http://www.sunmanagers.org/archives/1993/0574.html
 	 */
+	memset(tp, 0, sizeof(struct termios));
 	if (tcgetattr(STDIN_FILENO, tp) < 0)
 		error("%s: tcgetattr: %m", tty);
 
@@ -871,8 +902,11 @@ static void termio_init(struct options *op, struct termios *tp)
 		setlocale(LC_CTYPE, "POSIX");
 		op->flags &= ~F_UTF8;
 #endif
-		reset_vc(op);
-		op->flags |= F_EIGHTBITS;
+		reset_vc(op, tp);
+
+		if ((tp->c_cflag & (CS8|PARODD|PARENB)) == CS8)
+			op->flags |= F_EIGHTBITS;
+
 		if ((op->flags & F_NOCLEAR) == 0) {
 			/*
 			 * Do not write a full reset (ESC c) because this destroys
@@ -883,7 +917,7 @@ static void termio_init(struct options *op, struct termios *tp)
 			 * erase everything below the cursor (ESC [ J), and set the
 			 * scrolling region to the full window (ESC [ r)
 			 */
-			safe_write(0, "\033[r\033[H\033[J", 9);
+			safe_write(STDIN_FILENO, "\033[r\033[H\033[J", 9);
 		}
 		return;
 	}
@@ -960,71 +994,67 @@ static void termio_init(struct options *op, struct termios *tp)
 }
 
 /* Reset virtual console on stdin to its defaults */
-static void reset_vc(const struct options *op)
+static void reset_vc(const struct options *op, struct termios *tp)
 {
-	struct termios termios;
-	/*
-	 * The above reset only puts the output things into a sane state.
-	 * The input state is not reset.
-	 */
-	memset (&termios, 0, sizeof termios);
-	if (tcgetattr (0, &termios))
-		warn ("tcgetattr problem: %m");
-
 	/* Use defaults of <sys/ttydefaults.h> for base settings */
-	termios.c_iflag |= TTYDEF_IFLAG;
-	termios.c_oflag |= TTYDEF_OFLAG;
-	termios.c_lflag |= TTYDEF_LFLAG;
+	tp->c_iflag |= TTYDEF_IFLAG;
+	tp->c_oflag |= TTYDEF_OFLAG;
+	tp->c_lflag |= TTYDEF_LFLAG;
+
+	if ((op->flags & F_KEEPCFLAGS) == 0) {
 #ifdef CBAUD
-	termios.c_lflag &= ~CBAUD;
+		tp->c_lflag &= ~CBAUD;
 #endif
-	termios.c_cflag |= (B38400 | TTYDEF_CFLAG);
+		tp->c_cflag |= (B38400 | TTYDEF_CFLAG);
+	}
 
 	/* Sane setting, allow eight bit characters, no carriage return delay
 	 * the same result as `stty sane cr0 pass8'
 	 */
-	termios.c_iflag |=  (BRKINT | ICRNL | IMAXBEL);
-	termios.c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP);
-	termios.c_oflag |=  (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0);
-	termios.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\
+	tp->c_iflag |=  (BRKINT | ICRNL | IMAXBEL);
+	tp->c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP);
+	tp->c_oflag |=  (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0);
+	tp->c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\
 			    NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
-	termios.c_lflag |=  (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE);
-	termios.c_lflag &= ~(ECHONL|ECHOCTL|ECHOPRT | NOFLSH | XCASE | TOSTOP);
-	termios.c_cflag |=  (CREAD | CS8 | HUPCL);
-	termios.c_cflag &= ~(PARODD | PARENB);
+	tp->c_lflag |=  (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE);
+	tp->c_lflag &= ~(ECHONL|ECHOPRT | NOFLSH | XCASE | TOSTOP);
+	if ((op->flags & F_KEEPCFLAGS) == 0) {
+		tp->c_cflag |=  (CREAD | CS8 | HUPCL);
+		tp->c_cflag &= ~(PARODD | PARENB);
+	}
 #ifdef IUTF8
 	if (op->flags & F_UTF8)
-		termios.c_iflag |= IUTF8;	    /* Set UTF-8 input flag */
+		tp->c_iflag |= IUTF8;	    /* Set UTF-8 input flag */
 	else
 #endif
-		termios.c_iflag &= ~IUTF8;
+		tp->c_iflag &= ~IUTF8;
 
 	/* VTIME and VMIN can overlap with VEOF and VEOL since they are
 	 * only used for non-canonical mode. We just set the at the
 	 * beginning, so nothing bad should happen.
 	 */
-	termios.c_cc[VTIME]    = 0;
-	termios.c_cc[VMIN]     = 1;
-	termios.c_cc[VINTR]    = CINTR;
-	termios.c_cc[VQUIT]    = CQUIT;
-	termios.c_cc[VERASE]   = CERASE; /* ASCII DEL (0177) */
-	termios.c_cc[VKILL]    = CKILL;
-	termios.c_cc[VEOF]     = CEOF;
+	tp->c_cc[VTIME]    = 0;
+	tp->c_cc[VMIN]     = 1;
+	tp->c_cc[VINTR]    = CINTR;
+	tp->c_cc[VQUIT]    = CQUIT;
+	tp->c_cc[VERASE]   = CERASE; /* ASCII DEL (0177) */
+	tp->c_cc[VKILL]    = CKILL;
+	tp->c_cc[VEOF]     = CEOF;
 #ifdef VSWTC
-	termios.c_cc[VSWTC]    = _POSIX_VDISABLE;
-#else
-	termios.c_cc[VSWTCH]   = _POSIX_VDISABLE;
+	tp->c_cc[VSWTC]    = _POSIX_VDISABLE;
+#elif defined(VSWTCH)
+	tp->c_cc[VSWTCH]   = _POSIX_VDISABLE;
 #endif
-	termios.c_cc[VSTART]   = CSTART;
-	termios.c_cc[VSTOP]    = CSTOP;
-	termios.c_cc[VSUSP]    = CSUSP;
-	termios.c_cc[VEOL]     = _POSIX_VDISABLE;
-	termios.c_cc[VREPRINT] = CREPRINT;
-	termios.c_cc[VDISCARD] = CDISCARD;
-	termios.c_cc[VWERASE]  = CWERASE;
-	termios.c_cc[VLNEXT]   = CLNEXT;
-	termios.c_cc[VEOL2]    = _POSIX_VDISABLE;
-	if (tcsetattr (0, TCSADRAIN, &termios))
+	tp->c_cc[VSTART]   = CSTART;
+	tp->c_cc[VSTOP]    = CSTOP;
+	tp->c_cc[VSUSP]    = CSUSP;
+	tp->c_cc[VEOL]     = _POSIX_VDISABLE;
+	tp->c_cc[VREPRINT] = CREPRINT;
+	tp->c_cc[VDISCARD] = CDISCARD;
+	tp->c_cc[VWERASE]  = CWERASE;
+	tp->c_cc[VLNEXT]   = CLNEXT;
+	tp->c_cc[VEOL2]    = _POSIX_VDISABLE;
+	if (tcsetattr (STDIN_FILENO, TCSADRAIN, tp))
 		warn ("tcsetattr problem: %m");
 }
 
@@ -1093,7 +1123,7 @@ static void do_prompt(struct options *op, struct termios *tp)
 {
 #ifdef	ISSUE
 	FILE *fd;
-#endif				/* ISSUE */
+#endif
 
 	if ((op->flags & F_NONL) == 0)
 		/* Issue not in use, start with a new line. */
@@ -1167,7 +1197,7 @@ static void do_prompt(struct options *op, struct termios *tp)
 			}
  
 			if (len)
-				printf ("Hint: %s\n\n", warn);
+				printf ("Hint: %s\r\n\r\n", warn);
 		}
 	}
 #endif
@@ -1306,7 +1336,7 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
 				cp->erase = ascval; /* set erase character */
 				if (bp > logname) {
 					if ((tp->c_cflag & (ECHO)) == 0)
-						safe_write(1, erase[cp->parity], 3);
+						safe_write(STDOUT_FILENO, erase[cp->parity], 3);
 					bp--;
 				}
 				break;
@@ -1315,7 +1345,7 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
 				cp->kill = ascval;		/* set kill character */
 				while (bp > logname) {
 					if ((tp->c_cflag & (ECHO)) == 0)
-						safe_write(1, erase[cp->parity], 3);
+						safe_write(STDOUT_FILENO, erase[cp->parity], 3);
 					bp--;
 				}
 				break;
@@ -1327,7 +1357,7 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
 				if ((size_t)(bp - logname) >= sizeof(logname) - 1)
 					error(_("%s: input overrun"), op->tty);
 				if ((tp->c_cflag & (ECHO)) == 0)
-					safe_write(1, &c, 1);	/* echo the character */
+					safe_write(STDOUT_FILENO, &c, 1);	/* echo the character */
 				*bp++ = ascval;			/* and store it */
 				break;
 			}
@@ -1335,7 +1365,8 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
 	}
 
 
-	if ((op->flags & F_UTF8) && (ic = iconv_open("WCHAR_T", "UTF-8"))) {
+	if ((op->flags & (F_EIGHTBITS|F_UTF8)) == (F_EIGHTBITS|F_UTF8) &&
+	    (ic = iconv_open("WCHAR_T", "UTF-8"))) {
 		char tmpbuf[4*sizeof(logname)], *optr, *lptr;
 		size_t len = bp - logname;
 		size_t out = sizeof(tmpbuf) - 1;
@@ -1379,15 +1410,18 @@ static void termio_final(struct options *op, struct termios *tp, struct chardata
 	/* no longer| ECHOCTL | ECHOPRT */
 	tp->c_oflag |= OPOST;
 	/* tp->c_cflag = 0; */
-	tp->c_cc[VINTR] = DEF_INTR;
-	tp->c_cc[VQUIT] = DEF_QUIT;
-	tp->c_cc[VEOF] = DEF_EOF;
-	tp->c_cc[VEOL] = DEF_EOL;
-#ifdef __linux__
-	tp->c_cc[VSWTC] = DEF_SWITCH;
+	tp->c_cc[VINTR] = CINTR;
+	tp->c_cc[VQUIT] = CQUIT;
+	tp->c_cc[VEOF] = CEOF;
+	tp->c_cc[VEOL] = _POSIX_VDISABLE;
+#if defined(VSWTC)
+	tp->c_cc[VSWTC] = _POSIX_VDISABLE;
 #elif defined(VSWTCH)
-	tp->c_cc[VSWTCH] = DEF_SWITCH;
-#endif				/* __linux__ */
+	tp->c_cc[VSWTCH] = _POSIX_VDISABLE;
+#endif
+	tp->c_cc[VSTART] = CSTART;
+	tp->c_cc[VSTOP] = CSTOP;
+	tp->c_cc[VSUSP] = CSUSP;
 
 	/* Account for special characters seen in input. */
 	if (cp->eol == CR) {
@@ -1618,6 +1652,10 @@ static void output_special_char(unsigned char c, struct options *op,
 {
 	struct utsname uts;
 	(void) uname(&uts);
+
+	if ((op->flags & F_VCONSOLE) == 0)
+		setvbuf(stdout, NULL, _IONBF, 0);
+
 	switch (c) {
 	case 's':
 		(void) printf ("%s", uts.sysname);
-- 
1.6.0.2

--
To unsubscribe from this list: send the line "unsubscribe util-linux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux