~ubuntu-branches/ubuntu/maverick/samba/maverick-security

« back to all changes in this revision

Viewing changes to source/pidl/pidl

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2009-03-03 22:02:23 UTC
  • mfrom: (0.28.1 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090303220223-3bdlm2d9fwx1p1ye
Tags: 2:3.3.1-1ubuntu1
* Merge from Debian unstable (LP: #337094), remaining changes:
  + debian/patches/VERSION.patch:
    - setup SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access. 
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/mksambapasswd.awk:
    - Do not add user with UID less than 1000 to smbpasswd.
  + debian/control:
    - Make libwbclient0 replace/conflict with hardy's likewise-open.
    - Don't build against ctdb.
  + debian/rules:
    - enable "native" PIE hardening.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
* Dropped changes, merged in Debian:
  + debian/libpam-smbpass.pam-config, debian/libpam-smbpass.postinst,
    debian/libpam-smbpass.prerm, debian/libpam-smbpass.files,
    debian/rules:
    - Make libpam-smbpasswd depend on libpam-runtime to allow 
      libpam-smbpasswd for auto-configuration.
  + debian/control:
    - Provide a config block for the new PAM framework to auto-configure
      itself
  + debian/samba.postinst:
    - When populating the new sambashare group, it is not an error
      if the user simply does not exist; test for this case and let
      the install continue instead of aborting.
  + debian/winbind.files:
    - include additional files

Show diffs side-by-side

added added

removed removed

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