--- /dev/null
+###################################################
+# Samba3 server generator for IDL structures
+# Copyright jelmer@samba.org 2005-2006
+# Copyright metze@samba.org 2014
+# released under the GNU GPL
+
+package Parse::Pidl::Samba3::CompatServer;
+
+use Exporter;
+@ISA = qw(Exporter);
+
+use strict;
+use Parse::Pidl qw(warning error fatal);
+use Parse::Pidl::Util qw(has_property);
+use Parse::Pidl::Samba3::ServerNDR qw(CallWithStructExported);
+
+use vars qw($VERSION);
+$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"; }
+sub pidl_hdr($) { $res_hdr .= (shift)."\n"; }
+sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; }
+
+sub ParseFunctionState($$)
+{
+ my ($if,$fn) = @_;
+
+ my $op = "NDR_".uc($fn->{NAME});
+
+ my $fnprefix = "_s3_compat_$fn->{NAME}";
+
+ pidl "struct ${fnprefix}_state {";
+ indent;
+ pidl "struct tevent_context *ev;";
+ pidl "struct dcerpc_call_handle *call;";
+ pidl "struct $fn->{NAME} *r;";
+ deindent;
+ pidl "};";
+ pidl "";
+}
+
+sub ParseFunctionSend($$)
+{
+ my ($if,$fn) = @_;
+
+ my $op = "NDR_".uc($fn->{NAME});
+
+ my $fnprefix = "_s3_compat_$fn->{NAME}";
+
+ pidl "static struct tevent_req *${fnprefix}_send(TALLOC_CTX *mem_ctx,";
+ pidl "\t\t\t\t\tstruct tevent_context *ev,";
+ pidl "\t\t\t\t\tstruct dcerpc_call_handle *call,";
+ pidl "\t\t\t\t\tstruct $fn->{NAME} *r)";
+ pidl "{";
+ indent;
+ pidl "struct tevent_req *req";
+ pidl "struct ${fnprefix}_state *state;";
+ pidl "struct pipes_struct *p;";
+ pidl "";
+ pidl "req = tevent_req_create(mem_ctx, &state,";
+ pidl "\t\t\tstruct ${fnprefix}_state);";
+ pidl "if (req == NULL) {";
+ indent;
+ pidl "return NULL;";
+ deindent;
+ pidl "}";
+ pidl "state->ev = ev;";
+ pidl "state->call = call;";
+ pidl "state->r = r;";
+ pidl "";
+
+ pidl "p = dcerpc_call_handle_get_pipes_struct(call);";
+ pidl "";
+
+ my ($s, $h) = CallWithStructExported("p", "r", $fn,
+ sub ($) {
+ my ($name) = @_;
+ return "tevent_req_nomem(${name}, req)";
+ },
+ undef,
+ sub {
+ return "return tevent_req_post(req, ev);";
+ }
+ );
+ $res_hdr .= $h;
+ $res .= $s;
+ pidl "";
+
+ pidl "if (p->fault_state) {";
+ indent;
+ pidl "NTSTATUS status = dcerpc_fault_to_nt_status(p->fault_state);";
+ pidl "tevent_req_nterror(status);";
+ pidl "return tevent_req_post(req, ev);";
+ deindent;
+ pidl "}";
+ pidl "";
+
+ pidl "tevent_req_done(req);";
+ pidl "return tevent_req_post(req, ev);";
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
+sub ParseFunctionRecv($$)
+{
+ my ($if,$fn) = @_;
+
+ my $op = "NDR_".uc($fn->{NAME});
+
+ my $fnprefix = "_s3_compat_$fn->{NAME}";
+
+ pidl "static NTSTATUS ${fnprefix}_recv(struct tevent_req *req)";
+ pidl "{";
+ indent;
+ pidl "return tevent_req_simple_recv_ntstatus(req);";
+ deindent;
+ pidl "}";
+ pidl "";
+}
+
+sub ParseFunction($$)
+{
+ my ($if,$fn) = @_;
+
+ ParseFunctionState($fn, $fn);
+ ParseFunctionSend($fn, $fn);
+ ParseFunctionRecv($fn, $fn);
+}
+
+sub ParseInterface($)
+{
+ my $if = shift;
+
+ my $uif = uc($if->{NAME});
+
+ pidl_hdr "#ifndef __S3COMPAT_$uif\__";
+ pidl_hdr "#define __S3COMPAT_$uif\__";
+
+ foreach (@{$if->{FUNCTIONS}}) {
+ next if ($_->{PROPERTIES}{noopnum});
+ ParseFunction($if, $_);
+ }
+
+ pidl "";
+ pidl "static const struct dcerpc_call_entry_point_fns struct _s3_compat_$if->{NAME}_fns[] = {";
+ indent;
+
+ my $count = 0;
+ foreach (@{$if->{FUNCTIONS}}) {
+ next if ($_->{PROPERTIES}{noopnum});
+ my $op = "NDR_".uc($_->{NAME});
+ my $fnprefix = "_s3_compat_$_->{NAME}";
+
+ pidl "{";
+ indent;
+ pidl ".send_fn = (dcerpc_call_entry_point_send_fn_t)";
+ pidl "\t${fnprefix}_send,";
+ pidl ".recv_fn = (dcerpc_call_entry_point_recv_fn_t)";
+ pidl "\t${fnprefix}_recv,";
+ deindent;
+ pidl "},";
+
+ $count += 1;
+ }
+
+ pidl "{";
+ indent;
+ pidl ".send_fn = NULL,";
+ pidl ".recv_fn = NULL,";
+ deindent;
+ pidl "},";
+ deindent;
+ pidl "};";
+ pidl "";
+
+ pidl "static const struct dcerpc_call_entry_point_vector _s3_compat_$if->{NAME}_epv[] = {";
+ indent;
+ pidl ".name = \"_s3_compat_$if->{NAME}\",";
+ pidl ".table = &ndr_table_$if->{NAME},";
+ pidl ".num_fns = $count,";
+ pidl ".fns = _s3_compat_$if->{NAME}_fns,";
+ deindent;
+ pidl "};";
+ pidl "";
+
+ if (not has_property($if, "no_srv_register")) {
+ pidl_hdr "struct dcerpc_server;";
+ fn_declare "NTSTATUS dcerpc_server_setup_s3compat_$if->{NAME}(struct dcerpc_server *server)";
+ pidl "{";
+ indent;
+ pidl "return NT_STATUS_NOT_IMPLEMENTED;";
+ deindent;
+ pidl "}";
+ }
+
+ pidl_hdr "#endif /* __S3COMPAT_$uif\__ */";
+}
+
+sub Parse($$$)
+{
+ my($ndr,$header,$ndr_header) = @_;
+
+ pidl_reset();
+
+ pidl_hdr "/*";
+ pidl_hdr " * Unix SMB/CIFS implementation.";
+ pidl_hdr " * server auto-generated by pidl. DO NOT MODIFY!";
+ pidl_hdr " */";
+ pidl_hdr "";
+ 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 pidl_return;
+}
+
+1;
my($opt_samba3_server);
my($opt_samba3_ndr_client);
my($opt_samba3_ndr_server);
+my($opt_samba3_compat_server) = 0;
my($opt_samba3_template) = 0;
my($opt_template) = 0;
my($opt_client);
'dump-ndr-tree:s' => \$opt_dump_ndr_tree,
'samba3-ndr-client:s' => \$opt_samba3_ndr_client,
'samba3-ndr-server:s' => \$opt_samba3_ndr_server,
+ 'samba3-compat-server:s' => \$opt_samba3_compat_server,
'samba3-template' => \$opt_samba3_template,
'header:s' => \$opt_header,
'server:s' => \$opt_server,
defined($opt_samba3_parser) or
defined($opt_samba3_server) or
defined($opt_samba3_ndr_client) or
- defined($opt_samba3_ndr_server)) {
+ defined($opt_samba3_ndr_server) or
+ defined($opt_samba3_compat_server)) {
require Parse::Pidl::NDR;
$ndr = Parse::Pidl::NDR::Parse($pidl);
}
FileSave($header, $h_code);
}
+ if (defined($opt_samba3_compat_server)) {
+ my $server = ($opt_samba3_compat_server or "$outputdir/s3compat_$basename.c");
+ my $header = $server; $header =~ s/\.c$/\.h/;
+ require Parse::Pidl::Samba3::CompatServer;
+ my ($c_code,$h_code) = Parse::Pidl::Samba3::CompatServer::Parse($ndr, $header, $h_filename);
+ FileSave($server, $c_code);
+ FileSave($header, $h_code);
+ }
}
if (scalar(@ARGV) == 0) {