1
# ------------------------------------------------------------------
3
# Copyright (C) 2005-2006 Novell/SUSE
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of version 2 of the GNU General Public
7
# License published by the Free Software Foundation.
9
# ------------------------------------------------------------------
11
package Immunix::Severity;
23
$self->{DATABASENAME} = undef;
24
$self->{CAPABILITIES} = {};
26
$self->{REGEXPS} = {};
27
$self->{DEFAULT_RANK} = 10;
30
$self->init(@_) if @_;
35
my ($self, $resource, $read, $write, $execute, $severity);
37
$self->{DATABASENAME} = shift;
38
$self->{DEFAULT_RANK} = shift if defined $_[0];
39
open(DATABASE, $self->{DATABASENAME})
40
or die "Could not open severity db $self->{DATABASENAME}: $!\n";
46
# leading whitespace is fine; maybe it shouldn't be?
47
if (/^\s*\/(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/) {
48
my ($path, $read, $write, $execute) = ($1, $2, $3, $4);
50
if (index($path, "*") == -1) {
52
$self->{FILES}{$path} = {
60
my $ptr = $self->{REGEXPS};
61
my @pieces = split(/\//, $path);
63
while (my $piece = shift @pieces) {
64
if (index($piece, "*") != -1) {
65
my $path = join("/", $piece, @pieces);
66
my $regexp = convert_regexp($path);
67
$ptr->{$regexp}{SD_RANK} = {
74
$ptr->{$piece} = {} unless exists $ptr->{$piece};
75
$ptr = $ptr->{$piece};
79
} elsif (m|^\s*CAP|) {
80
($resource, $severity) = split;
81
$self->{CAPABILITIES}{$resource} = $severity;
83
print "unexpected database line: $_\n";
96
# if the name is in the database, return it
97
# otherwise, send a diagnostic message to stderr and return the default
100
# initialize the current return value to 0
101
# loop over each entry in the database;
102
# find the max() value for each mode that matches and set a 'found' flag
103
# if the found flag has not been set, return the default;
104
# otherwise, return the maximum from the database
106
sub handle_capability ($) {
107
my ($self, $resource) = @_;
109
my $ret = $self->{CAPABILITIES}{$resource};
110
if (!defined($ret)) {
111
return "unexpected capability rank input: $resource\n";
117
my ($tree, $mode, $sev, $first, @rest) = @_;
119
# reassemble the remaining path from this directory level
120
my $path = join("/", $first, @rest);
122
# first check if we have a literal directory match to descend into
123
if ($tree->{$first}) {
124
$sev = check_subtree($tree->{$first}, $mode, $sev, @rest);
127
# if we didn't get a severity already, check for matching globs
130
# check each glob at this directory level
131
for my $chunk (grep { index($_, "*") != -1 } keys %{$tree}) {
133
# does it match the rest of our path?
134
if ($path =~ /^$chunk$/) {
136
# if we've got a ranking, check if it's higher than
137
# current one, if any
138
if ($tree->{$chunk}->{SD_RANK}) {
139
for my $m (split(//, $mode)) {
141
|| $tree->{$chunk}->{SD_RANK}->{$m} > $sev)
143
$sev = $tree->{$chunk}->{SD_RANK}->{$m};
154
sub handle_file ($$) {
155
my ($self, $resource, $mode) = @_;
157
# strip off the initial / from the path we're checking
158
$resource = substr($resource, 1);
160
# break the path into directory-level chunks
161
my @pieces = split(/\//, $resource);
165
# if there's a exact match for this path in the db, use that instead of
167
if ($self->{FILES}{$resource}) {
169
# check each piece of the passed mode against the db entry
170
for my $m (split(//, $mode)) {
171
if ((!defined $sev) || $self->{FILES}{$resource}{$m} > $sev) {
172
$sev = $self->{FILES}{$resource}{$m};
178
# descend into the regexp tree looking for matches
179
$sev = check_subtree($self->{REGEXPS}, $mode, $sev, @pieces);
183
return (defined $sev) ? $sev : $self->{DEFAULT_RANK};
187
my ($self, $resource, $mode) = @_;
189
if (substr($resource, 0, 1) eq "/") {
190
return $self->handle_file($resource, $mode);
191
} elsif (substr($resource, 0, 3) eq "CAP") {
192
return $self->handle_capability($resource);
194
return "unexpected rank input: $resource\n";
198
sub convert_regexp ($) {
201
# we need to convert subdomain regexps to perl regexps
204
# escape + . [ and ] characters
205
$regexp =~ s/(\+|\.|\[|\])/\\$1/g;
207
# convert ** globs to match anything
208
$regexp =~ s/\*\*/.SDPROF_INTERNAL_GLOB/g;
210
# convert * globs to match anything at current path level
211
$regexp =~ s/\*/[^\/]SDPROF_INTERNAL_GLOB/g;
213
# convert {foo,baz} to (foo|baz)
214
$regexp =~ y/\{\}\,/\(\)\|/ if $regexp =~ /\{.*\,.*\}/;
216
# twiddle the escaped * chars back
217
$regexp =~ s/SDPROF_INTERNAL_GLOB/\*/g;
221
1; # so the require or use succeeds