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