File Coverage

blib/lib/File/Stat/ModeString.pm
Criterion Covered Total %
statement 72 72 100.0
branch 7 8 87.5
condition n/a
subroutine 12 12 100.0
pod 0 4 0.0
total 91 96 94.7


line stmt bran cond sub pod time code
1             package File::Stat::ModeString;
2              
3             =head1 NAME
4              
5             File::Stat::ModeString - conversion file stat(2) mode to/from string representation.
6              
7             =head1 SYNOPSIS
8              
9             use File::Stat::ModeString;
10              
11             $string = mode_to_string ( $st_mode );
12             $st_mode = string_to_mode ( $string );
13             $type = mode_to_typechar( $st_mode );
14              
15             $record = ; chomp $record;
16             $record =~ m/^some_prefix\s+$MODE_STRING_RE\s+some_suffix$/o
17             or die "invalid record format";
18              
19             die "Invalid mode in $string"
20             if is_mode_string_valid( $string );
21              
22              
23             =head1 DESCRIPTION
24              
25             This module provides a few functions for conversion between
26             binary and literal representations of file mode bits,
27             including file type.
28              
29             All of them use only symbolic constants for mode bits
30             from B.
31              
32              
33             =cut
34              
35             require 5.005;
36 1     1   11750 use strict;
  1         2  
  1         56  
37             local $^W=1; # use warnings only since 5.006
38 1     1   2230 use integer;
  1         11  
  1         5  
39              
40 1     1   27 use Carp;
  1         6  
  1         70  
41 1     1   1232 use File::Stat::Bits;
  1         5565  
  1         331  
42              
43              
44             BEGIN
45             {
46 1     1   6 use Exporter;
  1         2  
  1         42  
47 1         821 use vars qw($VERSION @ISA @EXPORT $MODE_STRING_RE
48             @type_to_char %char_to_typemode %ugorw_to_mode %ugox_to_mode
49 1     1   5 @perms_clnid @perms_setid @perms_stick);
  1         2  
50              
51 1     1   2 $VERSION = do { my @r = (q$Revision: 0.28 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
  1         8  
  1         7  
52              
53 1         16 @ISA = ('Exporter');
54              
55 1         4 @EXPORT = qw( &is_mode_string_valid $MODE_STRING_RE
56             &mode_to_typechar &mode_to_string &string_to_mode
57             );
58              
59 1         2 @type_to_char = ();
60 1         4 $type_to_char[S_IFDIR >> 9] = 'd';
61 1         7 $type_to_char[S_IFCHR >> 9] = 'c';
62 1         14 $type_to_char[S_IFBLK >> 9] = 'b';
63 1         8 $type_to_char[S_IFREG >> 9] = '-';
64 1         9 $type_to_char[S_IFIFO >> 9] = 'p';
65 1         5 $type_to_char[S_IFLNK >> 9] = 'l';
66 1         7 $type_to_char[S_IFSOCK >> 9] = 's';
67              
68 1         6 @perms_clnid = qw(--- --x -w- -wx r-- r-x rw- rwx);
69 1         3 @perms_setid = qw(--S --s -wS -ws r-S r-s rwS rws);
70 1         3 @perms_stick = qw(--T --t -wT -wt r-T r-t rwT rwt);
71              
72 1         3 %char_to_typemode =
73             (
74             'd' => S_IFDIR ,
75             'c' => S_IFCHR ,
76             'b' => S_IFBLK ,
77             '-' => S_IFREG ,
78             'p' => S_IFIFO ,
79             'l' => S_IFLNK ,
80             's' => S_IFSOCK
81             );
82              
83 1         24 %ugorw_to_mode =
84             (
85             'u--' => 0,
86             'ur-' => S_IRUSR,
87             'u-w' => S_IWUSR,
88             'urw' => S_IRUSR|S_IWUSR,
89              
90             'g--' => 0,
91             'gr-' => S_IRGRP,
92             'g-w' => S_IWGRP,
93             'grw' => S_IRGRP|S_IWGRP,
94              
95             'o--' => 0,
96             'or-' => S_IROTH,
97             'o-w' => S_IWOTH,
98             'orw' => S_IROTH|S_IWOTH
99             );
100              
101 1         25 %ugox_to_mode =
102             (
103             'u-' => 0,
104             'ux' => S_IXUSR,
105             'us' => S_IXUSR|S_ISUID,
106             'uS' => S_ISUID,
107              
108             'g-' => 0,
109             'gx' => S_IXGRP,
110             'gs' => S_IXGRP|S_ISGID,
111             'gS' => S_ISGID,
112              
113             'o-' => 0,
114             'ox' => S_IXOTH,
115             'ot' => S_IXOTH|S_ISVTX,
116             'oT' => S_ISVTX,
117             );
118             }
119              
120              
121             =head1 CONSTANTS
122              
123             =head2 $MODE_STRING_RE
124              
125             Regular expression to match mode string (without ^$).
126              
127             =cut
128              
129             BEGIN {
130 1     1   1426 $MODE_STRING_RE = '[-dcbpls]([r-][w-][xsS-]){2}?[r-][w-][xtT-]';
131             }
132              
133              
134              
135             =head1 FUNCTIONS
136              
137             =head2
138              
139             is_mode_string_valid( $string )
140              
141             Returns true if argument matches mode string pattern.
142              
143             =cut
144             sub is_mode_string_valid
145             {
146 28672     28672 0 1507354 my $string = shift;
147              
148 28672         153946 return $string =~ m/^$MODE_STRING_RE$/o;
149             }
150              
151              
152             =head2
153              
154             $type = mode_to_typechar( $mode )
155              
156             Returns file type character of binary mode, '?' on unknown file type.
157              
158             =cut
159             sub mode_to_typechar
160             {
161 57344     57344 0 1449954 my $mode = shift;
162 57344         132039 my $type = $type_to_char[ ($mode & S_IFMT) >> 9 ];
163 57344 50       334235 return defined $type ? $type : '?';
164             }
165              
166              
167             =head2
168              
169             $string = mode_to_string( $mode )
170              
171             Converts binary mode value to string representation.
172             '?' in file type field on unknown file type.
173              
174             =cut
175             sub mode_to_string
176             {
177 28672     28672 0 1160431 my $mode = shift;
178 28672         32998 my $string;
179             my $perms;
180              
181 28672         42854 $string = mode_to_typechar($mode);
182              
183             # user
184 28672 100       72406 $perms = ( $mode & S_ISUID ) ? \@perms_setid : \@perms_clnid;
185 28672         155461 $string .= $perms->[($mode & S_IRWXU) >> 6];
186              
187             # group
188 28672 100       137164 $perms = ( $mode & S_ISGID ) ? \@perms_setid : \@perms_clnid;
189 28672         155710 $string .= $perms->[($mode & S_IRWXG) >> 3];
190              
191             # other
192 28672 100       136244 $perms = ( $mode & S_ISVTX ) ? \@perms_stick : \@perms_clnid;
193 28672         166139 $string .= $perms->[($mode & S_IRWXO)];
194              
195 28672         128156 return $string;
196             }
197              
198              
199             =head2
200              
201             $mode = string_to_mode( $string )
202              
203             Converts string representation of file mode to binary one.
204              
205             =cut
206             sub string_to_mode
207             {
208 28672     28672 0 50333 my $string = shift;
209 28672         144990 my @list = split //, $string;
210 28672         46126 my $mode = 0;
211 28672         28646 my $char;
212              
213             # type
214 28672         40763 $char = shift @list;
215 28672         48258 $mode |= $char_to_typemode{$char};
216              
217             # user read | write
218 28672         49212 $char = 'u' . shift(@list) . shift(@list);
219 28672         51318 $mode |= $ugorw_to_mode{$char};
220              
221             # user execute
222 28672         42422 $char = 'u' . shift @list;
223 28672         52439 $mode |= $ugox_to_mode{$char};
224              
225             # group read | write
226 28672         43693 $char = 'g' . shift(@list) . shift(@list);
227 28672         47468 $mode |= $ugorw_to_mode{$char};
228              
229             # group execute
230 28672         43602 $char = 'g' . shift @list;
231 28672         37227 $mode |= $ugox_to_mode{$char};
232              
233             # others read | write
234 28672         44208 $char = 'o' . shift(@list) . shift(@list);
235 28672         50241 $mode |= $ugorw_to_mode{$char};
236              
237             # others execute
238 28672         35034 $char = 'o' . shift @list;
239 28672         44096 $mode |= $ugox_to_mode{$char};
240              
241              
242 28672         73511 return $mode;
243             }
244              
245              
246             =head1 SEE ALSO
247              
248             L;
249              
250             L;
251              
252             L;
253              
254             =head1 AUTHOR
255              
256             Dmitry Fedorov
257              
258             =head1 COPYRIGHT
259              
260             Copyright (C) 2003 Dmitry Fedorov
261              
262             =head1 LICENSE
263              
264             This program is free software; you can redistribute it and/or modify
265             it under the terms of the GNU General Public License as published by
266             the Free Software Foundation; either version 2 of the License,
267             or (at your option) any later version.
268              
269             =head1 DISCLAIMER
270              
271             The author disclaims any responsibility for any mangling of your system
272             etc, that this script may cause.
273              
274             =cut
275              
276              
277             1;
278