2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define UNICODE_FLAG(cli, flags) (!(flags & STR_ASCII) && \
27 ((flags & STR_UNICODE || \
28 (SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))))
30 /****************************************************************************
31 copy a string from a char* src to a unicode or ascii
32 dos code page destination choosing unicode or ascii based on the
33 cli->capabilities flag
34 return the number of bytes occupied by the string in the destination
36 STR_TERMINATE means include the null termination
37 STR_CONVERT means convert from unix to dos codepage
38 STR_UPPER means uppercase in the destination
39 STR_ASCII use ascii even with unicode servers
40 STR_NOALIGN means don't do alignment
41 dest_len is the maximum length allowed in the destination. If dest_len
42 is -1 then no maxiumum is used
43 ****************************************************************************/
44 int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
48 /* treat a pstring as "unlimited" length */
50 dest_len = sizeof(pstring);
53 if (clistr_align_out(cli, dest, flags)) {
55 dest = (void *)((char *)dest + 1);
60 if (!UNICODE_FLAG(cli, flags)) {
61 /* the server doesn't want unicode */
62 safe_strcpy(dest, src, dest_len);
64 if (flags & STR_TERMINATE) len++;
65 if (flags & STR_CONVERT) unix_to_dos(dest,True);
66 if (flags & STR_UPPER) strupper(dest);
70 /* the server likes unicode. give it the works */
71 if (flags & STR_CONVERT) {
72 dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
74 ascii_to_unistr(dest, src, dest_len);
76 if (flags & STR_UPPER) {
80 if (flags & STR_TERMINATE) len += 2;
84 /****************************************************************************
85 copy a string from a unicode or ascii source (depending on
86 cli->capabilities) to a char* destination
88 STR_CONVERT means convert from dos to unix codepage
89 STR_TERMINATE means the string in src is null terminated
90 STR_UNICODE means to force as unicode
91 STR_NOALIGN means don't do alignment
92 if STR_TERMINATE is set then src_len is ignored
93 src_len is the length of the source area in bytes
94 return the number of bytes occupied by the string in src
95 ****************************************************************************/
96 int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags)
100 if (dest_len == -1) {
101 dest_len = sizeof(pstring);
104 if (clistr_align_in(cli, src, flags)) {
105 src = (const void *)((const char *)src + 1);
106 if (src_len > 0) src_len--;
109 if (!UNICODE_FLAG(cli, flags)) {
110 /* the server doesn't want unicode */
111 if (flags & STR_TERMINATE) {
112 safe_strcpy(dest, src, dest_len);
115 if (src_len > dest_len) src_len = dest_len;
117 memcpy(dest, src, len);
120 if (flags & STR_CONVERT)
121 safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
125 if (flags & STR_TERMINATE) {
126 unistr_to_ascii(dest, src, dest_len);
127 len = strlen(dest)*2 + 2;
130 if (dest_len*2 < src_len) src_len = 2*dest_len;
131 for (i=0; i < src_len; i += 2) {
138 if (flags & STR_CONVERT)
139 safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
144 /****************************************************************************
145 return an alignment of either 0 or 1
146 if unicode is not negotiated then return 0
147 otherwise return 1 if offset is off
148 ****************************************************************************/
149 static int clistr_align(struct cli_state *cli, char *buf, const void *p, int flags)
151 if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags)) return 0;
152 return PTR_DIFF(p, buf) & 1;
155 int clistr_align_out(struct cli_state *cli, const void *p, int flags)
157 return clistr_align(cli, cli->outbuf, p, flags);
160 int clistr_align_in(struct cli_state *cli, const void *p, int flags)
162 return clistr_align(cli, cli->inbuf, p, flags);