Home | History | Annotate | Download | only in libadt_jni
      1 #!/usr/perl5/bin/perl -w
      2 #
      3 # CDDL HEADER START
      4 #
      5 # The contents of this file are subject to the terms of the
      6 # Common Development and Distribution License (the "License").
      7 # You may not use this file except in compliance with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 #
     23 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     24 # Use is subject to license terms.
     25 #
     26 # ident	"%Z%%M%	%I%	%E% SMI"
     27 #
     28 
     29 # auditxml_jni [-d] <xml input file>
     30 
     31 # auditxml takes the audit record description (.xml file) and
     32 # generates the files needed for the Java
     33 
     34 use auditxml;
     35 use Getopt::Std;
     36 use vars qw($opt_d);
     37 use strict;
     38 
     39 
     40 our $debug = 0; # normal use is to set via the file being parsed.
     41                # <debug set="on"/> or <debug set="off"/> or <debug/>
     42                # if the set attribute is omitted, debug state is toggled
     43                # Override with appDebug, but toggle won't do what you
     44                # want.
     45 my $appDebug = 0; # used after return from "new auditxml";
     46 
     47 my $genNotice = "
     48 DO NOT EDIT. This file is auto generated by the Solaris Audit
     49 system from adt.xml.
     50 
     51 See http://opensolaris.org/os/project/audit/
     52 ";
     53 
     54 # trim leading/trailing newlines
     55 $genNotice =~ s/^\n//s;
     56 $genNotice =~ s/\n$//s;
     57 my $prog = $0; $prog =~ s|.*/||g;
     58 my $usage = "usage: $prog [-d] file.xml\n";
     59 
     60 getopts('d');
     61 
     62 $appDebug = $opt_d;
     63 
     64 my $uniLabel = "adr";
     65 my $xlateUniLabelInc = 0;
     66 
     67 die $usage if ($#ARGV < 0);
     68 
     69 # where everything comes from and where it goes:
     70 
     71 my $templatePath = './';
     72 my $javaPath     = $templatePath;
     73 my $bsmBuildPath = "../libbsm";
     74 
     75 my $jniBuildPath = "$javaPath";
     76 
     77 my $buildPathJ	 = "$jniBuildPath/com/sun/audit";
     78 my $buildPathJNI = "$jniBuildPath/common";
     79 
     80 my $auditEventJ = "$buildPathJ/AuditEvent.java";
     81 my $jniC = "$buildPathJNI/adt_jni_event.c";
     82 my $mapFile = "$jniBuildPath/common/mapfile-vers";
     83 
     84 my $doc = new auditxml ($ARGV[0]);  # input XML file
     85 
     86 $debug = $appDebug;
     87 
     88 my %jniEventTable = ();
     89 my %externalIdNo = ();
     90 my %msg_list = ();
     91 my %eventCode = ();
     92 
     93 readAuditEventFile("$bsmBuildPath/audit_event.txt");
     94 
     95 my $event;
     96 while ($event = $doc->getNextEvent()) {
     97     my $eventId = $event->getId();
     98     my $idNo = $event->getIdNo();
     99     $externalIdNo{$eventId} = $idNo;
    100     my $super;
    101     my $omit = $event->getOmit();
    102     my $eventType = '';
    103     if ($super = $event->getSuperClass()) {
    104 	$event = $super;
    105 	$eventType = 'instance';
    106     } else {
    107 	$eventType = $event->getType();
    108     }
    109 
    110     # c file table for translation
    111     generateTableC($event, $eventId, $eventType, undef, $omit);
    112 }
    113 
    114 while (my $textList = $doc->getNextMsgId()) {
    115     generateMsgLists($textList);  # enum -> text mappings
    116 }
    117 
    118 printJavaFiles($jniC, $auditEventJ, $buildPathJ, $mapFile);
    119 
    120 exit 0;
    121 
    122 
    123 
    124 sub printJavaFiles {
    125     my $jniFile = shift;
    126     my $javaFile = shift;
    127     my $subclassPath = shift;
    128     my $mapFile = shift;
    129 
    130     # warning: time_t is equated to jlong since there is no
    131     # way to use sys/types.h in Java code.
    132     # java long is C long long, 64 bits.
    133     # java int is 32 bits.
    134 
    135     my %java_jni = ('ADT_DATE'		=> ['long',	'jlong'],
    136 		    'ADT_UINT'		=> ['int',	'jint'],
    137 		    'ADT_INT'		=> ['int',	'jint'],
    138 		    'ADT_INT32'		=> ['int',	'jint'],
    139 		    'ADT_UID'		=> ['int',	'jint'],
    140 		    'ADT_GID'		=> ['int',	'jint'],
    141 		    'ADT_UIDSTAR'	=> ['int[]',	'jintArray'],
    142 		    'ADT_GIDSTAR'	=> ['int[]',	'jintArray'],
    143 		    'ADT_CHAR'		=> ['String',	'jchar'],
    144 		    'ADT_CHARSTAR'	=> ['String',	'jstring'],
    145 		    'ADT_CHAR2STAR'	=> ['String[]',	'jstring'],
    146 		    'ADT_MSG'		=> ['int',	'jint'],
    147 		    'ADT_PID'		=> ['int',	'jint'],
    148 # ADT_PRIVSTAR omitted -- not implemented and the audit records that
    149 # use it must be coded to emit no java.  We'll cross that bridge
    150 # when someone in Java land needs to generate a priv token.
    151 		    'ADT_LONG'		=> ['int',	'jint'],
    152 		    'ADT_TERMIDSTAR'	=> ['String',	'jstring'],	# hostname -> termid
    153 		    'ADT_ULONG'		=> ['int',	'jint'],
    154 		    'ADT_UINT16'	=> ['int',	'jint'],
    155 		    'ADT_UINT32'	=> ['int',	'jint'],
    156 		    'ADT_UINT32STAR'	=> ['int[]',	'jintArray'],
    157 # ADT_UINT32ARRAY omitted; no Java implementation yet
    158 		    'ADT_UINT64'	=> ['long',	'jlong'],
    159 		    'ADT_UINT64STAR'	=> ['long[]',	'jlongArray']
    160 		   );
    161     my $noMemory = 'gettext("Out of memory")';
    162 
    163     # open output files
    164     open (Cfile, ">$jniFile") or
    165 	die "can't open output file ($jniFile): $!\n";
    166     open (Jfile, ">$javaFile") or
    167 	die "can't open output file ($javaFile): $!\n";
    168     open (MapFile, ">$mapFile") or
    169 	die "can't open output file ($mapFile): $!\n";
    170 
    171     # write headers
    172     my $notice = $genNotice;
    173     $notice =~ s/\n/\n * /gs;
    174     $notice =~ s/\s+\n/\n/gs;
    175     print Cfile <<EOF;
    176 /*
    177  * $notice
    178  */
    179 
    180 #include "../../libbsm/common/adt_xlate.h"
    181 #include <jni.h>
    182 #include "../com/sun/audit/AuditSession.h"	/* javah output */
    183 #include "adt_jni.h"
    184 #include <stdlib.h>
    185 #include <string.h>
    186 
    187 static char *except_class = "java/lang/Exception";
    188 
    189 EOF
    190     print Jfile <<EOF;
    191 /*
    192  * $notice
    193  */
    194 
    195 package com.sun.audit;
    196 
    197 public class AuditEvent {
    198 	protected AuditSession sh;	// associated session object
    199 
    200 	public AuditEvent(AuditSession auSession)
    201 	    throws Error
    202 	{
    203 
    204 		sh = auSession;
    205 	}
    206 
    207 	// See the subclasses of AuditEvent for mapping message codes
    208 	// to events
    209 EOF
    210 
    211     my $notice_map = $genNotice;
    212     $notice_map =~ s/\n/\n# /gs;
    213     $notice_map =~ s/\s+\n/\n/gs;
    214     print MapFile <<EOF;
    215 #
    216 # $notice_map
    217 #
    218 
    219 SUNWprivate_1.1 {
    220     global:
    221 	c2j_pointer;
    222 	j2c_pointer;
    223 	Java_com_sun_audit_AuditSession_bsmAuditOn;
    224 	Java_com_sun_audit_AuditSession_startSession;
    225 	Java_com_sun_audit_AuditSession_endSession;
    226 	Java_com_sun_audit_AuditSession_dupSession;
    227 	Java_com_sun_audit_AuditSession_getSessionId;
    228 	Java_com_sun_audit_AuditSession_exportSessionData;
    229 	Java_com_sun_audit_AuditSession_sessionAttr;
    230 
    231 # One subclass of AuditEvent per audit record...
    232 EOF
    233 
    234     # generate java final int classes to line up with string/enums
    235 
    236     foreach my $listName (sort keys %msg_list) {
    237         my $shortName = uc $listName;
    238         $shortName =~ s/_TEXT//;
    239         my ($listRef, $headref) = @{$msg_list{$listName}};
    240         my @listValue =  @$listRef;
    241         my ($header, $enumValue, $public, $deprecated) = @$headref;
    242         my $listValue;
    243     
    244         print Jfile "\n\t// adt_$listName" . "\n\n";
    245         print Jfile "\tpublic static final int ADT_$shortName",
    246     		" = $enumValue;\n" if $enumValue;
    247     
    248         next unless ($#listValue >= 0);
    249         print Jfile "\t// Deprecated message list\n" if $deprecated;
    250         foreach $listValue (@listValue) {
    251             my ($id, $text) = split(/\s*::\s*/, $listValue);
    252     	    print Jfile "\t// $text\n";
    253     	    print Jfile "\tpublic static final int ADT_$shortName";
    254 	    print Jfile "_$id = $enumValue;\n";
    255     	    $enumValue++;
    256         }
    257     }
    258 
    259     # generate event creation and access functions and event
    260     # generation for both Java and JNI
    261     # com.sun.audit.AuditEvent_xxx.java
    262     foreach my $eventId (sort keys %jniEventTable) {
    263 	my ($ref1, $eventType, $allowedIds, $header) = @{$jniEventTable{$eventId}};
    264 	$eventCode{$eventId} = -1 if ($eventType eq 'generic');
    265 	my @entries = @$ref1;
    266 	my $entries = $#entries;
    267 	my $root = $eventId;
    268 	$root =~ s/AUE_//;
    269 	my $javaPutEvent = 'putEvent';
    270 	my $putMethod = "_$root";
    271 	$putMethod =~ s/_/_1/g;
    272 	    
    273 	my $jniPutEvent = "Java_com_sun_audit_AuditEvent$putMethod" . "_$javaPutEvent";
    274 
    275 	# the subclass file template isn't used; it may be needed to get
    276 	# the right file header stuff in place.  The subclassPath is
    277 	# the directory that contains 'em.
    278 
    279 	my $validSfile = 1;
    280 	unless (open(Sfile, ">$subclassPath/AuditEvent_$root.java")) {
    281 	    print STDERR "can't open class file AuditEvent_$root.java: $!\n";
    282 	    $validSfile = 0;
    283 	}
    284 	if ($eventCode{"AUE_$root"}) {
    285 	    if ($validSfile) {
    286 		print Sfile <<EOF;
    287 /*
    288  * $notice
    289  */
    290 
    291 package com.sun.audit;
    292 
    293 // audit event:  $eventId = $eventCode{"AUE_$root"}
    294 
    295 public class AuditEvent_$root extends AuditEvent {
    296 
    297 EOF
    298 	    }
    299 	} else {
    300 	    print STDERR "no event code for $eventId.  Is audit_event current?\n";
    301 	}
    302 	my $nativeParameterList = '';
    303 	my $jniParameterList = '';
    304 	my $specParameterList = '';
    305 	my $jniStorageList = '';
    306 	my $needCleanupTarget = 0;
    307 	my $jniFreeList = '';
    308 
    309 	my $haveStringDef = 0;
    310 	my $haveCDef = 0;
    311 	my $haveLengthDef = 0;
    312 	my $haveStringArrayDef = 0;
    313 	my $cntTermidDef = 0;
    314 	my $jniDefine;
    315 	my $needLocaleDefined = 0;
    316 	my $jniADTalloc;
    317 	if (defined $header && ($header > 0) ) {
    318 	    $jniDefine = "union union_of_events	*event;\n" .
    319 		"\tadt_session_data_t	*session;\n";
    320 	    $jniADTalloc = '(union union_of_events *)adt_alloc_event';
    321 	} else {
    322 	    $jniDefine = "adt_event_data_t	*event;\n" .
    323 		"\tadt_session_data_t	*session;\n";
    324 	    $jniADTalloc = 'adt_alloc_event';
    325 	}
    326 	my $ref2;
    327 	foreach $ref2 (@entries) {
    328 	    my ($id, $type) = @$ref2;
    329 	    my $jniRoot = $root . $id;
    330 	    $jniRoot =~ s/_/_1/g;  # escape unicode "_"
    331 
    332 	    my $p_event;
    333 	    if (defined $header && ($header > 0) ) {
    334 		$p_event = "event->d$header.adt_$root.$id";
    335 	    } else {
    336 		$p_event = "event->adt_$root.$id";
    337 	    }
    338 
    339 	    if ($type eq 'ADT_UINT32STAR') { # int array
    340 	        $needLocaleDefined = 1;
    341 
    342 
    343 	        $jniStorageList .= <<EOF;
    344 	/* $id */
    345 	length = (*env)->GetArrayLength(env, $id);
    346 	$p_event =
    347 	    (int *)malloc(length * sizeof (int));
    348 	if ($p_event == NULL) {
    349 		locale = I18N_SETUP;
    350 		local_throw(env, except_class,
    351 		    $noMemory);
    352 		(void) setlocale(LC_MESSAGES, locale);
    353 		goto cleanup;
    354 	}
    355 	(*env)->GetIntArrayRegion(env, $id, 0, length,
    356 	    (int *)$p_event);
    357 EOF
    358 
    359 
    360 		$jniFreeList .= "\n\tif ($p_event != NULL)\n" .
    361 		    "\t\tfree($p_event);\n";
    362 		unless ($haveLengthDef) {
    363 		    $haveLengthDef = 1;
    364 		    $jniDefine .= "\tint\t\t\tlength;\n";
    365 		}
    366 		$nativeParameterList .= ",\n\t    int[]\t$id";
    367 		$jniParameterList .= ",\n    jintArray\t$id";
    368 		$specParameterList .= ", jintArray";
    369 		$needCleanupTarget = 1;
    370 	    } elsif (($type eq 'ADT_UIDSTAR') ||
    371 		     ($type eq 'ADT_GIDSTAR')) { # gid_t array
    372 		my $cType = 'uid_t';
    373 		$cType = 'gid_t' if ($type eq 'ADT_GIDSTAR');
    374 		$needLocaleDefined = 1;
    375 
    376 
    377 		$jniStorageList .= <<EOF;
    378 	/* $id */
    379 	length = (*env)->GetArrayLength(env, $id);
    380 	$p_event =
    381 	    ($cType *)malloc(length * sizeof ($cType));
    382 	if ($p_event == NULL) {
    383 		locale = I18N_SETUP;
    384 		local_throw(env, except_class,
    385 		    $noMemory);
    386 		(void) setlocale(LC_MESSAGES, locale);
    387 		goto cleanup;
    388 	}
    389 	(*env)->GetIntArrayRegion(env, $id, 0, length,
    390 	    (int *)$p_event);
    391 EOF
    392 
    393 
    394 		$jniFreeList .=
    395 		    "\n\tif ($p_event != NULL)\n" .
    396 		    "\t\tfree($p_event);\n";
    397 		unless ($haveLengthDef) {
    398 		    $haveLengthDef = 1;
    399 		    $jniDefine .= "\tint\t\t\tlength;\n";
    400 		}
    401 		$nativeParameterList .= ",\n\t    int[]\t$id";
    402 		$jniParameterList .= ",\n    jintArray\t$id";
    403 		$specParameterList .= ", jintArray";
    404 		$needCleanupTarget = 1;
    405 	    } elsif ($type eq 'ADT_UINT64STAR') { # long array
    406 	        $needLocaleDefined = 1;
    407 	        $jniStorageList .= <<EOF;
    408 	/* $id */
    409 	length = (*env)->GetArrayLength(env, $id);
    410 	$p_event =
    411 	    (long *)malloc(length * sizeof (long long));
    412 	if ($p_event == NULL) {
    413 		locale = I18N_SETUP;
    414 		local_throw(env, except_class,
    415 		    $noMemory);
    416 		(void) setlocale(LC_MESSAGES, locale);
    417 		goto cleanup;
    418 	}
    419 	(*env)->GetLongArrayRegion(env, $id, 0, length,
    420 	    $p_event);
    421 EOF
    422 		$jniFreeList .= "\n\tif ($p_event != NULL)\n" .
    423 		    "\t\tfree($p_event);\n";
    424 		unless ($haveLengthDef) {
    425 		    $haveLengthDef = 1;
    426 		    $jniDefine .= "\tint\t\t\tlength;\n";
    427 		}
    428 		$nativeParameterList .= ",\n\t    long[]\t$id";
    429 		$jniParameterList .= ",\n    jlongArray\t$id";
    430 		$specParameterList .= ", jlongArray";
    431 		$needCleanupTarget = 1;
    432 	    } elsif ($type eq 'ADT_CHAR') { # string in Java, char in C
    433 		$jniStorageList .= <<EOF;
    434 
    435 	/* $id */
    436 	c = (char *)(*env)->GetStringUTFChars(env, $id, NULL);
    437 	if (c == NULL)
    438 		goto cleanup; /* exception thrown */
    439 	$p_event = *c;
    440 	(*env)->ReleaseStringUTFChars(env, $id, c);
    441 EOF
    442 		# no need to free anything
    443 		unless ($haveCDef) {
    444 		    $haveCDef = 1;
    445 		    $jniDefine .= "\tchar\t\t\t*c\n";
    446 		}
    447 		$nativeParameterList .= ",\n\t    String\t$id";
    448 		$jniParameterList .= ",\n    jstring\t$id";
    449 		$specParameterList .= ", jstring";
    450 	    } elsif ($type eq 'ADT_CHARSTAR') {
    451 	        $needLocaleDefined = 1;
    452 		$jniStorageList .= <<EOF;
    453 	/* $id */
    454 	if ($id != NULL) {
    455 		string = (char *)(*env)->GetStringUTFChars(
    456 		    env, $id, NULL);
    457 		if (string == NULL)
    458 			goto cleanup; /* exception thrown */
    459 		$p_event = strdup(string);
    460 		(*env)->ReleaseStringUTFChars(env, $id, string);
    461 		if ($p_event == NULL) {
    462 			locale = I18N_SETUP;
    463 			local_throw(env, except_class,
    464 			    $noMemory);
    465 			(void) setlocale(LC_MESSAGES, locale);
    466 			goto cleanup;
    467 		}
    468 	}
    469 EOF
    470 		$jniFreeList .= "\n\tif ($p_event != NULL)\n" .
    471 		    "\t\tfree($p_event);\n";
    472 		unless ($haveStringDef) {
    473 		    $haveStringDef = 1;
    474 		    $jniDefine .= "\tchar\t\t\t*string;\n";
    475 		}
    476 		$nativeParameterList .= ",\n\t    String\t$id";
    477 		$jniParameterList .= ",\n    jstring\t$id";
    478 		$specParameterList .= ", jstring";
    479 		$needCleanupTarget = 1;
    480 	    } elsif ($type eq 'ADT_CHAR2STAR') { # array of string
    481 	        $needLocaleDefined = 1;
    482 		$jniStorageList .= <<EOF;
    483 	/* $id */
    484 	length = (*env)->GetArrayLength(env, $id);
    485 	$p_event = (char **)malloc(length
    486 	    * sizeof (char *));
    487 	if ($p_event == NULL) {
    488 		locale = I18N_SETUP;
    489 		local_throw(env, except_class,
    490 		    $noMemory);
    491 		(void) setlocale(LC_MESSAGES, locale);
    492 		goto cleanup;
    493 	}
    494 	p = $p_event;
    495 	for (i = 0; i < length; i++) {
    496 		jString = (*env)->GetObjectArrayElement(env, $id, i);
    497 		string = (char *)(*env)->GetStringUTFChars(
    498 		    env, jString, NULL);
    499 		if (string == NULL)
    500 			goto cleanup; /* exception thrown */
    501 		*p = strdup(string);
    502 		(*env)->ReleaseStringUTFChars(env, jString, string);
    503 		if (*p == NULL) {
    504 			locale = I18N_SETUP;
    505 			local_throw(env, except_class,
    506 			    $noMemory);
    507 			(void) setlocale(LC_MESSAGES, locale);
    508 			while (p >= $p_event)
    509 				free(*p--);
    510 			goto cleanup;
    511 		}
    512 		p++;
    513 	}
    514 EOF
    515 		$jniFreeList .=
    516 		    "\n\tif ($p_event != NULL)\n" .
    517 		    "\t\tfree($p_event);\n";
    518 		unless ($haveStringArrayDef) {
    519 		    unless ($haveStringDef) {
    520 			$haveStringDef = 1;
    521 			$jniDefine .= <<EOF;
    522 	char			*string;
    523 EOF
    524 		    }
    525 		    unless ($haveLengthDef) {
    526 			$haveLengthDef = 1;
    527 			$jniDefine .= <<EOF;
    528 	int			length;
    529 EOF
    530 		    }
    531 		    $haveStringArrayDef = 1;
    532 		    $jniDefine .= <<EOF;
    533 	int			i;
    534 	char			**p;
    535 	jstring			jString;
    536 EOF
    537 		}
    538 		$nativeParameterList .= ",\n\t    String[]\t$id";
    539 		$jniParameterList .= ",\n    jstring\t$id";
    540 		$specParameterList .= ", jstring";
    541 		$needCleanupTarget = 1;
    542 	      } elsif ($type eq 'ADT_TERMIDSTAR') {
    543 	        $needLocaleDefined = 1;
    544 
    545 	        $jniStorageList .= <<EOF;
    546 	/* $id */
    547 	hostname$cntTermidDef = (char *)(*env)->GetStringUTFChars(env, $id, NULL);
    548 
    549 	if (adt_load_hostname((const char *)hostname$cntTermidDef, &termid$cntTermidDef)) {
    550 		local_throw(env, except_class,
    551 			gettext("hostname lookup failed"));
    552 	}
    553 	$p_event = termid$cntTermidDef;
    554 
    555 	(*env)->ReleaseStringUTFChars(env, $id, hostname$cntTermidDef);
    556 EOF
    557 
    558 		$jniFreeList .= "\n\tif (hostname$cntTermidDef != NULL)\n" .
    559 		    "\t\tfree(hostname$cntTermidDef);\n";
    560 		$jniFreeList .= "\n\tif (termid$cntTermidDef != NULL)\n" .
    561 		    "\t\tfree(termid$cntTermidDef);\n";
    562 
    563 		$jniDefine .= "\tchar\t\t\t*hostname$cntTermidDef;\n";
    564 		$jniDefine .= "\tadt_termid_t\t\t*termid$cntTermidDef;\n"; #djdj
    565 
    566 		$cntTermidDef++;
    567 
    568 		my ($nativeParameter, $jniParameter) = @{$java_jni{$type}};
    569 		$nativeParameterList .= ",\n\t    $nativeParameter\t$id";
    570 		$jniParameterList .= ",\n    $jniParameter\t$id";
    571 		$specParameterList .= ", $jniParameter";
    572 		$needCleanupTarget = 1;
    573 	    } else {  # all others are primitive types
    574 		$jniStorageList .= "\n\t$p_event = $id;\n";
    575 		my ($nativeParameter, $jniParameter) = @{$java_jni{$type}};
    576 		$nativeParameter = "$nativeParameter\t"
    577 		    if length $nativeParameter < 4;  # why?
    578 		$nativeParameterList .= ",\n\t    $nativeParameter\t$id";
    579 		$jniParameterList .= ",\n    $jniParameter\t$id";
    580 		$specParameterList .= ", $jniParameter";
    581 	    }
    582 	}
    583 	if ($needLocaleDefined) {
    584 		$jniDefine .= <<EOF
    585 	char			*locale;
    586 EOF
    587 	}
    588 	my $genericOverride = '';
    589 	my $idParameter = $eventId;
    590 	$idParameter =~ s/AUE_/ADT_/;
    591 	if ($eventType eq 'generic') {
    592 	    $genericOverride = ', jint eventId';
    593 	    $idParameter = 'eventId';
    594 	}
    595 	$jniFreeList = "\tcleanup:\n" . $jniFreeList if $needCleanupTarget;
    596 
    597 	print Cfile qq{/* ARGSUSED */
    598 JNIEXPORT void JNICALL
    599 $jniPutEvent(
    600     JNIEnv	*env,
    601     jobject	self,
    602     jbyteArray	jsession$genericOverride,
    603     jint	status,
    604     jint	ret_val$jniParameterList)
    605 {
    606 	$jniDefine
    607 	(void) j2c_pointer(env, jsession, (char **)&session);
    608 
    609 	event = $jniADTalloc(session, $idParameter);
    610 
    611 $jniStorageList
    612 	(void) adt_put_event((adt_event_data_t *)event, status, ret_val);
    613 
    614 $jniFreeList
    615 	adt_free_event((adt_event_data_t *)event);
    616 }
    617 };
    618 	print MapFile qq{
    619 	$jniPutEvent; };
    620 	my $overrideParameter = '';
    621 	if ($eventType eq 'generic') {
    622 	    $overrideParameter = 'int eventId,';
    623 	    my @allowed = @$allowedIds;
    624 	    if (@allowed) {
    625 		my $i;
    626 		if ($validSfile) {
    627 		    print Sfile "\t// Allowed values for eventId in putEvent:\n";
    628 		    for ($i = 0; $i <= $#allowed; $i++) {
    629 			my $idNo = $externalIdNo{$allowed[$i]};
    630 			$allowed[$i] =~ s/AUE_/ADT_/;
    631 			print Sfile "\tstatic final int $allowed[$i] = ",
    632 			     "$idNo;\n";
    633 		    }
    634 		    print Sfile "\n";
    635 		}
    636 	    } else {
    637 		print STDERR "Generic event with no allowed instances: $eventId\n";
    638 	    }
    639 	}
    640 	if ($validSfile) {
    641 	    print Sfile <<EOF;
    642 	private native void $javaPutEvent(byte[]session, $overrideParameter
    643 	    int status, int ret_val$nativeParameterList);
    644 
    645 	public AuditEvent_$root(AuditSession session)
    646 		throws Exception
    647 	{
    648 		super(session);
    649 	}
    650 
    651 EOF
    652 	    my $javaParameterList = '';
    653 	    foreach $ref2 (@entries) {
    654 		my ($id, $type, $format, $jComment, $required) = @$ref2;
    655 
    656 		# generate java native method prototypes
    657 		# and the corresponding C method implementation
    658 		
    659 		my $javaMethodName = "$id";
    660 		my $javaStorageName = $javaMethodName . '_val';
    661 		my $jniMethodName = $root . $id;
    662 		my $storage;
    663 		my $enumUsage = '';
    664 		my $jParam = @{$java_jni{$type}}[0];
    665 		my $comment = '';
    666 		if ($required) {
    667 		    if ($format ne 'NULL') {
    668 			$comment = "\t// (required) formatted:  $format";
    669 		    } else {
    670 			$comment = "\t// required";
    671 		    }
    672 		} else {
    673 		    if ($format ne 'NULL') {
    674 			$comment = "\t// (optional) formatted:  $format";
    675 		    } else {
    676 			$comment = "\t// optional";
    677 		    }
    678 		}
    679 		if (($type eq 'ADT_UINT32STAR') ||
    680 		    ($type eq 'ADT_UIDSTAR') ||
    681 		    ($type eq 'ADT_GIDSTAR')) { # int array
    682 		    $storage = "int[] $javaStorageName" . ($required ?
    683 							   ' = {}' : '');
    684 		    $javaParameterList .= ",\n\t\t\t    $javaStorageName";
    685 		} elsif ($type eq 'ADT_UINT64STAR') { # long array
    686 		    $storage = "long[] $javaStorageName" . ($required ?
    687 							    ' = {}' : '');
    688 		    $javaParameterList .= ",\n\t\t\t    $javaStorageName";
    689 		} elsif (($type eq 'ADT_CHARSTAR') ||
    690 			 ($type eq 'ADT_CHAR')) { # string
    691 		    $storage = "String $javaStorageName" . ($required ?
    692 							    ' = ""' : '');
    693 		    $javaParameterList .= ",\n\t\t\t    $javaStorageName";
    694 		} elsif ($type eq 'ADT_CHAR2STAR') { # array of string
    695 		    $storage = "String[] $javaStorageName" . ($required ?
    696 							      ' = {}' : '');
    697 		    $javaParameterList .= ",\n\t\t\t    $javaStorageName";
    698 		} elsif ($type eq 'ADT_TERMIDSTAR') { # array of string
    699 		    $storage = "String $javaStorageName" . ($required ?
    700 							    ' = ""' : '');
    701 		    $javaParameterList .= ",\n\t\t\t    $javaStorageName";
    702 		} else {  # all others are primitive types
    703 		    $storage = "$jParam $javaStorageName = 0";
    704 		    $javaParameterList .= ",\n\t\t\t    $javaStorageName";
    705 		    $enumUsage = "\n\t// See $jComment in AuditEvent.java for valid values"
    706 			if $jComment;
    707 		}
    708 		print Sfile <<EOF;
    709 $enumUsage
    710 	private $storage;$comment
    711 	public void $javaMethodName($jParam setTo)
    712 	{
    713 		$javaStorageName = setTo;
    714 	}
    715 EOF
    716 	    }	# end foreach (@entries)
    717 	    if ($eventType eq 'generic') {
    718 		print Sfile <<EOF;
    719 
    720 	public void putEvent(int status, int ret_val, int eventId)
    721 	{
    722 		byte[]	session = super.sh.getSession();
    723 
    724 		if ((super.sh.AuditIsOn) && (super.sh.ValidSession))
    725 			$javaPutEvent(session, eventId,
    726 			    status, ret_val$javaParameterList);
    727 	}
    728 }
    729 EOF
    730 	    } else { 
    731 		print Sfile <<EOF;
    732 
    733 	public void putEvent(int status, int ret_val)
    734 	{
    735 		byte[]	session = super.sh.getSession();
    736 
    737 		if ((super.sh.AuditIsOn) && (super.sh.ValidSession))
    738 			$javaPutEvent(session, status, ret_val$javaParameterList);
    739 	}
    740 }
    741 EOF
    742 	    }
    743 	    close Sfile;
    744 	}	# end if ($validSfile);
    745     }
    746  
    747     # write trailers
    748     print Jfile <<EOF;
    749 
    750 }
    751 EOF
    752     print MapFile <<EOF;
    753 
    754     local:
    755 	*;
    756 };
    757 EOF
    758     close Cfile;
    759     close Jfile;
    760     close MapFile;
    761 }
    762 
    763 sub generateTableC {
    764     my $event = shift;
    765     my $eventId = shift;
    766     my $eventType = shift;
    767     my $eventHeader = shift;
    768     my $omit = shift;
    769 
    770     my %tokenType = (
    771 		  'acl'			=> 'AUT_ACL',
    772 		  'arbitrary'		=> 'AUT_ARBITRARY',
    773 		  'arg'			=> 'AUT_ARG',
    774 		  'attr'		=> 'AUT_ATTR',
    775 		  'command'		=> 'AUT_CMD',
    776 		  'command_1'		=> 'ADT_CMD_ALT',	# dummy token id
    777 		  'date'		=> 'AUT_TEXT',
    778 		  'exec_args'   	=> 'AUT_EXEC_ARGS',
    779 		  'exec_env'    	=> 'AUT_EXEC_ENV',
    780 		  'exit'        	=> 'AUT_EXIT',
    781 		  'file'        	=> 'AUT_FILE',
    782 		  'fmri'        	=> 'AUT_FMRI',
    783 		  'groups'      	=> 'AUT_GROUPS',
    784 	#	  'header'      	=> 'AUT_HEADER',	# not used
    785 		  'in_addr'     	=> 'AUT_IN_ADDR',
    786 		  'tid'          	=> 'AUT_TID',
    787 		  'ipc'         	=> 'AUT_IPC',
    788 		  'ipc_perm'    	=> 'AUT_IPC_PERM',
    789 		  'iport'		=> 'AUT_IPORT',
    790 		  'label'		=> 'AUT_LABEL',
    791 		  'newgroups'   	=> 'AUT_NEWGROUPS',
    792 		  'opaque'      	=> 'AUT_OPAQUE',
    793 		  'path'        	=> 'AUT_PATH',
    794 		  'path_list'		=> '-AUT_PATH',		# dummy token id
    795 		  'process'     	=> 'AUT_PROCESS',
    796 		  'priv_effective'	=> 'ADT_AUT_PRIV_E',	# dummy token id
    797 		  'priv_limit'		=> 'ADT_AUT_PRIV_L', 	# dummy token id
    798 		  'priv_inherit'	=> 'ADT_AUT_PRIV_I',	# dummy token id
    799 		  'return'      	=> 'AUT_RETURN',
    800 		  'seq'         	=> 'AUT_SEQ',
    801 		  'socket'      	=> 'AUT_SOCKET',
    802 		  'socket-inet' 	=> 'AUT_SOCKET_INET',
    803 		  'subject'     	=> 'AUT_SUBJECT',
    804 		  'text'        	=> 'AUT_TEXT',
    805 	#	  'trailer'     	=> 'AUT_TRAILER',	# not used
    806 		  'uauth'		=> 'AUT_UAUTH',
    807 		  'zonename'		=> 'AUT_ZONENAME'
    808 		 );
    809 
    810     my @xlateEntryList = ();
    811     my @jniEntryList = ();
    812 
    813     my $external = $event->getExternal();
    814     my $internal = $event->getInternal();
    815 
    816     unless ($external) {
    817 	print STDERR "No external object captured for event $eventId\n";
    818 	return;
    819     }
    820     unless ($internal) {
    821 	print STDERR "No internal object captured for event $eventId\n";
    822 	return;
    823     }
    824     my @entryRef = $internal->getEntries();
    825     my $entryRef;
    826     my @tokenOrder = ();
    827     my $firstTokenIndex = 0; # djdj not used yet, djdj BUG!
    828     			     # needs to be used by translate table
    829 
    830     if ($internal->isReorder()) { # prescan the entry list to get the token order
    831       my @inputOrder;
    832       foreach $entryRef (@entryRef) {
    833 	my ($intEntry, $entry) = @$entryRef;
    834 	push (@inputOrder, $intEntry->getAttr('order'));
    835       }
    836 
    837       my $i; # walk down the inputOrder list once
    838       my $k = 1; # discover next in line
    839       my $l = 0; # who should point to next in line
    840       for ($i = 0; $i <= $#inputOrder; $i++) {
    841 	my $j;
    842 	for ($j = 0; $j <= $#inputOrder; $j++) {
    843 	  if ($k == $inputOrder[$j]) {
    844 	    if ($k == 1) {
    845 	        $firstTokenIndex = $j;
    846 	    } else {
    847 	        $tokenOrder[$l] = "&(selfReference[$j])";
    848 	    }
    849 	    $l = $j;
    850 	    last;
    851 	  }
    852 	}
    853 	$k++;
    854       }
    855       $tokenOrder[$l] = 'NULL';
    856     }
    857     else { # default order -- input order same as output
    858       my $i;
    859       my $j;
    860       for ($i = 0; $i < $#entryRef; $i++) {
    861 	my $j = $i + 1;
    862 	$tokenOrder[$i] = "&(selfReference[$j])";
    863       }
    864       $tokenOrder[$#entryRef] = 'NULL';
    865     }
    866 
    867     my $sequence = 0;
    868     foreach $entryRef (@entryRef) {
    869       my ($intEntry, $entry) = @$entryRef;
    870       my $entryId = $entry->getAttr('id');
    871 
    872       my ($extEntry, $unusedEntry, $tokenId) =
    873 	$external->getEntry($entryId);
    874       my $opt = $extEntry->getAttr('opt');
    875 
    876       if ($opt eq 'none') {
    877 	if (defined ($doc->getToken($tokenId))) {
    878 	  if (defined ($tokenType{$tokenId})) {
    879 	    $tokenId = $tokenType{$tokenId};
    880 	  }
    881 	  else {
    882 	    print STDERR "token id $tokenId not implemented\n";
    883 	  }
    884 	}
    885 	else {
    886 	  print STDERR "token = $tokenId is undefined\n";
    887 	  $tokenId = 'error';
    888 	}
    889 	my ($xlate, $jni) =
    890 	  formatTableEntry ('', $tokenId, $eventId, '', 0, 0, $tokenOrder[$sequence],
    891 			    'NULL', '');
    892 	push (@xlateEntryList, $xlate);
    893 	push (@jniEntryList, @$jni);
    894       }
    895       else {
    896 	my $dataType = $extEntry->getAttr('type');
    897 	$dataType =~ s/\s+//g;   # remove blanks (char * => char*)
    898