TODO pidl:Samba3/CompatServer.pm:
authorStefan Metzmacher <metze@samba.org>
Tue, 18 Mar 2014 21:50:47 +0000 (22:50 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:58:01 +0000 (12:58 +0200)
pidl/lib/Parse/Pidl/Samba3/CompatServer.pm [new file with mode: 0644]
pidl/pidl

diff --git a/pidl/lib/Parse/Pidl/Samba3/CompatServer.pm b/pidl/lib/Parse/Pidl/Samba3/CompatServer.pm
new file mode 100644 (file)
index 0000000..0a4b840
--- /dev/null
@@ -0,0 +1,231 @@
+###################################################
+# 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;
index 38609aa865c5196b602dc93e6a99e5eb22e11fa8..ec06b16cfd3df401f04c0ba5e0f0f43002af1052 100755 (executable)
--- a/pidl/pidl
+++ b/pidl/pidl
@@ -469,6 +469,7 @@ my($opt_samba3_parser);
 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);
@@ -556,6 +557,7 @@ my $result = GetOptions (
                '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,
@@ -680,7 +682,8 @@ sub process_file($)
                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);
        }
@@ -797,6 +800,14 @@ sub process_file($)
                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) {