setup/serviceslint
Zbigniew Jędrzejewski-Szmek 36eef7070f Merge upstream into downstream
This implements https://pagure.io/setup/issue/51.

The "upstream" is only used to build the package in our dist-git, so we can reduce the
total amount of work by moving files downstream and maintaining them there.

The package after the rebuild is identical, except for intentional changes
(removal of Group, updating of Url, bumping of the Version):

$ rpmdiff -iT noarch/setup-2.14.5-2.fc41.noarch.rpm noarch/setup-2.15.0-1.fc41.noarch.rpm
S.5.....    GROUP
S.5.....    URL
removed     REQUIRES config(setup) = 2.14.5-2.fc41
added       REQUIRES config(setup) = 2.15.0-1.fc41
removed     PROVIDES config(setup) = 2.14.5-2.fc41
removed     PROVIDES setup = 2.14.5-2.fc41
added       PROVIDES config(setup) = 2.15.0-1.fc41
added       PROVIDES setup = 2.15.0-1.fc41
2024-05-27 14:32:47 +02:00

119 lines
3.1 KiB
Perl
Executable file

#!/usr/bin/perl
#
# Perform sanity checks on the services file, supplied as argument.
# Based on an earlier shell script of the same name, but much faster,
# and it also detects actual errors in the current services file :)
#
# This program includes a manual, run "perldoc serviceslint" to see it.
#
use strict;
use warnings;
die "Usage: $0 /etc/services\n" unless $#ARGV == 0;
# Build a hash of known protocols
my %protocol;
open FH, "protocols" or die "cannot open protocols: $!\n";
while (<FH>) {
chomp;
s/#.*$//;
my ($name, $port) = m/([\S]+)\s+(\d+)/ or next;
$protocol{$name} = $port;
}
close FH;
# Parse the supplied services file
my $retval = 0;
my $line = 0;
my %service;
open FH, $ARGV[0] or die "cannot open $ARGV[0]: $!\n";
while (<FH>) {
$line++; # Keep a line count
chomp; # Remove CR/LF chars
if (m/^\s+/) {
print "Malformed line $line\n"; # No leading whitespace
$retval = 1;
next;
}
s/\s*#.*$//; # Strip out comments
next if m/^$/; # Skip empty lines
my ($name, $port, $proto, $aliases) = # Primary pattern match
m/^([\S]+)\s+(\d+)\/(\w+)\s*(.*)/
or die "Malformed line: $line\n";
if (not exists $protocol{$proto}) {
print "Bad protocol at line $line: $proto\n";
$retval = 1;
}
if (exists $service{$proto}{$port}) {
print "Duplicate port at line $line: $port/$proto\n";
$retval = 1;
}
$service{$proto}{$port} = $name;
foreach ($name, split /\s+/, $aliases) {
if (exists $service{$proto}{$_}) {
print "Duplicate name at line $line: $_/$proto\n";
$retval = 1;
}
$service{$proto}{$_} = $port;
};
}
close FH;
exit $retval;
__END__
=head1 NAME
serviceslint - perform verification on the /etc/services file
=head1 SYNOPSIS
B<serviceslint> I<filename>
=head1 DESCRIPTION
The B<serviceslint> command performs syntax and content checks on the
given filename, normally a copy of the I</etc/services> file.
Syntax checking consists of a regular expression applied to
non-empty, non-comment lines. If the syntax check fails, then
the program prints a message and aborts with non-zero status code.
Content checking detects various kinds of duplicate entries.
Currently, warnings are printed for duplicate entries, but execution
continues, and the program I<exits with status code zero> (eg. success).
=over
=item B<Malformed line> I<NNN>
The specified line has invalid syntax. Note that leading whitespace
is not permitted. Non-empty lines must begin with a comment, or with
a service name followed by a port number / protocol pair.
=item B<Duplicate port at line> I<NNN>
Occurs when a port number / protocol pair is found more than once
in the services file. The warning is flagged on the second (and any
subsequent) occurrences. These entries will not be found via the
B<getservbyport()> function.
=item B<Duplicate name at line> I<NNN>
Occurs when a service name, or alias, occurs more than once in the
services file. The warning is flagged on the second (and subsequent)
occurrence. These entries will not be returned by the B<getservbyname()>
function.
=back
=head1 SEE ALSO
The services(5) man page describes the file format.
=head1 AUTHOR
Ralph Siemsen & Phil Knirsch