]> arthur.barton.de Git - netatalk.git/blob - contrib/shell_utils/asaddump.in
Nicely print dev/ino data. 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 use bigint; # require perl >= 5.8
19
20 open(INFILE, "<$ARGV[0]");
21
22 binmode(INFILE);     # for DOS/Win
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 #     Dump for each Entry ID --------------------------------
121
122 #    if ( $entid ==  1 ) { ; } # Data Fork
123 #    if ( $entid ==  2 ) { ; } # Resource Fork
124 #    if ( $entid ==  3 ) { ; } # Real Name
125 #    if ( $entid ==  4 ) { ; } # Comment
126 #    if ( $entid ==  5 ) { ; } # Icon, B&W
127 #    if ( $entid ==  6 ) { ; } # Icon Color
128 #    if ( $entid ==  7 ) { ; } # File Info
129     if ( $entid ==  8 ) { filedatesdump($ofst,$len); }
130     elsif ( $entid ==  9 ) { finderinfodump($ofst,$len); }
131 #    if ( $entid == 10 ) { ; } # Macintosh File Info
132 #    if ( $entid == 11 ) { ; } # ProDOS File Info
133 #    if ( $entid == 12 ) { ; } # MS-DOS File Info
134 #    if ( $entid == 13 ) { ; } # Short Name
135 #    if ( $entid == 14 ) { ; } # AFP File Info 
136     elsif ( $entid == 15 ) { bedump($ofst,$len); } # Directory ID
137     elsif ( $entid == 0x8053567E  ) { bedump($ofst,$len); } # CNID (Netatalk Extended)
138     elsif ( $entid == 0x8053594E  ) { bedump($ofst,$len); ledump($ofst,$len); } # DB stamp (Netatalk Extended)
139     elsif ( $entid == 0x80444556  ) { bedump($ofst,$len); ledump($ofst,$len); } # dev (Netatalk Extended)
140     elsif ( $entid == 0x80494E4F  ) { bedump($ofst,$len); ledump($ofst,$len); } # inode (Netatalk Extended)
141
142 #    Hex Dump ---------------------------------------------------
143
144     seek(INFILE, $ofst, 0);
145     $addrs = 0;
146     for ( $line = 0 ; $line < $quo ; $line++) {
147         $rc = read(INFILE, $buf, 16);
148         printf ( "%08X   :", $addrs);
149         hexdump($buf, 16, 16, " ");
150         $addrs = $addrs + 0x10;
151     }
152     if ( $rem != 0 ) {
153         $rc = read(INFILE, $buf, $rem);
154         printf ( "%08X   :", $addrs);
155         hexdump($buf, $rem, 16, " ");
156     }
157 }
158
159 close(INFILE);
160
161
162 #sub -----------------------------------------------------------
163
164 sub filedatesdump {
165     my ($ofst, $len) = @_;
166     my ($datedata);
167     my ($i);
168     my ($datestr);
169
170     @datetype =('create    ', 'modify    ', 'backup    ', 'access    ');
171
172     seek(INFILE, $ofst, 0);
173
174     for ( $i = 0 ; $i < 4 ; $i++) {
175         $rc = read(INFILE,$buf,4);
176         $datedata = unpack("N", $buf );
177         if ($datedata < 0x80000000) {
178             $datestr = gmtime( $datedata + 946684800)
179                 ." (GMT)\n                        "
180                 .localtime( $datedata + 946684800)
181                 ." (local)";
182         } elsif ($datedata == 0x80000000) {
183             $datestr = "Unknown or Initial";
184         } else {
185             $datestr = gmtime( $datedata - 3348282496)
186                 ." (GMT) / "
187                 .localtime( $datedata - 3348282496)
188                 ." (local)";
189         }
190         printf ("%s : %08X : %s\n",$datetype[$i], $datedata, $datestr);
191     }
192 }
193
194 sub finderinfodump {
195     my ($ofst, $len) = @_;
196
197     seek(INFILE, $ofst, 0);
198
199     $rc = read(INFILE,$buf,4);
200     print "Type       : ";
201     hexdump($buf, 4, 4, "");
202
203     $rc = read(INFILE,$buf,4);
204     print "Creator    : ";
205     hexdump($buf, 4, 4, "");
206
207     $rc = read(INFILE,$buf,2);
208     $flags = unpack("n", $buf );
209     printf ("isAlias    : %d\n", ($flags >> 15) & 1);
210     printf ("Invisible  : %d\n", ($flags >> 14) & 1);
211     printf ("hasBundle  : %d\n", ($flags >> 13) & 1);
212     printf ("nameLocked : %d\n", ($flags >> 12) & 1);
213     printf ("Stationery : %d\n", ($flags >> 11) & 1);
214     printf ("CustomIcon : %d\n", ($flags >> 10) & 1);
215     printf ("Reserved   : %d\n", ($flags >>  9) & 1);
216     printf ("Inited     : %d\n", ($flags >>  8) & 1);
217     printf ("NoINITS    : %d\n", ($flags >>  7) & 1);
218     printf ("Shared     : %d\n", ($flags >>  6) & 1);
219     printf ("SwitchLaunc: %d\n", ($flags >>  5) & 1);
220     printf ("colorReserv: %d\n", ($flags >>  4) & 1);
221     printf ("color      : %d%d%d\n", ($flags >>  3) & 1,
222             ($flags >>  2) & 1,
223             ($flags >>  1) & 1);
224     printf ("isOnDesk   : %d\n", ($flags >>  0) & 1);
225
226     $rc = read(INFILE,$buf,4);
227     print "Location   : ";
228     hexdump($buf, 4, 4, "");
229
230     $rc = read(INFILE,$buf,2);
231     print "Fldr       : ";
232     hexdump($buf, 2, 4, "");
233
234     $rc = read(INFILE,$buf,2);
235     print "IconID     : ";
236     hexdump($buf, 2, 4, "");
237
238     $rc = read(INFILE,$buf,2);
239     print "Unused     : ";
240     hexdump($buf, 2, 4, "");
241     $rc = read(INFILE,$buf,2);
242     print "Unused     : ";
243     hexdump($buf, 2, 4, "");
244     $rc = read(INFILE,$buf,2);
245     print "Unused     : ";
246     hexdump($buf, 2, 4, "");
247
248     $rc = read(INFILE,$buf,1);
249     print "Script     : ";
250     hexdump($buf, 1, 4, "");
251
252     $rc = read(INFILE,$buf,1);
253     print "XFlags     : ";
254     hexdump($buf, 1, 4, "");
255
256     $rc = read(INFILE,$buf,2);
257     print "Comment    : ";
258     hexdump($buf, 2, 4, "");
259
260     $rc = read(INFILE,$buf,4);
261     print "PutAway    : ";
262     hexdump($buf, 4, 4, "");
263
264     if ($len <= 32) { return; }
265
266     $rc = read(INFILE,$buf,2);
267     print "pad        : ";
268     hexdump($buf, 2, 4, "");
269
270     $rc = read(INFILE,$buf,4);
271     print "magic      : ";
272     hexdump($buf, 4, 4, "");
273
274     $rc = read(INFILE,$buf,4);
275     print "debug_tag  : ";
276     hexdump($buf, 4, 4, "");
277
278     $rc = read(INFILE,$buf,4);
279     $ofst = unpack("N", $buf );
280     printf("total_size : %08X", $ofst);
281     printf(" : %d \n", $ofst);
282
283     $rc = read(INFILE,$buf,4);
284     $ofst = unpack("N", $buf );
285     printf("data_start : %08X", $ofst);
286     printf(" : %d \n", $ofst);
287
288     $rc = read(INFILE,$buf,4);
289     $ofst = unpack("N", $buf );
290     printf("data_length: %08X", $ofst);
291     printf(" : %d \n", $ofst);
292
293     $rc = read(INFILE,$buf,4);
294     print "reserved[0]: ";
295     hexdump($buf, 4, 4, "");
296
297     $rc = read(INFILE,$buf,4);
298     print "reserved[1]: ";
299     hexdump($buf, 4, 4, "");
300
301     $rc = read(INFILE,$buf,4);
302     print "reserved[2]: ";
303     hexdump($buf, 4, 4, "");
304
305     $rc = read(INFILE,$buf,2);
306     print "flags      : ";
307     hexdump($buf, 2, 4, "");
308
309     $rc = read(INFILE,$buf,2);
310     $ofst = unpack("n", $buf );
311     printf("num_attrs  : %04X", $ofst);
312     printf("     : %d \n", $ofst);
313
314 }
315
316 sub bedump  {
317     my ($ofst, $len) = @_;
318     my ($i);
319     my ($value);
320     
321     seek(INFILE, $ofst, 0);
322     
323     printf("%2dbit-BE   : ", $len * 8 );
324     
325     $value = 0;
326     for ( $i=0 ; $i < $len ; $i++ ) {
327         $rc = read(INFILE,$buf,1);
328         $bytedata[$i] = unpack("C", $buf );
329         $value += $bytedata[$i] << (($len - $i -1) * 8) ;
330     }
331
332     for ( $i=0 ; $i < $len ; $i++ ) {
333         printf("%02X", $bytedata[$i]);
334     }
335
336     printf(" : %s", $value);
337     print "\n";
338     
339 }
340
341 sub ledump  {
342     my ($ofst, $len) = @_;
343     my ($i);
344     my ($value);
345     
346     seek(INFILE, $ofst, 0);
347     
348     printf("%2dbit-LE   : ", $len * 8 );
349     
350     $value = 0;
351     for ( $i=0 ; $i < $len ; $i++ ) {
352         $rc = read(INFILE,$buf,1);
353         $bytedata[$len - $i - 1] = unpack("C", $buf );
354         $value += $bytedata[$len - $i -1] << ($i * 8) ;
355     }
356
357     for ( $i=0 ; $i < $len ; $i++ ) {
358         printf("%02X", $bytedata[$i]);
359     }
360
361     printf(" : %s", $value);
362     print "\n";
363     
364 }
365
366 sub hexdump {
367     my ($buf, $len, $col, $delimit) = @_;
368     my ($i);
369
370     $hexstr = "";
371     $ascstr = "";
372
373     for ( $i=0 ; $i < $len ; $i++ ) {
374         $val = substr($buf, $i, 1);
375         $ascval = ord($val);
376         $hexstr .= sprintf("%s%02X", $delimit, $ascval);
377
378         if (($ascval < 32) || (  $ascval > 126 )) {
379             $val = ".";
380         }
381         $ascstr .= $val;
382     }
383     for ( ; $i < $col ; $i++) {
384         $hexstr .= "  ".$delimit;
385         $ascstr .= " ";
386     }
387
388     printf("%s : %s", $hexstr,$ascstr);
389
390     print "\n";
391 }
392
393 #EOF