]> arthur.barton.de Git - netatalk.git/blobdiff - contrib/shell_utils/apple_dump.in
Merge remote branch 'sf/develop' into develop
[netatalk.git] / contrib / shell_utils / apple_dump.in
index 65eec7908e0b4ea2c61e5f52308a1c2b5f537a13..e207151d5c3f1d625a1e7ac953f21efc3a3859b7 100755 (executable)
@@ -2,7 +2,7 @@
 #
 # AppleSingle/AppleDouble dump
 #
-# (c) 2009-2010 by HAT <hat@fa2.so-net.ne.jp>
+# (c) 2009-2012 by HAT <hat@fa2.so-net.ne.jp>
 #
 #  This program is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
-# 
+#
 
-# 
+#
 # References:
-# 
+#
 # Applesingle and AppleDouble format internals (version 1)
 # http://users.phg-online.de/tk/netatalk/doc/Apple/v1/
-# 
+#
 # AppleSingle/AppleDouble Formats for Foreign Files Developer's Note (version2)
 # http://users.phg-online.de/tk/netatalk/doc/Apple/v2/AppleSingle_AppleDouble.pdf
-# 
+#
 # Inside Macintosh: Macintosh Toolbox Essentials /
 # Chapter 7 - Finder Interface / Finder Interface Reference
 # http://developer.apple.com/legacy/mac/library/documentation/mac/toolbox/Toolbox-463.html
-# 
+#
 # Finder Interface Reference
 # http://developer.apple.com/legacy/mac/library/documentation/Carbon/Reference/Finder_Interface/Reference/reference.html
-# 
+#
 # Technical Note TN1150  HFS Plus Volume Format
 # http://developer.apple.com/mac/library/technotes/tn/tn1150.html#FinderInfo
-# 
+#
 # CarbonHeaders source
 # http://www.opensource.apple.com/source/CarbonHeaders/CarbonHeaders-8A428/Finder.h
 # http://www.opensource.apple.com/source/CarbonHeaders/CarbonHeaders-9A581/Finder.h
-# 
+#
 # Xcode 3.2.1
 # /usr/bin/SetFile
 # /usr/bin/GetFileInfo
-# 
+#
 # Mac OS X 10.6.2 kernel source
 # http://www.opensource.apple.com/source/xnu/xnu-1486.2.11/bsd/vfs/vfs_xattr.c
-# 
+#
 
 use File::Basename;
 use File::Spec;
+use File::Temp qw /tempfile/;
 use bigint; # require perl >= 5.8
 
+# check command for extended attributes -----------------------------------
+
+if (     0 == system("which getfattr > /dev/null 2>&1")) {
+    $eacommand = 1;
+} elsif (0 == system("which xattr > /dev/null 2>&1")) {
+    $eacommand = 2;
+} elsif (0 == system("which runat > /dev/null 2>&1")) {
+    $eacommand = 3;
+} elsif (0 == system("which getextattr > /dev/null 2>&1")) {
+    $eacommand = 4;
+} else {
+    $eacommand = 0;
+}
+
+#printf ( "eacommand = %d\n", $eacommand );   # debug
+
 # parse command line -----------------------------------------------
 
+$stdinputmode = 0;
+$eaoption = 0;
 $finderinfo = 0;              #  0: unknown   1: file   2: directory
 while ($arg = shift @ARGV)
 {
     if  ($arg =~ /^(-h|-help|--help)$/ ) {
-        printf ("usage: %s [-a] FILE|DIR\n"           ,basename($0));
-        printf (" or:   %s -f FILE\n"                 ,basename($0));
-        printf (" or:   %s -d FILE\n"                 ,basename($0));
+        printf ("usage: %s [-a] [FILE|DIR]\n"         ,basename($0));
+        printf (" or:   %s -e FILE|DIR\n"             ,basename($0));
+        printf (" or:   %s -f [FILE]\n"               ,basename($0));
+        printf (" or:   %s -d [FILE]\n"               ,basename($0));
         printf (" or:   %s -h|-help|--help\n"         ,basename($0));
         printf (" or:   %s -v|-version|--version\n"   ,basename($0));
-        printf ("Dump AppleSingle/AppleDouble format file.\n");
+        printf ("Dump AppleSingle/AppleDouble format data.\n");
+        printf ("With no FILE|DIR, or when FILE|DIR is -, read standard input.\n");
         printf ("\n");
-        printf ("  -a (default)     Dump a AppleSingle/AppleDouble file for FILE or DIR\n");
+        printf ("  -a (default)     Dump a AppleSingle/AppleDouble data for FILE or DIR\n");
         printf ("                   automatically.\n");
-        printf ("                   Extrapolate FinderInfo type from absolute path.\n");
         printf ("                   If FILE is not AppleSingle/AppleDouble format,\n");
-        printf ("                   look for '.AppleDouble/FILE' and '._FILE'.\n");
-        printf ("                   If DIR, look for 'DIR/.AppleDouble/.Parent' and '._DIR'.\n");
+        printf ("                   look for extended attribute, .AppleDouble/FILE and ._FILE.\n");
+        printf ("                   If DIR, look for extended attribute,\n");
+        printf ("                   DIR/.AppleDouble/.Parent and ._DIR.\n");
+        printf ("  -e               Dump extended attribute of FILE or DIR\n");
         printf ("  -f               Dump FILE. Assume FinderInfo to be FileInfo.\n");
         printf ("  -d               Dump FILE. Assume FinderInfo to be DirInfo.\n");
         printf ("  -h,-help,--help  Display this help and exit\n");
@@ -78,7 +100,7 @@ while ($arg = shift @ARGV)
         printf ("By default, %s examins whether file or directory,\n"   ,basename($0));
         printf ("a parent directory is .AppleDouble, filename is ._*, filename is .Parent,\n");
         printf ("and so on.\n");
-        printf ("If setting option -f or -d, %s assume FinderInfo and doesn't look for\n");
+        printf ("If setting option -e, -f or -d, %s assume FinderInfo and doesn't look for\n");
         printf ("another file.\n");
         exit 1;
     } elsif ($arg =~ /^(-v|-version|--version)$/ ) {
@@ -86,25 +108,32 @@ while ($arg = shift @ARGV)
         exit 1;
     } elsif ($arg eq "-a") {
         $finderinfo = 0;
+    } elsif ($arg eq "-e") {
+        if ($eacommand == 0) {
+            printf (STDERR "%s: unsupported option -e\n", basename($0));
+            printf (STDERR "because neither getfattr, xattr nor runat is found.\n");
+            exit 1;
+        }
+        $eaoption = 1;
     } elsif ($arg eq "-f") {
         $finderinfo = 1;
     } elsif ($arg eq "-d") {
         $finderinfo = 2;
+    } elsif ($arg eq "-") {
+        $stdinputmode = 1;
     } elsif ($arg =~ /^-/) {
-       printf (STDERR "%s: invalid option %s\n", basename($0), $arg);
-       printf (STDERR "Try \`%s\ -h' for more information.\n", basename($0));
-       exit 1;
+        printf (STDERR "%s: invalid option %s\n", basename($0), $arg);
+        printf (STDERR "Try \`%s\ -h' for more information.\n", basename($0));
+        exit 1;
     } else {
         $afile = $arg;
     }
 }
 
 if (!($afile)) {
-    printf (STDERR "missing file operand.\n");
-    exit 1;
-}
-if (!( -e $afile)) {
-    printf (STDERR "\"%s\" not found.\n", $afile);
+    $stdinputmode = 1;
+} elsif (!( -e $afile)) {
+    printf (STDERR "\"%s\" is not found.\n", $afile);
     exit 1;
 }
 
@@ -113,80 +142,131 @@ if (!( -e $afile)) {
 $abspath = File::Spec->rel2abs($afile);
 ($basename, $path, $ext) = fileparse($abspath);
 
-if ( $finderinfo != 0 ) {
-    ;
+if ( $stdinputmode == 1) {
+    ($eatempfh, $openfile) = tempfile(UNLINK => 1);
+    system("cat - > $openfile");
+    close($eatempfh);
+    $openmessage = "Dumping Standard Input...\n";
+} elsif ( $eaoption == 1 ) {
+    if ( -f $afile ) {
+        $finderinfo = 1;
+    } elsif ( -d $afile ) {
+        $finderinfo = 2;
+    } else {
+        printf (STDERR "unknown error: %s\n", $afile);
+        exit 1;
+    }
+    if ( 0 == checkea($afile) ) {
+        printf (STDERR "\"%s\"'s extended attribute is not found\n",  $afile);
+        exit 1;
+    }
+    $openfile = eaopenfile($afile);
+    $openmessage = "Dumping \"$afile\"'s extended attribute...\n";
+} elsif ( $finderinfo != 0 ) {
+    $openfile = $afile;
+    $openmessage = "Dumping \"$openfile\"...\n";
 } elsif ( -f $afile ) {
     if ( $basename eq ".Parent") {
-       $finderinfo = 2;
+        $finderinfo = 2;
     } elsif ( $path =~ /\/.AppleDouble\/$/ ) {
-       $finderinfo =1;
+        $finderinfo = 1;
     } elsif ( $basename =~ /^._/ ) {
-       if ( -f $path.substr($basename, 2) ) {
-           $finderinfo =1;
-       } elsif ( -d $path.substr($basename, 2) ) {
-           $finderinfo =2;
-       }
+        if ( -f $path.substr($basename, 2) ) {
+            $finderinfo = 1;
+        } elsif ( -d $path.substr($basename, 2) ) {
+            $finderinfo = 2;
+        }
     }
     if (!open(INFILE, "<$afile")) {
-       printf (STDERR "cannot open %s\n",  $afile);
-       exit 1;
+        printf (STDERR "cannot open %s\n",  $afile);
+        exit 1;
     }
     read(INFILE,$buf,4);
     $val = unpack("N", $buf );
     close(INFILE);
     if ($val == 0x00051600 || $val == 0x00051607) {
-       ;
+        $openfile = $afile;
+        $openmessage = "Dumping \"$openfile\"...\n";
     } else {
-       printf ("\"%s\" is not AppleSingle/AppleDouble format.\n", $afile);
-       $finderinfo = 1;
-       $netatalkfile = $path.".AppleDouble/".$basename;
-       $osxfile = $path."._".$basename;
-
-       if (( -e $netatalkfile ) && !( -e $osxfile )) {
-           $afile = $netatalkfile;
-       } elsif (!( -e $netatalkfile ) && ( -e $osxfile )) {
-           $afile = $osxfile;
-       } elsif (( -e $netatalkfile ) && ( -e $osxfile )) {
-           printf ("\"%s\" found.\n", $netatalkfile);
-           printf ("\"%s\" found.\n", $osxfile);
-           printf ("Specify which of file.\n");
-           exit 1;
-       } else {
-           printf ("\"%s\" not found.\n", $netatalkfile);
-           printf ("\"%s\" not found.\n", $osxfile);
-           exit 1;
-       }
+        printf ("\"%s\" is not AppleSingle/AppleDouble format.\n", $afile);
+        $finderinfo = 1;
+        $adcount = 0;
+        $netatalkfile = $path.".AppleDouble/".$basename;
+        $osxfile = $path."._".$basename;
+
+        if ( 1 == checkea($afile) ) {
+            printf ("\"%s\"\'s extended attribute is found.\n", $afile);
+            $adcount++;
+            $openfile = eaopenfile($afile);
+            $openmessage = "Dumping \"$afile\"'s extended attribute...\n";
+        }
+        if ( -e $netatalkfile ) {
+            printf ("\"%s\" is found.\n", $netatalkfile);
+            $adcount++;
+            $openfile = $netatalkfile;
+            $openmessage = "Dumping \"$openfile\"...\n";
+        }
+        if ( -e $osxfile ) {
+            printf ("\"%s\" is found.\n", $osxfile);
+            $adcount++;
+            $openfile = $osxfile;
+            $openmessage = "Dumping \"$openfile\"...\n";
+        }
+        if ( $adcount == 0 ) {
+            printf ("AppleSingle/AppleDouble data is not found.\n");
+            exit 1;
+        }
+        if ( $adcount != 1 ) {
+            printf ("Specify any one.\n");
+            exit 1;
+        }
     }
 } elsif ( -d $afile) {
     printf ("\"%s\" is a directory.\n", $afile);
-    $finderinfo =2;
+    $finderinfo = 2;
+    $adcount = 0;
     $netatalkfile = $path.$basename."/.AppleDouble/.Parent";
     $osxfile = $path."._".$basename;
 
-    if (( -e $netatalkfile ) && !( -e $osxfile )) {
-       $afile = $netatalkfile;
-    } elsif (!( -e $netatalkfile ) && ( -e $osxfile )) {
-       $afile = $osxfile;
-    } elsif (( -e $netatalkfile ) && ( -e $osxfile )) {
-       printf ("\"%s\" found.\n", $netatalkfile);
-       printf ("\"%s\" found.\n", $osxfile);
-       printf ("Specify which of file.\n");
-       exit 1;
-    } else {
-       printf ("\"%s\" not found.\n", $netatalkfile);
-       printf ("\"%s\" not found.\n", $osxfile);
-       exit 1;
+    if ( 1 == checkea($afile) ) {
+        printf ("\"%s\"\'s extended attribute is found.\n", $afile);
+        $adcount++;
+        $openfile = eaopenfile($afile);
+        $openmessage = "Dumping \"$afile\"'s extended attribute...\n";
+    }
+    if ( -e $netatalkfile ) {
+        printf ("\"%s\" is found.\n", $netatalkfile);
+        $adcount++;
+        $openfile= $netatalkfile;
+        $openmessage = "Dumping \"$openfile\"...\n";
+    }
+    if ( -e $osxfile ) {
+        printf ("\"%s\" is found.\n", $osxfile);
+        $adcount++;
+        $openfile = $osxfile;
+        $openmessage = "Dumping \"$openfile\"...\n";
+    }
+    if ( $adcount == 0 ) {
+        printf ("AppleSingle/AppleDouble data is not found.\n");
+        exit 1;
+    }
+    if ( $adcount != 1 ) {
+        printf ("Specify any one.\n");
+        exit 1;
     }
 } else {
     printf (STDERR "unknown error: %s\n", $afile);
     exit 1;
 }
 
-if (!open(INFILE, "<$afile")) {
-    printf (STDERR "cannot open %s\n",  $afile);
+if (!open(INFILE, "<$openfile")) {
+    printf (STDERR "cannot open %s\n",  $openfile);
     exit 1;
 }
-printf ("%s:\n\n", $afile);
+
+printf ($openmessage);
+
+#Dump --------------------------------------------------------
 
 # Magic Number -----------------------------------------------
 
@@ -306,7 +386,7 @@ for ( $num = 0 ; $num < $entnum ; $num++) {
 #    if ( $entid == 13 ) { ; } # Short Name
 #    if ( $entid == 14 ) { ; } # AFP File Info 
     elsif ( $entid == 15 ) { print "\n"; bedump($ofst,$len); } # Directory ID
-    elsif ( $entid == 0x8053567E  ) { print "\n"; bedump($ofst,$len); } # CNID (Netatalk Extended)
+    elsif ( $entid == 0x8053567E  ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # CNID (Netatalk Extended)
     elsif ( $entid == 0x8053594E  ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # DB stamp (Netatalk Extended)
     elsif ( $entid == 0x80444556  ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # dev (Netatalk Extended)
     elsif ( $entid == 0x80494E4F  ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # inode (Netatalk Extended)
@@ -314,8 +394,8 @@ for ( $num = 0 ; $num < $entnum ; $num++) {
 #    RAW Dump ---------------------------------------------------
 
     if ( ($quo > 0) || ($rem > 0)) {
-       print "\n";
-       print "-RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)\n";
+        print "\n";
+        print "-RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)\n";
     }
 
     seek(INFILE, $ofst, 0);
@@ -365,16 +445,16 @@ sub finderinfodump {
     seek(INFILE, $ofst, 0);
 
     if ($finderinfo == 0) {
-       print "\n";
-       print "-NOTE------: cannot detect whether FInfo or DInfo. assume FInfo.\n";
+        print "\n";
+        print "-NOTE------: cannot detect whether FInfo or DInfo. assume FInfo.\n";
     }
 
     if ($finderinfo == 0 || $finderinfo == 1) {
-       filefinderinfodump();
+        filefinderinfodump();
     } elsif ($finderinfo == 2) {
-       dirfinderinfodump();
+        dirfinderinfodump();
     } else {
-       print STDERR "unknown FinderInfo type\n"
+        print STDERR "unknown FinderInfo type\n"
     }
 
     if ($len > 32) { eadump(); }
@@ -533,27 +613,27 @@ sub flagsdump {
     printf ("color      : %d%d%d      : %s\n", ($flags >>  3) & 1,
             ($flags >>  2) & 1,
             ($flags >>  1) & 1,
-           @colortype[($flags & 0xE)>>1]);
+            @colortype[($flags & 0xE)>>1]);
     printf ("isOnDesk   : %d\n", ($flags >>  0) & 1);
 
 }
 
 sub xflagsdump {
-    
+
     read(INFILE,$buf,2);
     $flags = unpack("n", $buf );
-    
+
     if (($flags >> 15) == 1) {
-       print "Script     : ";
-       hexdump($buf, 1, 4, "");
+        print "Script     : ";
+        hexdump($buf, 1, 4, "");
     } else {
-       printf ("AreInvalid : %d\n", ($flags >> 15) & 1);
-       printf ("unknown bit: %d\n", ($flags >> 14) & 1);
-       printf ("unknown bit: %d\n", ($flags >> 13) & 1);
-       printf ("unknown bit: %d\n", ($flags >> 12) & 1);
-       printf ("unknown bit: %d\n", ($flags >> 11) & 1);
-       printf ("unknown bit: %d\n", ($flags >> 10) & 1);
-       printf ("unknown bit: %d\n", ($flags >>  9) & 1);
+        printf ("AreInvalid : %d\n", ($flags >> 15) & 1);
+        printf ("unknown bit: %d\n", ($flags >> 14) & 1);
+        printf ("unknown bit: %d\n", ($flags >> 13) & 1);
+        printf ("unknown bit: %d\n", ($flags >> 12) & 1);
+        printf ("unknown bit: %d\n", ($flags >> 11) & 1);
+        printf ("unknown bit: %d\n", ($flags >> 10) & 1);
+        printf ("unknown bit: %d\n", ($flags >>  9) & 1);
     }
 
     printf ("CustomBadge: %d\n", ($flags >>  8) & 1);
@@ -569,7 +649,7 @@ sub xflagsdump {
 }
 
 sub eadump {
-    
+
     print "\n";
     print "-EA--------:\n";
 
@@ -623,45 +703,45 @@ sub eadump {
     printf("     : %d\n", $ea_num_attrs);
 
     $pos = tell(INFILE);
-    
+
     for ($i = 0 ; $i < $ea_num_attrs ; $i++) {
-       
-       $pos = (($pos & 0x3) == 0) ? ($pos) : ((($pos >> 2) + 1) << 2);
-       seek(INFILE, $pos, 0);
-
-       print "-EA ENTRY--:\n";
-       
-       read(INFILE,$buf,4);
-       $ea_offset = unpack("N", $buf );
-       printf("offset     : %08X", $ea_offset);
-       printf(" : %d\n", $ea_offset);
-       
-       read(INFILE,$buf,4);
-       $ea_length = unpack("N", $buf );
-       printf("length     : %08X", $ea_length);
-       printf(" : %d\n", $ea_length);
-       
-       read(INFILE,$buf,2);
-       print "flags      : ";
-       hexdump($buf, 2, 4, "");
-       
-       read(INFILE,$buf,1);
-       $ea_namelen = unpack("C", $buf );
-       printf("namelen    : %02X", $ea_namelen);
-       printf("       : %d\n", $ea_namelen);
-
-       $ea_namequo = $ea_namelen >> 4;
-       $ea_namerem = $ea_namelen & 0xF;
-       print "-EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)\n";
-       rawdump($ea_namequo, $ea_namerem);
-
-       $pos = tell(INFILE);
-
-       seek(INFILE, $ea_offset, 0);
-       $ea_quo = $ea_length >> 4;
-       $ea_rem = $ea_length & 0xF;
-       print "-EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)\n";
-       rawdump($ea_quo, $ea_rem);
+
+        $pos = (($pos & 0x3) == 0) ? ($pos) : ((($pos >> 2) + 1) << 2);
+        seek(INFILE, $pos, 0);
+
+        print "-EA ENTRY--:\n";
+
+        read(INFILE,$buf,4);
+        $ea_offset = unpack("N", $buf );
+        printf("offset     : %08X", $ea_offset);
+        printf(" : %d\n", $ea_offset);
+
+        read(INFILE,$buf,4);
+        $ea_length = unpack("N", $buf );
+        printf("length     : %08X", $ea_length);
+        printf(" : %d\n", $ea_length);
+
+        read(INFILE,$buf,2);
+        print "flags      : ";
+        hexdump($buf, 2, 4, "");
+
+        read(INFILE,$buf,1);
+        $ea_namelen = unpack("C", $buf );
+        printf("namelen    : %02X", $ea_namelen);
+        printf("       : %d\n", $ea_namelen);
+
+        $ea_namequo = $ea_namelen >> 4;
+        $ea_namerem = $ea_namelen & 0xF;
+        print "-EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)\n";
+        rawdump($ea_namequo, $ea_namerem);
+
+        $pos = tell(INFILE);
+
+        seek(INFILE, $ea_offset, 0);
+        $ea_quo = $ea_length >> 4;
+        $ea_rem = $ea_length & 0xF;
+        print "-EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)\n";
+        rawdump($ea_quo, $ea_rem);
     }
 }
 
@@ -669,56 +749,54 @@ sub bedump  {
     my ($ofst, $len) = @_;
     my ($i);
     my ($value);
-    
+
     seek(INFILE, $ofst, 0);
-    
+
     printf("%2dbit-BE   : ", $len * 8 );
-    
+
     $value = 0;
     for ( $i=0 ; $i < $len ; $i++ ) {
-       read(INFILE,$buf,1);
-       $bytedata[$i] = unpack("C", $buf );
-       $value += $bytedata[$i] << (($len - $i -1) * 8) ;
+        read(INFILE,$buf,1);
+        $bytedata[$i] = unpack("C", $buf );
+          $value += $bytedata[$i] << (($len - $i -1) * 8) ;
     }
 
     for ( $i=0 ; $i < $len ; $i++ ) {
-       printf("%02X", $bytedata[$i]);
+        printf("%02X", $bytedata[$i]);
     }
 
     printf(" : %s", $value);
     print "\n";
-    
 }
 
 sub ledump  {
     my ($ofst, $len) = @_;
     my ($i);
     my ($value);
-    
+
     seek(INFILE, $ofst, 0);
-    
+
     printf("%2dbit-LE   : ", $len * 8 );
-    
+
     $value = 0;
     for ( $i=0 ; $i < $len ; $i++ ) {
-       read(INFILE,$buf,1);
-       $bytedata[$len - $i - 1] = unpack("C", $buf );
-       $value += $bytedata[$len - $i -1] << ($i * 8) ;
+        read(INFILE,$buf,1);
+        $bytedata[$len - $i - 1] = unpack("C", $buf );
+          $value += $bytedata[$len - $i -1] << ($i * 8) ;
     }
 
     for ( $i=0 ; $i < $len ; $i++ ) {
-       printf("%02X", $bytedata[$i]);
+        printf("%02X", $bytedata[$i]);
     }
 
     printf(" : %s", $value);
     print "\n";
-    
 }
 
 sub rawdump {
     my ($quo, $rem) = @_;
     my ($addrs, $line, $buf);
-    
+
     $addrs = 0;
     for ( $line = 0 ; $line < $quo ; $line++) {
         read(INFILE, $buf, 16);
@@ -731,7 +809,6 @@ sub rawdump {
         printf ( "%08X   :", $addrs);
         hexdump($buf, $rem, 16, " ");
     }
-    
 }
 
 sub hexdump {
@@ -761,4 +838,82 @@ sub hexdump {
     print "\n";
 }
 
+sub checkea {
+    my ($file) = @_;
+
+    $file =~ s/\\/\\\\/g;
+    $file =~ s/\"/\\\"/g;
+    $file =~ s/\$/\\\$/g;
+    $file =~ s/\`/\\\`/g;
+    if ( $eacommand == 1 ) {
+        open(EALIST, "getfattr \"$file\" |");
+        while(<EALIST>) {
+            if ( $_ eq "user.org.netatalk.Metadata\n" ) {
+                close (EALIST);
+                return 1;
+            }
+        }
+        close (EALIST);
+        return 0;
+    } elsif ( $eacommand == 2 ) {
+        open(EALIST, "attr -q -l \"$file\" |");
+        while(<EALIST>) {
+            if ( $_ eq "org.netatalk.Metadata\n" ) {
+                close (EALIST);
+                return 1;
+            }
+        }
+        close (EALIST);
+        return 0;
+    } elsif ( $eacommand == 3 ) {
+        open(EALIST, "runat \"$file\" ls -1 |");
+        while(<EALIST>) {
+            if ( $_ eq "org.netatalk.Metadata\n" ) {
+                close (EALIST);
+                return 1;
+            }
+        }
+        close (EALIST);
+        return 0;
+    } elsif ( $eacommand == 4 ) {
+        open(EALIST, "lsextattr -q user \"$file\" |");
+        while(<EALIST>) {
+            $_ = "\t".$_;
+            if ( $_ =~ /\torg\.netatalk\.Metadata[\n\t]/ ) {
+                close (EALIST);
+                return 1;
+            }
+        }
+        close (EALIST);
+        return 0;
+    } else {
+        return 0;
+    }
+}
+
+sub eaopenfile {
+    my ($file) = @_;
+
+    $file =~ s/\\/\\\\/g;
+    $file =~ s/\"/\\\"/g;
+    $file =~ s/\$/\\\$/g;
+    $file =~ s/\`/\\\`/g;
+    ($eatempfh, $eatempfile) = tempfile(UNLINK => 1);
+
+    if ( $eacommand == 1 ) {
+        system("getfattr --only-values -n user.org.netatalk.Metadata \"$file\" > $eatempfile");
+    } elsif ( $eacommand == 2 ) {
+        system("attr -q -g org.netatalk.Metadata \"$file\" > $eatempfile");
+    } elsif ( $eacommand == 3 ) {
+        system("runat \"$file\" cat org.netatalk.Metadata > $eatempfile");
+    } elsif ( $eacommand == 4 ) {
+        system("getextattr -q user org.netatalk.Metadata \"$file\" > $eatempfile");
+    } else {
+        return "";
+    }
+
+    close($eatempfh);
+    return $eatempfile;
+}
+
 #EOF