Index: head/libexec/getty/gettytab.5 =================================================================== --- head/libexec/getty/gettytab.5 +++ head/libexec/getty/gettytab.5 @@ -28,7 +28,7 @@ .\" from: @(#)gettytab.5 8.4 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" " -.Dd April 19, 1994 +.Dd February 2, 2017 .Dt GETTYTAB 5 .Os .Sh NAME @@ -118,7 +118,7 @@ .Em NOT hangup line on last close .It "he str" Ta Dv NULL Ta -.No "hostname editing string" +.No "hostname editing regular expression" .It "hn str hostname hostname" .It "ht bool false terminal has real tabs" .It "hw bool false do cts/rts hardware flow control" @@ -302,18 +302,13 @@ table entry. In either case it may be edited with the .Va \&he -string. -A '@' in the -.Va \&he -string causes one character from the real hostname to -be copied to the final hostname. -A '#' in the -.Va \&he -string causes the next character of the real hostname -to be skipped. -Each character that -is neither '@' nor '#' is copied into the final hostname. -Surplus '@' and '#' characters are ignored. +POSIX +.Dq extended +regular expression, which is matched against the hostname. +If there are no parenthesized subexpressions in the pattern, +the entire matched string is used as the final hostname; +otherwise, the first matched subexpression is used instead. +If the pattern does not match, the original hostname is not modified. .It \&%t The tty name. .It "\&%m, \&%r, \&%s, \&%v" @@ -528,10 +523,6 @@ The terminal driver should support sane delay settings. .Pp The -.Va \&he -capability is stupid. -.Pp -The .Xr termcap 5 format is horrid, something more rational should have been chosen. Index: head/libexec/getty/subr.c =================================================================== --- head/libexec/getty/subr.c +++ head/libexec/getty/subr.c @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -53,8 +54,6 @@ #include "pathnames.h" #include "extern.h" - - /* * Get a table entry. */ @@ -469,42 +468,48 @@ char editedhost[MAXHOSTNAMELEN]; void -edithost(const char *pat) +edithost(const char *pattern) { - const char *host = HN; - char *res = editedhost; - - if (!pat) - pat = ""; - while (*pat) { - switch (*pat) { - - case '#': - if (*host) - host++; - break; - - case '@': - if (*host) - *res++ = *host++; - break; - - default: - *res++ = *pat; - break; + regex_t regex; + regmatch_t *match; + int found; + + if (pattern == NULL || *pattern == '\0') + goto copyasis; + if (regcomp(®ex, pattern, REG_EXTENDED) != 0) + goto copyasis; + + match = calloc(regex.re_nsub + 1, sizeof(*match)); + if (match == NULL) { + regfree(®ex); + goto copyasis; + } + + found = !regexec(®ex, HN, regex.re_nsub + 1, match, 0); + if (found) { + size_t subex, totalsize; - } - if (res == &editedhost[sizeof editedhost - 1]) { - *res = '\0'; - return; - } - pat++; - } - if (*host) - strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); - else - *res = '\0'; - editedhost[sizeof editedhost - 1] = '\0'; + /* + * We found a match. If there were no parenthesized + * subexpressions in the pattern, use entire matched + * string as ``editedhost''; otherwise use the first + * matched subexpression. + */ + subex = !!regex.re_nsub; + totalsize = match[subex].rm_eo - match[subex].rm_so + 1; + strlcpy(editedhost, HN + match[subex].rm_so, totalsize > + sizeof(editedhost) ? sizeof(editedhost) : totalsize); + } + free(match); + regfree(®ex); + if (found) + return; + /* + * In case of any errors, or if the pattern did not match, pass + * the original hostname as is. + */ + copyasis: + strlcpy(editedhost, HN, sizeof(editedhost)); } static struct speedtab {