Copy Link
Add to Bookmark
Report
NULL mag Issue 07 25 Read .dir files
this time lets read a .DIR file, that contains general info for files
inside a filebase and after, read the description (file_id.diz) of
that file, from a .DES file, of mystic.
the readdirfile() function is 99% the same as the readfilebase()
function, also included in this issue. so i am not going to explain
that. but i will explain how to get the description from the .DES
file.
first of all we need three parameters. the offset of the description
inside the .DES file, the length of the text (in lines, not
bytes/chars) and the filename we need to read.
def getfiledesc(ofs,length,filename):
always check if the file exists, otherwise we exit, with some error
num.
if os.path.exists(filename) == False:
return -1
open the file in byte mode, only for reading
f = open(filename, 'rb')
initialize some variables. cnt is how many lines we read until now, x
is the offset while we read the file and finally, desc[] is a list,
containing the description.
cnt = 1
x = 0
desc = []
set the pointer of the file to the desired position. this position we
know it, from the readdirfile() function.
f.seek(ofs,0)
now, until we read all lines of the description, read line by line.
because the .DES file is saved as a Pascal record file, as i have said
countless times, pascal, always saves the length of a string in the
beginning of that string. so if we read it first, we know, how many
characters we need to read next and that's what we do here.
read the length of the string, then read the whole string and append
it to the list
while cnt <=length:
x = f.tell()
c = f.read(1)
f.seek(f.tell()-1)
desc.append((f.read(ord(c)+1)).decode("CP437")[1:])
cnt +=1
close the file and exit the function with the desc[] list as our
result.
f.close()
return desc
done...
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
full script here
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
#!/usr/bin/python3
import os
import struct
import sys
# RecFileList = Record // .DIR
# FileName : String[70];
# Size : Cardinal;
# DateTime : LongInt;
# Uploader : String[30];
# Flags : Byte;
# Downloads : LongInt;
# Rating : Byte;
# DescPtr : Cardinal;
# DescLines : Byte;
# End;
def readdirfile(i,filename):
def byte2str(v):
s=''.join(str(v))
return s[2:-1]
if os.path.exists(filename) == False:
return -1
size = os.path.getsize(filename)
fdirrec = "<x70sLIx30sBIBLB"
sf = struct.calcsize(fdirrec)
items = size // sf
if i > items:
return -3
f = open(filename, 'rb')
try:
f.seek((i-1)*sf,1)
except:
return -2
fdirb = f.read(sf)
s = struct.unpack(fdirrec,fdirb)
f.close()
res = {}
res['filename'] = byte2str(s[0]).replace('\\x00','')
res['size'] = s[1]
res['datetime'] = s[2]
res['uploader'] = byte2str(s[3]).replace('\\x00','')
res['flags'] = s[4]
res['downloads'] = s[5]
res['rating'] = s[6]
res['descptr'] = s[7]
res['desclines'] = s[8]
return res
def getfiledesc(ofs,length,filename):
if os.path.exists(filename) == False:
return -1
f = open(filename, 'rb')
cnt = 1
x = 0
desc = []
f.seek(ofs,0)
while cnt <=length:
x = f.tell()
c = f.read(1)
f.seek(f.tell()-1)
desc.append((f.read(ord(c)+1)).decode("CP437")[1:])
cnt +=1
f.close()
return desc
#change the filenames to yours or else it will fail.
z=readdirfile(1,'fsx_mutl.dir')
desc = getfiledesc(z['descptr'],z['desclines'],'fsx_mutl.des')
for i in range(len(desc)):
print(desc[i])
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
end of script
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>