pidl:Samba3/ClientNDR: implement rpccli_ stubs on top of dcerpc_ stubs
authorStefan Metzmacher <metze@samba.org>
Thu, 5 Aug 2010 19:01:25 +0000 (21:01 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 12 Aug 2010 12:31:23 +0000 (14:31 +0200)
metze

pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
pidl/pidl
pidl/tests/samba3-cli.pl

index cb6c1f252a315df1e26a8c36d245488dc6636963..24f87b606375bd4273c5070eaec86cd63e74389f 100644 (file)
@@ -14,6 +14,7 @@ use Exporter;
 use strict;
 use Parse::Pidl qw(fatal warning error);
 use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::Typelist qw(mapTypeName);
 use Parse::Pidl::Samba4 qw(DeclLong);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
 
@@ -166,10 +167,10 @@ sub ParseFunctionAsyncState($$$)
 
        $self->pidl("$state_str {");
        $self->indent;
-       $self->pidl("struct $fn->{NAME} orig;");
-       $self->pidl("struct $fn->{NAME} tmp;");
        $self->pidl("TALLOC_CTX *out_mem_ctx;");
-       $self->pidl("NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);");
+       if (defined($fn->{RETURN_TYPE})) {
+               $self->pidl(mapTypeName($fn->{RETURN_TYPE}). " result;");
+       }
        $self->deindent;
        $self->pidl("};");
        $self->pidl("");
@@ -215,32 +216,14 @@ sub ParseFunctionAsyncSend($$$)
        $self->deindent;
        $self->pidl("}");
        $self->pidl("state->out_mem_ctx = NULL;");
-       $self->pidl("state->dispatch_recv = cli->dispatch_recv;");
-       $self->pidl("");
-
-       $self->pidl("/* In parameters */");
-       foreach (@{$fn->{ELEMENTS}}) {
-               if (grep(/in/, @{$_->{DIRECTION}})) {
-                       $self->pidl("state->orig.in.$_->{NAME} = _$_->{NAME};");
-               }
-       }
        $self->pidl("");
 
        my $out_params = 0;
-       $self->pidl("/* Out parameters */");
        foreach (@{$fn->{ELEMENTS}}) {
                if (grep(/out/, @{$_->{DIRECTION}})) {
-                       $self->pidl("state->orig.out.$_->{NAME} = _$_->{NAME};");
                        $out_params++;
                }
        }
-       $self->pidl("");
-
-       if (defined($fn->{RETURN_TYPE})) {
-               $self->pidl("/* Result */");
-               $self->pidl("ZERO_STRUCT(state->orig.out.result);");
-               $self->pidl("");
-       }
 
        if ($out_params > 0) {
                $self->pidl("state->out_mem_ctx = talloc_named_const(state, 0,");
@@ -253,14 +236,14 @@ sub ParseFunctionAsyncSend($$$)
                $self->pidl("");
        }
 
-       $self->pidl("/* make a temporary copy, that we pass to the dispatch function */");
-       $self->pidl("state->tmp = state->orig;");
-       $self->pidl("");
+       $fn_str = "subreq = dcerpc_$fn->{NAME}_send";
+       $pad = "\t" . genpad($fn_str);
+       $fn_args = "state,\n" . $pad . "ev,\n" . $pad . "cli->binding_handle";
+       foreach (@{$fn->{ELEMENTS}}) {
+               $fn_args .= ",\n" . $pad . "_". $_->{NAME};
+       }
 
-       $self->pidl("subreq = cli->dispatch_send(state, ev, cli,");
-       $self->pidl("\t\t\t    &ndr_table_$if,");
-       $self->pidl("\t\t\t    $ufn,");
-       $self->pidl("\t\t\t    &state->tmp);");
+       $self->pidl("$fn_str($fn_args);");
        $self->pidl("if (tevent_req_nomem(subreq, req)) {");
        $self->indent;
        $self->pidl("return tevent_req_post(req, ev);");
@@ -302,7 +285,14 @@ sub ParseFunctionAsyncDone($$$)
        $self->pidl("}");
        $self->pidl("");
 
-       $self->pidl("status = state->dispatch_recv(subreq, mem_ctx);");
+       my $fn_str = "status = dcerpc_$fn->{NAME}_recv";
+       my $pad = "\t" . genpad($fn_str);
+       my $fn_args = "subreq,\n" . $pad . "mem_ctx";
+       if (defined($fn->{RETURN_TYPE})) {
+               $fn_args .= ",\n" . $pad . "&state->result";
+       }
+
+       $self->pidl("$fn_str($fn_args);");
        $self->pidl("TALLOC_FREE(subreq);");
        $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
        $self->indent;
@@ -312,27 +302,6 @@ sub ParseFunctionAsyncDone($$$)
        $self->pidl("}");
        $self->pidl("");
 
-       $self->pidl("/* Copy out parameters */");
-       foreach my $e (@{$fn->{ELEMENTS}}) {
-               next unless (grep(/out/, @{$e->{DIRECTION}}));
-
-               $self->ParseOutputArgument($fn, $e,
-                                          "state->tmp.",
-                                          "state->orig.out.",
-                                          "async");
-       }
-       $self->pidl("");
-
-       if (defined($fn->{RETURN_TYPE})) {
-               $self->pidl("/* Copy result */");
-               $self->pidl("state->orig.out.result = state->tmp.out.result;");
-               $self->pidl("");
-       }
-
-       $self->pidl("/* Reset temporary structure */");
-       $self->pidl("ZERO_STRUCT(state->tmp);");
-       $self->pidl("");
-
        $self->pidl("tevent_req_done(req);");
        $self->deindent;
        $self->pidl("}");
@@ -375,7 +344,7 @@ sub ParseFunctionAsyncRecv($$$)
 
        if (defined($fn->{RETURN_TYPE})) {
                $self->pidl("/* Return result */");
-               $self->pidl("*result = state->orig.out.result;");
+               $self->pidl("*result = state->result;");
                $self->pidl("");
        }
 
@@ -401,7 +370,7 @@ sub ParseFunctionSync($$$)
        foreach (@{$fn->{ELEMENTS}}) {
                my $dir = ElementDirection($_);
                my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
-               $fn_args .= ",\n" . $pad . DeclLong($_) . " /* $dir $prop */";
+               $fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */";
        }
 
        if (defined($fn->{RETURN_TYPE}) && ($fn->{RETURN_TYPE} eq "WERROR")) {
@@ -411,60 +380,43 @@ sub ParseFunctionSync($$$)
        $self->fn_declare("$fn_str($fn_args)");
        $self->pidl("{");
        $self->indent;
-       $self->pidl("struct $fn->{NAME} r;");
+       if (defined($fn->{RETURN_TYPE})) {
+               $self->pidl(mapTypeName($fn->{RETURN_TYPE})." result;");
+       }
        $self->pidl("NTSTATUS status;");
        $self->pidl("");
-       $self->pidl("/* In parameters */");
 
+       $fn_str = "status = dcerpc_$fn->{NAME}";
+       $pad = "\t" . genpad($fn_str);
+       $fn_args = "cli->binding_handle,\n" . $pad . "mem_ctx";
        foreach (@{$fn->{ELEMENTS}}) {
-               if (grep(/in/, @{$_->{DIRECTION}})) {
-                       $self->pidl("r.in.$_->{NAME} = $_->{NAME};");
-               }
+               $fn_args .= ",\n" . $pad . "_". $_->{NAME};
+       }
+       if (defined($fn->{RETURN_TYPE})) {
+               $fn_args .= ",\n" . $pad . "&result";
        }
 
-       $self->pidl("");
-       $self->pidl("status = cli->dispatch(cli,");
-       $self->pidl("\t\t\tmem_ctx,");
-       $self->pidl("\t\t\t&ndr_table_$if,");
-       $self->pidl("\t\t\t$ufn,");
-       $self->pidl("\t\t\t&r);");
-       $self->pidl("");
-
+       $self->pidl("$fn_str($fn_args);");
        $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
        $self->indent;
        $self->pidl("return status;");
        $self->deindent;
        $self->pidl("}");
-
        $self->pidl("");
-       $self->pidl("if (NT_STATUS_IS_ERR(status)) {");
-       $self->indent;
-       $self->pidl("return status;");
-       $self->deindent;
-       $self->pidl("}");
-       $self->pidl("");
-       $self->pidl("/* Return variables */");
-       foreach my $e (@{$fn->{ELEMENTS}}) {
-               next unless (grep(/out/, @{$e->{DIRECTION}}));
-
-               $self->ParseOutputArgument($fn, $e);
 
-       }
-
-       $self->pidl("");
        $self->pidl("/* Return result */");
        if (not $fn->{RETURN_TYPE}) {
                $self->pidl("return NT_STATUS_OK;");
        } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
-               $self->pidl("return r.out.result;");
+               $self->pidl("return result;");
        } elsif ($fn->{RETURN_TYPE} eq "WERROR") {
                $self->pidl("if (werror) {");
                $self->indent;
-               $self->pidl("*werror = r.out.result;");
+               $self->pidl("*werror = result;");
                $self->deindent;
                $self->pidl("}");
                $self->pidl("");
-               $self->pidl("return werror_to_ntstatus(r.out.result);");
+               $self->pidl("return werror_to_ntstatus(result);");
        } else {
                warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS");
                $self->pidl("return NT_STATUS_OK;");
@@ -505,7 +457,7 @@ sub ParseInterface($$)
 
 sub Parse($$$$)
 {
-       my($self,$ndr,$header,$ndr_header) = @_;
+       my($self,$ndr,$header,$c_header) = @_;
 
        $self->pidl("/*");
        $self->pidl(" * Unix SMB/CIFS implementation.");
@@ -514,7 +466,7 @@ sub Parse($$$$)
        $self->pidl("");
        $self->pidl("#include \"includes.h\"");
        $self->pidl("#include \"$header\"");
-       $self->pidl_hdr("#include \"$ndr_header\"");
+       $self->pidl_hdr("#include \"$c_header\"");
        $self->pidl("");
        
        foreach (@$ndr) {
index c64ea959b1baa502852eee558c27119ddb679527..2a46e92925c18eb7e7a0052fffad53ea0dcbf26f 100755 (executable)
--- a/pidl/pidl
+++ b/pidl/pidl
@@ -692,10 +692,11 @@ sub process_file($)
        }
 
        my $h_filename = "$outputdir/ndr_$basename.h";
-       if (defined($opt_client)) {
+       my $c_header = "$outputdir/ndr_$basename\_c.h";
+       if (defined($opt_client) or defined($opt_samba3_ndr_client)) {
                require Parse::Pidl::Samba4::NDR::Client;
                my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c");
-               my ($c_header) = $c_client;
+               $c_header = $c_client;
                $c_header =~ s/\.c$/.h/;
 
                my $generator = new Parse::Pidl::Samba4::NDR::Client();
@@ -772,7 +773,7 @@ sub process_file($)
                my $header = $client; $header =~ s/\.c$/\.h/;
                require Parse::Pidl::Samba3::ClientNDR;
                my $generator = new Parse::Pidl::Samba3::ClientNDR();
-               my ($c_code,$h_code) = $generator->Parse($ndr, $header, $h_filename);
+               my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header);
                FileSave($client, $c_code);
                FileSave($header, $h_code);
        }
index fcf1fb171ba18ba0502b29684944bc3ec28a2085..367922a36b1ba699cbc8fd1de24ab27575dc0fad 100755 (executable)
@@ -31,10 +31,7 @@ $fn = { NAME => "bar", ELEMENTS => [ ] };
 $x->ParseFunction("foo", $fn);
 is($x->{res}, 
 "struct rpccli_bar_state {
-       struct bar orig;
-       struct bar tmp;
        TALLOC_CTX *out_mem_ctx;
-       NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
 };
 
 static void rpccli_bar_done(struct tevent_req *subreq);
@@ -53,19 +50,10 @@ struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
                return NULL;
        }
        state->out_mem_ctx = NULL;
-       state->dispatch_recv = cli->dispatch_recv;
 
-       /* In parameters */
-
-       /* Out parameters */
-
-       /* make a temporary copy, that we pass to the dispatch function */
-       state->tmp = state->orig;
-
-       subreq = cli->dispatch_send(state, ev, cli,
-                                   &ndr_table_foo,
-                                   NDR_BAR,
-                                   &state->tmp);
+       subreq = dcerpc_bar_send(state,
+                                ev,
+                                cli->binding_handle);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -88,18 +76,14 @@ static void rpccli_bar_done(struct tevent_req *subreq)
                mem_ctx = state;
        }
 
-       status = state->dispatch_recv(subreq, mem_ctx);
+       status = dcerpc_bar_recv(subreq,
+                                mem_ctx);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
                tevent_req_nterror(req, status);
                return;
        }
 
-       /* Copy out parameters */
-
-       /* Reset temporary structure */
-       ZERO_STRUCT(state->tmp);
-
        tevent_req_done(req);
 }
 
@@ -125,27 +109,14 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req,
 NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
                    TALLOC_CTX *mem_ctx)
 {
-       struct bar r;
        NTSTATUS status;
 
-       /* In parameters */
-
-       status = cli->dispatch(cli,
-                               mem_ctx,
-                               &ndr_table_foo,
-                               NDR_BAR,
-                               &r);
-
+       status = dcerpc_bar(cli->binding_handle,
+                           mem_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       if (NT_STATUS_IS_ERR(status)) {
-               return status;
-       }
-
-       /* Return variables */
-
        /* Return result */
        return NT_STATUS_OK;
 }
@@ -158,10 +129,8 @@ $fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" };
 $x->ParseFunction("foo", $fn);
 is($x->{res}, 
 "struct rpccli_bar_state {
-       struct bar orig;
-       struct bar tmp;
        TALLOC_CTX *out_mem_ctx;
-       NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
+       WERROR result;
 };
 
 static void rpccli_bar_done(struct tevent_req *subreq);
@@ -180,22 +149,10 @@ struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
                return NULL;
        }
        state->out_mem_ctx = NULL;
-       state->dispatch_recv = cli->dispatch_recv;
-
-       /* In parameters */
 
-       /* Out parameters */
-
-       /* Result */
-       ZERO_STRUCT(state->orig.out.result);
-
-       /* make a temporary copy, that we pass to the dispatch function */
-       state->tmp = state->orig;
-
-       subreq = cli->dispatch_send(state, ev, cli,
-                                   &ndr_table_foo,
-                                   NDR_BAR,
-                                   &state->tmp);
+       subreq = dcerpc_bar_send(state,
+                                ev,
+                                cli->binding_handle);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -218,21 +175,15 @@ static void rpccli_bar_done(struct tevent_req *subreq)
                mem_ctx = state;
        }
 
-       status = state->dispatch_recv(subreq, mem_ctx);
+       status = dcerpc_bar_recv(subreq,
+                                mem_ctx,
+                                &state->result);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
                tevent_req_nterror(req, status);
                return;
        }
 
-       /* Copy out parameters */
-
-       /* Copy result */
-       state->orig.out.result = state->tmp.out.result;
-
-       /* Reset temporary structure */
-       ZERO_STRUCT(state->tmp);
-
        tevent_req_done(req);
 }
 
@@ -253,7 +204,7 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req,
        talloc_steal(mem_ctx, state->out_mem_ctx);
 
        /* Return result */
-       *result = state->orig.out.result;
+       *result = state->result;
 
        tevent_req_received(req);
        return NT_STATUS_OK;
@@ -263,33 +214,22 @@ NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
                    TALLOC_CTX *mem_ctx,
                    WERROR *werror)
 {
-       struct bar r;
+       WERROR result;
        NTSTATUS status;
 
-       /* In parameters */
-
-       status = cli->dispatch(cli,
-                               mem_ctx,
-                               &ndr_table_foo,
-                               NDR_BAR,
-                               &r);
-
+       status = dcerpc_bar(cli->binding_handle,
+                           mem_ctx,
+                           &result);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       if (NT_STATUS_IS_ERR(status)) {
-               return status;
-       }
-
-       /* Return variables */
-
        /* Return result */
        if (werror) {
-               *werror = r.out.result;
+               *werror = result;
        }
 
-       return werror_to_ntstatus(r.out.result);
+       return werror_to_ntstatus(result);
 }
 
 ");