34f72596ce099a31002e37d5dddc1d101f6fe480
[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  link one parsing structure to another
71  ********************************************************************/
72 void prs_link(prs_struct *ps, prs_struct const *const to)
73 {
74         DEBUG(0,("NOT IMPLEMENTED\n"));
75 }
76
77 /*******************************************************************
78  align a pointer to a multiple of align_offset bytes.  looks like it
79  will work for offsets of 0, 2 and 4...
80  ********************************************************************/
81 void prs_align(prs_struct *ps)
82 {
83         int mod = ps->offset & (ps->align-1);
84         if (ps->align != 0 && mod != 0)
85         {
86                 ps->offset += ps->align - mod;
87         }
88 }
89
90 /*******************************************************************
91  attempt, if appropriate, to grow a data buffer.
92
93  depends on the data stream mode (io)
94  ********************************************************************/
95 BOOL prs_grow(prs_struct *ps)
96 {
97         return mem_grow_data(&(ps->data), ps->io, ps->offset, False);
98 }
99
100
101 /*******************************************************************
102  stream a uint8
103  ********************************************************************/
104 BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
105 {
106         char *q = mem_data(&(ps->data), ps->offset);
107         if (q == NULL) return False;
108
109         DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
110         ps->offset += 1;
111
112         return True;
113 }
114
115 /*******************************************************************
116  stream a uint16
117  ********************************************************************/
118 BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
119 {
120         char *q = mem_data(&(ps->data), ps->offset);
121         if (q == NULL) return False;
122
123         DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
124         ps->offset += 2;
125
126         return True;
127 }
128
129 /*******************************************************************
130  stream a uint32
131  ********************************************************************/
132 BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
133 {
134         char *q = mem_data(&(ps->data), ps->offset);
135         if (q == NULL) return False;
136
137         DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
138         ps->offset += 4;
139
140         return True;
141 }
142
143
144 /******************************************************************
145  stream an array of uint8s.  length is number of uint8s
146  ********************************************************************/
147 BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
148 {
149         char *q = mem_data(&(ps->data), ps->offset);
150         if (q == NULL) return False;
151
152         DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
153         ps->offset += len;
154
155         return True;
156 }
157
158 /******************************************************************
159  stream an array of uint32s.  length is number of uint32s
160  ********************************************************************/
161 BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
162 {
163         char *q = mem_data(&(ps->data), ps->offset);
164         if (q == NULL) return False;
165
166         DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
167         ps->offset += len * sizeof(uint32);
168
169         return True;
170 }
171
172 /******************************************************************
173  stream a "not" unicode string, length/buffer specified separately,
174  in byte chars
175  ********************************************************************/
176 BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str)
177 {
178         char *q = mem_data(&(ps->data), ps->offset);
179         if (q == NULL) return False;
180
181         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
182         ps->offset += str->uni_buf_len;
183
184         return True;
185 }
186
187 /******************************************************************
188  stream a string, length/buffer specified separately,
189  in uint8 chars.
190  ********************************************************************/
191 BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
192 {
193         char *q = mem_data(&(ps->data), ps->offset);
194         if (q == NULL) return False;
195
196         DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
197         ps->offset += str->str_str_len * sizeof(uint8);
198
199         return True;
200 }
201
202 /******************************************************************
203  stream a unicode string, length/buffer specified separately,
204  in uint16 chars.
205  ********************************************************************/
206 BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
207 {
208         char *q = mem_data(&(ps->data), ps->offset);
209         if (q == NULL) return False;
210
211         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
212         ps->offset += str->uni_str_len * sizeof(uint16);
213
214         return True;
215 }
216
217 /*******************************************************************
218  stream a unicode  null-terminated string
219  ********************************************************************/
220 BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
221 {
222         char *q = mem_data(&(ps->data), ps->offset);
223         int i = 0;
224         uint8 *start = (uint8*)q;
225
226         if (q == NULL) return False;
227
228         do 
229         {
230                 RW_SVAL(ps->io, q, str->buffer[i],0);
231                 q += 2;
232                 i++;
233
234         } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
235                      (str->buffer[i] != 0));
236
237         ps->offset += i*2;
238
239         dump_data(5+depth, (char *)start, ps->offset);
240
241         return True;
242 }
243
244 /*******************************************************************
245  stream a null-terminated string.  len is strlen, and therefore does
246  not include the null-termination character.
247
248  len == 0 indicates variable length string
249  (up to max size of pstring - 1024 chars).
250
251  ********************************************************************/
252 BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
253 {
254         char *q = mem_data(&(ps->data), ps->offset);
255         uint8 *start = (uint8*)q;
256         int i = -1; /* start off at zero after 1st i++ */
257
258         if (q == NULL) return False;
259
260         do
261         {
262                 i++;
263
264                 if (i < len || len == 0)
265                 {
266                         RW_CVAL(ps->io, q, str[i],0);
267                 }
268                 else
269                 {
270                         uint8 dummy = 0;
271                         RW_CVAL(ps->io, q, dummy,0);
272                 }
273
274                 q++;
275
276         } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
277
278         ps->offset += i+1;
279
280         dump_data(5+depth, (char *)start, ps->offset);
281
282         return True;
283 }
284