Index: head/include/ttyent.h =================================================================== --- head/include/ttyent.h (revision 315732) +++ head/include/ttyent.h (revision 315733) @@ -1,74 +1,75 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ttyent.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _TTYENT_H_ #define _TTYENT_H_ #define _PATH_TTYS "/etc/ttys" #define _TTYS_OFF "off" #define _TTYS_ON "on" #define _TTYS_ONIFCONSOLE "onifconsole" +#define _TTYS_ONIFEXISTS "onifexists" #define _TTYS_SECURE "secure" #define _TTYS_INSECURE "insecure" #define _TTYS_WINDOW "window" #define _TTYS_GROUP "group" #define _TTYS_NOGROUP "none" #define _TTYS_DIALUP "dialup" #define _TTYS_NETWORK "network" struct ttyent { char *ty_name; /* terminal device name */ char *ty_getty; /* command to execute, usually getty */ char *ty_type; /* terminal type for termcap */ #define TTY_ON 0x01 /* enable logins (start ty_getty program) */ #define TTY_SECURE 0x02 /* allow uid of 0 to login */ #define TTY_DIALUP 0x04 /* is a dialup tty */ #define TTY_NETWORK 0x08 /* is a network tty */ int ty_status; /* status flags */ char *ty_window; /* command to start up window manager */ char *ty_comment; /* comment field */ char *ty_group; /* tty group */ }; #include __BEGIN_DECLS struct ttyent *getttyent(void); struct ttyent *getttynam(const char *); int setttyent(void); int endttyent(void); int isdialuptty(const char *); int isnettty(const char *); __END_DECLS #endif /* !_TTYENT_H_ */ Index: head/lib/libc/gen/getttyent.c =================================================================== --- head/lib/libc/gen/getttyent.c (revision 315732) +++ head/lib/libc/gen/getttyent.c (revision 315733) @@ -1,292 +1,314 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include static char zapchar; static FILE *tf; static size_t lbsize; static char *line; #define MALLOCCHUNK 100 static char *skip(char *); static char *value(char *); struct ttyent * getttynam(const char *tty) { struct ttyent *t; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; setttyent(); while ( (t = getttyent()) ) if (!strcmp(tty, t->ty_name)) break; endttyent(); return (t); } static int auto_tty_status(const char *ty_name) { size_t len; char *buf, *cons, *nextcons; /* Check if this is an enabled kernel console line */ buf = NULL; if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1) return (0); /* Errors mean don't enable */ buf = malloc(len); if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1) goto done; if ((cons = strchr(buf, '/')) == NULL) goto done; *cons = '\0'; nextcons = buf; while ((cons = strsep(&nextcons, ",")) != NULL && strlen(cons) != 0) { if (strcmp(cons, ty_name) == 0) { free(buf); return (TTY_ON); } } done: free(buf); return (0); } +static int +auto_exists_status(const char *ty_name) +{ + struct stat sb; + char *dev; + int rv; + + rv = 0; + if (*ty_name == '/') + asprintf(&dev, "%s", ty_name); + else + asprintf(&dev, "/dev/%s", ty_name); + if (dev == NULL) + return 0; + if (stat(dev, &sb) == 0) + rv = TTY_ON; + free(dev); + return (rv); +} + struct ttyent * getttyent(void) { static struct ttyent tty; char *p; int c; size_t i; if (!tf && !setttyent()) return (NULL); for (;;) { if (!fgets(p = line, lbsize, tf)) return (NULL); /* extend buffer if line was too big, and retry */ while (!strchr(p, '\n') && !feof(tf)) { i = strlen(p); lbsize += MALLOCCHUNK; if ((p = realloc(line, lbsize)) == NULL) { (void)endttyent(); return (NULL); } line = p; if (!fgets(&line[i], lbsize - i, tf)) return (NULL); } while (isspace((unsigned char)*p)) ++p; if (*p && *p != '#') break; } #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1]) #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' zapchar = 0; tty.ty_name = p; tty.ty_status = 0; tty.ty_window = NULL; tty.ty_group = _TTYS_NOGROUP; p = skip(p); if (!*(tty.ty_getty = p)) tty.ty_getty = tty.ty_type = NULL; else { p = skip(p); if (!*(tty.ty_type = p)) tty.ty_type = NULL; else { /* compatibility kludge: handle network/dialup specially */ if (scmp(_TTYS_DIALUP)) tty.ty_status |= TTY_DIALUP; else if (scmp(_TTYS_NETWORK)) tty.ty_status |= TTY_NETWORK; p = skip(p); } } for (; *p; p = skip(p)) { if (scmp(_TTYS_OFF)) tty.ty_status &= ~TTY_ON; else if (scmp(_TTYS_ON)) tty.ty_status |= TTY_ON; else if (scmp(_TTYS_ONIFCONSOLE)) tty.ty_status |= auto_tty_status(tty.ty_name); + else if (scmp(_TTYS_ONIFEXISTS)) + tty.ty_status |= auto_exists_status(tty.ty_name); else if (scmp(_TTYS_SECURE)) tty.ty_status |= TTY_SECURE; else if (scmp(_TTYS_INSECURE)) tty.ty_status &= ~TTY_SECURE; else if (scmp(_TTYS_DIALUP)) tty.ty_status |= TTY_DIALUP; else if (scmp(_TTYS_NETWORK)) tty.ty_status |= TTY_NETWORK; else if (vcmp(_TTYS_WINDOW)) tty.ty_window = value(p); else if (vcmp(_TTYS_GROUP)) tty.ty_group = value(p); else break; } if (zapchar == '#' || *p == '#') while ((c = *++p) == ' ' || c == '\t') ; tty.ty_comment = p; if (*p == 0) tty.ty_comment = 0; if ((p = strchr(p, '\n'))) *p = '\0'; return (&tty); } #define QUOTED 1 /* * Skip over the current field, removing quotes, and return a pointer to * the next field. */ static char * skip(char *p) { char *t; int c, q; for (q = 0, t = p; (c = *p) != '\0'; p++) { if (c == '"') { q ^= QUOTED; /* obscure, but nice */ continue; } if (q == QUOTED && *p == '\\' && *(p+1) == '"') p++; *t++ = *p; if (q == QUOTED) continue; if (c == '#') { zapchar = c; *p = 0; break; } if (c == '\t' || c == ' ' || c == '\n') { zapchar = c; *p++ = 0; while ((c = *p) == '\t' || c == ' ' || c == '\n') p++; break; } } *--t = '\0'; return (p); } static char * value(char *p) { return ((p = strchr(p, '=')) ? ++p : NULL); } int setttyent(void) { if (line == NULL) { if ((line = malloc(MALLOCCHUNK)) == NULL) return (0); lbsize = MALLOCCHUNK; } if (tf) { rewind(tf); return (1); } else if ( (tf = fopen(_PATH_TTYS, "re")) ) return (1); return (0); } int endttyent(void) { int rval; /* * NB: Don't free `line' because getttynam() * may still be referencing it */ if (tf) { rval = (fclose(tf) != EOF); tf = NULL; return (rval); } return (1); } static int isttystat(const char *tty, int flag) { struct ttyent *t; return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag); } int isdialuptty(const char *tty) { return isttystat(tty, TTY_DIALUP); } int isnettty(const char *tty) { return isttystat(tty, TTY_NETWORK); } Index: head/libexec/getty/ttys.5 =================================================================== --- head/libexec/getty/ttys.5 (revision 315732) +++ head/libexec/getty/ttys.5 (revision 315733) @@ -1,170 +1,176 @@ .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" from: @(#)ttys.5 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" " -.Dd March 9, 2014 +.Dd March 16, 2017 .Dt TTYS 5 .Os .Sh NAME .Nm ttys .Nd terminal initialization information .Sh DESCRIPTION The file .Nm contains information that is used by various routines to initialize and control the use of terminal special files. Pseudo-terminals (see .Xr pts 4 ) are not listed. This information is read with the .Xr getttyent 3 library routines. There is one line in the .Nm file per special device file. Fields are separated by tabs and/or spaces. Fields comprised of more than one word should be enclosed in double quotes (``"''). Blank lines and comments may appear anywhere in the file; comments are delimited by hash marks (``#'') and new lines. Any unspecified fields will default to null. .Pp The first field is normally the name of the terminal special file as it is found in .Pa /dev . However, it can be any arbitrary string when the associated command is not related to a tty. .Pp The second field of the file is the command to execute for the line, usually .Xr getty 8 , which initializes and opens the line, setting the speed, waiting for a user name and executing the .Xr login 1 program. It can be, however, any desired command, for example the start up for a window system terminal emulator or some other daemon process, and can contain multiple words if quoted. .Pp The third field is the type of terminal usually connected to that tty line, normally the one found in the .Xr termcap 5 data base file. The environment variable .Ev TERM is initialized with the value by either .Xr getty 8 or .Xr login 1 . .Pp The remaining fields set flags in the .Fa ty_status entry (see .Xr getttyent 3 ) , specify a window system process that .Xr init 8 will maintain for the terminal line, optionally determine the type of tty (whether dialin, network or otherwise), or specify a tty group name that allows the login class database (see .Xr login.conf 5 ) to refer to many ttys as a group, to selectively allow or deny access or enable or disable accounting facilities for ttys as a group. .Pp As flag values, the strings ``on'' and ``off'' specify that .Xr init 8 should (should not) execute the command given in the second field. ``onifconsole'' will cause this line to be enabled if and only if it is an active kernel console device (it is equivalent to ``on'' in this case). +The flag ``onifexists'' will cause this line to be enabled if and only +if the name exists. +If the name starts with a ``/'', it will be considered an absolute +path. +Otherwise, it is considered a path relative to +.Pa /dev . The flag ``secure'' (if the console is enabled) allows users with a uid of 0 to login on this line. The flag ``dialin'' indicates that a tty entry describes a dialin line, and ``network'' is obsolete and does nothing. Either of these strings may also be specified in the terminal type field. The string ``window='' may be followed by a quoted command string which .Xr init 8 will execute .Em before starting the command specified by the second field. .Pp The string ``group='' may be followed by a group name comprised of alphanumeric characters that can be used by .Xr login.conf 5 to refer to many tty lines as a group to enable or disable access and accounting facilities. If no group is specified, then the tty becomes a member of the group "none". For backwards compatibility, the ``group='' should appear last on the line, immediately before the optional comment. .Pp Both the second field and any command specified with ``window='' will be split into words and executed using .Xr execve 2 . Words are separated by any combinations of tabs and spaces. Arguments containing whitespace should be enclosed in single quotes .Pq Li ' . Note that no shell-style globbing or other variable substitution occurs. .Sh FILES .Bl -tag -width /etc/ttys -compact .It Pa /etc/ttys .El .Sh EXAMPLES .Bd -literal # root login on console at 1200 baud console "/usr/libexec/getty std.1200" vt100 on secure # dialup at 1200 baud, no root logins ttyd0 "/usr/libexec/getty d1200" dialup on group=dialup # 555-1234 # Mike's terminal: hp2621 ttyh0 "/usr/libexec/getty std.9600" hp2621-nl on group=dialup # 457 Evans # John's terminal: vt100 ttyh1 "/usr/libexec/getty std.9600" vt100 on group=dialup # 459 Evans # terminal emulate/window system ttyv0 "/usr/local/bin/xterm -display :0" xterm on window="/usr/local/bin/X :0" .Ed .Sh SEE ALSO .Xr login 1 , .Xr getttyent 3 , .Xr gettytab 5 , .Xr login.conf 5 , .Xr termcap 5 , .Xr getty 8 , .Xr init 8 .\".Xr init 8 , .\".Xr ttyflags 8 .Sh HISTORY A .Nm file appeared in .At v6 .