Module Name:    src
Committed By:   reinoud
Date:           Sun Dec 27 21:13:18 UTC 2020

Modified Files:
        src/distrib/sets/lists/base: mi
        src/distrib/sets/lists/man: mi
        src/distrib/sets/lists/xbase: mi
        src/doc: CHANGES
        src/external/mit/xorg/bin/xterm: Makefile
Added Files:
        src/usr.bin/resize: Makefile resize.1 resize.c xstrings.c xstrings.h

Log Message:
Import Xterm's resize(1) for querying (x)terminal sizes in base for headless
clients


To generate a diff of this commit:
cvs rdiff -u -r1.1272 -r1.1273 src/distrib/sets/lists/base/mi
cvs rdiff -u -r1.1711 -r1.1712 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.163 -r1.164 src/distrib/sets/lists/xbase/mi
cvs rdiff -u -r1.2770 -r1.2771 src/doc/CHANGES
cvs rdiff -u -r1.18 -r1.19 src/external/mit/xorg/bin/xterm/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.bin/resize/Makefile \
    src/usr.bin/resize/resize.1 src/usr.bin/resize/resize.c \
    src/usr.bin/resize/xstrings.c src/usr.bin/resize/xstrings.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/base/mi
diff -u src/distrib/sets/lists/base/mi:1.1272 src/distrib/sets/lists/base/mi:1.1273
--- src/distrib/sets/lists/base/mi:1.1272	Mon Nov 23 12:41:47 2020
+++ src/distrib/sets/lists/base/mi	Sun Dec 27 21:13:18 2020
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1272 2020/11/23 12:41:47 martin Exp $
+# $NetBSD: mi,v 1.1273 2020/12/27 21:13:18 reinoud Exp $
 #
 # Note:	Don't delete entries from here - mark them as "obsolete" instead,
 #	unless otherwise stated below.
@@ -951,6 +951,7 @@
 ./usr/bin/renice				base-util-bin
 ./usr/bin/reset					base-util-bin
 ./usr/bin/rev					base-util-bin
+./usr/bin/resize				base-util-bin
 ./usr/bin/revoke				base-util-bin
 ./usr/bin/rfcomm_sppd				base-util-bin
 ./usr/bin/rlog					base-rcs-bin

Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1711 src/distrib/sets/lists/man/mi:1.1712
--- src/distrib/sets/lists/man/mi:1.1711	Tue Nov 10 21:47:41 2020
+++ src/distrib/sets/lists/man/mi	Sun Dec 27 21:13:18 2020
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1711 2020/11/10 21:47:41 kamil Exp $
+# $NetBSD: mi,v 1.1712 2020/12/27 21:13:18 reinoud Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -490,6 +490,7 @@
 ./usr/share/man/cat1/rehash.0			man-util-catman		.cat
 ./usr/share/man/cat1/repeat.0			man-util-catman		.cat
 ./usr/share/man/cat1/reset.0			man-util-catman		.cat
+./usr/share/man/cat1/resize.0			man-util-catman		.cat
 ./usr/share/man/cat1/rev.0			man-util-catman		.cat
 ./usr/share/man/cat1/rfcomm_sppd.0		man-util-catman		.cat
 ./usr/share/man/cat1/rlog.0			man-rcs-catman		.cat
@@ -3774,6 +3775,7 @@
 ./usr/share/man/html1/rehash.html		man-util-htmlman	html
 ./usr/share/man/html1/repeat.html		man-util-htmlman	html
 ./usr/share/man/html1/reset.html		man-util-htmlman	html
+./usr/share/man/html1/resize.html		man-util-htmlman	html
 ./usr/share/man/html1/rev.html			man-util-htmlman	html
 ./usr/share/man/html1/rfcomm_sppd.html		man-util-htmlman	html
 ./usr/share/man/html1/rlog.html			man-rcs-htmlman		html
@@ -6708,6 +6710,7 @@
 ./usr/share/man/man1/rehash.1			man-util-man		.man
 ./usr/share/man/man1/repeat.1			man-util-man		.man
 ./usr/share/man/man1/reset.1			man-util-man		.man
+./usr/share/man/man1/resize.1			man-util-man		.man
 ./usr/share/man/man1/rev.1			man-util-man		.man
 ./usr/share/man/man1/rfcomm_sppd.1		man-util-man		.man
 ./usr/share/man/man1/rlog.1			man-rcs-man		.man

Index: src/distrib/sets/lists/xbase/mi
diff -u src/distrib/sets/lists/xbase/mi:1.163 src/distrib/sets/lists/xbase/mi:1.164
--- src/distrib/sets/lists/xbase/mi:1.163	Tue Nov 10 21:47:41 2020
+++ src/distrib/sets/lists/xbase/mi	Sun Dec 27 21:13:18 2020
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.163 2020/11/10 21:47:41 kamil Exp $
+# $NetBSD: mi,v 1.164 2020/12/27 21:13:18 reinoud Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -53,7 +53,7 @@
 ./usr/X11R7/bin/perfboth				xbase-x11perf-bin	xorg
 ./usr/X11R7/bin/perfratio				xbase-x11perf-bin	xorg
 ./usr/X11R7/bin/proxymngr				xbase-proxymngr-bin	xorg
-./usr/X11R7/bin/resize					xbase-xterm-bin	xorg
+./usr/X11R7/bin/resize					xbase-obsolete		obsolete
 ./usr/X11R7/bin/revpath					xbase-revpath-bin	xorg
 ./usr/X11R7/bin/sessreg					xbase-sessreg-bin	xorg
 ./usr/X11R7/bin/setxkbmap				xbase-setxkbmap-bin	xorg
@@ -1309,7 +1309,7 @@
 ./usr/X11R7/man/cat1/mkhtmlindex.0			xbase-mkhtmlindex-catman	.cat,xorg
 ./usr/X11R7/man/cat1/oclock.0				xbase-oclock-catman	.cat,xorg
 ./usr/X11R7/man/cat1/proxymngr.0			xbase-proxymngr-catman	.cat,xorg
-./usr/X11R7/man/cat1/resize.0				xbase-xterm-catman	.cat,xorg
+./usr/X11R7/man/cat1/resize.0				xbase-obsolete		obsolete
 ./usr/X11R7/man/cat1/revpath.0				xbase-revpath-catman	.cat,xorg
 ./usr/X11R7/man/cat1/sessreg.0				xbase-sessreg-catman	.cat,xorg
 ./usr/X11R7/man/cat1/setxkbmap.0			xbase-setxkbmap-catman	.cat,xorg
@@ -1457,7 +1457,7 @@
 ./usr/X11R7/man/html1/mkhtmlindex.html			xbase-mkhtmlindex-htmlman	html,xorg
 ./usr/X11R7/man/html1/oclock.html			xbase-oclock-htmlman	html,xorg
 ./usr/X11R7/man/html1/proxymngr.html			xbase-proxymngr-htmlman	html,xorg
-./usr/X11R7/man/html1/resize.html			xbase-resize-htmlman	html,xorg
+./usr/X11R7/man/html1/resize.html			xbase-obsolete		obsolete
 ./usr/X11R7/man/html1/revpath.html			xbase-revpath-htmlman	html,xorg
 ./usr/X11R7/man/html1/sessreg.html			xbase-sessreg-htmlman	html,xorg
 ./usr/X11R7/man/html1/setxkbmap.html			xbase-setxkbmap-htmlman	html,xorg
@@ -1606,7 +1606,7 @@
 ./usr/X11R7/man/man1/mkhtmlindex.1			xbase-mkhtmlindex-man	.man,xorg
 ./usr/X11R7/man/man1/oclock.1				xbase-oclock-man	.man,xorg
 ./usr/X11R7/man/man1/proxymngr.1			xbase-proxymngr-man	.man,xorg
-./usr/X11R7/man/man1/resize.1				xbase-xterm-man	.man,xorg
+./usr/X11R7/man/man1/resize.1				xbase-obsolete		obsolete
 ./usr/X11R7/man/man1/revpath.1				xbase-revpath-man	.man,xorg
 ./usr/X11R7/man/man1/sessreg.1				xbase-sessreg-man	.man,xorg
 ./usr/X11R7/man/man1/setxkbmap.1			xbase-setxkbmap-man	.man,xorg

Index: src/doc/CHANGES
diff -u src/doc/CHANGES:1.2770 src/doc/CHANGES:1.2771
--- src/doc/CHANGES:1.2770	Sun Dec 27 20:56:14 2020
+++ src/doc/CHANGES	Sun Dec 27 21:13:17 2020
@@ -1,4 +1,4 @@
-# LIST OF CHANGES FROM LAST RELEASE:			<$Revision: 1.2770 $>
+# LIST OF CHANGES FROM LAST RELEASE:			<$Revision: 1.2771 $>
 #
 #
 # [Note: This file does not mention every change made to the NetBSD source tree.
@@ -322,4 +322,6 @@ Changes from NetBSD 9.0 to NetBSD 10.0:
 		framebuffer for HP9000/425t. [tsutsui 20201223]
 	openresolv: Update to version 3.12.0 [roy 20201227]
 	nvmm: implement support for trapping REP CMPS [reinoud 20201227]
+	resize: Import Xterm's resize(1) for querying (x)terminal sizes in
+		base for headless clients [reinoud 20201227]
 

Index: src/external/mit/xorg/bin/xterm/Makefile
diff -u src/external/mit/xorg/bin/xterm/Makefile:1.18 src/external/mit/xorg/bin/xterm/Makefile:1.19
--- src/external/mit/xorg/bin/xterm/Makefile:1.18	Fri Oct  2 13:08:07 2020
+++ src/external/mit/xorg/bin/xterm/Makefile	Sun Dec 27 21:13:18 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.18 2020/10/02 13:08:07 nia Exp $
+#	$NetBSD: Makefile,v 1.19 2020/12/27 21:13:18 reinoud Exp $
 
 .include <bsd.own.mk>
 
@@ -38,7 +38,7 @@ DPADD+=	${LIBXAW} ${LIBXMU} ${LIBXT} ${L
 LDADD+=	-lXpm -lXext -lX11 -lcurses -lterminfo -lutil
 DPADD+=	${LIBXPM} ${LIBXEXT} ${LIBX11} ${LIBCURSES} ${LIBTERMINFO} ${LIBUTIL}
 
-SUBDIR=	resize uxterm
+SUBDIR=	uxterm
 
 .PATH:	${X11SRCDIR.${PROG}}
 

Added files:

Index: src/usr.bin/resize/Makefile
diff -u /dev/null src/usr.bin/resize/Makefile:1.1
--- /dev/null	Sun Dec 27 21:13:18 2020
+++ src/usr.bin/resize/Makefile	Sun Dec 27 21:13:18 2020
@@ -0,0 +1,7 @@
+#	$NetBSD: Makefile,v 1.1 2020/12/27 21:13:18 reinoud Exp $
+
+WARNS=	3
+PROG=	resize
+SRCS=	resize.c xstrings.c
+
+.include <bsd.prog.mk>
Index: src/usr.bin/resize/resize.1
diff -u /dev/null src/usr.bin/resize/resize.1:1.1
--- /dev/null	Sun Dec 27 21:13:18 2020
+++ src/usr.bin/resize/resize.1	Sun Dec 27 21:13:18 2020
@@ -0,0 +1,219 @@
+.\" $XTermId: resize.man,v 1.32 2016/09/24 11:14:15 tom Exp $
+.\"
+.\" Copyright 1998-2013,2016 by Thomas E. Dickey
+.\"
+.\"                         All Rights Reserved
+.\"
+.\" Permission is hereby granted, free of charge, to any person obtaining a
+.\" copy of this software and associated documentation files (the
+.\" "Software"), to deal in the Software without restriction, including
+.\" without limitation the rights to use, copy, modify, merge, publish,
+.\" distribute, sublicense, and/or sell copies of the Software, and to
+.\" permit persons to whom the Software is furnished to do so, subject to
+.\" the following conditions:
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+.\" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+.\" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+.\" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name(s) of the above copyright
+.\" holders shall not be used in advertising or otherwise to promote the
+.\" sale, use or other dealings in this Software without prior written
+.\" authorization.
+.\"
+.\" updated by Thomas E. Dickey for XFree86, 1998-2006.
+.\"
+.ds N Resize
+.ds n resize
+.\"
+.\" Bulleted paragraph
+.de bP
+.IP \(bu 4
+..
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds AQ \(aq
+.el       .ds AQ '
+.ie \n(.g .ds `` \(lq
+.el       .ds `` ``
+.ie \n(.g .ds '' \(rq
+.el       .ds '' ''
+.TH RESIZE 1 "__app_date__" "__app_version__" "X Window System"
+.SH NAME
+resize \- set environment and terminal settings to current xterm window size
+.SH SYNOPSIS
+.B \*n
+[ \fB\-v\fP | \fB\-u\fP | \fB\-c\fP ] [ \fB\-s\fP [ \fIrow col\fP ] ]
+.SH DESCRIPTION
+.I \*N
+prints a shell command for setting the appropriate environment variables
+to indicate the current size of \fIxterm\fP window from which the command
+is run.
+.PP
+.I \*N
+determines the command through several steps:
+.bP
+first, it finds the name of the user's shell program.
+It uses the \fBSHELL\fP variable if set,
+otherwise it uses the user's data from /etc/passwd.
+.bP
+then it decides whether to use Bourne shell syntax or C-Shell syntax.
+It uses a built-in table of known shells,
+which can be overridden by the \fB\-u\fP and \fB\-c\fP options.
+.bP
+then \fI\*n\fP asks the operating system for the terminal settings.
+This is the same information which can be manipulated using \fIstty\fP.
+.bP
+then \fI\*n\fP asks the terminal for its size in characters.
+Depending on whether the "\fB\-s\fP option is given,
+\fI\*n\fP uses a different escape sequence to ask for this information.
+.bP
+at this point, \fI\*n\fP attempts to update the terminal settings
+to reflect the terminal window's size in pixels:
+.RS
+.bP
+if the \fB\-s\fP option is used,
+\fI\*n\fP then asks the terminal for its size in pixels.
+.bP
+otherwise,
+\fI\*n\fP asks the operating system for the information
+and updates that after ensuring that the window's dimensions are
+a multiple of the character height and width.
+.bP
+in either case, the updated terminal settings are done
+using a different system call than used for \fIstty\fP.
+.RE
+.bP
+then \fI\*n\fP updates the terminal settings to reflect any altered
+values such as its size in rows or columns.
+This affects the values shown by \fIstty\fP.
+.bP
+finally, \fI\*n\fP writes the shell command for setting the
+environment variables to the standard output.
+.SH EXAMPLES
+For \*n's output to take effect,
+\fI\*n\fP must either be evaluated
+as part of the command line (usually done with a shell alias or function) or
+else redirected to a file which can then be read in.
+From the C shell (usually
+known as \fI/bin/csh\fP), the following alias could be defined in the
+user's \fI.cshrc\fP:
+.sp
+.nf
+        %  alias rs \*(AQset noglob; eval \fC\`\fP\*n\fC\`\fP\*(AQ
+.fi
+.sp
+After resizing the window, the user would type:
+.sp
+.nf
+        %  rs
+.fi
+.sp
+Users of versions of the Bourne shell (usually known as \fI/bin/sh\fP) that
+don't have command
+functions will need to send the output to a temporary file and then read it back
+in with the \*(``.\*('' command:
+.sp
+.nf
+        $  \*n > /tmp/out
+        $  .\0/tmp/out
+.fi
+.SH OPTIONS
+The following options may be used with \fI\*n\fP:
+.TP 8
+.B \-c
+This option indicates that C shell commands should be generated even if the
+user's current shell is not \fI/bin/csh\fP.
+.TP 8
+.B \-s \fR[\fIrows columns\fP]
+This option indicates that Sun console escape sequences will be used
+instead of the VT100-style \fIxterm\fP escape codes.
+If \fIrows\fP and
+\fIcolumns\fP are given,
+\fI\*n\fP will ask the \fIxterm\fP to resize itself using those values.
+.IP
+Both of the escape sequences used for this option
+(first to obtain the window size and
+second to modify it)
+are subject to \fIxterm\fP's \fBallowWindowOps\fP resource setting.
+The window manager may also choose to disallow the change.
+.IP
+The VT100-style escape sequence used to determine the
+screen size always works for VT100-compatible terminals.
+VT100s have no corresponding way to modify the screensize.
+.TP 8
+.B \-u
+This option indicates that Bourne shell commands should be generated even if
+the user's current shell is not \fI/bin/sh\fP.
+.TP 8
+.B \-v
+This causes \fI\*n\fP to print a version number to the standard output,
+and then exit.
+.PP
+Note that the Sun console escape sequences are recognized
+by XFree86 \fIxterm\fP and
+by \fIdtterm\fP.
+The \fI\*n\fP program may be installed as \fIsunsize\fP,
+which causes makes it assume the \fB\-s\fP option.
+.PP
+The \fIrows\fP and
+\fIcolumns\fP arguments must appear last; though they are normally
+associated with the \fB\-s\fP option, they are parsed separately.
+.SH FILES
+.TP 15
+/etc/termcap
+for the base termcap entry to modify.
+.TP 15
+~/.cshrc
+user's alias for the command.
+.SH ENVIRONMENT
+.TP 15
+SHELL
+.I \*N
+determines the user's current shell by first checking if \fB$SHELL\fP
+is set, and using that.
+Otherwise it determines the user's shell by looking in the password file
+(/etc/passwd).
+Generally Bourne-shell variants (including \fIksh\fP)
+do not modify \fB$SHELL\fP,
+so it is possible for \fI\*n\fP to be confused if one runs
+\fI\*n\fP from a Bourne shell spawned from a C shell.
+.TP 15
+TERM
+.I \*N
+sets this to "__default_termname__" if not already set.
+.TP 15
+TERMCAP
+.I \*N
+sets this variable on systems using termcap,
+e.g., when \*n is linked with the \fItermcap\fP library
+rather than a \fIterminfo\fP library.
+The latter does not provide the complete text for a termcap entry.
+.TP 15
+COLUMNS, LINES
+.I \*N
+sets these variables on systems using terminfo.
+Many applications (including the curses library) 
+use those variables when set to override their screensize.
+.SH "SEE ALSO"
+use_env(3x)
+.br
+csh(1), stty(1), tset(1)
+.br
+xterm(__mansuffix__)
+.SH AUTHORS
+Mark Vandevoorde (MIT-Athena), Edward Moy (Berkeley)
+.br
+Thomas Dickey (invisible-island.net).
+.br
+Copyright (c) 1984, 1985 by X Consortium
+.br
+See
+.IR X (__miscmansuffix__)
+for a complete copyright notice.
Index: src/usr.bin/resize/resize.c
diff -u /dev/null src/usr.bin/resize/resize.c:1.1
--- /dev/null	Sun Dec 27 21:13:18 2020
+++ src/usr.bin/resize/resize.c	Sun Dec 27 21:13:18 2020
@@ -0,0 +1,388 @@
+/* $NetBSD: resize.c,v 1.1 2020/12/27 21:13:18 reinoud Exp $ */
+/* $XTermId: resize.c,v 1.139 2017/05/31 08:58:56 tom Exp $ */
+
+/*
+ * Copyright 2003-2015,2017 by Thomas E. Dickey
+ *
+ *                         All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization.
+ *
+ *
+ * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ *                         All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital Equipment
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ *
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Extracted version from Xterm tailored for NetBSD
+ */
+/* resize.c */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <strings.h>
+#include <libgen.h>
+#include <termios.h>
+#include "xstrings.h"
+
+
+/* imported from origional <xterm.h> */
+#define DFT_TERMTYPE "xterm"
+#define UIntClr(dst,bits) dst = dst & (unsigned) ~(bits)
+
+#include <signal.h>
+#include <pwd.h>
+
+#define ESCAPE(string) "\033" string
+
+#define	EMULATIONS	2
+#define	SUN		1
+#define	VT100		0
+
+#define	TIMEOUT		10
+
+#define	SHELL_UNKNOWN	0
+#define	SHELL_C		1
+#define	SHELL_BOURNE	2
+/* *INDENT-OFF* */
+static struct {
+    const char *name;
+    int type;
+} shell_list[] = {
+    { "csh",	SHELL_C },	/* vanilla cshell */
+    { "jcsh",   SHELL_C },
+    { "tcsh",   SHELL_C },
+    { "sh",	SHELL_BOURNE }, /* vanilla Bourne shell */
+    { "ash",    SHELL_BOURNE },
+    { "bash",	SHELL_BOURNE }, /* GNU Bourne again shell */
+    { "dash",	SHELL_BOURNE },
+    { "jsh",    SHELL_BOURNE },
+    { "ksh",	SHELL_BOURNE }, /* Korn shell (from AT&T toolchest) */
+    { "ksh-i",	SHELL_BOURNE }, /* another name for Korn shell */
+    { "ksh93",	SHELL_BOURNE }, /* Korn shell */
+    { "mksh",   SHELL_BOURNE },
+    { "pdksh",  SHELL_BOURNE },
+    { "zsh",    SHELL_BOURNE },
+    { NULL,	SHELL_BOURNE }	/* default (same as xterm's) */
+};
+/* *INDENT-ON* */
+
+static const char *const emuname[EMULATIONS] =
+{
+    "VT100",
+    "Sun",
+};
+static char *myname;
+static int shell_type = SHELL_UNKNOWN;
+static const char *const getsize[EMULATIONS] =
+{
+    ESCAPE("7") ESCAPE("[r") ESCAPE("[9999;9999H") ESCAPE("[6n"),
+    ESCAPE("[18t"),
+};
+static const char *const restore[EMULATIONS] =
+{
+    ESCAPE("8"),
+    0,
+};
+static const char *const setsize[EMULATIONS] =
+{
+    0,
+    ESCAPE("[8;%s;%st"),
+};
+
+static struct termios tioorig;
+
+static const char *const size[EMULATIONS] =
+{
+    ESCAPE("[%d;%dR"),
+    ESCAPE("[8;%d;%dt"),
+};
+static const char sunname[] = "sunsize";
+static int tty;
+static FILE *ttyfp;
+
+
+static void
+failed(const char *s)
+{
+    int save = errno;
+    IGNORE_RC(write(2, myname, strlen(myname)));
+    IGNORE_RC(write(2, ": ", (size_t) 2));
+    errno = save;
+    perror(s);
+    exit(EXIT_FAILURE);
+}
+
+/* ARGSUSED */
+static void
+onintr(int sig GCC_UNUSED)
+{
+    (void) tcsetattr(tty, TCSADRAIN, &tioorig);
+    exit(EXIT_FAILURE);
+}
+
+static void
+resize_timeout(int sig)
+{
+    fprintf(stderr, "\n%s: Time out occurred\r\n", myname);
+    onintr(sig);
+}
+
+static void
+Usage(void)
+{
+    fprintf(stderr, strcmp(myname, sunname) == 0 ?
+	    "Usage: %s [rows cols]\n" :
+	    "Usage: %s [-v] [-u] [-c] [-s [rows cols]]\n", myname);
+    exit(EXIT_FAILURE);
+}
+
+
+static int
+checkdigits(char *str)
+{
+    while (*str) {
+	if (!isdigit(CharOf(*str)))
+	    return (0);
+	str++;
+    }
+    return (1);
+}
+
+static void
+readstring(FILE *fp, char *buf, const char *str)
+{
+    int last, c;
+    struct itimerval it;
+
+    signal(SIGALRM, resize_timeout);
+    memset((char *) &it, 0, sizeof(struct itimerval));
+    it.it_value.tv_sec = TIMEOUT;
+    setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
+    if ((c = getc(fp)) == 0233) {	/* meta-escape, CSI */
+	c = ESCAPE("")[0];
+	*buf++ = (char) c;
+	*buf++ = '[';
+    } else {
+	*buf++ = (char) c;
+    }
+    if (c != *str) {
+	fprintf(stderr, "%s: unknown character, exiting.\r\n", myname);
+	onintr(0);
+    }
+    last = str[strlen(str) - 1];
+    while ((*buf++ = (char) getc(fp)) != last) {
+	;
+    }
+    memset((char *) &it, 0, sizeof(struct itimerval));
+    setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
+    *buf = 0;
+}
+
+/*
+   resets termcap string to reflect current screen size
+ */
+int
+main(int argc, char **argv ENVP_ARG)
+{
+    char *ptr;
+    int emu = VT100;
+    char *shell;
+    int i;
+    int rc;
+    int rows, cols;
+    struct termios tio;
+    char buf[BUFSIZ];
+    char *name_of_tty;
+    const char *setname = "";
+
+    myname = x_basename(argv[0]);
+    if (strcmp(myname, sunname) == 0)
+	emu = SUN;
+    for (argv++, argc--; argc > 0 && **argv == '-'; argv++, argc--) {
+	switch ((*argv)[1]) {
+	case 's':		/* Sun emulation */
+	    if (emu == SUN)
+		Usage();	/* Never returns */
+	    emu = SUN;
+	    break;
+	case 'u':		/* Bourne (Unix) shell */
+	    shell_type = SHELL_BOURNE;
+	    break;
+	case 'c':		/* C shell */
+	    shell_type = SHELL_C;
+	    break;
+	case 'v':
+	    printf("Xterm(330)\n");
+	    exit(EXIT_SUCCESS);
+	default:
+	    Usage();		/* Never returns */
+	}
+    }
+
+    if (SHELL_UNKNOWN == shell_type) {
+	/* Find out what kind of shell this user is running.
+	 * This is the same algorithm that xterm uses.
+	 */
+	if ((ptr = x_getenv("SHELL")) == NULL) {
+	    uid_t uid = getuid();
+	    struct passwd pw;
+
+	    if (x_getpwuid(uid, &pw)) {
+		(void) x_getlogin(uid, &pw);
+	    }
+	    if (!OkPasswd(&pw)
+		|| *(ptr = pw.pw_shell) == 0) {
+		/* this is the same default that xterm uses */
+		ptr = x_strdup("/bin/sh");
+	    }
+	}
+
+	shell = x_basename(ptr);
+
+	/* now that we know, what kind is it? */
+	for (i = 0; shell_list[i].name; i++) {
+	    if (!strcmp(shell_list[i].name, shell)) {
+		break;
+	    }
+	}
+	shell_type = shell_list[i].type;
+    }
+
+    if (argc == 2) {
+	if (!setsize[emu]) {
+	    fprintf(stderr,
+		    "%s: Can't set window size under %s emulation\n",
+		    myname, emuname[emu]);
+	    exit(EXIT_FAILURE);
+	}
+	if (!checkdigits(argv[0]) || !checkdigits(argv[1])) {
+	    Usage();		/* Never returns */
+	}
+    } else if (argc != 0) {
+	Usage();		/* Never returns */
+    }
+	name_of_tty = x_strdup("/dev/tty");
+
+    if ((ttyfp = fopen(name_of_tty, "r+")) == NULL) {
+	fprintf(stderr, "%s:  can't open terminal %s\n",
+		myname, name_of_tty);
+	exit(EXIT_FAILURE);
+    }
+    tty = fileno(ttyfp);
+    if (x_getenv("TERM") == 0) {
+	if (SHELL_BOURNE == shell_type) {
+	    setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n";
+	} else {
+	    setname = "setenv TERM " DFT_TERMTYPE ";\n";
+	}
+    }
+
+    rc = tcgetattr(tty, &tioorig);
+    tio = tioorig;
+    UIntClr(tio.c_iflag, ICRNL);
+    UIntClr(tio.c_lflag, (ICANON | ECHO));
+    tio.c_cflag |= CS8;
+    tio.c_cc[VMIN] = 6;
+    tio.c_cc[VTIME] = 1;
+    if (rc != 0)
+	failed("get tty settings");
+
+    signal(SIGINT, onintr);
+    signal(SIGQUIT, onintr);
+    signal(SIGTERM, onintr);
+
+    rc = tcsetattr(tty, TCSADRAIN, &tio);
+    if (rc != 0)
+	failed("set tty settings");
+
+    if (argc == 2) {		/* look for optional parameters of "-s" */
+	char *tmpbuf = TypeMallocN(char,
+				   strlen(setsize[emu]) +
+				   strlen(argv[0]) +
+				   strlen(argv[1]) +
+				   1);
+	if (tmpbuf == 0) {
+	    fprintf(stderr, "%s: Cannot query size\n", myname);
+	    onintr(0);
+	} else {
+	    sprintf(tmpbuf, setsize[emu], argv[0], argv[1]);
+	    IGNORE_RC(write(tty, tmpbuf, strlen(tmpbuf)));
+	    free(tmpbuf);
+	}
+    }
+    IGNORE_RC(write(tty, getsize[emu], strlen(getsize[emu])));
+    readstring(ttyfp, buf, size[emu]);
+    if (sscanf(buf, size[emu], &rows, &cols) != 2) {
+	fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
+	onintr(0);
+    }
+    if (restore[emu])
+	IGNORE_RC(write(tty, restore[emu], strlen(restore[emu])));
+
+    rc = tcsetattr(tty, TCSADRAIN, &tioorig);
+    if (rc != 0)
+	failed("set tty settings");
+
+    signal(SIGINT, SIG_DFL);
+    signal(SIGQUIT, SIG_DFL);
+    signal(SIGTERM, SIG_DFL);
+
+
+    if (SHELL_BOURNE == shell_type) {
+
+	printf("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n",
+	       setname, cols, rows);
+
+    } else {			/* not Bourne shell */
+
+	printf("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n",
+	       setname, cols, rows);
+    }
+    exit(EXIT_SUCCESS);
+}
Index: src/usr.bin/resize/xstrings.c
diff -u /dev/null src/usr.bin/resize/xstrings.c:1.1
--- /dev/null	Sun Dec 27 21:13:18 2020
+++ src/usr.bin/resize/xstrings.c	Sun Dec 27 21:13:18 2020
@@ -0,0 +1,580 @@
+/* $NetBSD: xstrings.c,v 1.1 2020/12/27 21:13:18 reinoud Exp $ */
+/* $XTermId: xstrings.c,v 1.70 2017/06/11 21:20:37 tom Exp $ */
+
+/*
+ * Copyright 2000-2016,2017 by Thomas E. Dickey
+ *
+ *                         All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization.
+ */
+
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "xstrings.h"
+
+static void
+alloc_pw(struct passwd *target, struct passwd *source)
+{
+    *target = *source;
+    /* we care only about these strings */
+    target->pw_dir = x_strdup(source->pw_dir);
+    target->pw_name = x_strdup(source->pw_name);
+    target->pw_shell = x_strdup(source->pw_shell);
+}
+
+static void
+free_pw(struct passwd *source)
+{
+    free(source->pw_dir);
+    free(source->pw_name);
+    free(source->pw_shell);
+}
+
+void
+x_appendargv(char **target, char **source)
+{
+    if (target && source) {
+	target += x_countargv(target);
+	while ((*target++ = *source++) != 0) ;
+    }
+}
+
+char *
+x_basename(char *name)
+{
+    char *cp;
+
+    cp = strrchr(name, '/');
+    return (cp ? cp + 1 : name);
+}
+
+unsigned
+x_countargv(char **argv)
+{
+    unsigned result = 0;
+    if (argv) {
+	while (*argv++) {
+	    ++result;
+	}
+    }
+    return result;
+}
+
+/*
+ * Decode a hexadecimal string, returning the decoded string.
+ * On return, 'next' points to the first character not part of the input.
+ * The caller must free the result.
+ */
+char *
+x_decode_hex(const char *source, const char **next)
+{
+    char *result = 0;
+    int pass;
+    size_t j, k;
+
+    for (pass = 0; pass < 2; ++pass) {
+	for (j = k = 0; isxdigit(CharOf(source[j])); ++j) {
+	    if ((pass != 0) && (j & 1) != 0) {
+		result[k++] = (char) ((x_hex2int(source[j - 1]) << 4)
+				      | x_hex2int(source[j]));
+	    }
+	}
+	*next = (source + j);
+	if ((j & 1) == 0) {
+	    if (pass) {
+		result[k] = '\0';
+	    } else {
+		result = malloc(++j);
+		if (result == 0)
+		    break;	/* not enough memory */
+	    }
+	} else {
+	    break;		/* must have an even number of digits */
+	}
+    }
+    return result;
+}
+
+/*
+ * Encode a string into hexadecimal, returning the encoded string.
+ * The caller must free the result.
+ */
+char *
+x_encode_hex(const char *source)
+{
+    size_t need = (strlen(source) * 2) + 1;
+    char *result = malloc(need);
+
+    if (result != 0) {
+	unsigned j, k;
+	for (j = k = 0; source[j] != '\0'; ++j) {
+	    sprintf(result + k, "%02X", CharOf(source[j]));
+	    k += 2;
+	}
+    }
+    return result;
+}
+
+char *
+x_getenv(const char *name)
+{
+    char *result;
+    result = x_strdup(x_nonempty(getenv(name)));
+    TRACE2(("getenv(%s) %s\n", name, result));
+    return result;
+}
+
+static char *
+login_alias(char *login_name, uid_t uid, struct passwd *in_out)
+{
+    /*
+     * If the logon-name differs from the value we get by looking in the
+     * password file, check if it does correspond to the same uid.  If so,
+     * allow that as an alias for the uid.
+     */
+    if (!IsEmpty(login_name)
+	&& strcmp(login_name, in_out->pw_name)) {
+	struct passwd pw2;
+	Boolean ok2;
+
+	if ((ok2 = x_getpwnam(login_name, &pw2))) {
+	    uid_t uid2 = pw2.pw_uid;
+	    struct passwd pw3;
+	    Boolean ok3;
+
+	    if ((ok3 = x_getpwuid(uid, &pw3))
+		&& ((uid_t) pw3.pw_uid == uid2)) {
+		/* use the other passwd-data including shell */
+		alloc_pw(in_out, &pw2);
+	    } else {
+		free(login_name);
+		login_name = NULL;
+	    }
+	    if (ok2)
+		free_pw(&pw2);
+	    if (ok3)
+		free_pw(&pw3);
+	}
+    }
+    return login_name;
+}
+
+/*
+ * Call this with in_out pointing to data filled in by x_getpwnam() or by
+ * x_getpwnam().  It finds the user's logon name, if possible.  As a side
+ * effect, it updates in_out to fill in possibly more-relevant data, i.e.,
+ * in case there is more than one alias for the same uid.
+ */
+char *
+x_getlogin(uid_t uid, struct passwd *in_out)
+{
+    char *login_name = NULL;
+
+    login_name = login_alias(x_getenv("LOGNAME"), uid, in_out);
+    if (IsEmpty(login_name)) {
+	free(login_name);
+	login_name = login_alias(x_getenv("USER"), uid, in_out);
+    }
+#ifdef HAVE_GETLOGIN
+    /*
+     * Of course getlogin() will fail if we're started from a window-manager,
+     * since there's no controlling terminal to fuss with.  For that reason, we
+     * tried first to get something useful from the user's $LOGNAME or $USER
+     * environment variables.
+     */
+    if (IsEmpty(login_name)) {
+	TRACE2(("...try getlogin\n"));
+	free(login_name);
+	login_name = login_alias(x_strdup(getlogin()), uid, in_out);
+    }
+#endif
+
+    if (IsEmpty(login_name)) {
+	free(login_name);
+	login_name = x_strdup(in_out->pw_name);
+    }
+
+    TRACE2(("x_getloginid ->%s\n", NonNull(login_name)));
+    return login_name;
+}
+
+/*
+ * Simpler than getpwnam_r, retrieves the passwd result by name and stores the
+ * result via the given pointer.  On failure, wipes the data to prevent use.
+ */
+Boolean
+x_getpwnam(const char *name, struct passwd *result)
+{
+    struct passwd *ptr = getpwnam(name);
+    Boolean code;
+
+    if (ptr != 0 && OkPasswd(ptr)) {
+	code = True;
+	alloc_pw(result, ptr);
+    } else {
+	code = False;
+	memset(result, 0, sizeof(*result));
+    }
+    return code;
+}
+
+/*
+ * Simpler than getpwuid_r, retrieves the passwd result by uid and stores the
+ * result via the given pointer.  On failure, wipes the data to prevent use.
+ */
+Boolean
+x_getpwuid(uid_t uid, struct passwd *result)
+{
+    struct passwd *ptr = getpwuid((uid_t) uid);
+    Boolean code;
+
+    if (ptr != 0 && OkPasswd(ptr)) {
+	code = True;
+	alloc_pw(result, ptr);
+    } else {
+	code = False;
+	memset(result, 0, sizeof(*result));
+    }
+    TRACE2(("x_getpwuid(%d) %d\n", (int) uid, (int) code));
+    return code;
+}
+
+/*
+ * Decode a single hex "nibble", returning the nibble as 0-15, or -1 on error.
+ */
+int
+x_hex2int(int c)
+{
+    if (c >= '0' && c <= '9')
+	return c - '0';
+    if (c >= 'a' && c <= 'f')
+	return c - 'a' + 10;
+    if (c >= 'A' && c <= 'F')
+	return c - 'A' + 10;
+    return -1;
+}
+
+/*
+ * Check if the given string is nonnull/nonempty.  If so, return a pointer
+ * to the beginning of its content, otherwise return null.
+ */
+String
+x_nonempty(String s)
+{
+    if (s != 0) {
+	if (*s == '\0') {
+	    s = 0;
+	} else {
+	    s = x_skip_blanks(s);
+	    if (*s == '\0')
+		s = 0;
+	}
+    }
+    return s;
+}
+
+String
+x_skip_blanks(String s)
+{
+    while (IsSpace(CharOf(*s)))
+	++s;
+    return s;
+}
+
+String
+x_skip_nonblanks(String s)
+{
+    while (*s != '\0' && !IsSpace(CharOf(*s)))
+	++s;
+    return s;
+}
+
+static const char *
+skip_blanks(const char *s)
+{
+    while (IsSpace(CharOf(*s)))
+	++s;
+    return s;
+}
+
+/*
+ * Split a command-string into an argv[]-style array.
+ */
+char **
+x_splitargs(const char *command)
+{
+    char **result = 0;
+
+    if (command != 0) {
+	const char *first = skip_blanks(command);
+	char *blob = x_strdup(first);
+
+	if (blob != 0) {
+	    int pass;
+
+	    for (pass = 0; pass < 2; ++pass) {
+		int state;
+		size_t count;
+		size_t n;
+
+		for (n = count = 0, state = 0; first[n] != '\0'; ++n) {
+
+		    switch (state) {
+		    case 0:
+			if (!IsSpace(CharOf(first[n]))) {
+			    state = 1;
+			    if (pass)
+				result[count] = blob + n;
+			    ++count;
+			} else {
+			    blob[n] = '\0';
+			}
+			break;
+		    case 1:
+			if (IsSpace(CharOf(first[n]))) {
+			    blob[n] = '\0';
+			    state = 0;
+			}
+			break;
+		    }
+		}
+		if (!pass) {
+		    result = TypeCallocN(char *, count + 1);
+		    if (!result) {
+			free(blob);
+			break;
+		    }
+		}
+	    }
+	}
+    } else {
+	result = TypeCalloc(char *);
+    }
+    return result;
+}
+
+/*
+ * Free storage allocated by x_splitargs().
+ */
+void
+x_freeargs(char **argv)
+{
+    if (argv != 0) {
+	if (*argv != 0)
+	    free(*argv);
+	free(argv);
+    }
+}
+
+int
+x_strcasecmp(const char *s1, const char *s2)
+{
+    size_t len = strlen(s1);
+
+    if (len != strlen(s2))
+	return 1;
+
+    return x_strncasecmp(s1, s2, (unsigned) len);
+}
+
+int
+x_strncasecmp(const char *s1, const char *s2, unsigned n)
+{
+    while (n-- != 0) {
+	char c1 = x_toupper(*s1);
+	char c2 = x_toupper(*s2);
+	if (c1 != c2)
+	    return 1;
+	if (c1 == 0)
+	    break;
+	s1++, s2++;
+    }
+
+    return 0;
+}
+
+/*
+ * Allocates a copy of a string
+ */
+char *
+x_strdup(const char *s)
+{
+    char *result = 0;
+
+    if (s != 0) {
+	char *t = TextAlloc(4 + strlen(s));
+	if (t != 0) {
+	    strcpy(t, s);
+	}
+	result = t;
+    }
+    return result;
+}
+
+/*
+ * Returns a pointer to the first occurrence of s2 in s1,
+ * or NULL if there are none.
+ */
+char *
+x_strindex(char *s1, const char *s2)
+{
+    char *s3;
+    size_t s2len = strlen(s2);
+
+    while ((s3 = (strchr) (s1, *s2)) != NULL) {
+	if (strncmp(s3, s2, s2len) == 0)
+	    return (s3);
+	s1 = ++s3;
+    }
+    return (NULL);
+}
+
+/*
+ * Trims leading/trailing spaces from a copy of the string.
+ */
+char *
+x_strtrim(const char *source)
+{
+    char *result;
+
+    if (source != 0 && *source != '\0') {
+	char *t = x_strdup(source);
+	if (t != 0) {
+	    char *s = t;
+	    char *d = s;
+	    while (IsSpace(CharOf(*s)))
+		++s;
+	    while ((*d++ = *s++) != '\0') {
+		;
+	    }
+	    if (*t != '\0') {
+		s = t + strlen(t);
+		while (s != t && IsSpace(CharOf(s[-1]))) {
+		    *--s = '\0';
+		}
+	    }
+	}
+	result = t;
+    } else {
+	result = x_strdup("");
+    }
+    return result;
+}
+
+/*
+ * Trims trailing whitespace from a copy of the string.
+ */
+char *
+x_strrtrim(const char *source)
+{
+    char *result;
+
+    if (source != 0 && *source != '\0') {
+	char *t = x_strdup(source);
+	if (t != 0) {
+	    if (*t != '\0') {
+		char *s = t + strlen(t);
+		while (s != t && IsSpace(CharOf(s[-1]))) {
+		    *--s = '\0';
+		}
+	    }
+	}
+	result = t;
+    } else {
+	result = x_strdup("");
+    }
+    return result;
+}
+
+/*
+ * Avoid using system locale for upper/lowercase conversion, since there are
+ * a few locales where toupper(tolower(c)) != c.
+ */
+char
+x_toupper(int ch)
+{
+    static char table[256];
+    char result = table[CharOf(ch)];
+
+    if (result == '\0') {
+	unsigned n;
+	static const char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+	for (n = 0; n < sizeof(table); ++n) {
+	    table[n] = (char) n;
+	}
+	for (n = 0; s[n] != '\0'; ++n) {
+	    table[CharOf(s[n])] = s[n % 26];
+	}
+	result = table[CharOf(ch)];
+    }
+
+    return result;
+}
+
+/*
+ * Match strings ignoring case and allowing glob-like '*' and '?'
+ */
+int
+x_wildstrcmp(const char *pattern, const char *actual)
+{
+    int result = 0;
+
+    while (*pattern && *actual) {
+	char c1 = x_toupper(*pattern);
+	char c2 = x_toupper(*actual);
+
+	if (c1 == '*') {
+	    Boolean found = False;
+	    pattern++;
+	    while (*actual != '\0') {
+		if (!x_wildstrcmp(pattern, actual++)) {
+		    found = True;
+		    break;
+		}
+	    }
+	    if (!found) {
+		result = 1;
+		break;
+	    }
+	} else if (c1 == '?') {
+	    ++pattern;
+	    ++actual;
+	} else if ((result = (c1 != c2)) == 0) {
+	    ++pattern;
+	    ++actual;
+	} else {
+	    break;
+	}
+    }
+    return result;
+}
Index: src/usr.bin/resize/xstrings.h
diff -u /dev/null src/usr.bin/resize/xstrings.h:1.1
--- /dev/null	Sun Dec 27 21:13:18 2020
+++ src/usr.bin/resize/xstrings.h	Sun Dec 27 21:13:18 2020
@@ -0,0 +1,87 @@
+/* $NetBSD: xstrings.h,v 1.1 2020/12/27 21:13:18 reinoud Exp $ */
+/* $XTermId: xstrings.h,v 1.30 2016/12/22 23:48:38 tom Exp $ */
+
+/*
+ * Copyright 2000-2015,2016 by Thomas E. Dickey
+ *
+ *                         All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization.
+ */
+
+#ifndef included_xstrings_h
+#define included_xstrings_h 1
+/* *INDENT-OFF* */
+
+#include <pwd.h>
+
+#include <stdbool.h>
+#define Boolean bool
+#define True true
+#define False false
+
+#define String char *
+#define ENVP_ARG
+#define GCC_UNUSED
+#define IGNORE_RC(a) (void) a
+#define TRACE2(a)
+
+#define TextAlloc(l) (char *) malloc((l))
+#define CharOf(a) ((int)(a))
+#define IsSpace(a) isspace((a))
+#define IsEmpty(s) ((s) == 0 || *(s) == '\0')
+#define TypeCallocN(type,n)  (type *)calloc((size_t) (n), sizeof(type))
+#define TypeCalloc(type)     TypeCallocN(type, 1)
+#define TypeMallocN(type,n)  TypeCallocN(type, n)
+
+#define OkPasswd(p) ((p)->pw_name != 0 && (p)->pw_name[0] != 0)
+
+extern Boolean x_getpwnam(const char * /* name */, struct passwd * /* result */);
+extern Boolean x_getpwuid(uid_t /* uid */, struct passwd * /* result */);
+extern String x_nonempty(String /* s */);
+extern String x_skip_blanks(String /* s */);
+extern String x_skip_nonblanks(String /* s */);
+extern char **x_splitargs(const char * /* command */);
+extern char *x_basename(char * /* name */);
+extern char *x_decode_hex(const char * /* source */, const char ** /* next */);
+extern char *x_encode_hex(const char * /* source */);
+extern char *x_getenv(const char * /* name */);
+extern char *x_getlogin(uid_t /* uid */, struct passwd * /* in_out */);
+extern char *x_strdup(const char * /* s */);
+extern char *x_strindex(char * /* s1 */, const char * /* s2 */);
+extern char *x_strtrim(const char * /* s */);
+extern char *x_strrtrim(const char * /* s */);
+extern char x_toupper(int /* ch */);
+extern int x_hex2int(int /* ch */);
+extern int x_strcasecmp(const char * /* s1 */, const char * /* s2 */);
+extern int x_strncasecmp(const char * /* s1 */, const char * /* s2 */, unsigned  /* n */);
+extern int x_wildstrcmp(const char * /* pattern */, const char * /* actual */);
+extern unsigned x_countargv(char ** /* argv */);
+extern void x_appendargv(char ** /* target */, char ** /* source */);
+extern void x_freeargs(char ** /* argv */);
+
+/* *INDENT-ON* */
+
+#endif /* included_xstrings_h */

Reply via email to