few edits
[Samba.git] / source / libsmb / clistr.c
blob72178967ed527d96f287b54c5447ab01c0e31dbd
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 client string routines
5 Copyright (C) Andrew Tridgell 2001
6 Copyright (C) Jeremy Allison 2001
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define NO_SYSLOG
25 #include "includes.h"
27 #define UNICODE_FLAG(cli, flags) (!(flags & STR_ASCII) && \
28 ((flags & STR_UNICODE || \
29 (SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))))
31 /****************************************************************************
32 copy a string from a char* src to a unicode or ascii
33 dos code page destination choosing unicode or ascii based on the
34 cli->capabilities flag
35 return the number of bytes occupied by the string in the destination
36 flags can have:
37 STR_TERMINATE means include the null termination
38 STR_CONVERT means convert from unix to dos codepage
39 STR_UPPER means uppercase in the destination
40 STR_ASCII use ascii even with unicode servers
41 STR_NOALIGN means don't do alignment
42 dest_len is the maximum length allowed in the destination. If dest_len
43 is -1 then no maxiumum is used
44 ****************************************************************************/
46 int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
48 int len=0;
50 /* treat a pstring as "unlimited" length */
51 if (dest_len == -1)
52 dest_len = sizeof(pstring);
54 if (clistr_align_out(cli, dest, flags)) {
55 *(char *)dest = 0;
56 dest = (void *)((char *)dest + 1);
57 dest_len--;
58 len++;
61 if (!UNICODE_FLAG(cli, flags)) {
62 /* the server doesn't want unicode */
63 safe_strcpy(dest, src, dest_len);
64 len = strlen(dest);
65 if (flags & STR_TERMINATE)
66 len++;
67 if (flags & STR_CONVERT)
68 unix_to_dos(dest);
69 if (flags & STR_UPPER)
70 strupper(dest);
71 return len;
74 /* the server likes unicode. give it the works */
75 if (flags & STR_CONVERT)
76 dos_PutUniCode(dest, unix_to_dos_static(src), dest_len, flags & STR_TERMINATE);
77 else
78 unix_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
80 if (flags & STR_UPPER)
81 strupper_w(dest);
83 len += strlen(src)*2;
84 if (flags & STR_TERMINATE)
85 len += 2;
86 return len;
89 /****************************************************************************
90 copy a string from a unicode or dos codepage source (depending on
91 cli->capabilities) to a unix char* destination
92 flags can have:
93 STR_TERMINATE means the string in src is null terminated
94 STR_UNICODE means to force as unicode
95 STR_NOALIGN means don't do alignment
96 if STR_TERMINATE is set then src_len is ignored
97 src_len is the length of the source area in bytes
98 return the number of bytes occupied by the string in src
99 ****************************************************************************/
101 int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags)
103 int len;
105 if (dest_len == -1)
106 dest_len = sizeof(pstring);
108 if (clistr_align_in(cli, src, flags)) {
109 src = (const void *)((const char *)src + 1);
110 if (src_len > 0)
111 src_len--;
114 if (!UNICODE_FLAG(cli, flags)) {
115 /* the server doesn't want unicode */
116 if (flags & STR_TERMINATE) {
117 safe_strcpy(dest, src, dest_len);
118 len = strlen(src)+1;
119 } else {
120 if (src_len > dest_len)
121 src_len = dest_len;
122 len = src_len;
123 memcpy(dest, src, len);
124 dest[len] = 0;
126 safe_strcpy(dest,dos_to_unix_static(dest),dest_len);
127 return len;
130 if (flags & STR_TERMINATE) {
131 int i;
132 src_len = strlen_w(src)*2+2;
133 for (i=0; i < src_len; i += 2) {
134 const smb_ucs2_t c = (smb_ucs2_t)SVAL(src, i);
135 if (c == (smb_ucs2_t)0 || (dest_len - i < 3))
136 break;
137 dest += unicode_to_unix_char(dest, c);
139 *dest++ = 0;
140 len = src_len;
141 } else {
142 int i;
143 if (dest_len*2 < src_len)
144 src_len = 2*dest_len;
145 for (i=0; i < src_len; i += 2) {
146 const smb_ucs2_t c = (smb_ucs2_t)SVAL(src, i);
147 dest += unicode_to_unix_char(dest, c);
149 *dest++ = 0;
150 len = src_len;
152 return len;
155 /****************************************************************************
156 Return an alignment of either 0 or 1.
157 If unicode is not negotiated then return 0
158 otherwise return 1 if offset is off.
159 ****************************************************************************/
161 static int clistr_align(struct cli_state *cli, char *buf, const void *p, int flags)
163 if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags))
164 return 0;
165 return PTR_DIFF(p, buf) & 1;
168 int clistr_align_out(struct cli_state *cli, const void *p, int flags)
170 return clistr_align(cli, cli->outbuf, p, flags);
173 int clistr_align_in(struct cli_state *cli, const void *p, int flags)
175 return clistr_align(cli, cli->inbuf, p, flags);