1 ###################################################
2 # Samba3 server 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::ServerNDR;
10 use Parse::Pidl::Typelist qw(hasType getType mapType scalar_is_reference);
11 use Parse::Pidl::Util qw(has_property ParseExpr is_constant);
12 use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred);
13 use Parse::Pidl::Samba4 qw(DeclLong);
15 use vars qw($VERSION);
21 sub indent() { $tabs.="\t"; }
22 sub deindent() { $tabs = substr($tabs, 1); }
23 sub pidl($) { $res .= $tabs.(shift)."\n"; }
24 sub pidl_hdr($) { $res_hdr .= (shift)."\n"; }
25 sub fatal($$) { my ($e,$s) = @_; die("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); }
26 sub warning($$) { my ($e,$s) = @_; warn("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); }
27 sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; }
31 my ($e, $mem_ctx, $name, $env) = @_;
33 my $l = $e->{LEVELS}[0];
35 if ($l->{TYPE} eq "POINTER") {
36 $l = GetNextLevel($e, $l);
39 if ($l->{TYPE} eq "ARRAY") {
40 my $size = ParseExpr($l->{SIZE_IS}, $env);
41 pidl "$name = talloc_zero_size($mem_ctx, sizeof(*$name) * $size);";
43 pidl "$name = talloc_zero_size($mem_ctx, sizeof(*$name));";
46 pidl "if ($name == NULL) {";
47 pidl "\ttalloc_free(mem_ctx);";
48 pidl "\treturn False;";
57 pidl "static BOOL api_$fn->{NAME}(pipes_struct *p)";
60 pidl "struct ndr_pull *pull;";
61 pidl "struct ndr_push *push;";
62 pidl "NTSTATUS status;";
63 pidl "DATA_BLOB blob;";
64 pidl "struct $fn->{NAME} r;";
65 pidl "TALLOC_CTX *mem_ctx = talloc_init(\"api_$fn->{NAME}\");";
67 pidl "if (!prs_data_blob(&p->in_data.data, &blob, mem_ctx)) {";
68 pidl "\ttalloc_free(mem_ctx);";
69 pidl "\treturn False;";
72 pidl "pull = ndr_pull_init_blob(&blob, mem_ctx);";
73 pidl "if (pull == NULL)";
74 pidl "\treturn False;";
76 pidl "pull->flags |= LIBNDR_FLAG_REF_ALLOC;";
77 pidl "status = ndr_pull_$fn->{NAME}(pull, NDR_IN, &r);";
78 pidl "if (NT_STATUS_IS_ERR(status)) {";
79 pidl "\ttalloc_free(mem_ctx);";
80 pidl "\treturn False;";
83 pidl "if (DEBUGLEVEL >= 10)";
84 pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, &r);";
89 foreach (@{$fn->{ELEMENTS}}) {
90 if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; }
91 next unless (grep (/in/, @{$_->{DIRECTION}}));
92 $env{$_->{NAME}} = "r.in.$_->{NAME}";
95 pidl "ZERO_STRUCT(r.out);" if ($hasout);
97 my $proto = "_$fn->{NAME}(pipes_struct *p";
98 my $ret = "_$fn->{NAME}(p";
99 foreach (@{$fn->{ELEMENTS}}) {
100 my @dir = @{$_->{DIRECTION}};
101 if (grep(/in/, @dir) and grep(/out/, @dir)) {
102 pidl "r.out.$_->{NAME} = r.in.$_->{NAME};";
103 } elsif (grep(/out/, @dir)) {
104 AllocOutVar($_, "mem_ctx", "r.out.$_->{NAME}", \%env);
106 if (grep(/in/, @dir)) { $ret .= ", r.in.$_->{NAME}"; }
107 else { $ret .= ", r.out.$_->{NAME}"; }
109 $proto .= ", " . DeclLong($_);
114 if ($fn->{RETURN_TYPE}) {
115 $ret = "r.out.result = $ret";
116 $proto = "$fn->{RETURN_TYPE} $proto";
118 $proto = "void $proto";
125 pidl "if (DEBUGLEVEL >= 10)";
126 pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, &r);";
128 pidl "push = ndr_push_init_ctx(mem_ctx);";
129 pidl "if (push == NULL) {";
130 pidl "\ttalloc_free(mem_ctx);";
131 pidl "\treturn False;";
134 pidl "status = ndr_push_$fn->{NAME}(push, NDR_OUT, &r);";
135 pidl "if (NT_STATUS_IS_ERR(status)) {";
136 pidl "\ttalloc_free(mem_ctx);";
137 pidl "\treturn False;";
140 pidl "blob = ndr_push_blob(push);";
141 pidl "if (!prs_copy_data_in(&p->out_data.rdata, blob.data, (uint32)blob.length)) {";
142 pidl "\ttalloc_free(mem_ctx);";
143 pidl "\treturn False;";
146 pidl "talloc_free(mem_ctx);";
154 sub ParseInterface($)
158 my $uif = uc($if->{NAME});
160 pidl_hdr "#ifndef __SRV_$uif\__";
161 pidl_hdr "#define __SRV_$uif\__";
162 ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
166 pidl "static struct api_struct api_$if->{NAME}_cmds[] = ";
170 foreach (@{$if->{FUNCTIONS}}) {
171 pidl "{\"" . uc($_->{NAME}) . "\", DCERPC_" . uc($_->{NAME}) . ", api_$_->{NAME}},";
179 pidl_hdr "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns);";
180 pidl "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns)";
183 pidl "*fns = api_$if->{NAME}_cmds;";
184 pidl "*n_fns = sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct);";
189 pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
190 pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
192 pidl "\treturn rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
195 pidl_hdr "#endif /* __SRV_$uif\__ */";
200 my($ndr,$header,$ndr_header) = @_;
206 pidl " * Unix SMB/CIFS implementation.";
207 pidl " * server auto-generated by pidl. DO NOT MODIFY!";
210 pidl "#include \"includes.h\"";
211 pidl "#include \"$header\"";
212 pidl_hdr "#include \"$ndr_header\"";
216 ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
219 return ($res, $res_hdr);