1 #!/usr/bin/perl --
2 #
3 # collectd - check_plugins.pl
4 # Copyright (C) 2006, 2007 Sebastian Harl
5 #
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; only version 2 of the License is applicable.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #
19 # Author:
20 # Sebastian Harl <sh at tokkee.org>
22 # This script checks each plugin and reports the address of each plugin's
23 # registered functions. It uses src/.libs/*.so for its checks. This can be
24 # used to check what kind of operations each plugin supports after it has been
25 # built.
27 use strict;
28 use warnings;
30 my $srcdir = 'src/';
31 my $libdir = 'src/.libs';
33 my $plugins = {};
35 my ($srcs, $libs) = (undef, undef);
37 if (! opendir($srcs, $srcdir)) {
38 print STDERR "Could not open directory '$srcdir': $!\n"
39 . "Make sure you are in the toplevel source directory.\n";
40 exit 1;
41 }
43 while (my $dirent = readdir($srcs)) {
44 if ($dirent !~ m/^(.*)\.c$/) {
45 next;
46 }
48 my $name = $1;
49 my $src = undef;
51 if (! open($src, "<", "$srcdir/$dirent")) {
52 print STDERR "Unable to open '$srcdir/$dirent': $!\n";
53 next;
54 }
56 while (my $line = <$src>) {
57 if ($line =~ m/plugin_register_(\w+)\s*\("([^"]+)",\s*(\w+)/) {
58 my ($t, $n, $f) = ($1, $2, $3);
60 $plugins->{$name}->{$n}->{$t} = $f;
61 }
62 }
64 close($src);
65 } # while (my $dirent = readdir($srcs))
67 closedir($srcs);
69 if (! opendir($libs, $libdir)) {
70 print STDERR "Could not open directory '$libdir': $!\n"
71 . "Make sure you ran 'make'.\n";
72 exit 1;
73 }
75 while (my $dirent = readdir($libs)) {
76 if ($dirent !~ m/^(.*)\.so$/) {
77 next;
78 }
80 my $name = $1;
81 my $nm = undef;
83 if (! defined $plugins->{$name}) {
84 print STDERR "No information available for plugin '$name'!\n";
85 next;
86 }
88 if (! open($nm, "-|", "nm $libdir/$dirent")) {
89 print STDERR "Unable to open pipe from nm(1): $!\n";
90 next;
91 }
93 while (my $line = <$nm>) {
94 if ($line !~ m/^([0-9a-fA-F]{8,}) [tT] (\w+)$/) {
95 next;
96 }
98 my $adr = $1;
99 my $sym = $2;
101 for my $n (keys %{$plugins->{$name}}) {
102 for my $t (keys %{$plugins->{$name}->{$n}}) {
103 if (defined $plugins->{$name}->{$n}->{$t}
104 && ($sym eq $plugins->{$name}->{$n}->{$t})) {
105 $plugins->{$name}->{$n}->{$t} = "0x" . $adr;
106 }
107 }
108 }
109 }
111 close($nm);
112 } # while (my $dirent = readdir($libs))
114 closedir($libs);
116 print 'plugin name config init read write log shutdown';
117 print $/ . '-' x 70 . $/;
119 for my $name (sort keys %$plugins) {
120 if (! -f "$libdir/$name.so") {
121 print "$name.c has not been compiled.\n";
122 next;
123 }
125 for my $n (sort keys %{$plugins->{$name}}) {
126 dump_plugin_data($n, $plugins->{$name}->{$n});
127 }
128 }
130 exit 0;
132 sub dump_plugin_data {
133 my $name = shift || return;
134 my $funcs = shift || return;
136 if (length($name) > 15) {
137 $name = substr($name, 0, 12) . '...';
138 }
140 printf '%-15s ', $name;
142 foreach my $t ("config", "init", "read", "write", "log", "shutdown") {
143 if (! defined $funcs->{$t}) {
144 print '- ';
145 }
146 elsif ($funcs->{$t} =~ m/^0x[A-Fa-f0-9]{8,}$/) {
147 print substr($funcs->{$t}, -8, 8) . " ";
148 }
149 else {
150 print 'nA ';
151 }
152 }
154 print $/;
155 return 1;
156 } # sub dump_plugin_data
158 # vim: set sw=4 ts=4 tw=78 noexpandtab :