xref: /onnv-gate/usr/src/lib/libbsm/auditxml (revision 11893:ff6e80260186)
14176Stz204579#!/usr/perl5/bin/perl -w
24176Stz204579#
34176Stz204579# CDDL HEADER START
44176Stz204579#
54176Stz204579# The contents of this file are subject to the terms of the
64176Stz204579# Common Development and Distribution License (the "License").
74176Stz204579# You may not use this file except in compliance with the License.
84176Stz204579#
94176Stz204579# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
104176Stz204579# or http://www.opensolaris.org/os/licensing.
114176Stz204579# See the License for the specific language governing permissions
124176Stz204579# and limitations under the License.
134176Stz204579#
144176Stz204579# When distributing Covered Code, include this CDDL HEADER in each
154176Stz204579# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
164176Stz204579# If applicable, add the following below this CDDL HEADER, with the
174176Stz204579# fields enclosed by brackets "[]" replaced with your own identifying
184176Stz204579# information: Portions Copyright [yyyy] [name of copyright owner]
194176Stz204579#
204176Stz204579# CDDL HEADER END
214176Stz204579#
224176Stz204579#
23*11893Sgww@eng.sun.com# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
244176Stz204579# Use is subject to license terms.
254176Stz204579#
264176Stz204579
274176Stz204579# auditxml takes the audit record description (.xml file) and
284176Stz204579# generates the files needed for the C audit api.
294176Stz204579
307496Sgww@eng.sun.commy $prog = $0; $prog =~ s|.*/||g;
317496Sgww@eng.sun.commy $usage = <<EOF;
327496Sgww@eng.sun.com
337496Sgww@eng.sun.comUsage: $prog [options] <xml-input-file>
347496Sgww@eng.sun.comOptions:
357496Sgww@eng.sun.com	-d	Enable debug output
367496Sgww@eng.sun.com	-e pfx	Internal event prefix (default: AUE)
377496Sgww@eng.sun.com	-i pfx	Interface prefix (default: adt)
387496Sgww@eng.sun.com		External event prefix is uppercase version of this string.
397496Sgww@eng.sun.com	-o dir	Output directory (default: current dir)
407496Sgww@eng.sun.com
417496Sgww@eng.sun.comEOF
427496Sgww@eng.sun.com
434176Stz204579use auditxml;
444176Stz204579use Getopt::Std;
454176Stz204579use strict;
464176Stz204579
474176Stz204579our $debug = 0; # normal use is to set via the file being parsed.
484176Stz204579               # <debug set="on"/> or <debug set="off"/> or <debug/>
494176Stz204579               # if the set attribute is omitted, debug state is toggled
504176Stz204579               # Override with appDebug, but toggle won't do what you
514176Stz204579               # want.
524176Stz204579my $appDebug = 0; # used after return from "new auditxml";
534176Stz204579
547496Sgww@eng.sun.com# Process command-line options
557496Sgww@eng.sun.comour ($opt_d, $opt_e, $opt_i, $opt_o);
567496Sgww@eng.sun.comif (!getopts('de:i:o:') || $#ARGV != 0) {
577496Sgww@eng.sun.com    die $usage;
587496Sgww@eng.sun.com}
597496Sgww@eng.sun.commy $outdir = $opt_o || ".";
607496Sgww@eng.sun.commy $pfx_adt = lc($opt_i) || "adt";
617496Sgww@eng.sun.commy $pfx_ADT = uc($pfx_adt);
627496Sgww@eng.sun.commy $pfx_AUE = uc($opt_e) || "AUE";
637496Sgww@eng.sun.com
647496Sgww@eng.sun.com$appDebug = $opt_d;
657496Sgww@eng.sun.com
667496Sgww@eng.sun.commy $uniLabel = "adr";
677496Sgww@eng.sun.commy $xlateUniLabelInc = 0;
687496Sgww@eng.sun.com
697496Sgww@eng.sun.com
707496Sgww@eng.sun.com# where everything comes from and where it goes:
717496Sgww@eng.sun.com
727496Sgww@eng.sun.commy $xlateFile = "$outdir/${pfx_adt}_xlate.c";
737496Sgww@eng.sun.commy $headerFile = "$outdir/${pfx_adt}_event_N.h";
747496Sgww@eng.sun.com
757496Sgww@eng.sun.commy $filename = $ARGV[0];  # input XML file
767496Sgww@eng.sun.commy $doc = new auditxml ($filename);
777496Sgww@eng.sun.com$filename =~ s|.*/||g;
787496Sgww@eng.sun.com
797496Sgww@eng.sun.com$debug = $appDebug;
807496Sgww@eng.sun.com
814176Stz204579my $genNotice = "
824176Stz204579DO NOT EDIT. This file is auto generated by the Solaris Audit
837496Sgww@eng.sun.comsystem from $filename.
844176Stz204579
854176Stz204579See http://opensolaris.org/os/project/audit/
864176Stz204579";
874176Stz204579
884176Stz204579# trim leading/trailing newlines
894176Stz204579$genNotice =~ s/^\n//s;
904176Stz204579$genNotice =~ s/\n$//s;
914176Stz204579
924176Stz204579my %xlateEventTable = ();
934176Stz204579my @xlateTypeList = ();
944176Stz204579my %xlateTypeList = ();
954176Stz204579my %eventAPI = ();
964176Stz204579my %eventExtra = ();
974176Stz204579my %headers = ();
984176Stz204579my %externalIdNo = ();
994176Stz204579my @outputState = ();
1004176Stz204579my %nameTranslation = ();
1014176Stz204579my @xlateDefaults = ();
1024176Stz204579my %xlateDefault = ();
1034176Stz204579my %msg_list = ();
1044176Stz204579
1054176Stz204579my $event;
1064176Stz204579while ($event = $doc->getNextEvent()) {
1074176Stz204579    my $eventId = $event->getId();
1084176Stz204579    my $eventHeader = $event->getHeader();
1094176Stz204579    my $idNo = $event->getIdNo();
1104176Stz204579    $externalIdNo{$eventId} = $idNo;
1114176Stz204579    addHeader($eventHeader) if defined ($eventHeader);
1124176Stz204579    my $super;
1134176Stz204579    my $omit = $event->getOmit();
1144176Stz204579    my $eventType = '';
1154176Stz204579    if ($super = $event->getSuperClass()) {
1164176Stz204579	$event = $super;
1174176Stz204579	$eventType = 'instance';
1184176Stz204579    } else {
1194176Stz204579	$eventType = $event->getType();
1204176Stz204579    }
1214176Stz204579
1224176Stz204579    # header file for API use
1234176Stz204579    generateAPIFile($event, $eventId, $eventType, $eventHeader, $idNo)
1244176Stz204579        unless $omit eq 'always';
1254176Stz204579
1264176Stz204579    # c file table for translation
1274176Stz204579    generateTableC($event, $eventId, $eventType, $eventHeader, $omit);
1284176Stz204579}
1294176Stz204579
1304176Stz204579my $textList;
1314176Stz204579while ($textList = $doc->getNextMsgId()) {
1324176Stz204579    generateMsgLists($textList);  # enum -> text mappings
1334176Stz204579}
1344176Stz204579
1354176Stz204579printTableC($xlateFile);
1364176Stz204579printAPIFile($headerFile, $doc);
1374176Stz204579
1384176Stz204579exit 0;
1394176Stz204579
1404176Stz204579
1414176Stz204579sub printTableC {
1424176Stz204579    my $file = shift;
1434176Stz204579
1444176Stz204579    unless (open(Cfile, ">$file")) {
1454176Stz204579	print STDERR "can't open output file ($file): $!\n";
1464176Stz204579	return;
1474176Stz204579    }
1484176Stz204579
1494176Stz204579    my $notice = $genNotice;
1504176Stz204579    $notice =~ s/\n/\n * /gs;
1514176Stz204579    $notice =~ s/\s+\n/\n/gs;
1524176Stz204579    print Cfile <<EOF;
1534176Stz204579/*
1544176Stz204579 * $notice
1554176Stz204579 */
1564176Stz204579
1574176Stz204579#include <bsm/libbsm.h>
1584176Stz204579#include <adt_xlate.h>
1594176Stz204579#include <libintl.h>
1604176Stz204579
1614176Stz204579EOF
1624176Stz204579    print Cfile "#ifndef _PRAUDIT\n";
1634176Stz204579    print Cfile "/* Internal data type definitions */\n\n";
1644176Stz204579    my $extDef;
1654176Stz204579    foreach $extDef (@xlateTypeList) {
1664176Stz204579      print Cfile "static $extDef\n";
1674176Stz204579    }
1684176Stz204579    @xlateTypeList = ();
1694176Stz204579
1704176Stz204579    print Cfile "\n/* External event structure to internal event structure */\n\n";
1714176Stz204579
1724176Stz204579    my @pointers = ();
1734176Stz204579
1744176Stz204579    foreach my $eventId (sort keys %xlateEventTable) {
1754176Stz204579	if ($xlateEventTable{$eventId}) {
1764176Stz204579	    my ($ref1, $eventType, $firstToken, $eventHeader) =
1774176Stz204579	      @{$xlateEventTable{$eventId}};
1784176Stz204579	    my @entries = @$ref1;
1794176Stz204579	    my $entry;
1804176Stz204579	    my $entries = $#entries;
1814176Stz204579	    my $count = $entries + 1;
1824176Stz204579	    my $externalName = $nameTranslation{$eventId};
1834176Stz204579	    my $externalRoot = $externalName;
1847496Sgww@eng.sun.com	    $externalRoot =~ s/${pfx_AUE}_//;
1854176Stz204579	    my $structName = "XX_$externalRoot";
1864176Stz204579	    my $root = $eventId;
1877496Sgww@eng.sun.com	    $root =~ s/${pfx_AUE}_//;
1884176Stz204579	    my $externalId = $eventId;
1897496Sgww@eng.sun.com	    $externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
1904176Stz204579
1914176Stz204579	    unless ($eventType eq 'generic') {
1924176Stz204579		print Cfile "static struct entry $structName\[$count\] = {\n";
1934176Stz204579		foreach $entry (@entries) {
1944176Stz204579		    if ($entries--) {
1954176Stz204579			$entry =~ s/EOL/,/;
1964176Stz204579		    }
1974176Stz204579		    else {
1984176Stz204579			$entry =~ s/EOL//;
1994176Stz204579		    }
2004176Stz204579		    $entry =~ s/selfReference/$structName/;
2014176Stz204579		    print Cfile "\t$entry\n";
2024176Stz204579		}
2034176Stz204579		print Cfile "};\n";
2044176Stz204579
2054176Stz204579		print Cfile "static struct translation X_$externalRoot = {\n";
2064176Stz204579		push (@pointers, "X_$externalRoot");
2074176Stz204579
2084176Stz204579		print Cfile "\t0,\n";   # tx_offsetsCalculated = 0
2094176Stz204579		print Cfile "\t$externalId,\n";
2104176Stz204579		print Cfile "\t$externalName,\n";
2114176Stz204579
2124176Stz204579		print Cfile "\t$count,\n";
2134176Stz204579		print Cfile "\t&XX_$externalRoot\[$firstToken\],\n";
2144176Stz204579		print Cfile "\t&XX_$externalRoot\[0\]\n};\n";
2154176Stz204579	    }
2164176Stz204579	} else {
2174176Stz204579	    print STDERR "expected entry for $eventId but none found\n";
2184176Stz204579	}
2194176Stz204579    }
2204176Stz204579
2214176Stz204579    my $count = $#pointers + 2;
2227496Sgww@eng.sun.com    print Cfile "adt_translation_t *${pfx_adt}_xlate_table[$count] = {\n";
2234176Stz204579
2244176Stz204579    my $firstEvent = 1;
2254176Stz204579    foreach my $eventId (@pointers) {
2264176Stz204579	if ($firstEvent) {
2274176Stz204579	    $firstEvent = 0;
2284176Stz204579	}
2294176Stz204579	else {
2304176Stz204579	    print Cfile ",\n";
2314176Stz204579	}
2324176Stz204579	print Cfile "\t&$eventId";
2334176Stz204579    }
2344176Stz204579    print Cfile ",\n\tNULL\n};\n";
2354176Stz204579
2367496Sgww@eng.sun.com    # generate the Event preload() function
2374176Stz204579
2384176Stz204579    print Cfile <<EOF;
2394176Stz204579
2404176Stz204579void
2417496Sgww@eng.sun.com${pfx_adt}_preload(au_event_t event_id, adt_event_data_t *event_data)
2424176Stz204579{
2434176Stz204579	switch (event_id) {
2444176Stz204579EOF
2454176Stz204579
2464176Stz204579        foreach my $id (@xlateDefaults) {
2474176Stz204579		my $adtID = $id;
2487496Sgww@eng.sun.com		$adtID =~ s/${pfx_AUE}/${pfx_ADT}/;
2494176Stz204579
2504176Stz204579		print Cfile <<EOF;
2514176Stz204579	case $adtID:
2524176Stz204579EOF
2534176Stz204579		my @preloads = @{$xlateDefault{$id}};
2544176Stz204579		while (@preloads) {
2554176Stz204579			my $fieldName = shift @preloads;
2564176Stz204579			my $default = shift @preloads;
2577496Sgww@eng.sun.com			$id =~ s/${pfx_AUE}_/${pfx_adt}_/;
2584176Stz204579
2594176Stz204579			print Cfile <<EOF;
2607496Sgww@eng.sun.com		event_data->$id.$fieldName = $default;
2614176Stz204579EOF
2624176Stz204579		}
2634176Stz204579
2644176Stz204579		print Cfile <<EOF;
2654176Stz204579		break;
2664176Stz204579EOF
2674176Stz204579	}
2684176Stz204579
2694176Stz204579    print Cfile <<EOF;
2704176Stz204579	default:
2714176Stz204579		break;
2724176Stz204579	}
2734176Stz204579}
2744176Stz204579#endif
2754176Stz204579
2767496Sgww@eng.sun.comEOF
2774176Stz204579
2787496Sgww@eng.sun.com    print Cfile "/* message lists */\n\n";
2794176Stz204579    my $listName;
2804176Stz204579    my @listName;
2814176Stz204579    foreach $listName (sort keys %msg_list) {
2824176Stz204579        my ($listRef, $headref) = @{$msg_list{$listName}};
2834176Stz204579	my ($header, $start, $public, $deprecated) = @$headref;
2844176Stz204579
2854176Stz204579	my @listValue =  @$listRef;
2864176Stz204579	my $listValue;
2874176Stz204579	my $listLength = $#listValue + 1;
2884176Stz204579
2894176Stz204579	$listName = 'NULL' if ($#listValue < 0);
2904176Stz204579
2914176Stz204579        push (@listName, [$listName, $listLength - 1, $start, $public]);
2924176Stz204579
2934176Stz204579	next if ($#listValue < 0);
2944176Stz204579
2954176Stz204579	print Cfile "/* Deprecated message list */\n" if ($deprecated);
2964176Stz204579	print Cfile "static char *msg_$listName\[$listLength] = {\n";
2974176Stz204579
2984176Stz204579	my $ffirst = 1;
2994176Stz204579	foreach $listValue (@listValue) {
3004176Stz204579	    print Cfile ",\n" unless $ffirst;
3014176Stz204579	    $ffirst = 0;
3024176Stz204579	    my ($id, $text) = split(/\s*::\s*/, $listValue);
3034176Stz204579	    if ($text) {
3044176Stz204579	        print Cfile "\t\"$text\"";
3054176Stz204579	    }
3064176Stz204579	    else {
3074176Stz204579	        print Cfile "\tNULL";
3084176Stz204579	    }
3094176Stz204579	}
3104176Stz204579	print Cfile "\n};\n";
3114176Stz204579    }
3127496Sgww@eng.sun.com
3137496Sgww@eng.sun.com    if ($#listName >= 0) {
3147496Sgww@eng.sun.com	print Cfile "\nstruct msg_text ${pfx_adt}_msg_text[", $#listName + 1,
3157496Sgww@eng.sun.com			"] = {\n";
3167496Sgww@eng.sun.com	my $ffirst = 1;
3177496Sgww@eng.sun.com	foreach $listName (@listName) {
3187496Sgww@eng.sun.com            my ($name, $max, $start) = @$listName;
3197496Sgww@eng.sun.com	    $start = -$start if $start;
3207496Sgww@eng.sun.com            print Cfile ",\n" unless $ffirst;
3217496Sgww@eng.sun.com	    $ffirst = 0;
3227496Sgww@eng.sun.com	    $name = "msg_$name" if ($name ne 'NULL');
3237496Sgww@eng.sun.com            print Cfile "\t{0, $max, $name, $start}";
3247496Sgww@eng.sun.com	}
3257496Sgww@eng.sun.com	print Cfile "\n};\n";
3264176Stz204579    }
3274176Stz204579
3284176Stz204579    close Cfile;
3294176Stz204579}
3304176Stz204579
3314176Stz204579sub printAPIFile {
3324176Stz204579    my $file = shift;
3334176Stz204579    my $xmlDoc = shift;
3344176Stz204579
3354176Stz204579    my @Hfile;
3364176Stz204579    @Hfile = openHeaderFiles($file);
3374176Stz204579
3384176Stz204579    my $notice = $genNotice;
3394176Stz204579    $notice =~ s/\n/\n * /gs;
3404176Stz204579    $notice =~ s/\s+\n/\n/gs;
3414176Stz204579
3424176Stz204579    foreach my $header (keys %headers) {
3434176Stz204579    	next unless $Hfile[$header];
3444176Stz204579	*Hfile = $Hfile[$header];
3454176Stz204579	my $include = "adt.h";
3467496Sgww@eng.sun.com	my $adt_event_n = "_${pfx_ADT}_EVENT_H";
3474176Stz204579	if ($header > 0) {
3487496Sgww@eng.sun.com	    $include = "${pfx_adt}_event.h";
3497496Sgww@eng.sun.com	    $adt_event_n = "_${pfx_ADT}_EVENT_".$header."_H";
3504176Stz204579	}
3514176Stz204579	print Hfile <<EOF;
3524176Stz204579/*
3534176Stz204579 * $notice
3544176Stz204579 */
3554176Stz204579
3564176Stz204579#ifndef $adt_event_n
3574176Stz204579#define	$adt_event_n
3584176Stz204579
3594176Stz204579#include <bsm/$include>
3604176Stz204579
3614176Stz204579#ifdef	__cplusplus
3624176Stz204579extern "C" {
3634176Stz204579#endif
3644176Stz204579
3654176Stz204579/*
3664176Stz204579 * adt_put_event() status values.  Positive values are for kernel-generated
3674176Stz204579 * failure, -1 for user-space.  For ADT_SUCCESS, the adt_put_event() return_val
3684176Stz204579 * is not used; the convention is to set it to ADT_SUCCESS.
3694176Stz204579 */
3704176Stz204579#define	ADT_SUCCESS	0
3714176Stz204579#define	ADT_FAILURE	-1
3724176Stz204579
3734176Stz204579EOF
3744176Stz204579    }
3754176Stz204579
3764176Stz204579    foreach my $listName (sort keys %msg_list) {
3774176Stz204579	my $shortName = uc $listName;
3784176Stz204579	$shortName =~ s/_TEXT//;
3794176Stz204579
3804176Stz204579        my ($listRef, $headref) = @{$msg_list{$listName}};
3814176Stz204579	my ($header, $start, $public, $deprecated) = @$headref;
3824176Stz204579	next unless $Hfile[$header];
3834176Stz204579	*Hfile = $Hfile[$header];
3844176Stz204579
3854176Stz204579	print Hfile "/* Deprecated message list */\n" if $deprecated;
3867496Sgww@eng.sun.com	print Hfile "#define\t${pfx_ADT}_$shortName\t$start\n" if $start;
3874176Stz204579
3884176Stz204579	my @listValue =  @$listRef;
3894176Stz204579	next unless ($#listValue >= 0);
3907496Sgww@eng.sun.com	print Hfile "enum\t${pfx_adt}_$listName", " {\n";
3914176Stz204579
3924176Stz204579	my $listValue;
3934176Stz204579	my $i = 0;
3944176Stz204579	my $j = $#listValue;
3954176Stz204579	my $comma = ',';
3964176Stz204579	foreach $listValue (@listValue) {
3974176Stz204579	    my ($id, $text) = split(/\s*::\s*/, $listValue);
3984176Stz204579	    $comma = '' if $i++ == $j;
3994176Stz204579	    if ($start) {
4004176Stz204579		$start = " = $start$comma";
4014176Stz204579	    } else {
4024176Stz204579	        $start = "$comma\t";
4034176Stz204579	    }
4044176Stz204579	    $text = "(no token will be generated)" unless $text;
4057496Sgww@eng.sun.com	    my $line = "\t${pfx_ADT}_$shortName"."_$id$start\t/* ";
4065319Stz204579	    # ensure whole line does not exceed 80 chars
4075319Stz204579	    my $eline = $line.$text;
4085319Stz204579	    #expand tabs
4095319Stz204579	    1 while $eline =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
4105319Stz204579	    if ((length($eline) > 77) && ($line =~ /\t\t/)) {
4115319Stz204579	    	# 77 = 80 - length(" */")
4125319Stz204579		# strip off double tab so that comment can be longer
4135319Stz204579		$line =~ s/\t\t/\t/;
4145319Stz204579		# shorten eline; don't mind where the spaces are removed, it is
4155319Stz204579		# only $eline length which matters
4165319Stz204579		$eline =~ s/ {8}//;
4175319Stz204579	    }
4185319Stz204579	    if (length($eline) > 77) { # 80 - length(" */")
4195319Stz204579	    	# here we use negative length in substr to leave off from the
4205319Stz204579		# right side; 74 = 77 - length("...")
4215319Stz204579	    	$line .= substr($text, 0, 74 - length($eline));
4225319Stz204579		# strip off part of last word (already cut)
4235319Stz204579		$line =~ s/\s(\S+)$/ /;
4245319Stz204579		$line .= "...";
4255319Stz204579	    } else {
4265319Stz204579	    	$line .= $text;
4275319Stz204579	    }
4285319Stz204579	    print Hfile "$line */\n";
4294176Stz204579	    $start = '';
4304176Stz204579	}
4314176Stz204579	print Hfile "};\n";
4324176Stz204579    }
4334176Stz204579
4347496Sgww@eng.sun.com    # generate defines for external event names
4354176Stz204579
4364176Stz204579    foreach my $eventId (sort keys %eventAPI) {
4374176Stz204579        my ($header, $idNo) = @{$eventExtra{$eventId}};
4384176Stz204579	unless (defined ($header)) {
4394176Stz204579	    print STDERR "missing header selection for $eventId\n";
4404176Stz204579	    next;
4414176Stz204579	}
4424176Stz204579	*Hfile = $Hfile[$header];
4434176Stz204579	next unless $Hfile[$header];
4444176Stz204579
4454176Stz204579	my $l = length($eventId) + 8; # label plus preceding #define\t
4464176Stz204579	$l = 5 - int(($l + 8)/8);
4474176Stz204579	$l = 1 if $l < 1;
4484176Stz204579	my $tab = "\t" x $l;
4494176Stz204579
4504176Stz204579        print STDERR "missing id number for $eventId\n" unless $idNo;
4514176Stz204579
4527496Sgww@eng.sun.com	$eventId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
4534176Stz204579	print Hfile "#define\t$eventId$tab$idNo\n";
4544176Stz204579    }
4554176Stz204579
4564176Stz204579
4574176Stz204579    # generate per-event structures
4584176Stz204579
4594176Stz204579    foreach my $eventId (sort keys %eventAPI) {
4604176Stz204579        my ($header, $idNo) = @{$eventExtra{$eventId}};
4614176Stz204579	my $dataId = $eventId;
4627496Sgww@eng.sun.com	$dataId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
4634176Stz204579	unless(defined ($header)) {
4644176Stz204579	    print STDERR "$eventId is missing the header assignment\n";
4654176Stz204579	    next;
4664176Stz204579	}
4674176Stz204579	*Hfile = $Hfile[$header];
4684176Stz204579	next unless $Hfile[$header];
4694176Stz204579
4704176Stz204579	my $externalId = $eventId;
4717496Sgww@eng.sun.com	$externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
4724176Stz204579
4734176Stz204579	print Hfile "\nstruct $dataId {\t/* $externalId */\n";
4744176Stz204579
4754176Stz204579	my @entries = @{$eventAPI{$eventId}};
4764176Stz204579	my $entry;
4774176Stz204579	if ($#entries < 0) {
4784176Stz204579	    print Hfile "\tint\tdummy;\t/* not used */\n";
4794176Stz204579	} else {
4804176Stz204579	    foreach $entry (@entries) {
4814176Stz204579		$entry =~ s/termid/adt_termid_t/;
4824176Stz204579		print Hfile "\t$entry\n";
4834176Stz204579	    }
4844176Stz204579	}
4854176Stz204579	print Hfile "};\n";
4867496Sgww@eng.sun.com	$eventId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
4874176Stz204579	print Hfile "typedef struct $dataId $eventId","_t;\n";
4884176Stz204579    }
4894176Stz204579
4904176Stz204579    foreach my $header (sort keys %headers) {
4914176Stz204579	$outputState[$header] = 0;
4924176Stz204579    }
4934176Stz204579
4944176Stz204579    foreach my $eventId (sort keys %eventAPI) {
4954176Stz204579        my ($header, $idNo) = @{$eventExtra{$eventId}};
4964176Stz204579	unless(defined ($header)) {
4974176Stz204579	    # don't print duplicate error message
4984176Stz204579	    next;
4994176Stz204579	}
5004176Stz204579	*Hfile = $Hfile[$header];
5014176Stz204579	next unless $Hfile[$header];
5024176Stz204579	if ($outputState[$header] == 0) {
5034176Stz204579	    $outputState[$header] = 1;
5044176Stz204579	    my $suffix = '';
5054176Stz204579	    $suffix = "_$header" if $header;
5064176Stz204579	    print Hfile "\nunion adt_event_data$suffix {\n";
5074176Stz204579	}
5084176Stz204579        my $elementName = $eventId;
5097496Sgww@eng.sun.com	$elementName =~ s/^${pfx_AUE}_/${pfx_adt}_/;
5107496Sgww@eng.sun.com	$eventId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
5114176Stz204579	$elementName =~ s/_t$//;
5124176Stz204579
5134176Stz204579	print Hfile "\t\t$eventId","_t\t$elementName;\n";
5144176Stz204579    }
5154176Stz204579    foreach my $header (sort keys %headers) {
5164176Stz204579	if ($outputState[$header]) {
5174176Stz204579	    *Hfile = $Hfile[$header];
5184176Stz204579	    next unless $Hfile[$header];
5194176Stz204579	    print Hfile "};\n";
5204176Stz204579	}
5214176Stz204579    }
5224176Stz204579    foreach my $header (keys %headers) {
5234176Stz204579    	next unless $Hfile[$header];
5244176Stz204579	*Hfile = $Hfile[$header];
5257496Sgww@eng.sun.com	my $adt_event_n = "_${pfx_ADT}_EVENT_H";
5264176Stz204579	if ($header > 0) {
5277496Sgww@eng.sun.com	    $adt_event_n = "_${pfx_ADT}_EVENT_".$header."_H";
5284176Stz204579	}
5294176Stz204579	print Hfile <<EOF;
5304176Stz204579
5314176Stz204579
5327496Sgww@eng.sun.com#ifndef	${pfx_ADT}_PRIVATE
5337496Sgww@eng.sun.com#define	${pfx_ADT}_PRIVATE
5344176Stz204579
5354176Stz204579/*
5364176Stz204579 * These interfaces are project private and will change without
5377496Sgww@eng.sun.com * notice as needed for the Solaris Audit project.
5384176Stz204579 */
5394176Stz204579
5404176Stz204579extern	void	adt_get_auid(const adt_session_data_t *, au_id_t *);
5414176Stz204579extern	void	adt_set_auid(const adt_session_data_t *, const au_id_t);
5424176Stz204579
5434176Stz204579extern	void	adt_get_mask(const adt_session_data_t *, au_mask_t *);
5444176Stz204579extern	void	adt_set_mask(const adt_session_data_t *, const au_mask_t *);
5454176Stz204579
5464176Stz204579extern	void	adt_get_termid(const adt_session_data_t *, au_tid_addr_t *);
5474176Stz204579extern	void	adt_set_termid(const adt_session_data_t *,
5484176Stz204579    const au_tid_addr_t *);
5494176Stz204579
5504176Stz204579extern	void	adt_get_asid(const adt_session_data_t *, au_asid_t *);
5514176Stz204579extern	void	adt_set_asid(const adt_session_data_t *, const au_asid_t);
5527649Sgww@eng.sun.comextern	au_asid_t adt_get_unique_id(au_id_t);
5537496Sgww@eng.sun.comextern	void	adt_load_table(const adt_session_data_t *, adt_translation_t **,
5547496Sgww@eng.sun.com    void (*preload)(au_event_t, adt_event_data_t *));
5557496Sgww@eng.sun.com
5567496Sgww@eng.sun.comextern	void	${pfx_adt}_preload(au_event_t, adt_event_data_t *);
5577496Sgww@eng.sun.com
5587496Sgww@eng.sun.comextern adt_translation_t *${pfx_adt}_xlate_table[];
5594176Stz204579
5604176Stz204579#endif
5614176Stz204579
5624176Stz204579#ifdef	__cplusplus
5634176Stz204579}
5644176Stz204579#endif
5654176Stz204579
5664176Stz204579#endif	/* $adt_event_n */
5674176Stz204579EOF
5684176Stz204579    }
5694176Stz204579    closeHeaderFiles(@Hfile);
5704176Stz204579}
5714176Stz204579
5724176Stz204579sub generateTableC {
5734176Stz204579    my $event = shift;
5744176Stz204579    my $eventId = shift;
5754176Stz204579    my $eventType = shift;
5764176Stz204579    my $eventHeader = shift;
5774176Stz204579    my $omit = shift;
5784176Stz204579
5794176Stz204579    my %tokenType = (
5805537Sgww	#
5815537Sgww	#	tokenTypes are the ones that are actually defined
5825537Sgww	#	for use in adt.xml audit records
5835537Sgww	#
5845537Sgww
5855537Sgww	#	  'acl'			=> 'AUT_ACL',		# not defined
5865537Sgww	#	  'arbitrary'		=> 'AUT_ARBITRARY',	# not defined
5875537Sgww	#	  'arg'			=> 'AUT_ARG',		# not defined
5885537Sgww	#	  'attr'		=> 'AUT_ATTR',
5894176Stz204579		  'command'		=> 'AUT_CMD',
5907427SJan.Friedel@Sun.COM		  'command_alt'		=> 'ADT_CMD_ALT',	# dummy token id
5915537Sgww	#	  'date'		=> 'AUT_TEXT',		# not used
5925537Sgww	#	  'exec_args'   	=> 'AUT_EXEC_ARGS',	# not defined
5935537Sgww	#	  'exec_env'    	=> 'AUT_EXEC_ENV',	# not defined
5945537Sgww	#	  'exit'        	=> 'AUT_EXIT',		# not defined
5954176Stz204579		  'fmri'        	=> 'AUT_FMRI',
5965537Sgww	#	  'groups'      	=> 'AUT_GROUPS',	# not defined
5975537Sgww	#	  'header'      	=> 'AUT_HEADER',	# not defined
5985537Sgww		  'in_peer'     	=> 'ADT_IN_PEER',	# dummy token id
59910645Sgww@eng.sun.com		  'in_remote'     	=> 'ADT_IN_REMOTE',	# dummy token id
6005537Sgww	#	  'ipc'         	=> 'AUT_IPC',		# not defined
6015537Sgww	#	  'ipc_perm'    	=> 'AUT_IPC_PERM',	# not defined
60210645Sgww@eng.sun.com		  'iport'		=> 'AUT_IPORT',
6034176Stz204579		  'label'		=> 'AUT_LABEL',
6044176Stz204579		  'newgroups'   	=> 'AUT_NEWGROUPS',
6055537Sgww	#	  'opaque'      	=> 'AUT_OPAQUE',	# not defined
6064176Stz204579		  'path'        	=> 'AUT_PATH',
6074176Stz204579		  'path_list'		=> '-AUT_PATH',		# dummy token id
6084176Stz204579		  'process'     	=> 'AUT_PROCESS',
6094176Stz204579		  'priv_effective'	=> 'ADT_AUT_PRIV_E',	# dummy token id
6104176Stz204579		  'priv_limit'		=> 'ADT_AUT_PRIV_L', 	# dummy token id
6114176Stz204579		  'priv_inherit'	=> 'ADT_AUT_PRIV_I',	# dummy token id
6124176Stz204579		  'return'      	=> 'AUT_RETURN',
6135537Sgww	#	  'seq'         	=> 'AUT_SEQ',		# not defined
6145537Sgww	#	  'socket'      	=> 'AUT_SOCKET',	# not defined
6155537Sgww	#	  'socket-inet' 	=> 'AUT_SOCKET_INET',
6164176Stz204579		  'subject'     	=> 'AUT_SUBJECT',
6174176Stz204579		  'text'        	=> 'AUT_TEXT',
618*11893Sgww@eng.sun.com		  'tid'          	=> 'AUT_TID',
6195537Sgww	#	  'trailer'     	=> 'AUT_TRAILER',	# not defined
6204176Stz204579		  'uauth'		=> 'AUT_UAUTH',
621*11893Sgww@eng.sun.com		  'user'		=> 'AUT_USER',
6224176Stz204579		  'zonename'		=> 'AUT_ZONENAME'
6234176Stz204579		 );
6244176Stz204579
6254176Stz204579    my @xlateEntryList = ();
6264176Stz204579
6274176Stz204579    my $external = $event->getExternal();
6284176Stz204579    my $internal = $event->getInternal();
6294176Stz204579
6304176Stz204579    unless ($external) {
6314176Stz204579	print STDERR "No external object captured for event $eventId\n";
6324176Stz204579	return;
6334176Stz204579    }
6344176Stz204579    if ($eventType) {
6354176Stz204579	$nameTranslation{$eventId} = $eventId;
6364176Stz204579    } else {
6374176Stz204579	$nameTranslation{$eventId} = $external->getInternalName();
6384176Stz204579    }
6394176Stz204579    unless ($internal) {
6404176Stz204579	print STDERR "No internal object captured for event $eventId\n";
6414176Stz204579	return;
6424176Stz204579    }
6434176Stz204579    my @entryRef = $internal->getEntries();
6444176Stz204579    my $entryRef;
6454176Stz204579    my @tokenOrder = ();
6464176Stz204579    my $firstTokenIndex = 0; # djdj not used yet, djdj BUG!
6474176Stz204579    			     # needs to be used by translate table
6484176Stz204579
6494176Stz204579    if ($internal->isReorder()) { # prescan the entry list to get the token order
6504176Stz204579      my @inputOrder;
6514176Stz204579      foreach $entryRef (@entryRef) {
6524176Stz204579	my ($intEntry, $entry) = @$entryRef;
6534176Stz204579	push (@inputOrder, $intEntry->getAttr('order'));
6544176Stz204579      }
6554176Stz204579
6564176Stz204579      my $i; # walk down the inputOrder list once
6574176Stz204579      my $k = 1; # discover next in line
6584176Stz204579      my $l = 0; # who should point to next in line
6594176Stz204579      for ($i = 0; $i <= $#inputOrder; $i++) {
6604176Stz204579	my $j;
6614176Stz204579	for ($j = 0; $j <= $#inputOrder; $j++) {
6624176Stz204579	  if ($k == $inputOrder[$j]) {
6634176Stz204579	    if ($k == 1) {
6644176Stz204579	        $firstTokenIndex = $j;
6654176Stz204579	    } else {
6664176Stz204579	        $tokenOrder[$l] = "&(selfReference[$j])";
6674176Stz204579	    }
6684176Stz204579	    $l = $j;
6694176Stz204579	    last;
6704176Stz204579	  }
6714176Stz204579	}
6724176Stz204579	$k++;
6734176Stz204579      }
6744176Stz204579      $tokenOrder[$l] = 'NULL';
6754176Stz204579    }
6764176Stz204579    else { # default order -- input order same as output
6774176Stz204579      my $i;
6784176Stz204579      my $j;
6794176Stz204579      for ($i = 0; $i < $#entryRef; $i++) {
6804176Stz204579	my $j = $i + 1;
6814176Stz204579	$tokenOrder[$i] = "&(selfReference[$j])";
6824176Stz204579      }
6834176Stz204579      $tokenOrder[$#entryRef] = 'NULL';
6844176Stz204579    }
6854176Stz204579
6864176Stz204579    my $sequence = 0;
6874176Stz204579    foreach $entryRef (@entryRef) {
6884176Stz204579      my ($intEntry, $entry) = @$entryRef;
6894176Stz204579      my $entryId = $entry->getAttr('id');
6904176Stz204579
6914176Stz204579      my ($extEntry, $unusedEntry, $tokenId) =
6924176Stz204579	$external->getEntry($entryId);
6934176Stz204579      my $opt = $extEntry->getAttr('opt');
6944176Stz204579
6954176Stz204579      if ($opt eq 'none') {
6964176Stz204579	if (defined ($doc->getToken($tokenId))) {
6974176Stz204579	  if (defined ($tokenType{$tokenId})) {
6984176Stz204579	    $tokenId = $tokenType{$tokenId};
6994176Stz204579	  }
7004176Stz204579	  else {
7014176Stz204579	    print STDERR "token id $tokenId not implemented\n";
7024176Stz204579	  }
7034176Stz204579	}
7044176Stz204579	else {
7054176Stz204579	  print STDERR "token = $tokenId is undefined\n";
7064176Stz204579	  $tokenId = 'error';
7074176Stz204579	}
7084176Stz204579	my ($xlate, $jni) =
7095300Sgww	  formatTableEntry ('', $tokenId, $eventId, '', 0, 0,
7105300Sgww			    $tokenOrder[$sequence], 'NULL', $omit);
7114176Stz204579	push (@xlateEntryList, $xlate);
7124176Stz204579      }
7134176Stz204579      else {
7144176Stz204579	my $dataType = $extEntry->getAttr('type');
7154176Stz204579	$dataType =~ s/\s+//g;   # remove blanks (char * => char*)
7164176Stz204579
7174176Stz204579	my $enumGroup = '';
7184176Stz204579	if ($dataType =~ /^msg/i) {
7194176Stz204579	    $enumGroup = $dataType;
7204176Stz204579	    $enumGroup =~ s/^msg\s*//i;
7217496Sgww@eng.sun.com	    $enumGroup = "${pfx_adt}_" . $enumGroup;
7224176Stz204579	}
7234176Stz204579	my $required = ($opt eq 'required') ? 1 : 0;
7244176Stz204579	my $tsol = 0;
7254176Stz204579	my $tokenId = $intEntry->getAttr('token');
7264176Stz204579	my $token;
7274176Stz204579	my $tokenName;
7284176Stz204579	my $tokenFormat = $intEntry->getAttr('format');
7294176Stz204579	if (defined ($tokenFormat)) {
7304176Stz204579	  $tokenFormat = "\"$tokenFormat\"";
7314176Stz204579	}
7324176Stz204579	else {
7334176Stz204579	  $tokenFormat = 'NULL';
7344176Stz204579	}
7354176Stz204579
7364176Stz204579	if (defined ($token = $doc->getToken($tokenId))) {
7374176Stz204579	  $tsol = (lc $token->getUsage() eq 'tsol') ? 1 : 0;
7384176Stz204579	  if (defined ($tokenType{$tokenId})) {
7394176Stz204579	    $tokenName = $tokenType{$tokenId};
7404176Stz204579	  }
7414176Stz204579	  else {
7424176Stz204579	    print STDERR "token id $tokenId not implemented\n";
7434176Stz204579	  }
7444176Stz204579	}
7454176Stz204579	else {
7464176Stz204579	  print STDERR
7474176Stz204579	    "$tokenId is an unimplemented token ($entryId in $eventId)\n";
7484176Stz204579	  $tokenName = 'AUT_TEXT';
7494176Stz204579	}
7504176Stz204579	my ($xlate, $jni) =
7514176Stz204579	  formatTableEntry($entryId, $tokenName, $eventId, $dataType, $required,
7524176Stz204579			   $tsol, $tokenOrder[$sequence], $tokenFormat,
7535300Sgww			   $enumGroup, $omit);
7544176Stz204579	push (@xlateEntryList, $xlate);
7554176Stz204579      }
7564176Stz204579      $sequence++;
7574176Stz204579    }
7584176Stz204579    $xlateEventTable{$eventId} = [\@xlateEntryList, $eventType, $firstTokenIndex,
7594176Stz204579				 $eventHeader];
7604176Stz204579}
7614176Stz204579
7624176Stz204579sub formatTableEntry {
7635300Sgww    my ($id, $token, $eventId, $type, $required, $tsol, $sequence, $format,
7645300Sgww	$enumGroup, $omitEntry) = @_;
7654176Stz204579
7664176Stz204579
7674176Stz204579    # does this map belong in the xml source?  (at least the defaults?)
7684176Stz204579    # fill in the default value only if it is other than zero.
7694176Stz204579    #		      base type		    adt name,	default value
7704176Stz204579    my %entryDef = ( 'au_asid_t'       	=> ['ADT_UINT32',	''],
7714176Stz204579		     'uint_t'		=> ['ADT_UINT32',      	''],
7724176Stz204579		     'int'		=> ['ADT_INT',		''],
7734176Stz204579		     'int32_t'		=> ['ADT_INT32',	''],
7744176Stz204579		     'uid_t'		=> ['ADT_UID',		'AU_NOAUDITID'],
7754176Stz204579		     'gid_t'		=> ['ADT_GID',		'AU_NOAUDITID'],
7764176Stz204579		     'uid_t*'		=> ['ADT_UIDSTAR',	''],
7774176Stz204579		     'gid_t*'		=> ['ADT_GIDSTAR',	''],
7784176Stz204579		     'char'		=> ['ADT_CHAR',		''],
7794176Stz204579		     'char*'		=> ['ADT_CHARSTAR',	''],
7804176Stz204579		     'char**'		=> ['ADT_CHAR2STAR',	''],
7814176Stz204579		     'long'		=> ['ADT_LONG',		''],
7824176Stz204579		     'pid_t'		=> ['ADT_PID',		''],
7834176Stz204579		     'priv_set_t*'	=> ['ADT_PRIVSTAR',	''],
7844176Stz204579		     'ulong_t'		=> ['ADT_ULONG',	''],
7854176Stz204579		     'uint16_t',	=> ['ADT_UINT16',	''],
7864176Stz204579		     'uint32_t'		=> ['ADT_UINT32',	''],
7874176Stz204579		     'uint32_t*'	=> ['ADT_UINT32STAR',	''],
7884176Stz204579		     'uint32_t[]'	=> ['ADT_UINT32ARRAY',  ''],
7894176Stz204579		     'uint64_t'		=> ['ADT_UINT64',	''],
7904176Stz204579		     'uint64_t*'	=> ['ADT_UINT64STAR',	''],
7914176Stz204579		     'm_label_t*'	=> ['ADT_MLABELSTAR',	''],
7925622Ssabdar		     'fd_t'		=> ['ADT_FD',		'-1'],
7934176Stz204579		    );
7944176Stz204579    my $xlateLabel = $uniLabel.$xlateUniLabelInc;
7954176Stz204579    my $xlateLabelInc = 0;
7964176Stz204579    my $xlateLine = '';
7974176Stz204579    my @jniLine = ();
7984176Stz204579
7994176Stz204579	# the list handling should be a simple loop with a loop of one
8004176Stz204579        # falling out naturally.
8014176Stz204579
8024176Stz204579    unless ($type =~ /,/) {	# if list, then generate sequence of entries
8034176Stz204579      my $dataType;
8044176Stz204579      my $dataSize;
8054176Stz204579      my $xlateLabelRef = '';
8064176Stz204579
8074176Stz204579      my $arraySize = '';
8084176Stz204579      $arraySize = $1 if ($type =~ s/\[(\d+)\]/[]/);
8094176Stz204579
8104176Stz204579      my $entryType = ${$entryDef{$type}}[0];
8114176Stz204579
8124176Stz204579      my @xlateType = ();	# for adt_xlate.c
8134176Stz204579      my $typeCount = 1;
8144176Stz204579
8154176Stz204579      if ($entryType) {
8164176Stz204579	$dataType = $entryType;
8174176Stz204579	$type =~ s/([^*]+)\s*(\*+)/$1 $2/;
8184176Stz204579	$type =~ s/\[\]//;
8194176Stz204579	$dataSize = "sizeof ($type)";
8204176Stz204579	if ($arraySize) {
8214176Stz204579		$dataSize = "$arraySize * " . $dataSize;
8224176Stz204579	}
8234176Stz204579	$xlateLine = "{{$dataType, $dataSize}}";
8244176Stz204579	push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
8254176Stz204579      } elsif ($type eq '') {
8264176Stz204579	  $xlateLabelRef = 'NULL';
8274176Stz204579      } elsif ($type =~ /^msg/i) {
8284176Stz204579	$type =~ s/^msg//i;
8294176Stz204579	$dataType = 'ADT_MSG';
8304176Stz204579	my $dataEnum = 'ADT_LIST_' . uc $type;
8314176Stz204579	$xlateLine = "{{$dataType, $dataEnum}}";
8324176Stz204579	push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
8334176Stz204579      } elsif ($type =~ /time_t/i) {
8344176Stz204579	$dataType = 'ADT_DATE';
8354176Stz204579	$dataSize = "sizeof (time_t)";
8364176Stz204579	$xlateLine = "{{$dataType, $dataSize}}";
8374176Stz204579	push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
8384176Stz204579      } elsif ($type =~ /termid/i) {
8394176Stz204579	$dataType = 'ADT_TERMIDSTAR';
8404176Stz204579	$dataSize = "sizeof (au_tid_addr_t *)";
8414176Stz204579	$xlateLine = "{{$dataType, $dataSize}}";
8424176Stz204579	push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
8435300Sgww      } elsif (uc $omitEntry eq 'JNI') {
8444176Stz204579	$xlateLabelRef = 'NULL';
8454176Stz204579      } else {
8464176Stz204579	print STDERR "$type is not an implemented data type\n";
8474176Stz204579	$xlateLabelRef = 'NULL';
8484176Stz204579      }
8494176Stz204579      if ($xlateLine && !($xlateTypeList{$xlateLine})) {
8504176Stz204579	$xlateTypeList{$xlateLine} = $xlateLabel;
8514176Stz204579	push (@xlateTypeList, "datadef\t$xlateLabel\[1\] =\t$xlateLine;");
8524176Stz204579	$xlateLabelInc = 1;
8534176Stz204579      } else {
8544176Stz204579	$xlateLabel = $xlateTypeList{$xlateLine};
8554176Stz204579      }
8564176Stz204579      $xlateLabelRef = '&' . $xlateLabel . '[0]'
8574176Stz204579	unless $xlateLabelRef eq 'NULL';
8584176Stz204579
8594176Stz204579      # "EOL" is where a comma should go unless end of list
8604176Stz204579      $xlateLine = "{$token,\t1,\t$xlateLabelRef,\t$sequence,\n" .
8614176Stz204579	  "\t\t0,\t$required,\t$tsol,\t$format}EOL";
8624176Stz204579
8635300Sgww      if (uc $omitEntry ne 'ALWAYS' && ${$entryDef{$type}}[1]) {
8644176Stz204579	  my @list = ();
8654176Stz204579	  if ($xlateDefault{$eventId}) {
8664176Stz204579	      @list = @{$xlateDefault{$eventId}};
8674176Stz204579	  } else {
8684176Stz204579	      push (@xlateDefaults, $eventId);
8694176Stz204579	  }
8704176Stz204579	  push (@list, $id, ${$entryDef{$type}}[1]);
8714176Stz204579	  $xlateDefault{$eventId} = \@list;
8724176Stz204579      }
8734176Stz204579    } else {	# is a list
8744176Stz204579      my @type = split(/,/, $type);
8754176Stz204579      my @arraySize = ();
8764176Stz204579      my @id   = split(/,/, $id);
8774176Stz204579      my @jniId  = @id;
8784176Stz204579      my $dataType;
8794176Stz204579      my $typeCount = ($#type + 1);
8804176Stz204579      my @xlateType = ();
8814176Stz204579      my @default = ();
8824176Stz204579
8834176Stz204579      foreach my $dtype (@type) {
8844176Stz204579	my $jniId = shift @jniId;
8854176Stz204579	my $id = shift @id;
8864176Stz204579	my $arraySize = '';
8874176Stz204579	$arraySize = $1 if ($dtype =~ s/\[(\d+)\]/[]/);
8884176Stz204579
8894176Stz204579	my $entryType = ${$entryDef{$dtype}}[0];
8904176Stz204579	if ($entryType) {
8914176Stz204579	  my $type = $dtype;
8924176Stz204579	  $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
8934176Stz204579	  $type =~ s/\[\]//;
8944176Stz204579
8954176Stz204579	  my $sizeString = "sizeof";
8964176Stz204579	  $sizeString = "$arraySize * " . $sizeString if $arraySize;
8974176Stz204579	  push (@xlateType, "\{$entryType, $sizeString ($type)\}");
8984176Stz204579	  push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
8994176Stz204579	} elsif ($type =~ /^msg/i) {
9004176Stz204579	  $type =~ s/^msg//i;
9014176Stz204579	  $dataType = 'ADT_MSG';
9024176Stz204579	  my $dataEnum = 'ADT_LIST_' . uc $type;
9034176Stz204579	  push (@xlateType, "\{$dataType, $dataEnum\}};");
9044176Stz204579	  push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
9054176Stz204579	} elsif ($type =~ /time_t/i) {
9064176Stz204579	  $dataType = 'ADT_DATE';
9074176Stz204579	  push (@xlateType, "\{$entryType, sizeof ($type)\}");
9084176Stz204579	  push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
9094176Stz204579	} elsif ($type =~ /termid/i) {
9104176Stz204579	  $dataType = 'ADT_TERMIDSTAR';
9114176Stz204579	  push (@xlateType, "\{$dataType, sizeof (au_tid_addr_t *)\}");
9124176Stz204579	  push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
9135300Sgww	} elsif (uc $omitEntry eq 'JNI') {
9144176Stz204579	  # nothing to do.
9154176Stz204579	} else {
9164176Stz204579	  print STDERR "$dtype is not an implemented data type\n";
9174176Stz204579	}
9185300Sgww	if (uc $omitEntry ne 'ALWAYS' && ${$entryDef{$dtype}}[1]) {
9194176Stz204579	  push (@default, $id, ${$entryDef{$dtype}}[1]);
9204176Stz204579	}
9214176Stz204579      }
9224176Stz204579      my $xlateArray = "\[$typeCount\] =\t{" . join(",\n\t\t\t\t", @xlateType) . "};";
9234176Stz204579
9244176Stz204579      unless ($xlateTypeList{$xlateArray}) {
9254176Stz204579	$xlateTypeList{$xlateArray} = $xlateLabel;
9264176Stz204579	$xlateArray = "datadef\t$xlateLabel" . $xlateArray;
9274176Stz204579	push (@xlateTypeList, $xlateArray);
9284176Stz204579	$xlateLabelInc = 1;
9294176Stz204579      } else {
9304176Stz204579	$xlateLabel = $xlateTypeList{$xlateArray};
9314176Stz204579      }
9324176Stz204579      $xlateLine =
9334176Stz204579	"{$token,\t$typeCount,\t&$xlateLabel\[0\],\t$sequence,\n" .
9344176Stz204579        "\t\t0,\t$required,\t$tsol,\t$format}EOL";
9354176Stz204579      if (@default) {
9364176Stz204579	  my @list = ();
9374176Stz204579	  if ($xlateDefault{$eventId}) {
9384176Stz204579	      @list = @{$xlateDefault{$eventId}};
9394176Stz204579	  } else {
9404176Stz204579	      push (@xlateDefaults, $eventId);
9414176Stz204579	  }
9424176Stz204579	  push (@list, @default);
9434176Stz204579	  $xlateDefault{$eventId} = \@list;
9444176Stz204579      }
9454176Stz204579    }
9464176Stz204579    $xlateUniLabelInc++ if $xlateLabelInc;
9474176Stz204579    return ($xlateLine, \@jniLine);
9484176Stz204579}
9494176Stz204579
9504176Stz204579sub generateAPIFile {
9514176Stz204579    my $event = shift;
9524176Stz204579    my $eventId = shift;
9534176Stz204579    my $eventType = shift;
9544176Stz204579    my $eventHeader = shift;
9554176Stz204579    my $idNo = shift;
9564176Stz204579
9574176Stz204579    my @entryList = ();
9584176Stz204579
9594176Stz204579    my $external = $event->getExternal();
9604176Stz204579
9614176Stz204579    if ($eventType && $debug) {
9624176Stz204579	print STDERR "event $eventId is of type $eventType\n";
9634176Stz204579    }
9644176Stz204579
9654176Stz204579    return unless $external;
9664176Stz204579
9674176Stz204579    my ($extEntry, $entry, $tokenId, $format);
9684176Stz204579    while (($extEntry, $entry, $tokenId, $format) = $external->getNextEntry()) {
9694176Stz204579	last unless $entry;
9704176Stz204579	my $entryId = $entry->getAttr('id');
9714176Stz204579
9724176Stz204579	unless (defined $entryId) {
9734176Stz204579	    print STDERR "undefined entry id for external $eventId\n";
9744176Stz204579	    next;
9754176Stz204579	}
9764176Stz204579	my $option = $extEntry->getAttr('opt');
9774176Stz204579	next if ($option eq 'none');
9784176Stz204579
9794176Stz204579	if (defined (my $token = $doc->getToken($tokenId))) {
9804176Stz204579	  $option = 'Trusted Solaris only'
9814176Stz204579	    if (lc $token->getUsage() eq 'tsol') ? 1 : 0;
9824176Stz204579	}
9834176Stz204579	$option .= " (format: $format)" if $format;
9844176Stz204579
9854176Stz204579	my $dataType = $extEntry->getAttr('type');
9864176Stz204579	unless (defined $dataType) {
9874176Stz204579	  print STDERR "no type defined for external tag for $eventId\n";
9884176Stz204579	  $dataType = "error";
9894176Stz204579	}
9904176Stz204579
9914176Stz204579	my $comment = $entry->getContent();
9924176Stz204579
9934176Stz204579	if (($dataType =~ /,/) || ($entryId =~ /,/)) {
9944176Stz204579	  my @type = split(/\s*,\s*/, $dataType);
9954176Stz204579	  my @id   = split(/\s*,\s*/, $entryId);
9964176Stz204579	  if ($#type != $#id) {
9974176Stz204579	    print STDERR
9984176Stz204579	      "number of data types ($dataType) does not match number of ids ($entryId)",
9994176Stz204579	      " for event $eventId\n";
10004176Stz204579	    if ($#type < $#id) {
10014176Stz204579	      $#id = $#type;
10024176Stz204579	    }
10034176Stz204579	    else {
10044176Stz204579	      $#type = $#id;
10054176Stz204579	    }
10064176Stz204579	  }
10074176Stz204579
10084176Stz204579	  my $i;
10094176Stz204579	  my $line = '';
10104176Stz204579	  $line = "/* $comment */\n\t" if defined $comment;
10114176Stz204579	  for ($i = 0; $i <= $#type; $i++) {
10124176Stz204579	    my ($primitive, $dereference) =
10134176Stz204579	        ($type[$i] =~ /([^\*]+)\s*(\**)/);
10144176Stz204579	    $id[$i] .= $1 if ($primitive =~ s/(\[\d+\])//);
10154176Stz204579	    $line .= "$primitive\t$dereference$id[$i];\t/*  $option  */";
10164176Stz204579	    push (@entryList, $line);
10174176Stz204579	    $line = '';
10184176Stz204579	  }
10194176Stz204579	}
10204176Stz204579	else {
10214176Stz204579	  my $line = '';
10224176Stz204579	  $line = "/* $comment */\n\t" if defined $comment;
10234176Stz204579	  if ($dataType =~ /^msg/i) {
10244176Stz204579	      $dataType =~ s/^msg\s*//i;
10257496Sgww@eng.sun.com	      $line .= "enum ${pfx_adt}_$dataType" . "\t$entryId;\t/*  $option  */";
10264176Stz204579	  }
10274176Stz204579	  elsif ($dataType =~ /time_t/i) {
10284176Stz204579	      $line .= "time_t\t$entryId;\t/* $option */";
10294176Stz204579	  }
10304176Stz204579	  else {
10314176Stz204579	    my ($primitive, $dereference) =
10324176Stz204579	        ($dataType =~ /([^\*]+)\s*(\**)/);
10334176Stz204579	    $entryId .= $1 if ($primitive =~ s/(\[\d+\])//);
10344176Stz204579	    $line .= "$primitive\t$dereference$entryId;\t/* $option */";
10354176Stz204579	  }
10364176Stz204579	  push (@entryList, $line);
10374176Stz204579	}
10384176Stz204579    }
10394176Stz204579    $eventExtra{$eventId} = [$eventHeader, $idNo];
10404176Stz204579    $eventAPI{$eventId} = \@entryList;
10414176Stz204579}
10424176Stz204579
10434176Stz204579sub generateMsgLists {
10444176Stz204579    my $textList = shift;
10454176Stz204579
10464176Stz204579    my $textName = $textList->getId();
10474176Stz204579    my $header = $textList->getHeader();
10484176Stz204579    my $start = $textList->getMsgStart();
10494176Stz204579    my $public = $textList->getMsgPublic();
10504176Stz204579    my $deprecated = $textList->getDeprecated();
10514176Stz204579
10524176Stz204579    addHeader($header);
10534176Stz204579    print "$textName starts at $start\n" if $debug;
10544176Stz204579
10554176Stz204579    my $entry;
10564176Stz204579    my @entry;
10574176Stz204579    while ($entry = $textList->getNextMsg()) {
10584176Stz204579        if ($debug) {
10594176Stz204579	    my ($id, $text) = split(/\s*::\s*/, $entry);
10604176Stz204579	    print "   $id = $text\n";
10614176Stz204579	}
10624176Stz204579	unshift (@entry, $entry);
10634176Stz204579    }
10644176Stz204579    $msg_list{$textName} =
10654176Stz204579	[\@entry, [$header, $start, $public, $deprecated]];
10664176Stz204579}
10674176Stz204579
10684176Stz204579sub addHeader {
10694176Stz204579    my $header_index = shift;
10704176Stz204579
10714176Stz204579    die "invalid adt_event_N.h index: $header_index\n"
10724176Stz204579        unless ($header_index =~ /^\d+$/);
10734176Stz204579
10744176Stz204579    $headers{$header_index} = $header_index;
10754176Stz204579}
10764176Stz204579
10774176Stz204579# $header = 0 is a special case; it is for adt_event.h
10784176Stz204579# $header > 0 creates adt_event_N.h, where N = $header
10794176Stz204579
10804176Stz204579sub openHeaderFiles {
10814176Stz204579    my $outfile = shift;	# path to an adt_event_N.h file
10824176Stz204579
10834176Stz204579    my $header;
10844176Stz204579    my @Hfile = (); # potentially sparse array of file handles
10854176Stz204579    my @HfileName = (); # parallel array to Hfile, file name (not path)
10864176Stz204579    foreach $header (sort keys %headers) {
10874176Stz204579        my $file = $outfile;
10884176Stz204579	if ($header > 0) {
10894176Stz204579	    $file =~ s/_N/_$header/;
10904176Stz204579	} else {
10914176Stz204579	    $file =~ s/_N//;
10924176Stz204579	}
10934176Stz204579	unless (open($Hfile[$header], ">$file")) {
10944176Stz204579	    print STDERR "can't open output ($file): $!\n";
10954176Stz204579	    $HfileName[$header] = '';
10964176Stz204579	    $Hfile[$header] = '';
10974176Stz204579	} else {
10984176Stz204579	    my @tmp = split(/\//, $file);
10994176Stz204579	    $HfileName[$header] = $tmp[$#tmp];
11004176Stz204579	}
11014176Stz204579    }
11024176Stz204579    return (@Hfile);
11034176Stz204579}
11044176Stz204579
11054176Stz204579sub closeHeaderFiles {
11064176Stz204579    my @Hfile = @_;
11074176Stz204579
11084176Stz204579    my $header;
11094176Stz204579    foreach $header (sort keys %headers) {
11104176Stz204579	close $Hfile[$header] if $Hfile[$header];
11114176Stz204579    }
11124176Stz204579}
1113