summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm136
-rwxr-xr-xsource4/pidl/pidl29
2 files changed, 162 insertions, 3 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
new file mode 100644
index 0000000000..ec3287ffb0
--- /dev/null
+++ b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -0,0 +1,136 @@
+###################################################
+# Samba3 client generator for IDL structures
+# on top of Samba4 style NDR functions
+# Copyright jelmer@samba.org 2005-2006
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::ClientNDR;
+
+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::Types qw(DeclLong);
+
+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->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); }
+sub warning($$) { my ($e,$s) = @_; warn("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); }
+
+sub CopyLevel($$$$)
+{
+ sub CopyLevel($$$$);
+ my ($e,$l,$argument,$member) = @_;
+
+ if ($l->{TYPE} eq "DATA") {
+ pidl "*$argument = *$member;";
+ } elsif ($l->{TYPE} eq "POINTER") {
+ pidl "if (r.ptr$l->{POINTER_INDEX}_$e->{NAME}) {";
+ indent;
+ pidl "*$argument = talloc_size(mem_ctx, sizeof(void *));";
+ CopyLevel($e,GetNextLevel($e,$l),"*$argument", $member);
+ deindent;
+ pidl "}";
+ } elsif ($l->{TYPE} eq "SWITCH") {
+ CopyLevel($e,GetNextLevel($e,$l),$argument,$member);
+ } elsif ($l->{TYPE} eq "ARRAY") {
+ pidl "*$argument = $member;";
+ }
+}
+
+sub ParseFunction($$)
+{
+ my ($if,$fn) = @_;
+
+ my $inargs = "";
+ my $defargs = "";
+ my $uif = uc($if->{NAME});
+ my $ufn = uc($fn->{NAME});
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ $defargs .= ", " . DeclLong($_);
+ }
+ pidl "NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)";
+ pidl "{";
+ indent;
+ pidl "struct $fn->{NAME} r;";
+ pidl "NTSTATUS status;";
+ pidl "";
+ pidl "/* In parameters */";
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ if (grep(/in/, @{$_->{DIRECTION}})) {
+ pidl "r.in.$_->{NAME} = $_->{NAME};";
+ }
+ }
+
+ pidl "status = cli_do_rpc_ndr(cli, mem_ctx, PI_$uif, $ufn, &r, ndr_pull_$fn->{NAME}, ndr_push_$fn->{NAME});";
+ pidl "if (NT_STATUS_IS_ERR(status)) {";
+ pidl "\treturn status;";
+ pidl "}";
+ pidl "";
+ pidl "/* Return variables */";
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless (grep(/out/, @{$e->{DIRECTION}}));
+
+ if ($e->{LEVELS}[0]->{TYPE} ne "POINTER") {
+ warning($e, "First element not a pointer for [out] argument");
+ next;
+ }
+
+ CopyLevel($e, $e->{LEVELS}[1], $e->{NAME}, "r.out.$e->{NAME}");
+ }
+
+ 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/pidl b/source4/pidl/pidl
index 314ab7c60b..5784822f26 100755
--- a/source4/pidl/pidl
+++ b/source4/pidl/pidl
@@ -17,7 +17,7 @@ pidl - An IDL compiler written in Perl
pidl --help
-pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--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-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [<idlfile>.idl]...
+pidl [--outputdir[=OUTNAME]] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--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-parser[=OUTPUT]] [--samba3-header[=OUTPUT]] [--samba3-parser=[OUTPUT]] [--samba3-server=[OUTPUT]] [--samba3-template[=OUTPUT]] [--samba3-client[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [<idlfile>.idl]...
=head1 DESCRIPTION
@@ -144,6 +144,12 @@ rpc_server/. Filename defaults to srv_BASENAME_nt.c
Generate client calls for Samba 3, to be placed in rpc_client/. Filename
defaults to cli_BASENAME.c.
+=item I<--samba3-ndr-client>
+
+Generate client calls for Samba3, to be placed in rpc_client/. Instead of
+calling out to the code in Samba3's rpc_parse/, this will call out to
+Samba4's NDR code instead.
+
=back
=head1 IDL SYNTAX
@@ -465,6 +471,7 @@ my($opt_samba3_parser);
my($opt_samba3_server);
my($opt_samba3_template);
my($opt_samba3_client);
+my($opt_samba3_ndr_client);
my($opt_template) = 0;
my($opt_client);
my($opt_server);
@@ -523,6 +530,8 @@ Samba 3 output:
--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]
+ --samba3-ndr-client[=OUTF] create client calls for Samba3
+ using Samba4's NDR code [cli_BASENAME.c]
Ethereal parsers:
--eth-parser[=OUTFILE] create ethereal parser and header
@@ -544,6 +553,7 @@ my $result = GetOptions (
'samba3-server:s' => \$opt_samba3_server,
'samba3-template:s' => \$opt_samba3_template,
'samba3-client:s' => \$opt_samba3_client,
+ 'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
'header:s' => \$opt_header,
'server:s' => \$opt_server,
'tdr-parser:s' => \$opt_tdr_parser,
@@ -570,6 +580,11 @@ if ($opt_help) {
exit(0);
}
+if ($opt_samba3_client and $opt_samba3_ndr_client) {
+ print "--samba3-client and --samba3-ndr-client can not be used together\n";
+ exit(1);
+}
+
sub process_file($)
{
my $idl_file = shift;
@@ -645,7 +660,8 @@ sub process_file($)
defined($opt_ndr_parser) or defined($opt_ejs) or
defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or
defined($opt_samba3_parser) or defined($opt_samba3_server) or
- defined($opt_samba3_template) or defined($opt_samba3_client)) {
+ defined($opt_samba3_template) or defined($opt_samba3_client) or
+ defined($opt_samba3_ndr_client)) {
require Parse::Pidl::NDR;
$ndr = Parse::Pidl::NDR::Parse($pidl);
}
@@ -756,7 +772,7 @@ $dcom
if (defined($opt_samba3_header) or defined($opt_samba3_parser) or
defined($opt_samba3_server) or defined($opt_samba3_client) or
- defined($opt_samba3_template)) {
+ defined($opt_samba3_ndr_client) or defined($opt_samba3_template)) {
require Parse::Pidl::Samba3::Types;
Parse::Pidl::Samba3::Types::LoadTypes($ndr);
}
@@ -791,6 +807,13 @@ $dcom
FileSave($header, Parse::Pidl::Samba3::Client::Parse($ndr, $basename));
}
+ if (defined($opt_samba3_ndr_client)) {
+ my $header = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c");
+ require Parse::Pidl::Samba3::ClientNDR;
+ FileSave($header, Parse::Pidl::Samba3::ClientNDR::Parse($ndr, $basename));
+ }
+
+
}
if (scalar(@ARGV) == 0) {