1 ###################################################
2 # Samba3 client generator for IDL structures
3 # on top of Samba4 style NDR functions
4 # Copyright jelmer@samba.org 2005-2006
5 # released under the GNU GPL
7 package Parse
::Pidl
::Samba3
::ClientNDR
;
11 @EXPORT_OK = qw(GenerateFunctionInEnv ParseFunction $res $res_hdr);
14 use Parse::Pidl qw(fatal warning);
15 use Parse
::Pidl
::Typelist
qw(hasType getType mapType scalar_is_reference);
16 use Parse
::Pidl
::Util
qw(has_property is_constant ParseExpr);
17 use Parse
::Pidl
::NDR
qw(GetPrevLevel GetNextLevel ContainsDeferred);
18 use Parse
::Pidl
::Samba4
qw(DeclLong);
20 use vars
qw($VERSION);
26 sub indent() { $tabs.="\t"; }
27 sub deindent() { $tabs = substr($tabs, 1); }
28 sub pidl($) { $res .= $tabs.(shift)."\n"; }
29 sub pidl_hdr($) { $res_hdr .= (shift)."\n"; }
30 sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; }
32 sub GenerateFunctionInEnv($)
37 foreach my $e (@{$fn->{ELEMENTS}}) {
38 if (grep (/in/, @{$e->{DIRECTION}})) {
39 $env{$e->{NAME}} = "r.in.$e->{NAME}";
52 my $ufn = "DCERPC_".uc($fn->{NAME});
54 foreach (@{$fn->{ELEMENTS}}) {
55 $defargs .= ", " . DeclLong($_);
57 fn_declare "NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)";
60 pidl "struct $fn->{NAME} r;";
61 pidl "NTSTATUS status;";
63 pidl "/* In parameters */";
65 foreach (@{$fn->{ELEMENTS}}) {
66 if (grep(/in/, @{$_->{DIRECTION}})) {
67 pidl "r.in.$_->{NAME} = $_->{NAME};";
72 pidl "if (DEBUGLEVEL >= 10)";
73 pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, &r);";
75 pidl "status = cli_do_rpc_ndr(cli, mem_ctx, PI_$uif, $ufn, &r, (ndr_pull_flags_fn_t)ndr_pull_$fn->{NAME}, (ndr_push_flags_fn_t)ndr_push_$fn->{NAME});";
78 pidl "if (!NT_STATUS_IS_OK(status)) {";
80 pidl "return status;";
85 pidl "if (DEBUGLEVEL >= 10)";
86 pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, &r);";
88 pidl "if (NT_STATUS_IS_ERR(status)) {";
89 pidl "\treturn status;";
92 pidl "/* Return variables */";
93 foreach my $e (@{$fn->{ELEMENTS}}) {
94 next unless (grep(/out/, @{$e->{DIRECTION}}));
96 fatal($e, "[out] argument is not a pointer or array") if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY");
98 if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") and
99 ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") ) {
100 pidl "if ( $e->{NAME} ) {";
104 if ($e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
105 # This is a call to GenerateFunctionInEnv intentionally.
106 # Since the data is being copied into a user-provided data
107 # structure, the user should be able to know the size beforehand
108 # to allocate a structure of the right size.
109 my $env = GenerateFunctionInEnv($fn);
110 my $size_is = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e);
111 pidl "memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is);";
113 pidl "*$e->{NAME} = *r.out.$e->{NAME};";
116 if ( ($e->{LEVELS}[0]->{TYPE} eq "POINTER") and
117 ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref") ) {
124 pidl "/* Return result */";
125 if (not $fn->{RETURN_TYPE}) {
126 pidl "return NT_STATUS_OK;";
127 } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
128 pidl "return r.out.result;";
129 } elsif ($fn->{RETURN_TYPE} eq "WERROR") {
130 pidl "return werror_to_ntstatus(r.out.result);";
132 warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS");
133 pidl "return NT_STATUS_OK;";
141 sub ParseInterface($)
145 my $uif = uc($if->{NAME});
147 pidl_hdr "#ifndef __CLI_$uif\__";
148 pidl_hdr "#define __CLI_$uif\__";
149 ParseFunction(uc($if->{NAME}), $_) foreach (@{$if->{FUNCTIONS}});
150 pidl_hdr "#endif /* __CLI_$uif\__ */";
155 my($ndr,$header,$ndr_header) = @_;
161 pidl " * Unix SMB/CIFS implementation.";
162 pidl " * client auto-generated by pidl. DO NOT MODIFY!";
165 pidl "#include \"includes.h\"";
166 pidl "#include \"$header\"";
167 pidl_hdr "#include \"$ndr_header\"";
171 ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
174 return ($res, $res_hdr);