2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-2001
5 Copyright (C) Simo Sorce 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/locale.h"
26 NOTE: oldc and newc must be 7 bit characters
28 _PUBLIC_ void string_replace_m(char *s, char oldc, char newc)
30 struct smb_iconv_handle *ic = get_iconv_handle();
33 codepoint_t c = next_codepoint_handle(ic, s, &size);
42 Convert a string to lower case, allocated with talloc
44 _PUBLIC_ char *strlower_talloc_handle(struct smb_iconv_handle *iconv_handle,
45 TALLOC_CTX *ctx, const char *src)
54 /* this takes advantage of the fact that upper/lower can't
55 change the length of a character by more than 1 byte */
56 dest = talloc_array(ctx, char, 2*(strlen(src))+1);
63 codepoint_t c = next_codepoint_handle(iconv_handle, src, &c_size);
68 c_size = push_codepoint_handle(iconv_handle, dest+size, c);
78 /* trim it so talloc_append_string() works */
79 dest = talloc_realloc(ctx, dest, char, size+1);
81 talloc_set_name_const(dest, dest);
86 _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
88 struct smb_iconv_handle *iconv_handle = get_iconv_handle();
89 return strlower_talloc_handle(iconv_handle, ctx, src);
93 Convert a string to UPPER case, allocated with talloc
94 source length limited to n bytes, iconv handle supplied
96 _PUBLIC_ char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle,
97 TALLOC_CTX *ctx, const char *src, size_t n)
106 /* this takes advantage of the fact that upper/lower can't
107 change the length of a character by more than 1 byte */
108 dest = talloc_array(ctx, char, 2*(n+1));
113 while (n-- && *src) {
115 codepoint_t c = next_codepoint_handle(iconv_handle, src, &c_size);
120 c_size = push_codepoint_handle(iconv_handle, dest+size, c);
130 /* trim it so talloc_append_string() works */
131 dest = talloc_realloc(ctx, dest, char, size+1);
133 talloc_set_name_const(dest, dest);
139 Convert a string to UPPER case, allocated with talloc
140 source length limited to n bytes
142 _PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n)
144 struct smb_iconv_handle *iconv_handle = get_iconv_handle();
145 return strupper_talloc_n_handle(iconv_handle, ctx, src, n);
148 Convert a string to UPPER case, allocated with talloc
150 _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
152 return strupper_talloc_n(ctx, src, src?strlen(src):0);
156 talloc_strdup() a unix string to upper case.
158 _PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src)
160 return strupper_talloc(ctx, src);
164 Convert a string to lower case.
166 _PUBLIC_ void strlower_m(char *s)
169 struct smb_iconv_handle *iconv_handle;
171 /* this is quite a common operation, so we want it to be
172 fast. We optimise for the ascii case, knowing that all our
173 supported multi-byte character sets are ascii-compatible
174 (ie. they match for the first 128 chars) */
175 while (*s && !(((uint8_t)*s) & 0x80)) {
176 *s = tolower((uint8_t)*s);
183 iconv_handle = get_iconv_handle();
188 size_t c_size, c_size2;
189 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
190 c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
191 if (c_size2 > c_size) {
192 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
193 c, tolower_m(c), (int)c_size, (int)c_size2));
194 smb_panic("codepoint expansion in strlower_m\n");
203 Convert a string to UPPER case.
205 _PUBLIC_ void strupper_m(char *s)
208 struct smb_iconv_handle *iconv_handle;
210 /* this is quite a common operation, so we want it to be
211 fast. We optimise for the ascii case, knowing that all our
212 supported multi-byte character sets are ascii-compatible
213 (ie. they match for the first 128 chars) */
214 while (*s && !(((uint8_t)*s) & 0x80)) {
215 *s = toupper((uint8_t)*s);
222 iconv_handle = get_iconv_handle();
227 size_t c_size, c_size2;
228 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
229 c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
230 if (c_size2 > c_size) {
231 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
232 c, toupper_m(c), (int)c_size, (int)c_size2));
233 smb_panic("codepoint expansion in strupper_m\n");
243 Find the number of 'c' chars in a string
245 _PUBLIC_ size_t count_chars_m(const char *s, char c)
247 struct smb_iconv_handle *ic = get_iconv_handle();
252 codepoint_t c2 = next_codepoint_handle(ic, s, &size);
253 if (c2 == c) count++;
262 * Copy a string from a char* unix src to a dos codepage string destination.
264 * @converted_size the number of bytes occupied by the string in the destination.
265 * @return bool true if success.
267 * @param flags can include
269 * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
270 * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
273 * @param dest_len the maximum length in bytes allowed in the
274 * destination. If @p dest_len is -1 then no maximum is used.
276 static bool push_ascii(void *dest, const char *src, size_t dest_len, int flags, size_t *converted_size)
281 if (flags & STR_UPPER) {
282 char *tmpbuf = strupper_talloc(NULL, src);
283 if (tmpbuf == NULL) {
286 ret = push_ascii(dest, tmpbuf, dest_len, flags & ~STR_UPPER, converted_size);
291 src_len = strlen(src);
293 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
296 return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, converted_size);
300 * Copy a string from a dos codepage source to a unix char* destination.
302 * The resulting string in "dest" is always null terminated.
304 * @param flags can have:
306 * <dt>STR_TERMINATE</dt>
307 * <dd>STR_TERMINATE means the string in @p src
308 * is null terminated, and src_len is ignored.</dd>
311 * @param src_len is the length of the source area in bytes.
312 * @returns the number of bytes occupied by the string in @p src.
314 static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
318 if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
319 if (src_len == (size_t)-1) {
320 src_len = strlen((const char *)src) + 1;
322 size_t len = strnlen((const char *)src, src_len);
329 /* We're ignoring the return here.. */
330 (void)convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, &size);
333 dest[MIN(size, dest_len-1)] = 0;
339 * Copy a string from a char* src to a unicode destination.
341 * @returns the number of bytes occupied by the string in the destination.
343 * @param flags can have:
346 * <dt>STR_TERMINATE <dd>means include the null termination.
347 * <dt>STR_UPPER <dd>means uppercase in the destination.
348 * <dt>STR_NOALIGN <dd>means don't do alignment.
351 * @param dest_len is the maximum length allowed in the
352 * destination. If dest_len is -1 then no maxiumum is used.
354 static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags)
357 size_t src_len = strlen(src);
361 if (flags & STR_UPPER) {
362 char *tmpbuf = strupper_talloc(NULL, src);
364 if (tmpbuf == NULL) {
367 retval = push_ucs2(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
372 if (flags & STR_TERMINATE)
375 if (ucs2_align(NULL, dest, flags)) {
377 dest = (void *)((char *)dest + 1);
378 if (dest_len) dest_len--;
382 /* ucs2 is always a multiple of 2 bytes */
385 ret = convert_string(CH_UNIX, CH_UTF16, src, src_len, dest, dest_len, &size);
397 Copy a string from a ucs2 source to a unix char* destination.
399 STR_TERMINATE means the string in src is null terminated.
400 STR_NOALIGN means don't try to align.
401 if STR_TERMINATE is set then src_len is ignored if it is -1.
402 src_len is the length of the source area in bytes
403 Return the number of bytes occupied by the string in src.
404 The resulting string in "dest" is always null terminated.
407 static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
411 if (ucs2_align(NULL, src, flags)) {
412 src = (const void *)((const char *)src + 1);
417 if (flags & STR_TERMINATE) {
418 if (src_len == (size_t)-1) {
419 src_len = utf16_len(src);
421 src_len = utf16_len_n(src, src_len);
425 /* ucs2 is always a multiple of 2 bytes */
426 if (src_len != (size_t)-1)
429 /* We're ignoring the return here.. */
430 (void)convert_string(CH_UTF16, CH_UNIX, src, src_len, dest, dest_len, &size);
432 dest[MIN(size, dest_len-1)] = 0;
438 Copy a string from a char* src to a unicode or ascii
439 dos codepage destination choosing unicode or ascii based on the
440 flags in the SMB buffer starting at base_ptr.
441 Return the number of bytes occupied by the string in the destination.
443 STR_TERMINATE means include the null termination.
444 STR_UPPER means uppercase in the destination.
445 STR_ASCII use ascii even with unicode packet.
446 STR_NOALIGN means don't do alignment.
447 dest_len is the maximum length allowed in the destination. If dest_len
448 is -1 then no maxiumum is used.
451 _PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
453 if (flags & STR_ASCII) {
455 if (push_ascii(dest, src, dest_len, flags, &size)) {
456 return (ssize_t)size;
460 } else if (flags & STR_UNICODE) {
461 return push_ucs2(dest, src, dest_len, flags);
463 smb_panic("push_string requires either STR_ASCII or STR_UNICODE flag to be set");
470 Copy a string from a unicode or ascii source (depending on
471 the packet flags) to a char* destination.
473 STR_TERMINATE means the string in src is null terminated.
474 STR_UNICODE means to force as unicode.
475 STR_ASCII use ascii even with unicode packet.
476 STR_NOALIGN means don't do alignment.
477 if STR_TERMINATE is set then src_len is ignored is it is -1
478 src_len is the length of the source area in bytes.
479 Return the number of bytes occupied by the string in src.
480 The resulting string in "dest" is always null terminated.
483 _PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
485 if (flags & STR_ASCII) {
486 return pull_ascii(dest, src, dest_len, src_len, flags);
487 } else if (flags & STR_UNICODE) {
488 return pull_ucs2(dest, src, dest_len, src_len, flags);
490 smb_panic("pull_string requires either STR_ASCII or STR_UNICODE flag to be set");