pyldb: avoid segfault when adding an element with no name
[kai/samba-autobuild/.git] / pidl / lib / Parse / Pidl / Samba3 / ServerNDR.pm
index 0ea43e48ad5f802dbb738eb963dc0a48e76569ea..fa7303b854340976fc9b34d253ccfcd3f08eb89e 100644 (file)
@@ -14,7 +14,7 @@ use strict;
 use Parse::Pidl qw(warning error fatal);
 use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
 use Parse::Pidl::Util qw(ParseExpr has_property is_constant);
-use Parse::Pidl::NDR qw(GetNextLevel);
+use Parse::Pidl::NDR qw(GetNextLevel ContainsPipe);
 use Parse::Pidl::Samba4 qw(ElementStars DeclLong);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionOutEnv);
 
@@ -24,6 +24,8 @@ $VERSION = '0.01';
 my $res;
 my $res_hdr;
 my $tabs = "";
+sub pidl_reset() { $res=""; $res_hdr="", $tabs=""; }
+sub pidl_return() { my $s = $res; my $h = $res_hdr; pidl_reset(); return ($s, $h) }
 sub indent() { $tabs.="\t"; }
 sub deindent() { $tabs = substr($tabs, 1); }
 sub pidl($) { my ($txt) = @_; $res .= $txt?$tabs.(shift)."\n":"\n"; }
@@ -48,9 +50,9 @@ sub DeclLevel($$)
        return $res;
 }
 
-sub AllocOutVar($$$$$)
+sub AllocOutVar($$$$$$$)
 {
-       my ($e, $mem_ctx, $name, $env, $fail) = @_;
+       my ($e, $mem_ctx, $name, $env, $check, $cleanup, $return) = @_;
 
        my $l = $e->{LEVELS}[0];
 
@@ -83,25 +85,26 @@ sub AllocOutVar($$$$$)
                pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
        }
 
-       pidl "if ($name == NULL) {";
-       $fail->();
+       pidl "if (" . $check->($name) . ") {";
+       indent;
+       pidl $cleanup->($name) if defined($cleanup);
+       pidl $return->($name) if defined($return);
+       deindent;
        pidl "}";
        pidl "";
 }
 
-sub CallWithStruct($$$$)
+sub CallWithStruct($$$$$$)
 {
-       my ($pipes_struct, $mem_ctx, $fn, $fail) = @_;
+       my ($pipes_struct, $mem_ctx, $fn, $check, $cleanup, $return) = @_;
        my $env = GenerateFunctionOutEnv($fn);
        my $hasout = 0;
        foreach (@{$fn->{ELEMENTS}}) {
                if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; }
        }
 
-       pidl "ZERO_STRUCT(r->out);" if ($hasout);
+       pidl "NDR_ZERO_STRUCT(r->out);" if ($hasout);
 
-       my $proto = "_$fn->{NAME}(pipes_struct *p, struct $fn->{NAME} *r";
-       my $ret = "_$fn->{NAME}($pipes_struct, r";
        foreach (@{$fn->{ELEMENTS}}) {
                my @dir = @{$_->{DIRECTION}};
                if (grep(/in/, @dir) and grep(/out/, @dir)) {
@@ -110,25 +113,28 @@ sub CallWithStruct($$$$)
        }
 
        foreach (@{$fn->{ELEMENTS}}) {
+               next if ContainsPipe($_, $_->{LEVELS}[0]);
                my @dir = @{$_->{DIRECTION}};
                if (grep(/in/, @dir) and grep(/out/, @dir)) {
                        # noop
                } elsif (grep(/out/, @dir) and not
                                 has_property($_, "represent_as")) {
-                       AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env, $fail);
+                       AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env,
+                                   $check, $cleanup, $return);
                }
        }
-       $ret .= ")";
-       $proto .= ");";
+
+       my $proto = "_$fn->{NAME}(struct pipes_struct *p, struct $fn->{NAME} *r)";
+       my $ret = "_$fn->{NAME}($pipes_struct, r)";
 
        if ($fn->{RETURN_TYPE}) {
                $ret = "r->out.result = $ret";
-               $proto = "$fn->{RETURN_TYPE} $proto";
+               $proto = mapTypeName($fn->{RETURN_TYPE})." $proto";
        } else {
                $proto = "void $proto";
        }
 
-       pidl_hdr "$proto";
+       pidl_hdr "$proto;";
        pidl "$ret;";
 }
 
@@ -138,7 +144,7 @@ sub ParseFunction($$)
 
        my $op = "NDR_".uc($fn->{NAME});
 
-       pidl "static bool api_$fn->{NAME}(pipes_struct *p)";
+       pidl "static bool api_$fn->{NAME}(struct pipes_struct *p)";
        pidl "{";
        indent;
        pidl "const struct ndr_interface_call *call;";
@@ -171,26 +177,34 @@ sub ParseFunction($$)
        pidl "}";
        pidl "";
        pidl "if (DEBUGLEVEL >= 10) {";
-       pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, r);";
+       pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_IN, r);";
        pidl "}";
        pidl "";
 
-       CallWithStruct("p", "r", $fn, 
-       sub { 
-                       pidl "\ttalloc_free(r);";
-                       pidl "\treturn false;";
+       CallWithStruct("p", "r", $fn,
+               sub ($) {
+                       my ($name) = @_;
+                       return "${name} == NULL";
+               },
+               sub ($) {
+                       my ($name) = @_;
+                       return "talloc_free(r);";
+               },
+               sub ($) {
+                       my ($name) = @_;
+                       return "return false;";
                }
        );
 
        pidl "";
-       pidl "if (p->rng_fault_state) {";
+       pidl "if (p->fault_state) {";
        pidl "\ttalloc_free(r);";
        pidl "\t/* Return true here, srv_pipe_hnd.c will take care */";
        pidl "\treturn true;";
        pidl "}";
        pidl "";
        pidl "if (DEBUGLEVEL >= 10) {";
-       pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, r);";
+       pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r);";
        pidl "}";
        pidl "";
        pidl "push = ndr_push_init_ctx(r);";
@@ -199,6 +213,12 @@ sub ParseFunction($$)
        pidl "\treturn false;";
        pidl "}";
        pidl "";
+       pidl "/*";
+       pidl " * carry over the pointer count to the reply in case we are";
+       pidl " * using full pointer. See NDR specification for full pointers";
+       pidl " */";
+       pidl "push->ptr_count = pull->ptr_count;";
+       pidl "";
        pidl "ndr_err = call->ndr_push(push, NDR_OUT, r);";
        pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {";
        pidl "\ttalloc_free(r);";
@@ -232,7 +252,7 @@ sub ParseInterface($)
 
        pidl "";
        pidl "/* Tables */";
-       pidl "static struct api_struct api_$if->{NAME}_cmds[] = ";
+       pidl "static const struct api_struct api_$if->{NAME}_cmds[] = ";
        pidl "{";
        indent;
 
@@ -246,21 +266,30 @@ sub ParseInterface($)
 
        pidl "";
 
-       pidl_hdr "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns);";
-       pidl "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns)";
+       pidl_hdr "const struct api_struct *$if->{NAME}_get_pipe_fns(int *n_fns);";
+       pidl "const struct api_struct *$if->{NAME}_get_pipe_fns(int *n_fns)";
        pidl "{";
        indent;
-       pidl "*fns = api_$if->{NAME}_cmds;";
        pidl "*n_fns = sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct);";
+       pidl "return api_$if->{NAME}_cmds;";
        deindent;
        pidl "}";
        pidl "";
 
        if (not has_property($if, "no_srv_register")) {
-           pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
-           pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
+           pidl_hdr "struct rpc_srv_callbacks;";
+           pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb);";
+           pidl "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb)";
+           pidl "{";
+           pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct), rpc_srv_cb);";
+           pidl "}";
+
+           pidl "";
+
+           pidl_hdr "NTSTATUS rpc_$if->{NAME}_shutdown(void);";
+           pidl "NTSTATUS rpc_$if->{NAME}_shutdown(void)";
            pidl "{";
-           pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
+           pidl "\treturn rpc_srv_unregister(\&ndr_table_$if->{NAME});";
            pidl "}";
        }
        pidl_hdr "#endif /* __SRV_$uif\__ */";
@@ -270,8 +299,7 @@ sub Parse($$$)
 {
        my($ndr,$header,$ndr_header) = @_;
 
-       $res = "";
-       $res_hdr = "";
+       pidl_reset();
 
        pidl "/*";
        pidl " * Unix SMB/CIFS implementation.";
@@ -279,6 +307,7 @@ sub Parse($$$)
        pidl " */";
        pidl "";
        pidl "#include \"includes.h\"";
+       pidl "#include \"ntdomain.h\"";
        pidl "#include \"$header\"";
        pidl_hdr "#include \"$ndr_header\"";
        pidl "";
@@ -287,7 +316,7 @@ sub Parse($$$)
                ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
        }
 
-       return ($res, $res_hdr);
+       return pidl_return();
 }
 
 1;