This commit was manufactured by cvs2svn to create branch 'SAMBA_TNG'.
[Samba.git] / source / rpc_parse / parse_prs.c
blob49481f7f2e7bc313f357317c6060786b7ee64336
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba memory buffer functions
5 Copyright (C) Andrew Tridgell 1992-1999
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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 extern int DEBUGLEVEL;
25 #include "includes.h"
28 /*******************************************************************
29 debug output for parsing info.
30 ********************************************************************/
31 void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
33 CHECK_STRUCT(ps);
34 DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
37 /*******************************************************************
38 debug a parse structure
39 ********************************************************************/
40 void prs_debug_out(const prs_struct *ps, char *msg, int level)
42 CHECK_STRUCT(ps);
43 DEBUG(level,("%s ps: io %s align %d offset %d err %d data %p\n",
44 msg, BOOLSTR(ps->io), ps->align, ps->offset, ps->error,
45 ps->data));
47 if (ps->data != NULL)
49 dump_data(level, ps->data, prs_buf_len(ps));
53 /*******************************************************************
54 initialise a parse structure
55 ********************************************************************/
56 void prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
58 ps->struct_start = 0xfefefefe;
59 ps->io = io;
60 ps->align = align;
61 ps->offset = 0;
62 ps->error = False;
63 ps->bigendian = False;
65 ps->data = NULL;
66 ps->data_size = 0;
68 ps->start = 0;
69 ps->end = 0;
71 ps->next = NULL;
73 ps->struct_end = 0xdcdcdcdc;
75 if (size != 0)
77 prs_realloc_data(ps, size);
78 ps->end = 0xffffffff;
81 CHECK_STRUCT(ps);
84 /*******************************************************************
85 set the packed data representation type in a parse structure
86 ********************************************************************/
87 void prs_set_packtype(prs_struct *ps, const uint8 *pack_type)
89 CHECK_STRUCT(ps);
90 ps->bigendian = pack_type[0] == 0x0;
93 /*******************************************************************
94 create a parse structure
95 ********************************************************************/
96 void prs_create(prs_struct *ps, char *data, uint32 size, uint8 align, BOOL io)
98 DEBUG(200,("prs_create: data:%p size:%d align:%d io:%s\n",
99 data, size, align, BOOLSTR(io)));
101 prs_init(ps, 0, align, io);
102 ps->data = data;
103 ps->data_size = size;
104 ps->end = size;
106 CHECK_STRUCT(ps);
109 /*******************************************************************
110 copy a parse structure
111 ********************************************************************/
112 BOOL prs_copy(prs_struct *ps, const prs_struct *from)
114 int len = prs_buf_len(from);
115 CHECK_STRUCT(ps);
116 CHECK_STRUCT(from);
117 prs_init(ps, len, from->align, from->io);
118 ps->bigendian = from->bigendian;
119 if (len != 0)
121 if (ps->data == NULL)
123 return False;
125 if (!prs_buf_copy(ps->data, from, 0, len))
127 return False;
130 ps->offset = len;
131 prs_link(NULL, ps, NULL);
132 return True;
135 /*******************************************************************
136 allocate a memory buffer. assume it's empty
137 ********************************************************************/
138 BOOL prs_alloc_data(prs_struct *buf, int size)
140 CHECK_STRUCT(buf);
142 buf->data_size = size;
143 buf->data = (char*)malloc(buf->data_size);
145 if (buf->data == NULL && size != 0)
147 DEBUG(3,("prs_alloc: could not malloc size %d\n",
148 buf->data_size));
149 buf->data_size = 0;
151 return False;
154 bzero(buf->data, buf->data_size);
155 buf->end = buf->start + size;
157 CHECK_STRUCT(buf);
158 return True;
161 /*******************************************************************
162 search for a memory buffer that falls within the specified offset
163 ********************************************************************/
164 static const prs_struct *prs_find(const prs_struct *buf, uint32 offset)
166 const prs_struct *f;
167 if (buf == NULL) return False;
169 f = buf;
171 CHECK_STRUCT(f);
172 DEBUG(200,("prs_find: data[%d..%d] offset: %d\n",
173 f->start, f->end, offset));
175 while (f != NULL && offset >= f->end)
177 DEBUG(200,("prs_find: next[%d..%d]\n", f->start, f->end));
179 f = f->next;
182 if (f != NULL)
184 DEBUG(200,("prs_find: found data[%d..%d]\n", f->start, f->end));
187 return f;
190 /*******************************************************************
191 allocates a memory buffer structure
192 ********************************************************************/
193 BOOL prs_buf_copy(char *copy_into, const prs_struct *buf,
194 uint32 offset, uint32 len)
196 uint32 end = offset + len;
197 char *q = NULL;
198 uint32 data_len = prs_buf_len(buf);
199 uint32 start_offset = offset;
200 const prs_struct *bcp = buf;
202 if (buf == NULL || copy_into == NULL) return False;
204 CHECK_STRUCT(buf);
205 DEBUG(200,("prs_struct_copy: data[%d..%d] offset %d len %d\n",
206 buf->start, data_len, offset, len));
208 prs_debug_out(bcp, "prs_struct_copy", 200);
210 /* there's probably an off-by-one bug, here, and i haven't even tested the code :-) */
211 while (offset < end && ((q = prs_data(bcp, offset)) != NULL))
213 uint32 copy_len;
214 bcp = prs_find(bcp, offset);
215 copy_len = bcp->end - offset;
217 DEBUG(200,("\tdata[%d..%d] - offset %d len %d\n",
218 bcp->start, bcp->end,
219 offset, copy_len));
221 memcpy(copy_into, q, copy_len);
223 offset += copy_len;
224 copy_into += copy_len;
227 if (bcp != NULL)
229 DEBUG(200,("prs_struct_copy: copied %d bytes\n", offset - start_offset));
231 else
233 DEBUG(200,("prs_struct_copy: failed\n"));
236 return buf != NULL;
239 /*******************************************************************
240 frees up a memory buffer.
241 ********************************************************************/
242 void prs_struct_free(prs_struct **buf)
244 if (buf == NULL) return;
245 if ((*buf) == NULL) return;
247 CHECK_STRUCT(*buf);
248 prs_free_data(*buf); /* delete memory data */
249 free(*buf); /* delete item */
250 (*buf) = NULL;
253 /*******************************************************************
254 frees a memory buffer chain. assumes that all items are malloced.
255 ********************************************************************/
256 static void prs_free_chain(prs_struct **buf)
258 if (buf == NULL) return;
259 if ((*buf) == NULL) return;
261 CHECK_STRUCT(*buf);
262 if ((*buf)->next != NULL)
264 prs_free_chain(&((*buf)->next)); /* delete all other items in chain */
266 prs_struct_free(buf);
269 /*******************************************************************
270 frees a memory buffer.
271 ********************************************************************/
272 void prs_free_data(prs_struct *buf)
274 if (buf == NULL) return;
276 if (buf->data != NULL)
278 CHECK_STRUCT(buf);
279 free(buf->data); /* delete data in this structure */
280 buf->data = NULL;
282 buf->data_size = 0;
285 static void *prs_realloc(void *p, size_t size)
287 void *ret;
288 if (size == 0)
290 safe_free(p);
291 return NULL;
293 ret = (void *)malloc(size);
294 if (!ret) return NULL;
295 if (p) {
296 memcpy(ret, p, size);
297 memset(p, 0, 1);
299 safe_free(p);
300 return ret;
303 /*******************************************************************
304 reallocate a memory buffer
305 ********************************************************************/
306 BOOL prs_realloc_data(prs_struct *buf, size_t new_size)
308 char *new_data;
310 CHECK_STRUCT(buf);
312 prs_debug_out(buf, "prs_realloc_data - before", 200);
314 if (new_size == 0)
316 prs_free_data(buf);
317 return True;
320 new_data = (char*)Realloc(buf->data, new_size);
322 if (new_data != NULL)
324 if (new_size > buf->data_size)
326 memset(&new_data[buf->data_size], 0, new_size - buf->data_size);
328 buf->data = new_data;
329 buf->data_size = new_size;
331 else if (buf->data_size >= new_size)
333 DEBUG(3,("prs_realloc_data: warning - could not realloc to %d\n",
334 new_size));
336 else
338 DEBUG(3,("prs_realloc_data: error - could not realloc to %d\n",
339 new_size));
341 prs_free_data(buf);
342 return False;
345 buf->end = buf->start + new_size;
347 prs_debug_out(buf, "prs_realloc_data - after", 200);
348 return True;
351 /*******************************************************************
352 reallocate a memory buffer, retrospectively :-)
353 ********************************************************************/
354 BOOL prs_grow_data(prs_struct *buf, BOOL io, int new_size, BOOL force_grow)
356 if (buf == NULL)
358 return False;
361 CHECK_STRUCT(buf);
363 if (new_size >= buf->data_size)
365 if (!io || force_grow)
367 /* writing or forge realloc */
368 return prs_realloc_data(buf, new_size);
370 else
374 return True;
378 /*******************************************************************
379 add up the lengths of all sections.
380 ********************************************************************/
381 uint32 prs_buf_len(const prs_struct *buf)
383 int len = 0;
384 CHECK_STRUCT(buf);
385 while (buf != NULL)
387 len += buf->end - buf->start;
388 buf = buf->next;
390 return len;
393 /*******************************************************************
394 return the memory location specified by may return NULL.
395 ********************************************************************/
396 char *prs_data(const prs_struct *buf, uint32 offset)
398 CHECK_STRUCT(buf);
399 buf = prs_find(buf, offset);
400 if (buf != NULL)
402 return &(buf->data[offset - buf->start]);
404 return NULL;
408 /*******************************************************************
409 link one parsing structure to another
410 ********************************************************************/
411 void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
413 CHECK_STRUCT(ps);
414 if (next != NULL)
416 CHECK_STRUCT(next);
418 if (prev != NULL)
420 CHECK_STRUCT(prev);
422 ps->start = prev != NULL ? prev->end : 0;
423 ps->end = ps->start + ps->offset;
425 ps->next = next;
427 DEBUG(150,("prs_link: start %d end %d\n", ps->start, ps->end));
430 /*******************************************************************
431 align a pointer to a multiple of align_offset bytes. looks like it
432 will work for offsets of 0, 2 and 4...
433 ********************************************************************/
434 void prs_align(prs_struct *ps)
436 int mod;
437 CHECK_STRUCT(ps);
438 if (ps->error) return;
439 mod = ps->offset & (ps->align-1);
440 if (ps->align != 0 && mod != 0)
442 ps->offset += ps->align - mod;
443 prs_grow(ps, ps->offset);
447 /*******************************************************************
448 attempt, if appropriate, to grow a data buffer.
450 depends on the data stream mode (io)
451 ********************************************************************/
452 BOOL prs_grow(prs_struct *ps, uint32 new_size)
454 CHECK_STRUCT(ps);
455 if (ps->error) return False;
456 return prs_grow_data(ps, ps->io, new_size, False);
459 /*******************************************************************
460 lengthens a buffer by len bytes and copies data into it.
461 ********************************************************************/
462 BOOL prs_append_data(prs_struct *ps, const char *data, int len)
464 int prev_size = ps->data_size;
465 int new_size = prev_size + len;
466 char *to;
468 DEBUG(200,("prs_append_data: prev_size: %d new_size: %d\n",
469 prev_size, new_size));
471 CHECK_STRUCT(ps);
472 prs_realloc_data(ps, new_size);
473 to = prs_data(ps, prev_size);
475 if (to == NULL || ps->data_size != new_size)
477 return False;
479 memcpy(to, data, len);
481 return True;
484 BOOL prs_add_data(prs_struct *ps, const char *data, int len)
486 int prev_size;
487 int new_size;
488 char *to = NULL;
490 ps->offset = 0;
492 if (ps->data == NULL)
494 DEBUG(10,("prs_add_data: new_size: %d\n", len));
495 prs_init(ps, len, 4, True);
496 prev_size = 0;
497 new_size = len;
498 if (ps->data == NULL)
500 return False;
503 else
505 prev_size = ps->data_size;
506 new_size = prev_size + len;
507 DEBUG(10,("prs_add_data: prev_size: %d new_size: %d\n",
508 prev_size, new_size));
509 if (!prs_realloc_data(ps, new_size))
511 return False;
515 DEBUG(10,("ps->start: %d\n", ps->start));
516 ps->start = 0x0;
518 to = prs_data(ps, prev_size);
519 if (to == NULL)
521 DEBUG(10,("prs_add_data: data could not be found\n"));
522 return False;
524 if (ps->data_size != new_size)
526 DEBUG(10,("prs_add_data: ERROR: data used %d new_size %d\n",
527 ps->data_size, new_size));
528 return False;
530 memcpy(to, data, len);
531 return True;
534 /*******************************************************************
535 stream a uint8
536 ********************************************************************/
537 BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
539 char *q;
540 CHECK_STRUCT(ps);
541 if (ps->error) return False;
542 prs_grow(ps, ps->offset + 1);
543 q = prs_data(ps, ps->offset);
544 if (q == NULL)
546 ps->error = True;
547 prs_debug_out(ps, "_prs_uint8 error", 5);
548 return False;
551 DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
552 ps->offset += 1;
555 return True;
558 /*******************************************************************
559 stream a uint16
560 ********************************************************************/
561 BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
563 char *q;
564 CHECK_STRUCT(ps);
565 if (ps->error) return False;
566 prs_grow(ps, ps->offset + 2);
567 q = prs_data(ps, ps->offset);
568 if (q == NULL)
570 ps->error = True;
571 prs_debug_out(ps, "_prs_uint16 error", 5);
572 return False;
575 DBG_RW_SVAL(name, depth, ps->offset, ps->io, ps->bigendian, q, *data16)
576 ps->offset += 2;
578 return True;
581 /*******************************************************************
582 hash a stream.
583 ********************************************************************/
584 BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
586 char *q;
587 CHECK_STRUCT(ps);
588 if (ps->error) return False;
589 q = prs_data(ps, ps->offset);
590 if (q == NULL)
592 ps->error = True;
593 prs_debug_out(ps, "_prs_hash1 error", 5);
594 return False;
597 #ifdef DEBUG_PASSWORD
598 DEBUG(100,("prs_hash1\n"));
599 dump_data(100, sess_key, 16);
600 dump_data(100, q, 68);
601 #endif
602 SamOEMhash((uchar*)q, sess_key, 2);
603 #ifdef DEBUG_PASSWORD
604 dump_data(100, q, 68);
605 #endif
607 return True;
610 /*******************************************************************
611 stream a uint32
612 ********************************************************************/
613 BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
615 char *q;
616 CHECK_STRUCT(ps);
617 if (ps->error) return False;
618 prs_grow(ps, ps->offset + 4);
619 q = prs_data(ps, ps->offset);
620 if (q == NULL)
622 fstring str;
623 slprintf(str, sizeof(str)-1, "_prs_uint32 error (%s)", name);
624 ps->error = True;
625 prs_debug_out(ps, str, 5);
626 return False;
629 DBG_RW_IVAL(name, depth, ps->offset, ps->io, ps->bigendian, q, *data32)
630 ps->offset += 4;
632 return True;
636 /******************************************************************
637 stream an array of uint8s. length is number of uint8s
638 ********************************************************************/
639 BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
641 char *q;
642 int end_offset;
643 char *e;
644 CHECK_STRUCT(ps);
646 if (len == 0)
648 return True;
651 if (ps->error) return False;
652 end_offset = ps->offset + len * sizeof(uint8);
653 prs_grow(ps, end_offset);
654 q = prs_data(ps, ps->offset);
655 e = prs_data(ps, end_offset-1);
657 if (q == NULL || e == NULL)
659 ps->error = True;
660 prs_debug_out(ps, "_prs_uint8s error", 5);
661 return False;
664 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
665 ps->offset = end_offset;
667 return True;
670 /******************************************************************
671 stream an array of uint16s. length is number of uint16s
672 ********************************************************************/
673 BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
675 char *q;
676 int end_offset;
677 char *e;
678 CHECK_STRUCT(ps);
679 if (ps->error) return False;
681 if (len == 0)
683 return True;
686 end_offset = ps->offset + len * sizeof(uint16);
687 prs_grow(ps, end_offset);
688 q = prs_data(ps, ps->offset);
689 e = prs_data(ps, end_offset-1);
691 if (q == NULL || e == NULL)
693 ps->error = True;
694 prs_debug_out(ps, "_prs_uint16s error", 5);
695 return False;
698 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, data16s, len)
699 ps->offset = end_offset;
701 return True;
704 /******************************************************************
705 stream an array of uint32s. length is number of uint32s
706 ********************************************************************/
707 BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
709 char *q;
710 int end_offset;
711 char *e;
712 CHECK_STRUCT(ps);
713 if (ps->error) return False;
715 if (len == 0)
717 return True;
720 end_offset = ps->offset + len * sizeof(uint32);
721 prs_grow(ps, end_offset);
722 q = prs_data(ps, ps->offset);
723 e = prs_data(ps, end_offset-1);
725 if (q == NULL || e == NULL)
727 ps->error = True;
728 prs_debug_out(ps, "_prs_uint32s error", 5);
729 return False;
732 DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, data32s, len)
733 ps->offset = end_offset;
735 return True;
738 /******************************************************************
739 stream a "not" unicode string, length/buffer specified separately,
740 in byte chars
741 ********************************************************************/
742 BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
744 char *q;
745 int end_offset;
746 char *e;
747 CHECK_STRUCT(ps);
748 if (ps->error) return False;
750 if (str->buf_len == 0)
752 return True;
755 end_offset = ps->offset + str->buf_len * sizeof(uint8);
756 prs_grow(ps, end_offset);
757 q = prs_data(ps, ps->offset);
758 e = prs_data(ps, end_offset-1);
760 if (q == NULL || e == NULL)
762 ps->error = True;
763 prs_debug_out(ps, "_prs_buffer2 error", 5);
764 return False;
767 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
768 ps->offset = end_offset;
770 return True;
773 /******************************************************************
774 stream a string, length/buffer specified separately,
775 in uint8 chars.
776 ********************************************************************/
777 BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
779 char *q;
780 int end_offset;
781 char *e;
782 CHECK_STRUCT(ps);
783 if (ps->error) return False;
785 if (str->str_str_len == 0)
787 return True;
790 end_offset = ps->offset + str->str_str_len * sizeof(uint8);
791 prs_grow(ps, end_offset);
792 q = prs_data(ps, ps->offset);
793 e = prs_data(ps, end_offset-1);
795 if (q == NULL || e == NULL)
797 ps->error = True;
798 prs_debug_out(ps, "_prs_string2 error", 5);
799 return False;
802 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_str_len)
803 ps->offset = end_offset;
805 return True;
808 /******************************************************************
809 stream a unicode string, length/buffer specified separately,
810 in uint16 chars.
811 ********************************************************************/
812 BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
814 char *q;
815 int end_offset;
816 char *e;
817 CHECK_STRUCT(ps);
818 if (ps->error) return False;
820 if (str->uni_str_len == 0)
822 return True;
825 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
826 prs_grow(ps, end_offset);
827 q = prs_data(ps, ps->offset);
828 e = prs_data(ps, end_offset-1);
830 if (q == NULL || e == NULL)
832 ps->error = True;
833 prs_debug_out(ps, "_prs_unistr2 error", 5);
834 return False;
837 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, str->buffer, str->uni_str_len)
838 ps->offset = end_offset;
840 return True;
843 /******************************************************************
844 stream a unicode string, length/buffer specified separately,
845 in uint16 chars.
846 ********************************************************************/
847 BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
849 char *q;
850 int end_offset;
851 char *e;
852 CHECK_STRUCT(ps);
853 if (ps->error) return False;
855 if (str->uni_str_len == 0)
857 return True;
860 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
861 prs_grow(ps, end_offset);
862 q = prs_data(ps, ps->offset);
863 e = prs_data(ps, end_offset-1);
865 if (q == NULL || e == NULL)
867 ps->error = True;
868 prs_debug_out(ps, "_prs_unistr3 error", 5);
869 return False;
872 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, str->str.buffer, str->uni_str_len)
873 ps->offset = end_offset;
875 return True;
878 /*******************************************************************
879 stream a unicode null-terminated string
880 ********************************************************************/
881 BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
883 int i = -1;
884 uint8 *start;
885 CHECK_STRUCT(ps);
886 if (ps->error) return False;
887 start = (uint8*)prs_data(ps, ps->offset);
891 char *q;
892 i++;
893 prs_grow(ps, ps->offset + (i+1)*2);
894 q = prs_data(ps, ps->offset + i*2);
895 if (q == NULL)
897 ps->error = True;
898 prs_debug_out(ps, "_prs_unistr error", 5);
899 return False;
901 RW_SVAL(ps->io, ps->bigendian, q, str->buffer[i],0);
903 while ((((size_t)i) < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
904 (str->buffer[i] != 0));
907 ps->offset += (i+1)*2;
909 dump_data(5+depth, (char *)start, i * 2);
911 return True;
914 /*******************************************************************
915 stream a null-terminated string. len is strlen, and therefore does
916 not include the null-termination character.
918 len == 0 indicates variable length string
919 (up to max size of pstring - 1024 chars).
921 ********************************************************************/
922 BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
924 int i = -1; /* start off at zero after 1st i++ */
925 BOOL len_limited;
927 CHECK_STRUCT(ps);
928 if (ps->error) return False;
930 len_limited = len == 0 || !ps->io;
932 DEBUG(200,("_prs_string: string %s len %d max %d\n",
933 str, len, max_buf_size));
935 DEBUG(10,("%s%04x %s: ", tab_depth(depth), ps->offset, name != NULL ? name : ""));
938 char *q;
939 i++;
941 prs_grow(ps, ps->offset + i+1);
942 q = prs_data(ps, ps->offset + i);
943 if (q == NULL)
945 ps->error = True;
946 DEBUG(10,("%s\n", str));
947 prs_debug_out(ps, "_prs_string error", 5);
948 return False;
951 if (i < len || len_limited)
953 RW_CVAL(ps->io, q, str[i], 0);
955 else
957 uint8 dummy = 0;
958 RW_CVAL(ps->io, q, dummy,0);
961 } while (i < max_buf_size && (len_limited ? str[i] != 0 : i < len) );
963 ps->offset += i+1;
965 DEBUG(10,("%s\n", str));
967 return True;
970 /*******************************************************************
971 prs_uint16 wrapper. call this and it sets up a pointer to where the
972 uint16 should be stored, or gets the size if reading
973 ********************************************************************/
974 BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
976 CHECK_STRUCT(ps);
977 if (ps->error) return False;
978 (*offset) = ps->offset;
979 if (ps->io)
981 /* reading. */
982 return _prs_uint16(name, ps, depth, data16);
984 else
986 ps->offset += sizeof(uint16);
988 return True;
991 /*******************************************************************
992 prs_uint16 wrapper. call this and it retrospectively stores the size.
993 does nothing on reading, as that is already handled by ...._pre()
994 ********************************************************************/
995 BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
996 uint32 ptr_uint16, uint32 start_offset)
998 CHECK_STRUCT(ps);
999 if (ps->error) return False;
1000 if (!ps->io)
1002 /* storing: go back and do a retrospective job. i hate this */
1003 uint16 data_size = ps->offset - start_offset;
1004 uint32 old_offset = ps->offset;
1006 ps->offset = ptr_uint16;
1007 prs_uint16(name, ps, depth, &data_size);
1008 ps->offset = old_offset;
1010 else
1012 ps->offset = start_offset + (*data16);
1014 return True;
1017 /*******************************************************************
1018 prs_uint32 wrapper. call this and it sets up a pointer to where the
1019 uint32 should be stored, or gets the size if reading
1020 ********************************************************************/
1021 BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
1023 CHECK_STRUCT(ps);
1024 if (ps->error) return False;
1025 (*offset) = ps->offset;
1026 if (ps->io)
1028 /* reading. */
1029 return _prs_uint32(name, ps, depth, data32);
1031 else
1033 ps->offset += sizeof(uint32);
1035 return True;
1038 /*******************************************************************
1039 prs_uint32 wrapper. call this and it retrospectively stores the size.
1040 does nothing on reading, as that is already handled by ...._pre()
1041 ********************************************************************/
1042 BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
1043 uint32 ptr_uint32, uint32 data_size)
1045 CHECK_STRUCT(ps);
1046 if (ps->error) return False;
1047 if (!ps->io)
1049 /* storing: go back and do a retrospective job. i hate this */
1050 uint32 old_offset = ps->offset;
1051 ps->offset = ptr_uint32;
1052 prs_uint32(name, ps, depth, &data_size);
1053 ps->offset = old_offset;
1055 else
1057 ps->offset = data_size + (*data32);
1059 return True;
1062 /*******************************************************************
1063 prs_tdb_store. stores prs_struct data by prs_struct key
1064 ********************************************************************/
1065 int prs_tdb_delete(TDB_CONTEXT *tdb, prs_struct *pk)
1067 TDB_DATA key;
1069 key.dptr = (char*)prs_data(pk, 0);
1070 key.dsize = prs_buf_len(pk);
1072 return tdb_delete(tdb, key);
1075 /*******************************************************************
1076 prs_tdb_store. stores prs_struct data by prs_struct key
1077 ********************************************************************/
1078 int prs_tdb_store(TDB_CONTEXT *tdb, int flgs, prs_struct *pk, prs_struct *pd)
1080 TDB_DATA key;
1081 TDB_DATA data;
1083 key.dptr = (char*)prs_data(pk, 0);
1084 key.dsize = prs_buf_len(pk);
1086 data.dptr = prs_data(pd, 0);
1087 data.dsize = prs_buf_len(pd);
1089 return tdb_store(tdb, key, data, flgs);
1092 /*******************************************************************
1093 prs_tdb_fetch. fetches prs_struct data by prs_struct key
1094 ********************************************************************/
1095 void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd)
1097 TDB_DATA key;
1098 TDB_DATA data;
1100 key.dptr = (char*)prs_data(pk, 0);
1101 key.dsize = prs_buf_len(pk);
1103 data = tdb_fetch(tdb, key);
1105 prs_create(pd, data.dptr, data.dsize, 4, True);