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