File Coverage

blib/lib/Linux/Ext2/FileAttributes.pm
Criterion Covered Total %
statement 24 46 52.1
branch 0 14 0.0
condition n/a
subroutine 8 13 61.5
pod n/a
total 32 73 43.8


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Linux::Ext2::FileAttributes - Access to Ext2/3 filesystem extended attributes
4              
5             =head1 SYNOPSIS
6              
7             use Linux::Ext2::FileAttributes;
8              
9             my $logfile = '/var/log/notreal';
10             my $unchanging = '/etc/motd';
11              
12             # set immutable flag on $unchanging
13             set_immutable( $unchanging );
14              
15             # set append flag on $logfile
16             set_append_only( $logfile );
17              
18             # check if a file is immutable
19             print "[$unchanging] is immutable\n" if is_immutable( $unchanging );
20              
21             =head1 DESCRIPTION
22              
23             Linux::Ext2::FileAttributes provides access to the Ext2 and Ext3
24             filesystem extended attributes from within perl.
25              
26             This module is pure perl and doesn't require or use the external L
27             or L binaries which can save a lot of load when doing filesystem
28             traversal and modification
29              
30             =cut
31              
32              
33             package Linux::Ext2::FileAttributes;
34 1     1   74502 use strict;
  1         3  
  1         35  
35 1     1   5 use warnings;
  1         2  
  1         35  
36              
37             # The first constant is from http://www.netadmintools.com/html/2ioctl_list.man.html
38             # Hard coding these removes the dependency on h2ph
39              
40 1     1   5 use constant EXT2_IOC_GETFLAGS => 0x80046601;
  1         5  
  1         79  
41 1     1   5 use constant EXT2_IOC_SETFLAGS => 0x40046602;
  1         1  
  1         50  
42 1     1   5 use constant EXT2_IMMUTABLE_FL => 16;
  1         1  
  1         41  
43 1     1   5 use constant EXT2_APPEND_FL => 32;
  1         2  
  1         43  
44              
45             require Exporter;
46 1     1   5 use vars qw(@EXPORT @ISA $VERSION);
  1         1  
  1         348  
47              
48             #--------------------------------#
49              
50             @ISA = qw(Exporter);
51             @EXPORT = qw(
52             is_immutable clear_immutable set_immutable
53             is_append_only clear_append_only set_append_only
54             );
55              
56             $VERSION = '0.01';
57              
58              
59             #--------------------------------#
60              
61             my %constants = (
62             immutable => EXT2_IMMUTABLE_FL,
63             append_only => EXT2_APPEND_FL,
64             );
65              
66             =head1 FUNCTIONS
67              
68             By default this module exports:
69             is_immutable clear_immutable set_immutable
70             is_append_only clear_append_only set_append_only
71              
72             =over 4
73              
74             =item set_immutable
75              
76             This function takes a filename and attempts to set its immutable flag.
77              
78             If this flag is set on a file, even root cannot change the files content
79             without first removing the flag.
80              
81             =item is_immutable
82              
83             This function takes a filename and returns true if the immutable flag is
84             set and false if it isn't.
85              
86             =item clear_immutable
87              
88             This function takes a filename and removes the immutable flag if it
89             is present.
90              
91             =item set_append_only
92              
93             This function takes a filename and attempts to set its appendable flag.
94              
95             If this flag is set on a file then its contents can be added to but not
96             removed unless the flag is first removed.
97              
98             =item is_append_only
99              
100             This function takes a filename and returns true if the immutable flag is
101             set and false if it isn't.
102              
103             =item clear_append_only
104              
105             This function takes a filename and removes the appendable flag if it
106             is present.
107              
108             =back
109              
110             =cut
111              
112             # generate get, set and clear methods for each value in
113             # %constants (above)
114              
115             for my $name (keys %constants) {
116             my $is_sub = sub {
117 0     0     my $file = shift;
118 0           my $flags = _get_ext2_attributes($file);
119 0 0         return unless defined $flags;
120 0           return $flags & $constants{ $name };
121             };
122              
123             my $set_sub = sub {
124 0     0     my $file = shift;
125 0           my $flags = _get_ext2_attributes($file);
126 0 0         return unless defined $flags;
127 0           return _set_ext2_attributes($file, $flags | $constants{ $name });
128             };
129              
130             my $clear_sub = sub {
131 0     0     my $file = shift;
132 0           my $flags = _get_ext2_attributes($file);
133 0 0         return unless defined $flags;
134 0           return _set_ext2_attributes($file, $flags & ~$constants{ $name } );
135             };
136              
137 1     1   5 no strict 'refs';
  1         1  
  1         251  
138             *{__PACKAGE__ . '::is_' . $name } = $is_sub;
139             *{__PACKAGE__ . '::set_' . $name } = $set_sub;
140             *{__PACKAGE__ . '::clear_' . $name } = $clear_sub;
141             }
142              
143             #--------------------------------#
144              
145             # TODO
146             # export in an expert tag in 0.2
147             # also export the hash of constants above.
148              
149             sub _get_ext2_attributes {
150 0     0     my $file = shift;
151 0 0         open my $fh, $file
152             or return;
153 0           my $res = pack 'i', 0;
154 0 0         return unless defined ioctl($fh, EXT2_IOC_GETFLAGS, $res);
155 0           $res = unpack 'i', $res;
156             }
157              
158             sub _set_ext2_attributes {
159 0     0     my $file = shift;
160 0           my $flags = shift;
161 0 0         open my $fh, $file
162             or return;
163 0           my $flag = pack 'i', $flags;
164 0 0         return unless defined ioctl($fh, EXT2_IOC_SETFLAGS, $flag);
165             }
166              
167             # export as expert tag ########################
168              
169              
170              
171              
172             #--------------------------------l
173              
174             # END OF MODULE CODE
175              
176             1;
177              
178             #--------------------------------#
179              
180              
181             =head1 DEPENDENCIES
182              
183             Linux::Ext2::FileAttributes has no external dependencies.
184              
185             =head1 TESTS
186              
187             As Linux::Ext2::FileAttributes is something of a niche module, which
188             requires an Ext2/Ext3 file system and root powers to run, I've placed
189             some test longer scripts in the examples directory to both show how to
190             us it and provide another set of tests for detecting regressions.
191              
192             =head1 SEE ALSO
193              
194             Filesys::Ext2 provides a different interface to some of the same
195             information. That module wraps the command line tools (lsattr and
196             chattr) rather than speaking directly to the ioctl.
197              
198             L
199              
200             Native Ext2 commands:
201              
202             L, L
203              
204             =head1 LICENCE AND COPYRIGHT
205              
206             Copyright (C) 2008 Dean Wilson. All Rights Reserved.
207              
208             This module is free software; you can redistribute it and/or modify it
209             under the same terms as Perl itself.
210              
211             =head1 AUTHOR
212              
213             Dean Wilson
214              
215             =head1 ACKNOWLEDGEMENTS
216              
217             Richard Clamp did the heavy lifting on this module and taught me a
218             fair chunk about using ioctls in perl while doing it. The cool stuff's
219             his. The errors are mine.
220              
221             =cut