File Coverage

blib/lib/Sys/Info/Driver/Linux/OS.pm
Criterion Covered Total %
statement 139 163 85.2
branch 21 52 40.3
condition 5 24 20.8
subroutine 29 30 96.6
pod 16 16 100.0
total 210 285 73.6


line stmt bran cond sub pod time code
1             package Sys::Info::Driver::Linux::OS;
2             $Sys::Info::Driver::Linux::OS::VERSION = '0.7905';
3 1     1   21159 use strict;
  1         3  
  1         28  
4 1     1   9 use warnings;
  1         3  
  1         34  
5 1     1   5 use base qw( Sys::Info::Base );
  1         2  
  1         117  
6 1     1   440 use POSIX ();
  1         5884  
  1         28  
7 1     1   22 use Cwd;
  1         2  
  1         78  
8 1     1   5 use Carp qw( croak );
  1         2  
  1         34  
9 1     1   367 use Sys::Info::Driver::Linux;
  1         2  
  1         42  
10 1     1   359 use Sys::Info::Driver::Linux::Constants qw( :all );
  1         2  
  1         169  
11 1     1   6 use constant FSTAB_LENGTH => 6;
  1         1  
  1         1761  
12              
13             ##no critic (InputOutput::ProhibitBacktickOperators)
14              
15             sub init {
16 1     1 1 2179 my $self = shift;
17 1         8 $self->{OSVERSION} = undef; # see _populate_osversion
18 1         3 $self->{FILESYSTEM} = undef; # see _populate_fs
19 1         3 return;
20             }
21              
22             # unimplemented
23       1 1   sub logon_server {}
24              
25             sub edition {
26 1     1 1 365 return shift->_populate_osversion->{OSVERSION}{RAW}{EDITION};
27             }
28              
29             sub tz {
30 2     2 1 485 my $self = shift;
31 2 50       60 return if ! -e proc->{timezone};
32 2         10 chomp( my $rv = $self->slurp( proc->{timezone} ) );
33 2         242 return $rv;
34             }
35              
36             sub meta {
37 1     1 1 15 my $self = shift->_populate_osversion;
38              
39 1         12 require POSIX;
40 1         4 require Sys::Info::Device;
41              
42 1         11 my $cpu = Sys::Info::Device->new('CPU');
43 1         119 my $arch = ($cpu->identify)[0]->{architecture};
44 1         72 my %mem = $self->_parse_meminfo;
45 1         11 my @swaps = $self->_parse_swap;
46 1         2 my %info;
47              
48 1         5 $info{manufacturer} = $self->{OSVERSION}{MANUFACTURER};
49 1         3 $info{build_type} = undef;
50 1         2 $info{owner} = undef;
51 1         3 $info{organization} = undef;
52 1         2 $info{product_id} = undef;
53 1         4 $info{install_date} = $self->{OSVERSION}{RAW}{BUILD_DATE};
54 1         2 $info{boot_device} = undef;
55              
56 1         4 $info{physical_memory_total} = $mem{MemTotal};
57 1         2 $info{physical_memory_available} = $mem{MemFree};
58 1         2 $info{page_file_total} = $mem{SwapTotal};
59 1         2 $info{page_file_available} = $mem{SwapFree};
60              
61             # windows specific
62 1         4 $info{windows_dir} = undef;
63 1         2 $info{system_dir} = undef;
64              
65 1         2 $info{system_manufacturer} = undef;
66 1         2 $info{system_model} = undef;
67 1         8 $info{system_type} = sprintf '%s based Computer', $arch;
68              
69 1         2 $info{page_file_path} = join ', ', map { $_->{Filename} } @swaps;
  1         6  
70              
71 1         64 return %info;
72             }
73              
74             sub tick_count {
75 2     2 1 4 my $self = shift;
76 2   50     8 my $uptime = $self->slurp( proc->{uptime} ) || return 0;
77 2         256 my @uptime = split /\s+/xms, $uptime;
78             # this file has two entries. uptime is the first one. second: idle time
79 2         13 return $uptime[UP_TIME];
80             }
81              
82             sub name {
83 3     3 1 38 my($self, @args) = @_;
84 3         40 $self->_populate_osversion;
85 3 50       13 my %opt = @args % 2 ? () : @args;
86 3 100       8 my $id = $opt{long} ? 'LONGNAME' : 'NAME';
87 3 100       23 return $self->{OSVERSION}{ $opt{edition} ? $id . '_EDITION' : $id };
88             }
89              
90 1     1 1 4 sub version { return shift->_populate_osversion->{OSVERSION}{VERSION} }
91 1     1 1 4 sub build { return shift->_populate_osversion->{OSVERSION}{RAW}{BUILD_DATE} }
92 1     1 1 8 sub uptime { return time - shift->tick_count }
93              
94             # user methods
95             sub is_root {
96 9 50   9 1 4729 return 0 if defined &Sys::Info::EMULATE;
97 9         21 my $name = login_name();
98 9         896 my $id = POSIX::geteuid();
99 9         386 my $gid = POSIX::getegid();
100 9 50       241 return 0 if $@;
101 9 50 33     35 return 0 if ! defined $id || ! defined $gid;
102 9   33     348 return $id == 0 && $gid == 0 && $name eq 'root';
103             }
104              
105             sub login_name {
106 11     11 1 5618 my($self, @args) = @_;
107 11 50       48 my %opt = @args % 2 ? () : @args;
108 11   50     218 my $login = POSIX::getlogin() || return;
109 0 0       0 my $rv = eval { $opt{real} ? (getpwnam $login)[REAL_NAME_FIELD] : $login };
  0         0  
110 0 0       0 $rv =~ s{ [,]{3,} \z }{}xms if $opt{real};
111 0         0 return $rv;
112             }
113              
114 2     2 1 516 sub node_name { return shift->uname->{nodename} }
115              
116             sub domain_name {
117 2     2 1 507 my $self = shift;
118             # hmmmm...
119 2         11 foreach my $line ( $self->read_file( proc->{resolv} ) ) {
120 6         225 chomp $line;
121 6 100       21 if ( $line =~ m{\A domain \s+ (.*) \z}xmso ) {
122 2         10 return $1;
123             }
124             }
125 0         0 my $sys = qx{dnsdomainname 2> /dev/null};
126 0         0 return $sys;
127             }
128              
129             sub fs {
130 1     1 1 4 my $self = shift;
131 1         13 $self->{current_dir} = Cwd::getcwd();
132              
133 1         3 my(@fstab, @junk, $re);
134 1         6 foreach my $line( $self->read_file( proc->{fstab} ) ) {
135 1         113 chomp $line;
136 1 50       9 next if $line =~ m{ \A \# }xms;
137 0         0 @junk = split /\s+/xms, $line;
138 0 0 0     0 next if ! @junk || @junk != FSTAB_LENGTH;
139 0 0       0 next if lc($junk[FS_TYPE]) eq 'swap'; # ignore swaps
140 0         0 $re = $junk[MOUNT_POINT];
141 0 0       0 next if $self->{current_dir} !~ m{\Q$re\E}xmsi;
142 0         0 push @fstab, [ $re, $junk[FS_TYPE] ];
143             }
144              
145 1 50       11 @fstab = reverse sort { $a->[0] cmp $b->[0] } @fstab if @fstab > 1;
  0         0  
146 1         5 my $fstype = $fstab[0]->[1];
147 1         11 my $attr = $self->_fs_attributes( $fstype );
148             return
149             filesystem => $fstype,
150 1 50       13 ($attr ? %{$attr} : ())
  0         0  
151             ;
152             }
153              
154 1 50   1 1 258 sub bitness { return shift->uname->{machine} =~ m{64}xms ? '64' : '32' }
155              
156             # ------------------------[ P R I V A T E ]------------------------ #
157              
158             sub _parse_meminfo {
159 1     1   6 my $self = shift;
160 1         2 my %mem;
161 1         7 foreach my $line ( split /\n/xms, $self->slurp( proc->{meminfo} ) ) {
162 45         590 chomp $line;
163 45         82 my($k, $v) = split /:/xms, $line;
164             # units in KB
165 45         98 $mem{ $k } = (split /\s+/xms, $self->trim( $v ) )[0];
166             }
167 1         30 return %mem;
168             }
169              
170             sub _parse_swap {
171 1     1   3 my $self = shift;
172 1         4 my @swaps = split /\n/xms, $self->slurp( proc->{swaps} );
173 1         126 my @swap_title = split /\s+/xms, shift @swaps;
174 1         3 my @swap_list;
175 1         2 foreach my $line ( @swaps ) {
176 1         3 chomp $line;
177 1         5 my @data = split /\s+/xms, $line;
178             push @swap_list,
179             {
180 1         3 map { $swap_title[$_] => $data[$_] } 0..$#swap_title
  5         15  
181             };
182             }
183 1         4 return @swap_list;
184             }
185              
186             sub _ip {
187 0     0   0 my $self = shift;
188 0         0 my $cmd = q{/sbin/ifconfig};
189 0 0 0     0 return if ! -e $cmd || ! -x _;
190 0         0 my $raw = qx($cmd);
191 0 0       0 return if not $raw;
192 0         0 my @raw = split /inet addr/xms, $raw;
193 0 0 0     0 return if ! @raw || @raw < 2 || ! $raw[1];
      0        
194 0 0       0 if ( $raw[1] =~ m{(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})}xms ) {
195 0         0 return $1;
196             }
197 0         0 return;
198             }
199              
200             sub _populate_osversion {
201 7     7   20 my $self = shift;
202 7 100       60 return $self if $self->{OSVERSION};
203 1         575 require Sys::Info::Driver::Linux::OS::Distribution;
204 1         11 my $distro = Sys::Info::Driver::Linux::OS::Distribution->new;
205 1         3 my $osname = $distro->name;
206 1         3 my $V = $distro->version;
207 1         3 my $edition = $distro->edition;
208 1         3 my $kernel = $distro->kernel;
209 1         3 my $build = $distro->build;
210 1         4 my $build_date = $distro->build_date;
211 1   50     4 my $manufacturer = $distro->manufacturer || q{};
212              
213             $self->{OSVERSION} = {
214 1 50       18 NAME => $osname,
    50          
    50          
215             NAME_EDITION => $edition ? "$osname ($edition)" : $osname,
216             LONGNAME => q{}, # will be set below
217             LONGNAME_EDITION => q{}, # will be set below
218             VERSION => $V,
219             KERNEL => $kernel,
220             MANUFACTURER => $manufacturer,
221             RAW => {
222             BUILD => defined $build ? $build : 0,
223             BUILD_DATE => defined $build_date ? $build_date : 0,
224             EDITION => $edition,
225             },
226             };
227              
228 1         2 my $o = $self->{OSVERSION};
229 1         2 my $t = '%s %s (kernel: %s)';
230 1         6 $o->{LONGNAME} = sprintf $t, $o->{NAME}, $o->{VERSION}, $kernel;
231 1         4 $o->{LONGNAME_EDITION} = sprintf $t, $o->{NAME_EDITION}, $o->{VERSION}, $kernel;
232 1         12 return $self;
233             }
234              
235             sub _fs_attributes {
236 1     1   2 my $self = shift;
237 1         2 my $fs = shift;
238              
239             return {
240             ext3 => {
241             case_sensitive => 1, #'supports case-sensitive filenames',
242             preserve_case => 1, #'preserves the case of filenames',
243             unicode => 1, #'supports Unicode in filenames',
244             #acl => '', #'preserves and enforces ACLs',
245             #file_compression => '', #'supports file-based compression',
246             #disk_quotas => '', #'supports disk quotas',
247             #sparse => '', #'supports sparse files',
248             #reparse => '', #'supports reparse points',
249             #remote_storage => '', #'supports remote storage',
250             #compressed_volume => '', #'is a compressed volume (e.g. DoubleSpace)',
251             #object_identifiers => '', #'supports object identifiers',
252             efs => '1', #'supports the Encrypted File System (EFS)',
253             #max_file_length => '';
254             },
255 1         49 }->{$fs};
256             }
257              
258             1;
259              
260             =pod
261              
262             =encoding UTF-8
263              
264             =head1 NAME
265              
266             Sys::Info::Driver::Linux::OS
267              
268             =head1 VERSION
269              
270             version 0.7905
271              
272             =head1 SYNOPSIS
273              
274             -
275              
276             =head1 DESCRIPTION
277              
278             -
279              
280             =head1 NAME
281              
282             Sys::Info::Driver::Linux::OS - Linux backend
283              
284             =head1 METHODS
285              
286             Please see L<Sys::Info::OS> for definitions of these methods and more.
287              
288             =head2 build
289              
290             =head2 domain_name
291              
292             =head2 edition
293              
294             =head2 fs
295              
296             =head2 init
297              
298             =head2 is_root
299              
300             =head2 login_name
301              
302             =head2 logon_server
303              
304             =head2 meta
305              
306             =head2 name
307              
308             =head2 node_name
309              
310             =head2 tick_count
311              
312             =head2 tz
313              
314             =head2 uptime
315              
316             =head2 version
317              
318             =head2 bitness
319              
320             =head1 SEE ALSO
321              
322             L<Sys::Info>, L<Sys::Info::OS>,
323             The C</proc> virtual filesystem:
324             L<http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/ref-guide/s1-proc-topfiles.html>.
325              
326             =head1 AUTHOR
327              
328             Burak Gursoy <burak@cpan.org>
329              
330             =head1 COPYRIGHT AND LICENSE
331              
332             This software is copyright (c) 2006 by Burak Gursoy.
333              
334             This is free software; you can redistribute it and/or modify it under
335             the same terms as the Perl 5 programming language system itself.
336              
337             =cut
338              
339             __END__
340              
341             sub _fetch_user_info {
342             my %user;
343             $user{NAME} = POSIX::getlogin();
344             $user{REAL_USER_ID} = POSIX::getuid(); # $< uid
345             $user{EFFECTIVE_USER_ID} = POSIX::geteuid(); # $> effective uid
346             $user{REAL_GROUP_ID} = POSIX::getgid(); # $( guid
347             $user{EFFECTIVE_GROUP_ID} = POSIX::getegid(); # $) effective guid
348             my %junk;
349             # quota, comment & expire are unreliable
350             @junk{qw(name passwd uid gid
351             quota comment gcos dir shell expire)} = getpwnam($user{NAME});
352             $user{REAL_NAME} = defined $junk{gcos} ? $junk{gcos} : '';
353             $user{COMMENT} = defined $junk{comment} ? $junk{comment} : '';
354             return %user;
355             }
356