1#!/usr/bin/perl -w 2 3################################################### 4# package to parse IDL files and generate code for 5# rpc functions in Samba 6# Copyright tridge@samba.org 2000-2003 7# Copyright jelmer@samba.org 2005 8# released under the GNU GPL 9 10=pod 11 12=head1 NAME 13 14pidl - An IDL compiler written in Perl 15 16=head1 SYNOPSIS 17 18pidl --help 19 20pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--swig[=OUTPUT]] [--uint-enums] [--ndr-parser[=OUTPUT]] [--client] [--server] [--dcom-proxy] [--com-header] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [<idlfile>.idl]... 21 22=head1 DESCRIPTION 23 24pidl is an IDL compiler written in Perl that aims to be somewhat 25compatible with the midl compiler. IDL is short for 26"Interface Definition Language". 27 28pidl can generate stubs for DCE/RPC server code, DCE/RPC 29client code and Wireshark dissectors for DCE/RPC traffic. 30 31IDL compilers like pidl take a description 32of an interface as their input and use it to generate C 33(though support for other languages may be added later) code that 34can use these interfaces, pretty print data sent 35using these interfaces, or even generate Wireshark 36dissectors that can parse data sent over the 37wire by these interfaces. 38 39pidl takes IDL files in the same format as is used by midl, 40converts it to a .pidl file (which contains pidl's internal representation of the interface) and can then generate whatever output you need. 41.pidl files should be used for debugging purposes only. Write your 42interface definitions in .idl format. 43 44The goal of pidl is to implement a IDL compiler that can be used 45while developing the RPC subsystem in Samba (for 46both marshalling/unmarshalling and debugging purposes). 47 48=head1 OPTIONS 49 50=over 4 51 52=item I<--help> 53 54Show list of available options. 55 56=item I<--outputdir OUTNAME> 57 58Write output files to the specified directory. Defaults to the current 59directory. 60 61=item I<--includedir DIR> 62 63Add DIR to the search path used by the preprocessor. This option can be 64specified multiple times. 65 66=item I<--parse-idl-tree> 67 68Read internal tree structure from input files rather 69than assuming they contain IDL. 70 71=item I<--dump-idl> 72 73Generate a new IDL file. File will be named OUTNAME.idl. 74 75=item I<--header> 76 77Generate a C header file for the specified interface. Filename defaults to OUTNAME.h. 78 79=item I<--ndr-parser> 80 81Generate a C file and C header containing NDR parsers. The filename for 82the parser defaults to ndr_OUTNAME.c. The header filename will be the 83parser filename with the extension changed from .c to .h. 84 85=item I<--tdr-parser> 86 87Generate a C file and C header containing TDR parsers. The filename for 88the parser defaults to tdr_OUTNAME.c. The header filename will be the 89parser filename with the extension changed from .c to .h. 90 91=item I<--server> 92 93Generate boilerplate for the RPC server that implements 94the interface. Filename defaults to ndr_OUTNAME_s.c. 95 96=item I<--template> 97 98Generate stubs for a RPC server that implements the interface. Output will 99be written to stdout. 100 101=item I<--ws-parser> 102 103Generate an Wireshark dissector (in C) and header file. The dissector filename 104defaults to packet-dcerpc-OUTNAME.c while the header filename defaults to 105packet-dcerpc-OUTNAME.h. 106 107Pidl will read additional data from an Wireshark conformance file if present. 108Such a file should have the same location as the IDL file but with the 109extension I<cnf> rather than I<idl>. See L<Parse::Pidl::Wireshark::Conformance> 110for details on the format of this file. 111 112=item I<--diff> 113 114Parse an IDL file, generate a new IDL file based on the internal data 115structures and see if there are any differences with the original IDL file. 116Useful for debugging pidl. 117 118=item I<--dump-idl-tree> 119 120Tell pidl to dump the internal tree representation of an IDL 121file the to disk. Useful for debugging pidl. 122 123=item I<--dump-ndr-tree> 124 125Tell pidl to dump the internal NDR information tree it generated 126from the IDL file to disk. Useful for debugging pidl. 127 128=item I<--samba3-ndr-client> 129 130Generate client calls for Samba3, to be placed in rpc_client/. Instead of 131calling out to the code in Samba3's rpc_parse/, this will call out to 132Samba4's NDR code instead. 133 134=item I<--samba3-ndr-server> 135 136Generate server calls for Samba3, to be placed in rpc_server/. Instead of 137calling out to the code in Samba3's rpc_parse/, this will call out to 138Samba4's NDR code instead. 139 140=back 141 142=head1 IDL SYNTAX 143 144IDL files are always preprocessed using the C preprocessor. 145 146Pretty much everything in an interface (the interface itself, functions, 147parameters) can have attributes (or properties whatever name you give them). 148Attributes always prepend the element they apply to and are surrounded 149by square brackets ([]). Multiple attributes are separated by comma's; 150arguments to attributes are specified between parentheses. 151 152See the section COMPATIBILITY for the list of attributes that 153pidl supports. 154 155C-style comments can be used. 156 157=head2 CONFORMANT ARRAYS 158 159A conformant array is one with that ends in [*] or []. The strange 160things about conformant arrays are that they can only appear as the last 161element of a structure (unless there is a pointer to the conformant array, 162of course) and the array size appears before the structure itself on the wire. 163 164So, in this example: 165 166 typedef struct { 167 long abc; 168 long count; 169 long foo; 170 [size_is(count)] long s[*]; 171 } Struct1; 172 173it appears like this: 174 175 [size_is] [abc] [count] [foo] [s...] 176 177the first [size_is] field is the allocation size of the array, and 178occurs before the array elements and even before the structure 179alignment. 180 181Note that size_is() can refer to a constant, but that doesn't change 182the wire representation. It does not make the array a fixed array. 183 184midl.exe would write the above array as the following C header: 185 186 typedef struct { 187 long abc; 188 long count; 189 long foo; 190 long s[1]; 191 } Struct1; 192 193pidl takes a different approach, and writes it like this: 194 195 typedef struct { 196 long abc; 197 long count; 198 long foo; 199 long *s; 200 } Struct1; 201 202=head2 VARYING ARRAYS 203 204A varying array looks like this: 205 206 typedef struct { 207 long abc; 208 long count; 209 long foo; 210 [size_is(count)] long *s; 211 } Struct1; 212 213This will look like this on the wire: 214 215 [abc] [count] [foo] [PTR_s] [count] [s...] 216 217=head2 FIXED ARRAYS 218 219A fixed array looks like this: 220 221 typedef struct { 222 long s[10]; 223 } Struct1; 224 225The NDR representation looks just like 10 separate long 226declarations. The array size is not encoded on the wire. 227 228pidl also supports "inline" arrays, which are not part of the IDL/NDR 229standard. These are declared like this: 230 231 typedef struct { 232 uint32 foo; 233 uint32 count; 234 uint32 bar; 235 long s[count]; 236 } Struct1; 237 238This appears like this: 239 240 [foo] [count] [bar] [s...] 241 242Fixed arrays are an extension added to support some of the strange 243embedded structures in security descriptors and spoolss. 244 245This section is by no means complete. See the OpenGroup and MSDN 246 documentation for additional information. 247 248=head1 COMPATIBILITY WITH MIDL 249 250=head2 Missing features in pidl 251 252The following MIDL features are not (yet) implemented in pidl 253or are implemented with an incompatible interface: 254 255=over 256 257=item * 258 259Asynchronous communication 260 261=item * 262 263Typelibs (.tlb files) 264 265=item * 266 267Datagram support (ncadg_*) 268 269=back 270 271=head2 Supported attributes and statements 272 273in, out, ref, length_is, switch_is, size_is, uuid, case, default, string, 274unique, ptr, pointer_default, v1_enum, object, helpstring, range, local, 275call_as, endpoint, switch_type, progid, coclass, iid_is, represent_as, 276transmit_as, import, include. 277 278=head2 PIDL Specific properties 279 280=over 4 281 282=item public 283 284The [public] property on a structure or union is a pidl extension that 285forces the generated pull/push functions to be non-static. This allows 286you to declare types that can be used between modules. If you don't 287specify [public] then pull/push functions for other than top-level 288functions are declared static. 289 290=item noprint 291 292The [noprint] property is a pidl extension that allows you to specify 293that pidl should not generate a ndr_print_*() function for that 294structure or union. This is used when you wish to define your own 295print function that prints a structure in a nicer manner. A good 296example is the use of [noprint] on dom_sid, which allows the 297pretty-printing of SIDs. 298 299=item value 300 301The [value(expression)] property is a pidl extension that allows you 302to specify the value of a field when it is put on the wire. This 303allows fields that always have a well-known value to be automatically 304filled in, thus making the API more programmer friendly. The 305expression can be any C expression. 306 307=item relative 308 309The [relative] property can be supplied on a pointer. When it is used 310it declares the pointer as a spoolss style "relative" pointer, which 311means it appears on the wire as an offset within the current 312encapsulating structure. This is not part of normal IDL/NDR, but it is 313a very useful extension as it avoids the manual encoding of many 314complex structures. 315 316=item subcontext(length) 317 318Specifies that a size of I<length> 319bytes should be read, followed by a blob of that size, 320which will be parsed as NDR. 321 322=item flag 323 324Specify boolean options, mostly used for 325low-level NDR options. Several options 326can be specified using the | character. 327Note that flags are inherited by substructures! 328 329=item nodiscriminant 330 331The [nodiscriminant] property on a union means that the usual uint16 332discriminent field at the start of the union on the wire is 333omitted. This is not normally allowed in IDL/NDR, but is used for some 334spoolss structures. 335 336=item charset(name) 337 338Specify that the array or string uses the specified 339charset. If this attribute is specified, pidl will 340take care of converting the character data from this format 341to the host format. Commonly used values are UCS2, DOS and UTF8. 342 343=back 344 345=head2 Unsupported MIDL properties or statements 346 347aggregatable, appobject, async_uuid, bindable, control, cpp_quote, 348defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface, 349displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext, 350helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib, 351includelib, last_is, lcid, licensed, max_is, module, 352ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl, 353oleautomation, optional, pragma, propget, propputref, propput, readonly, 354requestedit, restricted, retval, source, uidefault, 355usesgetlasterror, vararg, vi_progid, wire_marshal. 356 357=head1 EXAMPLES 358 359 # Generating an Wireshark parser 360 $ ./pidl --ws-parser -- atsvc.idl 361 362 # Generating a TDR parser and header 363 $ ./pidl --tdr-parser --header -- regf.idl 364 365 # Generating a Samba3 client and server 366 $ ./pidl --samba3-ndr-client --samba3-ndr-server -- dfs.idl 367 368 # Generating a Samba4 NDR parser, client and server 369 $ ./pidl --ndr-parser --ndr-client --ndr-server -- samr.idl 370 371=head1 SEE ALSO 372 373L<http://msdn.microsoft.com/library/en-us/rpc/rpc/field_attributes.asp>, 374L<http://wiki.wireshark.org/DCE/RPC>, 375L<http://www.samba.org/>, 376L<yapp(1)> 377 378=head1 LICENSE 379 380pidl is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>. 381 382=head1 AUTHOR 383 384pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim Potter and Jelmer 385Vernooij. The current maintainer is Jelmer Vernooij. 386 387This manpage was written by Jelmer Vernooij, partially based on the original 388pidl README by Andrew Tridgell. 389 390=cut 391 392 393use strict; 394use FindBin qw($RealBin); 395use lib "$RealBin"; 396use lib "$RealBin/lib"; 397use Getopt::Long; 398use File::Basename; 399use Parse::Pidl; 400use Parse::Pidl::Util; 401use Parse::Pidl::ODL; 402 403##################################################################### 404# save a data structure into a file 405sub SaveStructure($$) 406{ 407 my($filename,$v) = @_; 408 FileSave($filename, Parse::Pidl::Util::MyDumper($v)); 409} 410 411##################################################################### 412# load a data structure from a file (as saved with SaveStructure) 413sub LoadStructure($) 414{ 415 my $f = shift; 416 my $contents = FileLoad($f); 417 defined $contents || return undef; 418 return eval "$contents"; 419} 420 421##################################################################### 422# read a file into a string 423sub FileLoad($) 424{ 425 my($filename) = shift; 426 local(*INPUTFILE); 427 open(INPUTFILE, $filename) || return undef; 428 my($saved_delim) = $/; 429 undef $/; 430 my($data) = <INPUTFILE>; 431 close(INPUTFILE); 432 $/ = $saved_delim; 433 return $data; 434} 435 436##################################################################### 437# write a string into a file 438sub FileSave($$) 439{ 440 my($filename) = shift; 441 my($v) = shift; 442 local(*FILE); 443 open(FILE, ">$filename") || die "can't open $filename"; 444 print FILE $v; 445 close(FILE); 446} 447 448my(@opt_incdirs) = (); 449my($opt_help) = 0; 450my($opt_parse_idl_tree) = 0; 451my($opt_dump_idl_tree); 452my($opt_dump_ndr_tree); 453my($opt_dump_idl) = 0; 454my($opt_uint_enums) = 0; 455my($opt_diff) = 0; 456my($opt_header); 457my($opt_samba3_header); 458my($opt_samba3_parser); 459my($opt_samba3_server); 460my($opt_samba3_ndr_client); 461my($opt_samba3_ndr_server); 462my($opt_template) = 0; 463my($opt_client); 464my($opt_server); 465my($opt_ndr_parser); 466my($opt_tdr_parser); 467my($opt_ws_parser); 468my($opt_swig); 469my($opt_dcom_proxy); 470my($opt_com_header); 471my($opt_ejs); 472my($opt_quiet) = 0; 473my($opt_outputdir) = '.'; 474my($opt_verbose) = 0; 475my($opt_warn_compat) = 0; 476 477######################################### 478# display help text 479sub ShowHelp() 480{ 481print "perl IDL parser and code generator 482Copyright (C) Andrew Tridgell <tridge\@samba.org> 483Copyright (C) Jelmer Vernooij <jelmer\@samba.org> 484 485Usage: pidl [options] [--] <idlfile> [<idlfile>...] 486 487Generic Options: 488 --help this help page 489 --outputdir=OUTDIR put output in OUTDIR/ [.] 490 --warn-compat warn about incompatibility with other compilers 491 --quiet be quiet 492 --verbose be verbose 493 --includedir DIR search DIR for included files 494 495Debugging: 496 --dump-idl-tree[=FILE] dump internal representation to file [BASENAME.pidl] 497 --parse-idl-tree read internal representation instead of IDL 498 --dump-ndr-tree[=FILE] dump internal NDR data tree to file [BASENAME.ndr] 499 --dump-idl regenerate IDL file 500 --diff run diff on original IDL and dumped output 501 502Samba 4 output: 503 --header[=OUTFILE] create generic header file [BASENAME.h] 504 --uint-enums don't use C enums, instead use uint* types 505 --ndr-parser[=OUTFILE] create a C NDR parser [ndr_BASENAME.c] 506 --client[=OUTFILE] create a C NDR client [ndr_BASENAME_c.c] 507 --tdr-parser[=OUTFILE] create a C TDR parser [tdr_BASENAME.c] 508 --ejs[=OUTFILE] create ejs wrapper file [BASENAME_ejs.c] 509 --swig[=OUTFILE] create swig wrapper file [BASENAME.i] 510 --server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c] 511 --template print a template for a pipe 512 --dcom-proxy[=OUTFILE] create DCOM proxy [ndr_BASENAME_p.c] 513 --com-header[=OUTFILE] create header for COM [com_BASENAME.h] 514 515Samba 3 output: 516 --samba3-ndr-client[=OUTF] create client calls for Samba3 517 using Samba4's NDR code [cli_BASENAME.c] 518 --samba3-ndr-server[=OUTF] create server call wrapper for Samba3 519 using Samba4's NDR code [srv_BASENAME.c] 520 521Wireshark parsers: 522 --ws-parser[=OUTFILE] create Wireshark parser and header 523\n"; 524 exit(0); 525} 526 527# main program 528my $result = GetOptions ( 529 'help|h|?' => \$opt_help, 530 'outputdir=s' => \$opt_outputdir, 531 'dump-idl' => \$opt_dump_idl, 532 'dump-idl-tree:s' => \$opt_dump_idl_tree, 533 'parse-idl-tree' => \$opt_parse_idl_tree, 534 'dump-ndr-tree:s' => \$opt_dump_ndr_tree, 535 'uint-enums' => \$opt_uint_enums, 536 'samba3-ndr-client:s' => \$opt_samba3_ndr_client, 537 'samba3-ndr-server:s' => \$opt_samba3_ndr_server, 538 'header:s' => \$opt_header, 539 'server:s' => \$opt_server, 540 'tdr-parser:s' => \$opt_tdr_parser, 541 'template' => \$opt_template, 542 'ndr-parser:s' => \$opt_ndr_parser, 543 'client:s' => \$opt_client, 544 'ws-parser:s' => \$opt_ws_parser, 545 'ejs' => \$opt_ejs, 546 'diff' => \$opt_diff, 547 'swig:s' => \$opt_swig, 548 'dcom-proxy:s' => \$opt_dcom_proxy, 549 'com-header:s' => \$opt_com_header, 550 'quiet' => \$opt_quiet, 551 'verbose' => \$opt_verbose, 552 'warn-compat' => \$opt_warn_compat, 553 'includedir=s@' => \@opt_incdirs 554 ); 555 556if (not $result) { 557 exit(1); 558} 559 560if ($opt_help) { 561 ShowHelp(); 562 exit(0); 563} 564 565sub process_file($) 566{ 567 my $idl_file = shift; 568 my $outputdir = $opt_outputdir; 569 my $pidl; 570 my $ndr; 571 572 my $basename = basename($idl_file, ".idl"); 573 574 unless ($opt_quiet) { print "Compiling $idl_file\n"; } 575 576 if ($opt_parse_idl_tree) { 577 $pidl = LoadStructure($idl_file); 578 defined $pidl || die "Failed to load $idl_file"; 579 } else { 580 require Parse::Pidl::IDL; 581 582 $pidl = Parse::Pidl::IDL::parse_file($idl_file, \@opt_incdirs); 583 @$pidl || die "Failed to parse $idl_file"; 584 require Parse::Pidl::Typelist; 585 Parse::Pidl::Typelist::LoadIdl($pidl); 586 } 587 588 if (defined($opt_dump_idl_tree)) { 589 my($pidl_file) = ($opt_dump_idl_tree or "$outputdir/$basename.pidl"); 590 SaveStructure($pidl_file, $pidl) or die "Failed to save $pidl_file\n"; 591 } 592 593 if ($opt_uint_enums) { 594 Parse::Pidl::Util::setUseUintEnums(1); 595 } 596 597 if ($opt_dump_idl) { 598 require Parse::Pidl::Dump; 599 print Parse::Pidl::Dump($pidl); 600 } 601 602 if ($opt_diff) { 603 my($tempfile) = "$outputdir/$basename.tmp"; 604 FileSave($tempfile, IdlDump::Dump($pidl)); 605 system("diff -wu $idl_file $tempfile"); 606 unlink($tempfile); 607 } 608 609 610 my $comh_filename = ($opt_com_header or "$outputdir/com_$basename.h"); 611 if (defined($opt_com_header)) { 612 require Parse::Pidl::Samba4::COM::Header; 613 my $res = Parse::Pidl::Samba4::COM::Header::Parse($pidl,"$outputdir/ndr_$basename.h"); 614 if ($res) { 615 FileSave($comh_filename, $res); 616 } 617 } 618 619 if (defined($opt_dcom_proxy)) { 620 require Parse::Pidl::Samba4::COM::Proxy; 621 my $res = Parse::Pidl::Samba4::COM::Proxy::Parse($pidl,$comh_filename); 622 if ($res) { 623 my ($client) = ($opt_dcom_proxy or "$outputdir/$basename\_p.c"); 624 FileSave($client, $res); 625 } 626 } 627 628 if ($opt_warn_compat) { 629 require Parse::Pidl::Compat; 630 Parse::Pidl::Compat::Check($pidl); 631 } 632 633 $pidl = Parse::Pidl::ODL::ODL2IDL($pidl); 634 635 if (defined($opt_ws_parser) or 636 defined($opt_client) or defined($opt_server) or 637 defined($opt_ndr_parser) or defined($opt_ejs) or 638 defined($opt_dump_ndr_tree) or defined($opt_samba3_header) or 639 defined($opt_samba3_parser) or defined($opt_samba3_server) or 640 defined($opt_swig) or defined($opt_samba3_ndr_client) or 641 defined($opt_samba3_ndr_server)) { 642 require Parse::Pidl::NDR; 643 $ndr = Parse::Pidl::NDR::Parse($pidl); 644 } 645 646 if (defined($opt_dump_ndr_tree)) { 647 my($ndr_file) = ($opt_dump_ndr_tree or "$outputdir/$basename.ndr"); 648 SaveStructure($ndr_file, $ndr) or die "Failed to save $ndr_file\n"; 649 } 650 651 my $gen_header = ($opt_header or "$outputdir/$basename.h"); 652 if (defined($opt_header)) { 653 require Parse::Pidl::Samba4::Header; 654 FileSave($gen_header, Parse::Pidl::Samba4::Header::Parse($pidl)); 655 } 656 657 my $h_filename = "$outputdir/ndr_$basename.h"; 658 if (defined($opt_client)) { 659 require Parse::Pidl::Samba4::NDR::Client; 660 my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c"); 661 my ($c_header) = $c_client; 662 $c_header =~ s/\.c$/.h/; 663 664 my ($srcd,$hdrd) = Parse::Pidl::Samba4::NDR::Client::Parse( 665 $ndr,$gen_header,$h_filename,$c_header); 666 667 FileSave($c_client, $srcd); 668 FileSave($c_header, $hdrd); 669 } 670 671 if (defined($opt_swig)) { 672 require Parse::Pidl::Samba4::SWIG; 673 my($filename) = ($opt_swig or "$outputdir/$basename.i"); 674 my $code = Parse::Pidl::Samba4::SWIG::Parse($ndr, $basename, "$outputdir/ndr_$basename\_c.h", $gen_header); 675 FileSave($filename, $code); 676 } 677 678 if (defined($opt_ejs)) { 679 require Parse::Pidl::Samba4::EJS; 680 my ($hdr,$prsr) = Parse::Pidl::Samba4::EJS::Parse($ndr, $h_filename); 681 FileSave("$outputdir/ndr_$basename\_ejs.c", $prsr); 682 FileSave("$outputdir/ndr_$basename\_ejs.h", $hdr); 683 } 684 685 if (defined($opt_server)) { 686 require Parse::Pidl::Samba4::NDR::Server; 687 my $dcom = ""; 688 689 foreach (@{$pidl}) { 690 next if ($_->{TYPE} ne "INTERFACE"); 691 692 if (Parse::Pidl::Util::has_property($_, "object")) { 693 require Parse::Pidl::Samba4::COM::Stub; 694 $dcom .= Parse::Pidl::Samba4::COM::Stub::ParseInterface($_); 695 } 696 } 697 698 FileSave(($opt_server or "$outputdir/ndr_$basename\_s.c"), Parse::Pidl::Samba4::NDR::Server::Parse($ndr,$h_filename)); 699 700 if ($dcom ne "") { 701 $dcom = " 702#include \"includes.h\" 703#include \"$h_filename\" 704#include \"rpc_server/dcerpc_server.h\" 705#include \"rpc_server/common/common.h\" 706 707$dcom 708"; 709 FileSave("$outputdir/$basename\_d.c", $dcom); 710 } 711 } 712 713 if (defined($opt_ndr_parser)) { 714 my $parser_fname = ($opt_ndr_parser or "$outputdir/ndr_$basename.c"); 715 require Parse::Pidl::Samba4::NDR::Parser; 716 my ($header,$parser) = Parse::Pidl::Samba4::NDR::Parser::Parse($ndr, $gen_header, $h_filename); 717 718 719 FileSave($parser_fname, $parser); 720 FileSave($h_filename, $header); 721 722 } 723 724 if (defined($opt_ws_parser)) { 725 require Parse::Pidl::Wireshark::NDR; 726 my($eparser) = ($opt_ws_parser or "$outputdir/packet-dcerpc-$basename.c"); 727 my $eheader = $eparser; 728 $eheader =~ s/\.c$/\.h/; 729 my $cnffile = $idl_file; 730 $cnffile =~ s/\.idl$/\.cnf/; 731 732 my ($dp, $dh) = Parse::Pidl::Wireshark::NDR::Parse($ndr, $idl_file, $eheader, $cnffile); 733 FileSave($eparser, $dp) if defined($dp); 734 FileSave($eheader, $dh) if defined($dh); 735 } 736 737 if (defined($opt_tdr_parser)) { 738 my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c"); 739 my $tdr_header = $tdr_parser; 740 $tdr_header =~ s/\.c$/\.h/; 741 require Parse::Pidl::Samba4::TDR; 742 my ($hdr,$prsr) = Parse::Pidl::Samba4::TDR::Parser($pidl, $tdr_header, $gen_header); 743 FileSave($tdr_parser, $prsr); 744 FileSave($tdr_header, $hdr); 745 } 746 747 if ($opt_template) { 748 require Parse::Pidl::Samba4::Template; 749 print Parse::Pidl::Samba4::Template::Parse($pidl); 750 } 751 752 if (defined($opt_samba3_ndr_client)) { 753 my $client = ($opt_samba3_ndr_client or "$outputdir/cli_$basename.c"); 754 my $header = $client; $header =~ s/\.c$/\.h/; 755 require Parse::Pidl::Samba3::ClientNDR; 756 my ($c_code,$h_code) = Parse::Pidl::Samba3::ClientNDR::Parse($ndr, $header, $h_filename); 757 FileSave($client, $c_code); 758 FileSave($header, $h_code); 759 } 760 761 if (defined($opt_samba3_ndr_server)) { 762 my $server = ($opt_samba3_ndr_server or "$outputdir/srv_$basename.c"); 763 my $header = $server; $header =~ s/\.c$/\.h/; 764 require Parse::Pidl::Samba3::ServerNDR; 765 my ($c_code,$h_code) = Parse::Pidl::Samba3::ServerNDR::Parse($ndr, $header, $h_filename); 766 FileSave($server, $c_code); 767 FileSave($header, $h_code); 768 } 769 770} 771 772if (scalar(@ARGV) == 0) { 773 print "pidl: no input files\n"; 774 exit(1); 775} 776 777process_file($_) foreach (@ARGV); 778