ad05831229bb3c55e9121e63c65bf501544d3f4a
[samba.git] / source3 / rpc_parse / parse_prs.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba memory buffer functions
5    Copyright (C) Andrew Tridgell              1992-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
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.
12    
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.
17    
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.
21 */
22
23 extern int DEBUGLEVEL;
24
25 #include "includes.h"
26
27
28 /*******************************************************************
29  debug output for parsing info.
30
31  XXXX side-effect of this function is to increase the debug depth XXXX
32
33  ********************************************************************/
34 void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
35 {
36         DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
37 }
38
39 /*******************************************************************
40  initialise a parse structure
41  ********************************************************************/
42 void prs_init(prs_struct *ps, uint32 size,
43                                 uint8 align, uint32 margin,
44                                 BOOL io)
45 {
46         ps->io = io;
47         ps->align = align;
48         ps->offset = 0;
49
50         ps->data = NULL;
51         mem_buf_init(&(ps->data), margin);
52
53         if (size != 0)
54         {
55                 mem_alloc_data(ps->data, size);
56                 ps->data->offset.start = 0;
57                 ps->data->offset.end   = 0xffffffff;
58         }
59 }
60
61 /*******************************************************************
62  initialise a parse structure
63  ********************************************************************/
64 void prs_mem_free(prs_struct *ps)
65 {
66         mem_buf_free(&(ps->data));
67 }
68
69 /*******************************************************************
70  align a pointer to a multiple of align_offset bytes.  looks like it
71  will work for offsets of 0, 2 and 4...
72  ********************************************************************/
73 void prs_align(prs_struct *ps)
74 {
75         int mod = ps->offset & (ps->align-1);
76         if (ps->align != 0 && mod != 0)
77         {
78                 ps->offset += ps->align - mod;
79         }
80 }
81
82 /*******************************************************************
83  attempt, if appropriate, to grow a data buffer.
84
85  depends on the data stream mode (io)
86  ********************************************************************/
87 BOOL prs_grow(prs_struct *ps)
88 {
89         return mem_grow_data(&(ps->data), ps->io, ps->offset, False);
90 }
91
92
93 /*******************************************************************
94  stream a uint8
95  ********************************************************************/
96 BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
97 {
98         char *q = mem_data(&(ps->data), ps->offset);
99         if (q == NULL) return False;
100
101         DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
102         ps->offset += 1;
103
104         return True;
105 }
106
107 /*******************************************************************
108  stream a uint16
109  ********************************************************************/
110 BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
111 {
112         char *q = mem_data(&(ps->data), ps->offset);
113         if (q == NULL) return False;
114
115         DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
116         ps->offset += 2;
117
118         return True;
119 }
120
121 /*******************************************************************
122  stream a uint32
123  ********************************************************************/
124 BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
125 {
126         char *q = mem_data(&(ps->data), ps->offset);
127         if (q == NULL) return False;
128
129         DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
130         ps->offset += 4;
131
132         return True;
133 }
134
135
136 /******************************************************************
137  stream an array of uint8s.  length is number of uint8s
138  ********************************************************************/
139 BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
140 {
141         char *q = mem_data(&(ps->data), ps->offset);
142         if (q == NULL) return False;
143
144         DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
145         ps->offset += len;
146
147         return True;
148 }
149
150 /******************************************************************
151  stream an array of uint16s.  length is number of uint16s
152  ********************************************************************/
153 BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
154 {
155         char *q = mem_data(&(ps->data), ps->offset);
156         if (q == NULL) return False;
157
158         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
159         ps->offset += len * sizeof(uint16);
160
161         return True;
162 }
163
164 /******************************************************************
165  stream an array of uint32s.  length is number of uint32s
166  ********************************************************************/
167 BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
168 {
169         char *q = mem_data(&(ps->data), ps->offset);
170         if (q == NULL) return False;
171
172         DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
173         ps->offset += len * sizeof(uint32);
174
175         return True;
176 }
177
178 /******************************************************************
179  stream a "not" unicode string, length/buffer specified separately,
180  in byte chars
181  ********************************************************************/
182 BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str)
183 {
184         char *q = mem_data(&(ps->data), ps->offset);
185         if (q == NULL) return False;
186
187         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
188         ps->offset += str->uni_buf_len;
189
190         return True;
191 }
192
193 /******************************************************************
194  stream a string, length/buffer specified separately,
195  in uint8 chars.
196  ********************************************************************/
197 BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
198 {
199         char *q = mem_data(&(ps->data), ps->offset);
200         if (q == NULL) return False;
201
202         DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
203         ps->offset += str->str_str_len * sizeof(uint8);
204
205         return True;
206 }
207
208 /******************************************************************
209  stream a unicode string, length/buffer specified separately,
210  in uint16 chars.
211  ********************************************************************/
212 BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
213 {
214         char *q = mem_data(&(ps->data), ps->offset);
215         if (q == NULL) return False;
216
217         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
218         ps->offset += str->uni_str_len * sizeof(uint16);
219
220         return True;
221 }
222
223 /*******************************************************************
224  stream a unicode  null-terminated string
225  ********************************************************************/
226 BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
227 {
228         char *q = mem_data(&(ps->data), ps->offset);
229         int i = 0;
230         uint8 *start = (uint8*)q;
231
232         if (q == NULL) return False;
233
234         do 
235         {
236                 RW_SVAL(ps->io, q, str->buffer[i],0);
237                 q += 2;
238                 i++;
239
240         } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
241                      (str->buffer[i] != 0));
242
243         ps->offset += i*2;
244
245         dump_data(5+depth, (char *)start, ps->offset);
246
247         return True;
248 }
249
250 /*******************************************************************
251  stream a null-terminated string.  len is strlen, and therefore does
252  not include the null-termination character.
253
254  len == 0 indicates variable length string
255  (up to max size of pstring - 1024 chars).
256
257  ********************************************************************/
258 BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len)
259 {
260         char *q = mem_data(&(ps->data), ps->offset);
261         uint8 *start = (uint8*)q;
262         int i = -1; /* start off at zero after 1st i++ */
263
264         if (q == NULL) return False;
265
266         do
267         {
268                 i++;
269
270                 if (i < len || len == 0)
271                 {
272                         RW_CVAL(ps->io, q, str[i],0);
273                 }
274                 else
275                 {
276                         uint8 dummy = 0;
277                         RW_CVAL(ps->io, q, dummy,0);
278                 }
279
280                 q++;
281
282         } while (i < sizeof(pstring) && (len == 0 ? str[i] != 0 : i < len) );
283
284         ps->offset += i+1;
285
286         dump_data(5+depth, (char *)start, ps->offset);
287
288         return True;
289 }
290