summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/aparser/Makefile2
-rw-r--r--source3/aparser/basic.awk43
-rw-r--r--source3/aparser/func.awk39
-rw-r--r--source3/aparser/parser.awk207
-rw-r--r--source3/aparser/struct.awk158
-rw-r--r--source3/aparser/test.struct51
-rw-r--r--source3/aparser/union.awk16
7 files changed, 327 insertions, 189 deletions
diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile
index e9ff8ad010..d088071090 100644
--- a/source3/aparser/Makefile
+++ b/source3/aparser/Makefile
@@ -2,7 +2,7 @@ CFLAGS=-Wall -g
CC=gcc
%.h : %.struct
- awk -f parser.awk < $*.struct > $*.h
+ igawk -f parser.awk < $*.struct > $*.h
OBJ = harness.o parser.o
diff --git a/source3/aparser/basic.awk b/source3/aparser/basic.awk
new file mode 100644
index 0000000000..3dab8a4768
--- /dev/null
+++ b/source3/aparser/basic.awk
@@ -0,0 +1,43 @@
+function uint32_parser(elem) {
+ printf("\
+ if(!prs_uint32(\"%s\", ps, depth, &il->%s))\n\
+ return False;\n\
+", elem, elem);
+}
+
+function unistr2_parser(elem) {
+ printf("\
+ if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
+ return False;\n\
+", elem, elem);
+}
+
+function buffer5_parser(elem) {
+ printf("\
+ if(!prs_uint32(\"%s_len\", ps, depth, &il->%s_len))\n\
+ return False;\n\
+ if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
+ return False;\n\
+", elem, elem, elem, elem);
+}
+
+function nttime_parser(elem) {
+ printf("\
+ if(!smb_io_time(\"%s\", &il->%s, ps, depth))\n\
+ return False;\n\
+", elem, elem);
+}
+
+function uint64_parser(elem) {
+ printf("\
+ if(!prs_uint64(\"%s\", ps, depth, &il->%s))\n\
+ return False;\n\
+", elem, elem);
+}
+
+function generic_parser(type, elem) {
+ printf("\
+ if(!%s(\"%s\", &il->%s, ps, depth))\n\
+ return False;\n\
+", "io_"tolower(type), elem, elem);
+}
diff --git a/source3/aparser/func.awk b/source3/aparser/func.awk
new file mode 100644
index 0000000000..fcf21a0a2e
--- /dev/null
+++ b/source3/aparser/func.awk
@@ -0,0 +1,39 @@
+function func_footer() {
+ printf("\n\
+\n\
+ return True;\n\
+}\n");
+}
+
+function func_header(func_name, struct_name)
+{
+ printf("\
+/*******************************************************************\n\
+parse a %s structure\n\
+********************************************************************/ \n\
+BOOL %s(char *desc, %s **q_u, \n\
+ prs_struct *ps, int depth)\n\
+{ \n\
+ %s *il;\n\
+ \n\
+ prs_debug(ps, depth, desc, \"%s\");\n\
+ depth++;\n\
+ \n\
+ /* reading */\n\
+ if (UNMARSHALLING(ps)) {\n\
+ il=(%s *)malloc(sizeof(%s));\n\
+ if(il == NULL)\n\
+ return False;\n\
+ ZERO_STRUCTP(il);\n\
+ *q_u=il;\n\
+ }\n\
+ else {\n\
+ il=*q_u;\n\
+ }\n\
+ \n\
+ if(!prs_align(ps))\n\
+ return False;\n\
+\n\
+", struct_name, func_name, struct_name, struct_name, func_name, struct_name, struct_name);
+}
+
diff --git a/source3/aparser/parser.awk b/source3/aparser/parser.awk
index a32d4b727b..dde43b91a2 100644
--- a/source3/aparser/parser.awk
+++ b/source3/aparser/parser.awk
@@ -1,9 +1,7 @@
-function add_elem(type, elem)
-{
- types[num_elems] = type;
- elems[num_elems] = elem;
- num_elems++;
-}
+@include basic.awk
+@include struct.awk
+@include union.awk
+@include func.awk
function produce_preamble() {
printf("#define TEST_STRUCT %s\n", struct_name);
@@ -12,189 +10,50 @@ function produce_preamble() {
printf("\n\n");
}
-function produce_header() {
- printf("\n/* %s structure */\n", struct_name);
- printf("typedef struct {\n");
- for (i=0;i<num_elems;i++) {
- if (types[i] == "UNISTR2") {
- printf("\tuint32 %s_ptr;\n", elems[i]);
- } else if (types[i] == "BUFFER5") {
- printf("\tuint32 %s_len;\n", elems[i]);
- printf("\tuint32 %s_ptr;\n", elems[i]);
- } else {
- printf("\t%s\t%s;\n", types[i], elems[i]);
- }
- }
- for (i=0;i<num_elems;i++) {
- if (types[i] == "UNISTR2" ||
- types[i] == "BUFFER5") {
- printf("\t%s\t%s;\n", types[i], elems[i]);
- }
- }
- printf("} %s;\n\n", struct_name);
-}
-
-
-function parse_structs() {
- printf("\n\t/* parse the structures in the packet */\n\n");
- for (i=0;i<num_elems;i++) {
- if (types[i] == "UNISTR2") {
- io_unistr2(elems[i]);
- }
- if (types[i] == "BUFFER5") {
- io_buffer5(elems[i]);
- }
- }
-}
-
-function io_unistr2(elem) {
- printf("\
- if(!smb_io_unistr2(\"%s\", &il->%s, il->%s_ptr, ps, depth))\n\
- return False;\n\
- if(!prs_align(ps))\n\
- return False;\n\
-", elem, elem, elem);
-}
-
-function io_buffer5(elem) {
- printf("\
- if (il->%s_ptr) {\n\
- if(!smb_io_buffer5(\"%s\", &il->%s, ps, depth))\n\
- return False;\n\
- if(!prs_align(ps))\n\
- return False;\n\
- }\n\
-", elem, elem, elem);
-}
-
-function start_struct(name) {
- num_elems=0;
- struct_name=toupper(module"_"name);
- func_name=tolower(module"_io_"name);
-}
-
-function parse_elems() {
- printf("\n\t/* parse the main elements the packet */\n\n");
- for (i=0;i<num_elems;i++) {
- if (types[i] == "uint32") {
- uint32_parser(elems[i]);
- }
- if (types[i] == "UINT64_S") {
- uint64_parser(elems[i]);
- }
- if (types[i] == "UNISTR2") {
- unistr2_parser(elems[i]);
- }
- if (types[i] == "BUFFER5") {
- buffer5_parser(elems[i]);
- }
- if (types[i] == "NTTIME") {
- nttime_parser(elems[i]);
- }
- }
-}
-
-function end_struct() {
- produce_preamble();
- produce_header();
- func_header(func_name, struct_name);
- parse_elems();
- parse_structs();
- func_footer();
-}
-
-
-function func_footer() {
- printf("\n\
-\n\
- return True;\n\
-}\n");
-}
-
-function func_header(func_name, struct_name)
-{
- printf("\
-/*******************************************************************\n\
-parse a %s structure\n\
-********************************************************************/ \n\
-BOOL %s(char *desc, %s **q_u, \n\
- prs_struct *ps, int depth)\n\
-{ \n\
- %s *il;\n\
- \n\
- prs_debug(ps, depth, desc, \"%s\");\n\
- depth++;\n\
- \n\
- /* reading */\n\
- if (UNMARSHALLING(ps)) {\n\
- il=(%s *)malloc(sizeof(%s));\n\
- if(il == NULL)\n\
- return False;\n\
- ZERO_STRUCTP(il);\n\
- *q_u=il;\n\
- }\n\
- else {\n\
- il=*q_u;\n\
- }\n\
- \n\
- if(!prs_align(ps))\n\
- return False;\n\
-\n\
-", struct_name, func_name, struct_name, struct_name, func_name, struct_name, struct_name);
-}
-
-function uint32_parser(elem) {
- printf("\
- if(!prs_uint32(\"%s\", ps, depth, &il->%s))\n\
- return False;\n\
-", elem, elem);
+/^module/ {
+ module=$2;
+ next;
}
-function unistr2_parser(elem) {
- printf("\
- if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
- return False;\n\
-", elem, elem);
+/^test/ {
+ test=$2;
+ next;
}
-function buffer5_parser(elem) {
- printf("\
- if(!prs_uint32(\"%s_len\", ps, depth, &il->%s_len))\n\
- return False;\n\
- if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
- return False;\n\
-", elem, elem, elem, elem);
+/^struct/ {
+ start_struct($2);
+ next;
}
-function nttime_parser(elem) {
- printf("\
- if(!smb_io_time(\"%s\", &il->%s, ps, depth))\n\
- return False;\n\
-", elem, elem);
+/^[ \t]*union/ {
+ start_union($2, $3);
+ next;
}
-function uint64_parser(elem) {
- printf("\
- if(!prs_uint64(\"%s\", ps, depth, &il->%s))\n\
- return False;\n\
-", elem, elem);
+/^[ \t]*case/ {
+ split($0,a,"[ \t;]*");
+ parse_case(a[3],a[4],a[5]);
+ next;
}
-/^module/ {
- module=$2;
+/^\};/ {
+ end_struct();
+ next;
}
-/^struct/ {
- start_struct($2);
+/^[ \t]*\}/ {
+ end_union();
+ next;
}
-
-/^\}/ {
- end_struct();
+/^[ \t]*REF/ {
+ split($0,a,"[ \t;]*");
+ add_elem(a[3],a[4], 1);
+ next;
}
-/uint32|UINT64_S|UNISTR2|BUFFER5|NTTIME/ {
- split($0,a,"[ ;]*");
- add_elem(a[2], a[3]);
+/.*;/ {
+ split($0,a,"[ \t;]*");
+ add_elem(a[2], a[3], 0);
}
diff --git a/source3/aparser/struct.awk b/source3/aparser/struct.awk
new file mode 100644
index 0000000000..0f25536d94
--- /dev/null
+++ b/source3/aparser/struct.awk
@@ -0,0 +1,158 @@
+function isaptr(elem) {
+ if (substr(elem, 1, 1) == "*") {
+ return 1;
+ }
+ return 0;
+}
+
+
+function header_elem1(type, elem, ref) {
+ if (type == "BUFFER5") {
+ printf("\tuint32 %s_len;\n", elem);
+ }
+ if (ref == 1) {
+ printf("\tuint32 %s_ptr;\n", elem);
+ } else {
+ printf("\t%s\t%s;\n", type, elem);
+ }
+}
+
+function header_elem2(type, elem, ref) {
+ if (ref) {
+ printf("\t%s\t%s;\n", type, elem);
+ }
+}
+
+function produce_header1() {
+ printf("\n/* %s structure */\n", struct_name);
+ printf("typedef struct {\n");
+ for (i=0;i<num_elems;i++) {
+ if (unions[i] != unions[i-1]) {
+ if (unions[i] != "") {
+ printf("\tunion {\n");
+ } else {
+ printf("\t} %s;\n", unions[i-1]);
+ }
+ }
+ if (isptr[i]) {
+ header_elem1(types[i], "*"elems[i], isref[i]);
+ } else {
+ header_elem1(types[i], elems[i], isref[i]);
+ }
+ }
+ if (unions[i-1] != "") {
+ printf("\t} %s;\n", unions[i-1]);
+ }
+}
+
+function produce_header2() {
+ for (i=0;i<num_elems;i++) {
+ if (isptr[i]) {
+ header_elem2(types[i], "*"elems[i], isref[i]);
+ } else {
+ header_elem2(types[i], elems[i], isref[i]);
+ }
+ }
+ printf("} %s;\n\n", struct_name);
+}
+
+function produce_header() {
+ produce_header1();
+ produce_header2();
+}
+
+function parse_structs() {
+ printf("\n\t/* parse the structures in the packet */\n\n");
+ for (i=0;i<num_elems;i++) {
+ if (types[i] == "UNISTR2") {
+ io_unistr2(elems[i]);
+ } else if (types[i] == "BUFFER5") {
+ io_buffer5(elems[i]);
+ }
+ }
+}
+
+function io_unistr2(elem) {
+ printf("\
+ if(!smb_io_unistr2(\"%s\", &il->%s, il->%s_ptr, ps, depth))\n\
+ return False;\n\
+ if(!prs_align(ps))\n\
+ return False;\n\
+", elem, elem, elem);
+}
+
+function io_buffer5(elem) {
+ printf("\
+ if (il->%s_ptr) {\n\
+ if(!smb_io_buffer5(\"%s\", &il->%s, ps, depth))\n\
+ return False;\n\
+ if(!prs_align(ps))\n\
+ return False;\n\
+ }\n\
+", elem, elem, elem);
+}
+
+function start_struct(name) {
+ num_elems=0;
+ union="";
+ case="";
+ struct_name=toupper(name);
+ func_name=tolower("io_"name);
+ if (name == test) {
+ produce_preamble();
+ }
+}
+
+function parse_one(type, elem) {
+ if (type == "uint32") {
+ uint32_parser(elem);
+ } else if (type == "UINT64_S") {
+ uint64_parser(elem);
+ } else if (type == "UNISTR2") {
+ unistr2_parser(elem);
+ } else if (type == "BUFFER5") {
+ buffer5_parser(elem);
+ } else if (type == "NTTIME") {
+ nttime_parser(elem);
+ } else {
+ generic_parser(type, elem);
+ }
+}
+
+function parse_elems() {
+ printf("\n\t/* parse the main elements of the packet */\n\n");
+ for (i=0;i<num_elems;i++) {
+ if (cases[i] != "") {
+ printf("\tif (il->%s == %s) {\n",
+ switches[i], cases[i]);
+ parse_one(types[i], unions[i]"."elems[i]);
+ printf("\t}\n");
+ } else {
+ parse_one(types[i], elems[i]);
+ }
+ }
+}
+
+function end_struct() {
+ produce_header();
+ func_header(func_name, struct_name);
+ parse_elems();
+ parse_structs();
+ func_footer();
+}
+
+function add_elem(type, elem, ref)
+{
+ types[num_elems] = type;
+ elems[num_elems] = elem;
+ switches[num_elems] = switch;
+ cases[num_elems] = case;
+ unions[num_elems] = union;
+ isref[num_elems] = ref;
+ isptr[num_elems] = isaptr(elem);
+ if (isptr[num_elems] == 1) {
+ elems[num_elems] = substr(elems[num_elems], 2);
+ }
+ num_elems++;
+}
+
diff --git a/source3/aparser/test.struct b/source3/aparser/test.struct
index 517197bac3..1f5c5b6519 100644
--- a/source3/aparser/test.struct
+++ b/source3/aparser/test.struct
@@ -1,23 +1,46 @@
module spool
+test PRINTER_DRIVER_INFO
+
+struct PRINTER_DRIVER_INFO_LEVEL_3 {
+ uint32 cversion;
+ REF UNISTR2 name;
+ REF UNISTR2 environment;
+ REF UNISTR2 driverpath;
+ REF UNISTR2 datafile;
+ REF UNISTR2 configfile;
+ REF UNISTR2 helpfile;
+ REF UNISTR2 monitorname;
+ REF UNISTR2 defaultdatatype;
+ REF BUFFER5 dependentfiles;
+};
+
struct PRINTER_DRIVER_INFO_LEVEL_6 {
uint32 dummy1;
uint32 version;
- UNISTR2 name;
- UNISTR2 environment;
- UNISTR2 driverpath;
- UNISTR2 datafile;
- UNISTR2 configfile;
- UNISTR2 helpfile;
- UNISTR2 monitorname;
- UNISTR2 defaultdatatype;
- BUFFER5 dependentfiles;
- BUFFER5 previousnames;
+ REF UNISTR2 name;
+ REF UNISTR2 environment;
+ REF UNISTR2 driverpath;
+ REF UNISTR2 datafile;
+ REF UNISTR2 configfile;
+ REF UNISTR2 helpfile;
+ REF UNISTR2 monitorname;
+ REF UNISTR2 defaultdatatype;
+ REF BUFFER5 dependentfiles;
+ REF BUFFER5 previousnames;
NTTIME driverdate;
UINT64_S driverversion;
uint32 dummy4;
- UNISTR2 mfgname;
- UNISTR2 oemurl;
- UNISTR2 hardwareid;
- UNISTR2 provider;
+ REF UNISTR2 mfgname;
+ REF UNISTR2 oemurl;
+ REF UNISTR2 hardwareid;
+ REF UNISTR2 provider;
};
+
+struct PRINTER_DRIVER_INFO {
+ uint32 level;
+ union level info {
+ case 3 PRINTER_DRIVER_INFO_LEVEL_3 *info_3;
+ case 6 PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
+ }
+};
diff --git a/source3/aparser/union.awk b/source3/aparser/union.awk
new file mode 100644
index 0000000000..4a26bd9c20
--- /dev/null
+++ b/source3/aparser/union.awk
@@ -0,0 +1,16 @@
+function start_union(elem, name) {
+ switch=elem;
+ union=name;
+}
+
+function parse_case(value,type,elem) {
+ case=value;
+ add_elem(type, elem, 0);
+}
+
+function end_union() {
+ union="";
+ case="";
+ switch="";
+}
+