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