1############################################################
2#
3#   $Id: Unix.pm 185 2010-07-15 19:25:30Z trevor $
4#   Sys::Filesystem - Retrieve list of filesystems and their properties
5#
6#   Copyright 2004,2005,2006 Nicola Worthington
7#   Copyright 2009           Jens Rehsack
8#
9#   Licensed under the Apache License, Version 2.0 (the "License");
10#   you may not use this file except in compliance with the License.
11#   You may obtain a copy of the License at
12#
13#       http://www.apache.org/licenses/LICENSE-2.0
14#
15#   Unless required by applicable law or agreed to in writing, software
16#   distributed under the License is distributed on an "AS IS" BASIS,
17#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18#   See the License for the specific language governing permissions and
19#   limitations under the License.
20#
21############################################################
22
23package Sys::Filesystem::Unix;
24
25# vim:ts=4:sw=4:tw=78
26
27use strict;
28use Carp qw(croak);
29use Fcntl qw(:flock);
30use IO::File;
31
32use vars qw($VERSION);
33$VERSION = '1.30';
34
35sub version()
36{
37    return $VERSION;
38}
39
40# Default fstab and mtab layout
41my @keys = qw(fs_spec fs_file fs_vfstype fs_mntops fs_freq fs_passno);
42my %special_fs = (
43                   swap => 1,
44                   proc => 1
45                 );
46
47sub new
48{
49    ref( my $class = shift ) && croak 'Class name required';
50    my %args = @_;
51    my $self = bless( {}, $class );
52
53    # Defaults
54    $args{fstab} ||= '/etc/fstab';
55    $args{mtab}  ||= '/etc/mtab';
56
57    # $args{xtab}  ||= '/etc/lib/nfs/xtab';
58
59    $self->readFsTab( $args{fstab}, \@keys, [ 0, 1, 2 ], \%special_fs );
60    $self->readMntTab( $args{mtab}, \@keys, [ 0, 1, 2 ], \%special_fs );
61
62    $self;
63}
64
65sub readFsTab($\@\@\%)
66{
67    my ( $self, $fstabPath, $fstabKeys, $pridx, $special_fs ) = @_;
68
69    # Read the fstab
70    local $/ = "\n";
71    if ( my $fstab = IO::File->new( $fstabPath, 'r' ) )
72    {
73        while (<$fstab>)
74        {
75            next if ( /^\s*#/ || /^\s*$/ );
76
77            # $_ =~ s/#.*$//;
78            # next if( /^\s*$/ );
79
80            my @vals = split( ' ', $_ );
81            $self->{ $vals[ $pridx->[1] ] }->{mount_point} = $vals[ $pridx->[1] ];
82            $self->{ $vals[ $pridx->[1] ] }->{device}      = $vals[ $pridx->[0] ];
83            $self->{ $vals[ $pridx->[1] ] }->{unmounted}   = 1
84              unless ( defined( $self->{ $vals[ $pridx->[1] ] }->{mounted} ) );
85
86            if ( defined( $pridx->[2] ) )
87            {
88                my $vfs_type = $self->{ $vals[ $pridx->[1] ] }->{fs_vfstype} = $vals[ $pridx->[2] ];
89                $self->{ $vals[ $pridx->[1] ] }->{special} = 1 if ( defined( $special_fs->{$vfs_type} ) );
90            }
91            else
92            {
93                $self->{ $vals[ $pridx->[1] ] }->{special} = 0
94                  unless ( defined( $self->{ $vals[ $pridx->[1] ] }->{special} ) );
95            }
96
97            for ( my $i = 0; $i < @{$fstabKeys}; ++$i )
98            {
99                $self->{ $vals[ $pridx->[1] ] }->{ $fstabKeys->[$i] } = defined( $vals[$i] ) ? $vals[$i] : '';
100            }
101        }
102        $fstab->close();
103        1;
104    }
105    else
106    {
107        0;
108    }
109}
110
111sub readMntTab($\@\@\%)
112{
113    my ( $self, $mnttabPath, $mnttabKeys, $pridx, $special_fs ) = @_;
114
115    # Read the mtab
116    local $/ = "\n";
117    my $mtab;
118    if ( ( $mtab = IO::File->new( $mnttabPath, 'r' ) ) && flock( $mtab, LOCK_SH | LOCK_NB ) )
119    {
120        while (<$mtab>)
121        {
122            next if ( /^\s*#/ || /^\s*$/ );
123
124            # $_ =~ s/#.*$//;
125            # next if( /^\s*$/ );
126
127            my @vals = split( /\s+/, $_ );
128            delete $self->{ $vals[ $pridx->[1] ] }->{unmounted}
129              if ( exists( $self->{ $vals[ $pridx->[1] ] }->{unmounted} ) );
130            $self->{ $vals[ $pridx->[1] ] }->{mounted}     = 1;
131            $self->{ $vals[ $pridx->[1] ] }->{mount_point} = $vals[ $pridx->[1] ];
132            $self->{ $vals[ $pridx->[1] ] }->{device}      = $vals[ $pridx->[0] ];
133
134            if ( defined( $pridx->[2] ) )
135            {
136                my $vfs_type = $self->{ $vals[ $pridx->[1] ] }->{fs_vfstype} = $vals[ $pridx->[2] ];
137                $self->{ $vals[ $pridx->[1] ] }->{special} = 1 if ( defined( $special_fs->{$vfs_type} ) );
138            }
139            else
140            {
141                $self->{ $vals[ $pridx->[1] ] }->{special} = 0
142                  unless ( defined( $self->{ $vals[ $pridx->[1] ] }->{special} ) );
143            }
144
145            for ( my $i = 0; $i < @{$mnttabKeys}; ++$i )
146            {
147                $self->{ $vals[ $pridx->[1] ] }->{ $mnttabKeys->[$i] } = defined( $vals[$i] ) ? $vals[$i] : '';
148            }
149        }
150        $mtab->close();
151        1;
152    }
153    else
154    {
155        0;
156    }
157}
158
159sub readMounts
160{
161    my ( $self, $mount_rx, $pridx, $keys, $special, @lines ) = @_;
162
163    foreach my $line (@lines)
164    {
165        if ( my @vals = $line =~ $mount_rx )
166        {
167            $self->{ $vals[ $pridx->[1] ] }->{mount_point} = $vals[ $pridx->[1] ];
168            $self->{ $vals[ $pridx->[1] ] }->{device}      = $vals[ $pridx->[0] ];
169            $self->{ $vals[ $pridx->[1] ] }->{mounted}     = 1;
170            delete $self->{ $vals[ $pridx->[1] ] }->{unmounted}
171              if ( exists( $self->{ $vals[ $pridx->[1] ] }->{unmounted} ) );
172
173            if ( defined( $pridx->[2] ) )
174            {
175                my $vfs_type = $self->{ $vals[ $pridx->[1] ] }->{fs_vfstype} = $vals[ $pridx->[2] ];
176                $self->{ $vals[ $pridx->[1] ] }->{special} = 1 if ( defined( $special->{$vfs_type} ) );
177            }
178            elsif ( !defined( $self->{ $vals[ $pridx->[1] ] }->{special} ) )
179            {
180                $self->{ $vals[ $pridx->[1] ] }->{special} = 0;
181            }
182
183            for ( my $i = 0; $i < @{$keys}; ++$i )
184            {
185                $self->{ $vals[ $pridx->[1] ] }->{ $keys->[$i] } = defined( $vals[$i] ) ? $vals[$i] : '';
186            }
187        }
188    }
189
190    $self;
191}
192
193sub readSwap
194{
195    my ( $self, $swap_rx, @lines ) = @_;
196    foreach my $line (@lines)
197    {
198        if ( my ($dev) = $line =~ $swap_rx )
199        {
200            $self->{none}->{mount_point} ||= 'none';
201            $self->{none}->{device}     = $dev;
202            $self->{none}->{fs_vfstype} = 'swap';
203            $self->{none}->{mounted}    = 1;
204            $self->{none}->{special}    = 1;
205            delete $self->{none}->{unmounted};
206        }
207    }
208    $self;
209}
210
2111;
212
213=pod
214
215=head1 NAME
216
217Sys::Filesystem::Unix - Return generic Unix filesystem information to Sys::Filesystem
218
219=head1 SYNOPSIS
220
221See L<Sys::Filesystem>.
222
223=head1 INHERITANCE
224
225  Sys::Filesystem::Unix
226  ISA UNIVERSAL
227
228=head1 METHODS
229
230=over 4
231
232=item version()
233
234Return the version of the (sub)module.
235
236=item readFsTab
237
238This method provides the capability to parse a standard unix fstab file.
239
240It expects following arguments:
241
242=over 8
243
244=item fstabPath
245
246Full qualified path to the fstab file to read.
247
248=item fstabKeys
249
250The column names for the fstab file through an array reference.
251
252=item special_fs
253
254Hash reference containing the names of all special file systems having a true
255value as key.
256
257=back
258
259This method return true in case the specified file could be opened for reading,
260false otherwise.
261
262=item readMntTab
263
264This method provides the capability to read abd parse a standard unix
265mount-tab file. The file is locked using flock after opening it.
266
267It expects following arguments:
268
269=over 8
270
271=item mnttabPath
272
273Full qualified path to the mnttab file to read.
274
275=item mnttabKeys
276
277The column names for the mnttab file through an array reference.
278
279=item $special_fs
280
281Hash reference containing the names of all special file systems having a true
282value as key.
283
284=back
285
286This method return true in case the specified file could be opened for reading
287and locked, false otherwise.
288
289=item readMounts
290
291This method is called to parse the information got from C<mount> system command.
292It expects following arguments:
293
294=over 8
295
296=item mount_rx
297
298Regular expression to extract the information from each mount line.
299
300=item pridx
301
302Array reference containing the index for primary keys of interest in match
303in following order: device, mount_point, type.
304
305=item keys
306
307Array reference of the columns of the match - in order of paranteses in
308regular expression.
309
310=item special
311
312Array reference containing the names of the special file system types.
313
314=item lines
315
316Array containing the lines to parse.
317
318=back
319
320=item readSwap
321
322This method is called to parse the information from the swap status.
323It expects following arguments:
324
325=over 8
326
327=item swap_rx
328
329Regular expression to extract the information from each swap status line.
330This regular expression should have exact one pair of parantheses to
331identify the swap device.
332
333=item lines
334
335Array containing the lines to parse.
336
337=back
338
339=back
340
341=head1 VERSION
342
343$Id: Unix.pm 185 2010-07-15 19:25:30Z trevor $
344
345=head1 AUTHOR
346
347Nicola Worthington <nicolaw@cpan.org> - L<http://perlgirl.org.uk>
348
349Jens Rehsack <rehsack@cpan.org> - L<http://www.rehsack.de/>
350
351=head1 COPYRIGHT
352
353Copyright 2004,2005,2006 Nicola Worthington.
354Copyright 2008-2010 Jens Rehsack.
355
356This software is licensed under The Apache Software License, Version 2.0.
357
358L<http://www.apache.org/licenses/LICENSE-2.0>
359
360=cut
361
362