Refactor build system to use waf. Waf is better at handling dependency paths which I need for IDL support
This commit is contained in:
parent
df7f98bc6f
commit
9fd10dec9c
77 changed files with 312 additions and 86 deletions
418
bin/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
Normal file
418
bin/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
Normal file
|
@ -0,0 +1,418 @@
|
|||
###################################################
|
||||
# Samba3 client generator for IDL structures
|
||||
# on top of Samba4 style NDR functions
|
||||
# Copyright jelmer@samba.org 2005-2006
|
||||
# Copyright gd@samba.org 2008
|
||||
# released under the GNU GPL
|
||||
|
||||
package Parse::Pidl::Samba3::ClientNDR;
|
||||
|
||||
use Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw(ParseFunction $res $res_hdr);
|
||||
|
||||
use strict;
|
||||
use Parse::Pidl qw(fatal warning error);
|
||||
use Parse::Pidl::Util qw(has_property ParseExpr);
|
||||
use Parse::Pidl::NDR qw(ContainsPipe);
|
||||
use Parse::Pidl::Typelist qw(mapTypeName);
|
||||
use Parse::Pidl::Samba4 qw(DeclLong);
|
||||
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
|
||||
|
||||
use vars qw($VERSION);
|
||||
$VERSION = '0.01';
|
||||
|
||||
sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
|
||||
sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
|
||||
sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
|
||||
sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
|
||||
sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
|
||||
|
||||
sub genpad($)
|
||||
{
|
||||
my ($s) = @_;
|
||||
my $nt = int((length($s)+1)/8);
|
||||
my $lt = ($nt*8)-1;
|
||||
my $ns = (length($s)-$lt);
|
||||
return "\t"x($nt)." "x($ns);
|
||||
}
|
||||
|
||||
sub new($)
|
||||
{
|
||||
my ($class) = shift;
|
||||
my $self = { res => "", res_hdr => "", tabs => "" };
|
||||
bless($self, $class);
|
||||
}
|
||||
|
||||
sub ElementDirection($)
|
||||
{
|
||||
my ($e) = @_;
|
||||
|
||||
return "[in,out]" if (has_property($e, "in") and has_property($e, "out"));
|
||||
return "[in]" if (has_property($e, "in"));
|
||||
return "[out]" if (has_property($e, "out"));
|
||||
return "[in,out]";
|
||||
}
|
||||
|
||||
sub HeaderProperties($$)
|
||||
{
|
||||
my($props,$ignores) = @_;
|
||||
my $ret = "";
|
||||
|
||||
foreach my $d (keys %{$props}) {
|
||||
next if (grep(/^$d$/, @$ignores));
|
||||
if($props->{$d} ne "1") {
|
||||
$ret.= "$d($props->{$d}),";
|
||||
} else {
|
||||
$ret.="$d,";
|
||||
}
|
||||
}
|
||||
|
||||
if ($ret) {
|
||||
return "[" . substr($ret, 0, -1) . "]";
|
||||
}
|
||||
}
|
||||
|
||||
sub ParseInvalidResponse($$)
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
|
||||
if ($type eq "sync") {
|
||||
$self->pidl("return NT_STATUS_INVALID_NETWORK_RESPONSE;");
|
||||
} elsif ($type eq "async") {
|
||||
$self->pidl("tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);");
|
||||
$self->pidl("return;");
|
||||
} else {
|
||||
die("ParseInvalidResponse($type)");
|
||||
}
|
||||
}
|
||||
|
||||
sub ParseFunctionAsyncState($$$)
|
||||
{
|
||||
my ($self, $if, $fn) = @_;
|
||||
|
||||
my $state_str = "struct rpccli_$fn->{NAME}_state";
|
||||
my $done_fn = "rpccli_$fn->{NAME}_done";
|
||||
|
||||
$self->pidl("$state_str {");
|
||||
$self->indent;
|
||||
$self->pidl("TALLOC_CTX *out_mem_ctx;");
|
||||
if (defined($fn->{RETURN_TYPE})) {
|
||||
$self->pidl(mapTypeName($fn->{RETURN_TYPE}). " result;");
|
||||
}
|
||||
$self->deindent;
|
||||
$self->pidl("};");
|
||||
$self->pidl("");
|
||||
$self->pidl("static void $done_fn(struct tevent_req *subreq);");
|
||||
$self->pidl("");
|
||||
}
|
||||
|
||||
sub ParseFunctionAsyncSend($$$)
|
||||
{
|
||||
my ($self, $if, $fn) = @_;
|
||||
|
||||
my $fn_args = "";
|
||||
my $uif = uc($if);
|
||||
my $ufn = "NDR_".uc($fn->{NAME});
|
||||
my $state_str = "struct rpccli_$fn->{NAME}_state";
|
||||
my $done_fn = "rpccli_$fn->{NAME}_done";
|
||||
my $out_mem_ctx = "rpccli_$fn->{NAME}_out_memory";
|
||||
my $fn_str = "struct tevent_req *rpccli_$fn->{NAME}_send";
|
||||
my $pad = genpad($fn_str);
|
||||
|
||||
$fn_args .= "TALLOC_CTX *mem_ctx";
|
||||
$fn_args .= ",\n" . $pad . "struct tevent_context *ev";
|
||||
$fn_args .= ",\n" . $pad . "struct rpc_pipe_client *cli";
|
||||
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
my $dir = ElementDirection($_);
|
||||
my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
|
||||
$fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */";
|
||||
}
|
||||
|
||||
$self->fn_declare("$fn_str($fn_args)");
|
||||
$self->pidl("{");
|
||||
$self->indent;
|
||||
$self->pidl("struct tevent_req *req;");
|
||||
$self->pidl("$state_str *state;");
|
||||
$self->pidl("struct tevent_req *subreq;");
|
||||
$self->pidl("");
|
||||
$self->pidl("req = tevent_req_create(mem_ctx, &state,");
|
||||
$self->pidl("\t\t\t$state_str);");
|
||||
$self->pidl("if (req == NULL) {");
|
||||
$self->indent;
|
||||
$self->pidl("return NULL;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("state->out_mem_ctx = NULL;");
|
||||
$self->pidl("");
|
||||
|
||||
my $out_params = 0;
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
if (grep(/out/, @{$_->{DIRECTION}})) {
|
||||
$out_params++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($out_params > 0) {
|
||||
$self->pidl("state->out_mem_ctx = talloc_named_const(state, 0,");
|
||||
$self->pidl("\t\t \"$out_mem_ctx\");");
|
||||
$self->pidl("if (tevent_req_nomem(state->out_mem_ctx, req)) {");
|
||||
$self->indent;
|
||||
$self->pidl("return tevent_req_post(req, ev);");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$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("$fn_str($fn_args);");
|
||||
$self->pidl("if (tevent_req_nomem(subreq, req)) {");
|
||||
$self->indent;
|
||||
$self->pidl("return tevent_req_post(req, ev);");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("tevent_req_set_callback(subreq, $done_fn, req);");
|
||||
$self->pidl("return req;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
}
|
||||
|
||||
sub ParseFunctionAsyncDone($$$)
|
||||
{
|
||||
my ($self, $if, $fn) = @_;
|
||||
|
||||
my $state_str = "struct rpccli_$fn->{NAME}_state";
|
||||
my $done_fn = "rpccli_$fn->{NAME}_done";
|
||||
|
||||
$self->pidl("static void $done_fn(struct tevent_req *subreq)");
|
||||
$self->pidl("{");
|
||||
$self->indent;
|
||||
$self->pidl("struct tevent_req *req = tevent_req_callback_data(");
|
||||
$self->pidl("\tsubreq, struct tevent_req);");
|
||||
$self->pidl("$state_str *state = tevent_req_data(");
|
||||
$self->pidl("\treq, $state_str);");
|
||||
$self->pidl("NTSTATUS status;");
|
||||
$self->pidl("TALLOC_CTX *mem_ctx;");
|
||||
$self->pidl("");
|
||||
|
||||
$self->pidl("if (state->out_mem_ctx) {");
|
||||
$self->indent;
|
||||
$self->pidl("mem_ctx = state->out_mem_ctx;");
|
||||
$self->deindent;
|
||||
$self->pidl("} else {");
|
||||
$self->indent;
|
||||
$self->pidl("mem_ctx = state;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
|
||||
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;
|
||||
$self->pidl("tevent_req_nterror(req, status);");
|
||||
$self->pidl("return;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
|
||||
$self->pidl("tevent_req_done(req);");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
}
|
||||
|
||||
sub ParseFunctionAsyncRecv($$$)
|
||||
{
|
||||
my ($self, $if, $fn) = @_;
|
||||
|
||||
my $fn_args = "";
|
||||
my $state_str = "struct rpccli_$fn->{NAME}_state";
|
||||
my $fn_str = "NTSTATUS rpccli_$fn->{NAME}_recv";
|
||||
my $pad = genpad($fn_str);
|
||||
|
||||
$fn_args .= "struct tevent_req *req,\n" . $pad . "TALLOC_CTX *mem_ctx";
|
||||
|
||||
if (defined($fn->{RETURN_TYPE})) {
|
||||
$fn_args .= ",\n" . $pad . "$fn->{RETURN_TYPE} *result";
|
||||
}
|
||||
|
||||
$self->fn_declare("$fn_str($fn_args)");
|
||||
$self->pidl("{");
|
||||
$self->indent;
|
||||
$self->pidl("$state_str *state = tevent_req_data(");
|
||||
$self->pidl("\treq, $state_str);");
|
||||
$self->pidl("NTSTATUS status;");
|
||||
$self->pidl("");
|
||||
$self->pidl("if (tevent_req_is_nterror(req, &status)) {");
|
||||
$self->indent;
|
||||
$self->pidl("tevent_req_received(req);");
|
||||
$self->pidl("return status;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
|
||||
$self->pidl("/* Steal possible out parameters to the callers context */");
|
||||
$self->pidl("talloc_steal(mem_ctx, state->out_mem_ctx);");
|
||||
$self->pidl("");
|
||||
|
||||
if (defined($fn->{RETURN_TYPE})) {
|
||||
$self->pidl("/* Return result */");
|
||||
$self->pidl("*result = state->result;");
|
||||
$self->pidl("");
|
||||
}
|
||||
|
||||
$self->pidl("tevent_req_received(req);");
|
||||
$self->pidl("return NT_STATUS_OK;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
}
|
||||
|
||||
sub ParseFunctionSync($$$)
|
||||
{
|
||||
my ($self, $if, $fn) = @_;
|
||||
|
||||
my $fn_args = "";
|
||||
my $uif = uc($if);
|
||||
my $ufn = "NDR_".uc($fn->{NAME});
|
||||
my $fn_str = "NTSTATUS rpccli_$fn->{NAME}";
|
||||
my $pad = genpad($fn_str);
|
||||
|
||||
$fn_args .= "struct rpc_pipe_client *cli,\n" . $pad . "TALLOC_CTX *mem_ctx";
|
||||
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
my $dir = ElementDirection($_);
|
||||
my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]);
|
||||
$fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */";
|
||||
}
|
||||
|
||||
if (defined($fn->{RETURN_TYPE}) && ($fn->{RETURN_TYPE} eq "WERROR")) {
|
||||
$fn_args .= ",\n" . $pad . "WERROR *werror";
|
||||
}
|
||||
|
||||
$self->fn_declare("$fn_str($fn_args)");
|
||||
$self->pidl("{");
|
||||
$self->indent;
|
||||
if (defined($fn->{RETURN_TYPE})) {
|
||||
$self->pidl(mapTypeName($fn->{RETURN_TYPE})." result;");
|
||||
}
|
||||
$self->pidl("NTSTATUS status;");
|
||||
$self->pidl("");
|
||||
|
||||
$fn_str = "status = dcerpc_$fn->{NAME}";
|
||||
$pad = "\t" . genpad($fn_str);
|
||||
$fn_args = "cli->binding_handle,\n" . $pad . "mem_ctx";
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
$fn_args .= ",\n" . $pad . "_". $_->{NAME};
|
||||
}
|
||||
if (defined($fn->{RETURN_TYPE})) {
|
||||
$fn_args .= ",\n" . $pad . "&result";
|
||||
}
|
||||
|
||||
$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("/* Return result */");
|
||||
if (not $fn->{RETURN_TYPE}) {
|
||||
$self->pidl("return NT_STATUS_OK;");
|
||||
} elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
|
||||
$self->pidl("return result;");
|
||||
} elsif ($fn->{RETURN_TYPE} eq "WERROR") {
|
||||
$self->pidl("if (werror) {");
|
||||
$self->indent;
|
||||
$self->pidl("*werror = result;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
$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;");
|
||||
}
|
||||
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("");
|
||||
}
|
||||
|
||||
sub ParseFunction($$$)
|
||||
{
|
||||
my ($self, $if, $fn) = @_;
|
||||
|
||||
$self->ParseFunctionAsyncState($if, $fn);
|
||||
$self->ParseFunctionAsyncSend($if, $fn);
|
||||
$self->ParseFunctionAsyncDone($if, $fn);
|
||||
$self->ParseFunctionAsyncRecv($if, $fn);
|
||||
|
||||
$self->ParseFunctionSync($if, $fn);
|
||||
}
|
||||
|
||||
sub ParseInterface($$)
|
||||
{
|
||||
my ($self, $if) = @_;
|
||||
|
||||
my $uif = uc($if->{NAME});
|
||||
|
||||
$self->pidl_hdr("#ifndef __CLI_$uif\__");
|
||||
$self->pidl_hdr("#define __CLI_$uif\__");
|
||||
foreach my $fn (@{$if->{FUNCTIONS}}) {
|
||||
next if has_property($fn, "noopnum");
|
||||
next if has_property($fn, "todo");
|
||||
|
||||
my $skip = 0;
|
||||
foreach my $e (@{$fn->{ELEMENTS}}) {
|
||||
if (ContainsPipe($e, $e->{LEVELS}[0])) {
|
||||
$skip = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
next if $skip;
|
||||
|
||||
$self->ParseFunction($if->{NAME}, $fn);
|
||||
}
|
||||
$self->pidl_hdr("#endif /* __CLI_$uif\__ */");
|
||||
}
|
||||
|
||||
sub Parse($$$$)
|
||||
{
|
||||
my($self,$ndr,$header,$c_header) = @_;
|
||||
|
||||
$self->pidl("/*");
|
||||
$self->pidl(" * Unix SMB/CIFS implementation.");
|
||||
$self->pidl(" * client auto-generated by pidl. DO NOT MODIFY!");
|
||||
$self->pidl(" */");
|
||||
$self->pidl("");
|
||||
$self->pidl("#include \"includes.h\"");
|
||||
$self->pidl("#include \"$header\"");
|
||||
$self->pidl_hdr("#include \"$c_header\"");
|
||||
$self->pidl("");
|
||||
|
||||
foreach (@$ndr) {
|
||||
$self->ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
|
||||
}
|
||||
|
||||
return ($self->{res}, $self->{res_hdr});
|
||||
}
|
||||
|
||||
1;
|
309
bin/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
Normal file
309
bin/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
Normal file
|
@ -0,0 +1,309 @@
|
|||
###################################################
|
||||
# Samba3 server 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::ServerNDR;
|
||||
|
||||
use Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw(DeclLevel);
|
||||
|
||||
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::Samba4 qw(ElementStars DeclLong);
|
||||
use Parse::Pidl::Samba4::Header qw(GenerateFunctionOutEnv);
|
||||
|
||||
use vars qw($VERSION);
|
||||
$VERSION = '0.01';
|
||||
|
||||
my $res;
|
||||
my $res_hdr;
|
||||
my $tabs = "";
|
||||
sub indent() { $tabs.="\t"; }
|
||||
sub deindent() { $tabs = substr($tabs, 1); }
|
||||
sub pidl($) { my ($txt) = @_; $res .= $txt?$tabs.(shift)."\n":"\n"; }
|
||||
sub pidl_hdr($) { $res_hdr .= (shift)."\n"; }
|
||||
sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; }
|
||||
|
||||
sub DeclLevel($$)
|
||||
{
|
||||
my ($e, $l) = @_;
|
||||
my $res = "";
|
||||
|
||||
if (has_property($e, "charset")) {
|
||||
$res .= "const char";
|
||||
} else {
|
||||
$res .= mapTypeName($e->{TYPE});
|
||||
}
|
||||
|
||||
my $stars = ElementStars($e, $l);
|
||||
|
||||
$res .= " ".$stars unless ($stars eq "");
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub AllocOutVar($$$$$)
|
||||
{
|
||||
my ($e, $mem_ctx, $name, $env, $fail) = @_;
|
||||
|
||||
my $l = $e->{LEVELS}[0];
|
||||
|
||||
# we skip pointer to arrays
|
||||
if ($l->{TYPE} eq "POINTER") {
|
||||
my $nl = GetNextLevel($e, $l);
|
||||
$l = $nl if ($nl->{TYPE} eq "ARRAY");
|
||||
} elsif
|
||||
|
||||
# we don't support multi-dimentional arrays yet
|
||||
($l->{TYPE} eq "ARRAY") {
|
||||
my $nl = GetNextLevel($e, $l);
|
||||
if ($nl->{TYPE} eq "ARRAY") {
|
||||
fatal($e->{ORIGINAL},"multi-dimentional [out] arrays are not supported!");
|
||||
}
|
||||
} else {
|
||||
# neither pointer nor array, no need to alloc something.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($l->{TYPE} eq "ARRAY") {
|
||||
unless(defined($l->{SIZE_IS})) {
|
||||
error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'");
|
||||
pidl "#error No size known for array `$e->{NAME}'";
|
||||
} else {
|
||||
my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
|
||||
pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
|
||||
}
|
||||
} else {
|
||||
pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
|
||||
}
|
||||
|
||||
pidl "if ($name == NULL) {";
|
||||
$fail->();
|
||||
pidl "}";
|
||||
pidl "";
|
||||
}
|
||||
|
||||
sub CallWithStruct($$$$)
|
||||
{
|
||||
my ($pipes_struct, $mem_ctx, $fn, $fail) = @_;
|
||||
my $env = GenerateFunctionOutEnv($fn);
|
||||
my $hasout = 0;
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; }
|
||||
}
|
||||
|
||||
pidl "ZERO_STRUCT(r->out);" if ($hasout);
|
||||
|
||||
my $proto = "_$fn->{NAME}(struct 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)) {
|
||||
pidl "r->out.$_->{NAME} = r->in.$_->{NAME};";
|
||||
}
|
||||
}
|
||||
|
||||
foreach (@{$fn->{ELEMENTS}}) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
$ret .= ")";
|
||||
$proto .= ");";
|
||||
|
||||
if ($fn->{RETURN_TYPE}) {
|
||||
$ret = "r->out.result = $ret";
|
||||
$proto = "$fn->{RETURN_TYPE} $proto";
|
||||
} else {
|
||||
$proto = "void $proto";
|
||||
}
|
||||
|
||||
pidl_hdr "$proto";
|
||||
pidl "$ret;";
|
||||
}
|
||||
|
||||
sub ParseFunction($$)
|
||||
{
|
||||
my ($if,$fn) = @_;
|
||||
|
||||
my $op = "NDR_".uc($fn->{NAME});
|
||||
|
||||
pidl "static bool api_$fn->{NAME}(struct pipes_struct *p)";
|
||||
pidl "{";
|
||||
indent;
|
||||
pidl "const struct ndr_interface_call *call;";
|
||||
pidl "struct ndr_pull *pull;";
|
||||
pidl "struct ndr_push *push;";
|
||||
pidl "enum ndr_err_code ndr_err;";
|
||||
pidl "struct $fn->{NAME} *r;";
|
||||
pidl "";
|
||||
pidl "call = &ndr_table_$if->{NAME}.calls[$op];";
|
||||
pidl "";
|
||||
pidl "r = talloc(talloc_tos(), struct $fn->{NAME});";
|
||||
pidl "if (r == NULL) {";
|
||||
pidl "\treturn false;";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "pull = ndr_pull_init_blob(&p->in_data.data, r);";
|
||||
pidl "if (pull == NULL) {";
|
||||
pidl "\ttalloc_free(r);";
|
||||
pidl "\treturn false;";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "pull->flags |= LIBNDR_FLAG_REF_ALLOC;";
|
||||
pidl "if (p->endian) {";
|
||||
pidl "\tpull->flags |= LIBNDR_FLAG_BIGENDIAN;";
|
||||
pidl "}";
|
||||
pidl "ndr_err = call->ndr_pull(pull, NDR_IN, r);";
|
||||
pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {";
|
||||
pidl "\ttalloc_free(r);";
|
||||
pidl "\treturn false;";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "if (DEBUGLEVEL >= 10) {";
|
||||
pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_IN, r);";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
|
||||
CallWithStruct("p", "r", $fn,
|
||||
sub {
|
||||
pidl "\ttalloc_free(r);";
|
||||
pidl "\treturn false;";
|
||||
}
|
||||
);
|
||||
|
||||
pidl "";
|
||||
pidl "if (p->rng_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_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r);";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "push = ndr_push_init_ctx(r);";
|
||||
pidl "if (push == NULL) {";
|
||||
pidl "\ttalloc_free(r);";
|
||||
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);";
|
||||
pidl "\treturn false;";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "p->out_data.rdata = ndr_push_blob(push);";
|
||||
pidl "talloc_steal(p->mem_ctx, p->out_data.rdata.data);";
|
||||
pidl "";
|
||||
pidl "talloc_free(r);";
|
||||
pidl "";
|
||||
pidl "return true;";
|
||||
deindent;
|
||||
pidl "}";
|
||||
pidl "";
|
||||
}
|
||||
|
||||
sub ParseInterface($)
|
||||
{
|
||||
my $if = shift;
|
||||
|
||||
my $uif = uc($if->{NAME});
|
||||
|
||||
pidl_hdr "#ifndef __SRV_$uif\__";
|
||||
pidl_hdr "#define __SRV_$uif\__";
|
||||
|
||||
foreach (@{$if->{FUNCTIONS}}) {
|
||||
next if ($_->{PROPERTIES}{noopnum});
|
||||
ParseFunction($if, $_);
|
||||
}
|
||||
|
||||
pidl "";
|
||||
pidl "/* Tables */";
|
||||
pidl "static struct api_struct api_$if->{NAME}_cmds[] = ";
|
||||
pidl "{";
|
||||
indent;
|
||||
|
||||
foreach (@{$if->{FUNCTIONS}}) {
|
||||
next if ($_->{PROPERTIES}{noopnum});
|
||||
pidl "{\"" . uc($_->{NAME}) . "\", NDR_" . uc($_->{NAME}) . ", api_$_->{NAME}},";
|
||||
}
|
||||
|
||||
deindent;
|
||||
pidl "};";
|
||||
|
||||
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 "{";
|
||||
indent;
|
||||
pidl "*fns = api_$if->{NAME}_cmds;";
|
||||
pidl "*n_fns = sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct);";
|
||||
deindent;
|
||||
pidl "}";
|
||||
pidl "";
|
||||
|
||||
if (not has_property($if, "no_srv_register")) {
|
||||
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_unregister(\&ndr_table_$if->{NAME});";
|
||||
pidl "}";
|
||||
}
|
||||
pidl_hdr "#endif /* __SRV_$uif\__ */";
|
||||
}
|
||||
|
||||
sub Parse($$$)
|
||||
{
|
||||
my($ndr,$header,$ndr_header) = @_;
|
||||
|
||||
$res = "";
|
||||
$res_hdr = "";
|
||||
|
||||
pidl "/*";
|
||||
pidl " * Unix SMB/CIFS implementation.";
|
||||
pidl " * server auto-generated by pidl. DO NOT MODIFY!";
|
||||
pidl " */";
|
||||
pidl "";
|
||||
pidl "#include \"includes.h\"";
|
||||
pidl "#include \"ntdomain.h\"";
|
||||
pidl "#include \"$header\"";
|
||||
pidl_hdr "#include \"$ndr_header\"";
|
||||
pidl "";
|
||||
|
||||
foreach (@$ndr) {
|
||||
ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
|
||||
}
|
||||
|
||||
return ($res, $res_hdr);
|
||||
}
|
||||
|
||||
1;
|
Loading…
Add table
Add a link
Reference in a new issue