Print this page
5516 perl problems in libbsm/auditxml
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libbsm/auditxml
+++ new/usr/src/lib/libbsm/auditxml
1 1 #!/usr/perl5/bin/perl -w
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 #
23 23 # Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 # Use is subject to license terms.
25 25 #
26 26
27 27 # auditxml takes the audit record description (.xml file) and
28 28 # generates the files needed for the C audit api.
29 29
30 30 my $prog = $0; $prog =~ s|.*/||g;
31 31 my $usage = <<EOF;
32 32
33 33 Usage: $prog [options] <xml-input-file>
34 34 Options:
35 35 -d Enable debug output
36 36 -e pfx Internal event prefix (default: AUE)
37 37 -i pfx Interface prefix (default: adt)
38 38 External event prefix is uppercase version of this string.
39 39 -o dir Output directory (default: current dir)
40 40
41 41 EOF
42 42
43 43 use auditxml;
44 44 use Getopt::Std;
45 45 use strict;
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
46 46
47 47 our $debug = 0; # normal use is to set via the file being parsed.
48 48 # <debug set="on"/> or <debug set="off"/> or <debug/>
49 49 # if the set attribute is omitted, debug state is toggled
50 50 # Override with appDebug, but toggle won't do what you
51 51 # want.
52 52 my $appDebug = 0; # used after return from "new auditxml";
53 53
54 54 # Process command-line options
55 55 our ($opt_d, $opt_e, $opt_i, $opt_o);
56 +$opt_e = "";
57 +$opt_i = "";
58 +$opt_o = "";
56 59 if (!getopts('de:i:o:') || $#ARGV != 0) {
57 60 die $usage;
58 61 }
59 62 my $outdir = $opt_o || ".";
60 63 my $pfx_adt = lc($opt_i) || "adt";
61 64 my $pfx_ADT = uc($pfx_adt);
62 65 my $pfx_AUE = uc($opt_e) || "AUE";
63 66
64 67 $appDebug = $opt_d;
65 68
66 69 my $uniLabel = "adr";
67 70 my $xlateUniLabelInc = 0;
68 71
69 72
70 73 # where everything comes from and where it goes:
71 74
72 75 my $xlateFile = "$outdir/${pfx_adt}_xlate.c";
73 76 my $headerFile = "$outdir/${pfx_adt}_event_N.h";
74 77
75 78 my $filename = $ARGV[0]; # input XML file
76 79 my $doc = new auditxml ($filename);
77 80 $filename =~ s|.*/||g;
78 81
79 82 $debug = $appDebug;
80 83
81 84 my $genNotice = "
82 85 DO NOT EDIT. This file is auto generated by the Solaris Audit
83 86 system from $filename.
84 87
85 88 See http://opensolaris.org/os/project/audit/
86 89 ";
87 90
88 91 # trim leading/trailing newlines
89 92 $genNotice =~ s/^\n//s;
90 93 $genNotice =~ s/\n$//s;
91 94
92 95 my %xlateEventTable = ();
93 96 my @xlateTypeList = ();
94 97 my %xlateTypeList = ();
95 98 my %eventAPI = ();
96 99 my %eventExtra = ();
97 100 my %headers = ();
98 101 my %externalIdNo = ();
99 102 my @outputState = ();
100 103 my %nameTranslation = ();
101 104 my @xlateDefaults = ();
102 105 my %xlateDefault = ();
103 106 my %msg_list = ();
104 107
105 108 my $event;
106 109 while ($event = $doc->getNextEvent()) {
107 110 my $eventId = $event->getId();
108 111 my $eventHeader = $event->getHeader();
109 112 my $idNo = $event->getIdNo();
110 113 $externalIdNo{$eventId} = $idNo;
111 114 addHeader($eventHeader) if defined ($eventHeader);
112 115 my $super;
113 116 my $omit = $event->getOmit();
114 117 my $eventType = '';
115 118 if ($super = $event->getSuperClass()) {
116 119 $event = $super;
117 120 $eventType = 'instance';
118 121 } else {
119 122 $eventType = $event->getType();
120 123 }
121 124
122 125 # header file for API use
123 126 generateAPIFile($event, $eventId, $eventType, $eventHeader, $idNo)
124 127 unless $omit eq 'always';
125 128
126 129 # c file table for translation
127 130 generateTableC($event, $eventId, $eventType, $eventHeader, $omit);
128 131 }
129 132
130 133 my $textList;
131 134 while ($textList = $doc->getNextMsgId()) {
132 135 generateMsgLists($textList); # enum -> text mappings
133 136 }
134 137
135 138 printTableC($xlateFile);
136 139 printAPIFile($headerFile, $doc);
137 140
138 141 exit 0;
139 142
140 143
141 144 sub printTableC {
142 145 my $file = shift;
143 146
144 147 unless (open(Cfile, ">$file")) {
145 148 print STDERR "can't open output file ($file): $!\n";
146 149 return;
147 150 }
148 151
149 152 my $notice = $genNotice;
150 153 $notice =~ s/\n/\n * /gs;
151 154 $notice =~ s/\s+\n/\n/gs;
152 155 print Cfile <<EOF;
153 156 /*
154 157 * $notice
155 158 */
156 159
157 160 #include <bsm/libbsm.h>
158 161 #include <adt_xlate.h>
159 162 #include <libintl.h>
160 163
161 164 EOF
162 165 print Cfile "#ifndef _PRAUDIT\n";
163 166 print Cfile "/* Internal data type definitions */\n\n";
164 167 my $extDef;
165 168 foreach $extDef (@xlateTypeList) {
166 169 print Cfile "static $extDef\n";
167 170 }
168 171 @xlateTypeList = ();
169 172
170 173 print Cfile "\n/* External event structure to internal event structure */\n\n";
171 174
172 175 my @pointers = ();
173 176
174 177 foreach my $eventId (sort keys %xlateEventTable) {
175 178 if ($xlateEventTable{$eventId}) {
176 179 my ($ref1, $eventType, $firstToken, $eventHeader) =
177 180 @{$xlateEventTable{$eventId}};
178 181 my @entries = @$ref1;
179 182 my $entry;
180 183 my $entries = $#entries;
181 184 my $count = $entries + 1;
182 185 my $externalName = $nameTranslation{$eventId};
183 186 my $externalRoot = $externalName;
184 187 $externalRoot =~ s/${pfx_AUE}_//;
185 188 my $structName = "XX_$externalRoot";
186 189 my $root = $eventId;
187 190 $root =~ s/${pfx_AUE}_//;
188 191 my $externalId = $eventId;
189 192 $externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
190 193
191 194 unless ($eventType eq 'generic') {
192 195 print Cfile "static struct entry $structName\[$count\] = {\n";
193 196 foreach $entry (@entries) {
194 197 if ($entries--) {
195 198 $entry =~ s/EOL/,/;
196 199 }
197 200 else {
198 201 $entry =~ s/EOL//;
199 202 }
200 203 $entry =~ s/selfReference/$structName/;
201 204 print Cfile "\t$entry\n";
202 205 }
203 206 print Cfile "};\n";
204 207
205 208 print Cfile "static struct translation X_$externalRoot = {\n";
206 209 push (@pointers, "X_$externalRoot");
207 210
208 211 print Cfile "\t0,\n"; # tx_offsetsCalculated = 0
209 212 print Cfile "\t$externalId,\n";
210 213 print Cfile "\t$externalName,\n";
211 214
212 215 print Cfile "\t$count,\n";
213 216 print Cfile "\t&XX_$externalRoot\[$firstToken\],\n";
214 217 print Cfile "\t&XX_$externalRoot\[0\]\n};\n";
215 218 }
216 219 } else {
217 220 print STDERR "expected entry for $eventId but none found\n";
218 221 }
219 222 }
220 223
221 224 my $count = $#pointers + 2;
222 225 print Cfile "adt_translation_t *${pfx_adt}_xlate_table[$count] = {\n";
223 226
224 227 my $firstEvent = 1;
225 228 foreach my $eventId (@pointers) {
226 229 if ($firstEvent) {
227 230 $firstEvent = 0;
228 231 }
229 232 else {
230 233 print Cfile ",\n";
231 234 }
232 235 print Cfile "\t&$eventId";
233 236 }
234 237 print Cfile ",\n\tNULL\n};\n";
235 238
236 239 # generate the Event preload() function
237 240
238 241 print Cfile <<EOF;
239 242
240 243 void
241 244 ${pfx_adt}_preload(au_event_t event_id, adt_event_data_t *event_data)
242 245 {
243 246 switch (event_id) {
244 247 EOF
245 248
246 249 foreach my $id (@xlateDefaults) {
247 250 my $adtID = $id;
248 251 $adtID =~ s/${pfx_AUE}/${pfx_ADT}/;
249 252
250 253 print Cfile <<EOF;
251 254 case $adtID:
252 255 EOF
253 256 my @preloads = @{$xlateDefault{$id}};
254 257 while (@preloads) {
255 258 my $fieldName = shift @preloads;
256 259 my $default = shift @preloads;
257 260 $id =~ s/${pfx_AUE}_/${pfx_adt}_/;
258 261
259 262 print Cfile <<EOF;
260 263 event_data->$id.$fieldName = $default;
261 264 EOF
262 265 }
263 266
264 267 print Cfile <<EOF;
265 268 break;
266 269 EOF
267 270 }
268 271
269 272 print Cfile <<EOF;
270 273 default:
271 274 break;
272 275 }
273 276 }
274 277 #endif
275 278
276 279 EOF
277 280
278 281 print Cfile "/* message lists */\n\n";
279 282 my $listName;
280 283 my @listName;
281 284 foreach $listName (sort keys %msg_list) {
282 285 my ($listRef, $headref) = @{$msg_list{$listName}};
283 286 my ($header, $start, $public, $deprecated) = @$headref;
284 287
285 288 my @listValue = @$listRef;
286 289 my $listValue;
287 290 my $listLength = $#listValue + 1;
288 291
289 292 $listName = 'NULL' if ($#listValue < 0);
290 293
291 294 push (@listName, [$listName, $listLength - 1, $start, $public]);
292 295
293 296 next if ($#listValue < 0);
294 297
295 298 print Cfile "/* Deprecated message list */\n" if ($deprecated);
296 299 print Cfile "static char *msg_$listName\[$listLength] = {\n";
297 300
298 301 my $ffirst = 1;
299 302 foreach $listValue (@listValue) {
300 303 print Cfile ",\n" unless $ffirst;
301 304 $ffirst = 0;
302 305 my ($id, $text) = split(/\s*::\s*/, $listValue);
303 306 if ($text) {
304 307 print Cfile "\t\"$text\"";
305 308 }
306 309 else {
307 310 print Cfile "\tNULL";
308 311 }
309 312 }
310 313 print Cfile "\n};\n";
311 314 }
312 315
313 316 if ($#listName >= 0) {
314 317 print Cfile "\nstruct msg_text ${pfx_adt}_msg_text[", $#listName + 1,
315 318 "] = {\n";
316 319 my $ffirst = 1;
317 320 foreach $listName (@listName) {
318 321 my ($name, $max, $start) = @$listName;
319 322 $start = -$start if $start;
320 323 print Cfile ",\n" unless $ffirst;
321 324 $ffirst = 0;
322 325 $name = "msg_$name" if ($name ne 'NULL');
323 326 print Cfile "\t{0, $max, $name, $start}";
324 327 }
325 328 print Cfile "\n};\n";
326 329 }
327 330
328 331 close Cfile;
329 332 }
330 333
331 334 sub printAPIFile {
332 335 my $file = shift;
333 336 my $xmlDoc = shift;
334 337
335 338 my @Hfile;
336 339 @Hfile = openHeaderFiles($file);
337 340
338 341 my $notice = $genNotice;
339 342 $notice =~ s/\n/\n * /gs;
340 343 $notice =~ s/\s+\n/\n/gs;
341 344
342 345 foreach my $header (keys %headers) {
343 346 next unless $Hfile[$header];
344 347 *Hfile = $Hfile[$header];
345 348 my $include = "adt.h";
346 349 my $adt_event_n = "_${pfx_ADT}_EVENT_H";
347 350 if ($header > 0) {
348 351 $include = "${pfx_adt}_event.h";
349 352 $adt_event_n = "_${pfx_ADT}_EVENT_".$header."_H";
350 353 }
351 354 print Hfile <<EOF;
352 355 /*
353 356 * $notice
354 357 */
355 358
356 359 #ifndef $adt_event_n
357 360 #define $adt_event_n
358 361
359 362 #include <bsm/$include>
360 363
361 364 #ifdef __cplusplus
362 365 extern "C" {
363 366 #endif
364 367
365 368 /*
366 369 * adt_put_event() status values. Positive values are for kernel-generated
367 370 * failure, -1 for user-space. For ADT_SUCCESS, the adt_put_event() return_val
368 371 * is not used; the convention is to set it to ADT_SUCCESS.
369 372 */
370 373 #define ADT_SUCCESS 0
371 374 #define ADT_FAILURE -1
372 375
373 376 EOF
374 377 }
375 378
376 379 foreach my $listName (sort keys %msg_list) {
377 380 my $shortName = uc $listName;
378 381 $shortName =~ s/_TEXT//;
379 382
380 383 my ($listRef, $headref) = @{$msg_list{$listName}};
381 384 my ($header, $start, $public, $deprecated) = @$headref;
382 385 next unless $Hfile[$header];
383 386 *Hfile = $Hfile[$header];
384 387
385 388 print Hfile "/* Deprecated message list */\n" if $deprecated;
386 389 print Hfile "#define\t${pfx_ADT}_$shortName\t$start\n" if $start;
387 390
388 391 my @listValue = @$listRef;
389 392 next unless ($#listValue >= 0);
390 393 print Hfile "enum\t${pfx_adt}_$listName", " {\n";
391 394
392 395 my $listValue;
393 396 my $i = 0;
394 397 my $j = $#listValue;
395 398 my $comma = ',';
396 399 foreach $listValue (@listValue) {
397 400 my ($id, $text) = split(/\s*::\s*/, $listValue);
398 401 $comma = '' if $i++ == $j;
399 402 if ($start) {
400 403 $start = " = $start$comma";
401 404 } else {
402 405 $start = "$comma\t";
403 406 }
404 407 $text = "(no token will be generated)" unless $text;
405 408 my $line = "\t${pfx_ADT}_$shortName"."_$id$start\t/* ";
406 409 # ensure whole line does not exceed 80 chars
407 410 my $eline = $line.$text;
408 411 #expand tabs
409 412 1 while $eline =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
410 413 if ((length($eline) > 77) && ($line =~ /\t\t/)) {
411 414 # 77 = 80 - length(" */")
412 415 # strip off double tab so that comment can be longer
413 416 $line =~ s/\t\t/\t/;
414 417 # shorten eline; don't mind where the spaces are removed, it is
415 418 # only $eline length which matters
416 419 $eline =~ s/ {8}//;
417 420 }
418 421 if (length($eline) > 77) { # 80 - length(" */")
419 422 # here we use negative length in substr to leave off from the
420 423 # right side; 74 = 77 - length("...")
421 424 $line .= substr($text, 0, 74 - length($eline));
422 425 # strip off part of last word (already cut)
423 426 $line =~ s/\s(\S+)$/ /;
424 427 $line .= "...";
425 428 } else {
426 429 $line .= $text;
427 430 }
428 431 print Hfile "$line */\n";
429 432 $start = '';
430 433 }
431 434 print Hfile "};\n";
432 435 }
433 436
434 437 # generate defines for external event names
435 438
436 439 foreach my $eventId (sort keys %eventAPI) {
437 440 my ($header, $idNo) = @{$eventExtra{$eventId}};
438 441 unless (defined ($header)) {
439 442 print STDERR "missing header selection for $eventId\n";
440 443 next;
441 444 }
442 445 *Hfile = $Hfile[$header];
443 446 next unless $Hfile[$header];
444 447
445 448 my $l = length($eventId) + 8; # label plus preceding #define\t
446 449 $l = 5 - int(($l + 8)/8);
447 450 $l = 1 if $l < 1;
448 451 my $tab = "\t" x $l;
449 452
450 453 print STDERR "missing id number for $eventId\n" unless $idNo;
451 454
452 455 $eventId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
453 456 print Hfile "#define\t$eventId$tab$idNo\n";
454 457 }
455 458
456 459
457 460 # generate per-event structures
458 461
459 462 foreach my $eventId (sort keys %eventAPI) {
460 463 my ($header, $idNo) = @{$eventExtra{$eventId}};
461 464 my $dataId = $eventId;
462 465 $dataId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
463 466 unless(defined ($header)) {
464 467 print STDERR "$eventId is missing the header assignment\n";
465 468 next;
466 469 }
467 470 *Hfile = $Hfile[$header];
468 471 next unless $Hfile[$header];
469 472
470 473 my $externalId = $eventId;
471 474 $externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
472 475
473 476 print Hfile "\nstruct $dataId {\t/* $externalId */\n";
474 477
475 478 my @entries = @{$eventAPI{$eventId}};
476 479 my $entry;
477 480 if ($#entries < 0) {
478 481 print Hfile "\tint\tdummy;\t/* not used */\n";
479 482 } else {
480 483 foreach $entry (@entries) {
481 484 $entry =~ s/termid/adt_termid_t/;
482 485 print Hfile "\t$entry\n";
483 486 }
484 487 }
485 488 print Hfile "};\n";
486 489 $eventId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
487 490 print Hfile "typedef struct $dataId $eventId","_t;\n";
488 491 }
489 492
490 493 foreach my $header (sort keys %headers) {
491 494 $outputState[$header] = 0;
492 495 }
493 496
494 497 foreach my $eventId (sort keys %eventAPI) {
495 498 my ($header, $idNo) = @{$eventExtra{$eventId}};
496 499 unless(defined ($header)) {
497 500 # don't print duplicate error message
498 501 next;
499 502 }
500 503 *Hfile = $Hfile[$header];
501 504 next unless $Hfile[$header];
502 505 if ($outputState[$header] == 0) {
503 506 $outputState[$header] = 1;
504 507 my $suffix = '';
505 508 $suffix = "_$header" if $header;
506 509 print Hfile "\nunion adt_event_data$suffix {\n";
507 510 }
508 511 my $elementName = $eventId;
509 512 $elementName =~ s/^${pfx_AUE}_/${pfx_adt}_/;
510 513 $eventId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
511 514 $elementName =~ s/_t$//;
512 515
513 516 print Hfile "\t\t$eventId","_t\t$elementName;\n";
514 517 }
515 518 foreach my $header (sort keys %headers) {
516 519 if ($outputState[$header]) {
517 520 *Hfile = $Hfile[$header];
518 521 next unless $Hfile[$header];
519 522 print Hfile "};\n";
520 523 }
521 524 }
522 525 foreach my $header (keys %headers) {
523 526 next unless $Hfile[$header];
524 527 *Hfile = $Hfile[$header];
525 528 my $adt_event_n = "_${pfx_ADT}_EVENT_H";
526 529 if ($header > 0) {
527 530 $adt_event_n = "_${pfx_ADT}_EVENT_".$header."_H";
528 531 }
529 532 print Hfile <<EOF;
530 533
531 534
532 535 #ifndef ${pfx_ADT}_PRIVATE
533 536 #define ${pfx_ADT}_PRIVATE
534 537
535 538 /*
536 539 * These interfaces are project private and will change without
537 540 * notice as needed for the Solaris Audit project.
538 541 */
539 542
540 543 extern void adt_get_auid(const adt_session_data_t *, au_id_t *);
541 544 extern void adt_set_auid(const adt_session_data_t *, const au_id_t);
542 545
543 546 extern void adt_get_mask(const adt_session_data_t *, au_mask_t *);
544 547 extern void adt_set_mask(const adt_session_data_t *, const au_mask_t *);
545 548
546 549 extern void adt_get_termid(const adt_session_data_t *, au_tid_addr_t *);
547 550 extern void adt_set_termid(const adt_session_data_t *,
548 551 const au_tid_addr_t *);
549 552
550 553 extern void adt_get_asid(const adt_session_data_t *, au_asid_t *);
551 554 extern void adt_set_asid(const adt_session_data_t *, const au_asid_t);
552 555 extern au_asid_t adt_get_unique_id(au_id_t);
553 556 extern void adt_load_table(const adt_session_data_t *, adt_translation_t **,
554 557 void (*preload)(au_event_t, adt_event_data_t *));
555 558
556 559 extern void ${pfx_adt}_preload(au_event_t, adt_event_data_t *);
557 560
558 561 extern adt_translation_t *${pfx_adt}_xlate_table[];
559 562
560 563 #endif
561 564
562 565 #ifdef __cplusplus
563 566 }
564 567 #endif
565 568
566 569 #endif /* $adt_event_n */
567 570 EOF
568 571 }
569 572 closeHeaderFiles(@Hfile);
570 573 }
571 574
572 575 sub generateTableC {
573 576 my $event = shift;
574 577 my $eventId = shift;
575 578 my $eventType = shift;
576 579 my $eventHeader = shift;
577 580 my $omit = shift;
578 581
579 582 my %tokenType = (
580 583 #
581 584 # tokenTypes are the ones that are actually defined
582 585 # for use in adt.xml audit records
583 586 #
584 587
585 588 # 'acl' => 'AUT_ACL', # not defined
586 589 # 'arbitrary' => 'AUT_ARBITRARY', # not defined
587 590 # 'arg' => 'AUT_ARG', # not defined
588 591 # 'attr' => 'AUT_ATTR',
589 592 'command' => 'AUT_CMD',
590 593 'command_alt' => 'ADT_CMD_ALT', # dummy token id
591 594 # 'date' => 'AUT_TEXT', # not used
592 595 # 'exec_args' => 'AUT_EXEC_ARGS', # not defined
593 596 # 'exec_env' => 'AUT_EXEC_ENV', # not defined
594 597 # 'exit' => 'AUT_EXIT', # not defined
595 598 'fmri' => 'AUT_FMRI',
596 599 # 'groups' => 'AUT_GROUPS', # not defined
597 600 # 'header' => 'AUT_HEADER', # not defined
598 601 'in_peer' => 'ADT_IN_PEER', # dummy token id
599 602 'in_remote' => 'ADT_IN_REMOTE', # dummy token id
600 603 # 'ipc' => 'AUT_IPC', # not defined
601 604 # 'ipc_perm' => 'AUT_IPC_PERM', # not defined
602 605 'iport' => 'AUT_IPORT',
603 606 'label' => 'AUT_LABEL',
604 607 'newgroups' => 'AUT_NEWGROUPS',
605 608 # 'opaque' => 'AUT_OPAQUE', # not defined
606 609 'path' => 'AUT_PATH',
607 610 'path_list' => '-AUT_PATH', # dummy token id
608 611 'process' => 'AUT_PROCESS',
609 612 'priv_effective' => 'ADT_AUT_PRIV_E', # dummy token id
610 613 'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id
611 614 'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id
612 615 'return' => 'AUT_RETURN',
613 616 # 'seq' => 'AUT_SEQ', # not defined
614 617 # 'socket' => 'AUT_SOCKET', # not defined
615 618 # 'socket-inet' => 'AUT_SOCKET_INET',
616 619 'subject' => 'AUT_SUBJECT',
617 620 'text' => 'AUT_TEXT',
618 621 'tid' => 'AUT_TID',
619 622 # 'trailer' => 'AUT_TRAILER', # not defined
620 623 'uauth' => 'AUT_UAUTH',
621 624 'user' => 'AUT_USER',
622 625 'zonename' => 'AUT_ZONENAME'
623 626 );
624 627
625 628 my @xlateEntryList = ();
626 629
627 630 my $external = $event->getExternal();
628 631 my $internal = $event->getInternal();
629 632
630 633 unless ($external) {
631 634 print STDERR "No external object captured for event $eventId\n";
632 635 return;
633 636 }
634 637 if ($eventType) {
635 638 $nameTranslation{$eventId} = $eventId;
636 639 } else {
637 640 $nameTranslation{$eventId} = $external->getInternalName();
638 641 }
639 642 unless ($internal) {
640 643 print STDERR "No internal object captured for event $eventId\n";
641 644 return;
642 645 }
643 646 my @entryRef = $internal->getEntries();
644 647 my $entryRef;
645 648 my @tokenOrder = ();
646 649 my $firstTokenIndex = 0; # djdj not used yet, djdj BUG!
647 650 # needs to be used by translate table
648 651
649 652 if ($internal->isReorder()) { # prescan the entry list to get the token order
650 653 my @inputOrder;
651 654 foreach $entryRef (@entryRef) {
652 655 my ($intEntry, $entry) = @$entryRef;
653 656 push (@inputOrder, $intEntry->getAttr('order'));
654 657 }
655 658
656 659 my $i; # walk down the inputOrder list once
657 660 my $k = 1; # discover next in line
658 661 my $l = 0; # who should point to next in line
659 662 for ($i = 0; $i <= $#inputOrder; $i++) {
660 663 my $j;
661 664 for ($j = 0; $j <= $#inputOrder; $j++) {
662 665 if ($k == $inputOrder[$j]) {
663 666 if ($k == 1) {
664 667 $firstTokenIndex = $j;
665 668 } else {
666 669 $tokenOrder[$l] = "&(selfReference[$j])";
667 670 }
668 671 $l = $j;
669 672 last;
670 673 }
671 674 }
672 675 $k++;
673 676 }
674 677 $tokenOrder[$l] = 'NULL';
675 678 }
676 679 else { # default order -- input order same as output
677 680 my $i;
678 681 my $j;
679 682 for ($i = 0; $i < $#entryRef; $i++) {
680 683 my $j = $i + 1;
681 684 $tokenOrder[$i] = "&(selfReference[$j])";
682 685 }
683 686 $tokenOrder[$#entryRef] = 'NULL';
684 687 }
685 688
686 689 my $sequence = 0;
687 690 foreach $entryRef (@entryRef) {
688 691 my ($intEntry, $entry) = @$entryRef;
689 692 my $entryId = $entry->getAttr('id');
690 693
691 694 my ($extEntry, $unusedEntry, $tokenId) =
692 695 $external->getEntry($entryId);
693 696 my $opt = $extEntry->getAttr('opt');
694 697
695 698 if ($opt eq 'none') {
696 699 if (defined ($doc->getToken($tokenId))) {
697 700 if (defined ($tokenType{$tokenId})) {
698 701 $tokenId = $tokenType{$tokenId};
699 702 }
↓ open down ↓ |
634 lines elided |
↑ open up ↑ |
700 703 else {
701 704 print STDERR "token id $tokenId not implemented\n";
702 705 }
703 706 }
704 707 else {
705 708 print STDERR "token = $tokenId is undefined\n";
706 709 $tokenId = 'error';
707 710 }
708 711 my ($xlate, $jni) =
709 712 formatTableEntry ('', $tokenId, $eventId, '', 0, 0,
710 - $tokenOrder[$sequence], 'NULL', $omit);
713 + $tokenOrder[$sequence], 'NULL', '', $omit);
711 714 push (@xlateEntryList, $xlate);
712 715 }
713 716 else {
714 717 my $dataType = $extEntry->getAttr('type');
715 718 $dataType =~ s/\s+//g; # remove blanks (char * => char*)
716 719
717 720 my $enumGroup = '';
718 721 if ($dataType =~ /^msg/i) {
719 722 $enumGroup = $dataType;
720 723 $enumGroup =~ s/^msg\s*//i;
721 724 $enumGroup = "${pfx_adt}_" . $enumGroup;
722 725 }
723 726 my $required = ($opt eq 'required') ? 1 : 0;
724 727 my $tsol = 0;
725 728 my $tokenId = $intEntry->getAttr('token');
726 729 my $token;
727 730 my $tokenName;
728 731 my $tokenFormat = $intEntry->getAttr('format');
729 732 if (defined ($tokenFormat)) {
730 733 $tokenFormat = "\"$tokenFormat\"";
731 734 }
732 735 else {
733 736 $tokenFormat = 'NULL';
734 737 }
735 738
736 739 if (defined ($token = $doc->getToken($tokenId))) {
737 740 $tsol = (lc $token->getUsage() eq 'tsol') ? 1 : 0;
738 741 if (defined ($tokenType{$tokenId})) {
739 742 $tokenName = $tokenType{$tokenId};
740 743 }
741 744 else {
742 745 print STDERR "token id $tokenId not implemented\n";
743 746 }
744 747 }
745 748 else {
746 749 print STDERR
747 750 "$tokenId is an unimplemented token ($entryId in $eventId)\n";
748 751 $tokenName = 'AUT_TEXT';
749 752 }
750 753 my ($xlate, $jni) =
751 754 formatTableEntry($entryId, $tokenName, $eventId, $dataType, $required,
752 755 $tsol, $tokenOrder[$sequence], $tokenFormat,
753 756 $enumGroup, $omit);
754 757 push (@xlateEntryList, $xlate);
755 758 }
756 759 $sequence++;
757 760 }
758 761 $xlateEventTable{$eventId} = [\@xlateEntryList, $eventType, $firstTokenIndex,
759 762 $eventHeader];
760 763 }
761 764
762 765 sub formatTableEntry {
763 766 my ($id, $token, $eventId, $type, $required, $tsol, $sequence, $format,
764 767 $enumGroup, $omitEntry) = @_;
765 768
766 769
767 770 # does this map belong in the xml source? (at least the defaults?)
768 771 # fill in the default value only if it is other than zero.
769 772 # base type adt name, default value
770 773 my %entryDef = ( 'au_asid_t' => ['ADT_UINT32', ''],
771 774 'uint_t' => ['ADT_UINT32', ''],
772 775 'int' => ['ADT_INT', ''],
773 776 'int32_t' => ['ADT_INT32', ''],
774 777 'uid_t' => ['ADT_UID', 'AU_NOAUDITID'],
775 778 'gid_t' => ['ADT_GID', 'AU_NOAUDITID'],
776 779 'uid_t*' => ['ADT_UIDSTAR', ''],
777 780 'gid_t*' => ['ADT_GIDSTAR', ''],
778 781 'char' => ['ADT_CHAR', ''],
779 782 'char*' => ['ADT_CHARSTAR', ''],
780 783 'char**' => ['ADT_CHAR2STAR', ''],
781 784 'long' => ['ADT_LONG', ''],
782 785 'pid_t' => ['ADT_PID', ''],
783 786 'priv_set_t*' => ['ADT_PRIVSTAR', ''],
784 787 'ulong_t' => ['ADT_ULONG', ''],
785 788 'uint16_t', => ['ADT_UINT16', ''],
786 789 'uint32_t' => ['ADT_UINT32', ''],
787 790 'uint32_t*' => ['ADT_UINT32STAR', ''],
788 791 'uint32_t[]' => ['ADT_UINT32ARRAY', ''],
789 792 'uint64_t' => ['ADT_UINT64', ''],
790 793 'uint64_t*' => ['ADT_UINT64STAR', ''],
791 794 'm_label_t*' => ['ADT_MLABELSTAR', ''],
792 795 'fd_t' => ['ADT_FD', '-1'],
793 796 );
794 797 my $xlateLabel = $uniLabel.$xlateUniLabelInc;
795 798 my $xlateLabelInc = 0;
796 799 my $xlateLine = '';
797 800 my @jniLine = ();
798 801
799 802 # the list handling should be a simple loop with a loop of one
800 803 # falling out naturally.
801 804
802 805 unless ($type =~ /,/) { # if list, then generate sequence of entries
803 806 my $dataType;
804 807 my $dataSize;
805 808 my $xlateLabelRef = '';
806 809
807 810 my $arraySize = '';
808 811 $arraySize = $1 if ($type =~ s/\[(\d+)\]/[]/);
809 812
810 813 my $entryType = ${$entryDef{$type}}[0];
811 814
812 815 my @xlateType = (); # for adt_xlate.c
813 816 my $typeCount = 1;
814 817
815 818 if ($entryType) {
816 819 $dataType = $entryType;
817 820 $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
818 821 $type =~ s/\[\]//;
819 822 $dataSize = "sizeof ($type)";
820 823 if ($arraySize) {
821 824 $dataSize = "$arraySize * " . $dataSize;
822 825 }
823 826 $xlateLine = "{{$dataType, $dataSize}}";
824 827 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
825 828 } elsif ($type eq '') {
826 829 $xlateLabelRef = 'NULL';
827 830 } elsif ($type =~ /^msg/i) {
828 831 $type =~ s/^msg//i;
829 832 $dataType = 'ADT_MSG';
830 833 my $dataEnum = 'ADT_LIST_' . uc $type;
831 834 $xlateLine = "{{$dataType, $dataEnum}}";
832 835 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
833 836 } elsif ($type =~ /time_t/i) {
834 837 $dataType = 'ADT_DATE';
835 838 $dataSize = "sizeof (time_t)";
836 839 $xlateLine = "{{$dataType, $dataSize}}";
837 840 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
838 841 } elsif ($type =~ /termid/i) {
839 842 $dataType = 'ADT_TERMIDSTAR';
840 843 $dataSize = "sizeof (au_tid_addr_t *)";
841 844 $xlateLine = "{{$dataType, $dataSize}}";
842 845 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
843 846 } elsif (uc $omitEntry eq 'JNI') {
844 847 $xlateLabelRef = 'NULL';
845 848 } else {
846 849 print STDERR "$type is not an implemented data type\n";
847 850 $xlateLabelRef = 'NULL';
848 851 }
849 852 if ($xlateLine && !($xlateTypeList{$xlateLine})) {
850 853 $xlateTypeList{$xlateLine} = $xlateLabel;
851 854 push (@xlateTypeList, "datadef\t$xlateLabel\[1\] =\t$xlateLine;");
852 855 $xlateLabelInc = 1;
853 856 } else {
854 857 $xlateLabel = $xlateTypeList{$xlateLine};
855 858 }
856 859 $xlateLabelRef = '&' . $xlateLabel . '[0]'
857 860 unless $xlateLabelRef eq 'NULL';
858 861
859 862 # "EOL" is where a comma should go unless end of list
860 863 $xlateLine = "{$token,\t1,\t$xlateLabelRef,\t$sequence,\n" .
861 864 "\t\t0,\t$required,\t$tsol,\t$format}EOL";
862 865
863 866 if (uc $omitEntry ne 'ALWAYS' && ${$entryDef{$type}}[1]) {
864 867 my @list = ();
865 868 if ($xlateDefault{$eventId}) {
866 869 @list = @{$xlateDefault{$eventId}};
867 870 } else {
868 871 push (@xlateDefaults, $eventId);
869 872 }
870 873 push (@list, $id, ${$entryDef{$type}}[1]);
871 874 $xlateDefault{$eventId} = \@list;
872 875 }
873 876 } else { # is a list
874 877 my @type = split(/,/, $type);
875 878 my @arraySize = ();
876 879 my @id = split(/,/, $id);
877 880 my @jniId = @id;
878 881 my $dataType;
879 882 my $typeCount = ($#type + 1);
880 883 my @xlateType = ();
881 884 my @default = ();
882 885
883 886 foreach my $dtype (@type) {
884 887 my $jniId = shift @jniId;
885 888 my $id = shift @id;
886 889 my $arraySize = '';
887 890 $arraySize = $1 if ($dtype =~ s/\[(\d+)\]/[]/);
888 891
889 892 my $entryType = ${$entryDef{$dtype}}[0];
890 893 if ($entryType) {
891 894 my $type = $dtype;
892 895 $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
893 896 $type =~ s/\[\]//;
894 897
895 898 my $sizeString = "sizeof";
896 899 $sizeString = "$arraySize * " . $sizeString if $arraySize;
897 900 push (@xlateType, "\{$entryType, $sizeString ($type)\}");
898 901 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
899 902 } elsif ($type =~ /^msg/i) {
900 903 $type =~ s/^msg//i;
901 904 $dataType = 'ADT_MSG';
902 905 my $dataEnum = 'ADT_LIST_' . uc $type;
903 906 push (@xlateType, "\{$dataType, $dataEnum\}};");
904 907 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
905 908 } elsif ($type =~ /time_t/i) {
906 909 $dataType = 'ADT_DATE';
907 910 push (@xlateType, "\{$entryType, sizeof ($type)\}");
908 911 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
909 912 } elsif ($type =~ /termid/i) {
910 913 $dataType = 'ADT_TERMIDSTAR';
911 914 push (@xlateType, "\{$dataType, sizeof (au_tid_addr_t *)\}");
912 915 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
913 916 } elsif (uc $omitEntry eq 'JNI') {
914 917 # nothing to do.
915 918 } else {
916 919 print STDERR "$dtype is not an implemented data type\n";
917 920 }
918 921 if (uc $omitEntry ne 'ALWAYS' && ${$entryDef{$dtype}}[1]) {
919 922 push (@default, $id, ${$entryDef{$dtype}}[1]);
920 923 }
921 924 }
922 925 my $xlateArray = "\[$typeCount\] =\t{" . join(",\n\t\t\t\t", @xlateType) . "};";
923 926
924 927 unless ($xlateTypeList{$xlateArray}) {
925 928 $xlateTypeList{$xlateArray} = $xlateLabel;
926 929 $xlateArray = "datadef\t$xlateLabel" . $xlateArray;
927 930 push (@xlateTypeList, $xlateArray);
928 931 $xlateLabelInc = 1;
929 932 } else {
930 933 $xlateLabel = $xlateTypeList{$xlateArray};
931 934 }
932 935 $xlateLine =
933 936 "{$token,\t$typeCount,\t&$xlateLabel\[0\],\t$sequence,\n" .
934 937 "\t\t0,\t$required,\t$tsol,\t$format}EOL";
935 938 if (@default) {
936 939 my @list = ();
937 940 if ($xlateDefault{$eventId}) {
938 941 @list = @{$xlateDefault{$eventId}};
939 942 } else {
940 943 push (@xlateDefaults, $eventId);
941 944 }
942 945 push (@list, @default);
943 946 $xlateDefault{$eventId} = \@list;
944 947 }
945 948 }
946 949 $xlateUniLabelInc++ if $xlateLabelInc;
947 950 return ($xlateLine, \@jniLine);
948 951 }
949 952
950 953 sub generateAPIFile {
951 954 my $event = shift;
952 955 my $eventId = shift;
953 956 my $eventType = shift;
954 957 my $eventHeader = shift;
955 958 my $idNo = shift;
956 959
957 960 my @entryList = ();
958 961
959 962 my $external = $event->getExternal();
960 963
961 964 if ($eventType && $debug) {
962 965 print STDERR "event $eventId is of type $eventType\n";
963 966 }
964 967
965 968 return unless $external;
966 969
967 970 my ($extEntry, $entry, $tokenId, $format);
968 971 while (($extEntry, $entry, $tokenId, $format) = $external->getNextEntry()) {
969 972 last unless $entry;
970 973 my $entryId = $entry->getAttr('id');
971 974
972 975 unless (defined $entryId) {
973 976 print STDERR "undefined entry id for external $eventId\n";
974 977 next;
975 978 }
976 979 my $option = $extEntry->getAttr('opt');
977 980 next if ($option eq 'none');
978 981
979 982 if (defined (my $token = $doc->getToken($tokenId))) {
980 983 $option = 'Trusted Solaris only'
981 984 if (lc $token->getUsage() eq 'tsol') ? 1 : 0;
982 985 }
983 986 $option .= " (format: $format)" if $format;
984 987
985 988 my $dataType = $extEntry->getAttr('type');
986 989 unless (defined $dataType) {
987 990 print STDERR "no type defined for external tag for $eventId\n";
988 991 $dataType = "error";
989 992 }
990 993
991 994 my $comment = $entry->getContent();
992 995
993 996 if (($dataType =~ /,/) || ($entryId =~ /,/)) {
994 997 my @type = split(/\s*,\s*/, $dataType);
995 998 my @id = split(/\s*,\s*/, $entryId);
996 999 if ($#type != $#id) {
997 1000 print STDERR
998 1001 "number of data types ($dataType) does not match number of ids ($entryId)",
999 1002 " for event $eventId\n";
1000 1003 if ($#type < $#id) {
1001 1004 $#id = $#type;
1002 1005 }
1003 1006 else {
1004 1007 $#type = $#id;
1005 1008 }
1006 1009 }
1007 1010
1008 1011 my $i;
1009 1012 my $line = '';
1010 1013 $line = "/* $comment */\n\t" if defined $comment;
1011 1014 for ($i = 0; $i <= $#type; $i++) {
1012 1015 my ($primitive, $dereference) =
1013 1016 ($type[$i] =~ /([^\*]+)\s*(\**)/);
1014 1017 $id[$i] .= $1 if ($primitive =~ s/(\[\d+\])//);
1015 1018 $line .= "$primitive\t$dereference$id[$i];\t/* $option */";
1016 1019 push (@entryList, $line);
1017 1020 $line = '';
1018 1021 }
1019 1022 }
1020 1023 else {
1021 1024 my $line = '';
1022 1025 $line = "/* $comment */\n\t" if defined $comment;
1023 1026 if ($dataType =~ /^msg/i) {
1024 1027 $dataType =~ s/^msg\s*//i;
1025 1028 $line .= "enum ${pfx_adt}_$dataType" . "\t$entryId;\t/* $option */";
1026 1029 }
1027 1030 elsif ($dataType =~ /time_t/i) {
1028 1031 $line .= "time_t\t$entryId;\t/* $option */";
1029 1032 }
1030 1033 else {
1031 1034 my ($primitive, $dereference) =
1032 1035 ($dataType =~ /([^\*]+)\s*(\**)/);
1033 1036 $entryId .= $1 if ($primitive =~ s/(\[\d+\])//);
1034 1037 $line .= "$primitive\t$dereference$entryId;\t/* $option */";
1035 1038 }
1036 1039 push (@entryList, $line);
1037 1040 }
1038 1041 }
1039 1042 $eventExtra{$eventId} = [$eventHeader, $idNo];
1040 1043 $eventAPI{$eventId} = \@entryList;
1041 1044 }
1042 1045
1043 1046 sub generateMsgLists {
1044 1047 my $textList = shift;
1045 1048
1046 1049 my $textName = $textList->getId();
1047 1050 my $header = $textList->getHeader();
1048 1051 my $start = $textList->getMsgStart();
1049 1052 my $public = $textList->getMsgPublic();
1050 1053 my $deprecated = $textList->getDeprecated();
1051 1054
1052 1055 addHeader($header);
1053 1056 print "$textName starts at $start\n" if $debug;
1054 1057
1055 1058 my $entry;
1056 1059 my @entry;
1057 1060 while ($entry = $textList->getNextMsg()) {
1058 1061 if ($debug) {
1059 1062 my ($id, $text) = split(/\s*::\s*/, $entry);
1060 1063 print " $id = $text\n";
1061 1064 }
1062 1065 unshift (@entry, $entry);
1063 1066 }
1064 1067 $msg_list{$textName} =
1065 1068 [\@entry, [$header, $start, $public, $deprecated]];
1066 1069 }
1067 1070
1068 1071 sub addHeader {
1069 1072 my $header_index = shift;
1070 1073
1071 1074 die "invalid adt_event_N.h index: $header_index\n"
1072 1075 unless ($header_index =~ /^\d+$/);
1073 1076
1074 1077 $headers{$header_index} = $header_index;
1075 1078 }
1076 1079
1077 1080 # $header = 0 is a special case; it is for adt_event.h
1078 1081 # $header > 0 creates adt_event_N.h, where N = $header
1079 1082
1080 1083 sub openHeaderFiles {
1081 1084 my $outfile = shift; # path to an adt_event_N.h file
1082 1085
1083 1086 my $header;
1084 1087 my @Hfile = (); # potentially sparse array of file handles
1085 1088 my @HfileName = (); # parallel array to Hfile, file name (not path)
1086 1089 foreach $header (sort keys %headers) {
1087 1090 my $file = $outfile;
1088 1091 if ($header > 0) {
1089 1092 $file =~ s/_N/_$header/;
1090 1093 } else {
1091 1094 $file =~ s/_N//;
1092 1095 }
1093 1096 unless (open($Hfile[$header], ">$file")) {
1094 1097 print STDERR "can't open output ($file): $!\n";
1095 1098 $HfileName[$header] = '';
1096 1099 $Hfile[$header] = '';
1097 1100 } else {
1098 1101 my @tmp = split(/\//, $file);
1099 1102 $HfileName[$header] = $tmp[$#tmp];
1100 1103 }
1101 1104 }
1102 1105 return (@Hfile);
1103 1106 }
1104 1107
1105 1108 sub closeHeaderFiles {
1106 1109 my @Hfile = @_;
1107 1110
1108 1111 my $header;
1109 1112 foreach $header (sort keys %headers) {
1110 1113 close $Hfile[$header] if $Hfile[$header];
1111 1114 }
1112 1115 }
↓ open down ↓ |
392 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX