1package File::ExtAttr; 2 3=head1 NAME 4 5File::ExtAttr - Perl extension for accessing extended attributes of files 6 7=head1 SYNOPSIS 8 9 use File::ExtAttr ':all'; 10 use IO::File; 11 12 # Manipulate the extended attributes of files. 13 setfattr('foo.txt', 'colour', 'red') || die; 14 my $colour = getfattr('bar.txt', 'colour'); 15 if (defined($colour)) 16 { 17 print $colour; 18 delfattr('bar.txt', 'colour'); 19 } 20 21 # Manipulate the extended attributes of a file via a file handle. 22 my $fh = new IO::File('<foo.txt') || die; 23 setfattr($fh, 'colour', 'red') || die; 24 25 $fh = new IO::File('<bar.txt') || die; 26 $colour = getfattr($fh, 'colour'); 27 if (defined($colour)) 28 { 29 print $colour; 30 delfattr($fh, 'colour'); 31 } 32 33 # List attributes in the default namespace. 34 print "Attributes of bar.txt:\n"; 35 foreach (listfattr($fh)) 36 { 37 print "\t$_\n"; 38 } 39 40 # Examine attributes in a namespace-aware manner. 41 my @namespaces = listfattrns($fh); 42 43 foreach my $ns (@namespaces) 44 { 45 print "Attributes in namespace '$ns': "; 46 my @attrs = listfattr($fh, { namespace => $ns }); 47 print join(',', @attrs)."\n"; 48 } 49 50=head1 DESCRIPTION 51 52File::ExtAttr is a Perl module providing access to the extended attributes 53of files. 54 55Extended attributes are metadata associated with a file. 56Examples are access control lists (ACLs) and other security parameters. 57But users can add their own key=value pairs. 58 59Extended attributes may not be supported by your operating system. 60This module is aimed at Linux, Unix or Unix-like operating systems 61(e.g.: Mac OS X, FreeBSD, NetBSD, Solaris). 62 63Extended attributes may also not be supported by your filesystem 64or require special options to be enabled for a particular filesystem. 65E.g.: 66 67 mount -o user_xattr /dev/hda1 /some/path 68 69=head2 Supported OSes 70 71=over 4 72 73=item Linux 74 75=item Mac OS X 76 77=item FreeBSD 5.0 and later 78 79=item NetBSD 4.0 and later 80 81=item Solaris 10 and later 82 83=back 84 85=head2 Unsupported OSes 86 87=over 4 88 89=item OpenBSD 90 91=back 92 93=head2 Namespaces 94 95Some implementations of extended attributes support namespacing. 96In those implementations, the attribute is referred to by namespace 97and attribute name. 98 99=over 4 100 101=item Linux 102 103The primary namespaces are C<user> for user programs; 104C<security>, C<system> and C<trusted> for file security/access-control. 105See L<http://www.die.net/doc/linux/man/man5/attr.5.html> 106for more details. 107 108Namespaces on Linux are described by a string, but only certain values 109are supported by filesystems. In general C<user>, C<security>, C<system> 110and C<trusted> are supported, by others may be supported -- 111e.g.: C<os2> on JFS. File::Extattr will be able to access any of these. 112 113=item FreeBSD, NetBSD 114 115*BSD have two namespaces: C<user> and C<system>. 116 117Namespaces on *BSD are described by an integer. File::ExtAttr will only 118be able to access attributes in C<user> and C<system>. 119 120=item Mac OS X 121 122OS X has no support for namespaces. 123 124=item Solaris 125 126Solaris has no support for namespaces. 127 128=back 129 130=head2 Flags 131 132The functions take a hash reference as their final parameter, 133which can specify flags to modify the behaviour of the functions. 134The flags specific to a function are documented in the function's 135description. 136 137All functions support a C<namespace> flag. E.g.: 138 139 use File::ExtAttr ':all'; 140 use IO::File; 141 142 # Manipulate the extended attributes of files. 143 setfattr('foo.txt', 'colour', 'red') || die; 144 my $colour = getfattr('bar.txt', 'colour', { namespace => 'user'); 145 146If no namespace is specified, the default namespace will be used. 147On Linux and *BSD the default namespace will be C<user>. 148 149=cut 150 151use strict; 152use warnings; 153use Carp; 154use Scalar::Util; 155 156require Exporter; 157use AutoLoader; 158 159our @ISA = qw(Exporter); 160 161# Items to export into callers namespace by default. Note: do not export 162# names by default without a very good reason. Use EXPORT_OK instead. 163# Do not simply export all your public functions/methods/constants. 164 165# This allows declaration use File::ExtAttr ':all'; 166# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK 167# will save memory. 168our %EXPORT_TAGS = ( 'all' => [ qw( 169 getfattr 170 setfattr 171 delfattr 172 listfattr 173 listfattrns 174) ] ); 175 176our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); 177 178our @EXPORT = qw( 179); 180 181our $VERSION = '1.09'; 182 183#this is used by getxattr(), needs documentation 184$File::ExtAttr::MAX_INITIAL_VALUELEN = 255; 185 186require XSLoader; 187XSLoader::load('File::ExtAttr', $VERSION); 188 189# Preloaded methods go here. 190 191=head1 METHODS 192 193=over 4 194 195=cut 196 197sub _is_fh 198{ 199 my $file = shift; 200 my $is_fh = 0; 201 202 eval 203 { 204 # TODO: Does this work with Perl 5.005, 5.6.x? 205 # Relies on autovivification of filehandles? 206 $is_fh = 1 if ($file->isa('IO::Handle')); 207 208 # TODO: Does this work with Perl 5.005, 5.6.x? 209 # Better solution for detecting a file handle? 210 $is_fh = 1 if (openhandle($file)); 211 }; 212 213 return $is_fh; 214} 215 216=item getfattr([$filename | $filehandle], $attrname, [\%flags]) 217 218Return the value of the attribute named C<$attrname> 219for the file named C<$filename> or referenced by the open filehandle 220C<$filehandle> (which should be an IO::Handle or subclass thereof). 221 222If no attribute is found, returns C<undef>. Otherwise gives a warning. 223 224=cut 225 226sub getfattr 227{ 228 my $file = shift; 229 230 return _is_fh($file) 231 # File handle 232 ? _fgetfattr($file->fileno(), @_) 233 # Filename 234 : _getfattr($file, @_); 235} 236 237=item setfattr([$filename | $filehandle], $attrname, $attrval, [\%flags]) 238 239Set the attribute named C<$attrname> with the value C<$attrval> 240for the file named C<$filename> or referenced by the open filehandle 241C<$filehandle> (which should be an IO::Handle or subclass thereof). 242 243C<%flags> allows control of whether the attribute should be created 244or should replace an existing attribute's value. If the key C<create> 245is true, setfattr will fail if the attribute already exists. If the key 246C<replace> is true, setfattr will fail if the attribute 247does not already exist. If neither is specified, then the attribute 248will be created (if necessary) or silently replaced. 249 250If the attribute could not be set, a warning is issued. 251 252Note that C<create> cannot be implemented in a race-free manner on *BSD. 253If your code relies on the C<create> behaviour, it may be insecure on *BSD. 254 255=cut 256 257sub setfattr 258{ 259 my ($file, $attrname, $attrval, $flagsref) = @_; 260 261 die "Only one of the 'create' and 'replace' options can be passed to setfattr" 262 if ($flagsref->{create} && $flagsref->{replace}); 263 264 return _is_fh($file) 265 # File handle 266 ? _fsetfattr($file->fileno(), $attrname, $attrval, $flagsref) 267 # Filename 268 : _setfattr($file, $attrname, $attrval, $flagsref); 269} 270 271=item delfattr([$filename | $filehandle], $attrname, [\%flags]) 272 273Delete the attribute named C<$attrname> for the file named C<$filename> 274or referenced by the open filehandle C<$filehandle> 275(which should be an IO::Handle or subclass thereof). 276 277Returns true on success, otherwise false and a warning is issued. 278 279=cut 280 281sub delfattr 282{ 283 my $file = shift; 284 285 return _is_fh($file) 286 # File handle 287 ? _fdelfattr($file->fileno(), @_) 288 # Filename 289 : _delfattr($file, @_); 290} 291 292=item listfattr([$filename | $filehandle], [\%flags]) 293 294Return an array of the attributes on the file named C<$filename> 295or referenced by the open filehandle C<$filehandle> (which should be 296an IO::Handle or subclass thereof). 297 298Returns undef on failure and $! will be set. 299 300=cut 301 302sub listfattr 303{ 304 my $file = shift; 305 306 return _is_fh($file) 307 # File handle 308 ? _listfattr('', $file->fileno(), @_) 309 # Filename 310 : _listfattr($file, -1, @_); 311} 312 313=item listfattrns([$filename | $filehandle], [\%flags]) 314 315Return an array containing the namespaces of attributes on the file named 316C<$filename> or referenced by the open filehandle C<$filehandle> 317(which should be an IO::Handle or subclass thereof). 318 319Returns undef on failure and $! will be set. 320 321=cut 322 323sub listfattrns 324{ 325 my $file = shift; 326 327 return _is_fh($file) 328 # File handle 329 ? _listfattrns('', $file->fileno(), @_) 330 # Filename 331 : _listfattrns($file, -1, @_); 332} 333 334=back 335 336=cut 337 338# TODO: l* functions 339 340=head1 EXPORT 341 342None by default. 343 344You can request that C<getfattr>, C<setfattr>, C<delfattr> 345and C<listfattr> be exported using the tag ":all". 346 347=head2 Exportable constants 348 349None 350 351=head1 BUGS 352 353You cannot set empty attributes on Mac OS X 10.4 and earlier. 354This is a bug in Darwin, rather than File::ExtAttr. 355 356=head1 SEE ALSO 357 358The latest version of this software should be available from its 359home page: L<http://sourceforge.net/projects/file-extattr/> 360 361L<OS2::ExtAttr> provides access to extended attributes on OS/2. 362 363Eiciel, L<http://rofi.pinchito.com/eiciel/>, is an access control list (ACL) 364editor for GNOME; the ACLs are stored in extended attributes. 365 366Various low-level APIs exist for manipulating extended attributes: 367 368=over 4 369 370=item Linux 371 372getattr(2), attr(5) 373 374L<http://www.die.net/doc/linux/man/man2/getxattr.2.html> 375 376L<http://www.die.net/doc/linux/man/man5/attr.5.html> 377 378=item OpenBSD 379 380OpenBSD 3.7 supported extended attributes, although support was never 381built into the default GENERIC kernel. Its support was documented 382in the C<extattr> man page: 383 384L<http://www.openbsd.org/cgi-bin/man.cgi?query=extattr_get_file&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html> 385 386Support was removed in OpenBSD 3.8 -- see the CVS history 387for the include file C<sys/extattr.h>. 388 389L<http://www.openbsd.org/cgi-bin/cvsweb/src/sys/sys/Attic/extattr.h> 390 391=item FreeBSD 392 393FreeBSD >= 5.0 supports extended attributes. 394 395extattr(2) 396 397L<http://www.freebsd.org/cgi/man.cgi?query=extattr&sektion=2&apropos=0&manpath=FreeBSD+6.0-RELEASE+and+Ports> 398 399=item NetBSD 400 401NetBSD >= 3.0 supports extended attributes, but you'll need to use 402NetBSD >= 4.0 to get UFS filesystem support for them. 403 404L<http://netbsd.gw.com/cgi-bin/man-cgi?extattr_get_file+2+NetBSD-current> 405 406L<http://www.netbsd.org/Changes/changes-4.0.html#ufs> 407 408=item Mac OS X 409 410getxattr(2) 411 412L<http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/getxattr.2.html> 413 414L<http://arstechnica.com/reviews/os/macosx-10.4.ars/7> 415 416=item Solaris 417 418attropen(3C), fsattr(5) 419 420L<http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWaman/hman3c/attropen.3c.html> 421 422L<http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWaman/hman5/fsattr.5.html> 423 424Solaris also has extensible system attributes, which are used 425by Solaris's CIFS support on ZFS, and have a confusingly similar 426name to extended file attributes. These system attributes are stored 427in extended file attributes called SUNWattr_ro and SUNWattr_rw. 428See PSARC 2007/315 for more details: 429 430L<http://opensolaris.org/os/community/arc/caselog/2007/315/spec-final-txt/> 431 432=back 433 434=head1 AUTHOR 435 436Kevin M. Goess, E<lt>kgoess@ensenda.comE<gt> 437 438Richard Dawe, E<lt>richdawe@cpan.orgE<gt> 439 440=head1 COPYRIGHT AND LICENSE 441 442Copyright (C) 2005 by Kevin M. Goess 443 444Copyright (C) 2005, 2006, 2007, 2008 by Richard Dawe 445 446This library is free software; you can redistribute it and/or modify 447it under the same terms as Perl itself, either Perl version 5.8.5 or, 448at your option, any later version of Perl 5 you may have available. 449 450=cut 451 4521; 453__END__ 454