home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
13
/
COMMIO0B.ZIP
/
DFUNIT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-05-14
|
14KB
|
422 lines
{$V-,O+,F+}
{^..^ overlay it; since the routines here are only used once, theres no
need for the code to sit in memory, if not being used. }
unit DFunit; {Drop file unit}
{
This unit is a companion to the COMMIO communications kit.
Written by Jason Morriss a.k.a. Lief O'Pardy
Copyright (C) 1995,1996 by Jason Morriss
v- All of the following crap can be ignored (except for the last paragraph)
I finally decided that this method will still require just about the
same amount of programming. The Last paragraph discribes the best
option IMO.
This unit contains the functions needed to read in a drop file that the
BBS creates when your DOOR is run. I thought long and hard trying to
make this unit easy to use. Since there are a countless number of
different Drop File formats, its hard to make it easy for the programmer
to support them all (or most), without a lot of extra programming. I
finally decided to make a seperate RECORD for each format (only the ones
that i know are implemented). But no variables of those types are declared
by this unit, Thats totally up to the programmer. The method i can think
of that is the easiest to use (IMO), would be something like:
x) This method is useful because you only need to declare _1_ pointer,
and you can use all of the different types of drop files. The method
below is only a suggestion, you don't have to use it. You could also
declare a variable for each dropfile, and do it that way, but it takes
more memory that way... its a waste. anyways...
1) declare a pointer in your program (a generic pointer, that is... it
must not have a TYPE except of "pointer"; ie: p:pointer).
2) Decide which Dropfile you want to load (either through the command
line, or an INI file, etc), and getmem() memory for the pointer. The
amount of memory it needs depends on which dropfile your going to
load. Use the record types that i defined in the interface section.
(ie: sizeof(Tchain_txt))
3) Call the corresponding function to load the dropfile you want, passing
the pointer you created as the buffer to be filled.
4) Later in your program, whenever you need to get info from the pointer,
you have to TYPECAST the pointer to the corresponding dropfile record
needed. Example: port := Tchain_txt(p^).comport;
Looks weird? it does kinda, but those that haven't seen anything
like this, its easy to understand. What it does is, it "fools" TP
into thinking that p^ is actually of the type Tchain_txt, and not
a pointer, this way TP will calculate the offset needed to find the
"comport" variable in p^.
4a) If your going to support more then 1 dropfile then you'll have to
setup some sort of case statement everywhere you want to access info
from the dropfile buffer. Just create a variable of the type
"Tdropfiles", and when you load a dropfile, change the variable to
the dropfile loaded. ie:
case DFloaded of
DFdorinfox_def : port := Tdorinfox_def(p^).comport;
DFchain_txt : port := Tchain_txt(p^).comport;
end;
That does require a little more programming on your part, but i feel
that its minimal.
Another method that would be a LOT easier is to make a seperate program
to read in the drop file that the sysop specifies, and extract all
important data from it (anything your door needs) into another file.
Then your door would only need to support that _1_ (one, uno) file, and
no extra programming is needed in the actual DOOR code! At the time that
I write this, i have not made such a program... But I might create one for
this door library (its easy enough ;)
}
interface
uses dos;
type
string40 = string[40];
TUserSex = (SexUnknown,SexMale,SexFemale);
TDropFiles = (DFfake,DFdorinfox_def,DFchain_txt); {known drop file types}
TDorinfox_Def = record
Node : byte;
BBSName : string[40];
SysopName : string[40];
{^ FName & LName are actually on seperate lines (LName is blank if none;
but the line for it is STILL there!)}
Comport : byte;
Baudrate : longint;
DataBits : byte;
StopBits : byte;
Parity : char;
_Unknown_ : byte; {this has always been 0 in my experience}
UserName : string[40]; {could be an alias or real name (but mostly alias i think)}
{^ FName & LName are actually on seperate lines (LName is blank if none;
but the line for it is STILL there!)}
UserLoc : string[40]; {ie: "Silver Spring, MD" [w/o quotes]}
UseAnsi : boolean;
Seclevel : integer;
BBSMinLeft : word; {minutes left on BBS, when user entered DOOR}
UseFossil : boolean;
end;
TChain_Txt = record
UserNum : word;
UserName : string[40]; {user's ALIAS}
UserRealName : string[40];
UserCallSign : string[15];
{^ what the hell is "HAM radio"!?!? In my 3½ years of BBSing, i've
never been able to find out! (i haven't really looked either ;)}
UserAge : byte;
UserSex : TUserSex;
UserGold : Real;
LastLogon : string[10]; {ie: "08/5/95" [w/o quotes]}
ScreenWidth : byte; {80 mostly}
ScreenLength : byte; {24/25 mostly}
SecLevel : integer;
IsCoSysop : boolean; {Is user a CoSysop?}
IsSysop : boolean; {Is user the Sysop?}
UseAnsi : boolean;
Local : boolean; {Is user on locally?}
BBSsecLeft : real; {Seconds left on BBS, before entering DOOR}
GFILESpath : string[80];
SYSDATApath : string[80];
SYSLOGname : string[12];
Baudrate : longint;
Comport : byte;
BBSname : string[40];
SysopName : string[40];
_Unknown_ : longint; {# of secs after midnight... or something...?}
UserTotalSec : longint;
UserTotalULk : longint;
UserTotalUL : word;
UserTotalDLk : longint;
UserTotalDL : word;
DataBits : byte; {this actually is written to the file like: "8N1". }
parity : char; {"}
StopBits : byte; {"}
end;
{const
AutoFillDoorRec : boolean = true;{}
{─--[headers]-──────────────────────────────────────────────────────────────}
Function Read_Fake:boolean;
{^ "fake" reading a dropfile. This is to help you test your DOOR, w/o
needing a dropfile. This will load in a bunch of default settings, so
you won't just have a zero dropfile record. If you don't load a DropFile,
then all the comport info MUST be in the INI file, or you can get it from
the command line. It is suggested though, that you always include an INI
file with your DOOR, its easier then using the command line, IMO. }
Function Read_ChainTxt(fn:pathstr; var p):boolean;
{^ Read in a CHAIN.TXT dropfile.
NOTE: This function is untested, but it should work fine.
fn = [d:\path\]filename to drop file. If the file is in another
directory, then the entire path WILL need to be given.
P = Buffer to store the info. Besure its large enough to hold the
entire record. }
Function Read_DorinfoxDef(fn:pathstr; var p):boolean;
{^ Read in a DORINFOx.DEF dropfile.
NOTE: This function has been tested, and it works.
fn = [d:\path\]filename to drop file. If the file is in another
directory, then the entire path WILL need to be given.
The "X" in the filename is actually replaced (by the bbs) with
the node # of the user about to play your door. It ranges from
0..9. So the filename never actually has an "X" in it.
P = Buffer to store the info. Besure its large enough to hold the
entire record. }
implementation
var
f : text; {used in reading the drop files}
i,e : integer; {"}
s,s2 : string; {"}
{───────────────────────────────────────────────────────────────────────────}
procedure KillExtraBlanks(var s:string);
{This only kills the blanks in front of and at the end of the string}
var i:byte;
begin
i:=1;
while (s[i]=' ')and(i<=length(s)) do delete(s,i,1);
i:=length(s);
while (s[i]=' ')and(i>=1) do begin
delete(s,i,1);
dec(i);
end;
end;
{───────────────────────────────────────────────────────────────────────────}
Function Read_DorinfoxDef;
var
buf : TDorinfox_Def absolute p;
begin
fillchar(buf,sizeof(buf),0);
assign(f,fn);
{$I-}
reset(f);
{$I+}
if IOresult<>0 then begin
Read_DorinfoxDef:=false;
exit;
end;
s:=fn[length(fn)-4]; {get node# from filename}
val(s,buf.node,e);
readln(f,buf.BBSname); {get BBS name}
killextrablanks(buf.BBSname);
readln(f,s); {get sysop's name}
killextrablanks(s);
buf.sysopname:=s;
readln(f,s);
killextrablanks(s);
buf.sysopname:=buf.sysopname+' '+s;
readln(f,s); {get comport}
killextrablanks(s);
while not (s[1] in ['0'..'9']) do delete(s,1,1);
val(s,buf.comport,e);
readln(f,s); {get baudrate & parity info}
killextrablanks(s);
s2:='';
while s[1] in ['0'..'9'] do begin
s2:=s2 + s[1];
delete(s,1,1);
end;
val(s2,buf.baudrate,e);
while not (s[1]=',' {in [',']}) do delete(s,1,1);
delete(s,1,1);
buf.parity:=s[1];
delete(s,1,2);
val(s[1],buf.databits,e);
delete(s,1,2);
val(s[1],buf.stopbits,e);
readln(f,s); {get _unknown_ variable}
val(s,buf._unknown_,e);
readln(f,s); {get user's name}
killextrablanks(s);
buf.username:=s;
readln(f,s);
killextrablanks(s);
buf.username:=buf.username+' '+s;
readln(f,s); {get user's location}
killextrablanks(s);
buf.userloc:=s;
readln(f,s); {get ansi mode (on/off)}
killextrablanks(s);
{ val(s[1],i,e);
buf.UseAnsi:=(i=1);{}
buf.UseAnsi:=(s[1]='1');
readln(f,s); {get security level}
killextrablanks(s);
val(s,buf.seclevel,e);
readln(f,s); {get minutes left on BBS}
killextrablanks(s);
val(s,buf.BBSMinLeft,e);
readln(f,s); {get fossil info (on/off)}
killextrablanks(s);
val(s,i,e);
buf.UseFossil:=(i=-1);
close(f);
Read_DorinfoxDef:=true;
end;
{───────────────────────────────────────────────────────────────────────────}
Function Read_ChainTxt;
var
buf : TChain_Txt absolute p;
begin
fillchar(buf,sizeof(buf),0);
assign(f,fn);
{$I-}
reset(f);
{$I+}
if IOresult<>0 then begin
Read_ChainTxt:=false;
exit;
end;
readln(f,s); {get user #}
killextrablanks(s);
val(s,buf.usernum,e);
readln(f,s); {get user's name}
killextrablanks(s);
buf.username:=s;
readln(f,s); {get user's name}
killextrablanks(s);
buf.userrealname:=s;
readln(f,s);
killextrablanks(s);
buf.usercallsign:=s;
readln(f,s);
killextrablanks(s);
val(s,buf.userage,e);
readln(f,s);
killextrablanks(s);
case s[1] of
'M' : buf.usersex:=sexmale;
'F' : buf.usersex:=sexfemale;
else buf.usersex:=sexunknown;
end;
readln(f,s);
killextrablanks(s);
val(s,buf.usergold,e);
readln(f,s);
killextrablanks(s);
buf.lastlogon:=s;
readln(f,s);
killextrablanks(s);
val(s,buf.ScreenWidth,e);
readln(f,s);
killextrablanks(s);
val(s,buf.ScreenLength,e);
readln(f,s);
killextrablanks(s);
val(s,buf.seclevel,e);
readln(f,s);
killextrablanks(s);
buf.IsCoSysop:=boolean(ord(s[1]));
readln(f,s);
killextrablanks(s);
buf.IsSysop:=boolean(ord(s[1]));
readln(f,s);
killextrablanks(s);
buf.UseAnsi:=boolean(ord(s[1]));
readln(f,s);
killextrablanks(s);
buf.Local:=not boolean(ord(s[1]));
readln(f,s);
killextrablanks(s);
val(s,buf.bbssecleft,e);
readln(f,s);
killextrablanks(s);
buf.GFILESpath:=s;
readln(f,s);
killextrablanks(s);
buf.SYSDATApath:=s;
readln(f,s);
killextrablanks(s);
buf.SYSLOGname:=s;
readln(f,s);
killextrablanks(s);
val(s,buf.baudrate,e);
readln(f,s);
killextrablanks(s);
val(s,buf.comport,e);
readln(f,s);
killextrablanks(s);
buf.BBSname:=s;
readln(f,s);
killextrablanks(s);
buf.SysopName:=s;
readln(f,s);
killextrablanks(s);
val(s,buf._unknown_,e);
readln(f,s);
killextrablanks(s);
val(s,buf.UserTotalSec,e);
readln(f,s);
killextrablanks(s);
val(s,buf.UserTotalULk,e);
readln(f,s);
killextrablanks(s);
val(s,buf.UserTotalUL,e);
readln(f,s);
killextrablanks(s);
val(s,buf.UserTotalDLk,e);
readln(f,s);
killextrablanks(s);
val(s,buf.UserTotalDL,e);
readln(f,s);
killextrablanks(s);
val(s[1],buf.DataBits,e);
buf.parity:=s[2];
val(s[3],buf.StopBits,e);
close(f);
end;
{───────────────────────────────────────────────────────────────────────────}
Function Read_Fake;
begin
end;
{───────────────────────────────────────────────────────────────────────────}
{var
p:pointer; c:byte;
begin
p:= tdorinfox_def(p) absolute{}
end.