4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
22 # Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 # Use is subject to license terms.
25 # ident "%Z%%M% %I% %E% SMI"
30 package externalEvent
;
39 my @kid = $obj->getKids(); # kids of event are entry or allowed_types
41 # separate kids into classes and create hash of entries and an
46 my @allowed_types = ();
48 my $internalName = '';
52 my $class = $kid->getClass();
53 my $kidId = $kid->getAttr('id');
55 if ($class eq 'entry') {
56 my $tokenId = 'undefined';
58 my $internal = $kid->getKid('internal');
59 if (defined $internal) {
60 $tokenId = $internal->getAttr('token');
61 $format = $internal->getAttr('format');
62 $format = '' unless defined $format;
65 my $commentKid = $kid->getKid('comment');
66 if (defined $commentKid) {
67 $comment = $commentKid->getContent;
69 my $external = $kid->getKid('external');
70 if (defined ($external)) {
71 $entry{$kidId} = [$external, $kid, $tokenId, $format, $comment];
72 push (@entry, $kidId);
75 print STDERR
"no external attributes defined for $id/$kidId\n";
77 } # handle event id translation...
78 elsif ($class eq 'altname') {
79 $internalName = $kid->getAttr('id');
80 unless (defined $internalName) {
81 print STDERR
"missing id for internal name of $id\n";
82 $internalName = 'error';
85 elsif ($class eq 'allowed_types') {
86 my $content = $kid->getContent();
87 @allowed_types = (@allowed_types, split(/\s*,\s*/, $content));
90 my @entryCopy = @entry;
91 return bless {'id' => $id,
92 'internalName' => $internalName,
93 'allowed_types' => \
@allowed_types,
95 'entryList' => \
@entry,
96 'entryListCopy' => \
@entryCopy,
97 'include' => \
@include,
98 'xmlObj' => $obj}, $pkg;
103 sub getExternalName
{
110 # return internal name if it exists, else id
112 sub getInternalName
{
115 if ($pkg->{'internalName'}) {
116 return $pkg->{'internalName'};
123 # getNextEntry reads from 'entryList' destructively
124 # but resets when the list after the list is emptied
129 unless (@
{$pkg->{'entryList'}}) {
130 @
{$pkg->{'entryList'}} = @
{$pkg->{'entryListCopy'}};
133 my $id = shift @
{$pkg->{'entryList'}};
135 return ($pkg->getEntry($id)); # getEntry returns an array
138 # getEntryIds returns list of all ids from entryList
142 return (@
{$pkg->{'entryList'}});
145 # getEntry returns a selected entry for the current event
149 my $id = shift; #entry id
151 my $ref = $pkg->{'entry'};
152 my $array = $$ref{$id};
157 # getNextInclude reads from 'include' destructively
162 return shift @
{$pkg->{'include'}};
165 # getIncludes returns list of 'include'
169 return @
{$pkg->{'include'}};
172 # return a reference to the list of event id's allowed for
175 sub getAllowedTypes
{
178 return $pkg->{'allowed_types'};
181 package internalEvent
;
190 my @kid = $obj->getKids(); # kids of event are entry
195 if ($reorder = $obj->getAttr('reorder')) {
196 $reorder = 1 if $reorder eq 'yes';
199 foreach $kid (@kid) {
200 my $class = $kid->getClass();
201 my $id = $kid->getAttr('id');
203 if ($class eq 'entry') {
204 my $internal = $kid->getKid('internal');
205 if (defined ($internal)) {
206 push (@entry, [$internal, $kid]);
209 print STDERR
"no internal attributes defined for $id\n";
213 return bless {'id' => $id,
214 'reorder' => $reorder,
216 'xmlObj' => $obj}, $pkg;
219 # getEntries returns a list of all entry references
224 return undef unless @
{$pkg->{'entry'}};
226 return @
{$pkg->{'entry'}};
232 return $pkg->{'reorder'};
262 $omit = '' unless $omit = $obj->getAttr('omit');
263 $type = '' unless $type = $obj->getAttr('type');
264 $header = 0 unless $header = $obj->getAttr('header');
265 $idNo = '' unless $idNo = $obj->getAttr('idNo');
267 if ($idNo ne '' && $uniqueId{$idNo}) {
268 print STDERR
"$uniqueId{$idNo} and $id have the same id ($idNo)\n";
271 $uniqueId{$idNo} = $id;
274 return bless {'id' => $id,
281 'program' => \
@program,
284 'internal' => 0}, $pkg;
287 # putDef is called at the end of an <event></event> block, so
288 # it sees a completed object.
292 my $obj = shift; # ref to xmlHandlers event object
295 my $id = $pkg->{'id'};
297 if ($context eq 'internal') {
298 $pkg->{$context} = new internalEvent
($id, $obj);
300 } elsif ($context eq 'external') {
301 my $ref = $pkg->{$context} = new externalEvent
($id, $obj);
302 return $ref->{'internalName'};
315 return $pkg->{'header'};
321 return $pkg->{'idNo'};
327 return $pkg->{'super'};
333 return $pkg->{'omit'};
339 return $pkg->{'type'};
343 return shift->{'title'};
347 return shift->{'program'};
351 return shift->{'see'};
357 return $pkg->{'internal'};
363 return $pkg->{'external'};
366 # this isn't fully implemented; just a skeleton
377 $usage = $obj->getAttr('usage');
378 $usage = '' unless defined $usage;
380 return bless {'id' => $id,
394 return $pkg->{'usage'};
408 my $deprecated = shift;
412 my @kid = $obj->getKids(); # kids of msg_list are msg
414 foreach $kid (@kid) {
415 my $class = $kid->getClass();
416 if ($class eq 'msg') {
417 my $text = $kid->getContent();
418 $text = '' unless defined ($text);
419 my $msgId = $kid->getAttr('id');
420 if (defined ($msgId)) {
421 push(@msg, join('::', $msgId, $text));
424 print STDERR
"missing id for $class <msg>\n";
428 print STDERR
"invalid tag in <msg_list> block: $class\n";
432 return bless {'id' => $id,
437 'deprecated' => $deprecated
450 return $pkg->{'start'};
456 return $pkg->{'deprecated'};
462 return $pkg->{'public'};
468 return $pkg->{'header'};
471 # destructive read of @msg...
476 my @msg = @
{$pkg->{'msg'}};
478 return undef unless @msg;
480 my $text = pop(@msg);
481 $pkg->{'msg'} = \
@msg;
489 return @
{$pkg->{'msg'}};
495 # These aren't internal state because the callback functions don't
496 # have the object handle.
498 @debug = (); # stack for nesting debug state
499 %event = (); # event name => $objRef
500 @event = (); # event id
501 %token = (); # token name => $objRef
502 @token = (); # token id
503 %msg_list = (); # messageList string list id to obj
504 @msg_list = (); # id list
505 %service = (); # valid service names
506 %externalToInternal = (); # map external event name to internal event name
512 my $file = shift; # xml file to be parsed
514 register
('event', \
&eventStart
, \
&eventEnd
);
515 register
('entry', 0, \
&entry
);
516 register
('external', 0, \
&external
);
517 register
('internal', 0, \
&internal
);
518 register
('include', 0, \
&include
);
519 register
('token', 0, \
&token
);
520 register
('service', 0, \
&service
);
521 register
('msg_list', 0, \
&msg_list
);
522 register
('msg', 0, \
&msg
);
524 # do not use register() for debug because register generates extra
527 xmlHandlers
::registerStartCallback
('debug', \
&debugStart
);
528 xmlHandlers
::registerEndCallback
('debug', \
&debugEnd
);
530 $xml = new xmlHandlers
(0, 'top level', $file);
532 return bless {'xmlObj' => $xml,
534 'firstEvent' => 1}, $pkg;
537 # local function -- register both the auditxml function and the
538 # xmlHandler callback
541 my $localName = shift;
542 my $startFunction = shift;
543 my $endFunction = shift;
545 if ($startFunction) {
546 xmlHandlers
::registerStartCallback
($localName, \
&completed
);
547 $startFunction{$localName} = $startFunction;
550 xmlHandlers
::registerEndCallback
($localName, \
&completed
);
551 $endFunction{$localName} = $endFunction;
557 my $callbackSource = shift;
559 my $id = $obj->getAttr('id');
560 my $class = $obj->getClass();
563 print "*** $callbackSource: $class", (defined ($id)) ?
"= $id\n" : "\n";
565 my %attributes = $obj->getAttributes();
567 foreach $attribute (keys %attributes) {
568 print "*** $attribute = $attributes{$attribute}\n";
570 my $content = $obj->getContent();
571 print "*** content = $content\n" if defined $content;
573 if ($callbackSource eq 'start') {
574 &{$startFunction{$class}}($obj);
576 elsif ($callbackSource eq 'end') {
577 &{$endFunction{$class}}($obj);
580 print STDERR
"no auditxml function defined for $class\n";
584 # getNextEvent reads from @event destructively. 'firstEvent' could
585 # be used to make a copy from which to read.
590 return undef unless (@event);
591 if ($pkg->{'firstEvent'}) {
592 @token = sort @token;
593 $pkg->{'firstEvent'} = 1;
596 my $id = shift @event;
601 # returns all event ids
608 # returns event for id
623 # getNextToken reads from @token destructively. 'firstToken' could
624 # be used to make a copy from which to read.
629 return undef unless (@token);
631 if ($pkg->{'firstToken'}) {
632 @token = sort @token;
633 $pkg->{'firstToken'} = 1;
635 my $id = shift @token;
648 # getNextMsgId reads from @msg_list destructively.
653 return undef unless (@msg_list);
655 my $id = shift @msg_list;
657 return ($id, $msg_list{$id});
670 return $msg_list{$id};
683 my $id = $obj->getAttr('id');
686 print STDERR
"eventStart can't get a valid id\n";
689 unless (defined $event{$id}) {
691 if ($super = $obj->getAttr('instance_of')) {
692 $super = $event{$super};
696 $event{$id} = new eventDef
($id, $obj, $super);
699 print STDERR
"duplicate event id: $id\n";
706 my $id = $obj->getAttr('id');
707 unless (defined $id) {
708 print STDERR
"event element is missing required id attribute\n";
711 print "event = $id\n" if $main::debug
;
713 foreach my $kid ($obj->getKids) {
714 my $class = $kid->getClass;
715 next unless ($class =~ /title|program|see/);
716 my $content = $kid->getContent;
717 if ($class eq 'title') {
718 $event{$id}->{$class} = $content;
720 push @
{$event{$id}->{$class}}, $content;
723 $event{$id}->putDef($obj, 'internal');
725 my $internalName = $event{$id}->putDef($obj, 'external');
727 $externalToInternal{$id} = $internalName if $internalName;
732 #sub getInternalName {
735 # return $externalToInternal{$name};
744 # my $id = $obj->getAttr('id');
747 # print "include = $id\n" if $main::debug;
750 # print STDERR "include element is missing required id attribute\n";
757 my $id = $obj->getAttr('id');
760 print "token = $id\n" if $main::debug
;
761 $token{$id} = new tokenDef
($obj, $id);
765 print STDERR
"token element is missing required id attribute\n";
772 my $id = $obj->getAttr('id');
773 my $header = $obj->getAttr('header');
774 my $start = $obj->getAttr('start');
775 my $public = $obj->getAttr('public');
776 my $deprecated = $obj->getAttr('deprecated');
778 $header = 0 unless $header;
779 $start = 0 unless $start;
780 $public = ($public) ?
1 : 0;
781 $deprecated = ($deprecated) ?
1 : 0;
784 print "msg_list = $id\n" if $main::debug
;
785 $msg_list{$id} = new messageList
($obj, $id, $header, $start,
786 $public, $deprecated);
787 push (@msg_list, $id);
791 "msg_list element is missing required id attribute\n";
799 # Service name was dropped during PSARC review
804 my $name = $obj->getAttr('name');
805 my $id = $obj->getAttr('id');
807 if ((defined $id) && (defined $name)) {
808 print "service $name = $id\n" if $main::debug
;
809 $service{$name} = $id;
811 elsif (defined $name) {
812 print STDERR
"service $name is missing an id number\n";
814 elsif (defined $id) {
815 print STDERR
"service name missing for id = $id\n";
818 print STDERR
"missing both name and id for a service entry\n";
827 # <debug set="on"> or <debug set="off"> or <debug>
828 # if the set attribute is omitted, debug state is toggled
830 # debugStart / debugEnd are used to insure debug state is
831 # scoped to the block between <debug> and </debug>
836 push (@debug, $main::debug
);
837 my $debug = $main::debug
;
839 my $state = $obj->getAttr('set');
841 if (defined $state) {
842 $main::debug
= ($state eq 'on') ?
1 : 0;
845 $main::debug
= !$debug;
847 if ($debug != $main::debug
) {
848 print 'debug is ', $main::debug ?
'on' : 'off', "\n";
855 my $debug = $main::debug
;
856 $main::debug
= pop (@debug);
858 if ($debug != $main::debug
) {
859 print 'debug is ', $main::debug ?
'on' : 'off', "\n";