Codebase list fusioninventory-agent / 07bfeca
Import Debian changes 2.1.9902-1 fusioninventory-agent (2.1.9902-1) experimental; urgency=low * New upstream beta release Gonéri Le Bouder authored 12 years ago Guillaume Bougard committed 5 years ago
78 changed file(s) with 1873 addition(s) and 1560 deletion(s). Raw diff Collapse all Expand all
5252 * Add the HARDWARE/CHASSIS_TYPE information
5353 * Linux: Use /sbin/ip to get the interface IP addresses (#854)
5454 * HPUX: don't report unoccupied memory slots
55
56 2.1.12
57
58 SOLARIS
59 ✔ Fix some warnings for spurious stat() calls
60 ✔ Fix hostname being forced to 'SOLARIS'
61
62 2.1.11 Mon, 12 Sep 2011 17:34:38 +0200
63
64 WINDOWS
65 ✔ Fix the BIOS information collect on Win2003 <= system
66 commit:8c2427da5, commit: fe345815
67 http://forge.fusioninventory.org/issues/1156
5568
5669 2.1.10 Tue, 06 Sep 2011 08:48:27 -0000
5770
3838 lib/FusionInventory/Agent/Logger/Stderr.pm
3939 lib/FusionInventory/Agent/Logger/Syslog.pm
4040 lib/FusionInventory/Agent/Scheduler.pm
41 lib/FusionInventory/Agent/SNMP.pm
4241 lib/FusionInventory/Agent/Storage.pm
4342 lib/FusionInventory/Agent/Target.pm
4443 lib/FusionInventory/Agent/Target/Local.pm
382381 resources/aix/README
383382 resources/bsd/lsvfs/freebsd-8.1
384383 resources/bsd/mount/dragonfly-1
384 resources/bsd/pkg_info/sample1
385385 resources/generic/df/aix
386386 resources/generic/df/freebsd
387387 resources/generic/df/linux
420420 resources/generic/ifconfig/hpux2-lan0
421421 resources/generic/ifconfig/linux-bonding
422422 resources/generic/ifconfig/linux-rhel5.6
423 resources/generic/ifconfig/opensolaris
423424 resources/generic/ifconfig/solaris-10
424425 resources/generic/ipmitool_lan_print/sample1
425426 resources/generic/lspci/dell-xt2
434435 resources/generic/netstat/hpux1
435436 resources/generic/netstat/hpux2
436437 resources/generic/netstat/linux1
438 resources/generic/netstat/macosx1
437439 resources/generic/netstat/netbsd
438440 resources/generic/netstat/openbsd
439441 resources/generic/ps/linux
602604 resources/virtualization/virsh/list1
603605 resources/virtualization/virsh/list2
604606 resources/virtualization/xm/sample1
607 resources/win32/printer/xppro1/USB.reg
608 resources/win32/printer/xppro1/USBPRINT.reg
609 resources/win32/printer/xppro2/USB.reg
610 resources/win32/printer/xppro2/USBPRINT.reg
605611 resources/xml/response/message1.xml
606612 resources/xml/response/message2.xml
607613 resources/xml/response/message3.xml
627633 t/components/inventory.t
628634 t/components/logger.t
629635 t/components/server.t
630 t/components/SNMP.t
631636 t/components/storage.t
632637 t/components/target.t
633638 t/components/task.t
651656 t/inventory/aix/storages.t
652657 t/inventory/aix/videos.t
653658 t/inventory/bsd/networks.t
659 t/inventory/bsd/softwares.t
654660 t/inventory/generic/dmidecode/battery.t
655661 t/inventory/generic/dmidecode/bios.t
656662 t/inventory/generic/dmidecode/memory.t
674680 t/inventory/linux/drives.t
675681 t/inventory/linux/ilo.t
676682 t/inventory/linux/lvm.t
677 t/inventory/linux/networks.t
678683 t/inventory/linux/rhn-systemid.t
679684 t/inventory/linux/softwares.t
680685 t/inventory/linux/storages/3ware.t
690695 t/inventory/virtualization/parallels.t
691696 t/inventory/virtualization/virtualbox.t
692697 t/inventory/virtualization/xen.t
698 t/inventory/win32/printer/xppro1/USB.reg
699 t/inventory/win32/printer/xppro1/USBPRINT.reg
700 t/inventory/win32/printer/xppro2/USB.reg
701 t/inventory/win32/printer/xppro2/USBPRINT.reg
693702 t/perlcriticrc
694703 t/ssl/cnf/alternate.cnf
695704 t/ssl/cnf/bad.cnf
44 HTTP::Proxy: 0
55 HTTP::Server::Simple: 0
66 HTTP::Server::Simple::Authen: 0
7 HTTP::Server::Simple::CGI: 0
87 IO::Capture::Stderr: 0
98 IPC::Run: 0
109 Test::Exception: 0
11 Test::More: 0
10 Test::More: 0.93
1211 YAML: 0
1312 configure_requires:
1413 ExtUtils::MakeMaker: 6.42
1514 distribution_type: module
16 generated_by: 'Module::Install version 1.01'
15 generated_by: 'Module::Install version 1.02'
1716 license: gpl
1817 meta-spec:
1918 url: http://module-build.sourceforge.net/META-spec-v1.4.html
4241 perl: 5.8.0
4342 resources:
4443 license: http://opensource.org/licenses/gpl-license.php
45 version: 2.1.9901
44 version: 2.1.9902
3636 }
3737
3838 # test dependencies
39 test_requires 'Test::More' => undef;
39 test_requires 'Test::More' => '0.93'; # subtest
4040 test_requires 'IPC::Run' => undef;
4141 test_requires 'HTTP::Proxy' => undef;
4242 test_requires 'HTTP::Server::Simple' => undef;
43 test_requires 'HTTP::Server::Simple::CGI' => undef;
4443 test_requires 'HTTP::Server::Simple::Authen' => undef;
4544 test_requires 'IO::Capture::Stderr' => undef;
4645 test_requires 'Test::Exception' => undef;
4948 install_script 'fusioninventory-agent';
5049 install_script 'fusioninventory-win32-service' if $OSNAME eq 'MSWin32';
5150 install_script 'fusioninventory-injector';
52
5351 # memconf is needed by Solaris backend module
54 if ($OSNAME eq 'solaris') {
55 install_script 'memconf';
56 }
52 install_script 'memconf' if $OSNAME eq 'solaris';
5753
5854 makemaker_args(
5955 test => {
6359
6460 WriteAll;
6561
62 # substitute prefix everywhere
63 $MY::variables{SYSCONFDIR} =~ s/\$\(PREFIX\)/$MY::variables{PREFIX}/;
64 $MY::variables{DATADIR} =~ s/\$\(PREFIX\)/$MY::variables{PREFIX}/;
65 $MY::variables{LOCALSTATEDIR} =~ s/\$\(PREFIX\)/$MY::variables{PREFIX}/;
66
67 # look for already existing configuration file
68 my $config_file_message = -f "$MY::variables{SYSCONFDIR}/agent.cfg" ?
69 "previous configuration file found, new one will be installed as agent.cfg.new" :
70 "no previous configuration file found, new one will be installed as agent.cfg";
71
6672 print <<EOF;
6773
6874 Installation summary
6975 --------------------
70
7176 prefix: $MY::variables{PREFIX}
7277 configuration installation directory: $MY::variables{SYSCONFDIR}
7378 constant data installation directory: $MY::variables{DATADIR}
7479 variable data installation directory: $MY::variables{LOCALSTATEDIR}
7580
81 $config_file_message
7682 EOF
7783
7884 package MY;
8894 # for some reason, initialising variables from the global scope doesn't work
8995 %variables = (
9096 PREFIX => '/usr/local',
91 INSTALLBIN => '$(PREFIX)/bin',
92 INSTALLSITEBIN => '$(PREFIX)/bin',
93 INSTALLVENDORBIN => '$(PREFIX)/bin',
97 INSTALLSCRIPT => '$(PREFIX)/bin',
98 INSTALLSITESCRIPT => '$(PREFIX)/bin',
99 INSTALLVENDORSCRIPT => '$(PREFIX)/bin',
94100 INSTALLMAN1DIR => '$(PREFIX)/share/man/man1',
95101 INSTALLSITEMAN1DIR => '$(PREFIX)/share/man/man1',
96102 INSTALLVENDORMAN1DIR => '$(PREFIX)/share/man/man1',
110116 # Skip comments
111117 next if $line =~ /^\s*#/;
112118 # Skip everything which isn't a var assignment.
113 next unless $line =~ /^([A-Z_]+) =/;
119 next unless $line =~ /^([A-Z0-9_]+) =/;
114120 my $name = $1;
115121 # skip variables we're not interested
116122 next unless $variables{$name};
0 This package uses quilt to manage all modifications to the upstream
1 source. Changes are stored in the source package as diffs in
2 debian/patches and applied during the build.
3
4 To configure quilt to use debian/patches instead of patches, you want
5 either to export QUILT_PATCHES=debian/patches in your environment
6 or use this snippet in your ~/.quiltrc:
7
8 for where in ./ ../ ../../ ../../../ ../../../../ ../../../../../; do
9 if [ -e ${where}debian/rules -a -d ${where}debian/patches ]; then
10 export QUILT_PATCHES=debian/patches
11 break
12 fi
13 done
14
15 To get the fully patched source after unpacking the source package, cd to
16 the root level of the source package and run:
17
18 quilt push -a
19
20 The last patch listed in debian/patches/series will become the current
21 patch.
22
23 To add a new set of changes, first run quilt push -a, and then run:
24
25 quilt new <patch>
26
27 where <patch> is a descriptive name for the patch, used as the filename in
28 debian/patches. Then, for every file that will be modified by this patch,
29 run:
30
31 quilt add <file>
32
33 before editing those files. You must tell quilt with quilt add what files
34 will be part of the patch before making changes or quilt will not work
35 properly. After editing the files, run:
36
37 quilt refresh
38
39 to save the results as a patch.
40
41 Alternately, if you already have an external patch and you just want to
42 add it to the build system, run quilt push -a and then:
43
44 quilt import -P <patch> /path/to/patch
45 quilt push -a
46
47 (add -p 0 to quilt import if needed). <patch> as above is the filename to
48 use in debian/patches. The last quilt push -a will apply the patch to
49 make sure it works properly.
50
51 To remove an existing patch from the list of patches that will be applied,
52 run:
53
54 quilt delete <patch>
55
56 You may need to run quilt pop -a to unapply patches first before running
57 this command.
0 fusioninventory-agent (2.1.9902-1) experimental; urgency=low
1
2 * New upstream beta release
3
4 -- Gonéri Le Bouder <goneri@rulezlan.org> Fri, 21 Oct 2011 17:51:50 +0200
5
06 fusioninventory-agent (2.1.9901-2) experimental; urgency=low
17
28 * Restore the B-D, sorry
2121 Package: fusioninventory-agent
2222 Architecture: any
2323 Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends},
24 ucf, libxml-simple-perl,
25 libnet-ip-perl, libcompress-zlib-perl, libwww-perl, libnet-ssleay-perl,
24 ucf, libnet-ip-perl, libcompress-zlib-perl, libwww-perl, libnet-ssleay-perl,
2625 libproc-daemon-perl, dmidecode [amd64 i386 ia64 kfreebsd-amd64 kfreebsd-i386],
27 libuniversal-require-perl, libproc-pid-file-perl, hdparm, libhttp-daemon-perl,
26 libuniversal-require-perl, libproc-pid-file-perl, hdparm,
2827 libfile-which-perl, libxml-treepp-perl, libyaml-perl, libtext-template-perl,
2928 libjson-perl,
29 # LWP 6
30 libhttp-daemon-perl,
3031 Suggests: pciutils, smartmontools, read-edid
3132 Description: Hardware and software inventory tool (client)
3233 FusionInventory Agent is an application designed to help a network
00 --- fusioninventory-agent.orig/Makefile.PL
11 +++ fusioninventory-agent/Makefile.PL
2 @@ -95,9 +95,9 @@
2 @@ -94,16 +94,16 @@
3
4 # for some reason, initialising variables from the global scope doesn't work
5 %variables = (
6 - PREFIX => '/usr/local',
7 + PREFIX => '/usr',
8 INSTALLSCRIPT => '$(PREFIX)/bin',
9 INSTALLSITESCRIPT => '$(PREFIX)/bin',
10 INSTALLVENDORSCRIPT => '$(PREFIX)/bin',
311 INSTALLMAN1DIR => '$(PREFIX)/share/man/man1',
412 INSTALLSITEMAN1DIR => '$(PREFIX)/share/man/man1',
513 INSTALLVENDORMAN1DIR => '$(PREFIX)/share/man/man1',
715 + SYSCONFDIR => '/etc/fusioninventory',
816 DATADIR => '$(PREFIX)/share/fusioninventory',
917 - LOCALSTATEDIR => '$(PREFIX)/var/fusioninventory',
10 + LOCALSTATEDIR => '/var/fusioninventory',
18 + LOCALSTATEDIR => '/var/lib/fusioninventory-agent',
1119 );
1220
1321 # allow variables defined on command line to override defaults
00 #!/usr/bin/make -f
11
2 BACKPORT = "no"
2 BACKPORT = no
33
44 %:
5 dh $@
5 dh $@ --with quilt
66
77 override_dh_auto_clean:
88 [ ! -d var ] || rm -r var
0 3.0 (quilt)
0 1.0
0 #!/bin/sh
1
2 VERSION=`dpkg-parsechangelog | awk '/Version/ {print $2}'`
3 UBUREV=1
4
5 echo $VERSION
6
7 for dist in natty maverick lucid hardy; do
8 git checkout HEAD -- debian/changelog
9 dch --force-distribution -v $VERSION$dist$UBUREV -D $dist "Backport for $dist"
10 dpkg-buildpackage -S -D -sa -i.git
11 dput ppa ../fusioninventory-agent_$VERSION$dist${UBUREV}_source.changes
12 done
1010 # send tasks results to an OCS server
1111 #server = http://server.domain.com/ocsinventory
1212 # send tasks results to a FusionInventory for GLPI server
13 #server = http://server.domain.com/glpi/plugins/fusioninventory/front/plugin_fusioninventory.communication.php
13 #server = http://server.domain.com/glpi/plugins/fusioninventory/
1414 # write tasks results in a directory
1515 #local = /tmp
1616 # write tasks results on stdout
2121 #
2222
2323 # disable software deployment tasks
24 #no-task = deploy,ocsdeploy
24 #no-task = deploy
2525
2626 #
2727 # Target scheduling options
7676 exit 0;
7777 }
7878
79 my $agent = FusionInventory::Agent->new(
80 confdir => './etc',
81 datadir => './share',
82 vardir => './var',
83 );
84
7985 if ($options->{'list-tasks'}) {
80 my %tasks = FusionInventory::Agent->getKnownTasks();
86 my %tasks = $agent->getAvailableTasks();
8187 foreach my $task (keys %tasks) {
8288 print "$task (v$tasks{$task})\n";
8389 }
8591 }
8692
8793 eval {
88 my $agent = FusionInventory::Agent->new(
89 confdir => './etc',
90 datadir => './share',
91 vardir => './var',
92 options => $options
93 );
94 $agent->init(options => $options);
9495 $agent->run();
9596 };
9697
99100 print STDERR $EVAL_ERROR;
100101 exit 1;
101102 }
103
104 exit(0);
102105
103106 __END__
104107
113113 pod2usage();
114114 }
115115
116 exit(0);
117
116118 __END__
117119
118120 =head1 NAME
00 #!/usr/bin/perl
1 BEGIN {
2 use File::Spec;
3 use File::Basename;
4 chdir(dirname(File::Spec->rel2abs( __FILE__ ))."/../..");
5 }
61
72 use strict;
83 use warnings;
94 use lib './lib';
105 use threads;
116 use threads::shared;
7 use constant SERVICE_SLEEP_TIME => 2000; # 20 milliseconds
8
9 use File::Spec;
10 use File::Basename;
1211
1312 use English qw(-no_match_vars);
1413 use Win32;
1918 delete($ENV{PERL5LIB});
2019 delete($ENV{PERLLIB});
2120
21 my $directory = dirname(File::Spec->rel2abs( __FILE__ ));
22 # on Win2k, Windows do not chdir to the bin directory
23 # we need to do it by ourself
24 chdir($directory);
25
2226 my $win32service = 1;
2327 Win32::Daemon::StartService();
24 my $SERVICE_SLEEP_TIME = 2000; # 20 milliseconds
25 my $PrevState = SERVICE_START_PENDING;
2628
27 my $thr;
29 my $thread;
2830
29 sub startAgent {
30 return if $thr;
31 $thr = threads->create(sub {
32 my $agent = new FusionInventory::Agent(
33 confdir => './etc/fusioninventory',
34 datadir => './share',
35 vardir => './var',
36 options => {
37 service => 1
38 }
39 );
40 $agent->run();
41 });
31 sub getMessage {
32
33 if ($Win32::Daemon::VERSION < 20101014) {
34 return Win32::Daemon::LastControlMessage(1);
35 } else {
36 return Win32::Daemon::QueryLastMessage();
37 }
4238 }
4339
44 sub killAgent {
45 $thr->kill('KILL');
46 $thr = undef;
47 }
48
49 my $State;
50 while (SERVICE_STOPPED != ($State = Win32::Daemon::State())){
51 if (SERVICE_START_PENDING == $State) {
40 my $state;
41 my $previousState = SERVICE_START_PENDING;
42 while (($state = Win32::Daemon::State()) != SERVICE_STOPPED) {
43 if ($state == SERVICE_START_PENDING) {
5244 # Initialization code
5345 startAgent();
5446 Win32::Daemon::State(SERVICE_RUNNING);
55 $PrevState = SERVICE_RUNNING;
56 } elsif (SERVICE_STOP_PENDING == $State) {
47 $previousState = SERVICE_RUNNING;
48 } elsif ($state == SERVICE_STOP_PENDING) {
5749 killAgent();
5850 Win32::Daemon::State(SERVICE_STOPPED);
59 } elsif (SERVICE_PAUSE_PENDING == $State) {
51 } elsif ($state == SERVICE_PAUSE_PENDING) {
6052 # "Pausing...";
6153 killAgent();
6254 Win32::Daemon::State(SERVICE_PAUSED);
63 $PrevState = SERVICE_PAUSED;
55 $previousState = SERVICE_PAUSED;
6456 killAgent();
6557 next;
66 } elsif (SERVICE_CONTINUE_PENDING == $State) {
58 } elsif ($state == SERVICE_CONTINUE_PENDING) {
6759 # "Resuming...";
6860 startAgent();
6961 Win32::Daemon::State(SERVICE_RUNNING);
70 $PrevState = SERVICE_RUNNING;
62 $previousState = SERVICE_RUNNING;
7163 next;
72 } elsif (SERVICE_STOP_PENDING == $State) {
64 } elsif ($state == SERVICE_STOP_PENDING) {
7365 # "Stopping...";
7466 killAgent();
7567 Win32::Daemon::State(SERVICE_STOPPED);
76 $PrevState = SERVICE_STOPPED;
68 $previousState = SERVICE_STOPPED;
7769 next;
78 } elsif (SERVICE_RUNNING == $State) {
70 } elsif ($state == SERVICE_RUNNING) {
7971 # The service is running as normal...
8072 # ...add the main code here...
8173 startAgent();
8274 } else {
8375 # Got an unhandled control message. Set the state to
8476 # whatever the previous state was.
85 Win32::Daemon::State($PrevState);
77 Win32::Daemon::State($previousState);
8678 }
8779
8880 # Check for any outstanding commands. Pass in a non zero value
8981 # and it resets the Last Message to SERVICE_CONTROL_NONE.
90 if (SERVICE_CONTROL_NONE != (my $Message =
91 Win32::Daemon::LastControlMessage(1))) {
92 if (SERVICE_CONTROL_INTERROGATE == $Message) {
82 if (SERVICE_CONTROL_NONE != (my $message = getMessage())) {
83 if (SERVICE_CONTROL_INTERROGATE == $message) {
9384 # Got here if the Service Control Manager is requesting
9485 # the current state of the service. This can happen for
9586 # a variety of reasons. Report the last state we set.
96 Win32::Daemon::State( $PrevState );
97 } elsif (SERVICE_CONTROL_SHUTDOWN == $Message) {
87 Win32::Daemon::State($previousState);
88 } elsif (SERVICE_CONTROL_SHUTDOWN == $message) {
9889 # Yikes! The system is shutting down. We had better clean up
9990 # and stop.
10091 # Tell the SCM that we are preparing to shutdown and that we expect
10495 }
10596 }
10697 # Snoose for awhile so we don't suck up cpu time...
107 Win32::Sleep($SERVICE_SLEEP_TIME);
98 Win32::Sleep(SERVICE_SLEEP_TIME);
99 }
100
101 sub startAgent {
102 return if $thread;
103 $thread = threads->create(sub {
104 my $agent = new FusionInventory::Agent(
105 confdir => $directory . '/../../etc/fusioninventory',
106 datadir => $directory . '/../../share',
107 vardir => $directory . '/../../var',
108 );
109 $agent->init(options => { service => 1 });
110 $agent->run();
111 });
112 }
113
114 sub killAgent {
115 $thread->kill('KILL');
116 $thread = undef;
108117 }
109118
110119 __END__
1616 );
1717
1818 # various lexical flags
19 my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $HasCPANPLUS );
19 my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $InstallDepsTarget, $HasCPANPLUS );
2020 my (
21 $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps
21 $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps,
22 $UpgradeDeps
2223 );
23 my ( $PostambleActions, $PostambleUsed );
24 my ( $PostambleActions, $PostambleActionsNoTest, $PostambleActionsUpgradeDeps,
25 $PostambleActionsUpgradeDepsNoTest, $PostambleActionsListDeps,
26 $PostambleActionsListAllDeps, $PostambleUsed, $NoTest);
2427
2528 # See if it's a testing or non-interactive session
2629 _accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN );
2831
2932 sub _accept_default {
3033 $AcceptDefault = shift;
34 }
35
36 sub _installdeps_target {
37 $InstallDepsTarget = shift;
3138 }
3239
3340 sub missing_modules {
6269 __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) );
6370 exit 0;
6471 }
72 elsif ( $arg =~ /^--upgradedeps=(.*)$/ ) {
73 $UpgradeDeps = 1;
74 __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) );
75 exit 0;
76 }
6577 elsif ( $arg =~ /^--default(?:deps)?$/ ) {
6678 $AcceptDefault = 1;
6779 }
124136 # check entirely since we don't want to have to load (and configure)
125137 # an old CPAN just for a cosmetic message
126138
127 $UnderCPAN = _check_lock(1) unless $SkipInstall;
139 $UnderCPAN = _check_lock(1) unless $SkipInstall || $InstallDepsTarget;
128140
129141 while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) {
130142 my ( @required, @tests, @skiptests );
206218 $CheckOnly
207219 or ($mandatory and $UnderCPAN)
208220 or $AllDeps
221 or $InstallDepsTarget
209222 or _prompt(
210223 qq{==> Auto-install the }
211224 . ( @required / 2 )
236249 }
237250 }
238251
239 if ( @Missing and not( $CheckOnly or $UnderCPAN ) ) {
252 if ( @Missing and not( $CheckOnly or $UnderCPAN) ) {
240253 require Config;
241 print
242 "*** Dependencies will be installed the next time you type '$Config::Config{make}'.\n";
254 my $make = $Config::Config{make};
255 if ($InstallDepsTarget) {
256 print
257 "*** To install dependencies type '$make installdeps' or '$make installdeps_notest'.\n";
258 }
259 else {
260 print
261 "*** Dependencies will be installed the next time you type '$make'.\n";
262 }
243263
244264 # make an educated guess of whether we'll need root permission.
245265 print " (You may need to do that as the 'root' user.)\n"
270290 sub _check_lock {
271291 return unless @Missing or @_;
272292
293 if ($ENV{PERL5_CPANM_IS_RUNNING}) {
294 return _running_under('cpanminus');
295 }
296
273297 my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING};
274298
275299 if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) {
329353 else {
330354 push @modules, $pkg, $ver;
331355 }
356 }
357
358 if ($UpgradeDeps) {
359 push @modules, @installed;
360 @installed = ();
332361 }
333362
334363 return @installed unless @modules; # nothing to do
462491 } else {
463492 die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n";
464493 }
494 push @config, 'prereqs', $value;
495 } elsif ( $key eq 'force' ) {
496 push @config, $key, $value;
497 } elsif ( $key eq 'notest' ) {
498 push @config, 'skiptest', $value;
465499 } else {
466500 die "*** Cannot convert option $key to CPANPLUS version.\n";
467501 }
496530 # set additional options
497531 while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) {
498532 ( $args{$opt} = $arg, next )
499 if $opt =~ /^force$/; # pseudo-option
533 if $opt =~ /^(?:force|notest)$/; # pseudo-option
500534 $CPAN::Config->{$opt} = $arg;
535 }
536
537 if ($args{notest} && (not CPAN::Shell->can('notest'))) {
538 die "Your version of CPAN is too old to support the 'notest' pragma";
501539 }
502540
503541 local $CPAN::Config->{prerequisites_policy} = 'follow';
518556 delete $INC{$inc};
519557 }
520558
521 my $rv = $args{force} ? CPAN::Shell->force( install => $pkg )
522 : CPAN::Shell->install($pkg);
559 my $rv = do {
560 if ($args{force}) {
561 CPAN::Shell->force( install => $pkg )
562 } elsif ($args{notest}) {
563 CPAN::Shell->notest( install => $pkg )
564 } else {
565 CPAN::Shell->install($pkg)
566 }
567 };
568
523569 $rv ||= eval {
524570 $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, )
525571 ->{install}
762808 : "\$(NOECHO) \$(NOOP)"
763809 );
764810
811 my $deps_list = join( ',', @Missing, @Existing );
812
813 $PostambleActionsUpgradeDeps =
814 "\$(PERL) $0 --config=$config --upgradedeps=$deps_list";
815
816 my $config_notest =
817 join( ',', (UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config}),
818 'notest', 1 )
819 if $Config;
820
821 $PostambleActionsNoTest = (
822 ($missing and not $UnderCPAN)
823 ? "\$(PERL) $0 --config=$config_notest --installdeps=$missing"
824 : "\$(NOECHO) \$(NOOP)"
825 );
826
827 $PostambleActionsUpgradeDepsNoTest =
828 "\$(PERL) $0 --config=$config_notest --upgradedeps=$deps_list";
829
830 $PostambleActionsListDeps =
831 '@$(PERL) -le "print for @ARGV" '
832 . join(' ', map $Missing[$_], grep $_ % 2 == 0, 0..$#Missing);
833
834 my @all = (@Missing, @Existing);
835
836 $PostambleActionsListAllDeps =
837 '@$(PERL) -le "print for @ARGV" '
838 . join(' ', map $all[$_], grep $_ % 2 == 0, 0..$#all);
839
765840 return %args;
766841 }
767842
796871
797872 sub postamble {
798873 $PostambleUsed = 1;
799
800 return <<"END_MAKE";
874 my $fragment;
875
876 $fragment .= <<"AUTO_INSTALL" if !$InstallDepsTarget;
801877
802878 config :: installdeps
803879 \t\$(NOECHO) \$(NOOP)
880 AUTO_INSTALL
881
882 $fragment .= <<"END_MAKE";
804883
805884 checkdeps ::
806885 \t\$(PERL) $0 --checkdeps
808887 installdeps ::
809888 \t$PostambleActions
810889
890 installdeps_notest ::
891 \t$PostambleActionsNoTest
892
893 upgradedeps ::
894 \t$PostambleActionsUpgradeDeps
895
896 upgradedeps_notest ::
897 \t$PostambleActionsUpgradeDepsNoTest
898
899 listdeps ::
900 \t$PostambleActionsListDeps
901
902 listalldeps ::
903 \t$PostambleActionsListAllDeps
904
811905 END_MAKE
812906
907 return $fragment;
813908 }
814909
815910 1;
816911
817912 __END__
818913
819 #line 1071
914 #line 1178
33 use strict 'vars';
44 use vars qw{$VERSION};
55 BEGIN {
6 $VERSION = '1.01';
6 $VERSION = '1.02';
77 }
88
99 # Suspend handler for "redefined" warnings
88
99 use vars qw{$VERSION @ISA $ISCORE};
1010 BEGIN {
11 $VERSION = '1.01';
11 $VERSION = '1.02';
1212 @ISA = 'Module::Install::Base';
1313 $ISCORE = 1;
1414 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '1.01';
8 $VERSION = '1.02';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '1.01';
8 $VERSION = '1.02';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
77
88 use vars qw{$VERSION @ISA $ISCORE};
99 BEGIN {
10 $VERSION = '1.01';
10 $VERSION = '1.02';
1111 @ISA = 'Module::Install::Base';
1212 $ISCORE = 1;
1313 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '1.01';
8 $VERSION = '1.02';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
169169 # Normalize the version
170170 $version = $self->_perl_version($version);
171171
172 # We don't support the reall old versions
172 # We don't support the really old versions
173173 unless ( $version >= 5.005 ) {
174174 die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n";
175175 }
581581 sub requires_from {
582582 my $self = shift;
583583 my $content = Module::Install::_readperl($_[0]);
584 my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg;
584 my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+(v?[\d\.]+)/mg;
585585 while ( @requires ) {
586586 my $module = shift @requires;
587587 my $version = shift @requires;
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '1.01';
8 $VERSION = '1.02';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '1.01';
8 $VERSION = '1.02';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '1.01';
8 $VERSION = '1.02';
99 @ISA = qw{Module::Install::Base};
1010 $ISCORE = 1;
1111 }
3030 # This is not enforced yet, but will be some time in the next few
3131 # releases once we can make sure it won't clash with custom
3232 # Module::Install extensions.
33 $VERSION = '1.01';
33 $VERSION = '1.02';
3434
3535 # Storage for the pseudo-singleton
3636 $MAIN = undef;
1111 'logger' => 'Stderr',
1212 'logfacility' => 'LOG_USER',
1313 'delaytime' => 3600,
14 'backend-collect-timeout' => 180,
14 'backend-collect-timeout' => 30,
1515 'httpd-port' => 62354,
1616 };
1717
3333 $self->{ua}->default_header('Content-type' => 'application/x-compress');
3434 $self->{logger}->debug(
3535 $log_prefix .
36 'Using gzip for compression (server minimal version 1.02 needed)'
36 'Using gzip for compression'
3737 );
3838 } else {
3939 $self->{compression} = 'none';
4040 $self->{logger}->debug(
4141 $log_prefix .
42 'Not using compression (server minimal version 1.02 needed)'
42 'Not using compression'
4343 );
4444 }
4545
120120 if ($data =~ /(\x78\x9C.*)/s) {
121121 $self->{logger}->debug2("format: Zlib");
122122 return $self->_uncompressNative($1);
123 } elsif ($data =~ /(\x1F\x8B\x08\x08.*)/s) {
123 } elsif ($data =~ /(\x1F\x8B\x08.*)/s) {
124124 $self->{logger}->debug2("format: Gzip");
125125 return $self->_uncompressGzip($1);
126126 } elsif ($data =~ /(<html><\/html>|)[^<]*(<.*>)\s*$/s) {
3434 bless $self, $class;
3535
3636 # create user agent
37 $self->{ua} = LWP::UserAgent->new(keep_alive => 1, requests_redirectable => ['POST', 'GET', 'HEAD']);
37 $self->{ua} = LWP::UserAgent->new(
38 parse_head => 0, # No need to parse HTML
39 keep_alive => 1,
40 requests_redirectable => ['POST', 'GET', 'HEAD']
41 );
3842
3943 if ($params{proxy}) {
4044 $self->{ua}->proxy(['http', 'https'], $params{proxy});
4953 }
5054
5155 sub request {
52 my ($self, $request) = @_;
56 my ($self, $request, $file) = @_;
5357
5458 my $logger = $self->{logger};
5559
6266 if ($OSNAME eq 'MSWin32' && $scheme eq 'https') {
6367 alarm $self->{timeout};
6468 }
65 $result = $self->{ua}->request($request);
69 $result = $self->{ua}->request($request, $file);
6670 alarm 0;
6771 };
6872
9296 if ($OSNAME eq 'MSWin32' && $scheme eq 'https') {
9397 alarm $self->{timeout};
9498 }
95 $result = $self->{ua}->request($request);
99 $result = $self->{ua}->request($request, $file);
96100 alarm 0;
97101 };
98102 if (!$result->is_success()) {
22 use strict;
33 use warnings;
44 use threads;
5 use threads::shared;
56
67 use English qw(-no_match_vars);
78 use HTTP::Daemon;
1718 my ($class, %params) = @_;
1819
1920 my $self = {
20 logger => $params{logger} ||
21 FusionInventory::Agent::Logger->new(),
22 agent => $params{agent},
23 scheduler => $params{scheduler},
24 htmldir => $params{htmldir},
25 ip => $params{ip},
26 port => $params{port} || 62354,
27 trust => $params{trust}
28
21 logger => $params{logger} ||
22 FusionInventory::Agent::Logger->new(),
23 agent => $params{agent},
24 scheduler => $params{scheduler},
25 htmldir => $params{htmldir},
26 ip => $params{ip},
27 port => $params{port} || 62354,
28 trust => $params{trust}
2929 };
3030 bless $self, $class;
3131
32 $SIG{PIPE} = 'IGNORE';
32 $self->{stop} = 0;
33 my $stop = \$self->{stop};
34 threads::shared::share($stop);
3335 $self->{listener} = threads->create('_listen', $self);
3436
3537 return $self;
3941 my ($self, $client, $request, $clientIp) = @_;
4042
4143 my $logger = $self->{logger};
42 my $scheduler = $self->{scheduler};
43 my $htmldir = $self->{htmldir};
4444
4545 if (!$request) {
4646 $client->close();
6464 SWITCH: {
6565 # root request
6666 if ($path eq '/') {
67
68 my $template = Text::Template->new(
69 TYPE => 'FILE', SOURCE => "$self->{htmldir}/index.tpl"
70 );
71 if (!$template) {
72 $logger->error($log_prefix . "Template access failed: $Text::Template::ERROR");
73 ;
74
75 my $response = HTTP::Response->new(
76 500,
77 'KO',
78 HTTP::Headers->new('Content-Type' => 'text/html'),
79 "No template"
80 );
81
82 $client->send_response($response);
83 return;
84 }
85
86 my $hash = {
87 version => $FusionInventory::Agent::VERSION,
88 trust => $self->_is_trusted($clientIp),
89 status => $self->{agent}->getStatus(),
90 targets => [
91 map { $_->getStatus() } $self->{scheduler}->getTargets()
92 ]
93 };
94
95 my $response = HTTP::Response->new(
96 200,
97 'OK',
98 HTTP::Headers->new('Content-Type' => 'text/html'),
99 $template->fill_in(HASH => $hash)
100 );
101
102 $client->send_response($response);
103
67 $self->_handle_root($client, $request, $clientIp);
10468 last SWITCH;
10569 }
10670
10771 # deploy request
10872 if ($path =~ m{^/deploy/getFile/./../([\w\d/-]+)$}) {
109 File::Find->require;
110 my $sha512 = $1;
111 my $filePath;
112 foreach my $target (@{$self->{scheduler}{targets}}) {
113 my $file;
114 my $shareDir = $target->{storage}{directory}."/deploy/fileparts/shared";
115 next unless -d $shareDir;
116 File::Find::find({
117 wanted => sub {
118 return unless -f;
119 return unless basename($_) eq $sha512;
120 Digest::SHA->require;
121 my $sha = Digest::SHA->new('512');
122 $sha->addfile($File::Find::name, 'b');
123
124 if ($sha->hexdigest eq $sha512) {
125 $filePath = $File::Find::name;
126 return;
127 }
128 },
129 no_chdir => 1
130 }, $shareDir);
131 last if $filePath;
132 }
133 if ($filePath && -f $filePath) {
134 $logger->debug($log_prefix . "file $sha512 not found");
135 $client->send_file_response("$filePath");
136 $logger->debug($log_prefix . "file $filePath sent");
137 } else {
138 $client->send_error(404);
139 }
73 $self->_handle_deploy($client, $request, $clientIp, $1);
14074 last SWITCH;
14175 }
14276
14377 # now request
14478 if ($path =~ m{^/now(?:/(\S+))?$}) {
145 my $token = $1;
146
147 my ($code, $message, $trace);
148 if (
149 $self->_is_trusted($clientIp) ||
150 $self->_is_authenticated($token)
151 ) {
152 foreach my $target ($scheduler->getTargets()) {
153 $target->setNextRunDate(1);
154 }
155 $self->{agent}->resetToken();
156 $code = 200;
157 $message = "OK";
158 $trace = "valid request, forcing execution right now";
159 } else {
160 $code = 403;
161 $message = "Access denied";
162 $trace = "invalid request (bad token or bad address)";
163 }
164
165 my $template = Text::Template->new(
166 TYPE => 'FILE', SOURCE => "$self->{htmldir}/now.tpl"
167 );
168
169 my $hash = {
170 message => $message
171 };
172
173 my $response = HTTP::Response->new(
174 $code,
175 'OK',
176 HTTP::Headers->new('Content-Type' => 'text/html'),
177 $template->fill_in(HASH => $hash)
178 );
179
180 $client->send_response($response);
181 $logger->debug($log_prefix . $trace);
182
79 $self->_handle_now($client, $request, $clientIp, $1);
18380 last SWITCH;
18481 }
18582
18683 # status request
18784 if ($path eq '/status') {
188 my $status = $self->{agent}->getStatus();
189 my $response = HTTP::Response->new(
190 200,
191 'OK',
192 HTTP::Headers->new('Content-Type' => 'text/plain'),
193 "status: ".$status
194 );
195 $client->send_response($response);
85 $self->_handle_status($client, $request, $clientIp);
19686 last SWITCH;
19787 }
19888
19989 # static content request
20090 if ($path =~ m{^/(logo.png|site.css|favicon.ico)$}) {
20191 my $file = $1;
202 $client->send_file_response("$htmldir/$file");
92 $client->send_file_response("$self->{htmldir}/$file");
20393 last SWITCH;
20494 }
20595
20898 }
20999
210100 $client->close();
101 }
102
103 sub _handle_root {
104 my ($self, $client, $request, $clientIp) = @_;
105
106 my $logger = $self->{logger};
107
108 my $template = Text::Template->new(
109 TYPE => 'FILE', SOURCE => "$self->{htmldir}/index.tpl"
110 );
111 if (!$template) {
112 $logger->error($log_prefix . "Template access failed: $Text::Template::ERROR");
113 ;
114
115 my $response = HTTP::Response->new(
116 500,
117 'KO',
118 HTTP::Headers->new('Content-Type' => 'text/html'),
119 "No template"
120 );
121
122 $client->send_response($response);
123 return;
124 }
125
126 my $hash = {
127 version => $FusionInventory::Agent::VERSION,
128 trust => $self->_is_trusted($clientIp),
129 status => $self->{agent}->getStatus(),
130 targets => [
131 map { $_->getStatus() } $self->{scheduler}->getTargets()
132 ]
133 };
134
135 my $response = HTTP::Response->new(
136 200,
137 'OK',
138 HTTP::Headers->new('Content-Type' => 'text/html'),
139 $template->fill_in(HASH => $hash)
140 );
141
142 $client->send_response($response);
143 }
144
145 sub _handle_deploy {
146 my ($self, $client, $request, $clientIp, $sha512) = @_;
147
148 my $logger = $self->{logger};
149
150 return unless $sha512 =~ /^..(.{6})/;
151 my $name = $1;
152 my $path;
153
154 File::Find->require();
155 Digest::SHA->require();
156
157 foreach my $target ($self->{scheduler}->getTargets()) {
158 my $shareDir = $target->{storage}->getDirectory()."/deploy/fileparts/shared";
159 next unless -d $shareDir;
160
161 my $wanted = sub {
162 return unless -f $_;
163 return unless basename($_) eq $name;
164
165 my $sha = Digest::SHA->new('512');
166 $sha->addfile($File::Find::name, 'b');
167 return unless $sha->hexdigest eq $sha512;
168
169 $path = $File::Find::name;
170 };
171 File::Find::find({ wanted => $wanted, no_chdir => 1 }, $shareDir);
172 last if $path;
173 }
174 if ($path) {
175 $logger->debug($log_prefix . "file $sha512 found");
176 $client->send_file_response($path);
177 $logger->debug($log_prefix . "file $path sent");
178 } else {
179 $client->send_error(404);
180 }
181 }
182
183 sub _handle_now {
184 my ($self, $client, $request, $clientIp, $token) = @_;
185
186 my $logger = $self->{logger};
187
188 my ($code, $message, $trace);
189 if (
190 $self->_is_trusted($clientIp) ||
191 $self->_is_authenticated($token)
192 ) {
193 foreach my $target ($self->{scheduler}->getTargets()) {
194 $target->setNextRunDate(1);
195 }
196 $self->{agent}->resetToken();
197 $code = 200;
198 $message = "OK";
199 $trace = "valid request, forcing execution right now";
200 } else {
201 $code = 403;
202 $message = "Access denied";
203 $trace = "invalid request (bad token or bad address)";
204 }
205
206 my $template = Text::Template->new(
207 TYPE => 'FILE', SOURCE => "$self->{htmldir}/now.tpl"
208 );
209
210 my $hash = {
211 message => $message
212 };
213
214 my $response = HTTP::Response->new(
215 $code,
216 'OK',
217 HTTP::Headers->new('Content-Type' => 'text/html'),
218 $template->fill_in(HASH => $hash)
219 );
220
221 $client->send_response($response);
222 $logger->debug($log_prefix . $trace);
223 }
224
225 sub _handle_status {
226 my ($self, $client, $request, $clientIp) = @_;
227
228 my $status = $self->{agent}->getStatus();
229 my $response = HTTP::Response->new(
230 200,
231 'OK',
232 HTTP::Headers->new('Content-Type' => 'text/plain'),
233 "status: ".$status
234 );
235 $client->send_response($response);
211236 }
212237
213238 sub _is_trusted {
256281
257282 $logger->info($log_prefix . "HTTPD service started at $url");
258283
259 # allow the thread to be stopped
260 threads->set_thread_exit_only(1);
261 $SIG{'KILL'} = sub { threads->exit(); };
262
263284 while (1) {
264285 my ($client, $socket) = $daemon->accept();
286 last if $self->{stop};
265287 next unless $socket;
266288 my (undef, $iaddr) = sockaddr_in($socket);
267289 my $clientIp = inet_ntoa($iaddr);
270292 }
271293 }
272294
295 sub terminate {
296 my ($self) = @_;
297
298 lock $self->{stop};
299 $self->{stop} = 1;
300 }
301
273302 sub DESTROY {
274303 my ($self) = @_;
275304
277306
278307 if ($self->{listener}->is_joinable()) {
279308 $self->{listener}->join();
280 } else {
281 $self->{listener}->kill('KILL')->detach();
309 } elsif (!$self->{listener}->is_detached()) {
310 $self->{listener}->detach();
282311 }
283312 }
284313
+0
-253
lib/FusionInventory/Agent/SNMP.pm less more
0 package FusionInventory::Agent::SNMP;
1
2 use strict;
3 use warnings;
4
5 use Encode qw(encode);
6 use English qw(-no_match_vars);
7 use Net::SNMP;
8
9 use FusionInventory::Agent::Tools;
10 use FusionInventory::Agent::Tools::Network;
11
12 my @bad_oids = qw(
13 .1.3.6.1.2.1.2.2.1.6
14 .1.3.6.1.2.1.4.22.1.2
15 .1.3.6.1.2.1.17.1.1.0
16 .1.3.6.1.2.1.17.4.3.1.1
17 .1.3.6.1.4.1.9.9.23.1.2.1.1.4
18 );
19 my $bad_oids_pattern = '^(' . join('|', map { quotemeta($_) } @bad_oids) . ')';
20
21 sub new {
22 my ($class, %params) = @_;
23
24 die "no hostname parameters" unless $params{hostname};
25
26 my $version =
27 ! $params{version} ? 'snmpv1' :
28 $params{version} eq '1' ? 'snmpv1' :
29 $params{version} eq '2c' ? 'snmpv2c' :
30 $params{version} eq '3' ? 'snmpv3' :
31 undef ;
32
33 die "invalid SNMP version $params{version}" unless $version;
34
35 my $self = {};
36
37 my $error;
38 if ($version eq 'snmpv3') {
39 ($self->{session}, $error) = Net::SNMP->session(
40 -timeout => 1,
41 -retries => 0,
42 -version => $version,
43 -hostname => $params{hostname},
44 -username => $params{username},
45 -authpassword => $params{authpassword},
46 -authprotocol => $params{authprotocol},
47 -privpassword => $params{privpassword},
48 -privprotocol => $params{privprotocol},
49 );
50 } else { # snmpv2c && snmpv1 #
51 ($self->{session}, $error) = Net::SNMP->session(
52 -timeout => 1,
53 -retries => 0,
54 -version => $version,
55 -hostname => $params{hostname},
56 -community => $params{community},
57 );
58 }
59
60 die $error unless $self->{session};
61
62 bless $self, $class;
63
64 return $self;
65 }
66
67 sub get {
68 my ($self, $oid) = @_;
69
70 return unless $oid;
71
72 my $session = $self->{session};
73
74 my $response = $session->get_request(
75 -varbindlist => [$oid]
76 );
77
78 return unless $response;
79
80 return if $response->{$oid} =~ /noSuchInstance/;
81 return if $response->{$oid} =~ /noSuchObject/;
82
83 my $value = $response->{$oid};
84 chomp $value;
85
86 return $value;
87 }
88
89 sub walk {
90 my ($self, $oid) = @_;
91
92 return unless $oid;
93
94 my $session = $self->{session};
95
96 my $response = $session->get_table(
97 -baseoid => $oid
98 );
99
100 return unless $response;
101
102 my $values;
103
104 foreach my $oid (keys %{$response}) {
105 my $value = $response->{$oid};
106 chomp $value;
107 $values->{$oid} = $value;
108 }
109
110 return $values;
111 }
112
113 sub getMacAddress {
114 my ($self, $oid) = @_;
115
116 my $value = $self->get($oid);
117 return unless $value;
118
119 if ($oid =~ /$bad_oids_pattern/) {
120 $value = _sanitizeMacAddress($value);
121 }
122
123 $value = alt2canonical($value);
124
125 return $value;
126 }
127
128 sub walkMacAddresses {
129 my ($self, $oid) = @_;
130
131 my $values = $self->walk($oid);
132 return unless $values;
133
134 if ($oid =~ /$bad_oids_pattern/) {
135 foreach my $value (values %$values) {
136 $value = _sanitizeMacAddress($value);
137 }
138 }
139
140 foreach my $value (values %$values) {
141 $value = alt2canonical($value);
142 }
143
144 return $values;
145 }
146
147 sub _sanitizeMacAddress {
148 my ($value) = @_;
149
150 if ($value !~ /^0x/) {
151 # convert from binary to hexadecimal
152 $value = unpack 'H*', $value;
153 } else {
154 # drop hex prefix
155 $value =~ s/^0x//;
156 }
157
158 return $value;
159 }
160
161
162 sub getSerial {
163 my ($self, $oid) = @_;
164
165 my $value = $self->get($oid);
166 return unless $value;
167
168 $value =~ s/\n//g;
169 $value =~ s/\r//g;
170 $value =~ s/^\s+//;
171 $value =~ s/\s+$//;
172 $value =~ s/\.{2,}//g;
173
174 return $value;
175 }
176
177 1;
178 __END__
179
180 =head1 NAME
181
182 FusionInventory::Agent::SNMP - An SNMP query extension
183
184 =head1 DESCRIPTION
185
186 This is the object used by the agent to perform SNMP queries.
187
188 =head1 METHODS
189
190 =head2 new(%params)
191
192 The constructor. The following parameters are allowed, as keys of the %params
193 hash:
194
195 =over
196
197 =item version (mandatory)
198
199 Can be one of:
200
201 =over
202
203 =item '1'
204
205 =item '2c'
206
207 =item '3'
208
209 =back
210
211 =item hostname (mandatory)
212
213 =item community
214
215 =item username
216
217 =item authpassword
218
219 =item authprotocol
220
221 =item privpassword
222
223 =item privprotocol
224
225 =back
226
227 =head2 get($oid)
228
229 This method returns a single value, corresponding to a single OID. The value is
230 normalised to remove any control character, and hexadecimal mac addresses are
231 translated into plain ascii.
232
233 =head2 walk($oid)
234
235 This method returns an hashref of values, indexed by their OIDs, starting from
236 the given one. The values are normalised to remove any control character, and
237 hexadecimal mac addresses are translated into plain ascii.
238
239 =head2 getSerial($oid)
240
241 Wraps get($oid), assuming the value is a serial number and sanitizing it
242 accordingly.
243
244 =head2 getMacAddress($oid)
245
246 Wraps get($oid), assuming the value is a mac address and sanitizing it
247 accordingly.
248
249 =head2 walkMacAddresses($oid)
250
251 Wraps walk($oid), assuming the values are mac addresses and sanitizing them
252 accordingly.
1313 die 'no basevardir parameter' unless $params{basevardir};
1414
1515 my $self = {
16 logger => $params{logger} ||
17 FusionInventory::Agent::Logger->new(),
18 maxDelay => $params{maxDelay} || 3600,
16 logger => $params{logger} ||
17 FusionInventory::Agent::Logger->new(),
18 maxDelay => $params{maxDelay} || 3600,
19 initialDelay => $params{delaytime},
1920 };
2021 bless $self, $class;
2122
3839 # handle persistent state
3940 $self->_loadState();
4041
41 $self->{nextRunDate} = _computeNextRunDate($self->{maxDelay})
42 $self->{nextRunDate} = $self->_computeNextRunDate()
4243 if !$self->{nextRunDate};
4344
4445 $self->_saveState();
8182 my ($self) = @_;
8283
8384 lock($self->{nextRunDate}) if $self->{shared};
84 $self->{nextRunDate} = _computeNextRunDate($self->{maxDelay});
85 $self->{nextRunDate} = $self->_computeNextRunDate();
8586 $self->_saveState();
8687 }
8788
116117 # compute a run date, as current date and a random delay
117118 # between maxDelay / 2 and maxDelay
118119 sub _computeNextRunDate {
119 my ($maxDelay) = @_;
120
121 return
122 time +
123 $maxDelay / 2 +
124 int rand($maxDelay / 2);
120 my ($self) = @_;
121
122 my $ret;
123 if ($self->{initialDelay}) {
124 $ret = time + $self->{initialDelay};
125 $self->{initialDelay} = undef;
126 } else {
127 $ret =
128 time +
129 $self->{maxDelay} / 2 +
130 int rand($self->{maxDelay} / 2);
131 }
132
133 return $ret;
125134 }
126135
127136 sub _loadState {
1919 my $logger = $params{logger};
2020
2121 my $command = 'pkg_info';
22 my $packages = _getPackagesFromPkgInfo(
22 my $packages = _getPackagesListFromPkgInfo(
2323 logger => $logger, command => $command
2424 );
2525
4040 push @packages, {
4141 NAME => $1,
4242 VERSION => $2,
43 VERSION => $3
43 DESCRIPTION => $3
4444 };
4545 }
4646
101101
102102 my ($vendor_id, $device_id, $class_id);
103103 while (my $line = <$handle>) {
104 next if $line =~ /^#/;
105104
106 if ($line =~ /^(\S{4}) \s+ (.*)/x) {
107 # Vendor ID
108 $vendor_id = $1;
109 $vendors->{$vendor_id}->{name} = $2;
110 } elsif ($line =~ /^\t (\S{4}) \s+ (.*)/x) {
105 if ($line =~ /^\t (\S{4}) \s+ (.*)/x) {
111106 # Device ID
112107 $device_id = $1;
113108 $vendors->{$vendor_id}->{devices}->{$device_id}->{name} = $2;
115110 # Subdevice ID
116111 my $subdevice_id = "$1:$2";
117112 $vendors->{$vendor_id}->{devices}->{$device_id}->{subdevices}->{$subdevice_id}->{name} = $3;
113 } elsif ($line =~ /^(\S{4}) \s+ (.*)/x) {
114 # Vendor ID
115 $vendor_id = $1;
116 $vendors->{$vendor_id}->{name} = $2;
118117 } elsif ($line =~ /^C \s+ (\S{2}) \s+ (.*)/x) {
119118 # Class ID
120119 $class_id = $1;
2020 pattern => qr/Description:\s+(.+)/
2121 );
2222
23 # See: #1262
24 $release =~ s/^Enterprise Linux Enterprise Linux/Oracle Linux/;
25
2326 my $linuxDistributionName;
2427 my $linuxDistributionVersion;
2528 # Redirect stderr to /dev/null to avoid "No LSB modules are available" message
55 use FusionInventory::Agent::Tools;
66 use FusionInventory::Agent::Tools::Network;
77 use FusionInventory::Agent::Tools::Unix;
8 use FusionInventory::Agent::Tools::Linux;
89
910 sub isEnabled {
1011 return
4950 my $routes = $params{routes};
5051
5152 my @interfaces = canRun("/sbin/ip") ?
52 _parseIpAddrShow(command => '/sbin/ip addr show', logger => $logger):
53 _parseIfconfig(command => '/sbin/ifconfig -a', logger => $logger);
53 getInterfacesFromIp(logger => $logger):
54 getInterfacesFromIfconfig(logger => $logger);
5455
5556 foreach my $interface (@interfaces) {
5657 if (_isWifi($logger, $interface->{DESCRIPTION})) {
9192 }
9293 }
9394 }
94
95 return @interfaces;
96 }
97
98 sub _parseIfconfig {
99 my $handle = getFileHandle(@_);
100 return unless $handle;
101
102 my @interfaces;
103 my $interface;
104
105 while (my $line = <$handle>) {
106 if ($line =~ /^$/) {
107 # end of interface section
108 push @interfaces, $interface if $interface;
109 next;
110 }
111
112 if ($line =~ /^(\S+)/) {
113 # new interface
114 $interface = {
115 STATUS => 'Down',
116 DESCRIPTION => $1
117 }
118 }
119 if ($line =~ /inet addr:($ip_address_pattern)/i) {
120 $interface->{IPADDRESS} = $1;
121 }
122 if ($line =~ /Mask:($ip_address_pattern)/) {
123 $interface->{IPMASK} = $1;
124 }
125 if ($line =~ /inet6 addr: (\S+)/i) {
126 $interface->{IPADDRESS6} = $1;
127 }
128 if ($line =~ /hwadd?r\s+($mac_address_pattern)/i) {
129 $interface->{MACADDR} = $1;
130 }
131 if ($line =~ /^\s+UP\s/) {
132 $interface->{STATUS} = 'Up';
133 }
134 if ($line =~ /link encap:(\S+)/i) {
135 $interface->{TYPE} = $1;
136 }
137
138 }
139 close $handle;
14095
14196 return @interfaces;
14297 }
212167 return ($driver, $pcislot);
213168 }
214169
215
216 # http://forge.fusioninventory.org/issues/854
217 sub _parseIpAddrShow {
218 my $handle = getFileHandle(@_);
219 return unless $handle;
220
221 my @entries;
222 my $entry;
223 while (my $line = <$handle>) {
224 chomp $line;
225 if ($line =~ /^\d+:\s+(\S+): .*(UP|DOWN)/) {
226 push @entries, $entry if $entry;
227 $entry = {};
228 $entry->{DESCRIPTION} = $1;
229 $entry->{STATUS} = ucfirst(lc($2));
230 } elsif ($line =~ /link\/ether ($mac_address_pattern)/) {
231 $entry->{MACADDR} = $1;
232 } elsif ($line =~ /inet6 (\S+)\//) {
233 $entry->{IPADDRESS6} = $1;
234 } elsif ($line =~ /inet ($ip_address_pattern)\/(\d{1,3})/) {
235 $entry->{IPADDRESS} = $1;
236 $entry->{IPMASK} = getNetworkMask($1, $2);
237 $entry->{IPSUBNET} = getSubnetAddress(
238 $entry->{IPADDRESS}, $entry->{IPMASK}
239 );
240 }
241 }
242
243 return @entries;
244 }
245
246170 1;
66
77 use FusionInventory::Agent::Tools;
88 use FusionInventory::Agent::Tools::Network;
9 use FusionInventory::Agent::Tools::Unix;
910
1011 sub isEnabled {
1112 return canRun('ifconfig');
44
55 use FusionInventory::Agent::Tools;
66 use FusionInventory::Agent::Tools::MacOS;
7
78 sub isEnabled {
89 return
910 -r '/usr/sbin/system_profiler'
1011 }
1112
13 sub doInventory {
14 my (%params) = @_;
15
16 my $inventory = $params{inventory};
17
18 my %displays = _getDisplays();
19 foreach my $section (keys %displays ) {
20 foreach my $entry (@{$displays{$section}}) {
21 $inventory->addEntry(
22 section => $section,
23 entry => $entry,
24 );
25 }
26 }
27 }
1228
1329 sub _getDisplays {
1430 my $infos = getSystemProfilerInfos(@_);
2137
2238 my $displays = {};
2339 foreach my $displayName (keys %{$videoCardInfo->{Displays}}) {
24 next if $displayName =~ /^Display Connector$/;
25 next if $displayName =~ /^Display$/;
40 next if $displayName eq 'Display Connector';
41 next if $displayName eq 'Display';
2642 my $displayInfo = $videoCardInfo->{Displays}{$displayName};
27
2843
2944 my $resolution = $displayInfo->{Resolution};
3045 if ($resolution) {
3550 my $memory = $videoCardInfo->{'VRAM (Total)'};
3651 $memory =~ s/\ .*//g if $memory;
3752
38
39
40 # use Data::Dumper;
41 # print "display-BEGIN-\n";
42 # print Dumper($displayInfo);
43 # print "display-END-\n";
44 # print "video-BEGIN-\n";
45 # print Dumper($videoCardInfo);
46 # print "video-END-\n";
47
48
49
5053 push @$videos, {
51 CHIPSET => $videoCardInfo->{'Chipset Model'},
52 MEMORY => $memory,
53 NAME => $videoName,
54 CHIPSET => $videoCardInfo->{'Chipset Model'},
55 MEMORY => $memory,
56 NAME => $videoName,
5457 RESOLUTION => $resolution,
55 PCISLOT => $videoCardInfo->{Slot}
58 PCISLOT => $videoCardInfo->{Slot}
5659 };
5760
5861 push @$monitors, {
59 CAPTION => $displayName,
62 CAPTION => $displayName,
6063 DESCRIPTION => $displayName,
61 MANUFACTURER => '',
62 SERIAL => '',
6364 }
6465 }
6566 }
6667
6768 return (
6869 MONITORS => $monitors,
69 VIDEOS => $videos
70 VIDEOS => $videos
7071 );
7172
7273 }
7374
74 sub doInventory {
75 my (%params) = @_;
76
77 my $inventory = $params{inventory};
78
79 my %displays = _getDisplays();
80 foreach my $section (keys %displays ) {
81 foreach (@{$displays{$section}}) {
82 $inventory->addEntry(
83 section => $section,
84 entry => $_,
85 );
86 }
87 }
88 }
8975
9076 1;
1818 my $class = getClass();
1919
2020 my ($count, $cpu) =
21 $class == 7 ? _getCPUFromPrtcl(logger => $logger) :
22 _getCPUFromMemconf(logger => $logger);
21 $class == SOLARIS_CONTAINER ?
22 _getCPUFromPrtcl(logger => $logger) :
23 _getCPUFromMemconf(logger => $logger);
2324
2425 # fallback on generic method
2526 if (!$count) {
1414 command => "df --version"
1515 );
1616
17 return $line =~ /GNU/ ?
17 # df --help is on STDERR on some system
18 # so $line is undef
19 return ($line && $line =~ /GNU/) ?
1820 "df -P -k" :
1921 "df -k";
2022 }
4850 command => "zfs get org.opensolaris.libbe:uuid $filesystem->{VOLUMN}"
4951 );
5052
51 if ($line =~ /org.opensolaris.libbe:uuid\s+(\S{5}\S+)/) {
53 if ($line && $line =~ /org.opensolaris.libbe:uuid\s+(\S{5}\S+)/) {
5254 $filesystem->{UUID} = $1;
5355 $filesystem->{FILESYSTEM} = 'zfs';
5456 next;
2323 }
2424
2525 my @memories =
26 $class == 1 ? _getMemories1() :
27 $class == 2 ? _getMemories2() :
28 $class == 3 ? _getMemories3() :
29 $class == 4 ? _getMemories4() :
30 $class == 5 ? _getMemories5() :
31 $class == 6 ? _getMemories6() :
32 $class == 7 ? _getMemories7() :
33 () ;
26 $class == SOLARIS_FIRE ? _getMemories1() :
27 $class == SOLARIS_FIRE_V ? _getMemories2() :
28 $class == SOLARIS_FIRE_T ? _getMemories3() :
29 $class == SOLARIS_ENTERPRISE_T ? _getMemories4() :
30 $class == SOLARIS_ENTERPRISE ? _getMemories5() :
31 $class == SOLARIS_I86PC ? _getMemories6() :
32 $class == SOLARIS_CONTAINER ? _getMemories7() :
33 () ;
3434
3535 foreach my $memory (@memories) {
3636 $inventory->addEntry(
1818 my $class = getClass();
1919
2020 my @slots =
21 $class == 4 ? _getSlots4(logger => $logger, command => 'prtdiag') :
22 $class == 5 ? _getSlots5(logger => $logger, command => 'prtdiag') :
23 _getSlotsDefault(logger => $logger, command => 'prtdiag') ;
21 $class == SOLARIS_ENTERPRISE_T ? _getSlots4(logger => $logger) :
22 $class == SOLARIS_ENTERPRISE ? _getSlots5(logger => $logger) :
23 _getSlotsDefault(logger => $logger) ;
2424
2525 foreach my $slot (@slots) {
2626 $inventory->addEntry(
3131 }
3232
3333 sub _getSlots4 {
34 my %params = (
35 command => 'prtdiag',
36 @_
37 );
3438
35 my $handle = getFileHandle(@_);
39 my $handle = getFileHandle(%params);
3640 return unless $handle;
3741
3842 my @slots;
5256 }
5357
5458 sub _getSlots5 {
59 my %params = (
60 command => 'prtdiag',
61 @_
62 );
5563
56 my $handle = getFileHandle(@_);
64 my $handle = getFileHandle(%params);
5765 return unless $handle;
5866
5967 my @slots;
98106 }
99107
100108 sub _getSlotsDefault {
109 my %params = (
110 command => 'prtdiag',
111 @_
112 );
101113
102 my $handle = getFileHandle(@_);
114 my $handle = getFileHandle(%params);
103115 return unless $handle;
104116
105117 my @slots;
77 use FusionInventory::Agent::Tools::Unix;
88
99 sub isEnabled {
10 # Avoid duplicated entry with libvirt
11 return if can_run('virsh');
12
1013 return
1114 canRun('qemu') ||
1215 canRun('kvm') ||
33 use warnings;
44
55 use English qw(-no_match_vars);
6 use File::Basename;
7 use File::Glob qw(:glob);
6 use User::pwent;
87
98 use FusionInventory::Agent::Tools;
109
2625 my $logger = $params{logger};
2726 my $scanhomedirs = $params{scan_homedirs};
2827
29 my $cmd_list_vms = "VBoxManage -nologo list --long vms";
28 my $command = "VBoxManage -nologo list --long vms";
3029
31 my $owner;
32 if ( $REAL_USER_ID != 0 ) {
33 $owner = getpwuid $REAL_USER_ID;
34 }
30 my $owner = getpwuid($REAL_USER_ID)->name();
3531
36 foreach my $machine (_parseVBoxManage(logger => $logger, command => $cmd_list_vms)) {
32 foreach my $machine (_parseVBoxManage(
33 logger => $logger, command => $command
34 )) {
3735 $machine->{OWNER} = $owner;
3836 $inventory->addEntry(
3937 section => 'VIRTUALMACHINES', entry => $machine
4038 );
4139 }
4240
41 return unless $scanhomedirs == 1 && $REAL_USER_ID == 0;
4342
44 # If home directories scan is authorized
45 if ($scanhomedirs == 1 && $REAL_USER_ID == 0) {
46 my $homeDir = "/home";
43 # assume all system users with a suitable homedir is an actual human user
44 my $pattern = $OSNAME eq 'darwin' ?
45 qr{^/Users} : qr{^/home};
4746
48 if ($OSNAME eq 'darwin') {
49 $homeDir = "/Users";
50 }
51 my @homeDirlist = glob("$homeDir/*");
52 return if @homeDirlist > 10; # To many users, ignored.
53 foreach (@homeDirlist) {
54 my $login = basename($_);
55 next unless getpwnam ($login); # Invalid account
56 my $cmd_list_vms = "su \"$login\" -c \"VBoxManage -nologo list --long vms\"";
57 foreach my $machine (_parseVBoxManage(logger => $logger, command => $cmd_list_vms)) {
58 $machine->{OWNER} = $login;
59 $inventory->addEntry(
60 section => 'VIRTUALMACHINES', entry => $machine
61 );
62 }
47 my @users;
48 while (my $user = getpwent()) {
49 next unless $user->dir() =~ /$pattern/;
50 push @users, $user->name();
51 }
6352
53 # abort if too many users
54 return if @users > 10;
55
56 foreach my $user (@users) {
57 my $command = "su '$user' -c 'VBoxManage -nologo list --long vms'";
58 foreach my $machine (_parseVBoxManage(
59 logger => $logger, command => $command
60 )) {
61 $machine->{OWNER} = $user;
62 $inventory->addEntry(
63 section => 'VIRTUALMACHINES', entry => $machine
64 );
6465 }
6566 }
6667 }
7677 chomp $line;
7778
7879 if ($line =~ m/^Name:\s+(.*)$/) {
79 # this is a little tricky, because USB devices also have a 'name'
80 # field, so let's use the 'index' field to disambiguate
80 # this is a little tricky, because USB devices also have a 'name'
81 # field, so let's use the 'index' field to disambiguate
8182 if (defined $index) {
8283 $index = undef;
8384 next;
8485 }
85 if ($machine) {
86 $machine->{VCPU} = 1;
87 $machine->{SUBSYSTEM} = 'Oracle VM VirtualBox';
88 $machine->{VMTYPE} = 'VirtualBox';
89 push @machines, $machine;
90 }
86 push @machines, $machine if $machine;
9187 $machine = {
92 NAME => $1
93 }
88 NAME => $1,
89 VCPU => 1,
90 SUBSYSTEM => 'Oracle VM VirtualBox',
91 VMTYPE => 'VirtualBox'
92 };
9493 } elsif ($line =~ m/^UUID:\s+(.+)/) {
9594 $machine->{UUID} = $1;
9695 } elsif ($line =~ m/^Memory size:\s+(.+)/ ) {
103102 }
104103 close $handle;
105104
106 # push last remaining machine
107 if ($machine) {
108 $machine->{VCPU} = 1;
109 $machine->{SUBSYSTEM} = 'Oracle VM VirtualBox';
110 $machine->{VMTYPE} = 'VirtualBox';
111 push @machines, $machine;
112 }
105 # push last remaining machine
106 push @machines, $machine if $machine;
113107
114108 return @machines;
115109 }
4747
4848 use FusionInventory::Agent::Tools;
4949 use FusionInventory::Agent::Tools::Solaris;
50
51 my @vmware_patterns = (
52 'VMware vmxnet virtual NIC driver',
53 'Vendor: VMware\s+Model: Virtual disk',
54 'Vendor: VMware,\s+Model: VMware Virtual ',
55 ': VMware Virtual IDE CDROM Drive'
56 );
57 my $vmware_pattern = _assemblePatterns(@vmware_patterns);
58
59 my @qemu_patterns = (
60 ' QEMUAPIC ',
61 'QEMU Virtual CPU',
62 ': QEMU HARDDISK,',
63 ': QEMU CD-ROM,'
64 );
65 my $qemu_pattern = _assemblePatterns(@qemu_patterns);
66
67 my @virtual_machine_patterns = (
68 ': Virtual HD,',
69 ': Virtual CD,'
70 );
71 my $virtual_machine_pattern = _assemblePatterns(@virtual_machine_patterns);
72
73 my @virtualbox_patterns = (
74 ' VBOXBIOS ',
75 ': VBOX HARDDISK,',
76 ': VBOX CD-ROM,',
77 );
78 my $virtualbox_pattern = _assemblePatterns(@virtualbox_patterns);
79
80 my @xen_patterns = (
81 'Hypervisor signature: xen',
82 'Xen virtual console successfully installed',
83 'Xen reported:',
84 'Xen: \d+ - \d+',
85 'xen-vbd: registered block device',
86 'ACPI: [A-Z]{4} \(v\d+\s+Xen ',
87 );
88 my $xen_pattern = _assemblePatterns(@xen_patterns);
89
90 my %module_patterns = (
91 '^vmxnet\s' => 'VMware',
92 '^xen_\w+front\s' => 'Xen',
93 );
5094
5195 sub isEnabled {
5296 return 1;
109153 }
110154 }
111155
112 # Parse loaded modules
113 my %modmap = (
114 '^vmxnet\s' => 'VMware',
115 '^xen_\w+front\s' => 'Xen',
116 );
156 my $result;
157
158 # loaded modules
117159
118160 if (-f '/proc/modules') {
119161 my $handle = getFileHandle(
120162 file => '/proc/modules',
121163 logger => $logger
122164 );
123 while (<$handle>) {
124 foreach my $str (keys %modmap) {
125 next unless /$str/;
126 close $handle;
127 return $modmap{$str};
165 while (my $line = <$handle>) {
166 foreach my $pattern (keys %module_patterns) {
167 next unless $line =~ /$pattern/;
168 $result = $module_patterns{$pattern};
169 last;
128170 }
129171 }
130172 close $handle;
131173 }
132
133 # Let's parse some logs & /proc files for well known strings
134 my %msgmap = (
135 'VMware vmxnet virtual NIC driver' => 'VMware',
136 'Vendor: VMware\s+Model: Virtual disk' => 'VMware',
137 'Vendor: VMware,\s+Model: VMware Virtual ' => 'VMware',
138 ': VMware Virtual IDE CDROM Drive' => 'VMware',
139
140 ' QEMUAPIC ' => 'QEMU',
141 'QEMU Virtual CPU' => 'QEMU',
142 ': QEMU HARDDISK,' => 'QEMU',
143 ': QEMU CD-ROM,' => 'QEMU',
144
145 ': Virtual HD,' => 'Virtual Machine',
146 ': Virtual CD,' => 'Virtual Machine',
147
148 ' VBOXBIOS ' => 'VirtualBox',
149 ': VBOX HARDDISK,' => 'VirtualBox',
150 ': VBOX CD-ROM,' => 'VirtualBox',
151
152 'Hypervisor signature: xen' => 'Xen',
153 'Xen virtual console successfully installed' => 'Xen',
154 'Xen reported:' => 'Xen',
155 'Xen: \d+ - \d+' => 'Xen',
156 'xen-vbd: registered block device' => 'Xen',
157 'ACPI: [A-Z]{4} \(v\d+\s+Xen ' => 'Xen',
158 );
174 return $result if $result;
175
176 # dmesg
159177
160178 if (-r '/var/log/dmesg') {
161 my $handle = getFileHandle(
162 file => '/var/log/dmesg',
163 logger => $logger
164 );
165 while (<$handle>) {
166 foreach my $str (keys %msgmap) {
167 next unless /$str/;
168 close $handle;
169 return $msgmap{$str};
170 }
171 }
172 close $handle;
173 }
174
175 # On OpenBSD, dmesg is in sbin
176 # http://forge.fusioninventory.org/issues/402
177 # TODO: we should remove the head call here
178 foreach my $dmesg (qw(/bin/dmesg /sbin/dmesg)) {
179 next unless -f $dmesg;
180 my $command = "$dmesg | head -n 750";
181
182 my $handle = getFileHandle(
183 command => $command,
184 logger => $logger,
185 );
186 while (<$handle>) {
187 foreach my $str (keys %msgmap) {
188 next unless /$str/;
189 close $handle;
190 return $msgmap{$str};
191 }
192 }
193 close $handle;
194 }
179 my $handle = getFileHandle(file => '/var/log/dmesg', logger => $logger);
180 $result = _matchPatterns($handle);
181 close $handle;
182 } elsif (-x '/bin/dmesg') {
183 my $handle = getFileHandle(command => '/bin/dmesg', logger => $logger);
184 $result = _matchPatterns($handle);
185 close $handle;
186 } elsif (-x '/sbin/dmesg') {
187 # On OpenBSD, dmesg is in sbin
188 # http://forge.fusioninventory.org/issues/402
189 my $handle = getFileHandle(command => '/sbin/dmesg', logger => $logger);
190 $result = _matchPatterns($handle);
191 close $handle;
192 }
193 return $result if $result;
194
195 # scsci
195196
196197 if (-f '/proc/scsi/scsi') {
197198 my $handle = getFileHandle(
198199 file => '/proc/scsi/scsi',
199200 logger => $logger
200201 );
201 while (<$handle>) {
202 foreach my $str (keys %msgmap) {
203 next unless /$str/;
204 close $handle;
205 return $msgmap{$str};
206 }
207 }
208 close $handle;
209 }
202 $result = _findPattern($handle);
203 close $handle;
204 }
205 return $result if $result;
210206
211207 return 'Physical';
212208 }
213209
210 sub _assemblePatterns {
211 my (@patterns) = @_;
212
213 my $pattern = '(?:' . join('|', @patterns) . ')';
214 return qr/$pattern/;
215 }
216
217 sub _matchPatterns {
218 my ($handle) = @_;
219
220 while (my $line = <$handle>) {
221 return 'VMware' if $line =~ $vmware_pattern;
222 return 'QEMU' if $line =~ $qemu_pattern;
223 return 'Virtual Machine' if $line =~ $virtual_machine_pattern;
224 return 'VirtualBox' if $line =~ $virtualbox_pattern;
225 return 'Xen' if $line =~ $xen_pattern;
226 }
227 }
228
214229 1;
2727
2828 my $bios = {
2929 BDATE => getRegistryValue(
30 path => "Hardware/Description/System/BIOS/BIOSReleaseDate",
30 path => "HKEY_LOCAL_MACHINE/Hardware/Description/System/BIOS/BIOSReleaseDate",
3131 logger => $logger
3232 )
3333 };
8383
8484 $inventory->setBios($bios);
8585
86 if ($bios->{VERSION} eq 'VirtualBox' || $bios->{MMODEL} eq 'VirtualBox') {
86 if (
87 ($bios->{VERSION} && ($bios->{VERSION} eq 'VirtualBox'))
88 ||
89 ($bios->{MMODEL} && ($bios->{MMODEL} eq 'VirtualBox'))
90 ) {
8791 $inventory->setHardware ({
8892 VMSYSTEM => 'VirtualBox'
8993 });
8282
8383 $nics = $WMIService->ExecQuery('SELECT * FROM Win32_NetworkAdapter');
8484 foreach my $nic (in $nics) {
85 my $interface = {};
8685 # http://comments.gmane.org/gmane.comp.monitoring.fusion-inventory.devel/34
8786 next unless $nic->PNPDeviceID;
8887
89 my $virtualdev = 0;
88 my $interface = {
89 SPEED => $nic->Speed,
90 MACADDR => $nic->MACAddress,
91 PNPDEVICEID => $nic->PNPDeviceID,
92 };
93
9094 # PhysicalAdapter only work on OS > XP
91 if (!defined($nic->PhysicalAdapter)) {
92 if ($nic->PNPDeviceID =~ /^ROOT/) {
93 $virtualdev = 1;
94 }
95 if (defined $nic->PhysicalAdapter) {
96 $interface->{VIRTUALDEV} = $nic->PhysicalAdapter ? 0 : 1;
97 # http://forge.fusioninventory.org/issues/1166
98 } elsif ($interface->{description} =~ /RAS Async Adapter/i) {
99 $interface->{VIRTUALDEV} = 1;
95100 } else {
96 $virtualdev = $nic->PhysicalAdapter ? 0 : 1;
101 $interface->{VIRTUALDEV} = $nic->PNPDeviceID =~ /^ROOT/ ? 1 : 0;
97102 }
98103
99 $interface->{SPEED} = $nic->Speed;
100 $interface->{VIRTUALDEV} = $virtualdev;
101 $interface->{MACADDR} = $nic->MACAddress;
102 $interface->{PNPDEVICEID} = $nic->PNPDeviceID;
103104 push @interfaces, $interface;
104105 }
105106
2323 sub isEnabled {
2424 my (%params) = @_;
2525
26 my $prologresp = $params{prologresp};
27
28 return
29 $prologresp &&
30 $prologresp->getOptionsInfoByName("REGISTRY");
26 return $params{registry};
3127 }
3228
3329 sub doInventory {
3430 my (%params) = @_;
3531
3632 my $inventory = $params{inventory};
37 my $prologresp = $params{prologresp};
3833
39 my $options = $prologresp->getOptionsInfoByName("REGISTRY");
40
41 foreach my $option (@$options) {
34 foreach my $option (@{$params{registry}}) {
4235 my $name = $option->{NAME};
4336 my $regkey = $option->{REGKEY};
4437 my $regtree = $option->{REGTREE};
1111 qw/KEY_READ/
1212 );
1313
14 use FusionInventory::Agent::Tools;
1415 use FusionInventory::Agent::Tools::Win32;
1516
1617 my $seen;
4041 my $softwares64 =
4142 $machKey64->{"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"};
4243
43 _processSoftwares({
44 inventory => $inventory,
44 foreach my $software (_getSoftwares(
4545 softwares => $softwares64,
4646 is64bit => 1
47 });
47 )) {
48 $inventory->addEntry(section => 'SOFTWARES', entry => $software);
49 }
4850
4951 my $machKey32 = $Registry->Open('LMachine', {
5052 Access => KEY_READ | KEY_WOW64_32 ## no critic (ProhibitBitwise)
5355 my $softwares32 =
5456 $machKey32->{"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"};
5557
56 _processSoftwares({
57 inventory => $inventory,
58 foreach my $software (_getSoftwares(
5859 softwares => $softwares32,
59 is64bit => 0
60 });
60 is64bit => 0
61 )) {
62 $inventory->addEntry(section => 'SOFTWARES', entry => $software);
63 }
6164 } else {
6265 my $machKey = $Registry->Open('LMachine', {
6366 Access => KEY_READ
6669 my $softwares =
6770 $machKey->{"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"};
6871
69 _processSoftwares({
70 inventory => $inventory,
72 foreach my $software (_getSoftwares(
7173 softwares => $softwares,
72 is64bit => 0
73 });
74
74 is64bit => 0
75 )) {
76 $inventory->addEntry(section => 'SOFTWARES', entry => $software);
77 }
7578 }
76
7779 }
7880
7981 sub _dateFormat {
8082 my ($date) = @_;
8183
82 return unless $date;
84 ## no critic (ExplicitReturnUndef)
85 return undef unless $date;
8386
8487 return unless $date =~ /^(\d{4})(\d{2})(\d{2})/;
8588
8689 return "$3/$2/$1";
8790 }
8891
89 sub _processSoftwares {
90 my ($params) = @_;
92 sub _getSoftwares {
93 my (%params) = @_;
9194
92 my $softwares = $params->{softwares};
93 my $inventory = $params->{inventory};
94 my $is64bit = $params->{is64bit};
95 my $softwares = $params{softwares};
96 my $is64bit = $params{is64bit};
97
98 my @softwares;
9599
96100 foreach my $rawGuid (keys %$softwares) {
97101 my $data = $softwares->{$rawGuid};
98 next unless keys %$data;
99
100 my $guid = $rawGuid;
101 $guid =~ s/\/$//; # drop the tailing /
102
103102 # odd, found on Win2003
104103 next unless keys %$data > 2;
105104
106105 # See bug #927
107106 # http://stackoverflow.com/questions/2639513/duplicate-entries-in-uninstall-registry-key-when-compiling-list-of-installed-soft
108107 next if $data->{'/SystemComponent'};
108
109 my $guid = $rawGuid;
110 $guid =~ s/\/$//; # drop the tailing /
109111
110112 my $software = {
111113 FROM => "registry",
119121 URL_INFO_ABOUT => encodeFromRegistry($data->{'/URLInfoAbout'}),
120122 UNINSTALL_STRING => encodeFromRegistry($data->{'/UninstallString'}),
121123 INSTALLDATE => _dateFormat($data->{'/InstallDate'}),
122 VERSION_MINOR => hex2dec($data->{'/VersionMinor'}),
123 VERSION_MAJOR => hex2dec($data->{'/VersionMajor'}),
124 NO_REMOVE => $data->{'/NoRemove'} &&
125 $data->{'/NoRemove'} =~ /1/,
124 VERSION_MINOR => hex2dec($data->{'/MinorVersion'}),
125 VERSION_MAJOR => hex2dec($data->{'/MajorVersion'}),
126 NO_REMOVE => hex2dec($data->{'/NoRemove'}),
126127 IS64BIT => $is64bit,
127128 GUID => $guid,
128129 };
133134 # avoid duplicates
134135 next if $seen->{$software->{NAME}}->{$software->{VERSION}}++;
135136
136 $inventory->addEntry(
137 section => 'SOFTWARES',
138 entry => $software,
139 );
137 push @softwares, $software;
140138 }
139
140 return @softwares;
141141 }
142142
143143 1;
2121 DRIVES => [ qw/CREATEDATE DESCRIPTION FREE FILESYSTEM LABEL LETTER
2222 SERIAL SYSTEMDRIVE TOTAL TYPE VOLUMN/ ],
2323 ENVS => [ qw/KEY VAL/ ],
24 INPUTS => [ qw/CAPTION DESCRIPTION INTERFACE LAYOUT POINTTYPE TYPE/ ],
24 INPUTS => [ qw/NAME MANUFACTURER CAPTION DESCRIPTION INTERFACE LAYOUT
25 POINTINGTYPE TYPE/ ],
2526 MEMORIES => [qw/CAPACITY CAPTION FORMFACTOR REMOVABLE PURPOSE SPEED
2627 SERIALNUMBER TYPE DESCRIPTION NUMSLOTS/ ],
2728 MODEMS => [ qw/DESCRIPTION NAME/ ],
2829 MONITORS => [ qw/BASE64 CAPTION DESCRIPTION MANUFACTURER SERIAL
2930 UUENCODE/ ],
3031 NETWORKS => [ qw/DESCRIPTION DRIVER IPADDRESS IPADDRESS6 IPDHCP IPGATEWAY
31 IPMASK IPSUBNET MACADDR MTU PCISLOT STATUS TYPE
32 VIRTUALDEV SLAVES SPEED MANAGEMENT BSSID SSID/ ],
32 IPMASK IPSUBNET MACADDR MTU PCISLOT PNPDEVICEID STATUS
33 TYPE VIRTUALDEV SLAVES SPEED MANAGEMENT BSSID SSID/ ],
3334 PORTS => [ qw/CAPTION DESCRIPTION NAME TYPE/ ],
3435 PROCESSES => [ qw/USER PID CPUUSAGE MEM VIRTUALMEMORY TTY STARTED CMD/ ],
3536 REGISTRY => [ qw/NAME REGVALUE HIVE/ ],
3738 SOFTWARES => [ qw/COMMENTS FILESIZE FOLDER FROM HELPLINK INSTALLDATE NAME
3839 NO_REMOVE RELEASE_TYPE PUBLISHER UNINSTALL_STRING
3940 URL_INFO_ABOUT VERSION VERSION_MINOR VERSION_MAJOR
40 IS64BIT GUID/ ],
41 SOUNDS => [ qw/DESCRIPTION MANUFACTURER NAME/ ],
41 IS64BIT GUID RELEASETYPE/ ],
42 SOUNDS => [ qw/CAPTION DESCRIPTION MANUFACTURER NAME/ ],
4243 STORAGES => [ qw/DESCRIPTION DISKSIZE INTERFACE MANUFACTURER MODEL NAME
4344 TYPE SERIAL SERIALNUMBER FIRMWARE SCSI_COID SCSI_CHID
4445 SCSI_UNID SCSI_LUN WWN/ ],
1313
1414 our $VERSION = '1.0';
1515
16 sub isEnabled {
17 my ($self, $response) = @_;
18
19 # always enabled for local target
20 return 1 unless
21 $self->{target}->isa('FusionInventory::Agent::Target::Server');
22
23 if ($self->{config}->{force}) {
24 $self->{logger}->debug("Prolog response ignored");
25 return 1;
26 }
27
28 my $content = $response->getContent();
29 if (!$content || !$content->{RESPONSE} || $content->{RESPONSE} ne 'SEND') {
30 $self->{logger}->debug("No inventory requested in the prolog response");
31 return;
32 }
33
34 $self->{registry} = $response->getOptionsInfoByName('REGISTRY');
35 return 1;
36 }
37
1638 sub run {
17 my ($self) = @_;
18
19 if ($self->{target}->isa('FusionInventory::Agent::Target::Server')) {
20 die "No server response" unless $self->{prologresp};
21
22 if ($self->{config}->{force}) {
23 $self->{logger}->debug(
24 "Force enable, ignore prolog and run inventory."
25 );
26 } else {
27 my $content = $self->{prologresp}->getContent();
28 if (!($content && $content->{RESPONSE} && $content->{RESPONSE} =~ /^SEND$/)) {
29 $self->{logger}->debug("No inventory requested in the prolog");
30 return;
31 }
32 }
33 }
39 my ($self, %params) = @_;
40
41 $self->{logger}->debug("FusionInventory Inventory task $VERSION");
3442
3543 $self->{modules} = {};
3644
8290 $self->{logger}->error("Can't write to $file: $ERRNO");
8391 }
8492 } elsif ($self->{target}->isa('FusionInventory::Agent::Target::Server')) {
93 my $client = FusionInventory::Agent::HTTP::Client::OCS->new(
94 logger => $self->{logger},
95 user => $params{user},
96 password => $params{password},
97 proxy => $params{proxy},
98 ca_cert_file => $params{ca_cert_file},
99 ca_cert_dir => $params{ca_cert_dir},
100 no_ssl_check => $params{no_ssl_check},
101 );
85102
86103 my $message = FusionInventory::Agent::XML::Query::Inventory->new(
87104 deviceid => $self->{deviceid},
88105 content => $inventory->getContent()
89106 );
90107
91 my $response = $self->{client}->send(
108 my $response = $client->send(
92109 url => $self->{target}->getUrl(),
93110 message => $message
94111 );
138155 params => {
139156 datadir => $self->{datadir},
140157 logger => $self->{logger},
141 prologresp => $self->{prologresp},
158 registry => $self->{registry},
142159 no_software => $self->{config}->{'no-software'},
143160 no_printer => $self->{config}->{'no-printer'},
144161 scan_homedirs => $self->{config}->{'scan-homedirs'},
209226 $self->_runModule($other_module, $inventory);
210227 }
211228
212 $logger->debug ("Running $module");
229 $logger->debug("Running $module");
213230
214231 runFunction(
215232 module => $module,
219236 datadir => $self->{datadir},
220237 inventory => $inventory,
221238 logger => $self->{logger},
222 prologresp => $self->{prologresp},
239 registry => $self->{registry},
223240 no_software => $self->{config}->{no_software},
224241 no_printer => $self->{config}->{no_printer},
225242 scan_homedirs => $self->{config}->{'scan-homedirs'},
299316 my $tpp = XML::TreePP->new(indent => 2);
300317 print {$params{handle}} $tpp->write({
301318 REQUEST => {
302 CONTENT => $params{inventory}->{content}
319 CONTENT => $params{inventory}->{content},
320 DEVICEID => $self->{deviceid},
321 QUERY => "INVENTORY",
303322 }
304323 });
305324
307326 }
308327
309328 if ($params{format} eq 'html') {
310
329 Text::Template->require();
311330 my $template = Text::Template->new(
312331 TYPE => 'FILE', SOURCE => "$self->{datadir}/html/inventory.tpl"
313332 );
1010 use English qw(-no_match_vars);
1111 use Socket;
1212
13 use FusionInventory::Agent::Tools;
14 use FusionInventory::Agent::Tools::Linux;
1315 use FusionInventory::Agent::Tools::Network;
1416
1517 our $VERSION = '1.0';
1618
17 sub run {
18 my ($self) = @_;
19 sub isEnabled {
20 my ($self, $response) = @_;
1921
20 if (!$self->{target}->isa('FusionInventory::Agent::Target::Server')) {
21 $self->{logger}->debug("No server. Exiting...");
22 return unless
23 $self->{target}->isa('FusionInventory::Agent::Target::Server');
24
25 my $options = $self->getOptionsFromServer(
26 $response, 'WAKEONLAN', 'WakeOnLan'
27 );
28 return unless $options;
29
30 my $target = $options->{PARAM}->[0]->{MAC};
31 if (!$target) {
32 $self->{logger}->debug("No mac address defined in the prolog response");
2233 return;
2334 }
2435
25 my $response = $self->{prologresp};
26 if (!$response) {
27 $self->{logger}->debug("No server response. Exiting...");
36 if (!$target !~ /^$mac_address_pattern$/) {
37 $self->{logger}->debug("invalid MAC address $target");
2838 return;
2939 }
3040
31 my $options = $response->getOptionsInfoByName('WAKEONLAN');
32 if (!$options) {
33 $self->{logger}->debug(
34 "No wake on lan requested in the prolog, exiting"
35 );
36 return;
37 }
41 $self->{options} = $options;
42 return 1;
43 }
3844
39 my $macaddress = $self->{WAKEONLAN}->{PARAM}->[0]->{MAC};
45 sub run {
46 my ($self, %params) = @_;
4047
41 return unless defined $macaddress;
48 $self->{logger}->debug("FusionInventory WakeOnLan task $VERSION");
4249
43 if ($macaddress !~ /^$mac_address_pattern$/) {
44 die "invalid MAC address $macaddress, exiting";
45 }
46 $macaddress =~ s/://g;
50 my $options = $self->{options};
51 my $target = $options->{PARAM}->[0]->{MAC};
52 $target =~ s/://g;
4753
4854 # Linux only
4955 eval {
5258 setsockopt(SOCKET, SOL_SOCKET, SO_BROADCAST, 1)
5359 or warn "Can't do setsockopt: $ERRNO\n";
5460
55 open my $handle, '-|', '/sbin/ifconfig -a'
56 or die "Can't run /sbin/ifconfig: $ERRNO";
57 while (my $line = <$handle>) {
58 next unless $line =~ /(\S+) \s+ Link \s \S+ \s+ HWaddr \s (\S+)/x;
59 my $netName = $1;
60 my $netMac = $2;
61 $self->{logger}->debug(
62 "Send magic packet to $macaddress directly on card driver"
63 );
64 $netMac =~ s/://g;
61 my $interface =
62 first { $_->{MACADDR} }
63 getInterfacesFromIfconfig(logger => $self->{logger});
64 my $source = $interface->{MACADDR};
65 $source =~ s/://g;
6566
66 my $magic_packet =
67 (pack('H12', $macaddress)) .
68 (pack('H12', $netMac)) .
69 (pack('H4', "0842"));
70 $magic_packet .= chr(0xFF) x 6 . (pack('H12', $macaddress) x 16);
71 my $destination = pack("Sa14", 0, $netName);
72 send(SOCKET, $magic_packet, 0, $destination)
73 or warn "Couldn't send packet: $ERRNO";
74 }
75 close $handle;
67 $self->{logger}->debug(
68 "Sending magic packet to $target as ethernet frame"
69 );
70
71 my $magic_packet =
72 (pack('H12', $target)) .
73 (pack('H12', $source)) .
74 (pack('H4', "0842"));
75 $magic_packet .= chr(0xFF) x 6 . (pack('H12', $target) x 16);
76 my $destination = pack("Sa14", 0, $interface->{DESCRIPTION});
77 send(SOCKET, $magic_packet, 0, $destination)
78 or warn "Couldn't send packet: $ERRNO";
7679 # TODO : For FreeBSD, send to /dev/bpf ....
7780 };
7881
8386 socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('udp'));
8487 my $magic_packet =
8588 chr(0xFF) x 6 .
86 (pack('H12', $macaddress) x 16);
89 (pack('H12', $target) x 16);
8790 my $sinbroadcast = sockaddr_in("9", inet_aton("255.255.255.255"));
8891 $self->{logger}->debug(
89 "Send magic packet to $macaddress in UDP mode (degraded wol)"
92 "Sending magic packet to $target as UDP packetm"
9093 );
9194 send(SOCKET, $magic_packet, 0, $sinbroadcast);
9295 };
1414 die 'no target parameter' unless $params{target};
1515
1616 my $self = {
17 logger => $params{logger} ||
18 FusionInventory::Agent::Logger->new(),
19 config => $params{config},
20 confdir => $params{confdir},
21 datadir => $params{datadir},
22 target => $params{target},
23 prologresp => $params{prologresp},
24 client => $params{client},
25 deviceid => $params{deviceid}
17 logger => $params{logger} ||
18 FusionInventory::Agent::Logger->new(),
19 config => $params{config},
20 confdir => $params{confdir},
21 datadir => $params{datadir},
22 target => $params{target},
23 deviceid => $params{deviceid},
2624 };
2725 bless $self, $class;
2826
2927 return $self;
28 }
29
30 sub getOptionsFromServer {
31 my ($self, $response, $name, $feature) = @_;
32
33 if (!$response) {
34 $self->{logger}->debug("No server response");
35 return;
36 }
37
38 my $options = $response->getOptionsInfoByName($name);
39 if (!$options) {
40 $self->{logger}->debug("No $feature requested in the prolog");
41 return;
42 }
43
44 return $options;
3045 }
3146
3247 sub getModules {
98113
99114 This is the method to be implemented by each subclass.
100115
116 =head2 getOptionsFromServer($response, $name, $feature)
117
118 Get task-specific options in server response to prolog message.
119
101120 =head2 getModules($prefix)
102121
103122 Return a list of modules for this task. All modules installed at the same
88
99 use FusionInventory::Agent::Tools;
1010 use FusionInventory::Agent::Tools::Unix;
11 use FusionInventory::Agent::Tools::Network;
1112
1213 our @EXPORT = qw(
1314 getDevicesFromUdev
1516 getDevicesFromProc
1617 getCPUsFromProc
1718 getSerialnumber
19 getInterfacesFromIfconfig
20 getInterfacesFromIp
1821 );
1922
2023 memoize('getDevicesFromUdev');
253256 return $serial;
254257 }
255258
259 sub getInterfacesFromIfconfig {
260 my %params = (
261 command => '/sbin/ifconfig -a',
262 @_
263 );
264 my $handle = getFileHandle(%params);
265 return unless $handle;
266
267 my @interfaces;
268 my $interface;
269
270 while (my $line = <$handle>) {
271 if ($line =~ /^$/) {
272 # end of interface section
273 push @interfaces, $interface if $interface;
274 next;
275 }
276
277 if ($line =~ /^(\S+)/) {
278 # new interface
279 $interface = {
280 STATUS => 'Down',
281 DESCRIPTION => $1
282 }
283 }
284 if ($line =~ /inet addr:($ip_address_pattern)/i) {
285 $interface->{IPADDRESS} = $1;
286 }
287 if ($line =~ /Mask:($ip_address_pattern)/) {
288 $interface->{IPMASK} = $1;
289 }
290 if ($line =~ /inet6 addr: (\S+)/i) {
291 $interface->{IPADDRESS6} = $1;
292 }
293 if ($line =~ /hwadd?r\s+($mac_address_pattern)/i) {
294 $interface->{MACADDR} = $1;
295 }
296 if ($line =~ /^\s+UP\s/) {
297 $interface->{STATUS} = 'Up';
298 }
299 if ($line =~ /link encap:(\S+)/i) {
300 $interface->{TYPE} = $1;
301 }
302
303 }
304 close $handle;
305
306 return @interfaces;
307 }
308 sub getInterfacesFromIp {
309 my %params = (
310 command => '/sbin/ip addr show',
311 @_
312 );
313
314 my $handle = getFileHandle(%params);
315 return unless $handle;
316
317 my @interfaces;
318 my $interface;
319
320 while (my $line = <$handle>) {
321 chomp $line;
322 if ($line =~ /^\d+:\s+(\S+): .*(UP|DOWN)/) {
323 push @interfaces, $interface if $interface;
324 $interface = {
325 DESCRIPTION => $1,
326 STATUS => ucfirst(lc($2))
327 };
328 } elsif ($line =~ /link\/ether ($mac_address_pattern)/) {
329 $interface->{MACADDR} = $1;
330 } elsif ($line =~ /inet6 (\S+)\//) {
331 $interface->{IPADDRESS6} = $1;
332 } elsif ($line =~ /inet ($ip_address_pattern)\/(\d{1,3})/) {
333 $interface->{IPADDRESS} = $1;
334 $interface->{IPMASK} = getNetworkMask($1, $2);
335 $interface->{IPSUBNET} = getSubnetAddress(
336 $interface->{IPADDRESS}, $interface->{IPMASK}
337 );
338 }
339 }
340
341 return @interfaces;
342 }
343
256344 1;
257345 __END__
258346
335423 =item file the file to use
336424
337425 =back
426
427 =head2 getInterfacesFromIfconfig(%params)
428
429 Returns the list of interfaces, by parsing ifconfig command output.
430
431 Availables parameters:
432
433 =over
434
435 =item logger a logger object
436
437 =item command the command to use (default: /sbin/ifconfig -a)
438
439 =item file the file to use
440
441 =back
442
443 =head2 getInterfacesFromIp(%params)
444
445 Returns the list of interfaces, by parsing ip command output.
446
447 Availables parameters:
448
449 =over
450
451 =item logger a logger object
452
453 =item command the command to use (default: /sbin/ip addr show)
454
455 =item file the file to use
456
457 =back
1818 getNetworkMask
1919 hex2canonical
2020 alt2canonical
21 getLastNumber
2221 );
2322
2423 my $hex_byte = qr/[0-9A-F]{2}/i;
6362
6463 my $binaddress = ip_iptobin($address, 6);
6564 my $binmask = ip_iptobin($mask, 6);
65
66 return unless $binaddress && $binmask;
67
6668 my $binsubnet = $binaddress & $binmask; ## no critic (ProhibitBitwise)
6769
6870 return ip_bintoip($binsubnet, 6);
7173 sub hex2canonical {
7274 my ($address) = @_;
7375
74 my @bytes = $address =~ /^(..)(..)(..)(..)$/;
76 my @bytes = $address =~ /^(?:0x)?(..)(..)(..)(..)$/;
7577 return join('.', map { hex($_) } @bytes);
7678 }
7779
7880 sub alt2canonical {
7981 my ($address) = @_;
8082
81 my @bytes = $address =~ /^(..)(..)(..)(..)(..)(..)$/;
83 my @bytes = $address =~ /^(?:0x)?(..)(..)(..)(..)(..)(..)$/;
8284 return join(':', @bytes);
8385 }
8486
9193
9294 my @bytes = $mask =~ /^(\d{8})(\d{8})(\d{8})(\d{8})$/;
9395 return join ('.', map { oct('0b' . $_) } @bytes);
94 }
95
96 sub getLastNumber {
97 my ($oid) = @_;
98
99 my @array = split(/\./, $oid);
100 return $array[-1];
10196 }
10297
10398 1;
150145 =head2 getNetworkMask($address, $prefix)
151146
152147 Returns the network mask.
153
154 =head2 getLastNumber($oid)
155
156 return the last number of an oid.
157
22 use strict;
33 use warnings;
44 use base 'Exporter';
5
6 use constant SOLARIS_UNKNOWN => 0;
7 use constant SOLARIS_FIRE => 1;
8 use constant SOLARIS_FIRE_V => 2;
9 use constant SOLARIS_FIRE_T => 3;
10 use constant SOLARIS_ENTERPRISE_T => 4;
11 use constant SOLARIS_ENTERPRISE => 5;
12 use constant SOLARIS_I86PC => 6;
13 use constant SOLARIS_CONTAINER => 7;
514
615 use English qw(-no_match_vars);
716
1221 getZone
1322 getModel
1423 getClass
24 SOLARIS_UNKNOWN
25 SOLARIS_FIRE
26 SOLARIS_FIRE_V
27 SOLARIS_FIRE_T
28 SOLARIS_ENTERPRISE_T
29 SOLARIS_ENTERPRISE
30 SOLARIS_I86PC
31 SOLARIS_CONTAINER
1532 );
1633
1734 memoize('getZone');
4966 my $model = getModel();
5067
5168 if ($model =~ /SUNW,Sun-Fire-\d/) {
52 return 1;
69 return SOLARIS_FIRE;
5370 }
5471
5572 if (
5774 $model =~ /SUNW,Netra-T/ or
5875 $model =~ /SUNW,Ultra-250/
5976 ) {
60 return 2;
77 return SOLARIS_FIRE_V;
6178 }
6279
6380 if (
6481 $model =~ /SUNW,Sun-Fire-T\d/ or
6582 $model =~ /SUNW,T\d/
6683 ) {
67 return 3;
84 return SOLARIS_FIRE_T;
6885 }
6986
7087 if ($model =~ /SUNW,SPARC-Enterprise-T\d/) {
71 return 4;
88 return SOLARIS_ENTERPRISE_T;
7289 }
7390 if ($model =~ /SUNW,SPARC-Enterprise/) {
74 return 5;
91 return SOLARIS_ENTERPRISE;
7592 }
7693 if ($model eq "i86pc") {
77 return 6;
94 return SOLARIS_I86PC;
7895 }
7996 if ($model =~ /Solaris Containers/) {
80 return 7;
97 return SOLARIS_CONTAINER;
8198 }
8299
83100 # unknown class
84 return 0;
101 return SOLARIS_UNKNOWN;
85102 }
86103
87104
1919 getProcessesFromPs
2020 getRoutingTable
2121 );
22
23 memoize('getProcessesFromPs');
2224
2325 sub getDeviceCapacity {
2426 my %params = @_;
4343 sub encodeFromRegistry {
4444 my ($string) = @_;
4545
46 return unless $string;
46 ## no critic (ExplicitReturnUndef)
47 return undef unless $string;
4748
4849 if (!$localCodepage) {
4950 my $lmachine = $Registry->Open('LMachine', {
236236 last SWITCH;
237237 }
238238 if ($params{string}) {
239
240239 open $handle, "<", \$params{string} or die;
240 last SWITCH;
241241 }
242 die "neither command nor file parameter given";
242 die "neither command, file or string parameter given";
243243 }
244244
245245 return $handle;
345345 sub hex2char {
346346 my ($value) = @_;
347347
348 return unless $value;
348 ## no critic (ExplicitReturnUndef)
349 return undef unless $value;
349350 return $value unless $value =~ /^0x/;
350351
351352 $value =~ s/^0x//;
357358 sub hex2dec {
358359 my ($value) = @_;
359360
360 return unless $value;
361 ## no critic (ExplicitReturnUndef)
362 return undef unless $value;
361363 return $value unless $value =~ /^0x/;
362364
363365 return oct($value);
366368 sub dec2hex {
367369 my ($value) = @_;
368370
369 return unless $value;
371 ## no critic (ExplicitReturnUndef)
372 return undef unless $value;
370373 return $value if $value =~ /^0x/;
371374
372375 return sprintf("0x%x", $value);
516519
517520 =head2 getFileHandle(%params)
518521
519 Returns an open file handle on either a command output, or a file.
520
521 =over
522
523 =item logger a logger object
524
525 =item command the exact command to use
522 Returns an open file handle on either a command output, a file, or a string.
523
524 =over
525
526 =item logger a logger object
527
528 =item command the command to use
526529
527530 =item file the file to use, as an alternative to the command
531
532 =item string the string to use, as an alternative to the command
528533
529534 =back
530535
66 use English qw(-no_match_vars);
77 use Sys::Hostname;
88 use UNIVERSAL::require;
9 use File::Glob;
910
1011 use FusionInventory::Agent::Config;
1112 use FusionInventory::Agent::HTTP::Client::OCS;
1920 use FusionInventory::Agent::Tools;
2021 use FusionInventory::Agent::XML::Query::Prolog;
2122
22 our $VERSION = '2.1.9901';
23 our $VERSION = '2.1.9902';
2324 our $VERSION_STRING =
2425 "FusionInventory unified agent for UNIX, Linux and MacOSX ($VERSION)";
2526 our $AGENT_STRING =
2627 "FusionInventory-Agent_v$VERSION";
27
28 my @tasks = qw/
29 Inventory
30 WakeOnLan
31 SNMPQuery
32 NetDiscovery
33 Deploy
34 ESX
35 /;
3628
3729 sub new {
3830 my ($class, %params) = @_;
4537 };
4638 bless $self, $class;
4739
40 return $self;
41 }
42
43 sub init {
44 my ($self, %params) = @_;
45
4846 my $config = FusionInventory::Agent::Config->new(
49 confdir => $params{confdir},
47 confdir => $self->{confdir},
5048 options => $params{options},
5149 );
5250 $self->{config} = $config;
165163
166164 $_->setShared() foreach $scheduler->getTargets();
167165
168 $self->{_server} = FusionInventory::Agent::HTTP::Server->new(
166 $self->{server} = FusionInventory::Agent::HTTP::Server->new(
169167 logger => $logger,
170168 scheduler => $scheduler,
171169 agent => $self,
177175 }
178176 }
179177
178 # compute list of allowed tasks
179 my %available = $self->getAvailableTasks();
180 my %disabled = map { lc($_) => 1 } @{$config->{'no-task'}};
181 my @allowed = grep { !$disabled{lc($_)} } keys %available;
182 $self->{tasks} = \@allowed;
183
180184 $logger->debug("FusionInventory Agent initialised");
181
182 return $self;
183 }
184
185 sub _isAlreadyRunning {
186 my ($self) = @_;
187
188 Proc::PID::File->require();
189 if ($EVAL_ERROR) {
190 $self->{logger}->debug(
191 'Proc::PID::File unavailable, unable to check for running agent'
192 );
193 return 0;
194 }
195
196 return Proc::PID::File->running();
197 }
198
199 sub _getHostname {
200
201 # use hostname directly under Unix
202 return hostname() if $OSNAME ne 'MSWin32';
203
204 # otherwise, use Win32 API
205 Encode->require();
206 Encode->import();
207 Win32::API->require();
208
209 my $getComputerName = Win32::API->new(
210 "kernel32", "GetComputerNameExW", ["I", "P", "P"], "N"
211 );
212 my $lpBuffer = "\x00" x 1024;
213 my $N = 1024; #pack ("c4", 160,0,0,0);
214
215 $getComputerName->Call(3, $lpBuffer, $N);
216
217 # GetComputerNameExW returns the string in UTF16, we have to change
218 # it to UTF8
219 return encode(
220 "UTF-8", substr(decode("UCS-2le", $lpBuffer), 0, ord $N)
221 );
222 }
223
224 sub _loadState {
225 my ($self) = @_;
226
227 my $data = $self->{storage}->restore(name => 'FusionInventory-Agent');
228
229 $self->{token} = $data->{token} if $data->{token};
230 $self->{deviceid} = $data->{deviceid} if $data->{deviceid};
231 }
232
233 sub _saveState {
234 my ($self) = @_;
235
236 $self->{storage}->save(
237 name => 'FusionInventory-Agent',
238 data => {
185 }
186
187 sub run {
188 my ($self) = @_;
189
190 $self->{status} = 'waiting';
191
192 # endless loop in server mode
193 while (my $target = $self->{scheduler}->getNextTarget()) {
194 eval {
195 $self->_runTarget($target);
196 };
197 $self->{logger}->fault($EVAL_ERROR) if $EVAL_ERROR;
198 $target->resetNextRunDate();
199 }
200 }
201
202 sub _runTarget {
203 my ($self, $target) = @_;
204
205 # the prolog dialog must be done once for all tasks,
206 # but only for server targets
207 my $response;
208 if ($target->isa('FusionInventory::Agent::Target::Server')) {
209 my $client = FusionInventory::Agent::HTTP::Client::OCS->new(
210 logger => $self->{logger},
211 user => $self->{config}->{user},
212 password => $self->{config}->{password},
213 proxy => $self->{config}->{proxy},
214 ca_cert_file => $self->{config}->{'ca-cert-file'},
215 ca_cert_dir => $self->{config}->{'ca-cert-dir'},
216 no_ssl_check => $self->{config}->{'no-ssl-check'},
217 );
218
219 my $prolog = FusionInventory::Agent::XML::Query::Prolog->new(
239220 token => $self->{token},
240221 deviceid => $self->{deviceid},
241 }
242 );
243 }
244
245 sub run {
246 my ($self) = @_;
247
248 my $config = $self->{config};
222 );
223
224 $response = $client->send(
225 url => $target->getUrl(),
226 message => $prolog
227 );
228 die "No answer from the server" unless $response;
229
230 # update target
231 my $content = $response->getContent();
232 if (defined($content->{PROLOG_FREQ})) {
233 $target->setMaxDelay($content->{PROLOG_FREQ} * 3600);
234 }
235 }
236
237 foreach my $name (@{$self->{tasks}}) {
238 eval {
239 $self->_runTask($target, $name, $response);
240 };
241 $self->{logger}->error($EVAL_ERROR) if $EVAL_ERROR;
242 $self->{status} = 'waiting';
243 }
244 }
245
246 sub _runTask {
247 my ($self, $target, $name, $response) = @_;
248
249 my $class = "FusionInventory::Agent::Task::$name";
250 my $task = $class->new(
251 config => $self->{config},
252 confdir => $self->{confdir},
253 datadir => $self->{datadir},
254 logger => $self->{logger},
255 target => $target,
256 deviceid => $self->{deviceid},
257 );
258
259 if (!$task->isEnabled($response)) {
260 $self->{logger}->info("task $name is not enabled");
261 return;
262 }
263
264 $self->{status} = "running task $name";
265
266 if ($self->{config}->{daemon} || $self->{config}->{service}) {
267 # daemon mode: run each task in a child process
268 if (my $pid = fork()) {
269 # parent
270 waitpid($pid, 0);
271 } else {
272 # child
273 die "fork failed: $ERRNO" unless defined $pid;
274
275 $self->{logger}->debug("running task $name in process $PID");
276 $task->run(
277 user => $self->{config}->{user},
278 password => $self->{config}->{password},
279 proxy => $self->{config}->{proxy},
280 ca_cert_file => $self->{config}->{'ca-cert-file'},
281 ca_cert_dir => $self->{config}->{'ca-cert-dir'},
282 no_ssl_check => $self->{config}->{'no-ssl-check'},
283 );
284 exit(0);
285 }
286 } else {
287 # standalone mode: run each task directly
288 $self->{logger}->debug("running task $name");
289 $task->run(
290 user => $self->{config}->{user},
291 password => $self->{config}->{password},
292 proxy => $self->{config}->{proxy},
293 ca_cert_file => $self->{config}->{'ca-cert-file'},
294 ca_cert_dir => $self->{config}->{'ca-cert-dir'},
295 no_ssl_check => $self->{config}->{'no-ssl-check'},
296 );
297 }
298 }
299
300 sub getToken {
301 my ($self) = @_;
302 return $self->{token};
303 }
304
305 sub resetToken {
306 my ($self) = @_;
307 $self->{token} = _computeToken();
308 }
309
310 sub getStatus {
311 my ($self) = @_;
312 return $self->{status};
313 }
314
315 sub getAvailableTasks {
316 my ($self) = @_;
317
249318 my $logger = $self->{logger};
250 my $scheduler = $self->{scheduler};
251 $self->{status} = 'waiting';
252
253 my $status = 0;
254
255 while (my $target = $scheduler->getNextTarget()) {
256 eval {
257 my $prologresp;
258 my $client;
259 if ($target->isa('FusionInventory::Agent::Target::Server')) {
260
261 $client = FusionInventory::Agent::HTTP::Client::OCS->new(
262 logger => $logger,
263 user => $self->{config}->{user},
264 password => $self->{config}->{password},
265 proxy => $self->{config}->{proxy},
266 ca_cert_file => $self->{config}->{'ca-cert-file'},
267 ca_cert_dir => $self->{config}->{'ca-cert-dir'},
268 no_ssl_check => $self->{config}->{'no-ssl-check'},
269 );
270
271 my $prolog = FusionInventory::Agent::XML::Query::Prolog->new(
272 token => $self->{token},
273 deviceid => $self->{deviceid},
274 );
275
276 $prologresp = $client->send(
277 url => $target->getUrl(),
278 message => $prolog
279 );
280
281 if (!$prologresp) {
282 $logger->error("No answer from the server");
283 $target->resetNextRunDate();
284 return;
285 }
286
287 # update target
288 my $content = $prologresp->getContent();
289 if (defined($content->{PROLOG_FREQ})) {
290 $target->setMaxDelay($content->{PROLOG_FREQ} * 3600);
291 }
292 }
293
294 # index list of disabled task for fast lookup
295 my %disabled = map { $_ => 1 } @{$config->{'no-task'}};
296
297 foreach my $module (@tasks) {
298
299 next if $disabled{lc($module)};
300
301 my $package = "FusionInventory::Agent::Task::$module";
302 if (!$package->require()) {
303 $logger->info("task $module is not available");
304 $logger->debug2("task $module compile error: $EVAL_ERROR");
305 next;
306 }
307 if (!$package->isa('FusionInventory::Agent::Task')) {
308 $logger->info(
309 "task $module is not compatible with this agent " .
310 "($VERSION)"
311 );
312 next;
313 }
314
315 $self->{status} = "running task $module";
316
317 my $task;
318 eval {
319 $task = $package->new(
320 config => $config,
321 confdir => $self->{confdir},
322 datadir => $self->{datadir},
323 logger => $logger,
324 target => $target,
325 prologresp => $prologresp,
326 client => $client,
327 deviceid => $self->{deviceid}
328 );
329 };
330 if (!$task) {
331 $logger->info("task $module can't be initialized: ".$EVAL_ERROR);
332 next;
333 }
334
335 if ($config->{daemon} || $config->{service}) {
336 # daemon mode: run each task in a child process
337 if (my $pid = fork()) {
338 # parent
339 waitpid($pid, 0);
340 } else {
341 # child
342 die "fork failed: $ERRNO" unless defined $pid;
343
344 $logger->debug(
345 "executing $module in process $$"
346 );
347 $task->run();
348 exit(0);
349 }
350 } else {
351 # standalone mode: run each task directly
352 $logger->debug("executing $module");
353 $task->run();
354 }
355 }
356
357 $self->{status} = 'waiting';
358
359 };
360 if ($EVAL_ERROR) {
361 $logger->fault($EVAL_ERROR);
362 $status++;
363 }
364 $target->resetNextRunDate();
365 }
366
367 exit $status;
368 }
369
370 sub getToken {
371 my ($self) = @_;
372 return $self->{token};
373 }
374
375 sub resetToken {
376 my ($self) = @_;
377 $self->{token} = _computeToken();
378 }
379
380 # compute a random token
381 sub _computeToken {
382 my @chars = ('A'..'Z');
383 return join('', map { $chars[rand @chars] } 1..8);
384 }
385
386 # compute an unique agent identifier, based on host name and current time
387 sub _computeDeviceId {
388 my $hostname = _getHostname();
389
390 my ($year, $month , $day, $hour, $min, $sec) =
391 (localtime (time))[5, 4, 3, 2, 1, 0];
392
393 return sprintf "%s-%02d-%02d-%02d-%02d-%02d-%02d",
394 $hostname, $year + 1900, $month + 1, $day, $hour, $min, $sec;
395 }
396
397 sub getStatus {
398 my ($self) = @_;
399 return $self->{status};
400 }
401
402 sub getKnownTasks {
403 my ($self) = @_;
404
405 my %tasks;
406 foreach my $module (@tasks) {
407
408 my $package = "FusionInventory::Agent::Task::$module";
409 next unless $package->require();
410 next unless $package->isa('FusionInventory::Agent::Task');
411
412 # retrieve version
413 my $version;
414 {
415 no strict 'refs'; ## no critic
416 $version = ${$package . '::VERSION'};
417 }
418
419 $tasks{$module} = $version;
420 }
421
422 return %tasks;
423 }
424
425 sub getAvailableTasks {
426 my ($self) = @_;
427
428319 my %tasks;
429320
430321 # tasks may be dispatched in every directory referenced in @INC
434325 next unless -d "$directory/$subdirectory";
435326
436327 # look for all perl modules here
437 foreach my $file (glob("$directory/$subdirectory/*.pm")) {
438 next unless $file =~ m{($subdirectory/\S+\.pm)$};
328 foreach my $file (File::Glob::glob("$directory/$subdirectory/*.pm")) {
329 next unless $file =~ m{($subdirectory/(\S+)\.pm)$};
439330 my $module = file2module($1);
440
331 my $name = file2module($2);
441332 # check module
442333 # todo: use a child process when running as a server to save memory
334 if (!$module->require()) {
335 $logger->debug2("module $module does not compile: $@") if $logger;
336 next;
337 }
338 if (!$module->isa('FusionInventory::Agent::Task')) {
339 $logger->debug2("module $module is not a task") if $logger;
340 next;
341 }
342
443343 next unless $module->require();
444344 next unless $module->isa('FusionInventory::Agent::Task');
445345
453353 $version = ${$module . '::VERSION'};
454354 }
455355
456 $tasks{$module} = $version;
356 $tasks{$name} = $version;
457357 }
458358 }
459359
460360 return %tasks;
361 }
362
363 sub _isAlreadyRunning {
364 my ($self) = @_;
365
366 Proc::PID::File->require();
367 if ($EVAL_ERROR) {
368 $self->{logger}->debug(
369 'Proc::PID::File unavailable, unable to check for running agent'
370 );
371 return 0;
372 }
373
374 return Proc::PID::File->running();
375 }
376
377 sub _getHostname {
378
379 # use hostname directly under Unix
380 return hostname() if $OSNAME ne 'MSWin32';
381
382 # otherwise, use Win32 API
383 Encode->require();
384 Encode->import();
385 Win32::API->require();
386
387 my $getComputerName = Win32::API->new(
388 "kernel32", "GetComputerNameExW", ["I", "P", "P"], "N"
389 );
390 my $lpBuffer = "\x00" x 1024;
391 my $N = 1024; #pack ("c4", 160,0,0,0);
392
393 $getComputerName->Call(3, $lpBuffer, $N);
394
395 # GetComputerNameExW returns the string in UTF16, we have to change
396 # it to UTF8
397 return encode(
398 "UTF-8", substr(decode("UCS-2le", $lpBuffer), 0, ord $N)
399 );
400 }
401
402 sub _loadState {
403 my ($self) = @_;
404
405 my $data = $self->{storage}->restore(name => 'FusionInventory-Agent');
406
407 $self->{token} = $data->{token} if $data->{token};
408 $self->{deviceid} = $data->{deviceid} if $data->{deviceid};
409 }
410
411 sub _saveState {
412 my ($self) = @_;
413
414 $self->{storage}->save(
415 name => 'FusionInventory-Agent',
416 data => {
417 token => $self->{token},
418 deviceid => $self->{deviceid},
419 }
420 );
421 }
422
423 # compute a random token
424 sub _computeToken {
425 my @chars = ('A'..'Z');
426 return join('', map { $chars[rand @chars] } 1..8);
427 }
428
429 # compute an unique agent identifier, based on host name and current time
430 sub _computeDeviceId {
431 my $hostname = _getHostname();
432
433 my ($year, $month , $day, $hour, $min, $sec) =
434 (localtime (time))[5, 4, 3, 2, 1, 0];
435
436 return sprintf "%s-%02d-%02d-%02d-%02d-%02d-%02d",
437 $hostname, $year + 1900, $month + 1, $day, $hour, $min, $sec;
461438 }
462439
463440 1;
514491
515492 Get the current agent status.
516493
517 =head2 getKnownTasks()
518
519 Get all available tasks among hard-coded list, as a list of module / version
494 =head2 getAvailableTasks()
495
496 Get all available tasks found on the system, as a list of module / version
520497 pairs:
521498
522499 %tasks = (
523500 'FusionInventory::Agent::Task::Foo' => x,
524501 'FusionInventory::Agent::Task::Bar' => y,
525502 );
526
527 =head2 getAvailableTasks()
528
529 Get all available tasks found on the system, as a list of module / version
530 pairs:
531
532 %tasks = (
533 'FusionInventory::Agent::Task::Foo' => x,
534 'FusionInventory::Agent::Task::Bar' => y,
535 );
0 GeoIP-1.4.8_1 Find the country that any IP address or hostname originates
1 ImageMagick-6.7.0.10_1 Image processing tools
2 ORBit2-2.14.19 High-performance CORBA ORB with support for the C language
3 Ocsinventory-Agent-1.1.2.1_1,1 Keep track of the computers configuration and software
4 Ocsinventory-Agent-2.0,1 Keep track of the computers configuration and software
5 OpenEXR-1.6.1_3 A high dynamic-range (HDR) image file format
6 a2ps-a4-4.13b_4 Formats an ascii file for printing on a postscript printer
7 aalib-1.4.r5_6 An ascii art library
8 acidrip-0.14_8 GTK2::Perl wrapper for MPlayer and MEncoder for ripping DVD
9 acroread8-8.1.7_3 Adobe Reader for view, print, and search PDF documents (ENU
10 acroreadwrapper-0.0.20110920 Wrapper script for Adobe Reader
11 alsa-lib-1.0.23 ALSA compatibility library
12 ap22-mod_perl2-2.0.5_1,3 Embeds a Perl interpreter in the Apache2 server
13 apache-2.2.19 Version 2.2.x of Apache web server with prefork MPM.
14 apache-ant-1.8.2 Java- and XML-based build tool, conceptually similar to mak
15 appres-1.0.3 Program to list application's resources
16 apr-ipv6-devrandom-gdbm-db42-1.4.5.1.3.12 Apache Portability Library
17 aspell-0.60.6.1 Spelling checker with better suggestion logic than ispell
18 atk-2.0.1 A GNOME accessibility toolkit (ATK)
19 atkmm-2.22.5 C++ wrapper for ATK API library
20 attica-0.2.80,1 Collaboration Services API library
21 atunes-2.0.1 A full-featured audio player and manager developed in Java
22 audacity-1.2.4b_9 Audacity is a GUI editor for digital audio waveforms
23 autoconf-2.13.000227_6 Automatically configure source code on many Un*x platforms
24 autoconf-2.68 Automatically configure source code on many Un*x platforms
25 autoconf-wrapper-20101119 Wrapper script for GNU autoconf
26 automake-1.11.1 GNU Standards-compliant Makefile generator (1.11)
27 automake-1.4.6_6 GNU Standards-compliant Makefile generator (1.4)
28 automake-wrapper-20101119 Wrapper script for GNU automake
29 automoc4-0.9.88_1 Automatic moc for Qt 4 packages
30 avahi-app-0.6.29 Service discovery on a local network
31 b43-fwcutter-012 Extracts firmware for Broadcom Wireless adapters
32 babl-0.1.4 Dynamic pixel format conversion library
33 bash-4.1.11 The GNU Project's Bourne Again SHell
0 lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
1 inet 127.0.0.1 netmask ff000000
2 e1000g0: flags=1004843<UP,BROADCAST,RUNNING,MULTICAST,DHCP,IPv4> mtu 1500 index 2
3 inet 192.168.0.41 netmask ffffff00 broadcast 192.168.0.255
4 ether 8:0:27:fc:ad:56
5 lo0: flags=2002000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv6,VIRTUAL> mtu 8252 index 1
6 inet6 ::1/128
7 e1000g0: flags=2000841<UP,RUNNING,MULTICAST,IPv6> mtu 1480 index 2
8 inet6 fe80::a00:27ff:fefc:ad56/10
9 ether 8:0:27:fc:ad:56
10 e1000g0:1: flags=2080841<UP,RUNNING,MULTICAST,ADDRCONF,IPv6> mtu 1480 index 2
11 inet6 2a01:e35:8ad7:48d0:a00:27ff:fefc:ad56/64
0 Routing tables
1
2 Internet:
3 Destination Gateway Flags Refs Use Netif Expire
4 default 192.168.0.254 UGSc 10 2 en0
5 127 127.0.0.1 UCS 0 0 lo0
6 127.0.0.1 127.0.0.1 UH 10 8841 lo0
7 169.254 link#4 UCS 0 0 en0
8 192.168.0 link#4 UCS 1 0 en0
9 192.168.0.27 127.0.0.1 UHS 0 13 lo0
10 192.168.0.254 f4:ca:e5:42:38:37 UHLW 8 21 en0 1001
3131 # exclude linked modules
3232 my @files = grep { filter($_) } all_pm_files('lib');
3333
34 eval { require FusionInventory::Agent::SNMP; };
35 if ($EVAL_ERROR) {
36 @files = grep { ! /SNMP/ } @files;
37 }
38
3934 all_pm_files_ok(@files);
+0
-92
t/components/SNMP.t less more
0 #!/usr/bin/perl
1
2 use strict;
3 use warnings;
4
5 use English qw(-no_match_vars);
6 use Test::More;
7 use Test::Exception;
8
9 use FusionInventory::Agent::XML::Response;
10
11 eval { require FusionInventory::Agent::SNMP; };
12
13 if ($EVAL_ERROR) {
14 my $msg = 'Unable to load FusionInventory::Agent::SNMP';
15 plan(skip_all => $msg);
16 }
17
18 plan tests => 9;
19
20 my $snmp;
21 throws_ok {
22 $snmp = FusionInventory::Agent::SNMP->new();
23 } qr/^no hostname parameter/,
24 'instanciation: no hostname parameter';
25
26 throws_ok {
27 $snmp = FusionInventory::Agent::SNMP->new(
28 hostname => 'localhost',
29 version => 'foo'
30 );
31 } qr/^invalid SNMP version/,
32 'instanciation: invalid version parameter';
33
34 throws_ok {
35 $snmp = FusionInventory::Agent::SNMP->new(
36 hostname => 'localhost',
37 version => 5
38 );
39 } qr/^invalid SNMP version/,
40 'instanciation: invalid version parameter';
41
42 throws_ok {
43 $snmp = FusionInventory::Agent::SNMP->new(
44 hostname => 'localhost',
45 version => 1
46 );
47 } qr/[Cc]ommunity (is )?not defined/,
48 'instanciation: undefined community';
49
50 lives_ok {
51 $snmp = FusionInventory::Agent::SNMP->new(
52 version => 1,
53 community => 'public',
54 hostname => 'localhost'
55 );
56 } 'instanciation: OK';
57
58 ok(
59 !defined $snmp->get(),
60 'no OID'
61 );
62
63 ok(
64 !defined $snmp->walk(),
65 'no first OID'
66 );
67
68 SKIP: {
69 skip 'live SNMP test disabled', 2 unless $ENV{TEST_LIVE_SNMP};
70
71 is(
72 $snmp->get('1.3.6.1.2.1.1.9.1.3.3'),
73 'The SNMP Management Architecture MIB.',
74 'simple value query'
75 );
76
77 is_deeply(
78 $snmp->walk('1.3.6.1.2.1.1.9.1.3'),
79 {
80 '1.3.6.1.2.1.1.9.1.3.1' => 'The MIB for Message Processing and Dispatching.',
81 '1.3.6.1.2.1.1.9.1.3.2' => 'The MIB for Message Processing and Dispatching.',
82 '1.3.6.1.2.1.1.9.1.3.3' => 'The SNMP Management Architecture MIB.',
83 '1.3.6.1.2.1.1.9.1.3.4' => 'The MIB module for SNMPv2 entities',
84 '1.3.6.1.2.1.1.9.1.3.5' => 'The MIB module for managing TCP implementations',
85 '1.3.6.1.2.1.1.9.1.3.6' => 'The MIB module for managing IP and ICMP implementations',
86 '1.3.6.1.2.1.1.9.1.3.7' => 'The MIB module for managing UDP implementations',
87 '1.3.6.1.2.1.1.9.1.3.8' => 'View-based Access Control Model for SNMP.'
88 },
89 'multiple value query'
90 );
91 }
1010
1111 plan tests => 8;
1212
13 my %before = FusionInventory::Agent->getAvailableTasks();
13 my $agent = FusionInventory::Agent->new();
14
15 my %before = $agent->getAvailableTasks();
1416 my $tmpdir = tempdir(CLEANUP => $ENV{TEST_DEBUG} ? 0 : 1);
1517 my $tasks;
1618
2224 $tasks = get_new_tasks("$tmpdir/1");
2325 is_deeply (
2426 $tasks,
25 { 'FusionInventory::Agent::Task::Test1' => 42 },
27 { 'Test1' => 42 },
2628 "single task"
2729 );
2830
4042 is_deeply (
4143 $tasks,
4244 {
43 'FusionInventory::Agent::Task::Test2a' => 42,
44 'FusionInventory::Agent::Task::Test2b' => 42
45 'Test2a' => 42,
46 'Test2b' => 42
4547 },
4648 "multiple tasks, single root"
4749 );
6062 is_deeply (
6163 $tasks,
6264 {
63 'FusionInventory::Agent::Task::Test3a' => 42,
64 'FusionInventory::Agent::Task::Test3b' => 42
65 'Test3a' => 42,
66 'Test3b' => 42
6567 },
6668 "multiple tasks, multiple roots"
6769 );
8082 is_deeply (
8183 $tasks,
8284 {
83 'FusionInventory::Agent::Task::Test4' => 42,
85 'Test4' => 42,
8486 },
8587 "single tasks, multiple versions, first found wins"
8688 );
133135
134136 unshift @INC, @dirs;
135137
136 my %after = FusionInventory::Agent->getAvailableTasks();
138 my %after = $agent->getAvailableTasks();
137139
138140 shift @INC foreach @dirs;
139141
1313 use FusionInventory::Agent::HTTP::Server;
1414 use FusionInventory::Agent::Logger;
1515
16 plan tests => 5;
16 plan tests => 7;
1717
1818 my $logger = FusionInventory::Agent::Logger->new(
1919 backends => [ 'Test' ]
3333 );
3434 } 'instanciation with default values: ok';
3535
36 my $client = LWP::UserAgent->new();
36 my $client = LWP::UserAgent->new(timeout => 2);
3737
3838 ok(
3939 $client->get('http://localhost:62354')->is_success(),
4040 'server listening on default port'
4141 );
42
43 $server->terminate();
4244
4345 lives_ok {
4446 $server = FusionInventory::Agent::HTTP::Server->new(
4951 htmldir => 'share/html'
5052 );
5153 } 'instanciation with specific port: ok';
54 sleep 1;
5255
5356 ok(
5457 !$client->get('http://localhost:62354')->is_success(),
5962 $client->get('http://localhost:8080')->is_success(),
6063 'server listening on specific port'
6164 );
65
66 # fork a child process, as when running in server mode
67 if (my $pid = fork()) {
68 # parent
69 waitpid($pid, 0);
70 } else {
71 # child
72 exit(0);
73 }
74
75 ok(
76 $client->get('http://localhost:8080')->is_success(),
77 'server still listening after child process exit'
78 );
79
80 # fork a child process, and raise ALRM from it, as when a timeout is reached
81 if (my $pid = fork()) {
82 # parent
83 waitpid($pid, 0);
84 } else {
85 # child
86 alarm 1;
87 exit(0);
88 }
89
90 ok(
91 $client->get('http://localhost:8080')->is_success(),
92 'server still listening after child process raised ALRM'
93 );
94
95
96 $server->terminate();
0 #!/usr/bin/perl
1
2 use strict;
3 use warnings;
4
5 use Test::More;
6
7 use FusionInventory::Agent::Task::Inventory::Input::BSD::Softwares;
8
9 my %pkg_info_tests = (
10 'sample1' => [
11 {
12 'NAME' => 'GeoIP',
13 'DESCRIPTION' => 'Find the country that any IP address or hostname originates',
14 'VERSION' => '1.4.8_1'
15 },
16 {
17 'NAME' => 'ImageMagick',
18 'DESCRIPTION' => 'Image processing tools',
19 'VERSION' => '6.7.0.10_1'
20 },
21 {
22 'NAME' => 'ORBit2',
23 'DESCRIPTION' => 'High-performance CORBA ORB with support for the C language',
24 'VERSION' => '2.14.19'
25 },
26 {
27 'NAME' => 'Ocsinventory-Agent',
28 'DESCRIPTION' => 'Keep track of the computers configuration and software',
29 'VERSION' => '1.1.2.1_1,1'
30 },
31 {
32 'NAME' => 'Ocsinventory-Agent',
33 'DESCRIPTION' => 'Keep track of the computers configuration and software',
34 'VERSION' => '2.0,1'
35 },
36 {
37 'NAME' => 'OpenEXR',
38 'DESCRIPTION' => 'A high dynamic-range (HDR) image file format',
39 'VERSION' => '1.6.1_3'
40 },
41 {
42 'NAME' => 'a2ps-a4',
43 'DESCRIPTION' => 'Formats an ascii file for printing on a postscript printer',
44 'VERSION' => '4.13b_4'
45 },
46 {
47 'NAME' => 'aalib',
48 'DESCRIPTION' => 'An ascii art library',
49 'VERSION' => '1.4.r5_6'
50 },
51 {
52 'NAME' => 'acidrip',
53 'DESCRIPTION' => 'GTK2::Perl wrapper for MPlayer and MEncoder for ripping DVD',
54 'VERSION' => '0.14_8'
55 },
56 {
57 'NAME' => 'acroread8',
58 'DESCRIPTION' => 'Adobe Reader for view, print, and search PDF documents (ENU',
59 'VERSION' => '8.1.7_3'
60 },
61 {
62 'NAME' => 'acroreadwrapper',
63 'DESCRIPTION' => 'Wrapper script for Adobe Reader',
64 'VERSION' => '0.0.20110920'
65 },
66 {
67 'NAME' => 'alsa-lib',
68 'DESCRIPTION' => 'ALSA compatibility library',
69 'VERSION' => '1.0.23'
70 },
71 {
72 'NAME' => 'ap22-mod_perl2',
73 'DESCRIPTION' => 'Embeds a Perl interpreter in the Apache2 server',
74 'VERSION' => '2.0.5_1,3'
75 },
76 {
77 'NAME' => 'apache',
78 'DESCRIPTION' => 'Version 2.2.x of Apache web server with prefork MPM.',
79 'VERSION' => '2.2.19'
80 },
81 {
82 'NAME' => 'apache-ant',
83 'DESCRIPTION' => 'Java- and XML-based build tool, conceptually similar to mak',
84 'VERSION' => '1.8.2'
85 },
86 {
87 'NAME' => 'appres',
88 'DESCRIPTION' => 'Program to list application\'s resources',
89 'VERSION' => '1.0.3'
90 },
91 {
92 'NAME' => 'apr-ipv6-devrandom-gdbm-db42',
93 'DESCRIPTION' => 'Apache Portability Library',
94 'VERSION' => '1.4.5.1.3.12'
95 },
96 {
97 'NAME' => 'aspell',
98 'DESCRIPTION' => 'Spelling checker with better suggestion logic than ispell',
99 'VERSION' => '0.60.6.1'
100 },
101 {
102 'NAME' => 'atk',
103 'DESCRIPTION' => 'A GNOME accessibility toolkit (ATK)',
104 'VERSION' => '2.0.1'
105 },
106 {
107 'NAME' => 'atkmm',
108 'DESCRIPTION' => 'C++ wrapper for ATK API library',
109 'VERSION' => '2.22.5'
110 },
111 {
112 'NAME' => 'attica',
113 'DESCRIPTION' => 'Collaboration Services API library',
114 'VERSION' => '0.2.80,1'
115 },
116 {
117 'NAME' => 'atunes',
118 'DESCRIPTION' => 'A full-featured audio player and manager developed in Java',
119 'VERSION' => '2.0.1'
120 },
121 {
122 'NAME' => 'audacity',
123 'DESCRIPTION' => 'Audacity is a GUI editor for digital audio waveforms',
124 'VERSION' => '1.2.4b_9'
125 },
126 {
127 'NAME' => 'autoconf',
128 'DESCRIPTION' => 'Automatically configure source code on many Un*x platforms ',
129 'VERSION' => '2.13.000227_6'
130 },
131 {
132 'NAME' => 'autoconf',
133 'DESCRIPTION' => 'Automatically configure source code on many Un*x platforms ',
134 'VERSION' => '2.68'
135 },
136 {
137 'NAME' => 'autoconf-wrapper',
138 'DESCRIPTION' => 'Wrapper script for GNU autoconf',
139 'VERSION' => '20101119'
140 },
141 {
142 'NAME' => 'automake',
143 'DESCRIPTION' => 'GNU Standards-compliant Makefile generator (1.11)',
144 'VERSION' => '1.11.1'
145 },
146 {
147 'NAME' => 'automake',
148 'DESCRIPTION' => 'GNU Standards-compliant Makefile generator (1.4)',
149 'VERSION' => '1.4.6_6'
150 },
151 {
152 'NAME' => 'automake-wrapper',
153 'DESCRIPTION' => 'Wrapper script for GNU automake',
154 'VERSION' => '20101119'
155 },
156 {
157 'NAME' => 'automoc4',
158 'DESCRIPTION' => 'Automatic moc for Qt 4 packages',
159 'VERSION' => '0.9.88_1'
160 },
161 {
162 'NAME' => 'avahi-app',
163 'DESCRIPTION' => 'Service discovery on a local network',
164 'VERSION' => '0.6.29'
165 },
166 {
167 'NAME' => 'b43-fwcutter',
168 'DESCRIPTION' => 'Extracts firmware for Broadcom Wireless adapters',
169 'VERSION' => '012'
170 },
171 {
172 'NAME' => 'babl',
173 'DESCRIPTION' => 'Dynamic pixel format conversion library',
174 'VERSION' => '0.1.4'
175 },
176 {
177 'NAME' => 'bash',
178 'DESCRIPTION' => 'The GNU Project\'s Bourne Again SHell',
179 'VERSION' => '4.1.11'
180 }
181 ]
182 );
183
184 plan tests => scalar keys %pkg_info_tests;
185
186 use Data::Dumper;
187 foreach my $test (keys %pkg_info_tests) {
188 my $file = "resources/bsd/pkg_info/$test";
189 my $results = FusionInventory::Agent::Task::Inventory::Input::BSD::Softwares::_getPackagesListFromPkgInfo(file => $file);
190 is_deeply($results, $pkg_info_tests{$test}, $test) or print Dumper($results);
191 }
+0
-221
t/inventory/linux/networks.t less more
0 #!/usr/bin/perl
1
2 use strict;
3 use warnings;
4
5 use Test::More;
6
7 use FusionInventory::Agent::Task::Inventory::Input::Linux::Networks;
8
9 my %ifconfig_tests = (
10 'dell-xt2' => [
11 {
12 MACADDR => 'A4:BA:DB:A5:F5:FA',
13 STATUS => 'Up',
14 TYPE => 'Ethernet',
15 DESCRIPTION => 'eth0',
16 IPMASK => '255.255.255.0',
17 IPADDRESS => '192.168.0.5',
18 IPADDRESS6 => 'fe80::a6ba:dbff:fea5:f5fa/64'
19 },
20 {
21 DESCRIPTION => 'lo',
22 STATUS => 'Up',
23 TYPE => 'Local',
24 IPMASK => '255.0.0.0',
25 IPADDRESS => '127.0.0.1',
26 IPADDRESS6 => '::1/128',
27 },
28 {
29 MACADDR => '4E:8C:81:ED:9B:35',
30 DESCRIPTION => 'pan0',
31 STATUS => 'Down',
32 TYPE => 'Ethernet',
33 },
34 {
35 DESCRIPTION => 'sit0',
36 STATUS => 'Down',
37 TYPE => 'IPv6-in-IPv4',
38 },
39 {
40 MACADDR => '00:24:D6:6F:81:3A',
41 STATUS => 'Up',
42 TYPE => 'Ethernet',
43 DESCRIPTION => 'wlan0',
44 IPMASK => '255.255.192.0',
45 IPADDRESS => '78.251.91.204',
46 IPADDRESS6 => 'fe80::224:d6ff:fe6f:813a/64'
47 }
48 ],
49 'linux-bonding' => [
50 {
51 IPMASK => '255.255.255.0',
52 MACADDR => '00:50:56:AD:00:0E',
53 DESCRIPTION => 'bond0',
54 STATUS => 'Up',
55 TYPE => 'Ethernet',
56 IPADDRESS6 => 'fe80::250:56ff:fead:e/64',
57 IPADDRESS => '192.168.1.181'
58 },
59 {
60 MACADDR => '00:50:56:AD:00:0E',
61 DESCRIPTION => 'eth0',
62 STATUS => 'Up',
63 TYPE => 'Ethernet'
64 },
65 {
66 IPMASK => '255.0.0.0',
67 DESCRIPTION => 'lo',
68 STATUS => 'Up',
69 TYPE => 'Local',
70 IPADDRESS6 => '::1/128',
71 IPADDRESS => '127.0.0.1'
72 }
73 ],
74 'linux-rhel5.6' => [
75 {
76 IPMASK => '255.255.252.0',
77 MACADDR => '00:1E:68:2F:85:D8',
78 DESCRIPTION => 'eth0',
79 STATUS => 'Up',
80 TYPE => 'Ethernet',
81 IPADDRESS6 => 'fe80::21e:68ff:fe2f:85d8/64',
82 IPADDRESS => '10.202.0.31'
83 },
84 {
85 IPMASK => '255.0.0.0',
86 DESCRIPTION => 'lo',
87 STATUS => 'Up',
88 TYPE => 'Local',
89 IPADDRESS6 => '::1/128',
90 IPADDRESS => '127.0.0.1'
91 },
92 {
93 MACADDR => '00:1E:68:2F:85:D8',
94 DESCRIPTION => 'peth0',
95 STATUS => 'Up',
96 TYPE => 'Ethernet',
97 IPADDRESS6 => 'fe80::21e:68ff:fe2f:85d8/64'
98 },
99 {
100 MACADDR => 'FE:FF:FF:FF:FF:FF',
101 DESCRIPTION => 'vif1.0',
102 STATUS => 'Up',
103 TYPE => 'Ethernet',
104 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
105 },
106 {
107 MACADDR => 'FE:FF:FF:FF:FF:FF',
108 DESCRIPTION => 'vif2.0',
109 STATUS => 'Up',
110 TYPE => 'Ethernet',
111 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
112 },
113 {
114 MACADDR => 'FE:FF:FF:FF:FF:FF',
115 DESCRIPTION => 'vif3.0',
116 STATUS => 'Up',
117 TYPE => 'Ethernet',
118 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
119 },
120 {
121 MACADDR => 'FE:FF:FF:FF:FF:FF',
122 DESCRIPTION => 'vif4.0',
123 STATUS => 'Up',
124 TYPE => 'Ethernet',
125 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
126 },
127 {
128 MACADDR => 'FE:FF:FF:FF:FF:FF',
129 DESCRIPTION => 'vif5.0',
130 STATUS => 'Up',
131 TYPE => 'Ethernet',
132 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
133 },
134 {
135 MACADDR => 'FE:FF:FF:FF:FF:FF',
136 DESCRIPTION => 'vif6.0',
137 STATUS => 'Up',
138 TYPE => 'Ethernet',
139 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
140 }
141 ]
142 );
143
144 my %ipaddrshow_tests = (
145 'ip_addr-1' => [
146 {
147 IPSUBNET => '127.0.0.0',
148 IPMASK => '255.0.0.0',
149 STATUS => 'Up',
150 DESCRIPTION => 'lo',
151 IPADDRESS6 => '::1',
152 IPADDRESS => '127.0.0.1'
153 },
154 {
155 IPSUBNET => '192.168.0.0',
156 IPMASK => '255.255.255.0',
157 MACADDR => '00:23:18:91:db:8d',
158 STATUS => 'Up',
159 DESCRIPTION => 'eth0',
160 IPADDRESS6 => 'fe80::223:18ff:fe91:db8d',
161 IPADDRESS => '192.168.0.10'
162 },
163 {
164 STATUS => 'Up',
165 DESCRIPTION => 'tun0'
166 },
167 {
168 STATUS => 'Up',
169 DESCRIPTION => 'tun1'
170 },
171 {
172 MACADDR => 'e8:39:df:3f:7d:ef',
173 STATUS => 'Down',
174 DESCRIPTION => 'wlan0'
175 }
176 ],
177 'ip_addr-2' => [
178 {
179 IPSUBNET => '127.0.0.0',
180 IPMASK => '255.0.0.0',
181 STATUS => 'Up',
182 DESCRIPTION => 'lo',
183 IPADDRESS6 => '::1',
184 IPADDRESS => '127.0.0.1'
185 },
186 {
187 IPSUBNET => '172.16.0.0',
188 IPMASK => '255.255.128.0',
189 MACADDR => '0f:0f:0f:0f:0f:0f',
190 STATUS => 'Up',
191 DESCRIPTION => 'eth0',
192 IPADDRESS6 => 'fe80::201:29ff:fed1:feb4',
193 IPADDRESS => '172.16.0.201'
194 },
195 {
196 STATUS => 'Down',
197 DESCRIPTION => 'eql'
198 },
199 {
200 STATUS => 'Down',
201 DESCRIPTION => 'sit0'
202 }
203 ]
204 );
205
206 plan tests =>
207 int (keys %ifconfig_tests) +
208 int (keys %ipaddrshow_tests);
209
210 foreach my $test (keys %ifconfig_tests) {
211 my $file = "resources/generic/ifconfig/$test";
212 my @results = FusionInventory::Agent::Task::Inventory::Input::Linux::Networks::_parseIfconfig(file => $file);
213 is_deeply(\@results, $ifconfig_tests{$test}, $test);
214 }
215
216 foreach my $test (keys %ipaddrshow_tests) {
217 my $file = "resources/linux/ip/$test";
218 my @results = FusionInventory::Agent::Task::Inventory::Input::Linux::Networks::_parseIpAddrShow(file => $file);
219 is_deeply(\@results, $ipaddrshow_tests{$test}, $test);
220 }
1010 '10.4-powerpc' => {
1111 MONITORS => [
1212 {
13 SERIAL => '',
14 MANUFACTURER => '',
1513 DESCRIPTION => 'ASUS VH222',
1614 CAPTION => 'ASUS VH222'
1715 }
3028 {
3129 MONITORS => [
3230 {
33 SERIAL => '',
34 MANUFACTURER => '',
3531 DESCRIPTION => 'ASUS VH222',
3632 CAPTION => 'ASUS VH222'
3733 }
4945 '10.6-intel' => {
5046 MONITORS => [
5147 {
52 SERIAL => '',
53 MANUFACTURER => '',
5448 DESCRIPTION => 'iMac',
5549 CAPTION => 'iMac'
5650 }
6862 '10.6.6-intel' => {
6963 MONITORS => [
7064 {
71 SERIAL => '',
72 MANUFACTURER => '',
7365 DESCRIPTION => 'Color LCD',
7466 CAPTION => 'Color LCD'
7567 }
7878 IPADDRESS => '192.168.20.1'
7979 }
8080 ],
81 'opensolaris' => [
82 {
83 'IPSUBNET' => '127.0.0.0',
84 'IPGATEWAY' => undef,
85 'IPMASK' => '255.0.0.0',
86 'DESCRIPTION' => 'lo0',
87 'STATUS' => 'Up',
88 'SPEED' => undef,
89 'IPADDRESS' => '127.0.0.1'
90 },
91 {
92 'IPGATEWAY' => undef,
93 'IPMASK' => '255.255.255.0',
94 'MACADDR' => '08:00:27:fc:ad:56',
95 'STATUS' => 'Up',
96 'SPEED' => undef,
97 'IPSUBNET' => '192.168.0.0',
98 'DESCRIPTION' => 'e1000g0',
99 'IPADDRESS' => '192.168.0.41'
100 },
101 {
102 'IPSUBNET' => undef,
103 'DESCRIPTION' => 'lo0',
104 'STATUS' => 'Up',
105 'SPEED' => undef
106 },
107 {
108 'IPSUBNET' => undef,
109 'MACADDR' => '08:00:27:fc:ad:56',
110 'DESCRIPTION' => 'e1000g0',
111 'STATUS' => 'Up',
112 'SPEED' => undef
113 },
114 {
115 'IPSUBNET' => undef,
116 'DESCRIPTION' => 'e1000g0:1',
117 'STATUS' => 'Up',
118 'SPEED' => undef
119 }
120 ]
81121
82122 );
83123
84124 plan tests =>
85125 int (keys %ifconfig_tests);
86126
127 use Data::Dumper;
87128 foreach my $test (keys %ifconfig_tests) {
88129 my $file = "resources/generic/ifconfig/$test";
89130 my @results = FusionInventory::Agent::Task::Inventory::Input::Solaris::Networks::_getInterfaces(file => $file);
90 is_deeply(\@results, $ifconfig_tests{$test}, $test);
131 is_deeply(\@results, $ifconfig_tests{$test}, $test) or print Dumper(\@results);
91132 }
92133
535535 'dell-xt2' => 'DFW1W11002SE002B3117'
536536 );
537537
538 my %ifconfig_tests = (
539 'dell-xt2' => [
540 {
541 MACADDR => 'A4:BA:DB:A5:F5:FA',
542 STATUS => 'Up',
543 TYPE => 'Ethernet',
544 DESCRIPTION => 'eth0',
545 IPMASK => '255.255.255.0',
546 IPADDRESS => '192.168.0.5',
547 IPADDRESS6 => 'fe80::a6ba:dbff:fea5:f5fa/64'
548 },
549 {
550 DESCRIPTION => 'lo',
551 STATUS => 'Up',
552 TYPE => 'Local',
553 IPMASK => '255.0.0.0',
554 IPADDRESS => '127.0.0.1',
555 IPADDRESS6 => '::1/128',
556 },
557 {
558 MACADDR => '4E:8C:81:ED:9B:35',
559 DESCRIPTION => 'pan0',
560 STATUS => 'Down',
561 TYPE => 'Ethernet',
562 },
563 {
564 DESCRIPTION => 'sit0',
565 STATUS => 'Down',
566 TYPE => 'IPv6-in-IPv4',
567 },
568 {
569 MACADDR => '00:24:D6:6F:81:3A',
570 STATUS => 'Up',
571 TYPE => 'Ethernet',
572 DESCRIPTION => 'wlan0',
573 IPMASK => '255.255.192.0',
574 IPADDRESS => '78.251.91.204',
575 IPADDRESS6 => 'fe80::224:d6ff:fe6f:813a/64'
576 }
577 ],
578 'linux-bonding' => [
579 {
580 IPMASK => '255.255.255.0',
581 MACADDR => '00:50:56:AD:00:0E',
582 DESCRIPTION => 'bond0',
583 STATUS => 'Up',
584 TYPE => 'Ethernet',
585 IPADDRESS6 => 'fe80::250:56ff:fead:e/64',
586 IPADDRESS => '192.168.1.181'
587 },
588 {
589 MACADDR => '00:50:56:AD:00:0E',
590 DESCRIPTION => 'eth0',
591 STATUS => 'Up',
592 TYPE => 'Ethernet'
593 },
594 {
595 IPMASK => '255.0.0.0',
596 DESCRIPTION => 'lo',
597 STATUS => 'Up',
598 TYPE => 'Local',
599 IPADDRESS6 => '::1/128',
600 IPADDRESS => '127.0.0.1'
601 }
602 ],
603 'linux-rhel5.6' => [
604 {
605 IPMASK => '255.255.252.0',
606 MACADDR => '00:1E:68:2F:85:D8',
607 DESCRIPTION => 'eth0',
608 STATUS => 'Up',
609 TYPE => 'Ethernet',
610 IPADDRESS6 => 'fe80::21e:68ff:fe2f:85d8/64',
611 IPADDRESS => '10.202.0.31'
612 },
613 {
614 IPMASK => '255.0.0.0',
615 DESCRIPTION => 'lo',
616 STATUS => 'Up',
617 TYPE => 'Local',
618 IPADDRESS6 => '::1/128',
619 IPADDRESS => '127.0.0.1'
620 },
621 {
622 MACADDR => '00:1E:68:2F:85:D8',
623 DESCRIPTION => 'peth0',
624 STATUS => 'Up',
625 TYPE => 'Ethernet',
626 IPADDRESS6 => 'fe80::21e:68ff:fe2f:85d8/64'
627 },
628 {
629 MACADDR => 'FE:FF:FF:FF:FF:FF',
630 DESCRIPTION => 'vif1.0',
631 STATUS => 'Up',
632 TYPE => 'Ethernet',
633 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
634 },
635 {
636 MACADDR => 'FE:FF:FF:FF:FF:FF',
637 DESCRIPTION => 'vif2.0',
638 STATUS => 'Up',
639 TYPE => 'Ethernet',
640 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
641 },
642 {
643 MACADDR => 'FE:FF:FF:FF:FF:FF',
644 DESCRIPTION => 'vif3.0',
645 STATUS => 'Up',
646 TYPE => 'Ethernet',
647 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
648 },
649 {
650 MACADDR => 'FE:FF:FF:FF:FF:FF',
651 DESCRIPTION => 'vif4.0',
652 STATUS => 'Up',
653 TYPE => 'Ethernet',
654 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
655 },
656 {
657 MACADDR => 'FE:FF:FF:FF:FF:FF',
658 DESCRIPTION => 'vif5.0',
659 STATUS => 'Up',
660 TYPE => 'Ethernet',
661 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
662 },
663 {
664 MACADDR => 'FE:FF:FF:FF:FF:FF',
665 DESCRIPTION => 'vif6.0',
666 STATUS => 'Up',
667 TYPE => 'Ethernet',
668 IPADDRESS6 => 'fe80::fcff:ffff:feff:ffff/64'
669 }
670 ]
671 );
672
673 my %ipaddrshow_tests = (
674 'ip_addr-1' => [
675 {
676 IPSUBNET => '127.0.0.0',
677 IPMASK => '255.0.0.0',
678 STATUS => 'Up',
679 DESCRIPTION => 'lo',
680 IPADDRESS6 => '::1',
681 IPADDRESS => '127.0.0.1'
682 },
683 {
684 IPSUBNET => '192.168.0.0',
685 IPMASK => '255.255.255.0',
686 MACADDR => '00:23:18:91:db:8d',
687 STATUS => 'Up',
688 DESCRIPTION => 'eth0',
689 IPADDRESS6 => 'fe80::223:18ff:fe91:db8d',
690 IPADDRESS => '192.168.0.10'
691 },
692 {
693 STATUS => 'Up',
694 DESCRIPTION => 'tun0'
695 },
696 {
697 STATUS => 'Up',
698 DESCRIPTION => 'tun1'
699 },
700 {
701 MACADDR => 'e8:39:df:3f:7d:ef',
702 STATUS => 'Down',
703 DESCRIPTION => 'wlan0'
704 }
705 ],
706 'ip_addr-2' => [
707 {
708 IPSUBNET => '127.0.0.0',
709 IPMASK => '255.0.0.0',
710 STATUS => 'Up',
711 DESCRIPTION => 'lo',
712 IPADDRESS6 => '::1',
713 IPADDRESS => '127.0.0.1'
714 },
715 {
716 IPSUBNET => '172.16.0.0',
717 IPMASK => '255.255.128.0',
718 MACADDR => '0f:0f:0f:0f:0f:0f',
719 STATUS => 'Up',
720 DESCRIPTION => 'eth0',
721 IPADDRESS6 => 'fe80::201:29ff:fed1:feb4',
722 IPADDRESS => '172.16.0.201'
723 },
724 {
725 STATUS => 'Down',
726 DESCRIPTION => 'eql'
727 },
728 {
729 STATUS => 'Down',
730 DESCRIPTION => 'sit0'
731 }
732 ]
733 );
734
538735 plan tests =>
539 (scalar keys %udev_tests) +
736 (scalar keys %udev_tests) +
540737 (scalar keys %cpuinfo_tests) +
541 (scalar keys %hal_tests) +
542 (scalar keys %smartctl_tests);
738 (scalar keys %hal_tests) +
739 (scalar keys %smartctl_tests) +
740 (scalar keys %ifconfig_tests) +
741 (scalar keys %ipaddrshow_tests);
543742
544743 foreach my $test (keys %udev_tests) {
545744 my $file = "resources/linux/udev/$test";
566765 my $result = getSerialnumber(file => $file);
567766 is($result, $smartctl_tests{$test}, "$test smartctl parsing");
568767 }
768
769 foreach my $test (keys %ifconfig_tests) {
770 my $file = "resources/generic/ifconfig/$test";
771 my @interfaces = getInterfacesFromIfconfig(file => $file);
772 is_deeply(\@interfaces, $ifconfig_tests{$test}, $test);
773 }
774
775 foreach my $test (keys %ipaddrshow_tests) {
776 my $file = "resources/linux/ip/$test";
777 my @interfaces = getInterfacesFromIp(file => $file);
778 is_deeply(\@interfaces, $ipaddrshow_tests{$test}, $test);
779 }
1818 );
1919
2020 my @hex2canonical_tests = (
21 [ 'ffffffff', '255.255.255.255' ],
22 [ '7f7f7f7f', '127.127.127.127' ]
21 [ 'ffffffff', '255.255.255.255' ],
22 [ '0xffffffff', '255.255.255.255' ],
23 [ '7f7f7f7f', '127.127.127.127' ],
24 [ '0x7f7f7f7f', '127.127.127.127' ]
2325 );
2426
2527 my @alt2canonical_tests = (
23482348 linux1 => {
23492349 '0.0.0.0' => '192.168.0.254',
23502350 '192.168.0.0' => '0.0.0.0'
2351 },
2352 macosx1 => {
2353 '192.168.0.254' => 'f4:ca:e5:42:38:37',
2354 '127.0.0.1' => '127.0.0.1',
2355 '192.168.0.27' => '127.0.0.1',
2356 'default' => '192.168.0.254'
23512357 }
23522358 );
23532359