11#! /usr/bin/env lua
22
33H = [[ This script shows what blocks are allocated to what files on a FAT12/16 formatted floppy disk image (.IMA).
4- The -z option will zero out unallocated clusters. Always backup the IMA before using this tool with the -z option on it.]]
4+ The -z option will zero out unallocated clusters. Always backup the IMA before using the -z option on it.]]
55if # arg < 1 then print (arg [- 1 ].. " " .. arg [0 ].. " [-z] [FILE...]" .. ' \n\n ' .. H )os.exit (1 )end
6- function A ()F = {} for _ ,v in ipairs (arg )do if v == " -z" then Z = true else table.insert (F ,v )end end end
76function R16 (s ,o )local a ,b = s :byte (o ,o + 1 )return a + b * 256 end
87function R32 (s ,o )local a ,b ,c ,d = s :byte (o ,o + 3 )return a + b * 256 + c * 65536 + d * 16777216 end
98function F12 (f ,o ,s )f :seek (" set" ,o )local fd ,fat ,mc = f :read (s ),{},math.floor (s * 8 / 12 )
@@ -16,8 +15,9 @@ function FD(ts,rs,nf,sf,rd,sc)
1615 local cc = math.floor ((ts - rs - (nf * sf )- rd )/ sc )
1716 if cc < 4085 then return 12 elseif cc < 65525 then return 16 else return 32 end end
1817function CC (fat ,sc )
19- local chain ,current = {},sc
20- while current >= 2 and current < 0xFF8 do table.insert (chain ,current )current = fat [current ] end return chain end
18+ local h ,c = {},sc
19+ while c >= 2 and c < 0xFF8 do table.insert (h ,c )c = fat [c ] end return h
20+ end
2121function FR (c )
2222 table.sort (c )local ranges ,i = {},1
2323 while i <=# c do
@@ -30,20 +30,17 @@ function DE(f,o,e,fat)
3030 for _ = 1 ,e do
3131 local en ,fb = f :read (32 )if not en then break end fb = en :byte (1 )if fb == 0 then break end
3232 if fb ~= 229 and (en :byte (12 )&8 )== 0 then
33- local n ,x = en :sub (1 ,8 ):gsub (" +$" ," " ),en :sub (9 ,11 ):gsub (" +$" ," " )n = n .. ( x ~= " " and " . " .. x or " " )
34- io.write (string.format (" \t %12s: % s\n " ,n ,FR (CC (fat ,R16 (en ,27 )))))end end end
33+ local n ,x = en :sub (1 ,8 ):gsub (" +$" ," " ),en :sub (9 ,11 ):gsub (" +$" ," " )
34+ io.write (string.format (" \t %8s %3s % s\n " ,n , x ,FR (CC (fat ,R16 (en ,27 )))))end end end
3535function FC (fat ,f ,st ,s )
36- io.write (" \n\t Free Space: " )
37- local free ,zero = {},string.rep (" \0 " ,s )
38- for i = 2 ,# fat do if fat [i ]== 0 then table.insert (free ,i )if Z then local o = st + (i - 2 )* s f :seek (" set" ,o )f :write (zero )end end end print (FR (free ))end
39- A ()for _ ,file in ipairs (F )do
40- local f = io.open (file ,(Z and " r+b" or " rb" ))
41- if f then
42- print (file .. " :" )
43- local boot = f :read (512 )assert (boot :sub (1 ,1 ):byte ()== 0xEB or boot :sub (1 ,1 ):byte ()== 0xE9 ," Invalid boot sector" )
44- local bs ,sc ,rs ,nf ,re ,ts ,sf = R16 (boot ,12 ),boot :byte (14 ),R16 (boot ,15 ),boot :byte (17 ),R16 (boot ,18 ),R16 (boot ,19 )or R32 (boot ,32 ),R16 (boot ,23 )
45- local rd ,fo ,fs ,ro = math.ceil (re * 32 / bs ),rs * bs ,sf * bs ,(rs + nf * sf )* bs
46- local ft = FD (ts ,rs ,nf ,sf ,rd ,bs )
36+ local fr ,z = {},string.rep (" \0 " ,s )io.write (" \n\t Free Space " )
37+ for i = 2 ,# fat do if fat [i ]== 0 then table.insert (fr ,i )if Z then local o = st + (i - 2 )* s f :seek (" set" ,o )f :write (z )end end end print (FR (fr ))end
38+ F = {}for _ ,v in ipairs (arg )do if v == " -z" then Z = 1 else table.insert (F ,v )end end for _ ,file in ipairs (F )do
39+ local f = io.open (file ,(Z and " r+b" or " rb" ))if f then
40+ print (file .. " :" )
41+ local b ,o = f :read (512 )o = b :sub (1 ,1 ):byte ()if o == 235 or o == 233 then
42+ local bs ,sc ,rs ,nf ,re ,ts ,sf = R16 (b ,12 ),b :byte (14 ),R16 (b ,15 ),b :byte (17 ),R16 (b ,18 ),R16 (b ,19 )or R32 (b ,32 ),R16 (b ,23 )
43+ local rd ,fo ,fs ,ro ,ft = math.ceil (re * 32 / bs ),rs * bs ,sf * bs ,(rs + nf * sf )* bs ft = FD (ts ,rs ,nf ,sf ,rd ,bs )
4744 print (string.format (" \t FAT type: FAT%s\n\t Bytes/sector: %d\n\t Sectors/cluster: %d\n\n " ,ft ,bs ,sc ))
4845 local fat = ft == 12 and F12 (f ,fo ,fs )or ft == 16 and F16 (f ,fo ,fs )or error (" Non-FAT type" )
49- DE (f ,ro ,re ,fat )FC (fat ,f ,(rs + (nf * sf )+ rd )* bs ,sc * bs )f :close ()print ()end end
46+ DE (f ,ro ,re ,fat )FC (fat ,f ,(rs + (nf * sf )+ rd )* bs ,sc * bs )end f :close ()print ()end end
0 commit comments