fixed some compilation errors with IRIX cc
[tprouty/samba.git] / source / libsmb / clistr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    client string routines
5    Copyright (C) Andrew Tridgell 2001
6    
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.
11    
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.
16    
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.
20 */
21
22 #define NO_SYSLOG
23
24 #include "includes.h"
25
26 /****************************************************************************
27 copy a string from a char* src to a unicode or ascii
28 dos code page destination choosing unicode or ascii based on the 
29 cli->capabilities flag
30 return the number of bytes occupied by the string in the destination
31 flags can have:
32   STR_TERMINATE means include the null termination
33   STR_CONVERT   means convert from unix to dos codepage
34   STR_UPPER     means uppercase in the destination
35   STR_ASCII     use ascii even with unicode servers
36 dest_len is the maximum length allowed in the destination. If dest_len
37 is -1 then no maxiumum is used
38 ****************************************************************************/
39 int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
40 {
41         int len=0;
42
43         /* treat a pstring as "unlimited" length */
44         if (dest_len == -1) {
45                 dest_len = sizeof(pstring);
46         }
47
48         if (!(flags & STR_ASCII) && clistr_align(cli->outbuf, dest)) {
49                 *(char *)dest = 0;
50                 dest = (void *)((char *)dest + 1);
51                 dest_len--;
52                 len++;
53         }
54
55         if ((flags & STR_ASCII) || !(SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) {
56                 /* the server doesn't want unicode */
57                 safe_strcpy(dest, src, dest_len);
58                 len = strlen(dest);
59                 if (flags & STR_TERMINATE) len++;
60                 if (flags & STR_CONVERT) unix_to_dos(dest,True);
61                 if (flags & STR_UPPER) strupper(dest);
62                 return len;
63         }
64
65         /* the server likes unicode. give it the works */
66         if (flags & STR_CONVERT) {
67                 dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
68         } else {
69                 ascii_to_unistr(dest, src, dest_len);
70         }
71         if (flags & STR_UPPER) {
72                 strupper_w(dest);
73         }
74         len += strlen(src)*2;
75         if (flags & STR_TERMINATE) len += 2;
76         return len;
77 }
78
79 /****************************************************************************
80 copy a string from a unicode or ascii source (depending on
81 cli->capabilities) to a char* destination
82 flags can have:
83   STR_CONVERT   means convert from dos to unix codepage
84   STR_TERMINATE means the string in src is null terminated
85   STR_UNICODE   means to force as unicode
86 if STR_TERMINATE is set then src_len is ignored
87 src_len is the length of the source area in bytes
88 return the number of bytes occupied by the string in src
89 ****************************************************************************/
90 int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags)
91 {
92         int len;
93
94         if (dest_len == -1) {
95                 dest_len = sizeof(pstring);
96         }
97
98         if (!(flags & STR_ASCII) && clistr_align(cli->inbuf, src)) {
99                 src = (void *)((char *)src + 1);
100                 if (src_len > 0) src_len--;
101         }
102
103         if ((flags & STR_ASCII) ||
104             (!(flags & STR_UNICODE) && !(SVAL(cli->inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))) {
105                 /* the server doesn't want unicode */
106                 if (flags & STR_TERMINATE) {
107                         safe_strcpy(dest, src, dest_len);
108                         len = strlen(src)+1;
109                 } else {
110                         if (src_len > dest_len) src_len = dest_len;
111                         len = src_len;
112                         memcpy(dest, src, len);
113                         dest[len] = 0;
114                 }
115                 if (flags & STR_CONVERT) dos_to_unix(dest,True);
116                 return len;
117         }
118
119         if (flags & STR_TERMINATE) {
120                 unistr_to_ascii(dest, src, dest_len);
121                 len = strlen(dest)*2 + 2;
122         } else {
123                 int i, c;
124                 if (dest_len*2 < src_len) src_len = 2*dest_len;
125                 for (i=0; i < src_len; i += 2) {
126                         c = SVAL(src, i);
127                         *dest++ = c;
128                 }
129                 *dest++ = 0;
130                 len = src_len;
131         }
132         if (flags & STR_CONVERT) dos_to_unix(dest,True);
133         return len;
134 }
135
136
137 /****************************************************************************
138 return an alignment of either 0 or 1
139 if unicode is not negotiated then return 0
140 otherwise return 1 if offset is off
141 ****************************************************************************/
142 int clistr_align(const void *buf, const void *p)
143 {
144         if (!(SVAL(buf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) return 0;
145         return PTR_DIFF(p, buf) & 1;
146 }