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 6 7package Parse::Pidl::Samba3::ClientNDR; 8 9use strict; 10use Parse::Pidl::Typelist qw(hasType getType mapType scalar_is_reference); 11use Parse::Pidl::Util qw(has_property ParseExpr is_constant); 12use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); 13use Parse::Pidl::Samba4 qw(DeclLong_cli IsUniqueOut); 14 15use vars qw($VERSION); 16$VERSION = '0.01'; 17 18my $res; 19my $res_hdr; 20my $tabs = ""; 21sub indent() { $tabs.="\t"; } 22sub deindent() { $tabs = substr($tabs, 1); } 23sub pidl($) { $res .= $tabs.(shift)."\n"; } 24sub pidl_hdr($) { $res_hdr .= (shift)."\n"; } 25sub fatal($$) { my ($e,$s) = @_; die("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); } 26sub warning($$) { my ($e,$s) = @_; warn("$e->{ORIGINAL}->{FILE}:$e->{ORIGINAL}->{LINE}: $s\n"); } 27sub fn_declare($) { my ($n) = @_; pidl $n; pidl_hdr "$n;"; } 28 29sub ParseFunction($$) 30{ 31 my ($if,$fn) = @_; 32 33 my $inargs = ""; 34 my $defargs = ""; 35 my $uif = uc($if->{NAME}); 36 my $ufn = "DCERPC_".uc($fn->{NAME}); 37 38 foreach (@{$fn->{ELEMENTS}}) { 39 $defargs .= ", " . DeclLong_cli($_); 40 } 41 fn_declare "NTSTATUS rpccli_$fn->{NAME}(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx$defargs)"; 42 pidl "{"; 43 indent; 44 pidl "struct $fn->{NAME} r;"; 45 pidl "NTSTATUS status;"; 46 pidl ""; 47 pidl "/* In parameters */"; 48 49 foreach (@{$fn->{ELEMENTS}}) { 50 if (grep(/in/, @{$_->{DIRECTION}})) { 51 if ( IsUniqueOut($_) ) { 52 pidl "r.in.$_->{NAME} = *$_->{NAME};"; 53 } 54 else { 55 pidl "r.in.$_->{NAME} = $_->{NAME};"; 56 } 57 } 58 } 59 60 pidl ""; 61 pidl "if (DEBUGLEVEL >= 10)"; 62 pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, &r);"; 63 pidl ""; 64 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});"; 65 pidl ""; 66 67 pidl "if ( !NT_STATUS_IS_OK(status) ) {"; 68 indent; 69 pidl "return status;"; 70 deindent; 71 pidl "}"; 72 73 pidl ""; 74 pidl "if (DEBUGLEVEL >= 10)"; 75 pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, &r);"; 76 pidl ""; 77 pidl "if (NT_STATUS_IS_ERR(status)) {"; 78 pidl "\treturn status;"; 79 pidl "}"; 80 pidl ""; 81 pidl "/* Return variables */"; 82 foreach my $e (@{$fn->{ELEMENTS}}) { 83 next unless (grep(/out/, @{$e->{DIRECTION}})); 84 85 fatal($e, "[out] argument is not a pointer or array") if ($e->{LEVELS}[0]->{TYPE} ne "POINTER" and $e->{LEVELS}[0]->{TYPE} ne "ARRAY"); 86 87 if ( IsUniqueOut($e) ) { 88 pidl "*$e->{NAME} = r.out.$e->{NAME};"; 89 } else { 90 pidl "*$e->{NAME} = *r.out.$e->{NAME};"; 91 } 92 93 } 94 95 pidl""; 96 pidl "/* Return result */"; 97 if (not $fn->{RETURN_TYPE}) { 98 pidl "return NT_STATUS_OK;"; 99 } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") { 100 pidl "return r.out.result;"; 101 } elsif ($fn->{RETURN_TYPE} eq "WERROR") { 102 pidl "return werror_to_ntstatus(r.out.result);"; 103 } else { 104 pidl "/* Sorry, don't know how to convert $fn->{RETURN_TYPE} to NTSTATUS */"; 105 pidl "return NT_STATUS_OK;"; 106 } 107 108 deindent; 109 pidl "}"; 110 pidl ""; 111} 112 113sub ParseInterface($) 114{ 115 my $if = shift; 116 117 my $uif = uc($if->{NAME}); 118 119 pidl_hdr "#ifndef __CLI_$uif\__"; 120 pidl_hdr "#define __CLI_$uif\__"; 121 ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}}); 122 pidl_hdr "#endif /* __CLI_$uif\__ */"; 123} 124 125sub Parse($$$) 126{ 127 my($ndr,$header,$ndr_header) = @_; 128 129 $res = ""; 130 $res_hdr = ""; 131 132 pidl "/*"; 133 pidl " * Unix SMB/CIFS implementation."; 134 pidl " * client auto-generated by pidl. DO NOT MODIFY!"; 135 pidl " */"; 136 pidl ""; 137 pidl "#include \"includes.h\""; 138 pidl "#include \"$header\""; 139 pidl_hdr "#include \"$ndr_header\""; 140 pidl ""; 141 142 foreach (@$ndr) { 143 ParseInterface($_) if ($_->{TYPE} eq "INTERFACE"); 144 } 145 146 return ($res, $res_hdr); 147} 148 1491; 150