home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
fbrow105.zip
/
FBROWSER.MEX
< prev
next >
Wrap
Text File
|
1996-03-05
|
23KB
|
760 lines
//======================== Interface 1.05 ============================
// Program: MEX Filebrowser
//
// Created in 1995 by Jonas Öberg, 2:204/466
// Modified 2 Oct 1995 by Neil Walker, 2:2500/509
//
// Thanks to:
// The author of XGetCh() used by this program
// Werner Schlagnitweit for the mex program f-titles, great program
// although it's a little slow with the 3d stuff.
//
// -=Public Domain=-
// Drastically altered by Jim Woodward 1:268/412, thus renamed
//
// on 12/10/95 I, Jim Woodward, incorporated Herman Freeman's
// viewrar.mex program into fbrowser.mex
//
// on 12/19/95
// Added: S for taglist inspired by: Ole Aggerholm, 2:238/11.0
//
// on 01/23/96 Redefined pageup/down keys to +/- keys, thus
// enabling me to use 'q' for quitting the program.
//
// Check for empty filearea error corrected by: Ole Aggerholm
// on 02/29/96 fbrowser will now skip blank lines in files.bbs
// on 03/02/96 added support for TTY users
// on 03/05/96 lines with something in first column and a blank (space)
// in the 2nd column will be treated as comment lines.
//
#include <\max\m\max.mh>
#include <\max\m\max_menu.mh>
#include <\max\m\prm.mh>
#include <\max\m\xgetch.mh>
//below added by jaw from viewrar.mex
#define ARCH_SIGN "\x52\x61\x72\x21\x1a\x07"
#define ARCH_WHICH "Display the contents of which archive? "
#define ARCH_TITLE " Name Size Packed Date Time"
#define ARCH_LINE "-------------------------------------------------"
unsigned int: HeadCRC;
unsigned char: HeadType;
unsigned int: Flags;
unsigned int: HeadSize;
unsigned long: PackSize;
unsigned long: UnpSize;
unsigned char: HostOS;
unsigned long: FileCRC;
unsigned int: FYear;
unsigned int: FMonth;
unsigned int: FDay;
unsigned int: FHour;
unsigned int: FMin;
unsigned int: FSec;
unsigned char: UnpVer;
unsigned char: Method;
unsigned int: NameSize;
unsigned long: FileAttr;
unsigned long: NBPos,nblock;
string: Afname;
// end of viewrar.mex's variables etc
//========================= Global variables =========================
int: page,fhandle;
// Page: The page number we're currently working on
// Fhandle: File handle for files.bbs
long: end; // file variable, end of file
array [1..100] of long: old; //up to 100 pages allowed
array [0..1] of string: descr_colour;
int: act_page; // active page, i.e. page on screen
int: linenumber; // line number
int: file_end; // 0 means reached end of file
int: fd; // file handle
//========================= Page structure ===========================
struct _page
// Lastfile: This integer defines the last file on this page, in most cases
// this should equal to 16, except for the last page
// Filename: Contains the filename, BUT! if filename="", <desc> contains
// a description that is continued from the last file.
// And, if filename=" ", <desc> is a comment.
// Size: Size of the file
// Date: Date of file as a string
// Desc: Description or comment
// Tagged: TRUE if file is tagged and FALSE if not
{
array [1..28] of string: filename;
array [1..28] of long: size;
array [1..28] of string: date;
array [1..28] of string: desc;
array [1..28] of int: tagged;
} ;
struct _page: p;
// Functions
// main function
void do_it();
//
void view_cont(string: filespec); // added by jaw 12/11/95
// from viewrar.mex
void settagged();
// Inserts tagged files in Maximus que.
void printpage();
// Redraws screen
int getpage();
// Reads Page of files
int validfilename(string:s);
// Returns: TRUE if file
string filesbbspath();
// Returns: Path to files.bbs file
// Description: Also checks to see if files.bbs is valid (exists) and
// if not, returns ""
void clearscreen();
// Clear display screen
void clearpage();
// Clear page
int processcommands();
// Processes keystrokes
// Returns 0 if exit, 2 if new screen etc
int readline(int: rpage);
// Reads a line from fhandle and processes it if ok.
// Returns 0 if Ok, 1 if EOF.
int processline();
// Processes one line of text, checks filename etc
//======================== Implementation ===========================
int processline(int: plinenumber,string: line)
// Processes one line of text, checks filename etc
{
int: len,pos, k, fnum;
string: fname,desc,temp;
struct _stamp: date;
if (strlen(line)<3 ) return plinenumber;
k:=stridx(line,1,' ');
if (k=2) return plinenumber;
if (k =0)
{
fname:=line; // Checks for desc.
temp:=line + " No description given to File Browser!";
line:=temp;
}
else fname:=substr(line,1,k-1);
if (strlen(line)>2)
{
if (validfilename(fname)=TRUE)
{
// This is a file!
p.filename[plinenumber]:=fname;
temp:=farea.downpath+fname;
if (fileexists(temp)=TRUE)
{
p.size[plinenumber]:=filesize(temp);
filedate(temp,date);
p.date[plinenumber]:=strpadleft(itostr(date.date.month),2,'0') + "/" + strpadleft(itostr(date.date.day),2,'0') + "/" +strpadleft(itostr(date.date.year+ 80),2,'0');
}
else
{
p.size[plinenumber]:=0; // Missing
}
fnum:=plinenumber; // line# where file name is.
if ((pos:=stridx(line,1,' '))>0)
{
p.desc[plinenumber]:=substr(line,pos+1,strlen(line)-pos+1);
p.desc[plinenumber]:=strtrim(p.desc[plinenumber]," ");
if (strlen(p.desc[plinenumber])<46)
plinenumber:=plinenumber+1;
else // Split line
{
desc:=p.desc[plinenumber];
do
{
pos:=stridx(desc,1,158);
if (pos=0)
{
desc:=strtrim(desc," ");
pos:=1;
if (desc[45]=' ' and desc[44]<>' ') pos:=44;
else
{
pos:=45;
do
{
pos:=pos-1;
} while (pos>1 and desc[pos]<>' ');
if (pos=1) pos:=44;
}
p.desc[plinenumber]:=substr(desc,1,pos);
desc:=substr(desc,pos+1,strlen(desc)-pos);
desc:=strtrim(desc," ");
plinenumber:=plinenumber+1;
}
else
{
p.desc[plinenumber]:=substr(desc,1,pos-1);
desc:=substr(desc,pos+1,strlen(desc)-pos+1);
plinenumber:=plinenumber+1;
}
} while (strlen(desc)>45 and plinenumber<18);
if (strlen(desc)>0 and plinenumber<16)
{
p.desc[plinenumber]:=desc;
plinenumber:=plinenumber+1;
}
}
}
}
else // This is a ?
{
p.filename[plinenumber]:=fname;
p.desc[plinenumber]:="File no longer in this directory!";
plinenumber:=plinenumber+1;
}
if (plinenumber>17) p.filename[fnum]:="";
}
return plinenumber;
}
int getpage(int: rpage) // a blank line within files.bbs
{ // will cause display to stop there
int: result,i;
string: line, line2,line3;
long: first, tmp1,tmp2;
if (rpage=2 and file_end=0) // already on last page
{
return 0;
}
if (act_page=1 and rpage=0) // already at the first file
{
return 0;
}
settagged();
linenumber:=1;
clearscreen();
clearpage();
fhandle:=open(filesbbspath(), IOPEN_READ);
if (rpage = 2 )
{
act_page:=act_page+1;
seek(fhandle,end,SEEK_SET);
old[act_page]:=tell(fhandle);
}
else if (rpage=1 or rpage=3)
{
seek(fhandle,0,SEEK_SET);
act_page:=1;
old[1]:=tell(fhandle);
}
else if (rpage=0)
{
if (act_page>1) act_page:=act_page-1;
seek(fhandle,old[act_page],SEEK_SET);
}
else if (rpage=4)
{
seek(fhandle,old[act_page],SEEK_SET);
}
file_end:=1;
i:=0;
do // Until i >= 16
{
first:=tell(fhandle);
result:=readln(fhandle, line);
while (result<>-1 and strlen(line)=0)
{
result:=readln(fhandle, line);
}
tmp1:=tell(fhandle);
tmp2:=readln(fhandle,line2);
while (line2[1]=' ' and strlen(line2)>0)
{
line3:=strtrim(line2," ");
line:=line+"₧"+line3;
tmp1:=tell(fhandle);
tmp2:=readln(fhandle,line2);
}
{
seek(fhandle,tmp1,SEEK_SET);
}
if (result>0) // EOF?
{
i:=processline(linenumber,line); //i is NOW the next free line
if (i<17)
{
end:=tell(fhandle);
linenumber:=i;
}
else if (i=17)
{
result:=0;
end:=tell(fhandle);
linenumber:=17;
result:=readln(fhandle, line);
if (result<1)
{
file_end:=0;
close(fhandle);
return 1;
}
else seek(fhandle, end, SEEK_SET);
}
else // needed to keep last display to not overlap
{
result:=0;
linenumber:=linenumber-1;
}
}
else // done with this screen
{
file_end:=0;
if (linenumber>16) linenumber:=16;
i:=17;
}
} while(i<17 and result>0);
close(fhandle);
return 1;
}
int processcommands()
// Processes keystrokes
{
int: exit,select,choice,num,posn,flags;
char: tempint;
string: filename;
exit:=FALSE;
tempint:=1;
choice:=1;
if (p.filename[choice]<>"" and p.filename[choice]<>" ") num:=choice;
// Find first file in list.
do
{
// Print filename in Yellow with blue background
print (AVATAR_GOTO, (char)(num+2),(char)1, COL_YELLOWONBLUE, p.filename[num]);
if (p.tagged[num]=TRUE) print(COL_WHITE, " *");
else print (COL_WHITE, " ");
// Get a key
choice:=xgetch();
if (choice=X_UP or choice='8')
// Up
{
print (AVATAR_GOTO, (char)(num+2),(char)1, COL_LGREEN,p.filename[num]);
select:=num;
choice:=0;
do // Find the first file
{
select:=select-1;
if (select=0) return 0;
if (p.filename[select]<>"" and p.filename[select]<>" ")
choice:=select;
}
while (choice=0);
num:=choice;
}
else if (choice=X_DOWN or choice='2')
// Down
{
print (AVATAR_GOTO, (char)(num+2),(char)1, COL_LGREEN,p.filename[num]);
select:=num;
choice:=0;
do // Find the first file
{
select:=select+1;
if (select=17) return 2;
if (p.filename[select]<>"" and p.filename[select]<>" ")
choice:=select;
}
while (choice=0);
num:=choice;
}
else if (choice=27 or choice='q' or choice='Q' or choice='n' or choice='N') exit:=TRUE;
// Escape
else if (choice=32) // Spacebar
if (p.tagged[num]=TRUE) p.tagged[num]:=FALSE;
else p.tagged[num]:=TRUE;
else if (choice='+' or choice='3' or choice=13) // PgDn
{
return 2; // Draw next page
}
else if (choice='-' or choice='9') // PgUp
{
return 0; // Draw previous page
}
else if (choice=X_HOME or choice='7') // Home
{
return 3; // Draw new page
}
else if (choice='U' or choice='u') // Upload
{
print(AVATAR_CLS);
menu_cmd(MNU_FILE_UPLOAD,"");
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempint);
return 4;
}
else if (choice='S' or choice='s') // List tagged files
{
print(AVATAR_CLS);
settagged();
if (tag_queue_size()<>0)
{
// TagList();
menu_cmd(MNU_FILE_TAG,"");
}
else
{
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempint);
print (AVATAR_GOTO, (char)(4),(char)2,COL_WHITE,"Your Tag list is empty!");
getch();
}
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempint);
return 4;
}
else if (choice='V' or choice='v') //
{
print(AVATAR_CLS);
filename:=p.filename[num];
view_cont(filename);
print( COL_LRED, "Tap a key to continue");
getch();
close(fd);
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempint);
return 4;
}
else if (choice='P' or choice='p') // Chng protocol
{
print(AVATAR_CLS);
menu_cmd(MNU_CHG_PROTOCOL,"");
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempint);
return 4;
}
else if (choice='D' or choice='d')
{
print(AVATAR_CLS);
settagged();
if (tag_queue_size()<>0)
{
menu_cmd(MNU_FILE_DOWNLOAD,"");
}
else
{
tag_queue_file(farea.downpath+p.filename[num],0);
menu_cmd(MNU_FILE_DOWNLOAD,"");
}
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempint);
return 4;
}
}
while (exit=FALSE);
return -1;
}
void clearscreen()
// Clear display screen
{
int: count;
print (AVATAR_GOTO, (char)2, (char)1);
for (count:=0;count<16;count:=count+1) print(AVATAR_DOWN AVATAR_CLEOL);
print (AVATAR_GOTO, (char)3, (char)1); // Restore cursor
}
string filesbbspath()
// Returns: Path and filename of files.bbs compatible file
// Description: Also checks to see if files.bbs is valid (exists) and
// if not, returns ""
// *** Modified function *** (Neil Walker 2 Oct 1995)
{
string: temp;
if (farea.filesbbs="") temp:=farea.downpath+"files.bbs";
else temp:=farea.filesbbs;
if (fileexists(temp)=FALSE) temp:="";
return temp;
}
int validfilename(string:s)
// Returns: TRUE if file
{
// if (stridx(s,1,'.')>0) return TRUE; else return FALSE;
return fileexists( farea.downpath+ s);
}
void printpage()
// Redraws screen
{
int: pos,i;
string: colour;
clearscreen();
i:=1;
if (linenumber>16) linenumber:=16;
print (COL_LBLUE,AVATAR_GOTO, (char)1, (char)(38-strlen(farea.descript)/2), "╣ ", COL_LRED, farea.descript, COL_LBLUE, " ╠", AVATAR_GOTO, (char)3, (char)1);
print (COL_LBLUE,AVATAR_GOTO, (char)19, (char)46,COL_LGREEN,strpad(ltostr(timeleft()),4,' ')," ");
print (AVATAR_GOTO, (char)2, (char)61, COL_YELLOW, strpad(itostr(act_page),3,' '),"\n");
for (pos:=1;pos<=linenumber;pos:=pos+1)
{
if (strlen(p.filename[pos])>0)
{
i:=i+1;
colour:=descr_colour[i%2];
}
if (p.filename[pos]=" ") print (COL_GRAY, p.desc[pos]);
else if (p.filename[pos]="") print (colour, AVATAR_GOTO, (char)(pos+2),(char)35,p.desc[pos]);
else
{
print (COL_LGREEN, p.filename[pos],strpad("",13-strlen(p.filename[pos]),' '));
if (p.tagged[pos]=TRUE) print (COL_WHITE,"*");
else print (" ");
if (p.size[pos]>0)
print (COL_YELLOW, strpadleft(ltostr(p.size[pos]),8,' ')," ",
COL_LGREEN, p.date[pos]," ",colour, p.desc[pos]);
else print(COL_YELLOW," <MISSING> ",colour,p.desc[pos]);
}
print("\n");
}
}
void settagged()
// Inserts tagged files in Maximus que.
{
int: pos,i,flgs, ok;
string: tagname,testname;
for (pos:=1;pos<17;pos:=pos+1)
if (p.tagged[pos]=TRUE)
{
ok:=0;
for (i:=0;i<tag_queue_size();i:=i+1)
{
tag_get_name(i, flgs,tagname);
testname:=strupper(farea.downpath+p.filename[pos]);
if (tagname=testname) ok:=1;
}
if (ok=0) tag_queue_file(farea.downpath+p.filename[pos],0);
}
}
void do_it()
{
int: k;
k:=1;
do {
k:=getpage(k);
if (k=1) printpage();
do
{
k:=processcommands();
}
while (k=1);
}
while (k>-1);
settagged(); // for last screen
}
void clearpage() // initializes page variables
{
int: i;
for (i:=1;i<29;i:=i+1)
{
p.filename[i]:="";
p.date[i]:="";
p.desc[i]:="";
p.size[i]:=0;
p.tagged[i]:=FALSE;
}
}
unsigned long hextoul(string: strinp, int: ofst)
{
unsigned long: wlong;
wlong := (unsigned char)strinp[ofst+3];
wlong := (wlong shl 8)+(unsigned char)strinp[ofst+2];
wlong := (wlong shl 8)+(unsigned char)strinp[ofst+1];
return (wlong shl 8)+(unsigned char)strinp[ofst];
}
int hextoi(string: strinp, int: ofst)
{
int: wint;
wint := (int)strinp[ofst+1];
return (wint shl 8) + (int)strinp[ofst];
}
unsigned int hextoui(string: strinp, int: ofst)
{
unsigned int: wint;
wint := (unsigned char)strinp[ofst+1];
return (wint shl 8) + (unsigned char)strinp[ofst];
}
unsigned long get_fblk(int: fh)
{
unsigned long: rc;
string: gtmp;
rc := read(fh,gtmp,31);
HeadType := gtmp[2];
Flags := hextoui(gtmp,3);
HeadSize := hextoui(gtmp,5);
PackSize := hextoul(gtmp,7);
UnpSize := hextoul(gtmp,11);
HostOS := gtmp[15];
FileCRC := hextoul(gtmp,16);
FHour := (hextoui(gtmp,20) shr 11);
if (FHour < 0) FHour := FHour - 65504;
FMin := ((hextoui(gtmp,20) & 0x07e0) shr 5);
FSec := (hextoui(gtmp,20) & 0x002f);
FYear := (hextoui(gtmp,22) shr 9)+80;
FMonth := ((hextoui(gtmp,22) & 0x01e0) shr 5);
FDay := (hextoui(gtmp,22) & 0x001f);
UnpVer := gtmp[24];
Method := gtmp[25];
NameSize := hextoui(gtmp,26);
FileAttr := hextoul(gtmp,28);
NBPos := tell(fh) - rc + HeadSize;
if (Flags & 0x8000) NBPos := NBPos + PackSize;
if (rc = 0 or HeadType <> 0x74)
{
seek(fh,NBPos,SEEK_SET);
}
if (rc > 0 and HeadType = 0x74)
{
read(fh,Afname,NameSize);
seek(fh,NBPos,SEEK_SET);
rc := rc + NameSize;
if (HeadType = 0) return(0);
}
return(rc);
}
unsigned int get_arch(int: fh)
{
int: rc;
string: ftmp;
seek(fh,8,SEEK_SET);
rc := read(fh,ftmp,13);
seek(fh,hextoui(ftmp,5)+8,SEEK_SET);
return hextoui(ftmp,5);
}
void view_cont(string: filespec)
{
int: Afs, I, rc;
long: fsize;
string: tmp;
fd := open(farea.downpath+filespec,IOPEN_READ|IOPEN_BINARY);
if (fd = -1)
{
print(COL_WHITE,"Can't find Archive ",farea.downpath+filespec,"\n");
return;
}
rc := read(fd,tmp,6);
if (tmp <> ARCH_SIGN)
{
close(fd);
input := input + filespec ;
menu_cmd(MNU_FILE_CONTENTS,"");
return;
}
fsize := filesize(farea.downpath+filespec);
print("\n");
print("Contents of Archive ",filespec,"\n\n");
print(ARCH_TITLE,"\n");
print(ARCH_LINE,"\n");
nblock := get_arch(fd); // position to read first file block
if (nblock = 0)
{
print ("exit");
return;
}
while(get_fblk(fd) > 0)
{
if (nblock >= fsize) return;
if (HeadType = 0x74)
{
Afs := 0;
for ( I := 1 ; I <> strlen(Afname) ; I := I + 1 )
{
if (substr(Afname,I,1) = "\\" or substr(Afname,I,1) = "/") Afs := I;
}
Afname := substr(Afname,Afs+1,strlen(Afname)-Afs+1);
print(strpad(Afname,13,' '),strpadleft(ultostr(UnpSize),12,' '));
print(strpadleft(ultostr(PackSize),9,' ')," ");
print(FYear,"/",strpadleft(ultostr(FMonth),2,'0'),"/");
print(strpadleft(ultostr(FDay),2,'0')," ");
print(strpadleft(ultostr(FHour),2,'0'),":");
print(strpadleft(ultostr(FMin),2,'0'));
print("\n");
}
}
close(fd);
print("\n");
}
int main()
{
int: count;
char: tempchar;
if (filesbbspath()="") // Too bad, files.bbs isn't there!
{
print ("Files.bbs doesn't exist!");
return 1;
}
if (usr.video< (char) 1)
{
menu_cmd(MNU_FILE_TITLES,"");
return 0;
}
if (filesize(filesbbspath()) < 10) // files.bbs is les than 10 bytes
{ // so it is probably empty
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempchar);
print (AVATAR_GOTO, (char)(4),(char)2,COL_WHITE,"This filearea is empty!");
getch();
return 1;
}
descr_colour[0]:=COL_WHITE;
descr_colour[1]:=COL_LCYAN;
// Opens Files.BBS for reading, filehandle fhandle.
print (COL_WHITE,"Reading Files.BBS...");
display_file(prm_string(PRM_MISCPATH)+"fbrowser.bbs",tempchar);
do_it();
print(AVATAR_CLS); // CLS on exit
return 0;
}