3 # AppleSingle/AppleDouble dump
5 # (c) 2009-2012 by HAT <hat@fa2.so-net.ne.jp>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
21 # Applesingle and AppleDouble format internals (version 1)
22 # http://users.phg-online.de/tk/netatalk/doc/Apple/v1/
24 # AppleSingle/AppleDouble Formats for Foreign Files Developer's Note (version2)
25 # http://users.phg-online.de/tk/netatalk/doc/Apple/v2/AppleSingle_AppleDouble.pdf
27 # Inside Macintosh: Macintosh Toolbox Essentials /
28 # Chapter 7 - Finder Interface / Finder Interface Reference
29 # http://developer.apple.com/legacy/mac/library/documentation/mac/toolbox/Toolbox-463.html
31 # Finder Interface Reference
32 # http://developer.apple.com/legacy/mac/library/documentation/Carbon/Reference/Finder_Interface/Reference/reference.html
34 # Technical Note TN1150 HFS Plus Volume Format
35 # http://developer.apple.com/mac/library/technotes/tn/tn1150.html#FinderInfo
37 # CarbonHeaders source
38 # http://www.opensource.apple.com/source/CarbonHeaders/CarbonHeaders-8A428/Finder.h
39 # http://www.opensource.apple.com/source/CarbonHeaders/CarbonHeaders-9A581/Finder.h
43 # /usr/bin/GetFileInfo
45 # Mac OS X 10.6.2 kernel source
46 # http://www.opensource.apple.com/source/xnu/xnu-1486.2.11/bsd/vfs/vfs_xattr.c
51 use File::Temp qw /tempfile/;
52 use bigint; # require perl >= 5.8
53 use IPC::Open2 qw /open2/;
55 # check command for extended attributes -----------------------------------
57 if ( 0 == system("which getfattr > /dev/null 2>&1")) {
59 } elsif (0 == system("which attr > /dev/null 2>&1")) {
61 } elsif (0 == system("which runat > /dev/null 2>&1")) {
63 } elsif (0 == system("which getextattr > /dev/null 2>&1")) {
69 #printf ( "eacommand = %d\n", $eacommand ); # debug
71 # parse command line -----------------------------------------------
75 $finderinfo = 0; # 0: unknown 1: file 2: directory
76 while ($arg = shift @ARGV)
78 if ($arg =~ /^(-h|-help|--help)$/ ) {
79 printf ("usage: %s [-a] [FILE|DIR]\n" ,basename($0));
80 printf (" or: %s -e FILE|DIR\n" ,basename($0));
81 printf (" or: %s -f [FILE]\n" ,basename($0));
82 printf (" or: %s -d [FILE]\n" ,basename($0));
83 printf (" or: %s -h|-help|--help\n" ,basename($0));
84 printf (" or: %s -v|-version|--version\n" ,basename($0));
85 printf ("Dump AppleSingle/AppleDouble format data.\n");
86 printf ("With no FILE|DIR, or when FILE|DIR is -, read standard input.\n");
88 printf (" -a (default) Dump a AppleSingle/AppleDouble data for FILE or DIR\n");
89 printf (" automatically.\n");
90 printf (" If FILE is not AppleSingle/AppleDouble format,\n");
91 printf (" look for extended attribute, .AppleDouble/FILE and ._FILE.\n");
92 printf (" If DIR, look for extended attribute,\n");
93 printf (" DIR/.AppleDouble/.Parent and ._DIR.\n");
94 printf (" -e Dump extended attribute of FILE or DIR\n");
95 printf (" -f Dump FILE. Assume FinderInfo to be FileInfo.\n");
96 printf (" -d Dump FILE. Assume FinderInfo to be DirInfo.\n");
97 printf (" -h,-help,--help Display this help and exit\n");
98 printf (" -v,-version,--version Show version and exit\n");
100 printf ("There is no way to detect whether FinderInfo is FileInfo or DirInfo.\n");
101 printf ("By default, %s examins whether file or directory,\n" ,basename($0));
102 printf ("a parent directory is .AppleDouble, filename is ._*, filename is .Parent,\n");
103 printf ("and so on.\n");
104 printf ("If setting option -e, -f or -d, %s assume FinderInfo and doesn't look for\n");
105 printf ("another file.\n");
107 } elsif ($arg =~ /^(-v|-version|--version)$/ ) {
108 printf ("%s \(Netatalk @NETATALK_VERSION@\)\n", basename($0));
110 } elsif ($arg eq "-a") {
112 } elsif ($arg eq "-e") {
113 if ($eacommand == 0) {
114 printf (STDERR "%s: unsupported option -e\n", basename($0));
115 printf (STDERR "because neither getfattr, attr, runat nor getextattr is found.\n");
119 } elsif ($arg eq "-f") {
121 } elsif ($arg eq "-d") {
123 } elsif ($arg eq "-") {
125 } elsif ($arg =~ /^-/) {
126 printf (STDERR "%s: invalid option %s\n", basename($0), $arg);
127 printf (STDERR "Try \`%s\ -h' for more information.\n", basename($0));
136 } elsif (!( -e $afile)) {
137 printf (STDERR "\"%s\" is not found.\n", $afile);
141 # detect FinderInfo, and search AppleSingle/AppleDouble file --------------
143 $abspath = File::Spec->rel2abs($afile);
144 ($basename, $path, $ext) = fileparse($abspath);
146 if ( $stdinputmode == 1) {
147 ($eatempfh, $openfile) = tempfile(UNLINK => 1);
148 system("cat - > $openfile");
150 $openmessage = "Dumping Standard Input...\n";
151 } elsif ( $eaoption == 1 ) {
154 } elsif ( -d $afile ) {
157 printf (STDERR "unknown error: %s\n", $afile);
160 if ( 0 == checkea($afile) ) {
161 printf (STDERR "\"%s\"'s extended attribute is not found\n", $afile);
164 $openfile = eaopenfile($afile);
165 $openmessage = "Dumping \"$afile\"'s extended attribute...\n";
166 } elsif ( $finderinfo != 0 ) {
168 $openmessage = "Dumping \"$openfile\"...\n";
169 } elsif ( -f $afile ) {
170 if ( $basename eq ".Parent") {
172 } elsif ( $path =~ /\/.AppleDouble\/$/ ) {
174 } elsif ( $basename =~ /^._/ ) {
175 if ( -f $path.substr($basename, 2) ) {
177 } elsif ( -d $path.substr($basename, 2) ) {
181 if (!open(INFILE, "<$afile")) {
182 printf (STDERR "cannot open %s\n", $afile);
186 $val = unpack("N", $buf );
188 if ($val == 0x00051600 || $val == 0x00051607) {
190 $openmessage = "Dumping \"$openfile\"...\n";
192 printf ("\"%s\" is not AppleSingle/AppleDouble format.\n", $afile);
195 $netatalkfile = $path.".AppleDouble/".$basename;
196 $osxfile = $path."._".$basename;
198 if ( 1 == checkea($afile) ) {
199 printf ("\"%s\"\'s extended attribute is found.\n", $afile);
201 $openfile = eaopenfile($afile);
202 $openmessage = "Dumping \"$afile\"'s extended attribute...\n";
204 if ( -e $netatalkfile ) {
205 printf ("\"%s\" is found.\n", $netatalkfile);
207 $openfile = $netatalkfile;
208 $openmessage = "Dumping \"$openfile\"...\n";
211 printf ("\"%s\" is found.\n", $osxfile);
213 $openfile = $osxfile;
214 $openmessage = "Dumping \"$openfile\"...\n";
216 if ( $adcount == 0 ) {
217 printf ("AppleSingle/AppleDouble data is not found.\n");
220 if ( $adcount != 1 ) {
221 printf ("Specify any one.\n");
225 } elsif ( -d $afile) {
226 printf ("\"%s\" is a directory.\n", $afile);
229 $netatalkfile = $path.$basename."/.AppleDouble/.Parent";
230 $osxfile = $path."._".$basename;
232 if ( 1 == checkea($afile) ) {
233 printf ("\"%s\"\'s extended attribute is found.\n", $afile);
235 $openfile = eaopenfile($afile);
236 $openmessage = "Dumping \"$afile\"'s extended attribute...\n";
238 if ( -e $netatalkfile ) {
239 printf ("\"%s\" is found.\n", $netatalkfile);
241 $openfile= $netatalkfile;
242 $openmessage = "Dumping \"$openfile\"...\n";
245 printf ("\"%s\" is found.\n", $osxfile);
247 $openfile = $osxfile;
248 $openmessage = "Dumping \"$openfile\"...\n";
250 if ( $adcount == 0 ) {
251 printf ("AppleSingle/AppleDouble data is not found.\n");
254 if ( $adcount != 1 ) {
255 printf ("Specify any one.\n");
259 printf (STDERR "unknown error: %s\n", $afile);
263 if (!open(INFILE, "<$openfile")) {
264 printf (STDERR "cannot open %s\n", $openfile);
268 printf ($openmessage);
270 #Dump --------------------------------------------------------
272 # Magic Number -----------------------------------------------
274 print "-------------------------------------------------------------------------------\n";
277 $val = unpack("N", $buf );
278 printf("MagicNumber: %08X", $val);
279 if ( $val == 0x00051600 ) {
280 printf(" : AppleSingle");
282 elsif ( $val == 0x00051607 ) {
283 printf(" : AppleDouble");
286 printf(" : Unknown" );
290 # Version Number ---------------------------------------------
293 $version = unpack("N", $buf );
294 printf("Version : %08X", $version);
295 if ( $version == 0x00010000 ) {
296 printf(" : Version 1");
297 } elsif ( $version == 0x00020000 ) {
298 printf(" : Version 2");
300 printf(" : Unknown" );
304 # v1:Home file system / v2:Filler ----------------------------
306 read(INFILE,$buf,16);
307 if ( $version == 0x00010000 ) {
308 print "HomeFileSys:";
312 hexdump($buf, 16, 16, " ");
314 # Number of entities -----------------------------------------
317 $entnum = unpack("n", $buf );
318 printf("Num. of ent: %04X ", $entnum);
319 printf(" : %d", $entnum);
322 # data -------------------------------------------------------
324 for ( $num = 0 ; $num < $entnum ; $num++) {
326 seek(INFILE, ($num * 12 + 26), 0);
328 # Entry ---------------------------------------------------
331 $entid = unpack("N", $buf );
332 print "\n-------------------------------------------------------------------------------\n";
333 printf("Entry ID : %08X", $entid);
334 if ( $entid == 1 ) { printf(" : Data Fork"); }
335 elsif ( $entid == 2 ) { printf(" : Resource Fork"); }
336 elsif ( $entid == 3 ) { printf(" : Real Name"); }
337 elsif ( $entid == 4 ) { printf(" : Comment"); }
338 elsif ( $entid == 5 ) { printf(" : Icon, B&W"); }
339 elsif ( $entid == 6 ) { printf(" : Icon Color"); }
340 elsif ( $entid == 7 ) { printf(" : File Info"); }
341 elsif ( $entid == 8 ) { printf(" : File Dates Info"); }
342 elsif ( $entid == 9 ) { printf(" : Finder Info"); }
343 elsif ( $entid == 10 ) { printf(" : Macintosh File Info"); }
344 elsif ( $entid == 11 ) { printf(" : ProDOS File Info"); }
345 elsif ( $entid == 12 ) { printf(" : MS-DOS File Info"); }
346 elsif ( $entid == 13 ) { printf(" : Short Name"); }
347 elsif ( $entid == 14 ) { printf(" : AFP File Info"); }
348 elsif ( $entid == 15 ) { printf(" : Directory ID"); }
349 elsif ( $entid == 0x8053567E ) { printf(" : CNID (Netatalk Extended)"); }
350 elsif ( $entid == 0x8053594E ) { printf(" : DB stamp (Netatalk Extended)"); }
351 elsif ( $entid == 0x80444556 ) { printf(" : dev (Netatalk Extended)"); }
352 elsif ( $entid == 0x80494E4F ) { printf(" : inode (Netatalk Extended)"); }
353 else { printf(" : Unknown"); }
356 # Offset -------------------------------------------------
359 $ofst = unpack("N", $buf );
360 printf("Offset : %08X", $ofst);
361 printf(" : %d ", $ofst);
363 # Length -------------------------------------------------
366 $len = unpack("N", $buf );
367 printf("\nLength : %08X", $len);
368 printf(" : %d", $len);
373 # Dump for each Entry ID --------------------------------
375 # if ( $entid == 1 ) { ; } # Data Fork
376 # if ( $entid == 2 ) { ; } # Resource Fork
377 # if ( $entid == 3 ) { ; } # Real Name
378 # if ( $entid == 4 ) { ; } # Comment
379 # if ( $entid == 5 ) { ; } # Icon, B&W
380 # if ( $entid == 6 ) { ; } # Icon Color
381 # if ( $entid == 7 ) { ; } # File Info
382 if ( $entid == 8 ) { filedatesdump($ofst,$len); }
383 elsif ( $entid == 9 ) { finderinfodump($ofst,$len); }
384 # if ( $entid == 10 ) { ; } # Macintosh File Info
385 # if ( $entid == 11 ) { ; } # ProDOS File Info
386 # if ( $entid == 12 ) { ; } # MS-DOS File Info
387 # if ( $entid == 13 ) { ; } # Short Name
388 # if ( $entid == 14 ) { ; } # AFP File Info
389 elsif ( $entid == 15 ) { print "\n"; bedump($ofst,$len); } # Directory ID
390 elsif ( $entid == 0x8053567E ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # CNID (Netatalk Extended)
391 elsif ( $entid == 0x8053594E ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # DB stamp (Netatalk Extended)
392 elsif ( $entid == 0x80444556 ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # dev (Netatalk Extended)
393 elsif ( $entid == 0x80494E4F ) { print "\n"; bedump($ofst,$len); ledump($ofst,$len); } # inode (Netatalk Extended)
395 # RAW Dump ---------------------------------------------------
397 if ( ($quo > 0) || ($rem > 0)) {
399 print "-RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)\n";
402 seek(INFILE, $ofst, 0);
410 #sub -----------------------------------------------------------
413 my ($ofst, $len) = @_;
418 @datetype =('create ', 'modify ', 'backup ', 'access ');
420 seek(INFILE, $ofst, 0);
423 printf ("-DATE------: : (GMT) : (Local)\n");
425 for ( $i = 0 ; $i < 4 ; $i++) {
427 $datedata = unpack("N", $buf );
428 if ($datedata < 0x80000000) {
429 $datestr = gmtime( $datedata + 946684800)
431 .localtime( $datedata + 946684800);
432 } elsif ($datedata == 0x80000000) {
433 $datestr = "Unknown or Initial";
435 $datestr = gmtime( $datedata - 3348282496)
437 .localtime( $datedata - 3348282496);
439 printf ("%s : %08X : %s\n",$datetype[$i], $datedata, $datestr);
444 my ($ofst, $len) = @_;
446 seek(INFILE, $ofst, 0);
448 if ($finderinfo == 0) {
450 print "-NOTE------: cannot detect whether FInfo or DInfo. assume FInfo.\n";
453 if ($finderinfo == 0 || $finderinfo == 1) {
454 filefinderinfodump();
455 } elsif ($finderinfo == 2) {
458 print STDERR "unknown FinderInfo type\n"
461 if ($len > 32) { eadump(); }
464 sub filefinderinfodump {
467 print "-FInfo-----:\n";
471 hexdump($buf, 4, 4, "");
475 hexdump($buf, 4, 4, "");
480 $val = unpack("n", $buf );
481 printf("Location v : %04X", $val);
482 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
485 $val = unpack("n", $buf );
486 printf("Location h : %04X", $val);
487 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
491 hexdump($buf, 2, 4, "");
494 print "-FXInfo----:\n";
497 $val = unpack("n", $buf );
498 printf("Rsvd|IconID: %04X", $val);
499 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
503 hexdump($buf, 2, 4, "");
506 hexdump($buf, 2, 4, "");
509 hexdump($buf, 2, 4, "");
514 $val = unpack("n", $buf );
515 printf("Rsvd|commnt: %04X", $val);
516 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
519 $val = unpack("N", $buf );
520 printf("PutAway : %08X", $val);
521 printf(" : %d\n", $val>0x7FFFFFFF?$val-0x100000000:$val); # Why SInt32?
525 sub dirfinderinfodump {
528 print "-DInfo-----:\n";
531 $val = unpack("n", $buf );
532 printf("Rect top : %04X", $val);
533 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
536 $val = unpack("n", $buf );
537 printf("Rect left : %04X", $val);
538 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
541 $val = unpack("n", $buf );
542 printf("Rect bottom: %04X", $val);
543 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
546 $val = unpack("n", $buf );
547 printf("Rect right : %04X", $val);
548 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
553 $val = unpack("n", $buf );
554 printf("Location v : %04X", $val);
555 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
558 $val = unpack("n", $buf );
559 printf("Location h : %04X", $val);
560 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
564 hexdump($buf, 2, 4, "");
567 print "-DXInfo----:\n";
570 $val = unpack("n", $buf );
571 printf("Scroll v : %04X", $val);
572 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
575 $val = unpack("n", $buf );
576 printf("Scroll h : %04X", $val);
577 printf(" : %d\n", $val>0x7FFF?$val-0x10000:$val);
580 $val = unpack("N", $buf );
581 printf("Rsvd|OpnChn: %08X", $val);
582 printf(" : %d\n", $val>0x7FFFFFFF?$val-0x100000000:$val); # Why SInt32?
588 hexdump($buf, 2, 4, "");
591 $val = unpack("N", $buf );
592 printf("PutAway : %08X", $val);
593 printf(" : %d\n", $val>0x7FFFFFFF?$val-0x100000000:$val); # Why SInt32?
598 @colortype =('none', 'gray', 'green', 'purple', 'blue', 'yellow', 'red', 'orange');
601 $flags = unpack("n", $buf );
602 printf ("isAlias : %d\n", ($flags >> 15) & 1);
603 printf ("Invisible : %d\n", ($flags >> 14) & 1);
604 printf ("hasBundle : %d\n", ($flags >> 13) & 1);
605 printf ("nameLocked : %d\n", ($flags >> 12) & 1);
606 printf ("Stationery : %d\n", ($flags >> 11) & 1);
607 printf ("CustomIcon : %d\n", ($flags >> 10) & 1);
608 printf ("Reserved : %d\n", ($flags >> 9) & 1);
609 printf ("Inited : %d\n", ($flags >> 8) & 1);
610 printf ("NoINITS : %d\n", ($flags >> 7) & 1);
611 printf ("Shared : %d\n", ($flags >> 6) & 1);
612 printf ("SwitchLaunc: %d\n", ($flags >> 5) & 1);
613 printf ("Hidden Ext : %d\n", ($flags >> 4) & 1);
614 printf ("color : %d%d%d : %s\n", ($flags >> 3) & 1,
617 @colortype[($flags & 0xE)>>1]);
618 printf ("isOnDesk : %d\n", ($flags >> 0) & 1);
625 $flags = unpack("n", $buf );
627 if (($flags >> 15) == 1) {
629 hexdump($buf, 1, 4, "");
631 printf ("AreInvalid : %d\n", ($flags >> 15) & 1);
632 printf ("unknown bit: %d\n", ($flags >> 14) & 1);
633 printf ("unknown bit: %d\n", ($flags >> 13) & 1);
634 printf ("unknown bit: %d\n", ($flags >> 12) & 1);
635 printf ("unknown bit: %d\n", ($flags >> 11) & 1);
636 printf ("unknown bit: %d\n", ($flags >> 10) & 1);
637 printf ("unknown bit: %d\n", ($flags >> 9) & 1);
640 printf ("CustomBadge: %d\n", ($flags >> 8) & 1);
641 printf ("ObjctIsBusy: %d\n", ($flags >> 7) & 1);
642 printf ("unknown bit: %d\n", ($flags >> 6) & 1);
643 printf ("unknown bit: %d\n", ($flags >> 5) & 1);
644 printf ("unknown bit: %d\n", ($flags >> 4) & 1);
645 printf ("unknown bit: %d\n", ($flags >> 3) & 1);
646 printf ("RoutingInfo: %d\n", ($flags >> 2) & 1);
647 printf ("unknown bit: %d\n", ($flags >> 1) & 1);
648 printf ("unknown bit: %d\n", ($flags >> 0) & 1);
655 print "-EA--------:\n";
659 hexdump($buf, 2, 4, "");
663 hexdump($buf, 4, 4, "");
666 $ea_debug_tag = unpack("N", $buf );
667 printf("debug_tag : %08X", $ea_debug_tag);
668 printf(" : %d\n", $ea_debug_tag);
671 $ea_total_size = unpack("N", $buf );
672 printf("total_size : %08X", $ea_total_size);
673 printf(" : %d\n", $ea_total_size);
676 $ea_data_start = unpack("N", $buf );
677 printf("data_start : %08X", $ea_data_start);
678 printf(" : %d\n", $ea_data_start);
681 $ea_data_length = unpack("N", $buf );
682 printf("data_length: %08X", $ea_data_length);
683 printf(" : %d\n", $ea_data_length);
686 print "reserved[0]: ";
687 hexdump($buf, 4, 4, "");
690 print "reserved[1]: ";
691 hexdump($buf, 4, 4, "");
694 print "reserved[2]: ";
695 hexdump($buf, 4, 4, "");
699 hexdump($buf, 2, 4, "");
702 $ea_num_attrs = unpack("n", $buf );
703 printf("num_attrs : %04X", $ea_num_attrs);
704 printf(" : %d\n", $ea_num_attrs);
708 for ($i = 0 ; $i < $ea_num_attrs ; $i++) {
710 $pos = (($pos & 0x3) == 0) ? ($pos) : ((($pos >> 2) + 1) << 2);
711 seek(INFILE, $pos, 0);
713 print "-EA ENTRY--:\n";
716 $ea_offset = unpack("N", $buf );
717 printf("offset : %08X", $ea_offset);
718 printf(" : %d\n", $ea_offset);
721 $ea_length = unpack("N", $buf );
722 printf("length : %08X", $ea_length);
723 printf(" : %d\n", $ea_length);
727 hexdump($buf, 2, 4, "");
730 $ea_namelen = unpack("C", $buf );
731 printf("namelen : %02X", $ea_namelen);
732 printf(" : %d\n", $ea_namelen);
734 $ea_namequo = $ea_namelen >> 4;
735 $ea_namerem = $ea_namelen & 0xF;
736 print "-EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)\n";
737 rawdump($ea_namequo, $ea_namerem);
741 seek(INFILE, $ea_offset, 0);
742 $ea_quo = $ea_length >> 4;
743 $ea_rem = $ea_length & 0xF;
744 print "-EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)\n";
745 rawdump($ea_quo, $ea_rem);
750 my ($ofst, $len) = @_;
754 seek(INFILE, $ofst, 0);
756 printf("%2dbit-BE : ", $len * 8 );
759 for ( $i=0 ; $i < $len ; $i++ ) {
761 $bytedata[$i] = unpack("C", $buf );
762 $value += $bytedata[$i] << (($len - $i -1) * 8) ;
765 for ( $i=0 ; $i < $len ; $i++ ) {
766 printf("%02X", $bytedata[$i]);
769 printf(" : %s", $value);
774 my ($ofst, $len) = @_;
778 seek(INFILE, $ofst, 0);
780 printf("%2dbit-LE : ", $len * 8 );
783 for ( $i=0 ; $i < $len ; $i++ ) {
785 $bytedata[$len - $i - 1] = unpack("C", $buf );
786 $value += $bytedata[$len - $i -1] << ($i * 8) ;
789 for ( $i=0 ; $i < $len ; $i++ ) {
790 printf("%02X", $bytedata[$i]);
793 printf(" : %s", $value);
798 my ($quo, $rem) = @_;
799 my ($addrs, $line, $buf);
802 for ( $line = 0 ; $line < $quo ; $line++) {
803 read(INFILE, $buf, 16);
804 printf ( "%08X :", $addrs);
805 hexdump($buf, 16, 16, " ");
806 $addrs = $addrs + 0x10;
809 read(INFILE, $buf, $rem);
810 printf ( "%08X :", $addrs);
811 hexdump($buf, $rem, 16, " ");
816 my ($buf, $len, $col, $delimit) = @_;
822 for ( $i=0 ; $i < $len ; $i++ ) {
823 $val = substr($buf, $i, 1);
825 $hexstr .= sprintf("%s%02X", $delimit, $ascval);
827 if (($ascval < 32) || ( $ascval > 126 )) {
832 for ( ; $i < $col ; $i++) {
833 $hexstr .= " ".$delimit;
837 printf("%s : %s", $hexstr,$ascstr);
845 if ( $eacommand == 1 ) {
846 open2(\*EALIST, \*EAIN, 'getfattr', $file) or die $@;
848 if ( $_ eq "user.org.netatalk.Metadata\n" ) {
849 close (EALIST, EAIN);
853 close (EALIST, EAIN);
855 } elsif ( $eacommand == 2 ) {
856 open2(\*EALIST, \*EAIN, 'attr', '-q', '-l', $file) or die $@;
858 if ( $_ eq "org.netatalk.Metadata\n" ) {
859 close (EALIST, EAIN);
863 close (EALIST, EAIN);
865 } elsif ( $eacommand == 3 ) {
866 open2(\*EALIST, \*EAIN, 'runat', $file, 'ls', '-1') or die $@;
868 if ( $_ eq "org.netatalk.Metadata\n" ) {
869 close (EALIST, EAIN);
873 close (EALIST, EAIN);
875 } elsif ( $eacommand == 4 ) {
876 open2(\*EALIST, \*EAIN, 'lsextattr', '-q', 'user', $file) or die $@;
879 if ( $_ =~ /\torg\.netatalk\.Metadata[\n\t]/ ) {
880 close (EALIST, EAIN);
884 close (EALIST, EAIN);
895 if ( $eacommand == 1 ) {
896 @eacommands = ('getfattr', '--only-values', '-n', 'user.org.netatalk.Metadata', $file);
897 } elsif ( $eacommand == 2 ) {
898 @eacommands = ('attr', '-q', '-g', 'org.netatalk.Metadata', $file);
899 } elsif ( $eacommand == 3 ) {
900 @eacommands = ('runat', $file, 'cat', 'org.netatalk.Metadata',);
901 } elsif ( $eacommand == 4 ) {
902 @eacommands = ('getextattr', '-q', 'user', 'org.netatalk.Metadata', $file);
907 my ($eatempfh, $eatempfile) = tempfile(UNLINK => 1);
908 open2(my $ealist, my $eain, @eacommands) or die $@;
909 print $eatempfh $_ while(<$ealist>);
910 close($ealist, $eain);