summaryrefslogtreecommitdiff
path: root/source4/pidl
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
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')
-rw-r--r--source4/pidl/lib/Parse/Pidl/Ethereal/NDR.pm6
-rw-r--r--source4/pidl/lib/Parse/Pidl/NDR.pm33
-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
-rw-r--r--source4/pidl/lib/Parse/Pidl/Typelist.pm38
-rwxr-xr-xsource4/pidl/pidl78
10 files changed, 856 insertions, 42 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Ethereal/NDR.pm b/source4/pidl/lib/Parse/Pidl/Ethereal/NDR.pm
index 8441ea25b9..b497f87403 100644
--- a/source4/pidl/lib/Parse/Pidl/Ethereal/NDR.pm
+++ b/source4/pidl/lib/Parse/Pidl/Ethereal/NDR.pm
@@ -485,6 +485,8 @@ sub Union($$$)
$res.="\t\tbreak;\n";
}
+ my $switch_type = $e->{SWITCH_TYPE};
+
pidl_code "static int";
pidl_code "$dissectorname(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_)";
pidl_code "{";
@@ -492,7 +494,7 @@ sub Union($$$)
pidl_code "proto_item *item = NULL;";
pidl_code "proto_tree *tree = NULL;";
pidl_code "int old_offset;";
- pidl_code "g$e->{SWITCH_TYPE} level;";
+ pidl_code "g$switch_type level;";
pidl_code "";
if ($e->{ALIGN} > 1) {
@@ -511,7 +513,7 @@ sub Union($$$)
pidl_code "";
- pidl_code "offset = dissect_ndr_$e->{SWITCH_TYPE}(tvb, offset, pinfo, tree, drep, hf_index, &level);";
+ pidl_code "offset = dissect_ndr_$switch_type(tvb, offset, pinfo, tree, drep, hf_index, &level);";
pidl_code "switch(level) {$res\t}";
pidl_code "proto_item_set_len(item, offset-old_offset);\n";
diff --git a/source4/pidl/lib/Parse/Pidl/NDR.pm b/source4/pidl/lib/Parse/Pidl/NDR.pm
index 42c9fd133b..6bb92a3b50 100644
--- a/source4/pidl/lib/Parse/Pidl/NDR.pm
+++ b/source4/pidl/lib/Parse/Pidl/NDR.pm
@@ -17,6 +17,37 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType);
use Parse::Pidl::Util qw(has_property property_matches);
+# Alignment of the built-in scalar types
+my $scalar_alignment = {
+ 'void' => 0,
+ 'char' => 1,
+ 'int8' => 1,
+ 'uint8' => 1,
+ 'int16' => 2,
+ 'uint16' => 2,
+ 'int32' => 4,
+ 'uint32' => 4,
+ 'hyper' => 8,
+ 'dlong' => 4,
+ 'udlong' => 4,
+ 'udlongr' => 4,
+ 'DATA_BLOB' => 4,
+ 'string' => 4,
+ 'string_array' => 4, #???
+ 'time_t' => 4,
+ 'NTTIME' => 4,
+ 'NTTIME_1sec' => 4,
+ 'NTTIME_hyper' => 8,
+ 'WERROR' => 4,
+ 'NTSTATUS' => 4,
+ 'COMRESULT' => 4,
+ 'nbt_string' => 4,
+ 'wrepl_nbt_name' => 4,
+ 'ipv4address' => 4
+};
+
+
+
sub nonfatal($$)
{
my ($e,$s) = @_;
@@ -299,7 +330,7 @@ sub align_type
} elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) {
return find_largest_alignment($dt);
} elsif ($dt->{TYPE} eq "SCALAR") {
- return Parse::Pidl::Typelist::getScalarAlignment($dt->{NAME});
+ return $scalar_alignment->{$dt->{NAME}};
}
die("Unknown data type type $dt->{TYPE}");
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;
diff --git a/source4/pidl/lib/Parse/Pidl/Typelist.pm b/source4/pidl/lib/Parse/Pidl/Typelist.pm
index d81fedf71e..111ce9ba11 100644
--- a/source4/pidl/lib/Parse/Pidl/Typelist.pm
+++ b/source4/pidl/lib/Parse/Pidl/Typelist.pm
@@ -7,7 +7,7 @@ package Parse::Pidl::Typelist;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(hasType getType mapType);
+@EXPORT_OK = qw(hasType getType mapType);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -22,109 +22,90 @@ my $scalars = {
"void" => {
C_TYPE => "void",
IS_REFERENCE => 0,
- NDR_ALIGN => 0
},
# 1 byte types
"char" => {
C_TYPE => "char",
IS_REFERENCE => 0,
- NDR_ALIGN => 1
},
"int8" => {
C_TYPE => "int8_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 1
},
"uint8" => {
C_TYPE => "uint8_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 1
},
# 2 byte types
"int16" => {
C_TYPE => "int16_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 2
},
"uint16" => { C_TYPE => "uint16_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 2
},
# 4 byte types
"int32" => {
C_TYPE => "int32_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"uint32" => { C_TYPE => "uint32_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
# 8 byte types
"hyper" => {
C_TYPE => "uint64_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 8
},
"dlong" => {
C_TYPE => "int64_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"udlong" => {
C_TYPE => "uint64_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"udlongr" => {
C_TYPE => "uint64_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
# DATA_BLOB types
"DATA_BLOB" => {
C_TYPE => "DATA_BLOB",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
# string types
"string" => {
C_TYPE => "const char *",
IS_REFERENCE => 1,
- NDR_ALIGN => 4 #???
},
"string_array" => {
C_TYPE => "const char **",
IS_REFERENCE => 1,
- NDR_ALIGN => 4 #???
},
# time types
"time_t" => {
C_TYPE => "time_t",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"NTTIME" => {
C_TYPE => "NTTIME",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"NTTIME_1sec" => {
C_TYPE => "NTTIME",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"NTTIME_hyper" => {
C_TYPE => "NTTIME",
IS_REFERENCE => 0,
- NDR_ALIGN => 8
},
@@ -132,34 +113,28 @@ my $scalars = {
"WERROR" => {
C_TYPE => "WERROR",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"NTSTATUS" => {
C_TYPE => "NTSTATUS",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"COMRESULT" => {
C_TYPE => "COMRESULT",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
# special types
"nbt_string" => {
C_TYPE => "const char *",
IS_REFERENCE => 1,
- NDR_ALIGN => 4 #???
},
"wrepl_nbt_name"=> {
C_TYPE => "struct nbt_name",
IS_REFERENCE => 0,
- NDR_ALIGN => 4
},
"ipv4address" => {
C_TYPE => "const char *",
IS_REFERENCE => 1,
- NDR_ALIGN => 4
}
};
@@ -175,17 +150,6 @@ sub mapScalarType($)
die("Unknown scalar type $name");
}
-sub getScalarAlignment($)
-{
- my $name = shift;
-
- # it's a bug when a type is not in the list
- # of known scalars or has no mapping
- return $scalars->{$name}{NDR_ALIGN} if defined($scalars->{$name}) and defined($scalars->{$name}{NDR_ALIGN});
-
- die("Unknown scalar type $name");
-}
-
sub addType($)
{
my $t = shift;
diff --git a/source4/pidl/pidl b/source4/pidl/pidl
index 01de049a6c..f0513546e9 100755
--- a/source4/pidl/pidl
+++ b/source4/pidl/pidl
@@ -15,7 +15,7 @@ pidl - IDL Compiler written in Perl
=head1 SYNOPSIS
pidl --help
-pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--ndr-header[=OUTPUT]] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--eth-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-header=[OUTPUT]] [--tdr-parser[=OUTPUT]] [<idlfile>.idl]...
+pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--ndr-header[=OUTPUT]] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--eth-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-header=[OUTPUT]] [--tdr-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [<idlfile>.idl]...
=head1 DESCRIPTION
@@ -114,6 +114,30 @@ file the to disk. Useful for debugging pidl.
Tell pidl to dump the internal NDR information tree it generated
from the IDL file to disk. Useful for debugging pidl.
+=item I<--samba3-header>
+
+Generate Samba3-style RPC header file. Filename defaults to rpc_BASENAME.h.
+
+=item I<--samba3-parser>
+
+Generate parser file for Samba3, to be placed in rpc_parse/. Filename defaults
+to parse_BASENAME.c.
+
+=item I<--samba3-server>
+
+Generate server file for Samba3, to be placed in rpc_server/. Filename defaults
+to srv_BASENAME.c.
+
+=item I<--samba3-template>
+
+Generate template for server-side implementation in Samba3, to be placed in
+rpc_server/. Filename defaults to srv_BASENAME_nt.c
+
+=item I<--samba3-client>
+
+Generate client calls for Samba 3, to be placed in rpc_client/. Filename
+defaults to cli_BASENAME.c.
+
=back
=head1 IDL SYNTAX
@@ -486,6 +510,11 @@ my($opt_uint_enums) = 0;
my($opt_diff) = 0;
my($opt_header);
my($opt_ndr_header);
+my($opt_samba3_header);
+my($opt_samba3_parser);
+my($opt_samba3_server);
+my($opt_samba3_template);
+my($opt_samba3_client);
my($opt_template) = 0;
my($opt_client);
my($opt_server);
@@ -540,6 +569,13 @@ Samba 4 output:
--dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c]
--com-header[=OUTFILE] create header for COM [com_BASENAME.h]
+Samba 3 output:
+ --samba3-header[=OUTF] create Samba3-style header [rpc_BASENAME.h]
+ --samba3-parser[=OUTF] create parser for Samba3 [parse_BASENAME.c]
+ --samba3-template[=OUTF]create template implementation [srv_BASENAME_nt.c]
+ --samba3-server[=OUTF] create server side wrappers for Samba3 [srv_BASENAME.c]
+ --samba3-client[=OUTF] create client calls for Samba3 [cli_BASENAME.c]
+
Ethereal parsers:
--eth-parser[=OUTFILE] create ethereal parser and header
\n";
@@ -556,6 +592,11 @@ my $result = GetOptions (
'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
'uint-enums' => \$opt_uint_enums,
'ndr-header:s' => \$opt_ndr_header,
+ 'samba3-header:s' => \$opt_samba3_header,
+ 'samba3-parser:s' => \$opt_samba3_parser,
+ 'samba3-server:s' => \$opt_samba3_server,
+ 'samba3-template:s' => \$opt_samba3_template,
+ 'samba3-client:s' => \$opt_samba3_client,
'header:s' => \$opt_header,
'server:s' => \$opt_server,
'tdr-header:s' => \$opt_tdr_header,
@@ -662,7 +703,9 @@ sub process_file($)
if (defined($opt_ndr_header) or defined($opt_eth_parser) or
defined($opt_client) or defined($opt_server) or
defined($opt_ndr_parser) or defined($opt_ejs) or
- defined($opt_dump_ndr_tree)) {
+ defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or
+ defined($opt_samba3_header) or defined($opt_samba3_server) or
+ defined($opt_samba3_template) or defined($opt_samba3_client)) {
require Parse::Pidl::NDR;
Parse::Pidl::NDR::Validate($pidl);
$ndr = Parse::Pidl::NDR::Parse($pidl);
@@ -769,6 +812,37 @@ $dcom
require Parse::Pidl::Samba::Template;
print Parse::Pidl::Samba::Template::Parse($pidl);
}
+
+ if (defined($opt_samba3_header)) {
+ my $header = ($opt_samba3_header or "$outputdir/rpc_$basename.h");
+ require Parse::Pidl::Samba3::Header;
+ FileSave($header, Parse::Pidl::Samba3::Header::Parse($ndr, $basename));
+ }
+
+ if (defined($opt_samba3_parser)) {
+ my $header = ($opt_samba3_parser or "$outputdir/parse_$basename.c");
+ require Parse::Pidl::Samba3::Parser;
+ FileSave($header, Parse::Pidl::Samba3::Parser::Parse($ndr, $basename));
+ }
+
+ if (defined($opt_samba3_server)) {
+ my $header = ($opt_samba3_server or "$outputdir/srv_$basename.c");
+ require Parse::Pidl::Samba3::Server;
+ FileSave($header, Parse::Pidl::Samba3::Server::Parse($ndr, $basename));
+ }
+
+ if (defined($opt_samba3_template)) {
+ my $header = ($opt_samba3_template or "$outputdir/srv_$basename\_nt.c");
+ require Parse::Pidl::Samba3::Template;
+ FileSave($header, Parse::Pidl::Samba3::Template::Parse($ndr, $basename));
+ }
+
+ if (defined($opt_samba3_client)) {
+ my $header = ($opt_samba3_client or "$outputdir/cli_$basename.c");
+ require Parse::Pidl::Samba3::Client;
+ FileSave($header, Parse::Pidl::Samba3::Client::Parse($ndr, $basename));
+ }
+
}
if (scalar(@ARGV) == 0) {