Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

How do I access FAT file attributes from Linux?

by Anonymous Monk
on Apr 02, 2010 at 16:05 UTC ( [id://832507]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I have a FAT file system mounted in Linux (SD card). I want to access and reset the "archive flag" on the files on the card. I have tried the File::Atrributes module, but the array returned by list_attributes is empty, as is the hash returned by get_attributes. Is there a way to do this in Perl? Do I need to tell File::Attributes which file system I want to use?

Replies are listed 'Best First'.
Re: How do I access FAT file attributes from Linux?
by jfroebe (Parson) on Apr 02, 2010 at 18:26 UTC
Re: How do I access FAT file attributes from Linux?
by ambrus (Abbot) on Apr 03, 2010 at 15:18 UTC

    Linux does have a native way to access FAT attributes of a mounted FAT filesystem, it's just not easy to find documentation about it. The interface is an ioctl.

    First, let's import some constants from a linux header file (you could just hardcode the numbers but this is more elegant).

    Create FatConst.xs with the following contents. (By the way, does someone know if I'm supposed to use ExtUtils::Constant?)

    #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = FatConst PACKAGE = FatConst #include "linux/msdos_fs.h" I32 ATTR_RO() CODE: RETVAL = ATTR_RO; OUTPUT: RETVAL
    int FAT_IOCTL_GET_ATTRIBUTES() CODE: RETVAL = FAT_IOCTL_GET_ATTRIBUTES; OUTPUT: RETVAL int FAT_IOCTL_SET_ATTRIBUTES() CODE: RETVAL = FAT_IOCTL_SET_ATTRIBUTES; OUTPUT: RETVAL # END

    Create FatConst.pm with the following contents.

    use warnings; use strict; package FatConst; use Exporter; use DynaLoader; use Fcntl; our $VERSION = 1.00; our @ISA = (Exporter::, DynaLoader::); bootstrap FatConst::; our @EXPORT = qw" ATTR_RO ATTR_HIDDEN ATTR_SYS ATTR_VOLUME ATTR_DIR ATTR_ARCH fat_get_attr fat_format_attr "; our @EXPORT_OK = qw" FAT_IOCTL_GET_ATTRIBUTES FAT_IOCTL_SET_ATTRIBUTES "; sub fat_get_attr { my($fname) = @_; sysopen my $F, $fname, O_RDONLY() or return; my $o = pack "x8"; ioctl $F, FAT_IOCTL_GET_ATTRIBUTES(), $o or return; return unpack "L", $o; } sub fat_format_attr { my($n) = @_; my $o = ""; for my $i (0 .. 7) { $o = ($n & (1 << $i) ? substr("RHSVDAXY", $i, 1) : " ") . $o; } $o; } 1; __END__

    Create Makefile.PL with the following contents.

    use warnings; use strict; use ExtUtils::MakeMaker; WriteMakefile( NAME => "FatConst", VERSION_FROM => "FatConst.pm", );

    Now compile the module we've created with perl Makefile.PL && make

    I have mounted a vfat filesystem to /mnt/s0, let's test reading file attributes with the above module on it. I run this command.

    sudo -u oper perl -I./blib/arch -we 'use FatConst; my $d = $ARGV[0]; opendir my $D, $d or die; while (my $b = readdir $D) { my +$n = $d . "/" . $b; my $err = !defined(my $a = fat_get_attr($n)); pri +ntf "%8s %s\n", ($err ? "E" : fat_format_attr($a)), $n; }' /mnt/s0

    And the output is

    Setting the attributes (instead of getting them) should be similar and is left as an exercise to the reader.

    Update: changed type of ioctl constants from I32 to int, for that's the more correct type, though they mean the same.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://832507]
Approved by moritz
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2024-04-26 01:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found