1
# $Id: Severity.pm 458 2007-03-20 22:58:38Z jmichael-at-suse-de $
2
# ------------------------------------------------------------------
4
# Copyright (C) 2005-2006 Novell/SUSE
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of version 2 of the GNU General Public
8
# License published by the Free Software Foundation.
10
# ------------------------------------------------------------------
12
package Immunix::Severity;
24
$self->{DATABASENAME} = undef;
25
$self->{CAPABILITIES} = {};
27
$self->{REGEXPS} = {};
28
$self->{DEFAULT_RANK} = 10;
31
$self->init(@_) if @_;
36
my ($self, $resource, $read, $write, $execute, $severity);
38
$self->{DATABASENAME} = shift;
39
$self->{DEFAULT_RANK} = shift if defined $_[0];
40
open(DATABASE, $self->{DATABASENAME})
41
or die "Could not open severity db $self->{DATABASENAME}: $!\n";
47
# leading whitespace is fine; maybe it shouldn't be?
48
if (/^\s*\/(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/) {
49
my ($path, $read, $write, $execute) = ($1, $2, $3, $4);
51
if (index($path, "*") == -1) {
53
$self->{FILES}{$path} = {
61
my $ptr = $self->{REGEXPS};
62
my @pieces = split(/\//, $path);
64
while (my $piece = shift @pieces) {
65
if (index($piece, "*") != -1) {
66
my $path = join("/", $piece, @pieces);
67
my $regexp = convert_regexp($path);
68
$ptr->{$regexp}{SD_RANK} = {
75
$ptr->{$piece} = {} unless exists $ptr->{$piece};
76
$ptr = $ptr->{$piece};
80
} elsif (m|^\s*CAP|) {
81
($resource, $severity) = split;
82
$self->{CAPABILITIES}{$resource} = $severity;
84
print "unexpected database line: $_\n";
97
# if the name is in the database, return it
98
# otherwise, send a diagnostic message to stderr and return the default
101
# initialize the current return value to 0
102
# loop over each entry in the database;
103
# find the max() value for each mode that matches and set a 'found' flag
104
# if the found flag has not been set, return the default;
105
# otherwise, return the maximum from the database
107
sub handle_capability ($) {
108
my ($self, $resource) = @_;
110
my $ret = $self->{CAPABILITIES}{$resource};
111
if (!defined($ret)) {
112
return "unexpected capability rank input: $resource\n";
118
my ($tree, $mode, $sev, $first, @rest) = @_;
120
# reassemble the remaining path from this directory level
121
my $path = join("/", $first, @rest);
123
# first check if we have a literal directory match to descend into
124
if ($tree->{$first}) {
125
$sev = check_subtree($tree->{$first}, $mode, $sev, @rest);
128
# if we didn't get a severity already, check for matching globs
131
# check each glob at this directory level
132
for my $chunk (grep { index($_, "*") != -1 } keys %{$tree}) {
134
# does it match the rest of our path?
135
if ($path =~ /^$chunk$/) {
137
# if we've got a ranking, check if it's higher than
138
# current one, if any
139
if ($tree->{$chunk}->{SD_RANK}) {
140
for my $m (split(//, $mode)) {
142
|| $tree->{$chunk}->{SD_RANK}->{$m} > $sev)
144
$sev = $tree->{$chunk}->{SD_RANK}->{$m};
155
sub handle_file ($$) {
156
my ($self, $resource, $mode) = @_;
158
# strip off the initial / from the path we're checking
159
$resource = substr($resource, 1);
161
# break the path into directory-level chunks
162
my @pieces = split(/\//, $resource);
166
# if there's a exact match for this path in the db, use that instead of
168
if ($self->{FILES}{$resource}) {
170
# check each piece of the passed mode against the db entry
171
for my $m (split(//, $mode)) {
172
if ((!defined $sev) || $self->{FILES}{$resource}{$m} > $sev) {
173
$sev = $self->{FILES}{$resource}{$m};
179
# descend into the regexp tree looking for matches
180
$sev = check_subtree($self->{REGEXPS}, $mode, $sev, @pieces);
184
return (defined $sev) ? $sev : $self->{DEFAULT_RANK};
188
my ($self, $resource, $mode) = @_;
190
if (substr($resource, 0, 1) eq "/") {
191
return $self->handle_file($resource, $mode);
192
} elsif (substr($resource, 0, 3) eq "CAP") {
193
return $self->handle_capability($resource);
195
return "unexpected rank input: $resource\n";
199
sub convert_regexp ($) {
202
# we need to convert subdomain regexps to perl regexps
205
# escape + . [ and ] characters
206
$regexp =~ s/(\+|\.|\[|\])/\\$1/g;
208
# convert ** globs to match anything
209
$regexp =~ s/\*\*/.SDPROF_INTERNAL_GLOB/g;
211
# convert * globs to match anything at current path level
212
$regexp =~ s/\*/[^\/]SDPROF_INTERNAL_GLOB/g;
214
# convert {foo,baz} to (foo|baz)
215
$regexp =~ y/\{\}\,/\(\)\|/ if $regexp =~ /\{.*\,.*\}/;
217
# twiddle the escaped * chars back
218
$regexp =~ s/SDPROF_INTERNAL_GLOB/\*/g;
222
1; # so the require or use succeeds