Thu, 04 Oct 2012 20:30:05 +0200
Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.
michael@428 | 1 | ## |
michael@428 | 2 | ## lint-fsl.pl -- OpenPKG fsl.* File Checker |
michael@428 | 3 | ## Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/> |
michael@428 | 4 | ## |
michael@428 | 5 | ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208. |
michael@428 | 6 | ## All rights reserved. Licenses which grant limited permission to use, |
michael@428 | 7 | ## copy, modify and distribute this software are available from the |
michael@428 | 8 | ## OpenPKG GmbH. |
michael@428 | 9 | ## |
michael@428 | 10 | ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
michael@428 | 11 | ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
michael@428 | 12 | ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
michael@428 | 13 | ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
michael@428 | 14 | ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@428 | 15 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@428 | 16 | ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
michael@428 | 17 | ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
michael@428 | 18 | ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
michael@428 | 19 | ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
michael@428 | 20 | ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
michael@428 | 21 | ## SUCH DAMAGE. |
michael@428 | 22 | ## |
michael@428 | 23 | |
michael@428 | 24 | # Perl run-time requirement |
michael@428 | 25 | require 5; |
michael@428 | 26 | BEGIN { |
michael@428 | 27 | eval "use Getopt::Long; use IO;"; |
michael@428 | 28 | if ($@) { |
michael@428 | 29 | print STDERR |
michael@428 | 30 | "lint-fsl: ERROR: This command requires a full-size Perl installation!\n" . |
michael@428 | 31 | "lint-fsl: HINT: Install OpenPKG \"perl\" package to use this command.\n"; |
michael@428 | 32 | exit(1); |
michael@428 | 33 | } |
michael@428 | 34 | } |
michael@428 | 35 | |
michael@428 | 36 | # OpenPKG instance prefix |
michael@428 | 37 | my $my_prefix = $ENV{'OPENPKG_PREFIX'}; |
michael@428 | 38 | delete $ENV{'OPENPKG_PREFIX'}; |
michael@428 | 39 | |
michael@428 | 40 | # program information |
michael@428 | 41 | my $progname = "lint-fsl"; |
michael@428 | 42 | my $progvers = "1.0.0"; |
michael@428 | 43 | |
michael@428 | 44 | # parameters (defaults) |
michael@428 | 45 | my $version = 0; |
michael@428 | 46 | my $verbose = 0; |
michael@428 | 47 | my $help = 0; |
michael@428 | 48 | my $check = 'all'; |
michael@428 | 49 | my $tmpdir = ($ENV{TMPDIR} || $ENV{TEMPDIR} || "/tmp") . "/$progname"; |
michael@428 | 50 | my $rpm = "$my_prefix/bin/openpkg rpm"; |
michael@428 | 51 | |
michael@428 | 52 | # exception handling support |
michael@428 | 53 | $SIG{__DIE__} = sub { |
michael@428 | 54 | my ($err) = @_; |
michael@428 | 55 | $err =~ s|\s+at\s+.*||s if (not $verbose); |
michael@428 | 56 | print STDERR "$progname:ERROR: $err ". ($! ? "($!)" : "") . "\n"; |
michael@428 | 57 | exit(1); |
michael@428 | 58 | }; |
michael@428 | 59 | |
michael@428 | 60 | # command line parsing |
michael@428 | 61 | Getopt::Long::Configure("bundling"); |
michael@428 | 62 | my $result = GetOptions( |
michael@428 | 63 | 'V|version' => \$version, |
michael@428 | 64 | 'v|verbose' => \$verbose, |
michael@428 | 65 | 'h|help' => \$help, |
michael@428 | 66 | 'c|check=s' => \$check, |
michael@428 | 67 | 't|tmpdir=s' => \$tmpdir, |
michael@428 | 68 | 'r|rpm=s' => \$rpm, |
michael@428 | 69 | ) || die "option parsing failed"; |
michael@428 | 70 | if ($help) { |
michael@428 | 71 | print "Usage: $progname [options] [RPMFILE ...]\n" . |
michael@428 | 72 | "Available options:\n" . |
michael@428 | 73 | " -v,--verbose enable verbose run-time mode\n" . |
michael@428 | 74 | " -h,--help print out this usage page\n" . |
michael@428 | 75 | " -c,--check=CHECKS select checks to perform (default='all')\n" . |
michael@428 | 76 | " -r,--rpm=FILE filesystem path to RPM program\n" . |
michael@428 | 77 | " -t,--tmpdir=PATH filesystem path to temporary directory\n" . |
michael@428 | 78 | " -V,--version print program version\n"; |
michael@428 | 79 | exit(0); |
michael@428 | 80 | } |
michael@428 | 81 | if ($version) { |
michael@428 | 82 | print "OpenPKG $progname $progvers\n"; |
michael@428 | 83 | exit(0); |
michael@428 | 84 | } |
michael@428 | 85 | |
michael@428 | 86 | # verbose message printing |
michael@428 | 87 | sub msg_verbose { |
michael@428 | 88 | my ($msg) = @_; |
michael@428 | 89 | print STDERR "$msg\n" if ($verbose); |
michael@428 | 90 | } |
michael@428 | 91 | |
michael@428 | 92 | # warning message printing |
michael@428 | 93 | sub msg_warning { |
michael@428 | 94 | my ($msg) = @_; |
michael@428 | 95 | print STDERR "$progname:WARNING: $msg\n"; |
michael@428 | 96 | } |
michael@428 | 97 | |
michael@428 | 98 | # error message printing |
michael@428 | 99 | sub msg_error { |
michael@428 | 100 | my ($msg) = @_; |
michael@428 | 101 | print STDERR "$progname:ERROR: $msg\n"; |
michael@428 | 102 | } |
michael@428 | 103 | |
michael@428 | 104 | # determine check list |
michael@428 | 105 | my @check_list = (qw( |
michael@428 | 106 | blank |
michael@428 | 107 | comment |
michael@428 | 108 | ident |
michael@428 | 109 | )); |
michael@428 | 110 | my @checks = (); |
michael@428 | 111 | if ($check eq 'all') { |
michael@428 | 112 | @checks = @check_list; |
michael@428 | 113 | } |
michael@428 | 114 | else { |
michael@428 | 115 | foreach my $c (split(/,/, $check)) { |
michael@428 | 116 | if (not grep(/^$c$/, @check_list)) { |
michael@428 | 117 | die "invalid check \"$c\""; |
michael@428 | 118 | } |
michael@428 | 119 | push(@checks, $c); |
michael@428 | 120 | } |
michael@428 | 121 | } |
michael@428 | 122 | |
michael@428 | 123 | # global return code |
michael@428 | 124 | $main::GRC = 0; |
michael@428 | 125 | |
michael@428 | 126 | # environment preparation |
michael@428 | 127 | system("rm -rf $tmpdir"); |
michael@428 | 128 | system("mkdir -p $tmpdir"); |
michael@428 | 129 | |
michael@428 | 130 | # iterate over all fsl. files |
michael@428 | 131 | foreach my $filename (@ARGV) { |
michael@428 | 132 | my $io = new IO::File "<$filename" |
michael@428 | 133 | or die "unable to open file \"$filename\" for reading"; |
michael@428 | 134 | my $spec; { local $/ = undef; $spec = <$io>; } |
michael@428 | 135 | $io->close; |
michael@428 | 136 | foreach my $check (@checks) { |
michael@428 | 137 | eval "\&check_$check(\$filename, \$spec);"; |
michael@428 | 138 | } |
michael@428 | 139 | } |
michael@428 | 140 | |
michael@428 | 141 | # environment cleanup |
michael@428 | 142 | system("rm -rf $tmpdir"); |
michael@428 | 143 | |
michael@428 | 144 | # die gracefully |
michael@428 | 145 | exit($main::GRC); |
michael@428 | 146 | |
michael@428 | 147 | ## _________________________________________________________________ |
michael@428 | 148 | ## |
michael@428 | 149 | ## COMMON SUBROUTINES |
michael@428 | 150 | ## _________________________________________________________________ |
michael@428 | 151 | ## |
michael@428 | 152 | |
michael@428 | 153 | sub lines { |
michael@428 | 154 | my ($txt) = @_; |
michael@428 | 155 | my $l = 0; |
michael@428 | 156 | $txt =~ s|\n|$l++, ''|sge; |
michael@428 | 157 | return $l; |
michael@428 | 158 | } |
michael@428 | 159 | |
michael@428 | 160 | sub lint_message { |
michael@428 | 161 | my ($type, $file, $done, $this, $msg) = @_; |
michael@428 | 162 | if (defined($done) and defined($this)) { |
michael@428 | 163 | my $start = &lines($done) + 1; |
michael@428 | 164 | my $end = $start + &lines($this); |
michael@428 | 165 | my $pos = $start; |
michael@428 | 166 | $pos .= "-". $end if ($end > $start); |
michael@428 | 167 | printf("%s:%s: %s:%s: %s\n", $progname, $type, $file, $pos, $msg); |
michael@428 | 168 | } |
michael@428 | 169 | else { |
michael@428 | 170 | printf("%s:%s: %s: %s\n", $progname, $type, $file, $msg); |
michael@428 | 171 | } |
michael@428 | 172 | } |
michael@428 | 173 | |
michael@428 | 174 | sub lint_warning { |
michael@428 | 175 | my ($file, $done, $this, $msg) = @_; |
michael@428 | 176 | &lint_message("WARNING", $file, $done, $this, $msg); |
michael@428 | 177 | $main::GRC = 1 if ($main::GRC < 1); |
michael@428 | 178 | } |
michael@428 | 179 | |
michael@428 | 180 | sub lint_error { |
michael@428 | 181 | my ($file, $done, $this, $msg) = @_; |
michael@428 | 182 | &lint_message("ERROR", $file, $done, $this, $msg); |
michael@428 | 183 | $main::GRC = 2 if ($main::GRC < 2); |
michael@428 | 184 | } |
michael@428 | 185 | |
michael@428 | 186 | ## _________________________________________________________________ |
michael@428 | 187 | ## |
michael@428 | 188 | ## CHECK "blank": whitespace and blank lines |
michael@428 | 189 | ## _________________________________________________________________ |
michael@428 | 190 | ## |
michael@428 | 191 | |
michael@428 | 192 | sub check_blank { |
michael@428 | 193 | my ($file, $spec) = @_; |
michael@428 | 194 | |
michael@428 | 195 | # check for CR-LF combination |
michael@428 | 196 | my $done = ''; my $this = ''; my $todo = $spec; |
michael@428 | 197 | while ($todo =~ m/\r\n/s) { |
michael@428 | 198 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 199 | &lint_warning($file, $done, $this, "carriage-return (CR, 0x0d) line-feed (NL, 0x0a) combination (expected just line-feed)"); |
michael@428 | 200 | $done .= $this; |
michael@428 | 201 | } |
michael@428 | 202 | |
michael@428 | 203 | # check for multiple blank lines |
michael@428 | 204 | $done = ''; $this = ''; $todo = $spec; |
michael@428 | 205 | while ($todo =~ m/(\r?\n[ \t]*){3,}/s) { |
michael@428 | 206 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 207 | &lint_warning($file, $done, $this, "multiple subsequent blank lines (expected single blank line)"); |
michael@428 | 208 | $done .= $this; |
michael@428 | 209 | } |
michael@428 | 210 | |
michael@428 | 211 | # check for trailing whitespaces |
michael@428 | 212 | $done = ''; $this = ''; $todo = $spec; |
michael@428 | 213 | while ($todo =~ m/[ \t]+\r?\n/s) { |
michael@428 | 214 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 215 | if ($done eq '' or $done =~ m|\n$|s) { |
michael@428 | 216 | &lint_warning($file, $done, $this, "whitespace on empty line (expected none)"); |
michael@428 | 217 | } |
michael@428 | 218 | else { |
michael@428 | 219 | &lint_warning($file, $done, $this, "trailing whitespace (expected none)"); |
michael@428 | 220 | } |
michael@428 | 221 | $done .= $this; |
michael@428 | 222 | } |
michael@428 | 223 | |
michael@428 | 224 | # check for bogus line continuations |
michael@428 | 225 | $done = ''; $this = ''; $todo = $spec; |
michael@428 | 226 | while ($todo =~ m/\\[ \t]*\r?\n(?=[ \t]*\r?\n)/s) { |
michael@428 | 227 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 228 | &lint_warning($file, $done, $this, "bogus line continuation for following empty line (expect no line continuation)"); |
michael@428 | 229 | $done .= $this; |
michael@428 | 230 | } |
michael@428 | 231 | |
michael@428 | 232 | # check for leading whitespaces before line continuations |
michael@428 | 233 | $done = ''; $this = ''; $todo = $spec; |
michael@428 | 234 | while ($todo =~ m/[ \t]{2,}\\[ \t]*\r?\n/s) { |
michael@428 | 235 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 236 | &lint_warning($file, $done, $this, "multiple leading whitespace before line continuation (expected just a single space)"); |
michael@428 | 237 | $done .= $this; |
michael@428 | 238 | } |
michael@428 | 239 | |
michael@428 | 240 | # check for leading tabs |
michael@428 | 241 | $done = ''; $this = ''; $todo = $spec; |
michael@428 | 242 | while ($todo =~ m/^ *\t+ *[^ \t]/m) { |
michael@428 | 243 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 244 | &lint_warning($file, $done, $this, "leading tabs (expected spaces)"); |
michael@428 | 245 | $done .= $this; |
michael@428 | 246 | } |
michael@428 | 247 | |
michael@428 | 248 | # check for mandatory/wished trailing blank line |
michael@428 | 249 | if ($spec !~ m|\n\n$|) { |
michael@428 | 250 | &lint_warning($file, $done, "", "mandatory/wished trailing blank line missing (expected one)"); |
michael@428 | 251 | } |
michael@428 | 252 | } |
michael@428 | 253 | |
michael@428 | 254 | ## _________________________________________________________________ |
michael@428 | 255 | ## |
michael@428 | 256 | ## CHECK "comment": sharp-comments |
michael@428 | 257 | ## _________________________________________________________________ |
michael@428 | 258 | ## |
michael@428 | 259 | |
michael@428 | 260 | sub check_comment { |
michael@428 | 261 | my ($file, $spec) = @_; |
michael@428 | 262 | my ($pkg); |
michael@428 | 263 | |
michael@428 | 264 | # determine package name |
michael@428 | 265 | $pkg = $file; |
michael@428 | 266 | $pkg =~ s|^.+/||; |
michael@428 | 267 | $pkg =~ s|^fsl\.||; |
michael@428 | 268 | |
michael@428 | 269 | # check comment header |
michael@428 | 270 | my $re = ""; |
michael@428 | 271 | $re .= "##\\n## fsl.$pkg -- OSSP fsl configuration\\n##\\n\\n"; |
michael@428 | 272 | if ($spec !~ m|^$re|os) { |
michael@428 | 273 | &lint_warning($file, "", "", "invalid comment header (expected $re)"); |
michael@428 | 274 | } |
michael@428 | 275 | |
michael@428 | 276 | # check for comment indentation |
michael@428 | 277 | my $done .= $`; my $this = $&; my $todo = $'; |
michael@428 | 278 | while ($todo =~ m/^([ \t]*)(#+)([ \t]*)(.*?)$/m) { |
michael@428 | 279 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 280 | my ($lead, $sharp, $pad, $text) = ($1, $2, $3, $4); |
michael@428 | 281 | if (length($lead) % 2 != 0) { |
michael@428 | 282 | &lint_warning($file, $done, $this, "incorrect comment indentation (expected a multiple of 2 spaces)"); |
michael@428 | 283 | } |
michael@428 | 284 | if (length($lead) > 1 && length($sharp) > 1) { |
michael@428 | 285 | &lint_warning($file, $done, $this, "indented comment has introduced with multiple sharps (expected single sharp character)"); |
michael@428 | 286 | } |
michael@428 | 287 | if (length($pad.$text) > 0 && length($sharp.$pad) % 4 != 0) { |
michael@428 | 288 | &lint_warning($file, $done, $this, "incorrect comment text padding (expected a multiple of 4 sharps or spaces)"); |
michael@428 | 289 | } |
michael@428 | 290 | if (length($pad) == 0 && length($text) > 0) { |
michael@428 | 291 | &lint_warning($file, $done, $this, "missing leading space before comment text (expected padding spaces)"); |
michael@428 | 292 | } |
michael@428 | 293 | if (length($pad) > 0 && length($text) == 0) { |
michael@428 | 294 | &lint_warning($file, $done, $this, "empty comment text (expected a reasonable text)"); |
michael@428 | 295 | } |
michael@428 | 296 | $done .= $this; |
michael@428 | 297 | } |
michael@428 | 298 | } |
michael@428 | 299 | |
michael@428 | 300 | ## _________________________________________________________________ |
michael@428 | 301 | ## |
michael@428 | 302 | ## CHECK "ident" |
michael@428 | 303 | ## _________________________________________________________________ |
michael@428 | 304 | ## |
michael@428 | 305 | |
michael@428 | 306 | sub check_ident { |
michael@428 | 307 | my ($file, $spec) = @_; |
michael@428 | 308 | my ($pkg, $section); |
michael@428 | 309 | |
michael@428 | 310 | # determine package name |
michael@428 | 311 | $pkg = $file; |
michael@428 | 312 | $pkg =~ s|^.+/||; |
michael@428 | 313 | $pkg =~ s|^fsl\.||; |
michael@428 | 314 | |
michael@428 | 315 | # check sections with ident/facility regex |
michael@428 | 316 | my $done .= ""; my $this = ""; my $todo = $spec; |
michael@428 | 317 | while ($todo =~ m:\n(\w+)(\s+)(\S+)/(\S+)(\s+)q\{(.*?)\};:s) { |
michael@428 | 318 | $done .= $`; $this = $&; $todo = $'; |
michael@428 | 319 | my ($section, $ws1, $ident, $facility, $ws2, $body) = ($1, $2, $3, $4, $5, $6); |
michael@428 | 320 | |
michael@428 | 321 | if ($pkg eq "fsl") { |
michael@428 | 322 | # enforce default section for fsl |
michael@428 | 323 | if ($section ne "default") { |
michael@428 | 324 | &lint_warning($file, "", "", "section \"$section\" not allowed for package $pkg (expected default)"); |
michael@428 | 325 | } |
michael@428 | 326 | } |
michael@428 | 327 | else { |
michael@428 | 328 | # enforce ident section for any package othen than fsl |
michael@428 | 329 | if ($section ne "ident") { |
michael@428 | 330 | &lint_warning($file, "", "", "section \"$section\" not allowed for package $pkg (expected ident)"); |
michael@428 | 331 | } |
michael@428 | 332 | |
michael@428 | 333 | # ident and facility wildcard-only would be a catch-all |
michael@428 | 334 | if ($ident =~ m/^[(]?\.[\+\*][)]?$/ and $facility =~ m/^[(]?\.[\+\*][)]?$/) { |
michael@428 | 335 | &lint_warning($file, "", "", "wildcard not allowed for both ident and facility (found $ident/$facility"); |
michael@428 | 336 | } |
michael@428 | 337 | } |
michael@428 | 338 | |
michael@428 | 339 | # enforce a single space |
michael@428 | 340 | if (length($ws1) != 1) { |
michael@428 | 341 | &lint_warning($file, "", "", "whitespace count wrong between section ($section) and ident ($ident)"); |
michael@428 | 342 | } |
michael@428 | 343 | |
michael@428 | 344 | # enforce a single space |
michael@428 | 345 | if (length($ws2) != 1) { |
michael@428 | 346 | &lint_warning($file, "", "", "whitespace count wrong between facility ($facility) and end of line"); |
michael@428 | 347 | } |
michael@428 | 348 | |
michael@428 | 349 | # ident same as facility is likely to be a typo |
michael@428 | 350 | if ($ident eq $facility) { |
michael@428 | 351 | &lint_warning($file, "", "", "unusual constellation ident equal to facility (found $ident/$facility"); |
michael@428 | 352 | } |
michael@428 | 353 | |
michael@428 | 354 | # FIXME MTAs hardcoded here for /mail |
michael@428 | 355 | if ($facility eq "mail" and $pkg !~ m/^(sendmail|ssmtp|postfix|exim)$/) { |
michael@428 | 356 | &lint_warning($file, "", "", "only MTAs may match facility mail"); |
michael@428 | 357 | } |
michael@428 | 358 | |
michael@428 | 359 | # FIXME inn hardcoded here for /news |
michael@428 | 360 | if ($facility eq "news" and $pkg !~ m/^(inn)$/) { |
michael@428 | 361 | &lint_warning($file, "", "", "only inn may match facility news"); |
michael@428 | 362 | } |
michael@428 | 363 | |
michael@428 | 364 | # check prefix channel |
michael@428 | 365 | if ($body =~ m/\n([ ]*)prefix(\s*?)\((.*?)\)/s) { |
michael@428 | 366 | my ($ws1, $ws2, $options) = ($1, $2, $3); |
michael@428 | 367 | |
michael@428 | 368 | # enforce eight spaces |
michael@428 | 369 | if (length($ws1) != 4) { |
michael@428 | 370 | &lint_warning($file, "", "", "prefix channel whitespace count at start of line"); |
michael@428 | 371 | } |
michael@428 | 372 | |
michael@428 | 373 | # enforce zero spaces |
michael@428 | 374 | if (length($ws2) != 0) { |
michael@428 | 375 | &lint_warning($file, "", "", "whitespace not allowed between prefix channel and round open bracket"); |
michael@428 | 376 | } |
michael@428 | 377 | |
michael@428 | 378 | # enforce prefix options in prefix channel |
michael@428 | 379 | if ($options !~ m/\sprefix="%b %d %H:%M:%S %N (<%L> )?\$1(\[%P\])?: "/) { |
michael@428 | 380 | &lint_warning($file, "", "", "prefix option in prefix channel invalid or missing"); |
michael@428 | 381 | } |
michael@428 | 382 | $options = $'; |
michael@428 | 383 | $options =~ s/,//; |
michael@428 | 384 | |
michael@428 | 385 | # detect superflous options in prefix channel |
michael@428 | 386 | if ($options =~ m/\S+/s) { |
michael@428 | 387 | $options =~ s/\n/\\n/; |
michael@428 | 388 | &lint_warning($file, "", "", "superflous option in prefix channel unseparated line detected: $options"); |
michael@428 | 389 | } |
michael@428 | 390 | } |
michael@428 | 391 | else { |
michael@428 | 392 | &lint_warning($file, "", "", "prefix channel missing"); |
michael@428 | 393 | } |
michael@428 | 394 | |
michael@428 | 395 | # check path branch |
michael@428 | 396 | if ($body !~ m/\n([ ]*)->(\s*?)\{(.*)\}\n/s) { |
michael@428 | 397 | &lint_warning($file, "", "", "no path branch found"); |
michael@428 | 398 | return; |
michael@428 | 399 | } |
michael@428 | 400 | my ($ws1, $ws2, $body) = ($1, $2, $3); #FIXME check ws1/ws2 |
michael@428 | 401 | |
michael@428 | 402 | # check path channel |
michael@428 | 403 | while ($body =~ m/\n([ ]*)(\w+):(\s+?)file(\s*?)\((.*?)\);/s) { |
michael@428 | 404 | my ($ws1, $level, $ws2, $ws3, $options) = ($1, $2, $3, $4, $5); |
michael@428 | 405 | $body = $'; |
michael@428 | 406 | |
michael@428 | 407 | # enforce eight spaces |
michael@428 | 408 | if (length($ws1) != 8) { |
michael@428 | 409 | &lint_warning($file, "", "", "path channel whitespace count at start of line"); |
michael@428 | 410 | } |
michael@428 | 411 | |
michael@428 | 412 | # enforce spaces |
michael@428 | 413 | if (length($ws2) < 1) { |
michael@428 | 414 | &lint_warning($file, "", "", "whitespace required between level and file"); |
michael@428 | 415 | } |
michael@428 | 416 | |
michael@428 | 417 | # enforce zero spaces |
michael@428 | 418 | if (length($ws3) != 0) { |
michael@428 | 419 | &lint_warning($file, "", "", "path channel whitespace not allowed between file channel and round open bracket"); |
michael@428 | 420 | } |
michael@428 | 421 | |
michael@428 | 422 | # check for legal l2 level |
michael@428 | 423 | if ($level !~ m/^(panic|critical|error|warning|notice|info|trace|debug)$/) { |
michael@428 | 424 | &lint_warning($file, "", "", "illegal l2 level $level detected"); |
michael@428 | 425 | } |
michael@428 | 426 | |
michael@428 | 427 | # enforce file option in file channel |
michael@428 | 428 | if ($options !~ m;path="\@l_prefix\@/var/$pkg/(log\S+|$pkg\.log)";) { |
michael@428 | 429 | &lint_warning($file, "", "", "path option in file channel invalid or missing"); |
michael@428 | 430 | } |
michael@428 | 431 | $options = $'; |
michael@428 | 432 | $options =~ s/,//; |
michael@428 | 433 | |
michael@428 | 434 | # enforce perm option in file channel |
michael@428 | 435 | if ($options !~ m;perm=0[0-7]{3};) { |
michael@428 | 436 | &lint_warning($file, "", "", "perm option in file channel invalid or missing"); |
michael@428 | 437 | } |
michael@428 | 438 | $options = $'; |
michael@428 | 439 | $options =~ s/,//; |
michael@428 | 440 | |
michael@428 | 441 | # detect superflous options in file channel |
michael@428 | 442 | if ($options =~ m/\S+/s) { |
michael@428 | 443 | $options =~ s/\n/\\n/; |
michael@428 | 444 | &lint_warning($file, "", "", "superflous option in prefix channel detected: $options"); |
michael@428 | 445 | } |
michael@428 | 446 | } |
michael@428 | 447 | |
michael@428 | 448 | # check path channel |
michael@428 | 449 | if ($body =~ m/\n([ ]*)(\w+):(\s*?)file(\s*?)\((.*?)\)/s) { |
michael@428 | 450 | my ($ws1, $level, $ws2, $ws3, $options) = ($1, $2, $3, $4, $5); |
michael@428 | 451 | |
michael@428 | 452 | # enforce eight spaces |
michael@428 | 453 | if (length($ws1) != 8) { |
michael@428 | 454 | &lint_warning($file, "", "", "path channel whitespace count at start of unseparated line"); |
michael@428 | 455 | } |
michael@428 | 456 | |
michael@428 | 457 | # enforce spaces |
michael@428 | 458 | if (length($ws2) < 1) { |
michael@428 | 459 | &lint_warning($file, "", "", "path channel whitespace required between level and file of unseparated line"); |
michael@428 | 460 | } |
michael@428 | 461 | |
michael@428 | 462 | # enforce zero spaces |
michael@428 | 463 | if (length($ws3) != 0) { |
michael@428 | 464 | &lint_warning($file, "", "", "whitespace not allowed between file channel and round open bracket"); |
michael@428 | 465 | } |
michael@428 | 466 | |
michael@428 | 467 | # check for legal l2 level |
michael@428 | 468 | if ($level !~ m/^(panic|critical|error|warning|notice|info|trace|debug)$/) { |
michael@428 | 469 | &lint_warning($file, "", "", "illegal l2 level $level detected on unseparated line"); |
michael@428 | 470 | } |
michael@428 | 471 | |
michael@428 | 472 | # enforce file option in file channel |
michael@428 | 473 | if ($options !~ m;path="\@l_prefix\@/var/$pkg/(log\S+|$pkg\.log)";) { |
michael@428 | 474 | &lint_warning($file, "", "", "XXX path option in file channel invalid or missing on unseparated line"); |
michael@428 | 475 | } |
michael@428 | 476 | $options = $'; |
michael@428 | 477 | $options =~ s/,//; |
michael@428 | 478 | |
michael@428 | 479 | # enforce perm option in file channel |
michael@428 | 480 | if ($options !~ m;perm=0[0-7]{3};) { |
michael@428 | 481 | &lint_warning($file, "", "", "perm option in file channel invalid or missing on unseparated line"); |
michael@428 | 482 | } |
michael@428 | 483 | |
michael@428 | 484 | $options = $'; |
michael@428 | 485 | $options =~ s/, jitter=[0-9]+//; |
michael@428 | 486 | $options =~ s/, monitor=[0-9]+//; |
michael@428 | 487 | $options =~ s/,//; |
michael@428 | 488 | |
michael@428 | 489 | # detect superflous options in file channel |
michael@428 | 490 | if ($options =~ m/\S+/s) { |
michael@428 | 491 | $options =~ s/\n/\\n/; |
michael@428 | 492 | &lint_warning($file, "", "", "superflous option in file channel unseparated line detected: $options"); |
michael@428 | 493 | } |
michael@428 | 494 | } |
michael@428 | 495 | else { |
michael@428 | 496 | &lint_warning($file, "", "", "file channel missing"); |
michael@428 | 497 | } |
michael@428 | 498 | |
michael@428 | 499 | $done .= $this; |
michael@428 | 500 | } |
michael@428 | 501 | return; |
michael@428 | 502 | } |