9511 printf family isn't aware of multibyte decimal point characters (fix regression)
[unleashed.git] / usr / src / lib / libadt_jni / auditxml_jni
blob7c00b3b7dbd2dbffa5ef08f75705842bba3e2b19
1 #!/usr/perl5/bin/perl -w
3 # CDDL HEADER START
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.
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.
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]
20 # CDDL HEADER END
23 # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
26 # auditxml_jni [-d] <xml input file>
28 # auditxml takes the audit record description (.xml file) and
29 # generates the files needed for the Java
31 use auditxml;
32 use Getopt::Std;
33 use vars qw($opt_d);
34 use strict;
37 our $debug = 0; # normal use is to set via the file being parsed.
38 # <debug set="on"/> or <debug set="off"/> or <debug/>
39 # if the set attribute is omitted, debug state is toggled
40 # Override with appDebug, but toggle won't do what you
41 # want.
42 my $appDebug = 0; # used after return from "new auditxml";
44 my $genNotice = "
45 DO NOT EDIT. This file is auto generated by the Solaris Audit
46 system from adt.xml.
48 See http://opensolaris.org/os/project/audit/
51 # trim leading/trailing newlines
52 $genNotice =~ s/^\n//s;
53 $genNotice =~ s/\n$//s;
54 my $prog = $0; $prog =~ s|.*/||g;
55 my $usage = "usage: $prog [-d] file.xml\n";
57 getopts('d');
59 $appDebug = $opt_d;
61 my $uniLabel = "adr";
62 my $xlateUniLabelInc = 0;
64 die $usage if ($#ARGV < 0);
66 # where everything comes from and where it goes:
68 my $templatePath = './';
69 my $javaPath = $templatePath;
70 my $bsmBuildPath = "../libbsm";
72 my $jniBuildPath = "$javaPath";
74 my $buildPathJ = "$jniBuildPath/com/sun/audit";
75 my $buildPathJNI = "$jniBuildPath/common";
77 my $auditEventJ = "$buildPathJ/AuditEvent.java";
78 my $jniC = "$buildPathJNI/adt_jni_event.c";
79 my $mapFile = "$jniBuildPath/common/mapfile-vers";
81 my $doc = new auditxml ($ARGV[0]); # input XML file
83 $debug = $appDebug;
85 my %jniEventTable = ();
86 my %externalIdNo = ();
87 my %msg_list = ();
88 my %eventCode = ();
90 readAuditEventFile("$bsmBuildPath/audit_event.txt");
92 my $event;
93 while ($event = $doc->getNextEvent()) {
94 my $eventId = $event->getId();
95 my $idNo = $event->getIdNo();
96 $externalIdNo{$eventId} = $idNo;
97 my $super;
98 my $omit = $event->getOmit();
99 my $eventType = '';
100 if ($super = $event->getSuperClass()) {
101 $event = $super;
102 $eventType = 'instance';
103 } else {
104 $eventType = $event->getType();
107 # c file table for translation
108 generateTableC($event, $eventId, $eventType, undef, $omit);
111 while (my $textList = $doc->getNextMsgId()) {
112 generateMsgLists($textList); # enum -> text mappings
115 printJavaFiles($jniC, $auditEventJ, $buildPathJ, $mapFile);
117 exit 0;
121 sub printJavaFiles {
122 my $jniFile = shift;
123 my $javaFile = shift;
124 my $subclassPath = shift;
125 my $mapFile = shift;
127 # warning: time_t is equated to jlong since there is no
128 # way to use sys/types.h in Java code.
129 # java long is C long long, 64 bits.
130 # java int is 32 bits.
132 my %java_jni = ('ADT_DATE' => ['long', 'jlong'],
133 'ADT_UINT' => ['int', 'jint'],
134 'ADT_INT' => ['int', 'jint'],
135 'ADT_INT32' => ['int', 'jint'],
136 'ADT_UID' => ['int', 'jint'],
137 'ADT_GID' => ['int', 'jint'],
138 'ADT_UIDSTAR' => ['int[]', 'jintArray'],
139 'ADT_GIDSTAR' => ['int[]', 'jintArray'],
140 'ADT_CHAR' => ['String', 'jchar'],
141 'ADT_CHARSTAR' => ['String', 'jstring'],
142 'ADT_CHAR2STAR' => ['String[]', 'jstring'],
143 'ADT_MSG' => ['int', 'jint'],
144 'ADT_PID' => ['int', 'jint'],
145 # ADT_PRIVSTAR omitted -- not implemented and the audit records that
146 # use it must be coded to emit no java. We'll cross that bridge
147 # when someone in Java land needs to generate a priv token.
148 'ADT_LONG' => ['int', 'jint'],
149 'ADT_TERMIDSTAR' => ['String', 'jstring'], # hostname -> termid
150 'ADT_ULONG' => ['int', 'jint'],
151 'ADT_UINT16' => ['int', 'jint'],
152 'ADT_UINT32' => ['int', 'jint'],
153 'ADT_UINT32STAR' => ['int[]', 'jintArray'],
154 # ADT_UINT32ARRAY omitted; no Java implementation yet
155 'ADT_UINT64' => ['long', 'jlong'],
156 'ADT_UINT64STAR' => ['long[]', 'jlongArray']
158 my $noMemory = 'gettext("Out of memory")';
160 # open output files
161 open (Cfile, ">$jniFile") or
162 die "can't open output file ($jniFile): $!\n";
163 open (Jfile, ">$javaFile") or
164 die "can't open output file ($javaFile): $!\n";
165 open (MapFile, ">$mapFile") or
166 die "can't open output file ($mapFile): $!\n";
168 # write headers
169 my $notice = $genNotice;
170 $notice =~ s/\n/\n * /gs;
171 $notice =~ s/\s+\n/\n/gs;
172 print Cfile <<EOF;
174 * $notice
177 #include "../../libbsm/common/adt_xlate.h"
178 #include <jni.h>
179 #include "../com/sun/audit/AuditSession.h" /* javah output */
180 #include "adt_jni.h"
181 #include <stdlib.h>
182 #include <string.h>
184 static char *except_class = "java/lang/Exception";
187 print Jfile <<EOF;
189 * $notice
192 package com.sun.audit;
194 public class AuditEvent {
195 protected AuditSession sh; // associated session object
197 public AuditEvent(AuditSession auSession)
198 throws Error
201 sh = auSession;
204 // Manifest values: keep them in sync with generated <bsm/adt_event.h>.
205 // It is generated by \$SRC/lib/libbsm/auditxml
207 public static final int ADT_SUCCESS = 0; // generated
208 public static final int ADT_FAILURE = -1; // generated
210 // See the subclasses of AuditEvent for mapping message codes
211 // to events
214 my $notice_map = $genNotice;
215 $notice_map =~ s/\n/\n# /gs;
216 $notice_map =~ s/\s+\n/\n/gs;
217 print MapFile <<EOF;
219 # $notice_map
222 \$mapfile_version 2
224 SYMBOL_VERSION SUNWprivate_1.1 {
225 global:
226 c2j_pointer;
227 j2c_pointer;
228 Java_com_sun_audit_AuditSession_bsmAuditOn;
229 Java_com_sun_audit_AuditSession_startSession;
230 Java_com_sun_audit_AuditSession_endSession;
231 Java_com_sun_audit_AuditSession_dupSession;
232 Java_com_sun_audit_AuditSession_getSessionId;
233 Java_com_sun_audit_AuditSession_exportSessionData;
234 Java_com_sun_audit_AuditSession_sessionAttr;
236 # One subclass of AuditEvent per audit record...
239 # generate java final int classes to line up with string/enums
241 foreach my $listName (sort keys %msg_list) {
242 my $shortName = uc $listName;
243 $shortName =~ s/_TEXT//;
244 my ($listRef, $headref) = @{$msg_list{$listName}};
245 my @listValue = @$listRef;
246 my ($header, $enumValue, $public, $deprecated) = @$headref;
247 my $listValue;
249 print Jfile "\n\t// adt_$listName" . "\n\n";
250 print Jfile "\tpublic static final int ADT_$shortName",
251 " = $enumValue;\n" if $enumValue;
253 next unless ($#listValue >= 0);
254 print Jfile "\t// Deprecated message list\n" if $deprecated;
255 foreach $listValue (@listValue) {
256 my ($id, $text) = split(/\s*::\s*/, $listValue);
257 print Jfile "\t// $text\n";
258 print Jfile "\tpublic static final int ADT_$shortName";
259 print Jfile "_$id = $enumValue;\n";
260 $enumValue++;
264 # generate event creation and access functions and event
265 # generation for both Java and JNI
266 # com.sun.audit.AuditEvent_xxx.java
267 foreach my $eventId (sort keys %jniEventTable) {
268 my ($ref1, $eventType, $allowedIds, $header) = @{$jniEventTable{$eventId}};
269 $eventCode{$eventId} = -1 if ($eventType eq 'generic');
270 my @entries = @$ref1;
271 my $entries = $#entries;
272 my $root = $eventId;
273 $root =~ s/AUE_//;
274 my $javaPutEvent = 'putEvent';
275 my $putMethod = "_$root";
276 $putMethod =~ s/_/_1/g;
278 my $jniPutEvent = "Java_com_sun_audit_AuditEvent$putMethod" . "_$javaPutEvent";
280 # the subclass file template isn't used; it may be needed to get
281 # the right file header stuff in place. The subclassPath is
282 # the directory that contains 'em.
284 my $validSfile = 1;
285 unless (open(Sfile, ">$subclassPath/AuditEvent_$root.java")) {
286 print STDERR "can't open class file AuditEvent_$root.java: $!\n";
287 $validSfile = 0;
289 if ($eventCode{"AUE_$root"}) {
290 if ($validSfile) {
291 print Sfile <<EOF;
293 * $notice
296 package com.sun.audit;
298 // audit event: $eventId = $eventCode{"AUE_$root"}
300 public class AuditEvent_$root extends AuditEvent {
304 } else {
305 print STDERR "no event code for $eventId. Is audit_event current?\n";
307 my $nativeParameterList = '';
308 my $jniParameterList = '';
309 my $specParameterList = '';
310 my $jniStorageList = '';
311 my $needCleanupTarget = 0;
312 my $jniFreeList = '';
314 my $haveStringDef = 0;
315 my $haveCDef = 0;
316 my $haveLengthDef = 0;
317 my $haveStringArrayDef = 0;
318 my $cntTermidDef = 0;
319 my $jniDefine;
320 my $needLocaleDefined = 0;
321 my $jniADTalloc;
322 if (defined $header && ($header > 0) ) {
323 $jniDefine = "union union_of_events *event;\n" .
324 "\tadt_session_data_t *session;\n";
325 $jniADTalloc = '(union union_of_events *)adt_alloc_event';
326 } else {
327 $jniDefine = "adt_event_data_t *event;\n" .
328 "\tadt_session_data_t *session;\n";
329 $jniADTalloc = 'adt_alloc_event';
331 my $ref2;
332 foreach $ref2 (@entries) {
333 my ($id, $type) = @$ref2;
334 my $jniRoot = $root . $id;
335 $jniRoot =~ s/_/_1/g; # escape unicode "_"
337 my $p_event;
338 if (defined $header && ($header > 0) ) {
339 $p_event = "event->d$header.adt_$root.$id";
340 } else {
341 $p_event = "event->adt_$root.$id";
344 if ($type eq 'ADT_UINT32STAR') { # int array
345 $needLocaleDefined = 1;
348 $jniStorageList .= <<EOF;
349 /* $id */
350 length = (*env)->GetArrayLength(env, $id);
351 $p_event =
352 (int *)malloc(length * sizeof (int));
353 if ($p_event == NULL) {
354 locale = I18N_SETUP;
355 local_throw(env, except_class,
356 $noMemory);
357 (void) setlocale(LC_MESSAGES, locale);
358 goto cleanup;
360 (*env)->GetIntArrayRegion(env, $id, 0, length,
361 (int *)$p_event);
365 $jniFreeList .= "\n\tif ($p_event != NULL)\n" .
366 "\t\tfree($p_event);\n";
367 unless ($haveLengthDef) {
368 $haveLengthDef = 1;
369 $jniDefine .= "\tint\t\t\tlength;\n";
371 $nativeParameterList .= ",\n\t int[]\t$id";
372 $jniParameterList .= ",\n jintArray\t$id";
373 $specParameterList .= ", jintArray";
374 $needCleanupTarget = 1;
375 } elsif (($type eq 'ADT_UIDSTAR') ||
376 ($type eq 'ADT_GIDSTAR')) { # gid_t array
377 my $cType = 'uid_t';
378 $cType = 'gid_t' if ($type eq 'ADT_GIDSTAR');
379 $needLocaleDefined = 1;
382 $jniStorageList .= <<EOF;
383 /* $id */
384 length = (*env)->GetArrayLength(env, $id);
385 $p_event =
386 ($cType *)malloc(length * sizeof ($cType));
387 if ($p_event == NULL) {
388 locale = I18N_SETUP;
389 local_throw(env, except_class,
390 $noMemory);
391 (void) setlocale(LC_MESSAGES, locale);
392 goto cleanup;
394 (*env)->GetIntArrayRegion(env, $id, 0, length,
395 (int *)$p_event);
399 $jniFreeList .=
400 "\n\tif ($p_event != NULL)\n" .
401 "\t\tfree($p_event);\n";
402 unless ($haveLengthDef) {
403 $haveLengthDef = 1;
404 $jniDefine .= "\tint\t\t\tlength;\n";
406 $nativeParameterList .= ",\n\t int[]\t$id";
407 $jniParameterList .= ",\n jintArray\t$id";
408 $specParameterList .= ", jintArray";
409 $needCleanupTarget = 1;
410 } elsif ($type eq 'ADT_UINT64STAR') { # long array
411 $needLocaleDefined = 1;
412 $jniStorageList .= <<EOF;
413 /* $id */
414 length = (*env)->GetArrayLength(env, $id);
415 $p_event =
416 (long *)malloc(length * sizeof (long long));
417 if ($p_event == NULL) {
418 locale = I18N_SETUP;
419 local_throw(env, except_class,
420 $noMemory);
421 (void) setlocale(LC_MESSAGES, locale);
422 goto cleanup;
424 (*env)->GetLongArrayRegion(env, $id, 0, length,
425 $p_event);
427 $jniFreeList .= "\n\tif ($p_event != NULL)\n" .
428 "\t\tfree($p_event);\n";
429 unless ($haveLengthDef) {
430 $haveLengthDef = 1;
431 $jniDefine .= "\tint\t\t\tlength;\n";
433 $nativeParameterList .= ",\n\t long[]\t$id";
434 $jniParameterList .= ",\n jlongArray\t$id";
435 $specParameterList .= ", jlongArray";
436 $needCleanupTarget = 1;
437 } elsif ($type eq 'ADT_CHAR') { # string in Java, char in C
438 $jniStorageList .= <<EOF;
440 /* $id */
441 c = (char *)(*env)->GetStringUTFChars(env, $id, NULL);
442 if (c == NULL)
443 goto cleanup; /* exception thrown */
444 $p_event = *c;
445 (*env)->ReleaseStringUTFChars(env, $id, c);
447 # no need to free anything
448 unless ($haveCDef) {
449 $haveCDef = 1;
450 $jniDefine .= "\tchar\t\t\t*c\n";
452 $nativeParameterList .= ",\n\t String\t$id";
453 $jniParameterList .= ",\n jstring\t$id";
454 $specParameterList .= ", jstring";
455 } elsif ($type eq 'ADT_CHARSTAR') {
456 $needLocaleDefined = 1;
457 $jniStorageList .= <<EOF;
458 /* $id */
459 if ($id != NULL) {
460 string = (char *)(*env)->GetStringUTFChars(
461 env, $id, NULL);
462 if (string == NULL)
463 goto cleanup; /* exception thrown */
464 $p_event = strdup(string);
465 (*env)->ReleaseStringUTFChars(env, $id, string);
466 if ($p_event == NULL) {
467 locale = I18N_SETUP;
468 local_throw(env, except_class,
469 $noMemory);
470 (void) setlocale(LC_MESSAGES, locale);
471 goto cleanup;
475 $jniFreeList .= "\n\tif ($p_event != NULL)\n" .
476 "\t\tfree($p_event);\n";
477 unless ($haveStringDef) {
478 $haveStringDef = 1;
479 $jniDefine .= "\tchar\t\t\t*string;\n";
481 $nativeParameterList .= ",\n\t String\t$id";
482 $jniParameterList .= ",\n jstring\t$id";
483 $specParameterList .= ", jstring";
484 $needCleanupTarget = 1;
485 } elsif ($type eq 'ADT_CHAR2STAR') { # array of string
486 $needLocaleDefined = 1;
487 $jniStorageList .= <<EOF;
488 /* $id */
489 length = (*env)->GetArrayLength(env, $id);
490 $p_event = (char **)malloc(length
491 * sizeof (char *));
492 if ($p_event == NULL) {
493 locale = I18N_SETUP;
494 local_throw(env, except_class,
495 $noMemory);
496 (void) setlocale(LC_MESSAGES, locale);
497 goto cleanup;
499 p = $p_event;
500 for (i = 0; i < length; i++) {
501 jString = (*env)->GetObjectArrayElement(env, $id, i);
502 string = (char *)(*env)->GetStringUTFChars(
503 env, jString, NULL);
504 if (string == NULL)
505 goto cleanup; /* exception thrown */
506 *p = strdup(string);
507 (*env)->ReleaseStringUTFChars(env, jString, string);
508 if (*p == NULL) {
509 locale = I18N_SETUP;
510 local_throw(env, except_class,
511 $noMemory);
512 (void) setlocale(LC_MESSAGES, locale);
513 while (p >= $p_event)
514 free(*p--);
515 goto cleanup;
517 p++;
520 $jniFreeList .=
521 "\n\tif ($p_event != NULL)\n" .
522 "\t\tfree($p_event);\n";
523 unless ($haveStringArrayDef) {
524 unless ($haveStringDef) {
525 $haveStringDef = 1;
526 $jniDefine .= <<EOF;
527 char *string;
530 unless ($haveLengthDef) {
531 $haveLengthDef = 1;
532 $jniDefine .= <<EOF;
533 int length;
536 $haveStringArrayDef = 1;
537 $jniDefine .= <<EOF;
538 int i;
539 char **p;
540 jstring jString;
543 $nativeParameterList .= ",\n\t String[]\t$id";
544 $jniParameterList .= ",\n jstring\t$id";
545 $specParameterList .= ", jstring";
546 $needCleanupTarget = 1;
547 } elsif ($type eq 'ADT_TERMIDSTAR') {
548 $needLocaleDefined = 1;
550 $jniStorageList .= <<EOF;
551 /* $id */
552 hostname$cntTermidDef = (char *)(*env)->GetStringUTFChars(env, $id, NULL);
554 if (adt_load_hostname((const char *)hostname$cntTermidDef, &termid$cntTermidDef)) {
555 local_throw(env, except_class,
556 gettext("hostname lookup failed"));
558 $p_event = termid$cntTermidDef;
560 (*env)->ReleaseStringUTFChars(env, $id, hostname$cntTermidDef);
563 $jniFreeList .= "\n\tif (hostname$cntTermidDef != NULL)\n" .
564 "\t\tfree(hostname$cntTermidDef);\n";
565 $jniFreeList .= "\n\tif (termid$cntTermidDef != NULL)\n" .
566 "\t\tfree(termid$cntTermidDef);\n";
568 $jniDefine .= "\tchar\t\t\t*hostname$cntTermidDef;\n";
569 $jniDefine .= "\tadt_termid_t\t\t*termid$cntTermidDef;\n"; #djdj
571 $cntTermidDef++;
573 my ($nativeParameter, $jniParameter) = @{$java_jni{$type}};
574 $nativeParameterList .= ",\n\t $nativeParameter\t$id";
575 $jniParameterList .= ",\n $jniParameter\t$id";
576 $specParameterList .= ", $jniParameter";
577 $needCleanupTarget = 1;
578 } else { # all others are primitive types
579 $jniStorageList .= "\n\t$p_event = $id;\n";
580 my ($nativeParameter, $jniParameter) = @{$java_jni{$type}};
581 $nativeParameter = "$nativeParameter\t"
582 if length $nativeParameter < 4; # why?
583 $nativeParameterList .= ",\n\t $nativeParameter\t$id";
584 $jniParameterList .= ",\n $jniParameter\t$id";
585 $specParameterList .= ", $jniParameter";
588 if ($needLocaleDefined) {
589 $jniDefine .= <<EOF
590 char *locale;
593 my $genericOverride = '';
594 my $idParameter = $eventId;
595 $idParameter =~ s/AUE_/ADT_/;
596 if ($eventType eq 'generic') {
597 $genericOverride = ', jint eventId';
598 $idParameter = 'eventId';
600 $jniFreeList = "\tcleanup:\n" . $jniFreeList if $needCleanupTarget;
602 print Cfile qq{/* ARGSUSED */
603 JNIEXPORT void JNICALL
604 $jniPutEvent(
605 JNIEnv *env,
606 jobject self,
607 jbyteArray jsession$genericOverride,
608 jint status,
609 jint ret_val$jniParameterList)
611 $jniDefine
612 (void) j2c_pointer(env, jsession, (char **)&session);
614 event = $jniADTalloc(session, $idParameter);
616 $jniStorageList
617 (void) adt_put_event((adt_event_data_t *)event, status, ret_val);
619 $jniFreeList
620 adt_free_event((adt_event_data_t *)event);
623 print MapFile qq{
624 $jniPutEvent; };
625 my $overrideParameter = '';
626 if ($eventType eq 'generic') {
627 $overrideParameter = 'int eventId,';
628 my @allowed = @$allowedIds;
629 if (@allowed) {
630 my $i;
631 if ($validSfile) {
632 print Sfile "\t// Allowed values for eventId in putEvent:\n";
633 for ($i = 0; $i <= $#allowed; $i++) {
634 my $idNo = $externalIdNo{$allowed[$i]};
635 $allowed[$i] =~ s/AUE_/ADT_/;
636 print Sfile "\tstatic final int $allowed[$i] = ",
637 "$idNo;\n";
639 print Sfile "\n";
641 } else {
642 print STDERR "Generic event with no allowed instances: $eventId\n";
645 if ($validSfile) {
646 print Sfile <<EOF;
647 private native void $javaPutEvent(byte[]session, $overrideParameter
648 int status, int ret_val$nativeParameterList);
650 public AuditEvent_$root(AuditSession session)
651 throws Exception
653 super(session);
657 my $javaParameterList = '';
658 foreach $ref2 (@entries) {
659 my ($id, $type, $format, $jComment, $required) = @$ref2;
661 # generate java native method prototypes
662 # and the corresponding C method implementation
664 my $javaMethodName = "$id";
665 my $javaStorageName = $javaMethodName . '_val';
666 my $jniMethodName = $root . $id;
667 my $storage;
668 my $enumUsage = '';
669 my $jParam = @{$java_jni{$type}}[0];
670 my $comment = '';
671 if ($required) {
672 if ($format ne 'NULL') {
673 $comment = "\t// (required) formatted: $format";
674 } else {
675 $comment = "\t// required";
677 } else {
678 if ($format ne 'NULL') {
679 $comment = "\t// (optional) formatted: $format";
680 } else {
681 $comment = "\t// optional";
684 if (($type eq 'ADT_UINT32STAR') ||
685 ($type eq 'ADT_UIDSTAR') ||
686 ($type eq 'ADT_GIDSTAR')) { # int array
687 $storage = "int[] $javaStorageName" . ($required ?
688 ' = {}' : '');
689 $javaParameterList .= ",\n\t\t\t $javaStorageName";
690 } elsif ($type eq 'ADT_UINT64STAR') { # long array
691 $storage = "long[] $javaStorageName" . ($required ?
692 ' = {}' : '');
693 $javaParameterList .= ",\n\t\t\t $javaStorageName";
694 } elsif (($type eq 'ADT_CHARSTAR') ||
695 ($type eq 'ADT_CHAR')) { # string
696 $storage = "String $javaStorageName" . ($required ?
697 ' = ""' : '');
698 $javaParameterList .= ",\n\t\t\t $javaStorageName";
699 } elsif ($type eq 'ADT_CHAR2STAR') { # array of string
700 $storage = "String[] $javaStorageName" . ($required ?
701 ' = {}' : '');
702 $javaParameterList .= ",\n\t\t\t $javaStorageName";
703 } elsif ($type eq 'ADT_TERMIDSTAR') { # array of string
704 $storage = "String $javaStorageName" . ($required ?
705 ' = ""' : '');
706 $javaParameterList .= ",\n\t\t\t $javaStorageName";
707 } else { # all others are primitive types
708 $storage = "$jParam $javaStorageName = 0";
709 $javaParameterList .= ",\n\t\t\t $javaStorageName";
710 $enumUsage = "\n\t// See $jComment in AuditEvent.java for valid values"
711 if $jComment;
713 print Sfile <<EOF;
714 $enumUsage
715 private $storage;$comment
716 public void $javaMethodName($jParam setTo)
718 $javaStorageName = setTo;
721 } # end foreach (@entries)
722 if ($eventType eq 'generic') {
723 print Sfile <<EOF;
725 public void putEvent(int status, int ret_val, int eventId)
727 byte[] session = super.sh.getSession();
729 if ((super.sh.AuditIsOn) && (super.sh.ValidSession))
730 $javaPutEvent(session, eventId,
731 status, ret_val$javaParameterList);
735 } else {
736 print Sfile <<EOF;
738 public void putEvent(int status, int ret_val)
740 byte[] session = super.sh.getSession();
742 if ((super.sh.AuditIsOn) && (super.sh.ValidSession))
743 $javaPutEvent(session, status, ret_val$javaParameterList);
748 close Sfile;
749 } # end if ($validSfile);
752 # write trailers
753 print Jfile <<EOF;
757 print MapFile <<EOF;
759 local:
763 close Cfile;
764 close Jfile;
765 close MapFile;
768 sub generateTableC {
769 my $event = shift;
770 my $eventId = shift;
771 my $eventType = shift;
772 my $eventHeader = shift;
773 my $omit = shift;
775 my %tokenType = (
776 'acl' => 'AUT_ACL',
777 'arbitrary' => 'AUT_ARBITRARY',
778 'arg' => 'AUT_ARG',
779 'attr' => 'AUT_ATTR',
780 'command' => 'AUT_CMD',
781 'command_1' => 'ADT_CMD_ALT', # dummy token id
782 'date' => 'AUT_TEXT',
783 'exec_args' => 'AUT_EXEC_ARGS',
784 'exec_env' => 'AUT_EXEC_ENV',
785 'exit' => 'AUT_EXIT',
786 'file' => 'AUT_FILE',
787 'fmri' => 'AUT_FMRI',
788 'groups' => 'AUT_GROUPS',
789 # 'header' => 'AUT_HEADER', # not used
790 'in_addr' => 'AUT_IN_ADDR',
791 'ipc' => 'AUT_IPC',
792 'ipc_perm' => 'AUT_IPC_PERM',
793 'iport' => 'AUT_IPORT',
794 'label' => 'AUT_LABEL',
795 'newgroups' => 'AUT_NEWGROUPS',
796 'opaque' => 'AUT_OPAQUE',
797 'path' => 'AUT_PATH',
798 'path_list' => '-AUT_PATH', # dummy token id
799 'process' => 'AUT_PROCESS',
800 'priv_effective' => 'ADT_AUT_PRIV_E', # dummy token id
801 'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id
802 'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id
803 'return' => 'AUT_RETURN',
804 'seq' => 'AUT_SEQ',
805 'socket' => 'AUT_SOCKET',
806 'socket-inet' => 'AUT_SOCKET_INET',
807 'subject' => 'AUT_SUBJECT',
808 'text' => 'AUT_TEXT',
809 'tid' => 'AUT_TID',
810 # 'trailer' => 'AUT_TRAILER', # not used
811 'uauth' => 'AUT_UAUTH',
812 'user' => 'AUT_USER',
813 'zonename' => 'AUT_ZONENAME'
816 my @xlateEntryList = ();
817 my @jniEntryList = ();
819 my $external = $event->getExternal();
820 my $internal = $event->getInternal();
822 unless ($external) {
823 print STDERR "No external object captured for event $eventId\n";
824 return;
826 unless ($internal) {
827 print STDERR "No internal object captured for event $eventId\n";
828 return;
830 my @entryRef = $internal->getEntries();
831 my $entryRef;
832 my @tokenOrder = ();
833 my $firstTokenIndex = 0; # djdj not used yet, djdj BUG!
834 # needs to be used by translate table
836 if ($internal->isReorder()) { # prescan the entry list to get the token order
837 my @inputOrder;
838 foreach $entryRef (@entryRef) {
839 my ($intEntry, $entry) = @$entryRef;
840 push (@inputOrder, $intEntry->getAttr('order'));
843 my $i; # walk down the inputOrder list once
844 my $k = 1; # discover next in line
845 my $l = 0; # who should point to next in line
846 for ($i = 0; $i <= $#inputOrder; $i++) {
847 my $j;
848 for ($j = 0; $j <= $#inputOrder; $j++) {
849 if ($k == $inputOrder[$j]) {
850 if ($k == 1) {
851 $firstTokenIndex = $j;
852 } else {
853 $tokenOrder[$l] = "&(selfReference[$j])";
855 $l = $j;
856 last;
859 $k++;
861 $tokenOrder[$l] = 'NULL';
863 else { # default order -- input order same as output
864 my $i;
865 my $j;
866 for ($i = 0; $i < $#entryRef; $i++) {
867 my $j = $i + 1;
868 $tokenOrder[$i] = "&(selfReference[$j])";
870 $tokenOrder[$#entryRef] = 'NULL';
873 my $sequence = 0;
874 foreach $entryRef (@entryRef) {
875 my ($intEntry, $entry) = @$entryRef;
876 my $entryId = $entry->getAttr('id');
878 my ($extEntry, $unusedEntry, $tokenId) =
879 $external->getEntry($entryId);
880 my $opt = $extEntry->getAttr('opt');
882 if ($opt eq 'none') {
883 if (defined ($doc->getToken($tokenId))) {
884 if (defined ($tokenType{$tokenId})) {
885 $tokenId = $tokenType{$tokenId};
887 else {
888 print STDERR "token id $tokenId not implemented\n";
891 else {
892 print STDERR "token = $tokenId is undefined\n";
893 $tokenId = 'error';
895 my ($xlate, $jni) =
896 formatTableEntry ('', $tokenId, $eventId, '', 0, 0, $tokenOrder[$sequence],
897 'NULL', '');
898 push (@xlateEntryList, $xlate);
899 push (@jniEntryList, @$jni);
901 else {
902 my $dataType = $extEntry->getAttr('type');
903 $dataType =~ s/\s+//g; # remove blanks (char * => char*)
905 my $enumGroup = '';
906 if ($dataType =~ /^msg/i) {
907 $enumGroup = $dataType;
908 $enumGroup =~ s/^msg\s*//i;
909 $enumGroup = 'adt_' . $enumGroup;
911 my $required = ($opt eq 'required') ? 1 : 0;
912 my $tsol = 0;
913 my $tokenId = $intEntry->getAttr('token');
914 my $token;
915 my $tokenName;
916 my $tokenFormat = $intEntry->getAttr('format');
917 if (defined ($tokenFormat)) {
918 $tokenFormat = "\"$tokenFormat\"";
920 else {
921 $tokenFormat = 'NULL';
924 if (defined ($token = $doc->getToken($tokenId))) {
925 $tsol = (lc $token->getUsage() eq 'tsol') ? 1 : 0;
926 if (defined ($tokenType{$tokenId})) {
927 $tokenName = $tokenType{$tokenId};
929 else {
930 print STDERR "token id $tokenId not implemented\n";
933 else {
934 print STDERR
935 "$tokenId is an unimplemented token ($entryId in $eventId)\n";
936 $tokenName = 'AUT_TEXT';
938 my ($xlate, $jni) =
939 formatTableEntry($entryId, $tokenName, $eventId, $dataType, $required,
940 $tsol, $tokenOrder[$sequence], $tokenFormat,
941 $enumGroup, (uc $omit eq 'JNI'));
942 push (@xlateEntryList, $xlate);
943 push (@jniEntryList, @$jni);
945 $sequence++;
947 $jniEventTable{$eventId} = [\@jniEntryList, $eventType,
948 $external->getAllowedTypes(), $eventHeader]
949 unless (uc $omit eq 'JNI') || ($omit eq 'always');
952 sub formatTableEntry {
953 my ($id, $token, $eventId, $type, $required, $tsol, $sequence, $format, $enumGroup,
954 $omitJNI) = @_;
957 # does this map belong in the xml source? (at least the defaults?)
958 # fill in the default value only if it is other than zero.
959 # base type adt name, default value
960 my %entryDef = ( 'au_asid_t' => ['ADT_UINT32', ''],
961 'uint_t' => ['ADT_UINT32', ''],
962 'int' => ['ADT_INT', ''],
963 'int32_t' => ['ADT_INT32', ''],
964 'uid_t' => ['ADT_UID', 'AU_NOAUDITID'],
965 'gid_t' => ['ADT_GID', 'AU_NOAUDITID'],
966 'uid_t*' => ['ADT_UIDSTAR', ''],
967 'gid_t*' => ['ADT_GIDSTAR', ''],
968 'char' => ['ADT_CHAR', ''],
969 'char*' => ['ADT_CHARSTAR', ''],
970 'char**' => ['ADT_CHAR2STAR', ''],
971 'long' => ['ADT_LONG', ''],
972 'pid_t' => ['ADT_PID', ''],
973 'priv_set_t*' => ['ADT_PRIVSTAR', ''],
974 'ulong_t' => ['ADT_ULONG', ''],
975 'uint16_t', => ['ADT_UINT16', ''],
976 'uint32_t' => ['ADT_UINT32', ''],
977 'uint32_t*' => ['ADT_UINT32STAR', ''],
978 'uint32_t[]' => ['ADT_UINT32ARRAY', ''],
979 'uint64_t' => ['ADT_UINT64', ''],
980 'uint64_t*' => ['ADT_UINT64STAR', ''],
981 'm_label_t*' => ['ADT_MLABELSTAR', ''],
983 my $xlateLabel = $uniLabel.$xlateUniLabelInc;
984 my $xlateLabelInc = 0;
985 my $xlateLine = '';
986 my @jniLine = ();
988 # the list handling should be a simple loop with a loop of one
989 # falling out naturally.
991 unless ($type =~ /,/) { # if list, then generate sequence of entries
992 my $dataType;
993 my $dataSize;
994 my $xlateLabelRef = '';
996 my $arraySize = '';
997 $arraySize = $1 if ($type =~ s/\[(\d+)\]/[]/);
999 my $entryType = ${$entryDef{$type}}[0];
1001 my @xlateType = (); # for adt_xlate.c
1002 my $typeCount = 1;
1004 if ($entryType) {
1005 $dataType = $entryType;
1006 $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
1007 $type =~ s/\[\]//;
1008 $dataSize = "sizeof ($type)";
1009 if ($arraySize) {
1010 $dataSize = "$arraySize * " . $dataSize;
1012 $xlateLine = "{{$dataType, $dataSize}}";
1013 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
1014 } elsif ($type eq '') {
1015 $xlateLabelRef = 'NULL';
1016 } elsif ($type =~ /^msg/i) {
1017 $type =~ s/^msg//i;
1018 $dataType = 'ADT_MSG';
1019 my $dataEnum = 'ADT_LIST_' . uc $type;
1020 $xlateLine = "{{$dataType, $dataEnum}}";
1021 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
1022 } elsif ($type =~ /time_t/i) {
1023 $dataType = 'ADT_DATE';
1024 $dataSize = "sizeof (time_t)";
1025 $xlateLine = "{{$dataType, $dataSize}}";
1026 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
1027 } elsif ($type =~ /termid/i) {
1028 $dataType = 'ADT_TERMIDSTAR';
1029 $dataSize = "sizeof (au_tid_addr_t *)";
1030 $xlateLine = "{{$dataType, $dataSize}}";
1031 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
1032 } elsif ($omitJNI) {
1033 $xlateLabelRef = 'NULL';
1034 } else {
1035 print STDERR "$type is not an implemented data type\n";
1036 $xlateLabelRef = 'NULL';
1038 $xlateLabelRef = '&' . $xlateLabel . '[0]'
1039 unless $xlateLabelRef eq 'NULL';
1041 # "EOL" is where a comma should go unless end of list
1042 $xlateLine = "{$token,\t1,\t$xlateLabelRef,\t$sequence,\n" .
1043 "\t\t0,\t$required,\t$tsol,\t$format}EOL";
1045 } else { # is a list
1046 my @type = split(/,/, $type);
1047 my @arraySize = ();
1048 my @id = split(/,/, $id);
1049 my @jniId = @id;
1050 my $dataType;
1051 my $typeCount = ($#type + 1);
1052 my @xlateType = ();
1053 my @default = ();
1055 foreach my $dtype (@type) {
1056 my $jniId = shift @jniId;
1057 my $id = shift @id;
1058 my $arraySize = '';
1059 $arraySize = $1 if ($dtype =~ s/\[(\d+)\]/[]/);
1061 my $entryType = ${$entryDef{$dtype}}[0];
1062 if ($entryType) {
1063 my $type = $dtype;
1064 $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
1065 $type =~ s/\[\]//;
1067 my $sizeString = "sizeof";
1068 $sizeString = "$arraySize * " . $sizeString if $arraySize;
1069 push (@xlateType, "\{$entryType, $sizeString ($type)\}");
1070 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
1071 } elsif ($type =~ /^msg/i) {
1072 $type =~ s/^msg//i;
1073 $dataType = 'ADT_MSG';
1074 my $dataEnum = 'ADT_LIST_' . uc $type;
1075 push (@xlateType, "\{$dataType, $dataEnum\}};");
1076 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
1077 } elsif ($type =~ /time_t/i) {
1078 $dataType = 'ADT_DATE';
1079 push (@xlateType, "\{$entryType, sizeof ($type)\}");
1080 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
1081 } elsif ($type =~ /termid/i) {
1082 $dataType = 'ADT_TERMIDSTAR';
1083 push (@xlateType, "\{$dataType, sizeof (au_tid_addr_t *)\}");
1084 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
1085 } elsif ($omitJNI) {
1086 # nothing to do.
1087 } else {
1088 print STDERR "$dtype is not an implemented data type\n";
1090 if (${$entryDef{$dtype}}[1]) {
1091 push (@default, $id, ${$entryDef{$dtype}}[1]);
1094 my $xlateArray = "\[$typeCount\] =\t{" . join(",\n\t\t\t\t", @xlateType) . "};";
1096 $xlateLine =
1097 "{$token,\t$typeCount,\t&$xlateLabel\[0\],\t$sequence,\n" .
1098 "\t\t0,\t$required,\t$tsol,\t$format}EOL";
1100 $xlateUniLabelInc++ if $xlateLabelInc;
1101 return ($xlateLine, \@jniLine);
1104 sub generateMsgLists {
1105 my $textList = shift;
1107 my $textName = $textList->getId();
1108 my $header = $textList->getHeader();
1109 my $start = $textList->getMsgStart();
1110 my $public = $textList->getMsgPublic();
1111 my $deprecated = $textList->getDeprecated();
1113 print "$textName starts at $start\n" if $debug;
1115 my $entry;
1116 my @entry;
1117 while ($entry = $textList->getNextMsg()) {
1118 if ($debug) {
1119 my ($id, $text) = split(/\s*::\s*/, $entry);
1120 print " $id = $text\n";
1122 unshift (@entry, $entry);
1124 $msg_list{$textName} =
1125 [\@entry, [$header, $start, $public, $deprecated]];
1127 sub readAuditEventFile {
1128 my $eventListFile = shift;
1130 open(Event, $eventListFile)
1131 or die "can't open $eventListFile: $!\n";
1132 while(<Event>) {
1133 next if /^\s*#/;
1134 next if /^\s*$/;
1135 my ($value, $name) = split(/\s*:\s*/);
1136 next if $value < 6000;
1137 $eventCode{$name} = $value;
1139 close Event;