]>
Commit | Line | Data |
---|---|---|
c5ceffad MT |
1 | #!/usr/bin/perl |
2 | # | |
3 | # Perform sanity checks on the services file, supplied as argument. | |
4 | # Based on an earlier shell script of the same name, but much faster, | |
5 | # and it also detects actual errors in the current services file :) | |
6 | # | |
7 | # This program includes a manual, run "perldoc serviceslint" to see it. | |
8 | # | |
9 | ||
10 | use strict; | |
11 | use warnings; | |
12 | ||
13 | die "Usage: $0 /etc/services\n" unless $#ARGV == 0; | |
14 | ||
15 | # Build a hash of known protocols | |
16 | my %protocol; | |
17 | open FH, "protocols" or die "cannot open protocols: $!\n"; | |
18 | while (<FH>) { | |
19 | chomp; | |
20 | s/#.*$//; | |
21 | my ($name, $port) = m/([\S]+)\s+(\d+)/ or next; | |
22 | $protocol{$name} = $port; | |
23 | } | |
24 | close FH; | |
25 | ||
26 | # Parse the supplied services file | |
27 | my $retval = 0; | |
28 | my $line = 0; | |
29 | my %service; | |
30 | open FH, $ARGV[0] or die "cannot open $ARGV[0]: $!\n"; | |
31 | while (<FH>) { | |
32 | $line++; # Keep a line count | |
33 | chomp; # Remove CR/LF chars | |
34 | if (m/^\s+/) { | |
35 | print "Malformed line $line\n"; # No leading whitespace | |
36 | $retval = 1; | |
37 | next; | |
38 | } | |
39 | s/\s*#.*$//; # Strip out comments | |
40 | next if m/^$/; # Skip empty lines | |
41 | my ($name, $port, $proto, $aliases) = # Primary pattern match | |
42 | m/^([\S]+)\s+(\d+)\/(\w+)\s*(.*)/ | |
43 | or die "Malformed line: $line\n"; | |
44 | if (not exists $protocol{$proto}) { | |
45 | print "Bad protocol at line $line: $proto\n"; | |
46 | $retval = 1; | |
47 | } | |
48 | if (exists $service{$proto}{$port}) { | |
49 | print "Duplicate port at line $line: $port/$proto\n"; | |
50 | $retval = 1; | |
51 | } | |
52 | $service{$proto}{$port} = $name; | |
53 | foreach ($name, split /\s+/, $aliases) { | |
54 | if (exists $service{$proto}{$_}) { | |
55 | print "Duplicate name at line $line: $_/$proto\n"; | |
56 | $retval = 1; | |
57 | } | |
58 | $service{$proto}{$_} = $port; | |
59 | }; | |
60 | ||
61 | } | |
62 | close FH; | |
63 | exit $retval; | |
64 | ||
65 | __END__ | |
66 | ||
67 | =head1 NAME | |
68 | ||
69 | serviceslint - perform verification on the /etc/services file | |
70 | ||
71 | =head1 SYNOPSIS | |
72 | ||
73 | B<serviceslint> I<filename> | |
74 | ||
75 | =head1 DESCRIPTION | |
76 | ||
77 | The B<serviceslint> command performs syntax and content checks on the | |
78 | given filename, normally a copy of the I</etc/services> file. | |
79 | ||
80 | Syntax checking consists of a regular expression applied to | |
81 | non-empty, non-comment lines. If the syntax check fails, then | |
82 | the program prints a message and aborts with non-zero status code. | |
83 | ||
84 | Content checking detects various kinds of duplicate entries. | |
85 | Currently, warnings are printed for duplicate entries, but execution | |
86 | continues, and the program I<exits with status code zero> (eg. success). | |
87 | ||
88 | =over | |
89 | ||
90 | =item B<Malformed line> I<NNN> | |
91 | ||
92 | The specified line has invalid syntax. Note that leading whitespace | |
93 | is not permitted. Non-empty lines must begin with a comment, or with | |
94 | a service name followed by a port number / protocol pair. | |
95 | ||
96 | =item B<Duplicate port at line> I<NNN> | |
97 | ||
98 | Occurs when a port number / protocol pair is found more than once | |
99 | in the services file. The warning is flagged on the second (and any | |
100 | subsequent) occurrences. These entries will not be found via the | |
101 | B<getservbyport()> function. | |
102 | ||
103 | =item B<Duplicate name at line> I<NNN> | |
104 | ||
105 | Occurs when a service name, or alias, occurs more than once in the | |
106 | services file. The warning is flagged on the second (and subsequent) | |
107 | occurrence. These entries will not be returned by the B<getservbyname()> | |
108 | function. | |
109 | ||
110 | =back | |
111 | ||
112 | =head1 SEE ALSO | |
113 | ||
114 | The services(5) man page describes the file format. | |
115 | ||
116 | =head1 AUTHOR | |
117 | ||
118 | Ralph Siemsen & Phil Knirsch | |
119 |