]> arthur.barton.de Git - netatalk.git/blob - contrib/shell_utils/asaddump.in
asaddump: dump AppleSingle/Double files. From HAT.
[netatalk.git] / contrib / shell_utils / asaddump.in
1 #!@PERL@
2 #
3 # AppleSingle/AppleDouble dump
4 #
5 # (c) 2009 by HAT <hat@fa2.so-net.ne.jp>
6 #
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.
11 #
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.
16 #
17
18 open(INFILE, "<$ARGV[0]");
19
20 binmode(INFILE);     # for DOS/Win
21
22 $addr = 0;
23
24 # Magic Number -----------------------------------------------
25
26 $rc = read(INFILE,$buf,4);
27 $val = unpack("N", $buf );
28 printf("Magic Num. : %08X", $val);
29 if    ( $val == 0x00051600 ) {
30     printf("                                        : AppleSingle");
31 }
32 elsif ( $val == 0x00051607 ) {
33     printf("                                        : AppleDouble");
34 }
35 else                         {
36     printf("                                        : Unknown"    );
37 }
38 print "\n";
39
40 # Version Number ---------------------------------------------
41
42 $rc = read(INFILE,$buf,4);
43 $val = unpack("N", $buf );
44 printf("Ver. Num.  : %08X", $val);
45 if    ( $val == 0x00010000 ) {
46     printf("                                        : Version 1");
47 }
48 elsif ( $val == 0x00020000 ) {
49     printf("                                        : Version 2");
50 }
51 else                         {
52     printf("                                        : Unknown"  );
53 }
54 print "\n";
55
56 # v1:Home file system / v2:Filler ----------------------------
57
58 $rc = read(INFILE,$buf,16);
59 print "Filler     :";
60 hexdump($buf, 16, 16, " ");
61
62 # Number of entities -----------------------------------------
63
64 $rc = read(INFILE,$buf,2);
65 $entnum = unpack("n", $buf );
66 printf("Num. of ent: %04X    ", $entnum);
67 printf("                                        : %d", $entnum);
68 print "\n";
69
70 # data -------------------------------------------------------
71
72 for ( $num = 0 ; $num < $entnum ; $num++) {
73
74     seek(INFILE, ($num * 12 + 26), 0);
75
76 #    Entry ---------------------------------------------------
77
78     $rc = read(INFILE,$buf,4);
79     $entid = unpack("N", $buf );
80     printf("\nEntry ID   : %08X", $entid);
81     if    ( $entid ==  1 ) { printf(" : Data Fork"); }
82     elsif ( $entid ==  2 ) { printf(" : Resource Fork"); }
83     elsif ( $entid ==  3 ) { printf(" : Real Name"); }
84     elsif ( $entid ==  4 ) { printf(" : Comment"); }
85     elsif ( $entid ==  5 ) { printf(" : Icon, B&W"); }
86     elsif ( $entid ==  6 ) { printf(" : Icon Color"); }
87     elsif ( $entid ==  7 ) { printf(" : File Info"); }
88     elsif ( $entid ==  8 ) { printf(" : File Dates Info"); }
89     elsif ( $entid ==  9 ) { printf(" : Finder Info"); }
90     elsif ( $entid == 10 ) { printf(" : Macintosh File Info"); }
91     elsif ( $entid == 11 ) { printf(" : ProDOS File Info"); }
92     elsif ( $entid == 12 ) { printf(" : MS-DOS File Info"); }
93     elsif ( $entid == 13 ) { printf(" : Short Name"); }
94     elsif ( $entid == 14 ) { printf(" : AFP File Info"); }
95     elsif ( $entid == 15 ) { printf(" : Directory ID"); }
96     elsif ( $entid == 0x8053567E ) { printf(" : CNID (Netatalk Extended)"); }
97     elsif ( $entid == 0x8053594E ) { printf(" : DB stamp (Netatalk Extended)"); }
98     elsif ( $entid == 0x80444556 ) { printf(" : dev (Netatalk Extended)"); }
99     elsif ( $entid == 0x80494E4F ) { printf(" : inode (Netatalk Extended)"); }
100     else { printf(" : Unknown"); }
101     print "\n";
102
103 #    Offset -------------------------------------------------
104
105     $rc = read(INFILE,$buf,4);
106     $ofst = unpack("N", $buf );
107     printf("Offset     : %08X", $ofst);
108     printf(" : %d ", $ofst);
109
110 #    Length -------------------------------------------------
111
112     $rc = read(INFILE,$buf,4);
113     $len = unpack("N", $buf );
114     printf("\nLength     : %08X", $len);
115     printf(" : %d", $len);
116     $quo = $len >> 4;
117     $rem = $len & 0xF;
118     print "\n";
119
120 #    if ( $entid ==  1 ) { ; } # Data Fork
121 #    if ( $entid ==  2 ) { ; } # Resource Fork
122 #    if ( $entid ==  3 ) { ; } # Real Name
123 #    if ( $entid ==  4 ) { ; } # Comment
124 #    if ( $entid ==  5 ) { ; } # Icon, B&W
125 #    if ( $entid ==  6 ) { ; } # Icon Color
126 #    if ( $entid ==  7 ) { ; } # File Info
127     if ( $entid ==  8 ) { filedatesdump($ofst,$len); }
128     elsif ( $entid ==  9 ) { finderinfodump($ofst,$len); }
129 #    if ( $entid == 10 ) { ; } # Macintosh File Info
130 #    if ( $entid == 11 ) { ; } # ProDOS File Info
131 #    if ( $entid == 12 ) { ; } # MS-DOS File Info
132 #    if ( $entid == 13 ) { ; } # Short Name
133 #    if ( $entid == 14 ) { ; } # AFP File Info 
134 #    if ( $entid == 15 ) { ; } # Directory ID
135 #    if ( $entid == 0x8053567E  ) { ; } # CNID (Netatalk Extended)
136 #    if ( $entid == 0x8053594E  ) { ; } # DB stamp (Netatalk Extended)
137 #    if ( $entid == 0x80444556  ) { ; } # dev (Netatalk Extended)
138 #    if ( $entid == 0x80494E4F  ) { ; } # inode (Netatalk Extended)
139
140 #    Dump ---------------------------------------------------
141
142     seek(INFILE, $ofst, 0);
143     $addrs = 0;
144     for ( $line = 0 ; $line < $quo ; $line++) {
145         $rc = read(INFILE, $buf, 16);
146         printf ( "%08X   :", $addrs);
147         hexdump($buf, 16, 16, " ");
148         $addrs = $addrs + 0x10;
149     }
150     if ( $rem != 0 ) {
151         $rc = read(INFILE, $buf, $rem);
152         printf ( "%08X   :", $addrs);
153         hexdump($buf, $rem, 16, " ");
154     }
155 }
156
157 close(INFILE);
158
159
160 #sub -----------------------------------------------------------
161
162 sub filedatesdump {
163     my ($ofst, $len) = @_;
164     my ($datedata);
165     my ($i);
166     my ($datestr);
167
168     @datetype =('create    ', 'modify    ', 'backup    ', 'access    ');
169
170     seek(INFILE, $ofst, 0);
171
172     for ( $i = 0 ; $i < 4 ; $i++) {
173         $rc = read(INFILE,$buf,4);
174         $datedata = unpack("N", $buf );
175         if ($datedata < 0x80000000) {
176             $datestr = gmtime( $datedata + 946684800)
177                 ." (GMT)\n                        "
178                 .localtime( $datedata + 946684800)
179                 ." (local)";
180         } elsif ($datedata == 0x80000000) {
181             $datestr = "Unknown or Initial";
182         } else {
183             $datestr = gmtime( $datedata - 3348282496)
184                 ." (GMT) / "
185                 .localtime( $datedata - 3348282496)
186                 ." (local)";
187         }
188         printf ("%s : %08X : %s\n",$datetype[$i], $datedata, $datestr);
189     }
190 }
191
192 sub finderinfodump {
193     my ($ofst, $len) = @_;
194
195     seek(INFILE, $ofst, 0);
196
197     $rc = read(INFILE,$buf,4);
198     print "Type       : ";
199     hexdump($buf, 4, 4, "");
200
201     $rc = read(INFILE,$buf,4);
202     print "Creator    : ";
203     hexdump($buf, 4, 4, "");
204
205     $rc = read(INFILE,$buf,2);
206     $flags = unpack("n", $buf );
207     printf ("isAlias    : %d\n", ($flags >> 15) & 1);
208     printf ("Invisible  : %d\n", ($flags >> 14) & 1);
209     printf ("hasBundle  : %d\n", ($flags >> 13) & 1);
210     printf ("nameLocked : %d\n", ($flags >> 12) & 1);
211     printf ("Stationery : %d\n", ($flags >> 11) & 1);
212     printf ("CustomIcon : %d\n", ($flags >> 10) & 1);
213     printf ("Reserved   : %d\n", ($flags >>  9) & 1);
214     printf ("Inited     : %d\n", ($flags >>  8) & 1);
215     printf ("NoINITS    : %d\n", ($flags >>  7) & 1);
216     printf ("Shared     : %d\n", ($flags >>  6) & 1);
217     printf ("SwitchLaunc: %d\n", ($flags >>  5) & 1);
218     printf ("colorReserv: %d\n", ($flags >>  4) & 1);
219     printf ("color      : %d%d%d\n", ($flags >>  3) & 1,
220             ($flags >>  2) & 1,
221             ($flags >>  1) & 1);
222     printf ("isOnDesk   : %d\n", ($flags >>  0) & 1);
223
224     $rc = read(INFILE,$buf,4);
225     print "Location   : ";
226     hexdump($buf, 4, 4, "");
227
228     $rc = read(INFILE,$buf,2);
229     print "Fldr       : ";
230     hexdump($buf, 2, 4, "");
231
232     $rc = read(INFILE,$buf,2);
233     print "IconID     : ";
234     hexdump($buf, 2, 4, "");
235
236     $rc = read(INFILE,$buf,2);
237     print "Unused     : ";
238     hexdump($buf, 2, 4, "");
239     $rc = read(INFILE,$buf,2);
240     print "Unused     : ";
241     hexdump($buf, 2, 4, "");
242     $rc = read(INFILE,$buf,2);
243     print "Unused     : ";
244     hexdump($buf, 2, 4, "");
245
246     $rc = read(INFILE,$buf,1);
247     print "Script     : ";
248     hexdump($buf, 1, 4, "");
249
250     $rc = read(INFILE,$buf,1);
251     print "XFlags     : ";
252     hexdump($buf, 1, 4, "");
253
254     $rc = read(INFILE,$buf,2);
255     print "Comment    : ";
256     hexdump($buf, 2, 4, "");
257
258     $rc = read(INFILE,$buf,4);
259     print "PutAway    : ";
260     hexdump($buf, 4, 4, "");
261
262     if ($len > 32) {
263         eadump();
264     }
265
266 }
267
268 sub eadump {
269     my ($eaofst, $ealen);
270
271     $rc = read(INFILE,$buf,2);
272     print "pad        : ";
273     hexdump($buf, 2, 4, "");
274
275     $rc = read(INFILE,$buf,4);
276     print "magic      : ";
277     hexdump($buf, 4, 4, "");
278
279     $rc = read(INFILE,$buf,4);
280     print "debug_tag  : ";
281     hexdump($buf, 4, 4, "");
282
283     $rc = read(INFILE,$buf,4);
284     print "total_size : ";
285     hexdump($buf, 4, 4, "");
286
287     $rc = read(INFILE,$buf,4);
288     print "data_start : ";
289     hexdump($buf, 4, 4, "");
290
291     $rc = read(INFILE,$buf,4);
292     print "data_length: ";
293     hexdump($buf, 4, 4, "");
294
295     $rc = read(INFILE,$buf,4);
296     print "reserved[2]: ";
297     hexdump($buf, 4, 4, "");
298
299     $rc = read(INFILE,$buf,4);
300     print "reserved[1]: ";
301     hexdump($buf, 4, 4, "");
302
303     $rc = read(INFILE,$buf,4);
304     print "reserved[0]: ";
305     hexdump($buf, 4, 4, "");
306
307     $rc = read(INFILE,$buf,2);
308     print "flags      : ";
309     hexdump($buf, 2, 4, "");
310
311     $rc = read(INFILE,$buf,2);
312     print "num_attrs  : ";
313     hexdump($buf, 2, 4, "");
314
315 }
316
317 sub hexdump {
318     my ($buf, $len, $col, $delimit) = @_;
319     my ($i);
320
321     $hexstr = "";
322     $ascstr = "";
323
324     for ( $i=0 ; $i < $len ; $i++ ) {
325         $val = substr($buf, $i, 1);
326         $ascval = ord($val);
327         $hexstr .= sprintf("%s%02X", $delimit, $ascval);
328
329         if (($ascval < 32) || (  $ascval > 126 )) {
330             $val = ".";
331         }
332         $ascstr .= $val;
333     }
334     for ( ; $i < $col ; $i++) {
335         $hexstr .= "  ".$delimit;
336         $ascstr .= " ";
337     }
338
339     printf("%s : %s", $hexstr,$ascstr);
340
341     print "\n";
342 }
343
344 sub htonl { unpack("N",pack("L",shift)) }
345 sub htons { unpack("n",pack("S",shift)) }
346 sub ntohl { unpack("L",pack("N",shift)) }
347 sub ntohs { unpack("S",pack("n",shift)) }
348
349 #EOF