From eee003da6aee5ffc00e318fc0390e6b19151a675 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Jun 2000 02:59:50 +0000 Subject: started adding support for relative, plus options for autoalignment so the same parser generator can be uses for cifs and rpc (This used to be commit c7829fa0d87081d9b3f33468527583e3b763916b) --- source3/aparser/Makefile | 2 +- source3/aparser/build | 2 +- source3/aparser/cifs.struct | 3 + source3/aparser/dump.awk | 6 + source3/aparser/header.awk | 10 +- source3/aparser/main.awk | 9 +- source3/aparser/parser.c | 20 ++- source3/aparser/parser.h | 19 ++- source3/aparser/parserel.awk | 213 +++++++++++++++++++++++++++++ source3/aparser/parsetree.awk | 12 +- source3/aparser/spool.struct | 36 ++--- source3/aparser/srvsvc2.struct | 5 + source3/aparser/templates/module_start.tpl | 1 - source3/aparser/token.awk | 5 + source3/aparser/util.awk | 6 + source3/aparser/util.c | 112 +++++++++++++++ source3/aparser/vluke.c | 2 + 17 files changed, 421 insertions(+), 42 deletions(-) create mode 100644 source3/aparser/parserel.awk create mode 100644 source3/aparser/util.c (limited to 'source3') diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile index 68e63193c2..953743b234 100644 --- a/source3/aparser/Makefile +++ b/source3/aparser/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -g CC=gcc -OBJ = vluke.o parser.o util.o +OBJ = vluke.o parser.o AWKPROGS=dump.awk harness.awk header.awk parsefn.awk main.awk parsetree.awk template.awk util.awk all: test.h vluke diff --git a/source3/aparser/build b/source3/aparser/build index 574cad9620..4cdf2901f8 100755 --- a/source3/aparser/build +++ b/source3/aparser/build @@ -8,6 +8,6 @@ if ! igawk -f main.awk $file; then fi echo compiling vluke -gcc -Wall -o vluke parser.c vluke.c util.c +gcc -Wall -g -o vluke parser.c vluke.c util.c echo done. diff --git a/source3/aparser/cifs.struct b/source3/aparser/cifs.struct index 9bafa1f930..202f0d7e61 100644 --- a/source3/aparser/cifs.struct +++ b/source3/aparser/cifs.struct @@ -1,5 +1,8 @@ module cifs +option autoalign False + + #define BOOL uint32 #define UCHAR uint8 #define WCHAR uint16 diff --git a/source3/aparser/dump.awk b/source3/aparser/dump.awk index 65e5675513..11bfb107e4 100644 --- a/source3/aparser/dump.awk +++ b/source3/aparser/dump.awk @@ -52,6 +52,12 @@ function dump_structs(f, NIL, LOCAL, i, j) { xprintf(f,"/* dump of parsed structures */\n\n\n"); + + for (i=0;i < num_options;i++) { + xprintf(f,"option %s %s\n", options[i, "name"], options[i, "value"]); + } + xprintf(f,"\n\n"); + for (i=0;i < num_structs;i++) { xprintf(f,"/* structure %d */\n", i); xprintf(f,"struct %s {\n", structs[i, "name"]); diff --git a/source3/aparser/header.awk b/source3/aparser/header.awk index 900985b84b..ba7117436b 100644 --- a/source3/aparser/header.awk +++ b/source3/aparser/header.awk @@ -7,7 +7,7 @@ function header_elstring(elnum, elem=elements[elnum, "elem"]; if (elements[elnum, "ptr"]=="1") elem="*"elem; if (array_len!="") { - if (match(array_len,"[0-9]") == 1) { + if (is_constant(array_len) == 1) { elem=elem"["array_len"]"; } else { elem="*"elem; @@ -63,6 +63,14 @@ function produce_headers(f, NIL, xprintf(f,"/* auto-generated headers for %s */\n\n\n", module); xprintf(f,"#ifndef _%s_\n", module); xprintf(f,"#define _%s_\n", module); + + xprintf(f,"\n\n"); + for (i=0;i < num_options;i++) { + xprintf(f,"#define OPTION_%s %s\n", + options[i, "name"], options[i, "value"]); + } + xprintf(f,"\n\n"); + for (i=0;i < num_structs;i++) { header_struct(f, i); } diff --git a/source3/aparser/main.awk b/source3/aparser/main.awk index 7163dbc829..4969f2217a 100644 --- a/source3/aparser/main.awk +++ b/source3/aparser/main.awk @@ -4,7 +4,8 @@ @include header.awk @include util.awk @include template.awk -@include parsefn.awk +#@include parsefn.awk +@include parserel.awk @include harness.awk @include parsetree.awk @include token.awk @@ -13,8 +14,10 @@ END { dump_structs("dump.out"); printf("Producing headers...\n"); produce_headers("prs_"module".h"); - printf("Producing parsers...\n"); - produce_parsers("prs_"module".c", "mod_"module".c"); +# printf("Producing parsers...\n"); +# produce_parsers("prs_"module".c", "mod_"module".c"); + printf("Producing relative parsers...\n"); + produce_relative("prs_"module".c"); printf("Producing harness...\n"); produce_harness("test.h"); printf("Done.\n"); diff --git a/source3/aparser/parser.c b/source3/aparser/parser.c index f831393973..c2348b84f9 100644 --- a/source3/aparser/parser.c +++ b/source3/aparser/parser.c @@ -1,5 +1,4 @@ -#include "includes.h" - +#include "parser.h" /******************************************************************* Attempt, if needed, to grow a data buffer. @@ -33,12 +32,7 @@ BOOL io_grow(io_struct *ps, uint32 extra_space) extra_space -= (ps->buffer_size - ps->data_offset); if(ps->buffer_size == 0) { - /* - * Ensure we have at least a PDU's length, or extra_space, whichever - * is greater. - */ - - new_size = MAX(MAX_PDU_FRAG_LEN,extra_space); + new_size = extra_space; if((new_data = malloc(new_size)) == NULL) { DEBUG(0,("io_grow: Malloc failure for size %u.\n", (unsigned int)new_size)); @@ -169,10 +163,12 @@ BOOL io_align4(io_struct *ps, int offset) BOOL io_align(io_struct *ps, int align) { - uint32 mod = ps->data_offset & (align-1); + uint32 mod; + + if (!ps->autoalign) return True; + + mod = ps->data_offset & (align-1); - return True; /* HACK! */ - if (align != 0 && mod != 0) { uint32 extra_space = (align - mod); if(!io_grow(ps, extra_space)) @@ -430,7 +426,7 @@ BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, q = io_mem_get(ps, len * sizeof(uint16)); if (q == NULL) return False; - DBG_RW_PSVAL(False, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + DBG_RW_PSVAL(True, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) ps->data_offset += (len * sizeof(uint16)); return True; diff --git a/source3/aparser/parser.h b/source3/aparser/parser.h index e5e5a757cb..3d6540d8a7 100644 --- a/source3/aparser/parser.h +++ b/source3/aparser/parser.h @@ -1,4 +1,9 @@ #include +#include +#include +#include +#include +#include #include "../include/byteorder.h" #define PARSE_SCALARS (1<<0) @@ -11,10 +16,9 @@ #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif -/* Maximum PDU fragment size. */ -#define MAX_PDU_FRAG_LEN 0x1630 #define DEBUG(lvl, str) printf str; +#define DEBUGADD(lvl, str) printf str; #define MARSHALL 0 #define UNMARSHALL 1 @@ -24,11 +28,15 @@ typedef int BOOL; typedef unsigned char uint8; +typedef unsigned char uchar; typedef unsigned short uint16; typedef unsigned short wchar; typedef unsigned uint32; typedef char *SMBSTR; +/* a null terminated unicode string */ +typedef uint16 ZUSTRING; + #ifndef _PSTRING #define PSTRING_LEN 1024 @@ -59,6 +67,7 @@ typedef struct _io_struct */ BOOL bigendian_data; BOOL is_dynamic; /* Do we own this memory or not ? */ + BOOL autoalign; /* should we auto-align all elements? */ uint32 data_offset; /* Current working offset into data. */ uint32 buffer_size; /* Current size of the buffer. */ uint32 grow_size; /* size requested via io_grow() calls */ @@ -72,7 +81,6 @@ void io_debug(io_struct *ps, int depth, char *desc, char *fn_name); BOOL io_align(io_struct *ps, int align); BOOL io_align4(io_struct *ps, int align); BOOL io_align2(io_struct *ps, int align); -void print_asc(int level, unsigned char *buf,int len); BOOL io_read(io_struct *ps, int fd, size_t len, int timeout); void dump_data(int level,char *buf1,int len); BOOL io_alloc(char *name, io_struct *ps, void **ptr, unsigned size); @@ -88,5 +96,8 @@ BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, un char *tab_depth(int depth); void *Realloc(void *p,size_t size); -void print_asc(int level, unsigned char *buf,int len); void dump_data(int level,char *buf1,int len); +void print_asc(int level, uchar const *buf, int len); +BOOL io_ZUSTRING(char *name, io_struct *ps, int depth, uint16 **ustr, unsigned flags); +size_t strlen_w(void *src); + diff --git a/source3/aparser/parserel.awk b/source3/aparser/parserel.awk new file mode 100644 index 0000000000..6d80f0607e --- /dev/null +++ b/source3/aparser/parserel.awk @@ -0,0 +1,213 @@ +# build parse functions for a parsed struct file + +function elem_name(v, elem) +{ + return v["UNION"]elem; +} + +function parse_array(f, v, elnum, flags, + LOCAL, type, elem, array_len) +{ + type = elements[elnum, "type"]; + elem = elements[elnum, "elem"]; + array_len = elements[elnum, "array_len"]; + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + v["ARRAY_LEN"] = array_len; + + if (array_len=="+") { + print_template(f,"prs_array_optional.tpl", v); + return; + } + + if (array_len=="&") { + print_template(f,"prs_array_null.tpl", v); + return; + } + + if (array_len=="*") { + print_template(f,"prs_array_remainder.tpl", v); + return; + } + + if (type == "wchar" || type == "uint16") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_wstring_fixed.tpl", v); + } else { + print_template(f, "prs_wstring.tpl", v); + } + } else if (type == "uint8") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_uint8s_fixed.tpl", v); + } else { + print_template(f, "prs_uint8s.tpl", v); + } + } else { + print_template(f, "prs_array.tpl", v); + } +} + + +function parse_element(f, v, elnum, flags, + LOCAL, type, elem) +{ + if (elements[elnum,"nowire"] != "") { + return; + } + type = elements[elnum, "type"]; + if (substr(type,1,1) == ".") return; + elem = elements[elnum, "elem"]; + if (elements[elnum,"ptr"] == "") { + v["PTR"] = "\\&"; + } else { + v["PTR"] = " "; + } + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + print_template(f, "prs_element.tpl", v); +} + +function parse_union(f, v, elnum, flags, + LOCAL, i) +{ + v["UNION"] = elements[elnum, "elem"]; + v["SWITCH"] = elements[elnum, "switch"]; + + if (elements[elnum, "ptr"] == "1") { + v["UNION"] = v["UNION"]"->"; + } else { + v["UNION"] = v["UNION"]"."; + } + + print_template(f, "union_start.tpl", v); + for (i=0;i 8) + DEBUGADD(level, (" ")); + while (n--) + DEBUGADD(level, (" ")); + + n = MIN(8, i % 16); + print_asc(level, &buf[i - (i % 16)], n); + DEBUGADD(level, (" ")); + n = (i % 16) - n; + if (n > 0) + print_asc(level, &buf[i - n], n); + DEBUGADD(level, ("\n")); + } +} diff --git a/source3/aparser/vluke.c b/source3/aparser/vluke.c index 87664267d0..d3868f2753 100644 --- a/source3/aparser/vluke.c +++ b/source3/aparser/vluke.c @@ -1,3 +1,4 @@ +#include "parser.h" #include "test.h" int main(int argc, char *argv[]) @@ -29,6 +30,7 @@ int main(int argc, char *argv[]) ps.data_offset = 0; ps.buffer_size = ps.grow_size; ps.io = UNMARSHALL; + ps.autoalign = OPTION_autoalign; ret = run_test(test, &ps, PARSE_SCALARS|PARSE_BUFFERS); printf("\nret=%s\n", ret?"OK":"Bad"); printf("Trailer is %d bytes\n\n", ps.grow_size - ps.data_offset); -- cgit