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