From b4e1f62edd6815f9365f752f0ef7a82d3d2d0a80 Mon Sep 17 00:00:00 2001 From: franklahm Date: Wed, 23 Dec 2009 15:53:15 +0000 Subject: [PATCH] asaddump: dump AppleSingle/Double files. From HAT. --- NEWS | 1 + configure.in | 3 +- contrib/shell_utils/.cvsignore | 1 + contrib/shell_utils/Makefile.am | 3 +- contrib/shell_utils/asaddump.in | 349 ++++++++++++++++++++++++++++++++ 5 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 contrib/shell_utils/asaddump.in diff --git a/NEWS b/NEWS index 37cf2e69..dac01f90 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ Changes in 2.1-beta1 database can't be open. * NEW: support for Unicode characters in the range above U+010000 using internal surrogate pairs +* NEW: asaddump: utility to dump AppleSingle and AppleDouble files * UPD: atalkd and papd are now disabled by default. AppleTalk is legacy. * UPD: slp advertisement is now disabled by default. server option -slp SRVLOC is legacy. diff --git a/configure.in b/configure.in index 0645aa88..57912588 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.234 2009-12-18 13:01:15 franklahm Exp $ +dnl $Id: configure.in,v 1.235 2009-12-23 15:53:15 franklahm Exp $ dnl configure.in for netatalk AC_INIT(etc/afpd/main.c) @@ -1216,6 +1216,7 @@ AC_OUTPUT([Makefile contrib/shell_utils/apple_cp contrib/shell_utils/apple_mv contrib/shell_utils/apple_rm + contrib/shell_utils/asaddump contrib/shell_utils/asip-status.pl contrib/timelord/Makefile contrib/a2boot/Makefile diff --git a/contrib/shell_utils/.cvsignore b/contrib/shell_utils/.cvsignore index eea21056..313b0b40 100644 --- a/contrib/shell_utils/.cvsignore +++ b/contrib/shell_utils/.cvsignore @@ -9,3 +9,4 @@ cleanappledouble.pl netatalkshorternamelinks.pl lp2pap.sh asip-status.pl +asaddump diff --git a/contrib/shell_utils/Makefile.am b/contrib/shell_utils/Makefile.am index 12a37e00..71bf8752 100644 --- a/contrib/shell_utils/Makefile.am +++ b/contrib/shell_utils/Makefile.am @@ -7,7 +7,8 @@ TEMPLATE_FILES = lp2pap.sh.tmpl PERLSCRIPTS = \ afpd-mtab.pl \ apple_cp apple_mv apple_rm \ - asip-status.pl + asip-status.pl \ + asaddump SUFFIXES = .tmpl . diff --git a/contrib/shell_utils/asaddump.in b/contrib/shell_utils/asaddump.in new file mode 100644 index 00000000..e2ec4b7b --- /dev/null +++ b/contrib/shell_utils/asaddump.in @@ -0,0 +1,349 @@ +#!@PERL@ +# +# AppleSingle/AppleDouble dump +# +# (c) 2009 by HAT +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# 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. +# + +open(INFILE, "<$ARGV[0]"); + +binmode(INFILE); # for DOS/Win + +$addr = 0; + +# Magic Number ----------------------------------------------- + +$rc = read(INFILE,$buf,4); +$val = unpack("N", $buf ); +printf("Magic Num. : %08X", $val); +if ( $val == 0x00051600 ) { + printf(" : AppleSingle"); +} +elsif ( $val == 0x00051607 ) { + printf(" : AppleDouble"); +} +else { + printf(" : Unknown" ); +} +print "\n"; + +# Version Number --------------------------------------------- + +$rc = read(INFILE,$buf,4); +$val = unpack("N", $buf ); +printf("Ver. Num. : %08X", $val); +if ( $val == 0x00010000 ) { + printf(" : Version 1"); +} +elsif ( $val == 0x00020000 ) { + printf(" : Version 2"); +} +else { + printf(" : Unknown" ); +} +print "\n"; + +# v1:Home file system / v2:Filler ---------------------------- + +$rc = read(INFILE,$buf,16); +print "Filler :"; +hexdump($buf, 16, 16, " "); + +# Number of entities ----------------------------------------- + +$rc = read(INFILE,$buf,2); +$entnum = unpack("n", $buf ); +printf("Num. of ent: %04X ", $entnum); +printf(" : %d", $entnum); +print "\n"; + +# data ------------------------------------------------------- + +for ( $num = 0 ; $num < $entnum ; $num++) { + + seek(INFILE, ($num * 12 + 26), 0); + +# Entry --------------------------------------------------- + + $rc = read(INFILE,$buf,4); + $entid = unpack("N", $buf ); + printf("\nEntry ID : %08X", $entid); + if ( $entid == 1 ) { printf(" : Data Fork"); } + elsif ( $entid == 2 ) { printf(" : Resource Fork"); } + elsif ( $entid == 3 ) { printf(" : Real Name"); } + elsif ( $entid == 4 ) { printf(" : Comment"); } + elsif ( $entid == 5 ) { printf(" : Icon, B&W"); } + elsif ( $entid == 6 ) { printf(" : Icon Color"); } + elsif ( $entid == 7 ) { printf(" : File Info"); } + elsif ( $entid == 8 ) { printf(" : File Dates Info"); } + elsif ( $entid == 9 ) { printf(" : Finder Info"); } + elsif ( $entid == 10 ) { printf(" : Macintosh File Info"); } + elsif ( $entid == 11 ) { printf(" : ProDOS File Info"); } + elsif ( $entid == 12 ) { printf(" : MS-DOS File Info"); } + elsif ( $entid == 13 ) { printf(" : Short Name"); } + elsif ( $entid == 14 ) { printf(" : AFP File Info"); } + elsif ( $entid == 15 ) { printf(" : Directory ID"); } + elsif ( $entid == 0x8053567E ) { printf(" : CNID (Netatalk Extended)"); } + elsif ( $entid == 0x8053594E ) { printf(" : DB stamp (Netatalk Extended)"); } + elsif ( $entid == 0x80444556 ) { printf(" : dev (Netatalk Extended)"); } + elsif ( $entid == 0x80494E4F ) { printf(" : inode (Netatalk Extended)"); } + else { printf(" : Unknown"); } + print "\n"; + +# Offset ------------------------------------------------- + + $rc = read(INFILE,$buf,4); + $ofst = unpack("N", $buf ); + printf("Offset : %08X", $ofst); + printf(" : %d ", $ofst); + +# Length ------------------------------------------------- + + $rc = read(INFILE,$buf,4); + $len = unpack("N", $buf ); + printf("\nLength : %08X", $len); + printf(" : %d", $len); + $quo = $len >> 4; + $rem = $len & 0xF; + print "\n"; + +# if ( $entid == 1 ) { ; } # Data Fork +# if ( $entid == 2 ) { ; } # Resource Fork +# if ( $entid == 3 ) { ; } # Real Name +# if ( $entid == 4 ) { ; } # Comment +# if ( $entid == 5 ) { ; } # Icon, B&W +# if ( $entid == 6 ) { ; } # Icon Color +# if ( $entid == 7 ) { ; } # File Info + if ( $entid == 8 ) { filedatesdump($ofst,$len); } + elsif ( $entid == 9 ) { finderinfodump($ofst,$len); } +# if ( $entid == 10 ) { ; } # Macintosh File Info +# if ( $entid == 11 ) { ; } # ProDOS File Info +# if ( $entid == 12 ) { ; } # MS-DOS File Info +# if ( $entid == 13 ) { ; } # Short Name +# if ( $entid == 14 ) { ; } # AFP File Info +# if ( $entid == 15 ) { ; } # Directory ID +# if ( $entid == 0x8053567E ) { ; } # CNID (Netatalk Extended) +# if ( $entid == 0x8053594E ) { ; } # DB stamp (Netatalk Extended) +# if ( $entid == 0x80444556 ) { ; } # dev (Netatalk Extended) +# if ( $entid == 0x80494E4F ) { ; } # inode (Netatalk Extended) + +# Dump --------------------------------------------------- + + seek(INFILE, $ofst, 0); + $addrs = 0; + for ( $line = 0 ; $line < $quo ; $line++) { + $rc = read(INFILE, $buf, 16); + printf ( "%08X :", $addrs); + hexdump($buf, 16, 16, " "); + $addrs = $addrs + 0x10; + } + if ( $rem != 0 ) { + $rc = read(INFILE, $buf, $rem); + printf ( "%08X :", $addrs); + hexdump($buf, $rem, 16, " "); + } +} + +close(INFILE); + + +#sub ----------------------------------------------------------- + +sub filedatesdump { + my ($ofst, $len) = @_; + my ($datedata); + my ($i); + my ($datestr); + + @datetype =('create ', 'modify ', 'backup ', 'access '); + + seek(INFILE, $ofst, 0); + + for ( $i = 0 ; $i < 4 ; $i++) { + $rc = read(INFILE,$buf,4); + $datedata = unpack("N", $buf ); + if ($datedata < 0x80000000) { + $datestr = gmtime( $datedata + 946684800) + ." (GMT)\n " + .localtime( $datedata + 946684800) + ." (local)"; + } elsif ($datedata == 0x80000000) { + $datestr = "Unknown or Initial"; + } else { + $datestr = gmtime( $datedata - 3348282496) + ." (GMT) / " + .localtime( $datedata - 3348282496) + ." (local)"; + } + printf ("%s : %08X : %s\n",$datetype[$i], $datedata, $datestr); + } +} + +sub finderinfodump { + my ($ofst, $len) = @_; + + seek(INFILE, $ofst, 0); + + $rc = read(INFILE,$buf,4); + print "Type : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "Creator : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,2); + $flags = unpack("n", $buf ); + printf ("isAlias : %d\n", ($flags >> 15) & 1); + printf ("Invisible : %d\n", ($flags >> 14) & 1); + printf ("hasBundle : %d\n", ($flags >> 13) & 1); + printf ("nameLocked : %d\n", ($flags >> 12) & 1); + printf ("Stationery : %d\n", ($flags >> 11) & 1); + printf ("CustomIcon : %d\n", ($flags >> 10) & 1); + printf ("Reserved : %d\n", ($flags >> 9) & 1); + printf ("Inited : %d\n", ($flags >> 8) & 1); + printf ("NoINITS : %d\n", ($flags >> 7) & 1); + printf ("Shared : %d\n", ($flags >> 6) & 1); + printf ("SwitchLaunc: %d\n", ($flags >> 5) & 1); + printf ("colorReserv: %d\n", ($flags >> 4) & 1); + printf ("color : %d%d%d\n", ($flags >> 3) & 1, + ($flags >> 2) & 1, + ($flags >> 1) & 1); + printf ("isOnDesk : %d\n", ($flags >> 0) & 1); + + $rc = read(INFILE,$buf,4); + print "Location : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,2); + print "Fldr : "; + hexdump($buf, 2, 4, ""); + + $rc = read(INFILE,$buf,2); + print "IconID : "; + hexdump($buf, 2, 4, ""); + + $rc = read(INFILE,$buf,2); + print "Unused : "; + hexdump($buf, 2, 4, ""); + $rc = read(INFILE,$buf,2); + print "Unused : "; + hexdump($buf, 2, 4, ""); + $rc = read(INFILE,$buf,2); + print "Unused : "; + hexdump($buf, 2, 4, ""); + + $rc = read(INFILE,$buf,1); + print "Script : "; + hexdump($buf, 1, 4, ""); + + $rc = read(INFILE,$buf,1); + print "XFlags : "; + hexdump($buf, 1, 4, ""); + + $rc = read(INFILE,$buf,2); + print "Comment : "; + hexdump($buf, 2, 4, ""); + + $rc = read(INFILE,$buf,4); + print "PutAway : "; + hexdump($buf, 4, 4, ""); + + if ($len > 32) { + eadump(); + } + +} + +sub eadump { + my ($eaofst, $ealen); + + $rc = read(INFILE,$buf,2); + print "pad : "; + hexdump($buf, 2, 4, ""); + + $rc = read(INFILE,$buf,4); + print "magic : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "debug_tag : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "total_size : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "data_start : "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "data_length: "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "reserved[2]: "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "reserved[1]: "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,4); + print "reserved[0]: "; + hexdump($buf, 4, 4, ""); + + $rc = read(INFILE,$buf,2); + print "flags : "; + hexdump($buf, 2, 4, ""); + + $rc = read(INFILE,$buf,2); + print "num_attrs : "; + hexdump($buf, 2, 4, ""); + +} + +sub hexdump { + my ($buf, $len, $col, $delimit) = @_; + my ($i); + + $hexstr = ""; + $ascstr = ""; + + for ( $i=0 ; $i < $len ; $i++ ) { + $val = substr($buf, $i, 1); + $ascval = ord($val); + $hexstr .= sprintf("%s%02X", $delimit, $ascval); + + if (($ascval < 32) || ( $ascval > 126 )) { + $val = "."; + } + $ascstr .= $val; + } + for ( ; $i < $col ; $i++) { + $hexstr .= " ".$delimit; + $ascstr .= " "; + } + + printf("%s : %s", $hexstr,$ascstr); + + print "\n"; +} + +sub htonl { unpack("N",pack("L",shift)) } +sub htons { unpack("n",pack("S",shift)) } +sub ntohl { unpack("L",pack("N",shift)) } +sub ntohs { unpack("S",pack("n",shift)) } + +#EOF -- 2.39.2