2 * Unix SMB/CIFS implementation.
4 * Registry helper routines
6 * Copyright (C) Gregor Beck 2010
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * @file reg_parse_internal.h
23 * @author Gregor Beck <gb@sernet.de>
28 #include "reg_parse_internal.h"
33 size_t iconvert_talloc(const void* ctx
,
35 const char* src
, size_t srclen
,
39 size_t obytes
, ibytes
;
40 char *optr
, *dst
, *tmp
;
43 if (cd
== NULL
|| cd
== ((smb_iconv_t
)-1)) {
51 * Allocate an extra two bytes for the
55 dst
= (char *)talloc_size(ctx
, dstlen
);
57 DEBUG(0,("iconver_talloc no mem\n"));
61 dstlen
= talloc_get_size(dst
);
69 ret
= smb_iconv(cd
, &iptr
, &ibytes
, &optr
, &obytes
);
72 const char *reason
="unknown error";
75 reason
="Incomplete multibyte sequence";
78 dstlen
= 2*dstlen
+ 2;
79 tmp
= talloc_realloc(ctx
, dst
, char, dstlen
);
81 reason
="talloc_realloc failed";
87 reason
="Illegal multibyte sequence";
90 DEBUG(0,("Conversion error: %s(%.80s) %li\n", reason
, iptr
,
91 (long int)(iptr
-src
)));
96 dstlen
= (dstlen
-2) - obytes
;
98 SSVAL(dst
, dstlen
, 0);
104 #ifndef HKEY_CURRENT_CONFIG
105 #define HKEY_CURRENT_CONFIG 0x80000005
107 #ifndef HKEY_DYN_DATA
108 #define HKEY_DYN_DATA 0x80000006
110 #ifndef HKEY_PERFORMANCE_TEXT
111 #define HKEY_PERFORMANCE_TEXT 0x80000050
113 #ifndef HKEY_PERFORMANCE_NLSTEXT
114 #define HKEY_PERFORMANCE_NLSTEXT 0x80000060
117 #define HIVE_INFO_ENTRY(SHORT,LONG) \
118 const struct hive_info HIVE_INFO_##SHORT = { \
120 .short_name = #SHORT, \
121 .short_name_len = sizeof(#SHORT)-1, \
122 .long_name = #LONG, \
123 .long_name_len = sizeof(#LONG)-1, \
126 HIVE_INFO_ENTRY(HKLM
, HKEY_LOCAL_MACHINE
);
127 HIVE_INFO_ENTRY(HKCU
, HKEY_CURRENT_USER
);
128 HIVE_INFO_ENTRY(HKCR
, HKEY_CLASSES_ROOT
);
129 HIVE_INFO_ENTRY(HKU
, HKEY_USERS
);
130 HIVE_INFO_ENTRY(HKCC
, HKEY_CURRENT_CONFIG
);
131 HIVE_INFO_ENTRY(HKDD
, HKEY_DYN_DATA
);
132 HIVE_INFO_ENTRY(HKPD
, HKEY_PERFORMANCE_DATA
);
133 HIVE_INFO_ENTRY(HKPT
, HKEY_PERFORMANCE_TEXT
);
134 HIVE_INFO_ENTRY(HKPN
, HKEY_PERFORMANCE_NLSTEXT
);
135 #undef HIVE_INFO_ENTRY
137 const struct hive_info
* HIVE_INFO
[] = {
138 &HIVE_INFO_HKLM
, &HIVE_INFO_HKCU
, &HIVE_INFO_HKCR
, &HIVE_INFO_HKU
,
139 &HIVE_INFO_HKCC
, &HIVE_INFO_HKDD
, &HIVE_INFO_HKPD
, &HIVE_INFO_HKPT
,
140 &HIVE_INFO_HKPN
, NULL
143 #define TOINT(A,B) ((int)(A) << 8) + (int)(B)
145 bool srprs_hive(const char** ptr
, const struct hive_info
** result
)
147 const char* str
= *ptr
;
148 const struct hive_info
* info
= NULL
;
149 bool long_hive
= false;
151 if ((toupper(str
[0]) != 'H') || (toupper(str
[1]) != 'K')
152 || (str
[2] == '\0') )
157 switch ( TOINT(toupper(str
[2]), toupper(str
[3])) ) {
158 case TOINT('E', 'Y'):
161 for (i
=0; (info
= HIVE_INFO
[i
]); i
++) {
162 if (strncmp(&str
[5], &info
->long_name
[5],
163 info
->long_name_len
-5) == 0)
171 case TOINT('L', 'M'):
172 info
= &HIVE_INFO_HKLM
;
174 case TOINT('C', 'U'):
175 info
= &HIVE_INFO_HKCU
;
177 case TOINT('C', 'R'):
178 info
= &HIVE_INFO_HKCR
;
180 case TOINT('C', 'C'):
181 info
= &HIVE_INFO_HKCC
;
183 case TOINT('D', 'D'):
184 info
= &HIVE_INFO_HKDD
;
186 case TOINT('P', 'D'):
187 info
= &HIVE_INFO_HKPD
;
189 case TOINT('P', 'T'):
190 info
= &HIVE_INFO_HKPT
;
192 case TOINT('P', 'N'):
193 info
= &HIVE_INFO_HKPN
;
196 if (toupper(str
[2]) == 'U') {
197 info
= &HIVE_INFO_HKU
;
202 if (result
!= NULL
) {
205 *ptr
+= long_hive
? info
->long_name_len
: info
->short_name_len
;
211 const struct hive_info
* hive_info(const char* name
)
213 const struct hive_info
* info
= NULL
;
214 srprs_hive(&name
, &info
);
218 const char *smbreg_get_charset(const char *c
)
220 if (strcmp(c
, "dos") == 0) {
221 return lp_dos_charset();
222 } else if (strcmp(c
, "unix") == 0) {
223 return lp_unix_charset();
229 bool set_iconv(smb_iconv_t
* t
, const char* to
, const char* from
)
231 smb_iconv_t cd
= (smb_iconv_t
)-1;
234 to
= smbreg_get_charset(to
);
235 from
= smbreg_get_charset(from
);
236 cd
= smb_iconv_open(to
, from
);
237 if (cd
== ((smb_iconv_t
)-1)) {
241 if ((*t
!= (smb_iconv_t
)NULL
) && (*t
!= (smb_iconv_t
)-1)) {
249 * Parse option string
250 * @param[in,out] ptr parse position
251 * @param[in] mem_ctx talloc context
252 * @param[out] name ptr 2 value
253 * @param[out] value ptr 2 value
254 * @return true on success
256 bool srprs_option(const char** ptr
, const void* mem_ctx
, char** name
, char** value
)
258 const char* pos
= *ptr
;
259 void* ctx
= talloc_new(mem_ctx
);
261 cbuf
* key
= cbuf_new(ctx
);
264 while(srprs_charsetinv(&pos
, ",= \t\n\r", key
))
272 *name
= talloc_steal(mem_ctx
, cbuf_gets(key
, 0));
278 if (!srprs_quoted_string(ptr
, val
, NULL
)) {
279 while(srprs_charsetinv(&pos
, ", \t\n\r", val
))
283 *value
= talloc_steal(mem_ctx
, cbuf_gets(val
, 0));
291 while(srprs_char(&pos
, ','))
298 #define CH_INVALID ((charset_t)-1)
299 static const struct {
300 const char* const name
;
305 {"UTF-8", CH_UTF8
, 3, {0xEF, 0xBB, 0xBF}},
306 {"UTF-32LE", CH_INVALID
, 4, {0xFF, 0xFE, 0x00, 0x00}},
307 {"UTF-16LE", CH_UTF16LE
, 2, {0xFF, 0xFE}},
308 {"UTF-16BE", CH_UTF16BE
, 2, {0xFE, 0xFF}},
309 {"UTF-32BE", CH_INVALID
, 4, {0x00, 0x00, 0xFE, 0xFF}},
313 bool srprs_bom(const char** ptr
, const char** name
, charset_t
* ctype
)
316 for (i
=0; BOM
[i
].name
; i
++) {
317 if (memcmp(*ptr
, BOM
[i
].seq
, BOM
[i
].len
) == 0) {
322 if (BOM
[i
].name
!= NULL
) {
323 DEBUG(0, ("Found Byte Order Mark for : %s\n", BOM
[i
].name
));
330 *ctype
= BOM
[i
].ctype
;
340 int write_bom(FILE* file
, const char* charset
, charset_t ctype
)
343 if ( charset
== NULL
) {
344 for (i
=0; BOM
[i
].name
; i
++) {
345 if (BOM
[i
].ctype
== ctype
) {
346 return fwrite(BOM
[i
].seq
, 1, BOM
[i
].len
, file
);
349 DEBUG(0, ("No Byte Order Mark for charset_t: %u\n", (unsigned)ctype
));
351 for (i
=0; BOM
[i
].name
; i
++) {
352 if (strcasecmp_m(BOM
[i
].name
, charset
) == 0) {
353 return fwrite(BOM
[i
].seq
, 1, BOM
[i
].len
, file
);
356 DEBUG(0, ("No Byte Order Mark for charset_t: %s\n", charset
));
362 int cbuf_puts_case(cbuf
* s
, const char* str
, size_t len
, enum fmt_case fmt
)
364 size_t pos
= cbuf_getpos(s
);
365 int ret
= cbuf_puts(s
, str
, len
);
366 char* ptr
= cbuf_gets(s
,pos
);
373 case FMT_CASE_PRESERVE
:
376 while(*ptr
!= '\0') {
377 *ptr
= toupper(*ptr
);
382 *ptr
= toupper(*ptr
);
386 while(*ptr
!= '\0') {
387 *ptr
= tolower(*ptr
);