_ _ _ ____ _ _
/ \ _ __ ___ | |_| |__ ___ _ __ | _ \ _ __ ___ (_) __| |
/ _ \ | '_ \ / _ \| __| '_ \ / _ \ '__| | | | | '__/ _ \| |/ _\` |
/ ___ \| | | | (_) | |_| | | | __/ | | |_| | | | (_) | | (_| |
/_/ \_\_| |_|\___/ \__|_| |_|\___|_| |____/|_| \___/|_|\__,_|
bbs
XQTRs lair...
Home //
Blog //
NULL emag. //
Files //
Docs //
Tutors //
GitHub repo
read filebases with python;xqtr;mystic;tut08
on the same concept we begin translating things for mystic bbs into
python code, lets write some code to get the filebases options, from
the fbase.dat file.
the record of each filebase has the following format:
RecFileBase = Record
Index : Word;
Name : String[60];
FtpName : String[60];
FileName : String[40];
DispFile : String[20];
Template : String[20];
ListACS : String[30];
FtpACS : String[30];
DLACS : String[30];
ULACS : String[30];
HatchACS : String[30];
SysOpACS : String[30];
PassEACS : String[30];
Path : String[mysMaxPathSize];
DefScan : Byte;
Flags : LongInt;
Created : LongInt;
NetAddr : Byte;
EchoTag : String[40];
ListEACS : String[30];
Res : Array[1..53] of Byte;
End;
this is a pascal format record. we must have in mind that pascal,
stores strings in a unique way. before the string, it always puts the
size of the string. so a string[60] type variable, will be actually 61
bytes in the file. for this reason we have to pad this byte and not
use it at all or we can read it and then copy only those bytes from
the string that follows. in this example i am padding the size and not
using at all.
lets begin... first import the libs we need
import os
import struct
we will need this handy function to convert bytes to a string format:
def byte2str(v):
s=''.join(str(v))
return s[2:-1]
check if the file exists... otherwise exit with an error value
if os.path.exists(filename) == False:
return -1
we have to check if the index of the base we want is a valid number. so
we take the size of the fbases.dat file and divide it with the size of
the record to find how many bases includes.
size = os.path.getsize(filename) # the file size
fbaserec = " items:
return -3
open the fbases.dat file and go to the position of the file base we
want, with the seek function
f = open(filename, 'rb')
try:
f.seek((i-1)*sf,1)
except:
return -2
read the bytes of the record
fbaseb = f.read(sf)
unpack the data and close the file
s = struct.unpack(fbaserec,fbaseb)
f.close()
we store all data into a dictionary. we are converting any strings that
are represented as bytes to a string format and also remove the \\x00
chars from it.
res = {}
res['index'] = s[0]
res['name'] = byte2str(s[1]).replace('\\x00','')
res['ftpname'] = byte2str(s[2]).replace('\\x00','')
res['filename'] = byte2str(s[3]).replace('\\x00','')
res['dispfile'] = byte2str(s[4]).replace('\\x00','')
res['template'] = byte2str(s[5]).replace('\\x00','')
res['listacs'] = byte2str(s[6]).replace('\\x00','')
res['ftpacs'] = byte2str(s[7]).replace('\\x00','')
res['downloadacs'] = byte2str(s[8]).replace('\\x00','')
res['uploadacs'] = byte2str(s[9]).replace('\\x00','')
res['hatchacs'] = byte2str(s[10]).replace('\\x00','')
res['sysopacs'] = byte2str(s[11]).replace('\\x00','')
res['passeacs'] = byte2str(s[12]).replace('\\x00','')
res['path'] = byte2str(s[13]).replace('\\x00','')
res['defscan'] = s[14]
res['flags'] = s[15]
res['created'] = s[16]
res['netaddr'] = s[17]
res['echotag'] = byte2str(s[18]).replace('\\x00','')
res['listeacs'] = byte2str(s[19]).replace('\\x00','')
res['reserved'] = s[20:]
the result will be our dictionary variable
return res
i hope this is easy to understand and will be helpful in your projects.
below the complete code, just copy/paste
/./././././././././././././././././././././././././././././././././././././
#!/usr/bin/python3
import os
import struct
import sys
# Type
# RecFileBase = Record
# Index : Word;
# Name : String[60];
# FtpName : String[60];
# FileName : String[40];
# DispFile : String[20];
# Template : String[20];
# ListACS : String[30];
# FtpACS : String[30];
# DLACS : String[30];
# ULACS : String[30];
# HatchACS : String[30];
# SysOpACS : String[30];
# PassEACS : String[30];
# Path : String[mysMaxPathSize];
# DefScan : Byte;
# Flags : LongInt;
# Created : LongInt;
# NetAddr : Byte;
# EchoTag : String[40];
# ListEACS : String[30];
# Res : Array[1..53] of Byte;
# End;
def readfilebase(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)
fbaserec = " items:
return -3
f = open(filename, 'rb')
try:
f.seek((i-1)*sf,1)
except:
return -2
fbaseb = f.read(sf)
s = struct.unpack(fbaserec,fbaseb)
f.close()
res = {}
res['index'] = s[0]
res['name'] = byte2str(s[1]).replace('\\x00','')
res['ftpname'] = byte2str(s[2]).replace('\\x00','')
res['filename'] = byte2str(s[3]).replace('\\x00','')
res['dispfile'] = byte2str(s[4]).replace('\\x00','')
res['template'] = byte2str(s[5]).replace('\\x00','')
res['listacs'] = byte2str(s[6]).replace('\\x00','')
res['ftpacs'] = byte2str(s[7]).replace('\\x00','')
res['downloadacs'] = byte2str(s[8]).replace('\\x00','')
res['uploadacs'] = byte2str(s[9]).replace('\\x00','')
res['hatchacs'] = byte2str(s[10]).replace('\\x00','')
res['sysopacs'] = byte2str(s[11]).replace('\\x00','')
res['passeacs'] = byte2str(s[12]).replace('\\x00','')
res['path'] = byte2str(s[13]).replace('\\x00','')
res['defscan'] = s[14]
res['flags'] = s[15]
res['created'] = s[16]
res['netaddr'] = s[17]
res['echotag'] = byte2str(s[18]).replace('\\x00','')
res['listeacs'] = byte2str(s[19]).replace('\\x00','')
res['reserved'] = s[20:]
return res
for i in range(36):
z=readfilebase(i,'fbases.dat')
print(z)