Subject: Re: workaround for pkg/14051
To: None <soda@sra.co.jp>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-userlevel
Date: 01/22/2002 02:00:42
----Next_Part(Tue_Jan_22_02:00:42_2002_641)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

From: Noriyuki Soda <soda@sra.co.jp>
> BTW, SUSv2 (*1) defines NL_CAT_LOCALE flag to use LC_MESSAGES on
> catopen(3), but it seems our catopen(3) doesn't look at it...
> Is this right thing? (This is questions to Klaus....)

I made patches(attached) and will commit it if no one objects.

- make symlinks(like de_DE.ISO8859-1 -> de) in /usr/share/nls.
- give the precedence to LC_ALL environment variable.
- implement NL_CAT_LOCALE and use it for strerror and strsignal.

---
YAMAMOTO Takashi<yamt@mwd.biglobe.ne.jp>

----Next_Part(Tue_Jan_22_02:00:42_2002_641)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="lcmsg.diff"

Index: locale/setlocale.c
===================================================================
RCS file: /cvs/cvsroot/basesrc/lib/libc/locale/setlocale.c,v
retrieving revision 1.35
diff -u -p -r1.35 setlocale.c
--- locale/setlocale.c	2001/04/17 20:12:32	1.35
+++ locale/setlocale.c	2002/01/21 16:41:02
@@ -49,6 +49,9 @@ __RCSID("$NetBSD: setlocale.c,v 1.35 200
 
 #include "namespace.h"
 #include <sys/localedef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
 #include <limits.h>
 #include <ctype.h>
 #define __SETLOCALE_SOURCE__
@@ -106,6 +109,7 @@ char *_PathLocale;
 
 static char *currentlocale __P((void));
 static char *loadlocale __P((int));
+static const char *__get_locale_env __P((int));
 
 char *
 __setlocale(category, locale)
@@ -114,7 +118,7 @@ __setlocale(category, locale)
 {
 	int i, loadlocale_success;
 	size_t len;
-	char *env, *r;
+	const char *env, *r;
 
 	if (issetugid() ||
 	    (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE"))))
@@ -138,28 +142,18 @@ __setlocale(category, locale)
 	 * Now go fill up new_categories from the locale argument
 	 */
 	if (!*locale) {
-		env = getenv(categories[category]);
-
-		if (!env || !*env)
-			env = getenv(categories[0]);
-
-		if (!env || !*env)
-			env = getenv("LANG");
-
-		if (!env || !*env || strchr(env, '/'))
-			env = "C";
-
-		(void)strlcpy(new_categories[category], env,
-		    sizeof(new_categories[category]));
-		if (!category) {
+		if (category == LC_ALL) {
 			for (i = 1; i < _LC_LAST; ++i) {
-				env = getenv(categories[i]);
-				if (!env || !*env || strchr(env, '/'))
-					env = new_categories[0];
+				env = __get_locale_env(category);
 				(void)strlcpy(new_categories[i], env,
 				    sizeof(new_categories[i]));
 			}
 		}
+		else {
+			env = __get_locale_env(category);
+			(void)strlcpy(new_categories[category], env,
+				sizeof(new_categories[category]));
+		}
 	} else if (category) {
 		(void)strlcpy(new_categories[category], locale,
 		    sizeof(new_categories[category]));
@@ -239,6 +233,8 @@ loadlocale(category)
 {
 	char name[PATH_MAX];
 
+	_DIAGASSERT(0 < category && category < _LC_LAST);
+
 	if (strcmp(new_categories[category], current_categories[category]) == 0)
 		return (current_categories[category]);
 
@@ -275,9 +271,6 @@ loadlocale(category)
 		return current_categories[category];
 	}
 
-	/*
-	 * Some day we will actually look at this file.
-	 */
 	(void)snprintf(name, sizeof(name), "%s/%s/%s",
 	    _PathLocale, new_categories[category], categories[category]);
 
@@ -296,19 +289,61 @@ loadlocale(category)
 		if (!__loadctype(name))
 			return NULL;
 #endif
+		break;
 
-		(void)strlcpy(current_categories[category],
-		    new_categories[category],
-		    sizeof(current_categories[category]));
-		return current_categories[category];
+	case LC_MESSAGES:
+		/*
+		 * XXX we don't have LC_MESSAGES support yet,
+		 * but catopen may use the value of LC_MESSAGE category.
+		 * so return successfully if locale directory is present.
+		 */
+		(void)snprintf(name, sizeof(name), "%s/%s",
+			_PathLocale, new_categories[category]);
+		/* local */
+		{
+			struct stat st;
+			if (stat(name, &st) < 0)
+				return NULL;
+			if (!S_ISDIR(st.st_mode))
+				return NULL;
+		}
+		break;
 
 	case LC_COLLATE:
-	case LC_MESSAGES:
 	case LC_MONETARY:
 	case LC_NUMERIC:
 	case LC_TIME:
 		return NULL;
 	}
+
+	(void)strlcpy(current_categories[category],
+		new_categories[category],
+		sizeof(current_categories[category]));
+	return current_categories[category];
+}
+
+static const char *
+__get_locale_env(category)
+	int category;
+{
+	const char *env;
+
+	_DIAGASSERT(category != LC_ALL);
+
+	/* 1. check LC_ALL. */
+	env = getenv(categories[0]);
+
+	/* 2. check LC_* */
+	if (!env || !*env)
+		env = getenv(categories[category]);
+
+	/* 3. check LANG */
+	if (!env || !*env)
+		env = getenv("LANG");
+
+	/* 4. if none is set, fall to "C" */
+	if (!env || !*env || strchr(env, '/'))
+		env = "C";
 
-	return NULL;
+	return env;
 }
Index: nls/Makefile.inc
===================================================================
RCS file: /cvs/cvsroot/basesrc/lib/libc/nls/Makefile.inc,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile.inc
--- nls/Makefile.inc	1996/05/13 23:29:32	1.8
+++ nls/Makefile.inc	2002/01/21 16:41:02
@@ -7,3 +7,69 @@ MAN+=	catclose.3 catgets.3 catopen.3
 
 # indirect reference stubs, to be removed soon.
 SRCS+=	_catclose.c _catgets.c _catopen.c
+
+# symbolic links for nls
+SYMLINKS+= cs ${NLSDIR}/cs_CZ.ISO8859-2
+#SYMLINKS+= da ${NLSDIR}/da_DK.ISO8859-1
+#SYMLINKS+= da ${NLSDIR}/da_DK.ISO8859-15
+SYMLINKS+= de ${NLSDIR}/de_AT.ISO8859-1
+SYMLINKS+= de ${NLSDIR}/de_AT.ISO8859-15
+SYMLINKS+= de ${NLSDIR}/de_CH.ISO8859-1
+SYMLINKS+= de ${NLSDIR}/de_CH.ISO8859-15
+SYMLINKS+= de ${NLSDIR}/de_DE.ISO8859-1
+SYMLINKS+= de ${NLSDIR}/de_DE.ISO8859-15
+#SYMLINKS+= en ${NLSDIR}/en_AU.ISO8859-1
+#SYMLINKS+= en ${NLSDIR}/en_AU.ISO8859-15
+#SYMLINKS+= en ${NLSDIR}/en_CA.ISO8859-1
+#SYMLINKS+= en ${NLSDIR}/en_CA.ISO8859-15
+#SYMLINKS+= en ${NLSDIR}/en_GB.ISO8859-1
+#SYMLINKS+= en ${NLSDIR}/en_GB.ISO8859-15
+#SYMLINKS+= en ${NLSDIR}/en_US.ISO8859-1
+#SYMLINKS+= en ${NLSDIR}/en_US.ISO8859-15
+#SYMLINKS+= en ${NLSDIR}/en_US.UTF-8
+SYMLINKS+= es ${NLSDIR}/es_ES.ISO8859-1
+SYMLINKS+= es ${NLSDIR}/es_ES.ISO8859-15
+SYMLINKS+= fi ${NLSDIR}/fi_FI.ISO8859-1
+SYMLINKS+= fi ${NLSDIR}/fi_FI.ISO8859-15
+SYMLINKS+= fr ${NLSDIR}/fr_BE.ISO8859-1
+SYMLINKS+= fr ${NLSDIR}/fr_BE.ISO8859-15
+SYMLINKS+= fr ${NLSDIR}/fr_CA.ISO8859-1
+SYMLINKS+= fr ${NLSDIR}/fr_CA.ISO8859-15
+SYMLINKS+= fr ${NLSDIR}/fr_CH.ISO8859-1
+SYMLINKS+= fr ${NLSDIR}/fr_CH.ISO8859-15
+SYMLINKS+= fr ${NLSDIR}/fr_FR.ISO8859-1
+SYMLINKS+= fr ${NLSDIR}/fr_FR.ISO8859-15
+#SYMLINKS+= hr ${NLSDIR}/hr_HR.ISO8859-2
+#SYMLINKS+= hu ${NLSDIR}/hu_HU.ISO8859-2
+#SYMLINKS+= is ${NLSDIR}/is_IS.ISO8859-1
+#SYMLINKS+= is ${NLSDIR}/is_IS.ISO8859-15
+#SYMLINKS+= it ${NLSDIR}/it_CH.ISO8859-1
+#SYMLINKS+= it ${NLSDIR}/it_CH.ISO8859-15
+#SYMLINKS+= it ${NLSDIR}/it_IT.ISO8859-1
+#SYMLINKS+= it ${NLSDIR}/it_IT.ISO8859-15
+#SYMLINKS+= ja ${NLSDIR}/ja_JP.ISO2022-JP
+#SYMLINKS+= ja ${NLSDIR}/ja_JP.ISO2022-JP2
+#SYMLINKS+= ja ${NLSDIR}/ja_JP.SJIS
+#SYMLINKS+= ja ${NLSDIR}/ja_JP.ct
+#SYMLINKS+= ja ${NLSDIR}/ja_JP.eucJP
+#SYMLINKS+= ko ${NLSDIR}/ko_KR.eucKR
+#SYMLINKS+= lt ${NLSDIR}/lt_LT.ISO8859-4
+SYMLINKS+= nl ${NLSDIR}/nl_BE.ISO8859-1
+SYMLINKS+= nl ${NLSDIR}/nl_BE.ISO8859-15
+SYMLINKS+= nl ${NLSDIR}/nl_NL.ISO8859-1
+SYMLINKS+= nl ${NLSDIR}/nl_NL.ISO8859-15
+SYMLINKS+= no ${NLSDIR}/no_NO.ISO8859-1
+SYMLINKS+= no ${NLSDIR}/no_NO.ISO8859-15
+SYMLINKS+= pl ${NLSDIR}/pl_PL.ISO8859-2
+#SYMLINKS+= pt ${NLSDIR}/pt_PT.ISO8859-1
+#SYMLINKS+= pt ${NLSDIR}/pt_PT.ISO8859-15
+#SYMLINKS+= ru ${NLSDIR}/ru_RU.CP866
+#SYMLINKS+= ru ${NLSDIR}/ru_RU.ISO8859-5
+#SYMLINKS+= ru ${NLSDIR}/ru_RU.KOI8-R
+#SYMLINKS+= sl ${NLSDIR}/sl_SI.ISO8859-2
+SYMLINKS+= sv ${NLSDIR}/sv_SE.ISO8859-1
+SYMLINKS+= sv ${NLSDIR}/sv_SE.ISO8859-15
+#SYMLINKS+= uk ${NLSDIR}/uk_UA.KOI8-U
+#SYMLINKS+= zh ${NLSDIR}/zh_CN.eucCN
+#SYMLINKS+= zh ${NLSDIR}/zh_TW.Big5
+#SYMLINKS+= zh ${NLSDIR}/zh_TW.eucTW
Index: nls/catopen.c
===================================================================
RCS file: /cvs/cvsroot/basesrc/lib/libc/nls/catopen.c,v
retrieving revision 1.18
diff -u -p -r1.18 catopen.c
--- nls/catopen.c	2000/09/30 16:47:26	1.18
+++ nls/catopen.c	2002/01/21 16:41:02
@@ -46,6 +46,7 @@
 #include <assert.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <locale.h>
 #include <nl_types.h>
 #include <stdlib.h>
 #include <string.h>
@@ -60,7 +61,6 @@ __weak_alias(catopen, _catopen)
 
 static nl_catd load_msgcat __P((const char *));
 
-/* ARGSUSED */
 nl_catd
 _catopen(name, oflag)
 	const char *name;
@@ -82,7 +82,13 @@ _catopen(name, oflag)
 
 	if (issetugid() || (nlspath = getenv("NLSPATH")) == NULL)
 		nlspath = NLS_DEFAULT_PATH;
-	if ((lang = getenv("LANG")) == NULL || strchr(lang, '/'))
+	if (oflag == NL_CAT_LOCALE) {
+		lang = setlocale(LC_MESSAGES, NULL);
+	}
+	else {
+		lang = getenv("LANG");
+	}
+	if (lang == NULL || strchr(lang, '/'))
 		lang = NLS_DEFAULT_LANG;
 
 	s = nlspath;
Index: string/__strerror.c
===================================================================
RCS file: /cvs/cvsroot/basesrc/lib/libc/string/__strerror.c,v
retrieving revision 1.17
diff -u -p -r1.17 __strerror.c
--- string/__strerror.c	2001/08/24 00:11:54	1.17
+++ string/__strerror.c	2002/01/21 16:41:02
@@ -72,7 +72,7 @@ __strerror(num, buf, buflen)
 #ifdef NLS
 	int saved_errno = errno;
 	nl_catd catd ;
-	catd = catopen("libc", 0);
+	catd = catopen("libc", NL_CAT_LOCALE);
 #endif
 	_DIAGASSERT(buf != NULL);
 
Index: string/__strsignal.c
===================================================================
RCS file: /cvs/cvsroot/basesrc/lib/libc/string/__strsignal.c,v
retrieving revision 1.19
diff -u -p -r1.19 __strsignal.c
--- string/__strsignal.c	1999/09/20 04:39:44	1.19
+++ string/__strsignal.c	2002/01/21 16:41:02
@@ -66,7 +66,7 @@ __strsignal(num, buf, buflen)
 
 #ifdef NLS
 	nl_catd catd ;
-	catd = catopen("libc", 0);
+	catd = catopen("libc", NL_CAT_LOCALE);
 #endif
 
 	_DIAGASSERT(buf != NULL);
Index: gettext.c
===================================================================
RCS file: /cvs/cvsroot/basesrc/lib/libintl/gettext.c,v
retrieving revision 1.12
diff -u -p -r1.12 gettext.c
--- gettext.c	2001/12/29 05:54:36	1.12
+++ gettext.c	2002/01/21 16:52:57
@@ -535,9 +535,9 @@ static const char *get_lang_env(const ch
 		return lang;
 
 	/* 2. if LANGUAGE isn't set, see LC_ALL, LC_xxx, LANG. */
-	lang = getenv(category_name);
+	lang = getenv("LC_ALL");
 	if (!lang)
-		lang = getenv("LC_ALL");
+		lang = getenv(category_name);
 	if (!lang)
 		lang = getenv("LANG");
 

----Next_Part(Tue_Jan_22_02:00:42_2002_641)----