- # Read metadata sector, which has a 4-byte signature followed by
- # the file size.
- my ($metadata) = read_fully ($disk_handle, $disk_file_name, 512);
- my ($signature, $size) = unpack ("a4 V", $metadata);
- (print STDERR "bad signature on scratch disk--did Pintos run fail?\n"),
- return 0
- if $signature ne "GET\0";
+ # Read ustar header sector.
+ my ($header) = read_fully ($disk_handle, $disk_file_name, 512);
+ return "scratch disk tar archive ends unexpectedly"
+ if $header eq ("\0" x 512);
+
+ # Verify magic numbers.
+ return "corrupt ustar signature" if substr ($header, 257, 6) ne "ustar\0";
+ return "invalid ustar version" if substr ($header, 263, 2) ne '00';
+
+ # Verify checksum.
+ my ($chksum) = oct (unpack ("Z*", substr ($header, 148, 8)));
+ my ($correct_chksum) = calc_ustar_chksum ($header);
+ return "checksum mismatch" if $chksum != $correct_chksum;
+
+ # Get type.
+ my ($typeflag) = substr ($header, 156, 1);
+ return "not a regular file" if $typeflag ne '0' && $typeflag ne "\0";
+
+ # Get size.
+ my ($size) = oct (unpack ("Z*", substr ($header, 124, 12)));
+ return "bad size $size\n" if $size < 0;