summaryrefslogtreecommitdiff
path: root/source3/aparser
diff options
context:
space:
mode:
Diffstat (limited to 'source3/aparser')
-rw-r--r--source3/aparser/Makefile17
-rwxr-xr-xsource3/aparser/build13
-rw-r--r--source3/aparser/cifs.struct1029
-rw-r--r--source3/aparser/dump.awk70
-rw-r--r--source3/aparser/harness.awk17
-rw-r--r--source3/aparser/header.awk80
-rw-r--r--source3/aparser/main.awk25
-rw-r--r--source3/aparser/parsefn.awk271
-rw-r--r--source3/aparser/parser.c471
-rw-r--r--source3/aparser/parser.h103
-rw-r--r--source3/aparser/parserel.awk213
-rw-r--r--source3/aparser/parsetree.awk224
-rw-r--r--source3/aparser/spool.struct90
-rw-r--r--source3/aparser/spool_io_printer_driver_info_level_3.prsbin0 -> 5636 bytes
-rw-r--r--source3/aparser/spool_io_printer_driver_info_level_6.prsbin0 -> 5636 bytes
-rw-r--r--source3/aparser/srvsvc.struct184
-rw-r--r--source3/aparser/srvsvc2.struct655
-rw-r--r--source3/aparser/template.awk18
-rw-r--r--source3/aparser/templates/fn_end.tpl13
-rw-r--r--source3/aparser/templates/fn_end0.tpl8
-rw-r--r--source3/aparser/templates/fn_i_end.tpl12
-rw-r--r--source3/aparser/templates/fn_i_start.tpl15
-rw-r--r--source3/aparser/templates/fn_mid.tpl6
-rw-r--r--source3/aparser/templates/fn_start.tpl17
-rw-r--r--source3/aparser/templates/harness.tpl5
-rw-r--r--source3/aparser/templates/harness_end.tpl7
-rw-r--r--source3/aparser/templates/harness_start.tpl7
-rw-r--r--source3/aparser/templates/ifptr_end.tpl1
-rw-r--r--source3/aparser/templates/ifptr_start.tpl2
-rw-r--r--source3/aparser/templates/module_end.tpl3
-rw-r--r--source3/aparser/templates/module_start.tpl5
-rw-r--r--source3/aparser/templates/prs_.align.tpl1
-rw-r--r--source3/aparser/templates/prs_align2.tpl1
-rw-r--r--source3/aparser/templates/prs_align4.tpl1
-rw-r--r--source3/aparser/templates/prs_array.tpl8
-rw-r--r--source3/aparser/templates/prs_array_optional.tpl5
-rw-r--r--source3/aparser/templates/prs_array_remainder.tpl17
-rw-r--r--source3/aparser/templates/prs_break.tpl1
-rw-r--r--source3/aparser/templates/prs_case.tpl1
-rw-r--r--source3/aparser/templates/prs_case_end.tpl1
-rw-r--r--source3/aparser/templates/prs_element.tpl1
-rw-r--r--source3/aparser/templates/prs_pointer.tpl2
-rw-r--r--source3/aparser/templates/prs_struct.tpl1
-rw-r--r--source3/aparser/templates/prs_struct_alloc.tpl1
-rw-r--r--source3/aparser/templates/prs_uint16.tpl1
-rw-r--r--source3/aparser/templates/prs_uint32.tpl1
-rw-r--r--source3/aparser/templates/prs_uint8s.tpl2
-rw-r--r--source3/aparser/templates/prs_uint8s_fixed.tpl1
-rw-r--r--source3/aparser/templates/prs_wstring.tpl2
-rw-r--r--source3/aparser/templates/prs_wstring_fixed.tpl2
-rw-r--r--source3/aparser/templates/union_end.tpl5
-rw-r--r--source3/aparser/templates/union_start.tpl1
-rw-r--r--source3/aparser/token.awk180
-rw-r--r--source3/aparser/util.awk39
-rw-r--r--source3/aparser/util.c112
-rw-r--r--source3/aparser/vluke.c41
56 files changed, 4009 insertions, 0 deletions
diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile
new file mode 100644
index 0000000000..953743b234
--- /dev/null
+++ b/source3/aparser/Makefile
@@ -0,0 +1,17 @@
+CFLAGS=-Wall -g
+CC=gcc
+
+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
+
+test.h : $(AWKPROGS)
+ igawk -f main.awk srvsvc.struct
+
+vluke: test.h $(OBJ)
+ $(CC) $(CFLAGS) -o vluke $(OBJ)
+
+clean:
+ rm -f *.o test.h prs_*.[ch]
+
diff --git a/source3/aparser/build b/source3/aparser/build
new file mode 100755
index 0000000000..4cdf2901f8
--- /dev/null
+++ b/source3/aparser/build
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+file=$1
+
+if ! igawk -f main.awk $file; then
+ echo parse failed;
+ exit 1;
+fi
+
+echo compiling vluke
+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
new file mode 100644
index 0000000000..202f0d7e61
--- /dev/null
+++ b/source3/aparser/cifs.struct
@@ -0,0 +1,1029 @@
+module cifs
+
+option autoalign False
+
+
+#define BOOL uint32
+#define UCHAR uint8
+#define WCHAR uint16
+#define USHORT uint16
+#define LONG uint32
+#define ULONG uint32
+#define DWORD uint32
+#define SMB_TIME uint16
+#define SMB_DATE uint16
+
+typedef struct {
+ ULONG low;
+ LONG high;
+} TIME;
+
+typedef struct {
+ ULONG low;
+ ULONG high;
+} hyper;
+
+typedef struct {
+ uint8 cmd;
+ uint8 reserved;
+ uint16 offset;
+} ANDX_INFO;
+
+
+typedef struct {
+ uint8 tag2;
+ STRING protocol;
+} BUF2;
+
+typedef struct {
+ uint16 bcount;
+ BUF2 protocol[*];
+} Q_NEGPROT_0;
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 0 Q_NEGPROT_0 q0;
+ }
+} Q_NEGPROT;
+
+typedef struct {
+ USHORT DialectIndex; /* Index of selected dialect */
+ USHORT SecurityMode; /* Security mode: */
+ /* bit 0: 0 = share, 1 = user */
+ /* bit 1: 1 = use challenge/response */
+ /* authentication */
+ USHORT MaxBufferSize; /* Max transmit buffer size (>= 1024) */
+ USHORT MaxMpxCount; /* Max pending multiplexed requests */
+ USHORT MaxNumberVcs; /* Max VCs between client and server */
+ USHORT RawMode; /* Raw modes supported: */
+ /* bit 0: 1 = Read Raw supported */
+ /* bit 1: 1 = Write Raw supported */
+ ULONG SessionKey; /* Unique token identifying this session */
+ SMB_TIME ServerTime; /* Current time at server */
+ SMB_DATE ServerDate; /* Current date at server */
+ USHORT ServerTimeZone; /* Current time zone at server */
+ USHORT ChallengeLength; /* Length of Challenge; MBZ if not LM2.1
+ /* dialect or later */
+ USHORT Reserved; /* MBZ */
+ USHORT ByteCount; /* Count of data bytes */
+ UCHAR Challenge[ChallengeLength]; /* The challenge */
+ STRING PrimaryDomain; /* The server's primary domain */
+
+} R_NEGPROT_12;
+
+typedef struct {
+ USHORT DialectIndex; /*Index of selected dialect */
+ UCHAR SecurityMode; /*Security mode: */
+ /* bit 0: 0 = share, 1 = user */
+ /* bit 1: 1 = use challenge/response */
+ /* authentication */
+ /* bit 2: 1 = Security Signatures (SMB integrity */
+ /* check) enabled */
+ /* bit 3: 1 = Security Signatures (SMB integrity */
+ /* check) required */
+ USHORT MaxMpxCount; /*Max pending outstanding requests */
+ USHORT MaxNumberVcs; /*Max VCs between client and server */
+ ULONG MaxBufferSize; /*Max transmit buffer size */
+ ULONG MaxRawSize; /*Maximum raw buffer size */
+ ULONG SessionKey; /*Unique token identifying this session */
+ ULONG Capabilities; /*Server capabilities */
+ ULONG SystemTimeLow; /*System (UTC) time of the server (low). */
+ ULONG SystemTimeHigh; /*System (UTC) time of the server (high). */
+ USHORT ServerTimeZone;/*Time zone of server (minutes from UTC) */
+ UCHAR SecurityBlobLength;/*Length of SecurityBlob */
+
+ USHORT bcount; /*Count of data bytes */
+ /*UCHAR GUID[16]; A globally unique identifier assigned to the */
+ /* server; present only when */
+ /* CAP_EXTENDED_SECURITY is on in the */
+ /* Capabilities field. */
+ UCHAR SecurityBlob[SecurityBlobLength]; /*Opaque Security Blob associated with the */
+ /* security package if CAP_EXTENDED_SECURITY is */
+ /* on in the Capabilities field; else challenge */
+ /* for CIFS challenge/response authentication. */
+ STRING OemDomainName[+]; /*The name of the domain (in OEM chars); not */
+ /* present if CAP_EXTENDED_SECURITY is on in the */
+ /* Capabilities field */
+} R_NEGPROT_17;
+
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 17 R_NEGPROT_17 r17;
+ }
+} R_NEGPROT;
+
+typedef struct {
+ uint8 wcount;
+ uint16 vwv[wcount];
+ uint16 bcount;
+ uint8 none[bcount];
+} Q_TDIS;
+
+typedef struct {
+ uint8 wcount;
+ uint16 vwv[wcount];
+ uint16 bcount;
+ uint8 none[bcount];
+} R_TDIS;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 bcount;
+ uint8 none[bcount];
+} R_ULOGOFF_ANDX_2;
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 2 R_ULOGOFF_ANDX_2 q2;
+ }
+} R_ULOGOFF_ANDX;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 bcount;
+ uint8 none[bcount];
+} Q_ULOGOFF_ANDX_2;
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 2 Q_ULOGOFF_ANDX_2 q2;
+ }
+} Q_ULOGOFF_ANDX;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 bufsize;
+ uint16 max_mpx;
+ uint16 vc;
+ ULONG sess_key;
+ uint16 pwlen;
+ ULONG reserved;
+
+ uint16 bcount;
+ uint8 password[pwlen];
+ STRING domain;
+ STRING os;
+ STRING server;
+
+} Q_SESSION_SETUP_ANDX_10;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 bufsize;
+ uint16 max_mpx;
+ uint16 vc;
+ ULONG sess_key;
+ uint16 pwlen;
+ uint16 upwlen;
+ ULONG capabilities;
+ ULONG reserved;
+
+ uint16 bcount;
+ uint8 password[pwlen];
+ uint8 upassword[upwlen];
+ STRING user;
+ STRING domain;
+ STRING os;
+ STRING server;
+
+} Q_SESSION_SETUP_ANDX_13;
+
+typedef struct _Q_SESSION_SETUP_ANDX {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 10 Q_SESSION_SETUP_ANDX_10 q10;
+ case 13 Q_SESSION_SETUP_ANDX_13 q13;
+ }
+} Q_SESSION_SETUP_ANDX;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 vwv2;
+ uint16 passlen;
+ uint16 bcount;
+ uint8 password[passlen];
+ STRING path;
+ STRING device;
+} Q_TCON_ANDX_4;
+
+typedef struct _Q_TCON_ANDX {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 4 Q_TCON_ANDX_4 q4;
+ }
+} Q_TCON_ANDX;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 vwv2;
+ uint16 bcount;
+ STRING share;
+} R_TCON_ANDX_3;
+
+typedef struct _R_TCON_ANDX {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 3 R_TCON_ANDX_3 q3;
+ }
+} R_TCON_ANDX;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint16 action;
+
+ uint16 count;
+ STRING os;
+ STRING server;
+ STRING domain;
+} R_SESSION_SETUP_ANDX_10;
+
+typedef struct _R_SESSION_SETUP_ANDX {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 3 R_SESSION_SETUP_ANDX_10 r3;
+ }
+} R_SESSION_SETUP_ANDX;
+
+
+typedef struct _R_CLOSE {
+ uint8 wcount;
+ uint16 count;
+ uint8 none[count];
+
+} R_CLOSE;
+
+typedef struct _Q_CLOSE {
+ uint8 wcount;
+ uint16 fnum;
+ uint32 vwv1;
+
+ uint16 count;
+ uint8 none[count];
+
+} Q_CLOSE;
+
+typedef struct {
+ uint16 dsize;
+ uint16 bsizehi;
+ uint16 bsizelo;
+ uint16 avail;
+ uint16 vwv4;
+
+ uint16 bcount;
+ uint8 none[bcount];
+
+} R_DSKATTR_5;
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 5 R_DSKATTR_5 r5;
+ }
+} R_DSKATTR;
+
+typedef struct {
+ uint16 count;
+ uint8 none[count];
+
+} Q_DSKATTR_0;
+
+typedef struct _Q_DSKATTR {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 0 Q_DSKATTR_0 q1;
+ }
+
+} Q_DSKATTR;
+
+typedef struct {
+ ANDX_INFO andx;
+
+ uint16 bcount;
+ uint8 none[bcount];
+
+} R_LOCKING_2;
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 2 R_LOCKING_2 r2;
+ }
+} R_LOCKING_ANDX;
+
+/* XXXX must do a switch on bit 0x10 to do large locks XXXX */
+/* LockType Flag Name Value Description */
+
+#define LOCKING_ANDX_SHARED_LOCK 0x01 /* Read-only lock */
+#define LOCKING_ANDX_OPLOCK_RELEASE 0x02 /* Oplock break notification */
+#define LOCKING_ANDX_CHANGE_LOCKTYPE 0x04 /* Change lock type */
+#define LOCKING_ANDX_CANCEL_LOCK 0x08 /* Cancel outstanding request */
+#define LOCKING_ANDX_LARGE_FILES 0x10 /* Large file locking format */
+
+typedef struct {
+ USHORT Pid; /* PID of process "owning" lock */
+ ULONG Offset; /* Offset to bytes to [un]lock */
+ ULONG Length; /* Number of bytes to [un]lock */
+} LOCKING_ANDX_RANGE_SHORT;
+
+typedef struct {
+ USHORT Pid; /* PID of process "owning" lock */
+ .align4 0;
+ ULONG OffsetHigh; /* Offset to bytes to [un]lock (high) */
+ ULONG OffsetLow; /* Offset to bytes to [un]lock (low) */
+ ULONG LengthHigh; /* Number of bytes to [un]lock (high) */
+ ULONG LengthLow; /* Number of bytes to [un]lock (low) */
+
+} LOCKING_ANDX_RANGE_LARGE;
+
+/* typedef struct { */
+ /* union ctr[LockType&0x10] { */
+ /* case 0 LOCKING_ANDX_RANGE_SHORT ls; */
+ /* case 0x10 LOCKING_ANDX_RANGE_LARGE ll; */
+ /* } */
+/* } LOCKING_ANDX_RANGE; */
+
+typedef struct {
+ ANDX_INFO andx;
+
+ USHORT Fid; /* File handle */
+ UCHAR LockType; /* See LockType table below */
+ UCHAR OplockLevel; /* The new oplock level */
+ ULONG Timeout; /* Milliseconds to wait for unlock */
+ USHORT NumberOfUnlocks; /* Num. unlock range structs following */
+ USHORT NumberOfLocks; /* Num. lock range structs following */
+
+ USHORT ByteCount; /* Count of data bytes */
+ LOCKING_ANDX_RANGE_SHORT Unlocks[NumberOfUnlocks]; /* Unlock ranges */
+ LOCKING_ANDX_RANGE_SHORT Locks[NumberOfLocks]; /* Lock ranges */
+
+} Q_LOCKING_8;
+
+typedef struct _Q_LOCKING {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 8 Q_LOCKING_8 q8;
+ }
+
+} Q_LOCKING_ANDX;
+
+
+typedef struct {
+ uint16 bcount;
+ uint8 protocols[bcount];
+
+} R_UNLINK_0;
+
+typedef struct {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 0 R_UNLINK_0 r0;
+ }
+} R_UNLINK;
+
+typedef struct {
+ uint16 dirtype;
+
+ uint16 count;
+ uint8 fname[count];
+
+} Q_UNLINK_1;
+
+typedef struct _Q_UNLINK {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 1 Q_UNLINK_1 q1;
+ }
+
+} Q_UNLINK;
+
+typedef struct _R_OPEN_ANDX{
+ uint8 wcount;
+ ANDX_INFO andx;
+ uint16 fnum;
+ uint16 fmode;
+ uint32 mtime;
+ uint32 size;
+ uint16 rmode;
+ uint16 vwv9;
+ uint16 vwv10;
+ uint16 smb_action;
+ uint16 vwv12;
+ uint16 vwv13;
+ uint16 vwv14;
+
+ uint16 count;
+ uint8 none[count];
+
+} R_OPEN_ANDX;
+
+typedef struct _Q_OPEN_ANDX{
+ uint8 wcount;
+ ANDX_INFO andx;
+ uint16 fnum;
+ uint16 fmode;
+ uint32 mtime;
+ uint32 size;
+ uint16 rmode;
+ uint16 vwv9;
+ uint16 vwv10;
+ uint16 smb_action;
+ uint16 vwv12;
+ uint16 vwv13;
+ uint16 vwv14;
+
+ uint16 count;
+ uint8 fname[count];
+
+} Q_OPEN_ANDX;
+
+typedef struct _R_READ_ANDX {
+ uint8 wcount;
+ ANDX_INFO andx;
+ uint16 vwv2;
+ uint16 vwv3;
+ uint16 vwv4;
+ uint16 nread;
+ uint16 offset;
+ uint16 vwv7;
+ uint16 vwv8;
+ uint16 vwv9;
+ uint16 vwv10;
+ uint16 vwv11;
+
+ uint16 count;
+ uint8 data[count];
+
+} R_READ_ANDX;
+
+typedef struct _Q_READ_ANDX_10 {
+ ANDX_INFO andx;
+ uint16 fnum;
+ uint32 startpos;
+ uint16 smb_maxcnt;
+ uint16 smb_mincnt;
+ uint16 vwv7;
+ uint16 vwv8;
+ uint16 vwv9;
+
+ uint16 count;
+ uint8 none[count];
+
+} Q_READ_ANDX_10;
+
+typedef struct _Q_READ_ANDX_12 {
+ ANDX_INFO andx;
+ uint16 fnum;
+ uint32 startpos;
+ uint16 smb_maxcnt;
+ uint16 smb_mincnt;
+ uint16 vwv7;
+ uint16 vwv8;
+ uint16 vwv9;
+ uint32 startposhi;
+
+ uint16 count;
+ uint8 none[count];
+
+} Q_READ_ANDX_12;
+
+typedef struct _Q_READ_ANDX {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 10 Q_READ_ANDX_10 q10;
+ case 12 Q_READ_ANDX_12 q12;
+ }
+} Q_READ_ANDX;
+
+typedef struct _R_WRITE_ANDX {
+ uint8 wcount;
+ ANDX_INFO andx;
+ uint16 nwritten;
+ uint16 vwv3;
+ uint16 vwv4;
+ uint16 vwv5;
+
+ uint16 count;
+ uint8 none[count];
+
+} R_WRITE_ANDX;
+
+typedef struct _Q_WRITE_ANDX_12 {
+ ANDX_INFO andx;
+ uint16 fnum;
+ uint32 startpos;
+ uint16 vwv5;
+ uint16 vwv6;
+ uint16 write_through;
+ uint16 vwv8;
+ uint16 vwv9;
+ uint16 numtowrite;
+ uint16 smb_doff;
+
+ uint16 count;
+ uint8 data[count];
+
+} Q_WRITE_ANDX_12;
+
+typedef struct _Q_WRITE_ANDX_14 {
+ ANDX_INFO andx;
+ uint16 fnum;
+ uint32 startpos;
+ uint16 vwv5;
+ uint16 vwv6;
+ uint16 write_through;
+ uint16 vwv8;
+ uint16 vwv9;
+ uint16 numtowrite;
+ uint16 smb_doff;
+ uint32 startposhi;
+
+ uint16 count;
+ uint8 data[count];
+
+} Q_WRITE_ANDX_14;
+
+typedef struct _Q_WRITE_ANDX {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 12 Q_WRITE_ANDX_12 q12;
+ case 14 Q_WRITE_ANDX_14 q14;
+ }
+} Q_WRITE_ANDX;
+
+
+
+typedef struct _Q_NTTRANS_19 {
+ UCHAR MaxSetupCount; /* Max setup words to return */
+ USHORT Reserved;
+ ULONG TotalParameterCount; /* Total parameter bytes being sent */
+ ULONG TotalDataCount; /* Total data bytes being sent */
+ ULONG MaxParameterCount; /* Max parameter bytes to return */
+ ULONG MaxDataCount; /* Max data bytes to return */
+ ULONG ParameterCount; /* Parameter bytes sent this buffer */
+ ULONG ParameterOffset; /* Offset (from header start) to */
+ /* Parameters */
+ ULONG DataCount; /* Data bytes sent this buffer */
+ ULONG DataOffset; /* Offset (from header start) to data */
+ UCHAR SetupCount; /* Count of setup words */
+ USHORT Function; /* The transaction function code */
+ UCHAR Buffer[1];
+ USHORT Setup[SetupCount]; /* Setup words */
+ USHORT ByteCount; /* Count of data bytes */
+ .align4 0;
+ UCHAR Parameters[ParameterCount];/* Parameter bytes */
+ .align4 0;
+ UCHAR Data[DataCount]; /* Data bytes */
+
+} Q_NTTRANS_19;
+
+typedef struct _Q_NTTRANS {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 19 Q_NTTRANS_19 q19;
+ }
+} Q_NTTRANS;
+
+typedef struct _R_NTTRANS_18 {
+ UCHAR Reserved[3];
+ ULONG TotalParameterCount; /* Total parameter bytes being sent */
+ ULONG TotalDataCount; /* Total data bytes being sent */
+ ULONG ParameterCount; /* Parameter bytes sent this buffer */
+ ULONG ParameterOffset; /* Offset (from header start) to */
+ /* Parameters */
+ ULONG ParameterDisplacement; /* Specifies the offset from the start */
+ /* of the overall parameter block to */
+ /* the parameter bytes that are */
+ /* contained in this message */
+ ULONG DataCount; /* Data bytes sent this buffer */
+ ULONG DataOffset; /* Offset (from header start) to data */
+ ULONG DataDisplacement; /* Specifies the offset from the start */
+ /* of the overall data block to the */
+ /* data bytes that are contained in */
+ /* this message. */
+ UCHAR SetupCount; /* Count of setup words */
+ USHORT Setup[SetupCount]; /* Setup words */
+ USHORT ByteCount; /* Count of data bytes */
+ .align4 0;
+ UCHAR Parameters[ParameterCount]; /* Parameter bytes */
+ .align4 0;
+ UCHAR Data[DataCount]; /* Data bytes */
+} R_NTTRANS_18;
+
+typedef struct _R_NTTRANS {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 18 R_NTTRANS_18 q18;
+ }
+ .align4 2;
+} R_NTTRANS;
+
+/*Setup[0] Transaction2 Value Description */
+/*Subcommand Code */
+/*=============================== ===== ============================= */
+
+#define TRANS2_OPEN2 0x00 /* Create file with extended attributes */
+#define TRANS2_FIND_FIRST2 0x01 /* Begin search for files */
+#define TRANS2_FIND_NEXT2 0x02 /* Resume search for files */
+#define TRANS2_QUERY_FS_INFO 0x03 /* Get file system information
+#define TRANS2_RESERVED4 0x04 /* Reserved */
+#define TRANS2_QUERY_PATH_INFO 0x05 /* Get information about a named file or directory */
+#define TRANS2_SET_PATH_INFO 0x06 /* Set information about a named file or directory */
+#define TRANS2_QUERY_FILE_INFO 0x07 /* Get information about a handle */
+#define TRANS2_SET_FILE_INFO 0x08 /* Set information by handle */
+#define TRANS2_FSCTL 0x09 /* Not implemented by NT server */
+#define TRANS2_IOCTL2 0x0A /* Not implemented by NT server */
+#define TRANS2_FIND_NOTIFY_FIRST 0x0B /* Not implemented by NT server */
+#define TRANS2_FIND_NOTIFY_NEXT 0x0C /* Not implemented by NT server */
+#define TRANS2_CREATE_DIRECTORY 0x0D /* Create directory with extended attributes */
+#define TRANS2_SESSION_SETUP 0x0E /* Session setup with extended security information */
+#define TRANS2_GET_DFS_REFERRAL 0x10 /* Get a DFS referral */
+#define TRANS2_REPORT_DFS_INCONSISTENCY 0x11 /* Report a DFS knowledge inconsistency */
+
+typedef struct {
+ USHORT InformationLevel; /* Level of information requested */
+} TRANS2_QUERY_FS_INFO_STRUCT;
+
+#define SMB_INFO_STANDARD 1
+#define SMB_INFO_QUERY_EA_SIZE 2
+#define SMB_SET_FILE_BASIC_INFO 0x101
+#define SMB_SET_FILE_DISPOSITION_INFO 0x102
+#define SMB_SET_FILE_ALLOCATION_INFO 0x103
+#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
+
+
+typedef struct {
+ hyper CreationTime;
+ hyper LastAccessTime;
+ hyper LastWriteTime;
+ hyper ChangeTime;
+ USHORT Attributes;
+ .align4 0;
+} SMB_QUERY_FILE_BASIC_INFO_STRUCT;
+
+
+typedef struct {
+ ULONG fs_atr;
+ LONG max_len_filename;
+ ULONG length;
+ uint8 fs[length];
+ .align4 2;
+} SMB_QUERY_FS_ATTRIBUTE_INFO_STRUCT;
+
+#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+#define FILE_CASE_PRESERVED_NAMES 0x00000002
+#define FILE_PRSISTENT_ACLS 0x00000004
+#define FILE_FILE_COMPRESSION 0x00000008
+#define FILE_VOLUME_QUOTAS 0x00000010
+#define FILE_DEVICE_IS_MOUNTED 0x00000020
+#define FILE_VOLUME_IS_COMPRESSED 0x00008000
+
+typedef struct {
+ USHORT Fid;
+ USHORT InformationLevel;
+ USHORT Reserved;
+ .align4 0;
+
+ union ctr[InformationLevel] {
+ case 0x101 SMB_QUERY_FILE_BASIC_INFO_STRUCT t101;
+ }
+
+} TRANS2_SET_FILE_INFO_STRUCT;
+
+typedef struct {
+ USHORT InformationLevel; /* Level of information requested */
+ ULONG Reserved; /* Must be zero */
+ STRING FileName; /* File or directory name */
+} TRANS2_QUERY_PATH_INFO_STRUCT;
+
+typedef struct {
+ USHORT SearchAttributes;
+ USHORT SearchCount;
+ USHORT Flags;
+ USHORT InformationLevel;
+ ULONG SearchStorageType;
+ STRING FileName;
+} TRANS2_FIND_FIRST2_STRUCT;
+
+typedef struct _Q_TRANS2_15 {
+ USHORT TotalParameterCount; /* Total parameter bytes being sent */
+ USHORT TotalDataCount; /* Total data bytes being sent */
+ USHORT MaxParameterCount; /* Max parameter bytes to return */
+ USHORT MaxDataCount; /* Max data bytes to return */
+ UCHAR MaxSetupCount; /* Max setup words to return */
+ UCHAR Reserved;
+ USHORT Flags; /* Additional information: */
+ /* bit 0 - also disconnect TID in TID */
+ ULONG Timeout;
+ USHORT Reserved2;
+ USHORT ParameterCount; /* Parameter bytes sent this buffer */
+ USHORT ParameterOffset; /* Offset (from header start) to */
+ /* Parameters */
+ USHORT DataCount; /* Data bytes sent this buffer */
+ USHORT DataOffset; /* Offset (from header start) to data */
+ UCHAR SetupCount; /* Count of setup words */
+ UCHAR Reserved3; /* Reserved (pad above to word) */
+ USHORT Setup[SetupCount]; /* Setup words (# = SetupWordCount) */
+ USHORT ByteCount; /* Count of data bytes */
+ .align4 0;
+ union ctr[Setup[0]] {
+ case 1 TRANS2_FIND_FIRST2_STRUCT t1;
+ case 3 TRANS2_QUERY_FS_INFO_STRUCT t3;
+ case 5 TRANS2_QUERY_PATH_INFO_STRUCT t5;
+ case 8 TRANS2_SET_FILE_INFO_STRUCT t8;
+ }
+
+} Q_TRANS2_15;
+
+typedef struct _Q_TRANS2 {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 15 Q_TRANS2_15 q15;
+ }
+} Q_TRANS2;
+
+typedef struct {
+ ULONG NextEntryOffset;
+ ULONG FileIndex;
+ hyper CreationTime;
+ hyper LastAccessTime;
+ hyper LastWriteTime;
+ hyper ChangeTime;
+ hyper EndOfFile;
+ hyper AllocationSize;
+ ULONG ExtFileAttributes;
+ ULONG FileNameLength;
+ ULONG EaSize;
+ UCHAR ShortNameLength;
+ UCHAR Reserved;
+ uint8 ShortName[24];
+ UCHAR FileName[FileNameLength];
+ .align4 2;
+} SMB_FIND_FILE_BOTH_DIRECTORY_INFO;
+
+typedef struct {
+ .align2 0;
+} R_TRANS2_D0;
+
+typedef struct {
+ .align4 2;
+} R_TRANS2_P0;
+
+typedef struct {
+ USHORT Reserved;
+} R_TRANS2_P2;
+
+typedef struct {
+ USHORT Sid; /* Search handle */
+ USHORT SearchCount; /* Number of entries returned */
+ USHORT EndOfSearch; /* Was last entry returned? */
+ USHORT EaErrorOffset; /* Offset into EA list if EA error */
+ USHORT LastNameOffset; /* Offset into data to file name of last */
+ /* entry, if server needs it to resume */
+ /* search; else 0 */
+ .align4 2;
+ SMB_FIND_FILE_BOTH_DIRECTORY_INFO i104[SearchCount];
+} R_TRANS2_FIND_FIRST2_STRUCT;
+
+typedef struct {
+ SMB_QUERY_FILE_BASIC_INFO_STRUCT i101;
+ .align4 2;
+} R_TRANS2_FILE_BASIC_STRUCT;
+
+typedef struct _R_TRANS2_10 {
+ USHORT TotalParameterCount;/* Total parameter bytes being sent */
+ USHORT TotalDataCount; /* Total data bytes being sent */
+ USHORT Reserved2;
+ USHORT ParameterCount; /* Parameter bytes sent this buffer */
+ USHORT ParameterOffset; /* Offset (from header start) to */
+ /* Parameters */
+ USHORT ParameterDisplacement; /* Specifies the offset from the start */
+ /* of the overall parameter block to */
+ /* the parameter bytes that are */
+ /* contained in this message */
+ USHORT DataCount; /* Data bytes sent this buffer */
+ USHORT DataOffset; /* Offset (from header start) to data */
+ USHORT DataDisplacement; /* Specifies the offset from the start */
+ /* of the overall data block to the */
+ /* data bytes that are contained in */
+ /* this message. */
+ UCHAR SetupCount; /* Count of setup words */
+ UCHAR Reserved3; /* Reserved (pad above to word) */
+ USHORT Setup[SetupCount]; /* Setup words */
+ USHORT ByteCount; /* Count of data bytes */
+ .align4 2;
+ union pctr[ParameterCount] {
+ case 0 R_TRANS2_P0 p0;
+ case 2 R_TRANS2_P2 p2;
+ case 10 R_TRANS2_FIND_FIRST2_STRUCT r10;
+ }
+ union dctr[DataCount] {
+ case 0 R_TRANS2_D0 d0;
+ case 0x24 R_TRANS2_FILE_BASIC_STRUCT r24;
+ case 0x14 SMB_QUERY_FS_ATTRIBUTE_INFO_STRUCT r14;
+ }
+} R_TRANS2_10;
+
+typedef struct {
+ USHORT ByteCount; /* Count of data bytes */
+} R_TRANS2_0;
+
+typedef struct _R_TRANS2 {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 0 R_TRANS2_0 q0;
+ case 10 R_TRANS2_10 q10;
+ }
+} R_TRANS2;
+
+typedef struct _Q_TRANS_16 {
+ USHORT TotalParameterCount; /* Total parameter bytes being sent */
+ USHORT TotalDataCount; /* Total data bytes being sent */
+ USHORT MaxParameterCount; /* Max parameter bytes to return */
+ USHORT MaxDataCount; /* Max data bytes to return */
+ UCHAR MaxSetupCount; /* Max setup words to return */
+ UCHAR Reserved;
+ USHORT Flags; /* Additional information: */
+ /* bit 0 - also disconnect TID in TID */
+ ULONG Timeout;
+ USHORT Reserved2;
+ USHORT ParameterCount; /* Parameter bytes sent this buffer */
+ USHORT ParameterOffset; /* Offset (from header start) to */
+ /* Parameters */
+ USHORT DataCount; /* Data bytes sent this buffer */
+ USHORT DataOffset; /* Offset (from header start) to data */
+ UCHAR SetupCount; /* Count of setup words */
+ UCHAR Reserved3; /* Reserved (pad above to word) */
+ USHORT Setup[SetupCount]; /* Setup words (# = SetupWordCount) */
+ USHORT ByteCount; /* Count of data bytes */
+ STRING Name; /* Must be NULL */
+ .align4 0;
+ UCHAR Parameters[ParameterCount];/* Parameter bytes (# = ParameterCount) */
+ .align4 0;
+ UCHAR Data[DataCount]; /* Data bytes (# = DataCount) */
+
+} Q_TRANS_16;
+
+typedef struct _Q_TRANS {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 16 Q_TRANS_16 q16;
+ }
+} Q_TRANS;
+
+typedef struct _R_TRANS_10 {
+ USHORT TotalParameterCount;/* Total parameter bytes being sent */
+ USHORT TotalDataCount; /* Total data bytes being sent */
+ USHORT Reserved2;
+ USHORT ParameterCount; /* Parameter bytes sent this buffer */
+ USHORT ParameterOffset; /* Offset (from header start) to */
+ /* Parameters */
+ USHORT ParameterDisplacement; /* Specifies the offset from the start */
+ /* of the overall parameter block to */
+ /* the parameter bytes that are */
+ /* contained in this message */
+ USHORT DataCount; /* Data bytes sent this buffer */
+ USHORT DataOffset; /* Offset (from header start) to data */
+ USHORT DataDisplacement; /* Specifies the offset from the start */
+ /* of the overall data block to the */
+ /* data bytes that are contained in */
+ /* this message. */
+ UCHAR SetupCount; /* Count of setup words */
+ UCHAR Reserved3; /* Reserved (pad above to word) */
+ USHORT Setup[SetupCount]; /* Setup words */
+ USHORT ByteCount; /* Count of data bytes */
+ .align4 0;
+ UCHAR Parameters[ParameterCount];/* Parameter bytes */
+ .align4 0;
+ UCHAR Data[DataCount]; /* Data bytes */
+} R_TRANS_10;
+
+typedef struct _R_TRANS {
+ uint8 wcount;
+ union ctr[wcount] {
+ case 10 R_TRANS_10 q10;
+ }
+} R_TRANS;
+
+typedef struct _Q_NT_CREATE_ANDX_24 {
+ ANDX_INFO andx;
+ uint8 reserved;
+ uint16 name_len;
+ ULONG flags;
+ ULONG rootfid;
+ ULONG access;
+ hyper allocsize;
+ ULONG attribs;
+ ULONG sharing;
+ ULONG creat_disp;
+ ULONG creat_options;
+ ULONG impersonation;
+ uint8 sec_flags;
+
+ uint16 count;
+ uint8 name[name_len];
+
+} Q_NTCREATE_ANDX_24;
+
+typedef struct _Q_NTCREATE_ANDX{
+ uint8 wcount;
+ union ctr[wcount] {
+ case 24 Q_NTCREATE_ANDX_24 q24;
+ }
+} Q_NTCREATE_ANDX;
+
+typedef struct {
+ ANDX_INFO andx;
+ uint8 oplock_level;
+ uint16 fid;
+ ULONG action;
+ TIME create_time;
+ TIME access_time;
+ TIME write_time;
+ TIME change_time;
+ ULONG ext_attribs;
+ hyper allocsize;
+ hyper size;
+ uint16 type;
+ uint16 state;
+ uint8 directory;
+
+ uint16 count;
+ uint8 none[count];
+
+} R_NTCREATE_ANDX_34;
+
+typedef struct _R_NTCREATE_ANDX{
+ uint8 wcount;
+ union ctr[wcount] {
+ case 34 R_NTCREATE_ANDX_34 q34;
+ }
+} R_NTCREATE_ANDX;
+
+typedef struct {
+ ULONG smbhdr;
+ uint8 com;
+ uint8 rcls;
+ uint8 reh;
+ uint16 err;
+ uint8 flg;
+ uint16 flg2;
+ uint16 reserved;
+ uint8 SecuritySignature[8];
+ uint16 pad;
+ uint16 tid;
+ uint16 pid;
+ uint16 uid;
+ uint16 mid;
+} SMB_HDR;
+
+typedef struct _R_SMB {
+ ULONG nbhdr;
+ SMB_HDR hdr;
+ union ctr[hdr.com] {
+ case 4 R_CLOSE r4;
+ case 6 R_UNLINK r6;
+ case 36 R_LOCKING_ANDX r36;
+ case 37 R_TRANS r37;
+ case 45 R_OPEN_ANDX r45;
+ case 46 R_READ_ANDX r46;
+ case 47 R_WRITE_ANDX r47;
+ case 50 R_TRANS2 q50;
+ case 113 R_TDIS r113;
+ case 114 R_NEGPROT r114;
+ case 115 R_SESSION_SETUP_ANDX r115;
+ case 116 R_ULOGOFF_ANDX r116;
+ case 117 R_TCON_ANDX r117;
+ case 128 R_DSKATTR r128;
+ case 160 R_NTTRANS r160;
+ case 162 R_NTCREATE_ANDX r162;
+ }
+} R_SMB;
+
+typedef struct _Q_SMB {
+ ULONG nbhdr;
+ SMB_HDR hdr;
+ union ctr[hdr.com] {
+ case 4 Q_CLOSE q4;
+ case 6 Q_UNLINK q6;
+ case 36 Q_LOCKING_ANDX q36;
+ case 37 Q_TRANS q37;
+ case 45 Q_OPEN_ANDX q45;
+ case 46 Q_READ_ANDX q46;
+ case 47 Q_WRITE_ANDX q47;
+ case 50 Q_TRANS2 q50;
+ case 113 Q_TDIS q113;
+ case 114 Q_NEGPROT q114;
+ case 115 Q_SESSION_SETUP_ANDX q115;
+ case 116 Q_ULOGOFF_ANDX q116;
+ case 117 Q_TCON_ANDX q117;
+ case 128 Q_DSKATTR q128;
+ case 160 Q_NTTRANS q160;
+ case 162 Q_NTCREATE_ANDX q162;
+ }
+} Q_SMB;
+
diff --git a/source3/aparser/dump.awk b/source3/aparser/dump.awk
new file mode 100644
index 0000000000..11bfb107e4
--- /dev/null
+++ b/source3/aparser/dump.awk
@@ -0,0 +1,70 @@
+# dump the current parse tree
+
+
+function element_string(elnum,
+ LOCAL, elem)
+{
+ elem = elements[elnum, "elem"];
+ if (elements[elnum, "ptr"]=="1") elem="*"elem;
+ if (elements[elnum, "array_len"]!="")
+ elem=elem"["elements[elnum, "array_len"]"]";
+ if (elements[elnum, "switch"]!="")
+ elem=elem"["elements[elnum, "switch"]"]";
+ return elem;
+}
+
+function dump_element(f, elnum,
+ LOCAL, elem, type)
+{
+ type = elements[elnum, "type"];
+ case = elements[elnum, "case"];
+ elem = element_string(elnum);
+ if (case != "") {
+ xprintf(f,"\t\tcase %d %s %s;\n", case, type, elem);
+ } else {
+ xprintf(f,"\t%s %s;\n", type, elem);
+ }
+}
+
+function dump_union(f, elnum,
+ LOCAL, i)
+{
+ xprintf(f,"\tunion %s {\n", element_string(elnum));
+ for (i=0;i<unions[elnum, "num_elems"];i++) {
+ dump_element(f, unions[elnum, i]);
+ }
+ xprintf(f,"\t}\n");
+}
+
+function dump_elem(f, struct_num, elem_num,
+ LOCAL, enum)
+{
+ elnum = structs[struct_num, elem_num];
+
+ if (elements[elnum, "type"] == "union") {
+ dump_union(f, elnum);
+ } else {
+ dump_element(f, elnum);
+ }
+}
+
+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"]);
+ for (j=0;j<structs[i, "num_elems"];j++) {
+ dump_elem(f, i, j);
+ }
+ xprintf(f,"};\n\n");
+ }
+ xprintf(f,"/* end dump */\n\n");
+}
diff --git a/source3/aparser/harness.awk b/source3/aparser/harness.awk
new file mode 100644
index 0000000000..6c4c35c40f
--- /dev/null
+++ b/source3/aparser/harness.awk
@@ -0,0 +1,17 @@
+function produce_harness(f,
+ LOCAL, v, struct_num, i)
+{
+ struct_num=structs[test];
+
+ v["MODULE"]=module;
+
+ print_template(f, "harness_start.tpl", v);
+
+ for (i=0;i<num_structs;i++) {
+ v["TEST"] = structs[i, "name"];
+ print_template(f, "harness.tpl", v);
+ }
+
+ print_template(f, "harness_end.tpl", v);
+}
+
diff --git a/source3/aparser/header.awk b/source3/aparser/header.awk
new file mode 100644
index 0000000000..ba7117436b
--- /dev/null
+++ b/source3/aparser/header.awk
@@ -0,0 +1,80 @@
+# produce a header file for a parsed struct file
+
+function header_elstring(elnum,
+ LOCAL, elem)
+{
+ array_len = elements[elnum, "array_len"];
+ elem=elements[elnum, "elem"];
+ if (elements[elnum, "ptr"]=="1") elem="*"elem;
+ if (array_len!="") {
+ if (is_constant(array_len) == 1) {
+ elem=elem"["array_len"]";
+ } else {
+ elem="*"elem;
+ }
+ }
+ return elem;
+}
+
+function header_element(f, elnum,
+ LOCAL, type)
+{
+ type=elements[elnum, "type"];
+ if (substr(type,1,1) == ".") return;
+ xprintf(f,"\t%s %s;\n", type, header_elstring(elnum));
+}
+
+function header_union(f, elnum,
+ LOCAL, i)
+{
+ xprintf(f,"\tunion {\n");
+ for (i=0;i<unions[elnum, "num_elems"];i++) {
+ header_element(f, unions[elnum, i]);
+ }
+ xprintf(f,"\t} %s;\n", header_elstring(elnum));
+}
+
+function header_elem(f, elnum)
+{
+
+ if (elements[elnum, "type"] == "union") {
+ header_union(f, elnum);
+ } else {
+ header_element(f, elnum);
+ }
+}
+
+function header_struct(f, struct_num,
+ LOCAL, i)
+{
+ xprintf(f,"/* structure %s */\n",
+ structs[struct_num, "name"]);
+ xprintf(f,"typedef struct {\n");
+ for (i=0;i < structs[struct_num, "num_elems"];i++) {
+ header_elem(f, structs[struct_num, i]);
+ }
+ xprintf(f,"} %s;\n\n\n", structs[struct_num, "name"]);
+}
+
+
+function produce_headers(f, NIL,
+ LOCAL, i)
+{
+ 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);
+ }
+ xprintf(f,"/* end auto-generated headers */\n\n");
+ xprintf(f,"#endif /* _%s_ */\n", module);
+}
+
diff --git a/source3/aparser/main.awk b/source3/aparser/main.awk
new file mode 100644
index 0000000000..4969f2217a
--- /dev/null
+++ b/source3/aparser/main.awk
@@ -0,0 +1,25 @@
+# the main program
+
+@include dump.awk
+@include header.awk
+@include util.awk
+@include template.awk
+#@include parsefn.awk
+@include parserel.awk
+@include harness.awk
+@include parsetree.awk
+@include token.awk
+
+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 relative parsers...\n");
+ produce_relative("prs_"module".c");
+ printf("Producing harness...\n");
+ produce_harness("test.h");
+ printf("Done.\n");
+ exit 0;
+}
diff --git a/source3/aparser/parsefn.awk b/source3/aparser/parsefn.awk
new file mode 100644
index 0000000000..2bebd765e6
--- /dev/null
+++ b/source3/aparser/parsefn.awk
@@ -0,0 +1,271 @@
+# 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_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<unions[elnum, "num_elems"];i++) {
+ v["CASE"] = elements[unions[elnum, i], "case"];
+ print_template(f, "prs_case.tpl", v);
+ if (elements[elnum, "ptr"] == "1") {
+ parse_scalars(f, v, unions[elnum, i], "PARSE_SCALARS");
+ parse_buffers(f, v, unions[elnum, i], "PARSE_BUFFERS");
+ } else {
+ if (flags == "PARSE_SCALARS") {
+ parse_scalars(f, v, unions[elnum, i], flags);
+ } else {
+ parse_buffers(f, v, unions[elnum, i], flags);
+ }
+ }
+ print_template(f, "prs_break.tpl", v);
+ }
+ v["UNION"] = "";
+
+ print_template(f, "union_end.tpl", v);
+}
+
+function parse_scalar(f, v, elnum, flags)
+{
+ if (elements[elnum, "type"] == "union") {
+ parse_union(f, v, elnum, flags);
+ } else if (elements[elnum, "array_len"]!="") {
+ parse_array(f, v, elnum, flags);
+ } else {
+ parse_element(f, v, elnum, flags);
+ }
+}
+
+function parse_align2(f, v, elnum, flags,
+ LOCAL, elem)
+{
+ elem = elements[elnum, "elem"];
+ v["OFFSET"] = elem_name(v, elem);
+ print_template(f, "prs_align2.tpl", v);
+}
+
+function parse_align4(f, v, elnum, flags,
+ LOCAL, elem)
+{
+ elem = elements[elnum, "elem"];
+ v["OFFSET"] = elem_name(v, elem);
+ print_template(f, "prs_align4.tpl", v);
+}
+
+function parse_pointer(f, v, elnum, flags,
+ LOCAL, elem)
+{
+ elem = elements[elnum, "elem"];
+ v["ELEM"] = elem_name(v, elem);
+ v["FLAGS"] = flags;
+ print_template(f, "prs_pointer.tpl", v);
+}
+
+function parse_scalar_fn(m, v, elnum,
+ LOCAL, elem, type)
+{
+ elem = elements[elnum, "elem"];
+ type = elements[elnum, "type"]
+ xprintf(m, "%s %s", type, elem_name(v, elem));
+ if (type == "union") {
+ } else if (elements[elnum, "array_len"]!="") {
+ } else {
+ }
+}
+
+function parse_pointer_fn(f, v, elnum, flags,
+ LOCAL, elem)
+{
+ elem = elements[elnum, "elem"];
+ v["ELEM"] = elem_name(v, elem);
+ v["FLAGS"] = flags;
+ xprintf(m, "%s\n", v["ELEM"]);
+}
+
+function parse_scalars_fn(m, v, elnum, flags)
+{
+ if (elements[elnum, "type"] == ".align2") {
+ }
+ else if (elements[elnum, "type"] == ".align4") {
+ }
+ else if (elements[elnum, "ptr"] == "1") {
+ parse_pointer_fn(m, v, elnum, flags);
+ } else {
+ parse_scalar_fn(m, v, elnum, flags);
+ }
+}
+
+function parse_scalars(f, v, elnum, flags)
+{
+ if (elements[elnum, "type"] == ".align2") {
+ parse_align2(f, v, elnum, flags);
+ }
+ else if (elements[elnum, "type"] == ".align4") {
+ parse_align4(f, v, elnum, flags);
+ }
+ else if (elements[elnum, "ptr"] == "1") {
+ parse_pointer(f, v, elnum, flags);
+ } else {
+ parse_scalar(f, v, elnum, flags);
+ }
+}
+
+function parse_buffers(f, v, elnum, flags,
+ LOCAL, elem, type)
+{
+ elem = elements[elnum, "elem"];
+ type = elements[elnum, "type"];
+ v["ELEM"] = elem_name(v, elem);
+ if (elements[elnum, "type"] == ".align2") {
+ }
+ else if (elements[elnum, "type"] == ".align4") {
+ } else if (elements[elnum, "ptr"] == "1") {
+ print_template(f, "ifptr_start.tpl", v);
+ parse_scalar(f, v, elnum, "PARSE_SCALARS|PARSE_BUFFERS");
+ print_template(f, "ifptr_end.tpl", v);
+ } else {
+ parse_scalar(f, v, elnum, flags);
+ }
+}
+
+function struct_parser(f, m, v, struct_num,
+ LOCAL, i, n1, f1, num_elems)
+{
+ f1 = -1;
+ num_elems = structs[struct_num, "num_elems"];
+ v["STRUCTNAME"] = structs[struct_num, "name"];
+ v["FUNCNAME"] = "io_" v["STRUCTNAME"];
+ print_template(f, "fn_start.tpl", v);
+
+ for (n1=0;n1<num_elems;n1++) {
+ if (elements[structs[struct_num, n1], "type"] == ".trailer") {
+ f1 = n1;
+ break;
+ }
+ }
+
+ # first all the structure pointers, scalars and arrays
+ for (i=0;i<n1;i++) {
+ parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS");
+ }
+
+ print_template(f, "fn_mid.tpl", v);
+
+ # now the buffers
+ for (i=0;i<n1;i++) {
+ parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS");
+ }
+
+ # and any trailers
+ for (i=n1;i<num_elems;i++) {
+ parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS");
+ parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS");
+ }
+
+ if (i > 0) {
+ print_template(f, "fn_end.tpl", v);
+ }
+ else {
+ print_template(f, "fn_end0.tpl", v);
+ }
+
+ if (f1 == -1)
+ return;
+
+ xprintf(m, "void fn_%s(\n", v["STRUCTNAME"]);
+
+ for (i=f1+1;i<num_elems;i++) {
+ parse_scalars_fn(m, v, structs[struct_num, i]);
+ if (i != num_elems-1)
+ xprintf(m, ", \n");
+
+ }
+
+ xprintf(m, ")\n{\n}\n");
+}
+
+function produce_parsers(f, m,
+ LOCAL, v, i)
+{
+ v["MODULE"]=module;
+
+ print_template(f, "module_start.tpl", v);
+
+ for (i=0;i < num_structs;i++) {
+ struct_parser(f, m, v, i);
+ }
+
+ print_template(f, "module_end.tpl", v);
+}
diff --git a/source3/aparser/parser.c b/source3/aparser/parser.c
new file mode 100644
index 0000000000..0c7153e1fb
--- /dev/null
+++ b/source3/aparser/parser.c
@@ -0,0 +1,471 @@
+#include "parser.h"
+
+/*******************************************************************
+ Attempt, if needed, to grow a data buffer.
+ Also depends on the data stream mode (io).
+ ********************************************************************/
+
+BOOL io_grow(io_struct *ps, uint32 extra_space)
+{
+ uint32 new_size;
+ char *new_data;
+
+ ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);
+
+ if(ps->data_offset + extra_space <= ps->buffer_size)
+ return True;
+
+ /*
+ * We cannot grow the buffer if we're not reading
+ * into the io_struct, or if we don't own the memory.
+ */
+
+ if(UNMARSHALLING(ps) || !ps->is_dynamic) {
+ DEBUG(0,("io_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
+ (unsigned int)extra_space));
+ return False;
+ }
+
+ /*
+ * Decide how much extra space we really need.
+ */
+
+ extra_space -= (ps->buffer_size - ps->data_offset);
+ if(ps->buffer_size == 0) {
+ 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));
+ return False;
+ }
+ memset(new_data, '\0', new_size );
+ } else {
+ /*
+ * If the current buffer size is bigger than the space needed, just
+ * double it, else add extra_space.
+ */
+ new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);
+
+ if ((new_data = Realloc(ps->data_p, new_size)) == NULL) {
+ DEBUG(0,("io_grow: Realloc failure for size %u.\n",
+ (unsigned int)new_size));
+ return False;
+ }
+ }
+ ps->buffer_size = new_size;
+ ps->data_p = new_data;
+
+ return True;
+}
+
+
+/*******************************************************************
+ Ensure we can read/write to a given offset.
+ ********************************************************************/
+
+char *io_mem_get(io_struct *ps, uint32 extra_size)
+{
+ if(UNMARSHALLING(ps)) {
+ /*
+ * If reading, ensure that we can read the requested size item.
+ */
+ if (ps->data_offset + extra_size > ps->buffer_size) {
+ DEBUG(0,("io_mem_get: reading data of size %u would overrun buffer.\n",
+ (unsigned int)extra_size ));
+ return NULL;
+ }
+ } else {
+ /*
+ * Writing - grow the buffer if needed.
+ */
+ if(!io_grow(ps, extra_size))
+ return False;
+ }
+ return &ps->data_p[ps->data_offset];
+}
+
+/*******************************************************************
+ Initialise a parse structure - malloc the data if requested.
+ ********************************************************************/
+
+BOOL io_init(io_struct *ps, uint32 size, BOOL io)
+{
+ ZERO_STRUCTP(ps);
+ ps->io = io;
+ ps->bigendian_data = False;
+ ps->is_dynamic = False;
+ ps->data_offset = 0;
+ ps->buffer_size = 0;
+ ps->data_p = NULL;
+
+ if (size != 0) {
+ ps->buffer_size = size;
+ if((ps->data_p = (char *)malloc((size_t)size)) == NULL) {
+ DEBUG(0,("io_init: malloc fail for %u bytes.\n", (unsigned int)size));
+ return False;
+ }
+ ps->is_dynamic = True; /* We own this memory. */
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ debug output for parsing info.
+
+ XXXX side-effect of this function is to increase the debug depth XXXX
+
+ ********************************************************************/
+void io_debug(io_struct *ps, int depth, char *desc, char *fn_name)
+{
+ DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
+}
+
+/*******************************************************************
+ Align a the data_len to a multiple of align bytes - filling with
+ zeros.
+ ********************************************************************/
+
+BOOL io_align2(io_struct *ps, int offset)
+{
+ uint32 mod = (ps->data_offset + offset) & (2-1);
+
+ if (mod != 0) {
+ uint32 extra_space = (2 - mod);
+ if(!io_grow(ps, extra_space))
+ return False;
+ memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
+ ps->data_offset += extra_space;
+ }
+
+ return True;
+}
+
+BOOL io_align4(io_struct *ps, int offset)
+{
+ uint32 mod = (ps->data_offset + offset) & (4-1);
+
+ if (mod != 0) {
+ uint32 extra_space = (4 - mod);
+ if(!io_grow(ps, extra_space))
+ return False;
+ memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
+ ps->data_offset += extra_space;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Align a the data_len to a multiple of align bytes - filling with
+ zeros.
+ ********************************************************************/
+
+BOOL io_align(io_struct *ps, int align)
+{
+ uint32 mod;
+
+ if (!ps->autoalign) return True;
+
+ mod = ps->data_offset & (align-1);
+
+ if (align != 0 && mod != 0) {
+ uint32 extra_space = (align - mod);
+ if(!io_grow(ps, extra_space))
+ return False;
+ memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
+ ps->data_offset += extra_space;
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
+ read from a socket into memory.
+ ********************************************************************/
+BOOL io_read(io_struct *ps, int fd, size_t len, int timeout)
+{
+ BOOL ok;
+ size_t prev_size = ps->buffer_size;
+ if (!io_grow(ps, len))
+ {
+ return False;
+ }
+
+ if (timeout > 0)
+ {
+ ok = (read(fd, &ps->data_p[prev_size], len) == len);
+ }
+ else
+ {
+ ok = (read(fd, &ps->data_p[prev_size], len) == len);
+ }
+ return ok;
+}
+
+
+/*******************************************************************
+ do IO on a uint32.
+ ********************************************************************/
+BOOL io_uint32(char *name, io_struct *ps, int depth, uint32 *data32, unsigned flags)
+{
+ char *q;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ if (!io_align(ps, 4)) return False;
+
+ q = io_mem_get(ps, sizeof(uint32));
+ if (q == NULL) return False;
+
+ DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32)
+ ps->data_offset += sizeof(uint32);
+
+ return True;
+}
+
+/*******************************************************************
+ do IO on a uint16.
+ ********************************************************************/
+BOOL io_uint16(char *name, io_struct *ps, int depth, uint16 *data16, unsigned flags)
+{
+ char *q;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ if (!io_align(ps, 2)) return False;
+
+ q = io_mem_get(ps, sizeof(uint16));
+ if (q == NULL) return False;
+
+ DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16)
+ ps->data_offset += sizeof(uint16);
+
+ return True;
+}
+
+/*******************************************************************
+ do IO on a uint8.
+ ********************************************************************/
+BOOL io_uint8(char *name, io_struct *ps, int depth, uint8 *data8, unsigned flags)
+{
+ char *q;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ q = io_mem_get(ps, sizeof(uint8));
+ if (q == NULL) return False;
+
+ DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data8)
+ ps->data_offset += sizeof(uint8);
+
+ return True;
+}
+
+/*******************************************************************
+ do IO on a pointer
+ ********************************************************************/
+BOOL io_pointer(char *desc, io_struct *ps, int depth, void **p, unsigned flags)
+{
+ uint32 v;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ v = (*p) ? 0xdeadbeef : 0;
+ if (!io_uint32(desc, ps, depth, &v, flags)) return False;
+ *p = (void *) (v ? 0xdeadbeef : 0);
+ return True;
+}
+
+/*******************************************************************
+ Stream a null-terminated string.
+ ********************************************************************/
+BOOL io_SMBSTR(char *name, io_struct *ps, int depth, char **str, unsigned flags)
+{
+ char *q;
+ uint8 *start;
+ int i;
+ size_t len;
+ int start_offset = ps->data_offset;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ if (UNMARSHALLING(ps)) {
+ *str = io_mem_get(ps, 0);
+ if (*str == NULL)
+ return False;
+ len = strlen(*str);
+ ps->data_offset += len + 1;
+ }
+ else
+ {
+ len = strlen(*str)+1;
+ start = (uint8*)q;
+
+ for(i = 0; i < len; i++) {
+ q = io_mem_get(ps, 1);
+ if (q == NULL)
+ return False;
+
+ RW_CVAL(ps->io, q, (*str)[i],0);
+ ps->data_offset++;
+ }
+ }
+
+ DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth),
+ start_offset, name, *str));
+ return True;
+}
+
+/******************************************************************
+ do IO on a byte array
+ ********************************************************************/
+BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, unsigned flags)
+{
+ char *q;
+ size_t num_bytes = len * sizeof(uint8);
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ q = io_mem_get(ps, num_bytes);
+ if (q == NULL) return False;
+
+ if (MARSHALLING(ps))
+ {
+ DBG_RW_PCVAL(True, name, depth, ps->data_offset, ps->io, q, *data8s, len)
+ }
+ else
+ {
+ *data8s = q;
+ dump_data(depth+5, *data8s, num_bytes);
+ }
+ ps->data_offset += num_bytes;
+
+ return True;
+}
+/******************************************************************
+ do IO on a fixed-size byte array
+ ********************************************************************/
+BOOL io_uint8s_fixed(char *name, io_struct *ps, int depth, uint8 *data8s, int len, unsigned flags)
+{
+ char *q;
+ size_t num_bytes = len * sizeof(uint8);
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ q = io_mem_get(ps, num_bytes);
+ if (q == NULL) return False;
+
+ DBG_RW_PCVAL(True, name, depth, ps->data_offset, ps->io, q, data8s, len)
+ ps->data_offset += num_bytes;
+
+ return True;
+}
+
+
+/******************************************************************
+ do IO on an io (eh?? :)
+ ********************************************************************/
+BOOL io_io_struct(char *name, io_struct *ps, int depth, io_struct *io, unsigned flags)
+{
+ char *q;
+ uint16 len;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ q = io_mem_get(ps, sizeof(uint16));
+ if (q == NULL) return False;
+
+ /* length first */
+ if (MARSHALLING(ps))
+ {
+ len = io->data_offset;
+ }
+ if (!io_uint16("len", ps, depth+1, &len, flags))
+ {
+ return False;
+ }
+ if (UNMARSHALLING(ps))
+ {
+ if (!io_init(io, len, UNMARSHALL))
+ {
+ return False;
+ }
+ }
+
+ /* now data */
+ q = io_mem_get(ps, len * sizeof(uint8));
+ if (q == NULL) return False;
+
+ if (MARSHALLING(ps))
+ {
+ DBG_RW_PCVAL(False, name, depth+1, ps->data_offset, ps->io, q, io->data_p, len)
+ }
+ else
+ {
+ io->data_p = q;
+ dump_data(depth+5, q, len);
+ }
+ ps->data_offset += len;
+
+ return True;
+}
+
+/******************************************************************
+ do IO on a unicode array
+ ********************************************************************/
+BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, unsigned flags)
+{
+ char *q;
+
+ if (!(flags & PARSE_SCALARS)) return True;
+
+ if (!io_align(ps, 2)) return False;
+
+ q = io_mem_get(ps, len * sizeof(uint16));
+ if (q == NULL) return False;
+
+ 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;
+}
+
+
+/******************************************************************
+allocate some memory for a parse structure
+ ********************************************************************/
+void io_free(io_struct *ps)
+{
+ if (ps->is_dynamic && ps->data_p)
+ {
+ free(ps->data_p);
+ ps->data_p = NULL;
+ }
+}
+
+/******************************************************************
+allocate some memory for a parse structure
+ ********************************************************************/
+BOOL io_alloc(char *name, io_struct *ps, void **ptr, unsigned size)
+{
+ (*ptr) = (void *)malloc(size);
+ if (*ptr) return True;
+ return False;
+}
+
+/******************************************************************
+realloc some memory for a parse structure
+ ********************************************************************/
+BOOL io_realloc(char *name, io_struct *ps, void **ptr, unsigned size)
+{
+ BOOL ret = True;
+ void *tp;
+
+ tp = (void *)Realloc(*ptr, size);
+ if (tp) *ptr = tp;
+ else ret = False;
+ return ret;
+}
+
diff --git a/source3/aparser/parser.h b/source3/aparser/parser.h
new file mode 100644
index 0000000000..319aeb5d13
--- /dev/null
+++ b/source3/aparser/parser.h
@@ -0,0 +1,103 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "../include/byteorder.h"
+
+#define PARSE_SCALARS (1<<0)
+#define PARSE_BUFFERS (1<<1)
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+#define DEBUG(lvl, str) printf str;
+#define DEBUGADD(lvl, str) printf str;
+
+#define MARSHALL 0
+#define UNMARSHALL 1
+
+#define MARSHALLING(ps) (!(ps)->io)
+#define UNMARSHALLING(ps) ((ps)->io)
+
+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
+#define FSTRING_LEN 128
+
+typedef char pstring[PSTRING_LEN];
+typedef char fstring[FSTRING_LEN];
+
+#define _PSTRING
+
+#endif
+#define False 0
+#define True 1
+
+/* zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
+
+#define MAX_UNISTRLEN 256
+#define MAX_STRINGLEN 256
+#define MAX_BUFFERLEN 512
+
+typedef struct _io_struct
+{
+ BOOL io; /* parsing in or out of data stream */
+ /*
+ * If the (incoming) data is big-endian. On output we are
+ * always little-endian.
+ */
+ 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 */
+ char *data_p; /* The buffer itself. */
+} io_struct;
+
+
+char *io_mem_get(io_struct *ps, uint32 extra_size);
+BOOL io_init(io_struct *ps, uint32 size, BOOL io);
+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);
+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);
+BOOL io_uint32(char *name, io_struct *ps, int depth, uint32 *data32, unsigned flags);
+BOOL io_uint16(char *name, io_struct *ps, int depth, uint16 *data16, unsigned flags);
+BOOL io_uint8(char *name, io_struct *ps, int depth, uint8 *data8, unsigned flags);
+BOOL io_pointer(char *desc, io_struct *ps, int depth, void **p, unsigned flags);
+BOOL io_SMBSTR(char *name, io_struct *ps, int depth, char **str, unsigned flags);
+BOOL io_io_struct(char *name, io_struct *ps, int depth, io_struct *io, unsigned flags);
+BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, unsigned flags);
+BOOL io_uint8s_fixed(char *name, io_struct *ps, int depth, uint8 *data8s, int len, unsigned flags);
+BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, unsigned flags);
+
+char *tab_depth(int depth);
+void *Realloc(void *p,size_t size);
+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<unions[elnum, "num_elems"];i++) {
+ v["CASE"] = elements[unions[elnum, i], "case"];
+ print_template(f, "prs_case.tpl", v);
+ if (elements[elnum, "ptr"] == "1") {
+ parse_scalars(f, v, unions[elnum, i], "PARSE_SCALARS");
+ parse_buffers(f, v, unions[elnum, i], "PARSE_BUFFERS");
+ } else {
+ if (flags == "PARSE_SCALARS") {
+ parse_scalars(f, v, unions[elnum, i], flags);
+ } else {
+ parse_buffers(f, v, unions[elnum, i], flags);
+ }
+ }
+ print_template(f, "prs_break.tpl", v);
+ }
+ v["UNION"] = "";
+
+ print_template(f, "union_end.tpl", v);
+}
+
+function parse_scalar(f, v, elnum, flags)
+{
+ if (elements[elnum, "type"] == "union") {
+ parse_union(f, v, elnum, flags);
+ } else if (elements[elnum, "array_len"]!="") {
+ parse_array(f, v, elnum, flags);
+ } else {
+ parse_element(f, v, elnum, flags);
+ }
+}
+
+function parse_pointer(f, v, elnum, flags,
+ LOCAL, elem)
+{
+ elem = elements[elnum, "elem"];
+ v["ELEM"] = elem_name(v, elem);
+ v["FLAGS"] = flags;
+ print_template(f, "prs_pointer.tpl", v);
+}
+
+function parse_scalars(f, v, elnum, flags)
+{
+ if (elements[elnum, "ptr"] == "1") {
+ parse_pointer(f, v, elnum, flags);
+ } else {
+ parse_scalar(f, v, elnum, flags);
+ }
+}
+
+function parse_buffers(f, v, elnum, flags,
+ LOCAL, elem, type)
+{
+ elem = elements[elnum, "elem"];
+ type = elements[elnum, "type"];
+ v["ELEM"] = elem_name(v, elem);
+ if (elements[elnum, "ptr"] == "1") {
+ print_template(f, "ifptr_start.tpl", v);
+ parse_scalar(f, v, elnum, "PARSE_SCALARS|PARSE_BUFFERS");
+ print_template(f, "ifptr_end.tpl", v);
+ } else {
+ parse_scalar(f, v, elnum, flags);
+ }
+}
+
+function struct_immediate(f, v, struct_num,
+ LOCAL, i, n1, num_elems)
+{
+ num_elems = structs[struct_num, "num_elems"];
+ v["STRUCTNAME"] = structs[struct_num, "name"];
+ v["FUNCNAME"] = "io_" v["STRUCTNAME"];
+
+ print_template(f, "fn_i_start.tpl", v);
+
+ for (i=0;i<num_elems;i++) {
+ parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS");
+ parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS");
+ }
+
+ print_template(f, "fn_i_end.tpl", v);
+}
+
+
+function struct_recursive(f, v, struct_num,
+ LOCAL, i, n1, num_elems)
+{
+ num_elems = structs[struct_num, "num_elems"];
+ v["STRUCTNAME"] = structs[struct_num, "name"];
+ v["FUNCNAME"] = "io_" v["STRUCTNAME"];
+
+ print_template(f, "fn_start.tpl", v);
+
+# first all the structure pointers, scalars and arrays
+ for (i=0;i<num_elems;i++) {
+ parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS");
+ }
+
+ print_template(f, "fn_mid.tpl", v);
+
+# now the buffers
+ for (i=0;i<num_elems;i++) {
+ parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS");
+ }
+
+ print_template(f, "fn_end.tpl", v);
+}
+
+function struct_parser(f, v, struct_num,
+ LOCAL, i, n1, num_elems)
+{
+ if (structs[struct_num, "recurse"] == "True") {
+ struct_recursive(f, v, struct_num);
+ } else {
+ struct_immediate(f, v, struct_num);
+ }
+}
+
+function produce_relative(f,
+ LOCAL, v, i)
+{
+ v["MODULE"]=module;
+
+ print_template(f, "module_start.tpl", v);
+
+ for (i=0;i < num_structs;i++) {
+ struct_parser(f, v, i);
+ }
+
+ print_template(f, "module_end.tpl", v);
+}
diff --git a/source3/aparser/parsetree.awk b/source3/aparser/parsetree.awk
new file mode 100644
index 0000000000..80587a0111
--- /dev/null
+++ b/source3/aparser/parsetree.awk
@@ -0,0 +1,224 @@
+# build the parse tree for a struct file
+
+function find_structure(name,
+ LOCAL, i)
+{
+ for (i=0;i<num_structs;i++) {
+ if (structs[i, "name"] == name) return i;
+ }
+ return "-1";
+}
+
+function start_module(name)
+{
+ module=name;
+ num_structs=0;
+ num_elements=0;
+ num_unions=0;
+ num_tests=0;
+ num_options=0;
+}
+
+function set_option(name, value)
+{
+ options[name] = value;
+ options[num_options, "name"] = name;
+ options[num_options, "value"] = value;
+ num_options++;
+}
+
+function parse_define(def1, def2,
+ LOCAL, type, i)
+{
+ defines[def1]=def2;
+}
+
+function start_struct(name)
+{
+ current_struct=num_structs;
+ structs[name]=current_struct;
+ structs[current_struct, "name"]=name;
+ structs[current_struct, "num_elems"]=0;
+ structs[current_struct, "num_unions"]=0;
+ structs[current_struct, "recurse"] = options["recurse"];
+}
+
+function end_struct(name)
+{
+ if (name!="") structs[num_structs, "name"]=name;
+ printf("struct %s with %d elements\n",
+ structs[num_structs, "name"],
+ structs[num_structs, "num_elems"]);
+ num_structs++;
+ current_struct="";
+}
+
+function add_element(type, elem, case,
+ LOCAL, elem_num, i, v)
+{
+ while (defines[type]!="") {
+ type=defines[type];
+ }
+ elem_num=num_elements;
+
+ if (substr(elem, 1, 1) == ".") {
+ elem=substr(elem, 2);
+ elements[elem_num, "nowire"]=1;
+ }
+
+ if (substr(elem, 1, 1) == "*") {
+ elem=substr(elem, 2);
+ elements[elem_num, "ptr"]=1;
+ }
+
+ i=match(elem,"[[]");
+ if (i != 0) {
+ v = substr(elem, i+1, length(elem)-i-1);
+ elem=substr(elem, 1, i-1);
+ if (type=="union") {
+ elements[elem_num, "switch"] = v;
+ } else {
+ elements[elem_num, "array_len"] = v;
+ }
+ }
+
+ elements[elem_num, "type"] = type;
+ elements[elem_num, "elem"] = elem;
+ elements[elem_num, "case"] = case;
+
+ num_elements++;
+ return elem_num;
+}
+
+function add_struct_elem(type, elem, case,
+ LOCAL, elem_num)
+{
+ elem_num=structs[current_struct, "num_elems"];
+ structs[current_struct, elem_num] = add_element(type, elem, case);
+ structs[current_struct, "num_elems"]++;
+ return structs[current_struct, elem_num];
+}
+
+function start_union(elem)
+{
+ current_union = add_struct_elem("union", elem);
+ unions[current_union, "num_elems"] = 0;
+}
+
+function start_union_notencap(switch)
+{
+ add_struct_elem("uint32", "switch_"switch);
+ start_union("UNKNOWN[switch_"switch"]");
+}
+
+function start_union_encap(struct, type, switch, union)
+{
+ start_struct(struct);
+ add_struct_elem(type, switch);
+ add_struct_elem(type, "switch_"switch);
+ start_union(union"[switch_"switch"]");
+ encap_union="1";
+}
+
+function parse_case(case, type, elem,
+ LOCAL, elem_num)
+{
+ split(case, a, "[:]");
+ case = a[1];
+ elem_num = unions[current_union, "num_elems"];
+ unions[current_union, elem_num] = add_element(type, elem, case);
+ unions[current_union, "num_elems"]++;
+}
+
+function end_union(name)
+{
+ if (name!="") {
+ elements[current_union, "elem"] = name;
+ }
+ current_union="";
+ if (encap_union=="1") {
+ end_struct(name);
+ encap_union="0";
+ }
+}
+
+function delete_element(struct, elnum,
+ LOCAL, i)
+{
+ for (i=elnum;i<structs[struct,"num_elems"]-1;i++) {
+ structs[struct, i] = structs[struct, i+1];
+ }
+ structs[struct, "num_elems"]--;
+}
+
+function copy_struct(from, to,
+ LOCAL, i)
+{
+ for (i=0;i<structs[from,"num_elems"];i++) {
+ structs[to, i] = structs[from, i];
+ }
+ structs[to, "name"] = structs[from, "name"];
+ structs[to, "num_elems"] = structs[from, "num_elems"];
+ structs[to, "num_unions"] = structs[from, "num_unions"];
+}
+
+function add_sizeis_array(count, type, elem)
+{
+ copy_struct(current_struct, current_struct+1);
+ elem=substr(elem,2);
+ start_struct("array_"current_struct"_"elem);
+ add_struct_elem("uint32", count);
+ add_struct_elem(type, elem"["count"]");
+ end_struct("");
+ current_struct=num_structs;
+ add_struct_elem("array_"current_struct-1"_"elem, "*"elem"_ptr");
+}
+
+
+function start_function(type, fname)
+{
+ start_struct(fname);
+ structs[current_struct, "recurse"] = "False";
+}
+
+function end_function(LOCAL, i)
+{
+ copy_struct(num_structs, num_structs+1);
+ structs[num_structs, "name"] = "Q_"structs[num_structs, "name"];
+ for (i=0;i<structs[num_structs, "num_elems"];i++) {
+ if (match(elements[structs[num_structs, i], "properties"], "in") == 0) {
+ delete_element(num_structs, i);
+ i--;
+ }
+ }
+ end_struct();
+ current_struct=num_structs;
+ structs[num_structs, "name"] = "R_"structs[num_structs, "name"];
+ for (i=0;i<structs[num_structs, "num_elems"];i++) {
+ if (match(elements[structs[num_structs, i], "properties"], "out") == 0) {
+ delete_element(num_structs, i);
+ i--;
+ }
+ }
+ if (return_result!="void")
+ add_function_param("[out]", return_result, "status");
+ end_struct();
+}
+
+function add_function_param(properties, type, elem,
+ LOCAL, elnum, len)
+{
+ len=length(type);
+ if (substr(type, len) == "*") {
+ type=substr(type, 1, len-1);
+ elem="*"elem;
+ }
+ if (substr(elem,1,1) == "*" &&
+ (match(properties,"in") == 0 ||
+ find_structure(type) != "-1")) {
+ elem=substr(elem, 2);
+ }
+ elnum = add_struct_elem(type, elem);
+ elements[elnum, "properties"] = properties;
+}
+
diff --git a/source3/aparser/spool.struct b/source3/aparser/spool.struct
new file mode 100644
index 0000000000..1563ba5be0
--- /dev/null
+++ b/source3/aparser/spool.struct
@@ -0,0 +1,90 @@
+module spool
+
+struct BUFFER5 {
+ uint32 buf_len;
+ uint16 buffer[buf_len];
+};
+
+struct BUFFERP {
+ uint32 buf_len;
+ BUFFER5 *buf;
+};
+
+struct UNISTR2 {
+ uint32 max_len;
+ uint32 undoc;
+ uint32 str_len;
+ uint16 buffer[str_len];
+};
+
+struct LPWSTR {
+ UNISTR2 *str;
+};
+
+struct VERSION {
+ uint32 version;
+ uint32 build;
+ uint32 osversion;
+};
+
+struct NTTIME {
+ uint32 low;
+ uint32 high;
+};
+
+struct DWORD {
+ uint32 x;
+};
+
+struct PRINTER_DRIVER_INFO_LEVEL_3 {
+ DWORD cversion;
+ LPWSTR name;
+ LPWSTR environment;
+ LPWSTR driverpath;
+ LPWSTR datafile;
+ LPWSTR configfile;
+ LPWSTR helpfile;
+ LPWSTR monitorname;
+ LPWSTR defaultdatatype;
+ BUFFERP dependentfiles;
+};
+
+struct PRINTER_DRIVER_INFO_LEVEL_6 {
+ DWORD dummy1;
+ DWORD version;
+ LPWSTR name;
+ LPWSTR environment;
+ LPWSTR driverpath;
+ LPWSTR datafile;
+ LPWSTR configfile;
+ LPWSTR helpfile;
+ LPWSTR monitorname;
+ LPWSTR defaultdatatype;
+ BUFFERP dependentfiles;
+ BUFFERP previousnames;
+ NTTIME driverdate;
+ VERSION driverversion;
+ LPWSTR mfgname;
+ LPWSTR oemurl;
+ LPWSTR hardwareid;
+ LPWSTR provider;
+};
+
+
+struct PRINTER_DRIVER_INFO {
+ uint32 level;
+ union *info[level] {
+ case 3 PRINTER_DRIVER_INFO_LEVEL_3 info_3;
+ case 6 PRINTER_DRIVER_INFO_LEVEL_6 info_6;
+ }
+};
+
+
+struct R_GETPRINTERDATA {
+ uint32 type;
+ uint32 size;
+ uint8 *data;
+ uint32 needed;
+ uint32 status;
+};
+
diff --git a/source3/aparser/spool_io_printer_driver_info_level_3.prs b/source3/aparser/spool_io_printer_driver_info_level_3.prs
new file mode 100644
index 0000000000..baa32ef7c7
--- /dev/null
+++ b/source3/aparser/spool_io_printer_driver_info_level_3.prs
Binary files differ
diff --git a/source3/aparser/spool_io_printer_driver_info_level_6.prs b/source3/aparser/spool_io_printer_driver_info_level_6.prs
new file mode 100644
index 0000000000..3c5a47e7a3
--- /dev/null
+++ b/source3/aparser/spool_io_printer_driver_info_level_6.prs
Binary files differ
diff --git a/source3/aparser/srvsvc.struct b/source3/aparser/srvsvc.struct
new file mode 100644
index 0000000000..aa40c8f15e
--- /dev/null
+++ b/source3/aparser/srvsvc.struct
@@ -0,0 +1,184 @@
+module srvsvc
+
+typedef uint32 LONG;
+typedef uint32 *ENUM_HND;
+
+typedef struct _UNISTR2 {
+ uint32 max_len;
+ uint32 undoc;
+ uint32 str_len;
+ wchar buffer[str_len];
+} UNISTR2;
+
+typedef UNISTR2 *LPWSTR;
+
+/* function 8 */
+struct CONN_INFO_0 {
+ uint32 id; /* connection id. */
+};
+
+struct CONN_INFO_1 {
+ uint32 id;
+ uint32 type;
+ uint32 num_opens;
+ uint32 num_users;
+ uint32 open_time;
+ LPWSTR usr_name;
+ LPWSTR net_name;
+};
+
+struct CONN_ENUM_CTR {
+ uint32 level;
+ uint32 level2;
+ uint32 num_entries;
+ uint32 num_entries2;
+ union *info[level] {
+ case 0 CONN_INFO_0 info0[num_entries];
+ case 1 CONN_INFO_1 info1[num_entries];
+ }
+};
+
+struct SRV_R_NET_CONN_ENUM {
+ .trailer;
+ CONN_ENUM_CTR ctr;
+ uint32 num_entries;
+ ENUM_HND handle;
+ uint32 status2;
+};
+
+struct SRV_Q_NET_CONN_ENUM {
+ .trailer;
+ LPWSTR dest_srv;
+ LPWSTR qual_srv;
+ uint32 level;
+ uint32 level2;
+ CONN_ENUM_CTR *ctr;
+ uint32 max_len;
+ ENUM_HND handle;
+};
+
+/* function 9 */
+struct FILE_INFO_3 {
+ uint32 id; /* file index */
+ uint32 perms; /* file permissions. don't know what format */
+ uint32 num_locks; /* file locks */
+ LPWSTR path_name; /* file name */
+ LPWSTR user_name; /* file owner */
+};
+
+struct SRV_FILE_INFO_CTR {
+ uint32 level;
+ uint32 num_entries;
+ uint32 dummy;
+ union *file[level] {
+ case 3 FILE_INFO_3 info3[num_entries];
+ }
+};
+
+struct SRV_Q_NET_FILE_ENUM {
+ .trailer;
+ LPWSTR srv_name;
+ LPWSTR qual_name;
+ uint32 dummy;
+ uint32 level;
+ SRV_FILE_INFO_CTR ctr;
+ uint32 *status;
+ uint32 preferred_len;
+ ENUM_HND enum_hnd;
+};
+
+
+struct SRV_R_NET_FILE_ENUM {
+ .trailer;
+ uint32 level;
+ uint32 dummy;
+ SRV_FILE_INFO_CTR *ctr;
+ uint32 total_entries; /* total number of files */
+ ENUM_HND enum_hnd;
+ uint32 status; /* return status */
+};
+
+
+/* function 15 */
+struct SRV_SHARE_INFO_1 {
+ LPWSTR uni_netname;
+ uint32 type;
+ LPWSTR uni_remark;
+};
+
+struct SRV_SHARE_INFO_2 {
+ LPWSTR uni_netname;
+ uint32 type;
+ LPWSTR uni_remark;
+ uint32 perms;
+ uint32 max_uses;
+ uint32 num_uses;
+ LPWSTR path;
+ LPWSTR passwd;
+};
+
+struct SRV_R_NET_SHARE_ENUM {
+ uint32 level;
+ uint32 level2;
+ uint32 *ret_count;
+ uint32 num_entries;
+ union *info[level] {
+ case 1 SRV_SHARE_INFO_1 info1[num_entries];
+ case 2 SRV_SHARE_INFO_2 info2[num_entries];
+ }
+ .trailer;
+ uint32 count;
+ ENUM_HND handle;
+ uint32 status;
+};
+
+
+
+/* function 21 */
+struct SERVER_INFO_100 {
+ uint32 dwPlatformID;
+ LPWSTR pszName;
+};
+
+struct SERVER_INFO_101 {
+ uint32 dwPlatformID;
+ LPWSTR pszName;
+ uint32 dwVerMajor;
+ uint32 dwVerMinor;
+ uint32 dwType;
+ LPWSTR pszComment;
+};
+
+struct SERVER_INFO_102 {
+ uint32 dwPlatformID;
+ LPWSTR pszName;
+ uint32 dwVerMajor;
+ uint32 dwVerMinor;
+ uint32 dwType;
+ LPWSTR pszComment;
+ uint32 dwUsers;
+ uint32 lDisc;
+ uint32 bHidden;
+ uint32 dwAnnounce;
+ uint32 dwAnnDelta;
+ uint32 dwLicenses;
+ LPWSTR pszUserPath;
+};
+
+struct SRV_R_NET_SERVER_INFO {
+ .trailer;
+ uint32 level;
+ union *info[level] {
+ case 100 SERVER_INFO_100 sv100;
+ case 101 SERVER_INFO_101 sv101;
+ case 102 SERVER_INFO_102 sv102;
+ }
+ uint32 status;
+};
+
+struct SRV_Q_NET_SERVER_INFO {
+ .trailer;
+ LPWSTR server;
+ uint32 level;
+};
+
diff --git a/source3/aparser/srvsvc2.struct b/source3/aparser/srvsvc2.struct
new file mode 100644
index 0000000000..362d121e37
--- /dev/null
+++ b/source3/aparser/srvsvc2.struct
@@ -0,0 +1,655 @@
+module srvsvc
+
+option autoalign True
+option relative False
+option recurse True
+option foo blah
+
+#define BOOL uint32
+#define LONG uint32
+#define DWORD uint32
+#define STATUS uint32
+
+typedef struct _UNISTR2 {
+ uint32 max_len;
+ uint32 undoc;
+ uint32 str_len;
+ wchar buffer[str_len];
+} UNISTR2;
+
+struct LPWSTR {
+ UNISTR2 *str;
+};
+
+
+
+ /* -- CHARACTER DEVICE INFORMATION -- */
+
+ typedef struct _CHARDEV_INFO_0 {
+ LPWSTR pszName;
+ } CHARDEV_INFO_0;
+
+ typedef struct _CHARDEV_INFO_1 {
+ LPWSTR pszName;
+ DWORD dwStatus;
+ LPWSTR pszUser;
+ DWORD dwTime;
+ } CHARDEV_INFO_1;
+
+ typedef union _CHARDEV_INFO switch (DWORD dwLevel) ctr {
+ case 1: CHARDEV_INFO_0 *ci0;
+ case 2: CHARDEV_INFO_1 *ci1;
+ } CHARDEV_INFO;
+
+ typedef struct _CHARDEV_ENUM_0 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] CHARDEV_INFO_0 *ci0;
+ } CHARDEV_ENUM_0;
+
+ typedef struct _CHARDEV_ENUM_1 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] CHARDEV_INFO_1 *ci1;
+ } CHARDEV_ENUM_1;
+
+ typedef struct _CHARDEV_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(0)] CHARDEV_ENUM_0 *ce0;
+ [case(1)] CHARDEV_ENUM_1 *ce1;
+ } ctr;
+ } CHARDEV_ENUM;
+
+ STATUS NetrCharDevEnum( /* Function 0x00 */
+ [in,unique] LPWSTR pszServer,
+ [in,out] CHARDEV_ENUM* pCharDevEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrCharDevGetInfo( /* Function 0x01 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszDevice,
+ [in] DWORD dwLevel,
+ [out] CHARDEV_INFO* pCharDevInfo
+ );
+
+ STATUS NetrCharDevControl( /* Function 0x02 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszDevice,
+ [in] DWORD dwOpcode
+ );
+
+ /* -- CHARACTER DEVICE QUEUE INFORMATION -- */
+
+ typedef struct _CHARDEVQ_INFO_0 {
+ LPWSTR pszName;
+ } CHARDEVQ_INFO_0;
+
+ typedef struct _CHARDEVQ_INFO_1 {
+ LPWSTR pszName;
+ DWORD dwPriority;
+ LPWSTR pszDevices;
+ DWORD dwNumUsers;
+ DWORD dwNumAhead;
+ } CHARDEVQ_INFO_1;
+
+ typedef union _CHARDEVQ_INFO switch (DWORD dwLevel) ctr {
+ case 1: CHARDEVQ_INFO_0 *ci0;
+ case 2: CHARDEVQ_INFO_1 *ci1;
+ } CHARDEVQ_INFO;
+
+ typedef struct _CHARDEVQ_ENUM_0 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] CHARDEVQ_INFO_0 *ci0;
+ } CHARDEVQ_ENUM_0;
+
+ typedef struct _CHARDEVQ_ENUM_1 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] CHARDEVQ_INFO_1 *ci1;
+ } CHARDEVQ_ENUM_1;
+
+ typedef struct _CHARDEVQ_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(0)] CHARDEVQ_ENUM_0 *ce0;
+ [case(1)] CHARDEVQ_ENUM_1 *ce1;
+ } ctr;
+ } CHARDEVQ_ENUM;
+
+ STATUS NetrCharDevQEnum( /* Function 0x03 */
+ [in,unique] LPWSTR pszServer,
+ [in,unique] LPWSTR pszUser,
+ [in,out] CHARDEVQ_ENUM* pCharDevQEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrCharDevQGetInfo( /* Function 0x04 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszQueue,
+ [in,ref] LPWSTR pszUser,
+ [in] DWORD dwLevel,
+ [out] CHARDEVQ_INFO* pCharDevQInfo
+ );
+
+ STATUS NetrCharDevQSetInfo( /* Function 0x05 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszQueue,
+ [in] DWORD dwLevel,
+ [in] CHARDEVQ_INFO* pCharDevQInfo,
+ [in,out] DWORD* dwParmError
+ );
+
+ STATUS NetrCharDevQPurge( /* Function 0x06 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszQueue
+ );
+
+ STATUS NetrCharDevQPurgeSelf( /* Function 0x07 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszQueue,
+ [in,ref] LPWSTR pszComputer
+ );
+
+ /* -- CONNECTION INFORMATION -- */
+
+ typedef struct _CONNECTION_INFO_0 {
+ DWORD dwConnID;
+ } CONNECTION_INFO_0;
+
+ typedef struct _CONNECTION_INFO_1 {
+ DWORD dwConnID;
+ DWORD dwType;
+ DWORD dwNumOpens;
+ DWORD dwNumUsers;
+ DWORD dwTime;
+ LPWSTR pszUser;
+ LPWSTR pszShare;
+ } CONNECTION_INFO_1;
+
+ typedef struct _CONNECTION_ENUM_0 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] CONNECTION_INFO_0 *ci0;
+ } CONNECTION_ENUM_0;
+
+ typedef struct _CONNECTION_ENUM_1 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] CONNECTION_INFO_1 *ci1;
+ } CONNECTION_ENUM_1;
+
+ typedef struct _CONNECTION_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(0)] CONNECTION_ENUM_0 *ce0;
+ [case(1)] CONNECTION_ENUM_1 *ce1;
+ } ctr;
+ } CONNECTION_ENUM;
+
+ STATUS NetrConnectionEnum( /* Function 0x08 */
+ [in,unique] LPWSTR pszServer,
+ [in,unique] LPWSTR pszClient,
+ [in,out] CONNECTION_ENUM* pConnectionEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ /* -- FILE INFORMATION -- */
+
+ typedef struct _FILE_INFO_2 {
+ DWORD dwFileID;
+ } FILE_INFO_2;
+
+ typedef struct _FILE_INFO_3 {
+ DWORD dwFileID;
+ DWORD dwPermissions;
+ DWORD dwNumLocks;
+ LPWSTR pszPath;
+ LPWSTR pszUser;
+ } FILE_INFO_3;
+
+ typedef union _FILE_INFO switch (DWORD dwLevel) ctr {
+ case 2: FILE_INFO_2 *fi2;
+ case 3: FILE_INFO_3 *fi3;
+ } FILE_INFO;
+
+ typedef struct _FILE_ENUM_2 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] FILE_INFO_2 *fi2;
+ } FILE_ENUM_2;
+
+ typedef struct _FILE_ENUM_3 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] FILE_INFO_3 *fi3;
+ } FILE_ENUM_3;
+
+ typedef struct _FILE_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(2)] FILE_ENUM_2 *fe2;
+ [case(3)] FILE_ENUM_3 *fe3;
+ } ctr;
+ } FILE_ENUM;
+
+ STATUS NetrFileEnum( /* Function 0x09 */
+ [in,unique] LPWSTR pszServer,
+ [in,unique] LPWSTR pszBasePath,
+ [in,unique] LPWSTR pszUser,
+ [in,out] FILE_ENUM* pFileEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrFileGetInfo( /* Function 0x0A */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwFileID,
+ [in] DWORD dwLevel,
+ [out] FILE_INFO* pFileInfo
+ );
+
+ STATUS NetrFileClose( /* Function 0x0B */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwFileID
+ );
+
+ /* -- SESSION INFORMATION -- */
+
+ typedef struct _SESSION_INFO_0 {
+ LPWSTR pszClient;
+ } SESSION_INFO_0;
+
+ typedef struct _SESSION_INFO_1 {
+ LPWSTR pszClient;
+ LPWSTR pszUser;
+ DWORD dwOpens;
+ DWORD dwTime;
+ DWORD dwIdleTime;
+ DWORD dwUserFlags;
+ } SESSION_INFO_1;
+
+ typedef struct _SESSION_INFO_2 {
+ LPWSTR pszClient;
+ LPWSTR pszUser;
+ DWORD dwOpens;
+ DWORD dwTime;
+ DWORD dwIdleTime;
+ DWORD dwUserFlags;
+ LPWSTR pszClientType;
+ } SESSION_INFO_2;
+
+ typedef struct _SESSION_ENUM_0 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] SESSION_INFO_0 *si0;
+ } SESSION_ENUM_0;
+
+ typedef struct _SESSION_ENUM_1 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] SESSION_INFO_1 *si1;
+ } SESSION_ENUM_1;
+
+ typedef struct _SESSION_ENUM_2 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] SESSION_INFO_2 *si2;
+ } SESSION_ENUM_2;
+
+ typedef struct _SESSION_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(0)] SESSION_ENUM_0 *se0;
+ [case(1)] SESSION_ENUM_1 *se1;
+ [case(2)] SESSION_ENUM_2 *se2;
+ } ctr;
+ } SESSION_ENUM;
+
+ STATUS NetrSessionEnum( /* Function 0x0C */
+ [in,unique] LPWSTR pszServer,
+ [in,unique] LPWSTR pszClient,
+ [in,unique] LPWSTR pszUser,
+ [in,out] SESSION_ENUM* pFileEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrSessionDel( /* Function 0x0D */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszClient,
+ [in,ref] LPWSTR pszUser
+ );
+
+ /* -- SHARE INFORMATION -- */
+
+ typedef struct _SHARE_INFO_0 {
+ LPWSTR pszName;
+ } SHARE_INFO_0;
+
+ typedef struct _SHARE_INFO_1 {
+ LPWSTR pszName;
+ DWORD dwType;
+ LPWSTR pszComment;
+ } SHARE_INFO_1;
+
+ typedef struct _SHARE_INFO_2 {
+ LPWSTR pszName;
+ DWORD dwType;
+ LPWSTR pszComment;
+ DWORD dwPermissions;
+ DWORD dwMaxUses;
+ DWORD dwCurrentUses;
+ LPWSTR pszPath;
+ LPWSTR pszPasswd;
+ } SHARE_INFO_2;
+
+ typedef union _SHARE_INFO switch (DWORD dwLevel) ctr {
+ case 0: SHARE_INFO_0 *si0;
+ case 1: SHARE_INFO_1 *si1;
+ case 2: SHARE_INFO_2 *si2;
+ } SHARE_INFO;
+
+ typedef struct _SHARE_ENUM_0 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] SHARE_INFO_0 *si0;
+ } SHARE_ENUM_0;
+
+ typedef struct _SHARE_ENUM_1 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] SHARE_INFO_1 *si1;
+ } SHARE_ENUM_1;
+
+ typedef struct _SHARE_ENUM_2 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] SHARE_INFO_2 *si2;
+ } SHARE_ENUM_2;
+
+ typedef struct _SHARE_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(0)] SHARE_ENUM_0 *se0;
+ [case(1)] SHARE_ENUM_1 *se1;
+ [case(2)] SHARE_ENUM_2 *se2;
+ } ctr;
+ } SHARE_ENUM;
+
+ STATUS NetrShareAdd( /* Function 0x0E */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwLevel,
+ [out] SHARE_INFO* pShareInfo,
+ [in,out] DWORD* dwParmError
+ );
+
+ STATUS NetrShareEnum( /* Function 0x0F */
+ [in,unique] LPWSTR pszServer,
+ [in,out] SHARE_ENUM* pShareEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrShareGetInfo( /* Function 0x10 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszShare,
+ [in] DWORD dwLevel,
+ [out] SHARE_INFO* pShareInfo
+ );
+
+ STATUS NetrShareSetInfo( /* Function 0x11 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszShare,
+ [in] DWORD dwLevel,
+ [in] SHARE_INFO* pShareInfo,
+ [in] DWORD dwReserved
+ );
+
+ STATUS NetrShareDel( /* Function 0x12 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszShare,
+ [in] DWORD dwReserved
+ );
+
+ STATUS NetrShareDelSticky( /* Function 0x13 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszShare,
+ [in] DWORD dwReserved
+ );
+
+ STATUS NetrShareCheck( /* Function 0x14 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszDevice,
+ [out] DWORD* dwType
+ );
+
+ /* --- SERVER INFORMATION --- */
+
+ typedef struct _SERVER_INFO_100 {
+ DWORD dwPlatformID;
+ LPWSTR pszName;
+ } SERVER_INFO_100;
+
+ typedef struct _SERVER_INFO_101 {
+ DWORD dwPlatformID;
+ LPWSTR pszName;
+ DWORD dwVerMajor;
+ DWORD dwVerMinor;
+ DWORD dwType;
+ LPWSTR pszComment;
+ } SERVER_INFO_101;
+
+ typedef struct _SERVER_INFO_102 {
+ DWORD dwPlatformID;
+ LPWSTR pszName;
+ DWORD dwVerMajor;
+ DWORD dwVerMinor;
+ DWORD dwType;
+ LPWSTR pszComment;
+ DWORD dwUsers;
+ LONG lDisc;
+ BOOL bHidden;
+ DWORD dwAnnounce;
+ DWORD dwAnnDelta;
+ DWORD dwLicenses;
+ LPWSTR pszUserPath;
+ } SERVER_INFO_102;
+
+ typedef union _SERVER_INFO switch (DWORD dwLevel) ctr {
+ case 100: SERVER_INFO_100 *sv100;
+ case 101: SERVER_INFO_101 *sv101;
+ case 102: SERVER_INFO_102 *sv102;
+ } SERVER_INFO;
+
+ STATUS NetrServerGetInfo( /* Function 0x15 */
+ [in,unique] LPWSTR pszServerName,
+ [in] DWORD dwLevel,
+ [out] SERVER_INFO* pServerInfo
+ );
+
+ STATUS NetrServerSetInfo( /* Function 0x16 */
+ [in,unique] LPWSTR pszServerName,
+ [in] DWORD dwLevel,
+ [in] SERVER_INFO* pServerInfo,
+ [in] DWORD dwReserved
+ );
+
+ typedef struct _DISK_INFO {
+ LPWSTR pszName;
+ } DISK_INFO;
+
+ typedef struct _DISK_ENUM {
+ DWORD dwEntries;
+ [size_is(dwEntries)] DISK_INFO *di;
+ } DISK_ENUM;
+
+ STATUS NetrServerDiskEnum( /* Function 0x17 */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwLevel,
+ [in,out] DISK_ENUM* pDiskEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ typedef struct _STAT_SERVER {
+ DWORD dwStart;
+ DWORD dwFOpens;
+ DWORD dwDevOpens;
+ DWORD dwJobsQueued;
+ DWORD dwSOpens;
+ DWORD dwSTimedOut;
+ DWORD dwSErrors;
+ DWORD dwPWErrors;
+ DWORD dwPermErrors;
+ DWORD dwSysErrors;
+ DWORD dwBytesSentLow;
+ DWORD dwBytesSentHigh;
+ DWORD dwBytesRcvdLow;
+ DWORD dwBytesRcvdHigh;
+ DWORD dwAVResponse;
+ DWORD dwReqBufNeed;
+ DWORD dwBigBufNeed;
+ } STAT_SERVER;
+
+ STATUS NetrServerStatisticsGet( /* Function 0x18 */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwLevel,
+ [in] DWORD dwOptions,
+ [out] STAT_SERVER* pStatServer
+ );
+
+ typedef struct _TRANSPORT_INFO_0 {
+ LPWSTR pszName;
+ } TRANSPORT_INFO_0;
+
+ typedef union _TRANSPORT_INFO switch (DWORD dwLevel) ctr {
+ case 0: TRANSPORT_INFO_0 *ti0;
+ } TRANSPORT_INFO;
+
+ typedef struct _TRANSPORT_ENUM_0 {
+ DWORD dwEntries;
+ [size_is(dwEntries)] TRANSPORT_INFO_0 *ti0;
+ } TRANSPORT_ENUM_0;
+
+ typedef struct _TRANSPORT_ENUM {
+ DWORD dwLevel;
+ [switch_is(dwLevel)] union {
+ [case(0)] TRANSPORT_ENUM_0 *te0;
+ } ctr;
+ } TRANSPORT_ENUM;
+
+ STATUS NetrServerTransportAdd( /* Function 0x19 */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwLevel,
+ [out] TRANSPORT_INFO* pTransportInfo
+ );
+
+ STATUS NetrServerTransportEnum( /* Function 0x1a */
+ [in,unique] LPWSTR pszServer,
+ [in,out] TRANSPORT_ENUM* pTransportEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrServerTransportDel( /* Function 0x1b */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwLevel,
+ [out] TRANSPORT_INFO* pTransportInfo
+ );
+
+ typedef struct _TIME_OF_DAY {
+ DWORD dwElapsedTime;
+ DWORD dwMsecs;
+ DWORD dwHours;
+ DWORD dwMins;
+ DWORD dwSecs;
+ DWORD dwHunds;
+ LONG lTimeZone;
+ DWORD dwInterval;
+ DWORD dwDay;
+ DWORD dwMonth;
+ DWORD dwYear;
+ DWORD dwWeekday;
+ } TIME_OF_DAY;
+
+ STATUS NetrRemoteTOD( /* Function 0x1c */
+ [in,unique] LPWSTR pszServer,
+ [out] TIME_OF_DAY* pTOD
+ );
+
+ STATUS NetrServerSetServiceBits( /* Function 0x1d */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD hServiceStatus, /* ?? */
+ [in] DWORD dwServiceBits,
+ [in] BOOL bSetBitsOn,
+ [in] BOOL bUpdateImmediately
+ );
+
+ /* --- PATH INFORMATION --- */
+
+ STATUS NetprPathType( /* Function 0x1e */
+ void /* Not known */
+ );
+
+ STATUS NetprPathCanonicalize( /* Function 0x1f */
+ void /* Not known */
+ );
+
+ STATUS NetprPathCompare( /* Function 0x20 */
+ void /* Not known */
+ );
+
+ STATUS NetprNameValidate( /* Function 0x21 */
+ void /* Not known */
+ );
+
+ STATUS NetprNameCanonicalize( /* Function 0x22 */
+ void /* Not known */
+ );
+
+ STATUS NetprNameCompare( /* Function 0x23 */
+ void /* Not known */
+ );
+
+ /* --- LATER ADDITIONS --- */
+
+ STATUS NetrShareEnumSticky( /* Function 0x24 */
+ [in,unique] LPWSTR pszServer,
+ [in,out] SHARE_ENUM* pShareEnum,
+ [in] DWORD dwMaxLen,
+ [out] DWORD* dwEntries,
+ [in,out] DWORD* hResume
+ );
+
+ STATUS NetrShareDelStart( /* Function 0x25 */
+ [in,unique] LPWSTR pszServer,
+ [in,ref] LPWSTR pszShare,
+ [in] DWORD dwReserved /* ? */
+ );
+
+ STATUS NetrShareDelCommit( /* Function 0x26 */
+ [in,unique] LPWSTR pszServer
+ );
+
+ STATUS NetrpGetFileSecurity( /* Function 0x27 */
+ void /* Not known */
+ );
+
+ STATUS NetrpSetFileSecurity( /* Function 0x28 */
+ void /* Not known */
+ );
+
+ STATUS NetrServerTransportAddEx( /* Function 0x29 */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD dwLevel,
+ [out] TRANSPORT_INFO* pTransportInfo
+ );
+
+ STATUS NetrServerSetServiceBitsEx( /* Function 0x30 */
+ [in,unique] LPWSTR pszServer,
+ [in] DWORD hServiceStatus, /* ?? */
+ [in] DWORD dwServiceBits,
+ [in] BOOL bSetBitsOn,
+ [in] BOOL bUpdateImmediately
+ );
+
diff --git a/source3/aparser/template.awk b/source3/aparser/template.awk
new file mode 100644
index 0000000000..2015700835
--- /dev/null
+++ b/source3/aparser/template.awk
@@ -0,0 +1,18 @@
+# template file handling
+
+function print_template(f, tplname, v,
+ LOCAL, i, pat, line)
+{
+ tplname="templates/"tplname;
+ if (numlines(tplname) <= 0) fatal("no template "tplname);
+ while ((getline line < tplname) > 0) {
+ while ((i = match(line,"@[a-zA-Z_]*@")) != 0) {
+ pat=substr(line,i+1,RLENGTH-2);
+ if (v[pat] == "") fatal("no value for "pat" in "tplname);
+ gsub("@"pat"@", v[pat], line);
+ }
+
+ xprintf(f, "%s\n", line);
+ }
+ close(tplname);
+}
diff --git a/source3/aparser/templates/fn_end.tpl b/source3/aparser/templates/fn_end.tpl
new file mode 100644
index 0000000000..2275ec4e33
--- /dev/null
+++ b/source3/aparser/templates/fn_end.tpl
@@ -0,0 +1,13 @@
+
+end:
+ /* the parse is OK */
+ return True;
+
+fail:
+ if (UNMARSHALLING(ps)) {
+ ZERO_STRUCTP(il);
+ }
+ return False;
+} /* @FUNCNAME@ */
+
+
diff --git a/source3/aparser/templates/fn_end0.tpl b/source3/aparser/templates/fn_end0.tpl
new file mode 100644
index 0000000000..6e49a10f53
--- /dev/null
+++ b/source3/aparser/templates/fn_end0.tpl
@@ -0,0 +1,8 @@
+
+end:
+ /* the parse is OK */
+ return True;
+
+} /* @FUNCNAME@ */
+
+
diff --git a/source3/aparser/templates/fn_i_end.tpl b/source3/aparser/templates/fn_i_end.tpl
new file mode 100644
index 0000000000..9de61decb3
--- /dev/null
+++ b/source3/aparser/templates/fn_i_end.tpl
@@ -0,0 +1,12 @@
+
+ /* the parse is OK */
+ return True;
+
+fail:
+ if (UNMARSHALLING(ps)) {
+ ZERO_STRUCTP(il);
+ }
+ return False;
+} /* @FUNCNAME@ */
+
+
diff --git a/source3/aparser/templates/fn_i_start.tpl b/source3/aparser/templates/fn_i_start.tpl
new file mode 100644
index 0000000000..3979d78e7d
--- /dev/null
+++ b/source3/aparser/templates/fn_i_start.tpl
@@ -0,0 +1,15 @@
+/*******************************************************************
+parse a @STRUCTNAME@ structure
+********************************************************************/
+BOOL @FUNCNAME@(char *desc, io_struct *ps, int depth,
+ @STRUCTNAME@ *il, unsigned flags)
+{
+ io_debug(ps, depth, desc, "@FUNCNAME@");
+ depth++;
+
+#if 0
+ if (UNMARSHALLING(ps)) {
+ ZERO_STRUCTP(il);
+ }
+#endif
+ /* parse the scalars */
diff --git a/source3/aparser/templates/fn_mid.tpl b/source3/aparser/templates/fn_mid.tpl
new file mode 100644
index 0000000000..b81de92a5b
--- /dev/null
+++ b/source3/aparser/templates/fn_mid.tpl
@@ -0,0 +1,6 @@
+
+buffers:
+ if (!(flags & PARSE_BUFFERS)) goto end;
+
+ /* now parse the buffers */
+
diff --git a/source3/aparser/templates/fn_start.tpl b/source3/aparser/templates/fn_start.tpl
new file mode 100644
index 0000000000..a5d58767a6
--- /dev/null
+++ b/source3/aparser/templates/fn_start.tpl
@@ -0,0 +1,17 @@
+/*******************************************************************
+parse a @STRUCTNAME@ structure
+********************************************************************/
+BOOL @FUNCNAME@(char *desc, io_struct *ps, int depth,
+ @STRUCTNAME@ *il, unsigned flags)
+{
+ io_debug(ps, depth, desc, "@FUNCNAME@");
+ depth++;
+
+ if (!(flags & PARSE_SCALARS)) goto buffers;
+
+#if 0
+ if (UNMARSHALLING(ps)) {
+ ZERO_STRUCTP(il);
+ }
+#endif
+ /* parse the scalars */
diff --git a/source3/aparser/templates/harness.tpl b/source3/aparser/templates/harness.tpl
new file mode 100644
index 0000000000..27c33c0adc
--- /dev/null
+++ b/source3/aparser/templates/harness.tpl
@@ -0,0 +1,5 @@
+
+ if (strcmp(test,"@TEST@")==0) {
+ @TEST@ il;
+ ret = io_@TEST@("@TEST@", ps, 0, &il, flags);
+ } else
diff --git a/source3/aparser/templates/harness_end.tpl b/source3/aparser/templates/harness_end.tpl
new file mode 100644
index 0000000000..1e15faec16
--- /dev/null
+++ b/source3/aparser/templates/harness_end.tpl
@@ -0,0 +1,7 @@
+ {
+ printf("structure %s not found\n", test);
+ ret = False;
+ }
+
+ return ret;
+}
diff --git a/source3/aparser/templates/harness_start.tpl b/source3/aparser/templates/harness_start.tpl
new file mode 100644
index 0000000000..beba6fc12d
--- /dev/null
+++ b/source3/aparser/templates/harness_start.tpl
@@ -0,0 +1,7 @@
+#include "prs_@MODULE@.c"
+
+static BOOL run_test(char *test, io_struct *ps, int flags)
+{
+ BOOL ret;
+
+
diff --git a/source3/aparser/templates/ifptr_end.tpl b/source3/aparser/templates/ifptr_end.tpl
new file mode 100644
index 0000000000..990635cf45
--- /dev/null
+++ b/source3/aparser/templates/ifptr_end.tpl
@@ -0,0 +1 @@
+ }
diff --git a/source3/aparser/templates/ifptr_start.tpl b/source3/aparser/templates/ifptr_start.tpl
new file mode 100644
index 0000000000..228b84bac9
--- /dev/null
+++ b/source3/aparser/templates/ifptr_start.tpl
@@ -0,0 +1,2 @@
+ if (il->@ELEM@) {
+ if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@)))) goto fail;
diff --git a/source3/aparser/templates/module_end.tpl b/source3/aparser/templates/module_end.tpl
new file mode 100644
index 0000000000..661f7edb95
--- /dev/null
+++ b/source3/aparser/templates/module_end.tpl
@@ -0,0 +1,3 @@
+
+
+/* end auto-generated structure parsers for @MODULE@ */
diff --git a/source3/aparser/templates/module_start.tpl b/source3/aparser/templates/module_start.tpl
new file mode 100644
index 0000000000..ac6a3c9d98
--- /dev/null
+++ b/source3/aparser/templates/module_start.tpl
@@ -0,0 +1,5 @@
+/* auto-generated structure parsers for @MODULE@
+ generated by aparser
+*/
+#include "prs_@MODULE@.h"
+
diff --git a/source3/aparser/templates/prs_.align.tpl b/source3/aparser/templates/prs_.align.tpl
new file mode 100644
index 0000000000..25816a23b3
--- /dev/null
+++ b/source3/aparser/templates/prs_.align.tpl
@@ -0,0 +1 @@
+ if(!io_align(ps)) goto fail;
diff --git a/source3/aparser/templates/prs_align2.tpl b/source3/aparser/templates/prs_align2.tpl
new file mode 100644
index 0000000000..54c569b547
--- /dev/null
+++ b/source3/aparser/templates/prs_align2.tpl
@@ -0,0 +1 @@
+ if (!io_align2(ps, @OFFSET@)) goto fail;
diff --git a/source3/aparser/templates/prs_align4.tpl b/source3/aparser/templates/prs_align4.tpl
new file mode 100644
index 0000000000..702fab1324
--- /dev/null
+++ b/source3/aparser/templates/prs_align4.tpl
@@ -0,0 +1 @@
+ if (!io_align4(ps, @OFFSET@)) goto fail;
diff --git a/source3/aparser/templates/prs_array.tpl b/source3/aparser/templates/prs_array.tpl
new file mode 100644
index 0000000000..4bd6a26c99
--- /dev/null
+++ b/source3/aparser/templates/prs_array.tpl
@@ -0,0 +1,8 @@
+ if ((@FLAGS@ & PARSE_SCALARS) &&
+ !io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(il->@ARRAY_LEN@))) goto fail;
+ {
+ int i;
+ for (i=0;i<il->@ARRAY_LEN@;i++) {
+ if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail;
+ }
+ }
diff --git a/source3/aparser/templates/prs_array_optional.tpl b/source3/aparser/templates/prs_array_optional.tpl
new file mode 100644
index 0000000000..38bd32861f
--- /dev/null
+++ b/source3/aparser/templates/prs_array_optional.tpl
@@ -0,0 +1,5 @@
+ if ((MARSHALLING(ps) && il->@ELEM@) ||
+ ps->data_offset < ps->buffer_size) {
+ if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@)))) goto fail;
+ if (!io_@TYPE@("@ELEM@...", ps, depth+1, il->@ELEM@, @FLAGS@)) goto fail;
+ }
diff --git a/source3/aparser/templates/prs_array_remainder.tpl b/source3/aparser/templates/prs_array_remainder.tpl
new file mode 100644
index 0000000000..c8b1e2ab5a
--- /dev/null
+++ b/source3/aparser/templates/prs_array_remainder.tpl
@@ -0,0 +1,17 @@
+ if (UNMARSHALLING(ps))
+ {
+ int i;
+ for (i=0;ps->data_offset < ps->buffer_size;i++) {
+ if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(i+1))) goto fail;
+ if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail;
+ }
+ }
+ else
+ {
+ int i = -1;
+ /* HACK ALERT! */
+ do {
+ i++;
+ if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail;
+ } while (il->@ELEM@[i].tag2 != 0);
+ }
diff --git a/source3/aparser/templates/prs_break.tpl b/source3/aparser/templates/prs_break.tpl
new file mode 100644
index 0000000000..eb540f7be8
--- /dev/null
+++ b/source3/aparser/templates/prs_break.tpl
@@ -0,0 +1 @@
+ break;
diff --git a/source3/aparser/templates/prs_case.tpl b/source3/aparser/templates/prs_case.tpl
new file mode 100644
index 0000000000..06c1bd3ae6
--- /dev/null
+++ b/source3/aparser/templates/prs_case.tpl
@@ -0,0 +1 @@
+ case @CASE@:
diff --git a/source3/aparser/templates/prs_case_end.tpl b/source3/aparser/templates/prs_case_end.tpl
new file mode 100644
index 0000000000..eb540f7be8
--- /dev/null
+++ b/source3/aparser/templates/prs_case_end.tpl
@@ -0,0 +1 @@
+ break;
diff --git a/source3/aparser/templates/prs_element.tpl b/source3/aparser/templates/prs_element.tpl
new file mode 100644
index 0000000000..e8bf5180ce
--- /dev/null
+++ b/source3/aparser/templates/prs_element.tpl
@@ -0,0 +1 @@
+ if (!io_@TYPE@("@ELEM@", ps, depth+1, @PTR@il->@ELEM@, @FLAGS@)) goto fail;
diff --git a/source3/aparser/templates/prs_pointer.tpl b/source3/aparser/templates/prs_pointer.tpl
new file mode 100644
index 0000000000..4ebcf19d83
--- /dev/null
+++ b/source3/aparser/templates/prs_pointer.tpl
@@ -0,0 +1,2 @@
+ if (!io_pointer("@ELEM@_ptr", ps, depth+1,
+ (void **)&il->@ELEM@, @FLAGS@)) goto fail;
diff --git a/source3/aparser/templates/prs_struct.tpl b/source3/aparser/templates/prs_struct.tpl
new file mode 100644
index 0000000000..ab8246db8e
--- /dev/null
+++ b/source3/aparser/templates/prs_struct.tpl
@@ -0,0 +1 @@
+ if (!@MODULE@_io_@TYPE@("@ELEM@", &il->@ELEM@, ps, depth+1)) goto fail;
diff --git a/source3/aparser/templates/prs_struct_alloc.tpl b/source3/aparser/templates/prs_struct_alloc.tpl
new file mode 100644
index 0000000000..9eae5c92fc
--- /dev/null
+++ b/source3/aparser/templates/prs_struct_alloc.tpl
@@ -0,0 +1 @@
+ if (!@MODULE@_io_@TYPE@_alloc("@ELEM@", &il->@ELEM@, ps, depth+1)) goto fail;
diff --git a/source3/aparser/templates/prs_uint16.tpl b/source3/aparser/templates/prs_uint16.tpl
new file mode 100644
index 0000000000..b40d6d4216
--- /dev/null
+++ b/source3/aparser/templates/prs_uint16.tpl
@@ -0,0 +1 @@
+ if (!io_uint16("@ELEM@", ps, depth+1, &il->@ELEM@)) goto fail;
diff --git a/source3/aparser/templates/prs_uint32.tpl b/source3/aparser/templates/prs_uint32.tpl
new file mode 100644
index 0000000000..eb76715d28
--- /dev/null
+++ b/source3/aparser/templates/prs_uint32.tpl
@@ -0,0 +1 @@
+ if (!io_uint32("@ELEM@", ps, depth+1, &il->@ELEM@)) goto fail;
diff --git a/source3/aparser/templates/prs_uint8s.tpl b/source3/aparser/templates/prs_uint8s.tpl
new file mode 100644
index 0000000000..967162213f
--- /dev/null
+++ b/source3/aparser/templates/prs_uint8s.tpl
@@ -0,0 +1,2 @@
+ if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(il->@ARRAY_LEN@))) goto fail;
+ if (!io_uint8s("@ELEM@", ps, depth+1, &il->@ELEM@, il->@ARRAY_LEN@, @FLAGS@)) goto fail;
diff --git a/source3/aparser/templates/prs_uint8s_fixed.tpl b/source3/aparser/templates/prs_uint8s_fixed.tpl
new file mode 100644
index 0000000000..26597f419f
--- /dev/null
+++ b/source3/aparser/templates/prs_uint8s_fixed.tpl
@@ -0,0 +1 @@
+ if (!io_uint8s_fixed("@ELEM@", ps, depth+1, il->@ELEM@, @ARRAY_LEN@, @FLAGS@)) goto fail;
diff --git a/source3/aparser/templates/prs_wstring.tpl b/source3/aparser/templates/prs_wstring.tpl
new file mode 100644
index 0000000000..4de46f093c
--- /dev/null
+++ b/source3/aparser/templates/prs_wstring.tpl
@@ -0,0 +1,2 @@
+ if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(il->@ARRAY_LEN@))) goto fail;
+ if (!io_wstring("@ELEM@", ps, depth+1, il->@ELEM@, il->@ARRAY_LEN@, @FLAGS@)) goto fail;
diff --git a/source3/aparser/templates/prs_wstring_fixed.tpl b/source3/aparser/templates/prs_wstring_fixed.tpl
new file mode 100644
index 0000000000..e33f7c3d5d
--- /dev/null
+++ b/source3/aparser/templates/prs_wstring_fixed.tpl
@@ -0,0 +1,2 @@
+ if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(@ARRAY_LEN@))) goto fail;
+ if (!io_wstring("@ELEM@", ps, depth+1, il->@ELEM@, @ARRAY_LEN@, @FLAGS@)) goto fail;
diff --git a/source3/aparser/templates/union_end.tpl b/source3/aparser/templates/union_end.tpl
new file mode 100644
index 0000000000..511adbcf60
--- /dev/null
+++ b/source3/aparser/templates/union_end.tpl
@@ -0,0 +1,5 @@
+ default:
+ DEBUG(5,("No handler for case %d in @FUNCNAME@\n",
+ (int)il->@SWITCH@));
+ goto fail;
+ }
diff --git a/source3/aparser/templates/union_start.tpl b/source3/aparser/templates/union_start.tpl
new file mode 100644
index 0000000000..aa052be697
--- /dev/null
+++ b/source3/aparser/templates/union_start.tpl
@@ -0,0 +1 @@
+ switch (il->@SWITCH@) {
diff --git a/source3/aparser/token.awk b/source3/aparser/token.awk
new file mode 100644
index 0000000000..fb2982f077
--- /dev/null
+++ b/source3/aparser/token.awk
@@ -0,0 +1,180 @@
+# tokenise the input file
+
+function parse_error(msg) {
+ printf("PARSE ERROR: %s\nLine "NR" : "$0"\n", msg);
+ exit 1;
+}
+
+# ignore multi-line C comments.
+{
+ if (t = index($0, "/*")) {
+ if (t > 1)
+ tmp = substr($0, 1, t - 1)
+ else
+ tmp = ""
+ u = index(substr($0, t + 2), "*/")
+ while (u == 0) {
+ getline
+ t = -1
+ u = index($0, "*/")
+ }
+ if (u <= length($0) - 2)
+ $0 = tmp substr($0, t + u + 3)
+ else
+ $0 = tmp
+ }
+}
+
+# ignore blank lines
+/^[ \t]*$/ {
+ next;
+}
+
+/^\#define.*/ {
+ split($0,a,"[ \t;]*");
+ parse_define(a[2], a[3]);
+ next;
+}
+
+# ignore comments
+/^[ \t]*\#/ {
+ next;
+}
+
+/^[ \t]*module/ {
+ {if (module!="") parse_error("you can only specify one module name");}
+ start_module($2);
+ next;
+}
+
+{if (module=="") parse_error("you must specify the module name first");}
+
+/^[ \t]*option/ {
+ set_option($2, $3);
+ next;
+}
+
+/^[ \t]*typedef struct.*\{/ {
+ {if (current_struct!="") parse_error("you cannot have nested structures");}
+ start_struct($3);
+ next;
+}
+
+/^[ \t]*struct.*\{/ {
+ {if (current_struct!="") parse_error("you cannot have nested structures");}
+ start_struct($2);
+ next;
+}
+
+/^[ \t]*typedef union.*\{/ {
+ {if (current_struct!="") parse_error("this cannot appear inside a structure");}
+ split($0,a,"[ \t;()]*");
+ start_union_encap(a[4], a[6], a[7], a[8]);
+ next;
+}
+
+/^[ \t]*void.*\(/ {
+ {if (current_struct!="") parse_error("you cannot have nested structures");}
+ split($0,a,"[ \t;()]*");
+ start_function(a[2], a[3]);
+ return_result="void";
+ next;
+}
+
+/^[ \t]*STATUS.*\(|^[ \t]*void.*\(/ {
+ {if (current_struct!="") parse_error("you cannot have nested structures");}
+ split($0,a,"[ \t;()]*");
+ start_function(a[2], a[3]);
+ return_result="STATUS";
+ next;
+}
+
+{if (current_struct=="") parse_error("this must appear inside a structure");}
+
+/^[ \t]*union.*\{/ {
+ {if (current_union!="") parse_error("you cannot have nested unions");}
+ start_union($2);
+ next;
+}
+
+/^[ \t]*\[switch_is.*union.*\{/ {
+ {if (current_union!="") parse_error("you cannot have nested unions");}
+ split($0,a,"[ \t;()]*");
+ start_union_notencap(a[3]);
+ next;
+}
+
+/^[ \t]*case.*;/ {
+ {if (current_union=="") parse_error("this must appear inide a union");}
+ split($0,a,"[ \t;]*");
+ parse_case(a[3],a[4],a[5]);
+ next;
+}
+
+/^[ \t]*\[case(.*)\].*;/ {
+ {if (current_union=="") parse_error("this must appear inide a union");}
+ split($0,a,"[ \t;()[\]]*");
+ parse_case(a[6],a[8],a[9]);
+ next;
+}
+
+/^[ \t]*\}$/ {
+ {if (current_union=="") parse_error("this must appear inside a union");}
+ end_union("");
+ next;
+}
+
+/^[ \t]*\} .*;/ {
+ if (current_union!="") {
+ split($2,a,"[ \t;]*");
+ end_union(a[1]);
+ next;
+ }
+}
+
+{if (current_union!="") parse_error("this cannot appear inside a union");}
+
+/^[ \t]*\};/ {
+ end_struct("");
+ next;
+}
+
+/^[ \t]*\} .*;/ {
+ split($2,a,"[ \t;]*");
+ end_struct(a[1]);
+ next;
+}
+
+/^[ \t]*\);/ {
+ end_function();
+ return_result="";
+ next;
+}
+
+/^.*size_is.*\*.*;/ {
+ split($0,a,"[ \t;()]*");
+ add_sizeis_array(a[3], a[5], a[6]);
+ next;
+}
+
+/^.*;/ {
+ split($0,a,"[ \t;]*");
+ add_struct_elem(a[2], a[3]);
+ next;
+}
+
+/^[\t ]*void/ {
+ next;
+}
+
+/^[ \t]*\[.*\].*/ {
+ split($0,a,"[ \t;]*");
+ split(a[4], b, "[,]");
+ add_function_param(a[2], a[3], b[1]);
+ next;
+}
+
+{
+ parse_error("Unknown construct.");
+}
+
diff --git a/source3/aparser/util.awk b/source3/aparser/util.awk
new file mode 100644
index 0000000000..6c5594da68
--- /dev/null
+++ b/source3/aparser/util.awk
@@ -0,0 +1,39 @@
+function isaptr(elem)
+{
+ if (substr(elem, 1, 1) == "*") {
+ return 1;
+ }
+ return 0;
+}
+
+function noptr(elem)
+{
+ if (!isaptr(elem)) return elem;
+ return substr(elem, 2);
+}
+
+function xprintf(f, fmt, v1, v2, v3, v4, v5, v6, v7)
+{
+ printf(fmt, v1, v2, v3, v4, v5, v6) > f;
+}
+
+function fatal(why)
+{
+ printf("FATAL: %s\n", why);
+ exit 1;
+}
+
+function numlines(fname,
+ LOCAL, line, count)
+{
+ count=0;
+ while ((getline line < fname) > 0) count++;
+ close(fname);
+ return count;
+}
+
+# return 1 if the string is a constant
+function is_constant(s)
+{
+ return match(s,"^[0-9]+$");
+}
diff --git a/source3/aparser/util.c b/source3/aparser/util.c
new file mode 100644
index 0000000000..ffa84dbfab
--- /dev/null
+++ b/source3/aparser/util.c
@@ -0,0 +1,112 @@
+#include "parser.h"
+
+
+/*******************************************************************
+ Count the number of characters (not bytes) in a unicode string.
+********************************************************************/
+size_t strlen_w(void *src)
+{
+ size_t len;
+
+ for (len = 0; SVAL(src, len*2); len++) ;
+
+ return len;
+}
+
+/****************************************************************************
+expand a pointer to be a particular size
+****************************************************************************/
+void *Realloc(void *p,size_t size)
+{
+ void *ret=NULL;
+
+ if (size == 0) {
+ if (p) free(p);
+ DEBUG(5,("Realloc asked for 0 bytes\n"));
+ return NULL;
+ }
+
+ if (!p)
+ ret = (void *)malloc(size);
+ else
+ ret = (void *)realloc(p,size);
+
+ if (!ret)
+ DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
+
+ return(ret);
+}
+
+
+char *tab_depth(int depth)
+{
+ static pstring spaces;
+ memset(spaces, ' ', depth * 4);
+ spaces[depth * 4] = 0;
+ return spaces;
+}
+
+void print_asc(int level, uchar const *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ DEBUGADD(level, ("%c", isprint(buf[i]) ? buf[i] : '.'));
+ }
+}
+
+void dump_data(int level, char *buf1, int len)
+{
+ uchar const *buf = (uchar const *)buf1;
+ int i = 0;
+ if (buf == NULL)
+ {
+ DEBUG(level, ("dump_data: NULL, len=%d\n", len));
+ return;
+ }
+ if (len < 0)
+ return;
+ if (len == 0)
+ {
+ DEBUG(level, ("\n"));
+ return;
+ }
+
+ DEBUG(level, ("[%03X] ", i));
+ for (i = 0; i < len;)
+ {
+ DEBUGADD(level, ("%02X ", (int)buf[i]));
+ i++;
+ if (i % 8 == 0)
+ DEBUGADD(level, (" "));
+ if (i % 16 == 0)
+ {
+ print_asc(level, &buf[i - 16], 8);
+ DEBUGADD(level, (" "));
+ print_asc(level, &buf[i - 8], 8);
+ DEBUGADD(level, ("\n"));
+ if (i < len)
+ DEBUGADD(level, ("[%03X] ", i));
+ }
+ }
+
+ if (i % 16 != 0) /* finish off a non-16-char-length row */
+ {
+ int n;
+
+ n = 16 - (i % 16);
+ DEBUGADD(level, (" "));
+ if (n > 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
new file mode 100644
index 0000000000..d3868f2753
--- /dev/null
+++ b/source3/aparser/vluke.c
@@ -0,0 +1,41 @@
+#include "parser.h"
+#include "test.h"
+
+int main(int argc, char *argv[])
+{
+ BOOL ret;
+ char *fname, *test;
+ int fd;
+ struct stat st;
+ io_struct ps;
+
+ if (argc < 3) {
+ printf("usage: vluke <structure> <file>\n");
+ exit(1);
+ }
+
+ test = argv[1];
+ fname = argv[2];
+
+ fd = open(fname,O_RDONLY);
+ if (fd == -1) {
+ perror(fname);
+ exit(1);
+ }
+ fstat(fd, &st);
+
+ io_init(&ps, 0, MARSHALL);
+ ps.is_dynamic=True;
+ io_read(&ps, fd, st.st_size, 0);
+ 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);
+ if (ps.grow_size - ps.data_offset > 0) {
+ dump_data(0, ps.data_p + ps.data_offset, ps.grow_size - ps.data_offset);
+ }
+ return !ret;
+}