Subject: Re: finger
To: None <kim@tac.nyc.ny.us>
From: T.SHIOZAKI <tshiozak@astec.co.jp>
List: tech-userlevel
Date: 09/10/2002 23:05:40
From: Kimmo Suominen <kim@tac.nyc.ny.us>
Subject: Re: finger
Date: Tue, 10 Sep 2002 07:57:46 -0400
Message-ID: <20020910115746.607587E10@beowulf.gw.com>

> Your change violates the recommendation in RFC-1288 that there
> be a way for the administrator to enable system-wide the display
> of 8-bit characters (i.e. characters over ASCII 126).

Do you say about the folloing sentence?

> 3.3.  Client security
..snip..
>    For environments that live and breathe international data, the system
>    administrator SHOULD be given a mechanism to enable the latter option
>    by default for all users on a particular system.  This can be done
>    via a global environment variable or similar mechanism.

Your change seems to violate this recommendation, too.
LC_CTYPE environment variable is NOT system-wide parameter.
There is no *global* environment variable, although I easily
add some code to look up some environment variable.

Anyway, this is NOT essential in this discussion.
The point is whether we should use ISO C locale system for our
finger program.


> Removing all protection from non-printable characters seems also
> quite against the recommendations in RFC-1288.  I was not trying
> to add pass-through of control characters.

OK, I have fixed it to conform to rfc1288 strictly in this point.
Thanks for your comment.

BTW, your way doesn't ensure to conform to this recommendation strictly,
because of the principle of ISO C locale system.


> Therefore, I oppose to your proposed change.

Hmm, I (itojun and others) pointed out the essential problems of
your change.  On the other hand, any indications you mentioned seem
not essential.

If you apply rfc1288 to our finger, you should not use setlocale()
and any ctype.h functions (except for a few functions).

While using ISO C locale system, we cannot touch any character code
directly, except for a few cases.  However, rfc1288 is hard-wired to
ASCII and mentions some concrete octet limits.  Thus, ISO C locale
system conflicts with rfc1288.

P.S.
In view of i18n, rfc1288 is too thoughtless.
This mentions nothing about I18N,
but something about "8bit through" only.
The i18n part of this document has been quite obsoleted.


Here is a new patch for finger.
This patch is not fine (because of rfc1288),
but this is better than using setlocale().


--- /dev/null	Tue Sep 10 16:36:41 2002
+++ src/usr.bin/finger/ascii.h	Tue Sep 10 16:37:29 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) || ascii_isspace(c))
+#define ascii_isdigit(c) ((c)>='0' && (c)<='9')
+#define ascii_isascii(c) ((c)>=0 && (c)<=0x7F)
--- src/usr.bin/finger/extern.h	2002/08/02 00:10:40	1.7
+++ src/usr.bin/finger/extern.h	2002/09/10 13:37:29
@@ -43,6 +43,7 @@
 extern int oflag;
 extern int gflag;
 extern int pplan;
+extern int b8flag;
 
 void	 enter_lastlog __P((PERSON *));
 PERSON	*enter_person __P((struct passwd *));
--- src/usr.bin/finger/finger.c	2002/09/10 03:02:40	1.20
+++ src/usr.bin/finger/finger.c	2002/09/10 13:37:29
@@ -87,9 +87,6 @@
 #include <time.h>
 #include <unistd.h>
 
-#include <locale.h>
-#include <langinfo.h>
-
 #include "utmpentry.h"
 
 #include "finger.h"
@@ -97,7 +94,7 @@
 
 DB *db;
 time_t now;
-int entries, gflag, lflag, mflag, oflag, sflag, pplan;
+int entries, gflag, lflag, mflag, oflag, sflag, pplan, b8flag;
 char tbuf[1024];
 struct utmpentry *ehead;
 
@@ -112,19 +109,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 */
@@ -146,6 +133,9 @@
 			break;
 		case 'g':
 			gflag = 1;		/* no gecos info, besides name */
+			break;
+		case '8':
+			b8flag = 1;		/* 8bit through */
 			break;
 		case '?':
 		default:
--- src/usr.bin/finger/lprint.c	2002/09/10 03:02:40	1.17
+++ src/usr.bin/finger/lprint.c	2002/09/10 13:37:30
@@ -59,7 +59,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
-#include <ctype.h>
 #include <string.h>
 #include <paths.h>
 #include <vis.h>
@@ -67,6 +66,7 @@
 #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 +364,10 @@
 {
 	char visout[5], *s2;
 
-	if ((isprint(ch)) || (isspace(ch))) {
+	if (ascii_isprint(ch) || (b8flag && !ascii_isascii(ch))) {
 	    (void)putchar(ch);
 	    return;
 	}
-	ch = toascii(ch);
 	vis(visout, ch, VIS_SAFE|VIS_NOSLASH, 0);
 	for (s2 = visout; *s2; s2++)
 		(void)putchar(*s2);
--- src/usr.bin/finger/net.c	2002/09/10 03:02:40	1.18
+++ src/usr.bin/finger/net.c	2002/09/10 13:37:30
@@ -59,7 +59,6 @@
 #include <pwd.h>
 #include <stdio.h>
 #include <string.h>
-#include <ctype.h>
 #include <unistd.h>
 #include <err.h>
 
@@ -67,6 +66,7 @@
 
 #include "finger.h"
 #include "extern.h"
+#include "ascii.h"
 
 void
 netfinger(name)
@@ -146,9 +146,9 @@
 				c = '\n';
 				lastc = '\r';
 			} else {
-				if (!isprint(c) && !isspace(c)) {
-					c &= 0x7f;
-					c |= 0x40;
+				if (!ascii_isprint(c) &&
+				    !(b8flag && !ascii_isascii(c))) {
+					c = '?';
 				}
 				if (lastc != '\r' || c != '\n')
 					lastc = c;
--- src/usr.bin/finger/util.c	2002/08/02 00:10:40	1.18
+++ src/usr.bin/finger/util.c	2002/09/10 13:37:30
@@ -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;



--
Takuya SHIOZAKI / ASTEC Products, Inc.