diff options
author | Andrew Tridgell <tridge@samba.org> | 2001-03-10 11:38:27 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2001-03-10 11:38:27 +0000 |
commit | b08b70faf873455ff14dcd633a7c9eb860ba4b28 (patch) | |
tree | 5c57e51d8bcca6e645289cc8f7c0c94f6dc666b0 /source3/smbd/srvstr.c | |
parent | 45c2ee3ff2d01fdd0a2db9fa90457cff4663c43d (diff) | |
download | samba-b08b70faf873455ff14dcd633a7c9eb860ba4b28.tar.gz samba-b08b70faf873455ff14dcd633a7c9eb860ba4b28.tar.bz2 samba-b08b70faf873455ff14dcd633a7c9eb860ba4b28.zip |
started support for unicode on the wire in smbd. Using a very similar
method to what was used in the client I now have session setup and
tconx working.
Currently this is enabled with SMBD_USE_UNICODE environment
variable. Once the code is complete this will become a smb.conf
option.
(This used to be commit 7684c1e67294266d018c6f0cab58f1a9d797174f)
Diffstat (limited to 'source3/smbd/srvstr.c')
-rw-r--r-- | source3/smbd/srvstr.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/source3/smbd/srvstr.c b/source3/smbd/srvstr.c new file mode 100644 index 0000000000..e420b8fa99 --- /dev/null +++ b/source3/smbd/srvstr.c @@ -0,0 +1,186 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + server specific string routines + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +#define UNICODE_FLAG() (SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) + +/**************************************************************************** +copy a string from a char* src to a unicode or ascii +dos code page destination choosing unicode or ascii based on the +FLAGS2_UNICODE_STRINGS bit in inbuf +return the number of bytes occupied by the string in the destination +flags can have: + STR_TERMINATE means include the null termination + STR_CONVERT means convert from unix to dos codepage + STR_UPPER means uppercase in the destination + STR_ASCII use ascii even with unicode servers +dest_len is the maximum length allowed in the destination. If dest_len +is -1 then no maxiumum is used +****************************************************************************/ +int srvstr_push(void *inbuf, void *outbuf, void *dest, const char *src, int dest_len, int flags) +{ + int len=0; + + /* treat a pstring as "unlimited" length */ + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (!(flags & STR_ASCII) && srvstr_align(inbuf, PTR_DIFF(dest, outbuf))) { + *(char *)dest = 0; + dest++; + dest_len--; + len++; + } + + if ((flags & STR_ASCII) || !UNICODE_FLAG()) { + /* the client doesn't want unicode */ + safe_strcpy(dest, src, dest_len); + len = strlen(dest); + if (flags & STR_TERMINATE) len++; + if (flags & STR_CONVERT) unix_to_dos(dest,True); + if (flags & STR_UPPER) strupper(dest); + return len; + } + + /* the server likes unicode. give it the works */ + if (flags & STR_CONVERT) { + dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE); + } else { + ascii_to_unistr(dest, src, dest_len); + } + if (flags & STR_UPPER) { + strupper_w(dest); + } + len += strlen(src)*2; + if (flags & STR_TERMINATE) len += 2; + return len; +} + + +/**************************************************************************** +return the length that a string would occupy when copied with srvstr_push() + STR_TERMINATE means include the null termination + STR_CONVERT means convert from unix to dos codepage + STR_UPPER means uppercase in the destination +note that dest is only used for alignment purposes. No data is written. +****************************************************************************/ +int srvstr_push_size(void *inbuf, void *outbuf, + const void *dest, const char *src, int dest_len, int flags) +{ + int len = strlen(src); + if (flags & STR_TERMINATE) len++; + if (!(flags & STR_ASCII) && UNICODE_FLAG()) len *= 2; + + if (!(flags & STR_ASCII) && dest && srvstr_align(inbuf, PTR_DIFF(outbuf, dest))) { + len++; + } + + return len; +} + +/**************************************************************************** +copy a string from a unicode or ascii source (depending on flg2) +to a char* destination +flags can have: + STR_CONVERT means convert from dos to unix codepage + STR_TERMINATE means the string in src is null terminated + STR_UNICODE means to force as unicode +if STR_TERMINATE is set then src_len is ignored +src_len is the length of the source area in bytes +return the number of bytes occupied by the string in src +****************************************************************************/ +int srvstr_pull(void *inbuf, char *dest, const void *src, int dest_len, int src_len, int flags) +{ + int len; + + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (srvstr_align(inbuf, PTR_DIFF(src, inbuf))) { + src++; + if (src_len > 0) src_len--; + } + + if (!(flags & STR_UNICODE) && !UNICODE_FLAG()) { + /* the server doesn't want unicode */ + if (flags & STR_TERMINATE) { + safe_strcpy(dest, src, dest_len); + len = strlen(src)+1; + } else { + if (src_len > dest_len) src_len = dest_len; + len = src_len; + memcpy(dest, src, len); + dest[len] = 0; + } + if (flags & STR_CONVERT) dos_to_unix(dest,True); + return len; + } + + if (flags & STR_TERMINATE) { + unistr_to_ascii(dest, src, dest_len); + len = strlen(dest)*2 + 2; + } else { + int i, c; + if (dest_len*2 < src_len) src_len = 2*dest_len; + for (i=0; i < src_len; i += 2) { + c = SVAL(src, i); + *dest++ = c; + } + *dest++ = 0; + len = src_len; + } + if (flags & STR_CONVERT) dos_to_unix(dest,True); + return len; +} + +/**************************************************************************** +return the length that a string would occupy (not including the null) +when copied with srvstr_pull() +if src_len is -1 then assume the source is null terminated +****************************************************************************/ +int srvstr_pull_size(void *inbuf, const void *src, int src_len) +{ + if (srvstr_align(inbuf, PTR_DIFF(src, inbuf))) { + src++; + if (src_len > 0) src_len--; + } + + if (!UNICODE_FLAG()) { + return strlen(src); + } + return strlen_w(src); +} + +/**************************************************************************** +return an alignment of either 0 or 1 +if unicode is not negotiated then return 0 +otherwise return 1 if offset is off +****************************************************************************/ +int srvstr_align(void *inbuf, int offset) +{ + if (!UNICODE_FLAG()) return 0; + return offset & 1; +} |