Subject: Re: finger
To: None <tech-userlevel@netbsd.org>
From: T.SHIOZAKI <tshiozak@astec.co.jp>
List: tech-userlevel
Date: 09/11/2002 15:16:18
From: "T.SHIOZAKI" <tshiozak@astec.co.jp>
Subject: Re: finger
Date: Wed, 11 Sep 2002 14:26:02 +0900 (JST)
Message-ID: <20020911.142602.123363712.tshiozak@astec.co.jp>

> OK, I suggest a solution:
>   - finger(1) never use ISO C locale system when it is called from fingerd.
>     Administrators can choose the one of two modes:
>       - ASCII only (default)
>       - 0x20-0xFF through (-8)
>   - standalone finger(1) can working the one of three modes:
>       - ASCII only (default)
>       - use ISO C locale for single byte locales (-i)
>       - 0x20-0xFF through (-8)
> 
> Comments?

Here is the patch.  I will commit it tomorrow.


Index: ascii.h
===================================================================
RCS file: ascii.h
diff -N ascii.h
--- /dev/null	Wed Sep 11 09:07:43 2002
+++ ascii.h	Wed Sep 11 09:08:36 2002
@@ -0,0 +1,38 @@
+/* $NetBSD: $ */
+
+/*-
+ * Copyright (c)2002 Citrus Project,
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+/*
+ * ASCII-dependent ctype routines.
+ */
+
+#define ascii_isspace(c) ((c)==' '||(c)=='\f'||(c)=='\n'||(c)=='\r'||	\
+			  (c)=='\t'||(c)=='\v')
+#define ascii_isprint(c) ((c)>=0x20 && (c)<=0x7E)
+#define ascii_isdigit(c) ((c)>='0' && (c)<='9')
+#define ascii_isascii(c) ((c)>=0 && (c)<=0x7F)
Index: extern.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/finger/extern.h,v
retrieving revision 1.7
diff -u -r1.7 extern.h
--- extern.h	2002/08/02 00:10:40	1.7
+++ extern.h	2002/09/11 06:08:36
@@ -43,6 +43,8 @@
 extern int oflag;
 extern int gflag;
 extern int pplan;
+extern int iflag;
+extern int b8flag;
 
 void	 enter_lastlog __P((PERSON *));
 PERSON	*enter_person __P((struct passwd *));
Index: finger.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/finger/finger.c,v
retrieving revision 1.20
diff -u -r1.20 finger.c
--- finger.c	2002/09/10 03:02:40	1.20
+++ finger.c	2002/09/11 06:08:36
@@ -86,9 +86,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-
 #include <locale.h>
-#include <langinfo.h>
 
 #include "utmpentry.h"
 
@@ -97,7 +95,7 @@
 
 DB *db;
 time_t now;
-int entries, gflag, lflag, mflag, oflag, sflag, pplan;
+int entries, gflag, lflag, mflag, oflag, sflag, pplan, iflag, b8flag;
 char tbuf[1024];
 struct utmpentry *ehead;
 
@@ -112,19 +110,9 @@
 {
 	int ch;
 
-	/* Allow user's locale settings to affect character output. */
-	(void *) setlocale(LC_CTYPE, "");
-
-	/*
-	 * Reset back to the C locale, unless we are using a known
-	 * single-byte 8-bit locale.
-	 */
-	if (strncmp(nl_langinfo(CODESET), "ISO8859-", 8))
-	    (void *) setlocale(LC_CTYPE, "C");
-
 	oflag = 1;		/* default to old "office" behavior */
 
-	while ((ch = getopt(argc, argv, "lmpshog")) != -1)
+	while ((ch = getopt(argc, argv, "lmpshogi8")) != -1)
 		switch(ch) {
 		case 'l':
 			lflag = 1;		/* long format */
@@ -147,10 +135,17 @@
 		case 'g':
 			gflag = 1;		/* no gecos info, besides name */
 			break;
+		case 'i':
+			if (!iflag && setlocale(LC_CTYPE, "")!=NULL)
+				iflag = 1;	/* partial i18n mode */
+			break;
+		case '8':
+			b8flag = 1;		/* fully 8bit through */
+			break;
 		case '?':
 		default:
 			(void)fprintf(stderr,
-			    "usage: finger [-lmpshog] [login ...]\n");
+			    "usage: finger [-lmpshogi8] [login ...]\n");
 			exit(1);
 		}
 	argc -= optind;
Index: finger.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/finger/finger.h,v
retrieving revision 1.8
diff -u -r1.8 finger.h
--- finger.h	2002/08/02 00:10:40	1.8
+++ finger.h	2002/09/11 06:08:36
@@ -39,6 +39,9 @@
  */
 
 #define _PATH_MAILSPOOL "/var/mail"
+#define finger_isprint(ch)	(ascii_isprint(ch) || ascii_isspace(ch) ||  \
+				 (iflag && (isprint(ch) || isspace(ch))) || \
+				 (b8flag && !ascii_isascii(ch)))
 
 /*
  * All unique persons are linked in a list headed by "head" and linkd
Index: lprint.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/finger/lprint.c,v
retrieving revision 1.17
diff -u -r1.17 lprint.c
--- lprint.c	2002/09/10 03:02:40	1.17
+++ lprint.c	2002/09/11 06:08:36
@@ -58,15 +58,14 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
-#include <time.h>
 #include <ctype.h>
-#include <string.h>
 #include <paths.h>
 #include <vis.h>
 
 #include "utmpentry.h"
 #include "finger.h"
 #include "extern.h"
+#include "ascii.h"
 
 #define	LINE_LEN	80
 #define	TAB_LEN		8		/* 8 spaces between tabs */
@@ -364,11 +363,10 @@
 {
 	char visout[5], *s2;
 
-	if ((isprint(ch)) || (isspace(ch))) {
+	if (finger_isprint(ch)) {
 	    (void)putchar(ch);
 	    return;
 	}
-	ch = toascii(ch);
 	vis(visout, ch, VIS_SAFE|VIS_NOSLASH, 0);
 	for (s2 = visout; *s2; s2++)
 		(void)putchar(*s2);
Index: net.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/finger/net.c,v
retrieving revision 1.18
diff -u -r1.18 net.c
--- net.c	2002/09/10 03:02:40	1.18
+++ net.c	2002/09/11 06:08:36
@@ -67,6 +67,7 @@
 
 #include "finger.h"
 #include "extern.h"
+#include "ascii.h"
 
 void
 netfinger(name)
@@ -146,9 +147,8 @@
 				c = '\n';
 				lastc = '\r';
 			} else {
-				if (!isprint(c) && !isspace(c)) {
-					c &= 0x7f;
-					c |= 0x40;
+				if (!finger_isprint(c)) {
+					c = '?';
 				}
 				if (lastc != '\r' || c != '\n')
 					lastc = c;
Index: util.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/finger/util.c,v
retrieving revision 1.18
diff -u -r1.18 util.c
--- util.c	2002/08/02 00:10:40	1.18
+++ util.c	2002/09/11 06:08:37
@@ -50,7 +50,6 @@
 #include <sys/stat.h>
 
 #include <db.h>
-#include <ctype.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -66,6 +65,7 @@
 
 #include "finger.h"
 #include "extern.h"
+#include "ascii.h"
 
 static void	 find_idle_and_ttywrite __P((WHERE *));
 static void	 userinfo __P((PERSON *, struct passwd *));
@@ -292,7 +292,7 @@
 
 	/* don't touch anything if the user has their own formatting */
 	for (p = num; *p; ++p)
-		if (!isdigit((unsigned char)*p))
+		if (!ascii_isdigit((unsigned char)*p))
 			return(num);
 	len = p - num;
 	p = pbuf;


Index: fingerd.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/fingerd/fingerd.c,v
retrieving revision 1.18
diff -u -r1.18 fingerd.c
--- fingerd.c	2002/09/10 04:06:26	1.18
+++ fingerd.c	2002/09/11 06:14:44
@@ -84,7 +84,7 @@
 	logging = no_forward = user_required = short_list = 0;
 	openlog("fingerd", LOG_PID, LOG_DAEMON);
 	opterr = 0;
-	while ((ch = getopt(argc, argv, "gsluShmpP:i")) != -1)
+	while ((ch = getopt(argc, argv, "gsluShmpP:8")) != -1)
 		switch (ch) {
 		case 'l':
 			logging = 1;
@@ -98,18 +98,6 @@
 		case 'u':
 			user_required = 1;
 			break;
-		case 'i':
-			/*
-			 * This is a hack to enable single-byte 8-bit
-			 * characters in the output of the default
-			 * finger program.  The character set is not
-			 * communicated to the network client, and the
-			 * exact value does not matter much as long
-			 * as it enables as many 8-bit characters as
-			 * possible.
-			 */
-			(void) putenv("LC_CTYPE=en_US.ISO8859-15");
-			break;
 		case 'S':
 			short_list = 1;
 			av[ac++] = "-s";
@@ -125,6 +113,9 @@
 			break;
 		case 'g':
 			av[ac++] = "-g";
+			break;
+		case '8':
+			av[ac++] = "-8";
 			break;
 		case '?':
 		default:



--
Takuya SHIOZAKI / ASTEC Products, Inc.