xref: /minix3/external/bsd/bind/dist/contrib/idn/idnkit-1.0-src/wsock/common/encoding.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1 /*	$NetBSD: encoding.c,v 1.3 2014/12/10 04:37:56 christos Exp $	*/
2 
3 /*
4  * encoding.c - get DNS/Local encodings
5  *
6  *      Software\JPNIC\IDN\Where
7  *                        \LogFile
8  *			  \LogLevel
9  *			  \InstallDir
10  *                        \PerProg\<name>\Where
11  *                        \PerProg\<name>\Encoding
12  */
13 
14 /*
15  * Copyright (c) 2000,2001,2002 Japan Network Information Center.
16  * All rights reserved.
17  *
18  * By using this file, you agree to the terms and conditions set forth bellow.
19  *
20  * 			LICENSE TERMS AND CONDITIONS
21  *
22  * The following License Terms and Conditions apply, unless a different
23  * license is obtained from Japan Network Information Center ("JPNIC"),
24  * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
25  * Chiyoda-ku, Tokyo 101-0047, Japan.
26  *
27  * 1. Use, Modification and Redistribution (including distribution of any
28  *    modified or derived work) in source and/or binary forms is permitted
29  *    under this License Terms and Conditions.
30  *
31  * 2. Redistribution of source code must retain the copyright notices as they
32  *    appear in each source code file, this License Terms and Conditions.
33  *
34  * 3. Redistribution in binary form must reproduce the Copyright Notice,
35  *    this License Terms and Conditions, in the documentation and/or other
36  *    materials provided with the distribution.  For the purposes of binary
37  *    distribution the "Copyright Notice" refers to the following language:
38  *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
39  *
40  * 4. The name of JPNIC may not be used to endorse or promote products
41  *    derived from this Software without specific prior written approval of
42  *    JPNIC.
43  *
44  * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
45  *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46  *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47  *    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JPNIC BE LIABLE
48  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
51  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
52  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
53  *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
54  *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
55  */
56 
57 #include <windows.h>
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <ctype.h>
62 
63 #include "wrapcommon.h"
64 
65 #define IDN_GLOBAL	1
66 #define IDN_PERPROG	2
67 #define IDN_CURUSER	4
68 
69 /*
70  * Registry of Encodings
71  */
72 
73 #define	IDNKEY_WRAPPER	"Software\\JPNIC\\IDN"
74 #define	IDNKEY_PERPROG	"Software\\JPNIC\\IDN\\PerProg"
75 #define	IDNVAL_WHERE	"Where"
76 #define	IDNVAL_ENCODE	"Encoding"
77 #define	IDNVAL_LOGLVL	"LogLevel"
78 #define	IDNVAL_LOGFILE	"LogFile"
79 #define IDNVAL_INSDIR	"InstallDir"
80 
81 static int	GetRegistry(HKEY top, const char *key, const char *name,
82 			    DWORD type, void *param, DWORD length);
83 static char	*GetPerProgKey(char *buf, size_t len);
84 static int	GetFromRegistry(const char *name, int where, DWORD type,
85 				void *param, DWORD length);
86 static int	GetIntFromRegistry(const char *name, int defvalue, int where);
87 static BOOL	GetStringFromRegistry(const char *name, char *result,
88 				      size_t length, int where);
89 
90 static int
GetRegistry(HKEY top,const char * key,const char * name,DWORD type,void * param,DWORD length)91 GetRegistry(HKEY top, const char *key, const char *name, DWORD type,
92 	    void *param, DWORD length)
93 {
94 	LONG stat;
95 	HKEY hk;
96 	DWORD realtype;
97 
98 	stat = RegOpenKeyEx(top, key, 0, KEY_READ, &hk);
99 	if (stat != ERROR_SUCCESS) {
100 		return 0;
101 	}
102 
103 	stat = RegQueryValueEx(hk, (LPCTSTR)name, NULL,
104 			       &realtype, (LPBYTE)param, &length);
105 
106 	RegCloseKey(hk);
107 
108 	if (stat != ERROR_SUCCESS || realtype != type)
109 		return 0;
110 
111 	return 1;
112 }
113 
114 static char *
GetPerProgKey(char * buf,size_t len)115 GetPerProgKey(char *buf, size_t len)
116 {
117 	char exename[256];
118 	char prgname[256];
119 	char *p, *last;
120 
121 	GetModuleFileName(NULL, exename, 256);
122 
123 	for (p = exename, last = NULL; *p != '\0'; p++) {
124 		if (*p == '/' || *p == '\\') {
125 			last = p;
126 		}
127 	}
128 	strcpy(prgname, (last == NULL) ? exename : (last + 1));
129 	if ((p = strrchr(prgname, '.')) != NULL) {
130 		*p = '\0';
131 	}
132 
133 	if (strlen(IDNKEY_PERPROG) + 1 + strlen(prgname) >= len) {
134 		return (NULL);
135 	}
136 	sprintf(buf, "%s\\%s", IDNKEY_PERPROG, prgname);
137 	return buf;
138 }
139 
140 static int
GetFromRegistry(const char * name,int where,DWORD type,void * param,DWORD length)141 GetFromRegistry(const char *name, int where, DWORD type,
142 		void *param, DWORD length)
143 {
144 	if (where & IDN_PERPROG) {
145 		/*
146 		 * First, try program specific setting.
147 		 */
148 		char keyname[256];
149 
150 		/*
151 		 * Try HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE.
152 		 */
153 		if (GetPerProgKey(keyname, sizeof(keyname)) != NULL) {
154 			if (((where & IDN_CURUSER) &&
155 			     GetRegistry(HKEY_CURRENT_USER, keyname, name,
156 					 type, param, length)) ||
157 			    GetRegistry(HKEY_LOCAL_MACHINE, keyname, name,
158 					type, param, length)) {
159 				return (1);
160 			}
161 		}
162 	}
163 
164 	if (where & IDN_GLOBAL) {
165 		/*
166 		 * Try global setting.
167 		 */
168 		if (((where & IDN_CURUSER) &&
169 		     GetRegistry(HKEY_CURRENT_USER, IDNKEY_WRAPPER, name,
170 				 type, param, length)) ||
171 		    GetRegistry(HKEY_LOCAL_MACHINE, IDNKEY_WRAPPER, name,
172 				type, param, length)) {
173 			return (1);
174 		}
175 	}
176 
177 	/*
178 	 * Not found.
179 	 */
180 	return (0);
181 }
182 
183 static int
GetIntFromRegistry(const char * name,int defvalue,int where)184 GetIntFromRegistry(const char *name, int defvalue, int where)
185 {
186     DWORD param;
187 
188     if (GetFromRegistry(name, where, REG_DWORD, &param, sizeof(param))) {
189 	    return ((int)param);
190     }
191     return (defvalue);
192 }
193 
194 static BOOL
GetStringFromRegistry(const char * name,char * result,size_t length,int where)195 GetStringFromRegistry(const char *name, char *result, size_t length, int where)
196 {
197     if (GetFromRegistry(name, where, REG_SZ, result, (DWORD)length)) {
198 	    return (TRUE);
199     }
200     return (FALSE);
201 }
202 
203 /*
204  * idnEncodeWhere - which module should convert domain name
205  */
206 int
idnEncodeWhere(void)207 idnEncodeWhere(void)
208 {
209 	int v = GetIntFromRegistry(IDNVAL_WHERE, IDN_ENCODE_ALWAYS,
210 				   IDN_GLOBAL|IDN_PERPROG|IDN_CURUSER);
211 
212 	idnLogPrintf(idn_log_level_trace, "idnEncodeWhere: %d\n", v);
213 	return (v);
214 }
215 
216 /*
217  * idnGetLogFile - refer to log file
218  */
219 BOOL
idnGetLogFile(char * file,size_t len)220 idnGetLogFile(char *file, size_t len)
221 {
222 	BOOL v = GetStringFromRegistry(IDNVAL_LOGFILE, file, len,
223 				       IDN_GLOBAL|IDN_CURUSER);
224 
225 	idnLogPrintf(idn_log_level_trace, "idnGetLogFile: %-.100s\n",
226 		     (v == TRUE) ? file : "<none>");
227 	return (v);
228 }
229 
230 /*
231  * idnGetPrgEncoding - refer to Program's Local Encoding
232  *
233  *      use program name as registry key
234  */
235 BOOL
idnGetPrgEncoding(char * enc,size_t len)236 idnGetPrgEncoding(char *enc, size_t len)
237 {
238 	if (GetStringFromRegistry(IDNVAL_ENCODE, enc, len,
239 				  IDN_PERPROG|IDN_CURUSER) != TRUE ||
240 	    enc[0] == '\0') {
241 		sprintf(enc, "CP%d", GetACP());
242 	}
243 	idnLogPrintf(idn_log_level_trace,
244 		     "idnGetPrgEncoding: %-.30s\n", enc);
245 	return (TRUE);
246 }
247 
248 /*
249  * idnGetLogLevel
250  */
251 int
idnGetLogLevel(void)252 idnGetLogLevel(void)
253 {
254 	int v  = GetIntFromRegistry(IDNVAL_LOGLVL, 0,
255 				    IDN_GLOBAL|IDN_CURUSER);
256 
257 	idnLogPrintf(idn_log_level_trace, "idnGetLogLevel: %d\n", v);
258 	return (v);
259 }
260 
261 /*
262  * idnGetInstallDir - get idn wrapper install directory
263  */
264 BOOL
idnGetInstallDir(char * dir,size_t len)265 idnGetInstallDir(char *dir, size_t len)
266 {
267 	/* No need to look at HKEY_CURRENT_USER */
268 	BOOL v = GetStringFromRegistry(IDNVAL_INSDIR, dir, len, IDN_GLOBAL);
269 
270 	idnLogPrintf(idn_log_level_trace, "idnGetInstallDir: %-.100s\n",
271 		     (v == TRUE) ? dir : "<none>");
272 	return (v);
273 }
274