summaryrefslogtreecommitdiff
path: root/source4/pidl/lib/Parse/Pidl/Samba3
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-10-03 23:27:33 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:39:20 -0500
commitf9a416743401121e1bc2961402cd6f87de68ca00 (patch)
treec5b83bc137b130022159934b22a90227da0ae67b /source4/pidl/lib/Parse/Pidl/Samba3
parent012893cb421d77efc538c9f4c78b2421aef3f06e (diff)
downloadsamba-f9a416743401121e1bc2961402cd6f87de68ca00.tar.gz
samba-f9a416743401121e1bc2961402cd6f87de68ca00.tar.bz2
samba-f9a416743401121e1bc2961402cd6f87de68ca00.zip
r10694: Add some work I did this afternoon on getting pidl to output Samba3
RPC parsers. Currently the following files can be generated: - include/rpc_BASENAME.h - rpc_server/srv_BASENAME.c - rpc_server/srv_BASENAME_nt.c (template only, user has to fill in functions) - rpc_client/cli_BASENAME.c - rpc_parse/parse_BASENAME.c So far, I have been working on getting DFS working. Currently still to do (all in rpc_parse/parse_BASENAME.c): - Proper handling of declarations - Proper handling of scalar/buffer parts of structs and unions - Subcontexts - Proper handling of arrays - Support for custom (non-scalar) types I hope to have a somewhat more working version later this week. Some files as currently generated are available from: http://samba.org/~jelmer/pidl_samba3/ (This used to be commit 8af8eaeeef6d46f4d25ccb1d25890e1eef063e4f)
Diffstat (limited to 'source4/pidl/lib/Parse/Pidl/Samba3')
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Client.pm104
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Header.pm160
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm269
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Server.pm115
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Template.pm66
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/Util.pm29
6 files changed, 743 insertions, 0 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm
new file mode 100644
index 0000000000..59d048176f
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/Client.pm
@@ -0,0 +1,104 @@
+###################################################
+# Samba3 NDR client generator for IDL structures
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::Client;
+
+use strict;
+use Parse::Pidl::Typelist qw(hasType getType mapType);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+use Parse::Pidl::Samba3::Util qw(MapSamba3Type);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+my $res = "";
+my $tabs = "";
+sub indent() { $tabs.="\t"; }
+sub deindent() { $tabs = substr($tabs, 1); }
+sub pidl($) { $res .= $tabs.(shift)."\n"; }
+sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
+
+sub ParseFunction($$)
+{
+ my ($if,$fn) = @_;
+
+ my $args = "";
+ my $defargs = "";
+ foreach (@{$fn->{ELEMENTS}}) {
+ $defargs .= ", " . MapSamba3Type($_);
+ $args .= ", $_->{NAME}";
+ }
+
+ my $uif = uc($if->{NAME});
+ my $ufn = uc($fn->{NAME});
+
+ pidl "NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)";
+ pidl "{";
+ indent;
+ pidl "prs_struct qbuf, rbuf;";
+ pidl "$uif\_Q_$ufn q;";
+ pidl "$uif\_R_$ufn r;";
+ pidl "";
+ pidl "ZERO_STRUCT(q);";
+ pidl "ZERO_STRUCT(r);";
+ pidl "";
+ pidl "/* Marshall data and send request */";
+ pidl "";
+ pidl "init_$if->{NAME}_q_$fn->{NAME}(&q$args);";
+ pidl "";
+ pidl "CLI_DO_RPC(cli, mem_ctx, PI_$uif, $ufn,";
+ pidl "\tq, r,";
+ pidl "\tqbuf, rbuf, ";
+ pidl "\t$if->{NAME}_q_$fn->{NAME},";
+ pidl "\t$if->{NAME}_r_$fn->{NAME},";
+ pidl "\tNT_STATUS_UNSUCCESSFUL);";
+ pidl "";
+ pidl "/* Return result */";
+ if (not $fn->{RETURN_TYPE}) {
+ pidl "return NT_STATUS_OK;";
+ } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
+ pidl "return r.status;";
+ } elsif ($fn->{RETURN_TYPE} eq "WERROR") {
+ pidl "return werror_to_ntstatus(r.status);";
+ } else {
+ pidl "/* Sorry, don't know how to convert $fn->{RETURN_TYPE} to NTSTATUS */";
+ pidl "return NT_STATUS_OK;";
+ }
+
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
+sub ParseInterface($)
+{
+ my $if = shift;
+
+ ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
+}
+
+sub Parse($$)
+{
+ my($ndr,$filename) = @_;
+
+ $res = "";
+
+ pidl "/*";
+ pidl " * Unix SMB/CIFS implementation.";
+ pidl " * client auto-generated by pidl. DO NOT MODIFY!";
+ pidl " */";
+ pidl "";
+ pidl "#include \"includes.h\"";
+ pidl "";
+
+ foreach (@$ndr) {
+ ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
+ }
+
+ return $res;
+}
+
+1;
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm
new file mode 100644
index 0000000000..be7f1ca5c4
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm
@@ -0,0 +1,160 @@
+###################################################
+# Samba3 NDR header generator for IDL structures
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::Header;
+
+use strict;
+use Parse::Pidl::Typelist qw(hasType getType);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+use Parse::Pidl::Samba3::Util qw(MapSamba3Type);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+my $res = "";
+sub pidl($) { my $x = shift; $res .= "$x\n"; }
+sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
+
+sub CreateStruct($$$$)
+{
+ my ($if,$fn,$n,$t) = @_;
+
+ pidl "typedef struct $n {";
+ foreach my $e (@$t) {
+ foreach my $l (@{$e->{LEVELS}}) {
+ if ($l->{TYPE} eq "POINTER") {
+ return if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "top");
+ pidl "\tuint32 ptr_$e->{NAME};";
+ } elsif ($l->{TYPE} eq "SWITCH") {
+ pidl "\tuint32 level_$e->{NAME};";
+ } elsif ($l->{TYPE} eq "DATA") {
+ pidl "\t" . MapSamba3Type($e) . ";";
+ }
+ }
+ }
+
+ if (not @$t) {
+ # Some compilers don't like empty structs
+ pidl "\tuint32 dummy;";
+ }
+
+ pidl "} " . uc($n) . ";";
+ pidl "";
+}
+
+sub ParseFunction($$)
+{
+ my ($if,$fn) = @_;
+
+ my @in = ();
+ my @out = ();
+
+ foreach (@{$_->{ELEMENTS}}) {
+ push (@in, $_) if (grep(/in/, @{$_->{DIRECTION}}));
+ push (@out, $_) if (grep(/out/, @{$_->{DIRECTION}}));
+ }
+
+ if (defined($fn->{RETURN_TYPE})) {
+ push (@out, {
+ NAME => "status",
+ TYPE => $fn->{RETURN_TYPE},
+ LEVELS => [
+ {
+ TYPE => "DATA",
+ DATA_TYPE => $fn->{RETURN_TYPE}
+ }
+ ]
+ } );
+ }
+
+ # define Q + R structures for functions
+
+ CreateStruct($if, $fn, "$if->{NAME}_q_$fn->{NAME}", \@in);
+ CreateStruct($if, $fn, "$if->{NAME}_r_$fn->{NAME}", \@out);
+}
+
+sub ParseStruct($$$)
+{
+ my ($if,$s,$n) = @_;
+
+ CreateStruct($if, $s, "$if->{NAME}_$n", $s->{ELEMENTS});
+}
+
+sub ParseEnum($$$)
+{
+ my ($if,$s,$n) = @_;
+
+ pidl "typedef enum {";
+
+ foreach (@{$s->{ELEMENTS}}) {
+ pidl "$_,";
+ }
+
+ pidl "} $n;";
+}
+
+sub ParseBitmap($$$)
+{
+ my ($if,$s,$n) = @_;
+
+ pidl "#define $_" foreach (@{$s->{ELEMENTS}});
+}
+
+sub ParseInterface($)
+{
+ my $if = shift;
+
+ my $def = "_RPC_" . uc($if->{NAME}) . "_H";
+
+ pidl "";
+
+ pidl "\#ifndef $def";
+ pidl "\#define $def";
+
+ pidl "";
+
+ foreach (@{$if->{FUNCTIONS}}) {
+ pidl "\#define " . uc($_->{NAME}) . " $_->{OPNUM}" ;
+ }
+
+ pidl "";
+
+ ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
+
+ foreach (@{$if->{TYPEDEFS}}) {
+ ParseStruct($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "STRUCT");
+ ParseEnum($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "ENUM");
+ ParseBitmap($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "BITMAP");
+ fatal($_, "Unions not supported for Samba3 yet") if ($_->{TYPE} eq "STRUCT");
+ }
+
+ foreach (@{$if->{CONSTS}}) {
+ pidl "$_->{NAME} ($_->{VALUE})";
+ }
+
+ pidl "\#endif /* $def */";
+}
+
+sub Parse($$)
+{
+ my($ndr,$filename) = @_;
+
+ $res = "";
+
+ pidl "/*";
+ pidl " * Unix SMB/CIFS implementation.";
+ pidl " * header auto-generated by pidl. DO NOT MODIFY!";
+ pidl " */";
+ pidl "";
+
+ # Loop over interfaces
+ foreach (@{$ndr}) {
+ ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
+ }
+ return $res;
+}
+
+1;
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm
new file mode 100644
index 0000000000..8518537ddb
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/Parser.pm
@@ -0,0 +1,269 @@
+###################################################
+# Samba3 NDR parser generator for IDL structures
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::Parser;
+
+use strict;
+use Parse::Pidl::Typelist qw(hasType getType mapType);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+use Parse::Pidl::Samba3::Util qw(MapSamba3Type);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+my $res = "";
+my $tabs = "";
+sub indent() { $tabs.="\t"; }
+sub deindent() { $tabs = substr($tabs, 1); }
+sub pidl($) { $res .= $tabs.(shift)."\n"; }
+sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
+
+sub ParseElementLevelData($$$$$)
+{
+ my ($e,$l,$nl,$env,$varname) = @_;
+
+ #FIXME: This only works for scalar types
+ pidl "if (!prs_$l->{DATA_TYPE}(\"$e->{NAME}\", ps, depth, &$varname))";
+ pidl "\treturn False;";
+ pidl "";
+}
+
+sub ParseElementLevelArray($$$$$)
+{
+ my ($e,$l,$nl,$env,$varname) = @_;
+
+ #FIXME
+ pidl "for (i=0; i<".ParseExpr("length_$e->{NAME}", $env) .";i++) {";
+ indent;
+ ParseElementLevel($e,$nl,$env,"$varname\[i]");
+ deindent;
+ pidl "}";
+}
+
+sub ParseElementLevelSwitch($$$$$)
+{
+ my ($e,$l,$nl,$env,$varname) = @_;
+
+ pidl "if (!prs_uint32(\"level\", ps, depth, " . ParseExpr("level_$e->{NAME}", $env) . ", ps, depth))";
+ pidl "\treturn False;";
+ pidl "";
+
+ ParseElementLevel($e,$nl,$env,$varname);
+}
+
+sub ParseElementLevelPtr($$$$$)
+{
+ my ($e,$l,$nl,$env,$varname) = @_;
+
+ # No top-level ref pointers for Samba 3
+ return if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP");
+
+ pidl "if (!prs_uint32(\"ptr_$e->{NAME}\",ps,depth,&" . ParseExpr("ptr_$e->{NAME}", $env) . ", ps, depth))";
+ pidl "\treturn False;";
+ pidl "";
+
+ pidl "if (" . ParseExpr("ptr_$e->{NAME}", $env) . ") {";
+ indent;
+ ParseElementLevel($e,$nl,$env,$varname);
+ deindent;
+ pidl "}";
+}
+
+sub ParseElementLevelSubcontext($$$$$)
+{
+ my ($e,$l,$nl,$env,$varname) = @_;
+
+ fatal($e, "subcontext() not supported for Samba 3");
+}
+
+sub ParseElementLevel($$$$)
+{
+ my ($e,$l,$env,$varname) = @_;
+
+ {
+ DATA => \&ParseElementLevelData,
+ SUBCONTEXT => \&ParseElementLevelSubcontext,
+ POINTER => \&ParseElementLevelPtr,
+ SWITCH => \&ParseElementLevelSwitch,
+ ARRAY => \&ParseElementLevelArray
+ }->{$l->{TYPE}}->($e,$l,GetNextLevel($e,$l),$env,$varname);
+}
+
+sub ParseElement($$)
+{
+ my ($e,$env) = @_;
+
+ ParseElementLevel($e, $e->{LEVELS}[0], $env, ParseExpr($e->{NAME}, $env));
+}
+
+sub CreateStruct($$$)
+{
+ my ($fn,$s,$es) = @_;
+
+ my $args = "";
+ foreach my $e (@$es) {
+ $args .= ", " . MapSamba3Type($_);
+ }
+
+ pidl "BOOL init_$fn($s *v$args)";
+ pidl "{";
+ indent;
+ pidl "DEBUG(5,(\"init_$fn\\n\"));";
+ # Call init for all arguments
+ foreach my $e (@$es) {
+ foreach my $l (@{$e->{LEVELS}}) {
+ #FIXME
+ }
+ }
+ pidl "return True;";
+ deindent;
+ pidl "}";
+ pidl "";
+
+ pidl "BOOL $fn(const char *desc, $s *v, prs_struct *ps, int depth)";
+ pidl "{";
+ indent;
+ pidl "if (v == NULL)";
+ pidl "\treturn False;";
+ pidl "";
+ pidl "prs_debug(ps, depth, desc, \"$fn\");";
+ pidl "depth++;";
+ pidl "if (!prs_align(ps))";
+ pidl "\treturn False;";
+ pidl "";
+
+ my $env = {};
+ foreach my $e (@$es) {
+ foreach my $l (@{$e->{LEVELS}}) {
+ if ($l->{TYPE} eq "DATA") {
+ $env->{"$e->{NAME}"} = $e->{"v->$e->{NAME}"};
+ } elsif ($l->{TYPE} eq "POINTER") {
+ $env->{"ptr_$e->{NAME}"} = $e->{"v->ptr_$e->{NAME}"};
+ } elsif ($l->{TYPE} eq "SWITCH") {
+ $env->{"level_$e->{NAME}"} = $e->{"v->level_$e->{NAME}"};
+ }
+ }
+ }
+
+ ParseElement($_, $env) foreach (@$es);
+
+ pidl "return True;";
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
+sub ParseStruct($$$)
+{
+ my ($if,$s,$n) = @_;
+
+ my $fn = "$if->{NAME}_io_$n";
+ my $sn = uc("$if->{NAME}_$n");
+
+ CreateStruct($fn, $sn, $s->{ELEMENTS});
+}
+
+sub ParseUnion($$$)
+{
+ my ($if,$u,$n) = @_;
+
+ my $fn = "$if->{NAME}_io_$n";
+ my $sn = uc("$if->{NAME}_$n");
+
+ pidl "BOOL $fn(const char *desc, $sn* v, uint32 level, prs_struct *ps, int depth)";
+ pidl "{";
+ indent;
+ pidl "switch (level) {";
+ indent;
+
+ foreach (@{$u->{ELEMENTS}}) {
+ pidl "$_->{CASE}:";
+ indent;
+ pidl "depth++;";
+ ParseElement($_, {});
+ deindent;
+ pidl "depth--;";
+ pidl "break";
+ }
+
+ deindent;
+ pidl "}";
+ pidl "";
+ pidl "return True;";
+ deindent;
+ pidl "}";
+}
+
+sub ParseFunction($$)
+{
+ my ($if,$fn) = @_;
+
+ my @in = ();
+ my @out = ();
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ push (@in, $_) if (grep(/in/, @{$_->{DIRECTION}}));
+ push (@out, $_) if (grep(/out/, @{$_->{DIRECTION}}));
+ }
+
+ if (defined($fn->{RETURN_TYPE})) {
+ push (@out, {
+ NAME => "status",
+ TYPE => $fn->{RETURN_TYPE},
+ LEVELS => [
+ {
+ TYPE => "DATA",
+ DATA_TYPE => $fn->{RETURN_TYPE}
+ }
+ ]
+ } );
+ }
+
+ CreateStruct("$if->{NAME}_io_q_$fn->{NAME}", uc("$if->{NAME}_q_$fn->{NAME}"), \@in);
+ CreateStruct("$if->{NAME}_io_r_$fn->{NAME}", uc("$if->{NAME}_r_$fn->{NAME}"), \@out);
+}
+
+sub ParseInterface($)
+{
+ my $if = shift;
+
+ # Structures first
+ pidl "/* $if->{NAME} structures */";
+ foreach (@{$if->{TYPEDEFS}}) {
+ ParseStruct($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "STRUCT");
+ ParseUnion($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "UNION");
+ }
+
+ pidl "/* $if->{NAME} functions */";
+ ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
+}
+
+sub Parse($$)
+{
+ my($ndr,$filename) = @_;
+
+ $tabs = "";
+ $res = "";
+
+ pidl "/*";
+ pidl " * Unix SMB/CIFS implementation.";
+ pidl " * parser auto-generated by pidl. DO NOT MODIFY!";
+ pidl " */";
+ pidl "";
+ pidl "#include \"includes.h\"";
+ pidl "";
+ pidl "#undef DBGC_CLASS";
+ pidl "#define DBGC_CLASS DBGC_RPC_PARSE";
+ pidl "";
+
+ foreach (@$ndr) {
+ ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
+ }
+
+ return $res;
+}
+
+1;
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Server.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Server.pm
new file mode 100644
index 0000000000..0372cf1117
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/Server.pm
@@ -0,0 +1,115 @@
+###################################################
+# Samba3 NDR server generator for IDL structures
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::Server;
+
+use strict;
+use Parse::Pidl::Typelist qw(hasType getType mapType);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+
+my $res = "";
+my $tabs = "";
+
+sub indent() { $tabs.="\t"; }
+sub deindent() { $tabs = substr($tabs, 1); }
+sub pidl($) { $res .= $tabs.(shift)."\n"; }
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+sub ParseFunction($$)
+{
+ my ($if,$fn) = @_;
+
+ pidl "/******************************************************************";
+ pidl " api_$fn->{NAME}";
+ pidl " *****************************************************************/";
+ pidl "";
+ pidl "static BOOL api_$fn->{NAME}(pipes_struct *p)";
+ pidl "{";
+ indent;
+ pidl uc("$if->{NAME}_q_$fn->{NAME}") . " q_u;";
+ pidl uc("$if->{NAME}_r_$fn->{NAME}") . " r_u;";
+ pidl "prs_struct *data = &p->in_data.data";
+ pidl "prs_struct *rdata = &p->out_data.rdata";
+ pidl "";
+ pidl "if (!$if->{NAME}_io_q_$fn->{NAME}(\"\", &q_u, data, 0))";
+ pidl "\treturn False;";
+ pidl "";
+ pidl "r_u.status = _$fn->{NAME}(p, &q_u, &r_u);";
+ pidl "";
+ pidl "if (!$if->{NAME}_io_r_$fn->{NAME}(\"\", &r_u, rdata, 0))";
+ pidl "\treturn False;";
+ pidl "";
+ pidl "return True;";
+ deindent;
+ pidl "}";
+}
+
+sub ParseInterface($)
+{
+ my $if = shift;
+
+ ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
+
+ pidl "";
+ pidl "/* Tables */";
+ pidl "static struct api_struct api_$if->{NAME}_cmds[] = ";
+ pidl "{";
+ indent;
+ foreach (@{$if->{FUNCTIONS}}) {
+ pidl "{\"" . uc($_->{NAME}) . "\", " . uc($_->{NAME}) . ", api_$_->{NAME}},";
+ }
+ deindent;
+ pidl "};";
+
+ pidl "";
+
+ pidl "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns)";
+ pidl "{";
+ indent;
+ pidl "*fns = api_$if->{NAME}_cmds;";
+ pidl "*n_fns = sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct);";
+ deindent;
+ pidl "}";
+
+ pidl "";
+
+ pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
+ pidl "{";
+ indent;
+ pidl "return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
+ deindent;
+ pidl "}";
+}
+
+sub Parse($$)
+{
+ my($ndr,$filename) = @_;
+
+ $tabs = "";
+ $res = "";
+
+ pidl "/*";
+ pidl " * Unix SMB/CIFS implementation.";
+ pidl " * server auto-generated by pidl. DO NOT MODIFY!";
+ pidl " */";
+ pidl "";
+ pidl "#include \"includes.h\"";
+ pidl "#include \"nterr.h\"";
+ pidl "";
+ pidl "#undef DBGC_CLASS";
+ pidl "#define DBGC_CLASS DBGC_RPC";
+ pidl "";
+
+ foreach (@$ndr) {
+ ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
+ }
+
+ return $res;
+}
+
+1;
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Template.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Template.pm
new file mode 100644
index 0000000000..072aa07850
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/Template.pm
@@ -0,0 +1,66 @@
+###################################################
+# Samba3 NDR client generator for IDL structures
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::Template;
+
+use strict;
+use Parse::Pidl::Typelist qw(hasType getType mapType);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+my $res;
+sub pidl($) { my $x = shift; $res.="$x\n"; }
+
+sub ParseInterface($)
+{
+ my $if = shift;
+
+ foreach (@{$if->{FUNCTIONS}}) {
+ my $ret = $_->{RETURN_TYPE};
+ if (not $ret) { $ret = "void"; }
+ pidl "$ret _$_->{NAME}(pipes_struct *p, " . uc($if->{NAME}) . "_Q_" . uc($_->{NAME}) . " *q_u, " . uc($if->{NAME}) . "_R_" . uc($_->{NAME}) . " *r_u)";
+ pidl "{";
+ pidl "\t/* FIXME: Implement your code here */";
+ if (not defined($_->{RETURN_TYPE})) {
+ } elsif ($_->{RETURN_TYPE} eq "WERROR") {
+ pidl "\treturn WERR_NOT_SUPPORTED;";
+ } elsif ($_->{RETURN_TYPE} eq "NTSTATUS") {
+ pidl "\treturn NT_STATUS_NOT_IMPLEMENTED;";
+ } elsif ($_->{RETURN_TYPE} eq "uint32") {
+ pidl "\treturn 0;";
+ }
+ pidl "}";
+ pidl "";
+ }
+}
+
+sub Parse($$)
+{
+ my($ndr,$filename) = @_;
+
+ $res = "";
+
+ pidl "/*";
+ pidl " * Unix SMB/CIFS implementation.";
+ pidl " * template auto-generated by pidl. Modify to your needs";
+ pidl " */";
+ pidl "";
+ pidl "#include \"includes.h\"";
+ pidl "";
+ pidl "#undef DBGC_CLASS";
+ pidl "#define DBGC_CLASS DBGC_MSRPC";
+ pidl "";
+
+ foreach (@$ndr) {
+ ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
+ }
+
+ return $res;
+}
+
+1;
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Util.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Util.pm
new file mode 100644
index 0000000000..2d4179df76
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/Util.pm
@@ -0,0 +1,29 @@
+###################################################
+# Samba3 common helper functions
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::Util;
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(MapSamba3Type);
+
+use strict;
+use Parse::Pidl::Typelist qw(hasType getType mapType);
+use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+sub MapSamba3Type($)
+{
+ my $e = shift;
+
+ return "UNISTR2 $e->{NAME}" if ($e->{TYPE} eq "string");
+
+ return "$e->{TYPE} $e->{NAME}";
+}
+
+1;