From 582bb62b81f0c9e116d696f7312ddfffeb211b82 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 31 Oct 2004 22:28:43 +0000 Subject: [PATCH] add to mksh the unique ability to spawn on a different VT --- Makefile | 4 ++-- chvt.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ksh.1tbl | 24 ++++++++++++++++++++- misc.c | 56 +++++++++++++++++++++++++++++++++++++++++++---- proto.h | 4 +++- 5 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 chvt.c diff --git a/Makefile b/Makefile index 531f51f..57684a2 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -# $MirBSD: Makefile,v 1.8 2004/10/28 16:35:01 tg Exp $ +# $MirBSD: Makefile,v 1.9 2004/10/31 22:28:41 tg Exp $ # $OpenBSD: Makefile,v 1.18 2004/02/16 19:07:19 deraadt Exp $ PROG= ksh -SRCS= alloc.c c_ksh.c c_sh.c c_test.c c_ulimit.c edit.c emacs.c \ +SRCS= alloc.c c_ksh.c c_sh.c c_test.c c_ulimit.c chvt.c edit.c emacs.c \ eval.c exec.c expr.c history.c io.c jobs.c lex.c mail.c \ main.c misc.c missing.c path.c rnd.c shf.c syn.c table.c \ trap.c tree.c tty.c var.c version.c vi.c diff --git a/chvt.c b/chvt.c new file mode 100644 index 0000000..e8d0d09 --- /dev/null +++ b/chvt.c @@ -0,0 +1,66 @@ +/** $MirBSD: chvt.c,v 1.1 2004/10/31 22:28:41 tg Exp $ */ + +/*- + * Copyright (c) 2004 + * Thorsten "mirabile" Glaser + * + * Licensee is hereby permitted to deal in this work without restric- + * tion, including unlimited rights to use, publically perform, modi- + * fy, merge, distribute, sell, give away or sublicence, provided the + * above copyright notices, these terms and the disclaimer are retai- + * ned in all redistributions, or reproduced in accompanying documen- + * tation or other materials provided with binary redistributions. + * + * Licensor hereby provides this work "AS IS" and WITHOUT WARRANTY of + * any kind, expressed or implied, to the maximum extent permitted by + * applicable law, but with the warranty of being written without ma- + * licious intent or gross negligence; in no event shall licensor, an + * author or contributor be held liable for any damage, direct, indi- + * rect or other, however caused, arising in any way out of the usage + * of covered work, even if advised of the possibility of such damage. + */ + +#include "sh.h" +#include +#include "ksh_stat.h" + +__RCSID("$MirBSD: chvt.c,v 1.1 2004/10/31 22:28:41 tg Exp $"); + + +char * +chvt(char *f) +{ + int fd; + + if (chown(f, 0, 0)) + return "chown"; + if (chmod(f, 0600)) + return "chmod"; + if (revoke(f)) + return "revoke"; + + if ((fd = open(f, O_RDWR)) == -1) { + sleep(1); + if ((fd = open(f, O_RDWR)) == -1) + return "open"; + } + switch (fork()) { + case -1: + return "fork"; + case 0: + break; + default: + _exit(0); + } + if (setsid() == -1) + return "setsid"; + if (ioctl(fd, TIOCSCTTY, NULL) == -1) + return "ioctl"; + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + if (fd > 2) + close(fd); + + return NULL; +} diff --git a/ksh.1tbl b/ksh.1tbl index f4d491b..0a08a64 100644 --- a/ksh.1tbl +++ b/ksh.1tbl @@ -1,4 +1,4 @@ -.\" $MirBSD: ksh.1tbl,v 1.34 2004/10/28 16:49:13 tg Exp $ +.\" $MirBSD: ksh.1tbl,v 1.35 2004/10/31 22:28:41 tg Exp $ .\" $OpenBSD: ksh.1tbl,v 1.72 2004/08/07 16:46:58 millert Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 @@ -55,6 +55,7 @@ .Sh SYNOPSIS .Nm .Op Fl +abCefhiklmnprsuvxX +.Op Fl T Ar /dev/ttyCn .Op Fl +o Ar option .Xo .Bk -words @@ -88,6 +89,13 @@ The shell reads commands from standard input; all non-option arguments are positional parameters. .It Fl r Restricted mode; see below. +.It Fl T Ar tty +Spawn +.Nm +on +.Xr tty 4 +device given. +Superuser only. .El .Pp In addition to the above, the options described in the @@ -135,6 +143,20 @@ option is on by default (see the .Ic set command below). .Pp +If the +.Fl T Ar ttydev +option is given, an interactive shell is spawned in the background +with the given device as controlling terminal. +The terminal devices are probed in the following order: +.Bl -enum -compact +.It +ttydev +.It +.Pa /dev/ttyC Ns ttydev +.It +.Pa /dev/tty Ns ttydev +.El +.Pp A shell is .Dq restricted if the diff --git a/misc.c b/misc.c index 88297c8..a72a38b 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/** $MirBSD: misc.c,v 1.12 2004/10/28 11:53:42 tg Exp $ */ +/** $MirBSD: misc.c,v 1.13 2004/10/31 22:28:42 tg Exp $ */ /* $OpenBSD: misc.c,v 1.20 2003/10/22 07:40:38 jmc Exp $ */ /* @@ -11,7 +11,7 @@ # include #endif -__RCSID("$MirBSD: misc.c,v 1.12 2004/10/28 11:53:42 tg Exp $"); +__RCSID("$MirBSD: misc.c,v 1.13 2004/10/31 22:28:42 tg Exp $"); #ifndef UCHAR_MAX # define UCHAR_MAX 0xFF @@ -24,6 +24,10 @@ static int do_gmatch(const unsigned char *s, const unsigned char *p, int isfile); static const unsigned char *cclass(const unsigned char *p, int sub); +#ifdef KSH +static int parse_T(char *); +#endif + /* * Fast character classes */ @@ -319,7 +323,8 @@ change_flag(enum sh_flag f, int what, int newval) } /* Changing interactive flag? */ if (f == FTALKING) { - if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) + if ((what == OF_CMDLINE || what == OF_SET) + && procpid == kshpid) Flag(FTALKING_I) = newval; } } @@ -333,7 +338,7 @@ parse_args(char **argv, int what, int *setargsp) /* OF_CMDLINE or OF_SET */ { - static char cmd_opts[NELEM(options) + 3]; /* o:\0 */ + static char cmd_opts[NELEM(options) + 5]; /* o:T:\0 */ static char set_opts[NELEM(options) + 5]; /* Ao;s\0 */ char *opts; char *array = (char *) 0; @@ -346,7 +351,11 @@ parse_args(char **argv, int what, int *setargsp) char *p, *q; /* see cmd_opts[] declaration */ +#ifdef KSH + strlcpy(cmd_opts, "o:T:", sizeof cmd_opts); +#else strlcpy(cmd_opts, "o:", sizeof cmd_opts); +#endif p = cmd_opts + strlen(cmd_opts); /* see set_opts[] declaration */ strlcpy(set_opts, "A:o;s", sizeof set_opts); @@ -383,6 +392,14 @@ parse_args(char **argv, int what, int *setargsp) array = go.optarg; break; +#ifdef KSH + case 'T': + if (parse_T(go.optarg)) + return -1; + change_flag(FTALKING, OF_CMDLINE, 1); + break; +#endif + case 'o': if (go.optarg == (char *) 0) { /* lone -o: print options @@ -1299,3 +1316,34 @@ ksh_get_wd(char *buf, int bsize) return b; #endif /* HAVE_GETCWD */ } + +#ifdef KSH +#include "ksh_stat.h" +static int +parse_T(char *fn) +{ + char *rv, dv[20]; + struct stat sb; + + strlcpy(dv, fn, 20); + if (stat(dv, &sb)) { + snprintf(dv, 20, "/dev/ttyC%s", fn); + if (stat(dv, &sb)) { + snprintf(dv, 20, "/dev/tty%s", fn); + if (stat(dv, &sb)) { + warningf(0, "chvt: can't find tty %s", fn); + return -1; + } + } + } + if (!(sb.st_mode & S_IFCHR)) { + warningf(0, "chvt: not a char device: %s", fn); + return -1; + } + if ((rv = chvt(dv)) != NULL) { + warningf(0, "chvt: failed to %s: %s", rv, strerror(errno)); + return -1; + } + return 0; +} +#endif diff --git a/proto.h b/proto.h index e75bc06..8fddc0b 100644 --- a/proto.h +++ b/proto.h @@ -1,4 +1,4 @@ -/** $MirBSD: proto.h,v 1.8 2004/10/28 11:53:43 tg Exp $ */ +/** $MirBSD: proto.h,v 1.9 2004/10/31 22:28:43 tg Exp $ */ /* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */ /* $From: proto.h,v 1.3 1994/05/19 18:32:40 michael Exp michael $ */ @@ -54,6 +54,8 @@ int c_exec(char **wp); int c_builtin(char **wp); /* c_test.c */ int c_test(char **wp); +/* chvt.c */ +char * chvt(char *); /* edit.c: most prototypes in edit.h */ void x_init(void); int x_read(char *buf, size_t len);