Updated to 2.22 and now Freeware! Four year date formats for birth dates

This commit is contained in:
larrystockman 2019-09-22 21:43:03 -05:00
parent ccaec1e634
commit d5afd506b8
492 changed files with 36511 additions and 0 deletions

BIN
ADF.EXE Normal file

Binary file not shown.

28
AKA.CPP Normal file
View File

@ -0,0 +1,28 @@
#include <string.h>
#include "proboard.hpp"
int
aka::read(int n)
{
File f(FileName(syspath,"AKA.PRO"));
if(!f.opened())
{
CLEAR_OBJECT(*this);
return -1;
}
CLEAR_OBJECT(*this);
f.seek(long(n)*sizeof(aka));
if(f.read(this,sizeof(aka)) != sizeof(aka))
{
CLEAR_OBJECT(*this);
return -1;
}
return 0;
}

BIN
AKA.OBJ Normal file

Binary file not shown.

71
BINLOG.CPP Normal file
View File

@ -0,0 +1,71 @@
#include "proboard.hpp"
#include <string.h>
const int BINLOG_BUF = 10;
bool
BinLog::append()
{
File f(FN_BINLOG_PB,fmode_rw | fmode_copen | fmode_denywr);
if(!f.opened()) return FALSE;
if(f.len() >= sizeof(BinLog))
{
Date today(TODAY);
BinLog *log = new BinLog[ BINLOG_BUF ];
f.seek(0);
f.read(log,sizeof(BinLog));
if(cfg.binlogdays && (today - log->date) > cfg.binlogdays)
{
f.seek(0);
for(long rec = 0;;rec++)
{
if(f.read(log,sizeof(BinLog)) != sizeof(BinLog)) break;
if((today - log->date) <= cfg.binlogdays)
{
long dest_rec = 0;
for(;;)
{
f.seek(rec * sizeof(BinLog));
word n = f.read(log,sizeof(BinLog) * BINLOG_BUF);
if(n < sizeof(BinLog)) break;
n /= sizeof(BinLog);
f.seek(dest_rec * sizeof(BinLog));
f.write(log,n * sizeof(BinLog));
dest_rec += n;
rec += n;
}
f.seek(dest_rec * sizeof(BinLog));
f.cut();
break;
}
}
}
delete [] log;
}
f.seek(f.len() / sizeof(BinLog) * sizeof(BinLog));
f.write(this,sizeof(*this));
return TRUE;
}
BinLog::BinLog()
{
memset(this,0,sizeof(*this));
}

BIN
BINLOG.OBJ Normal file

Binary file not shown.

44
BULLETIN.CPP Normal file
View File

@ -0,0 +1,44 @@
#include <string.h>
#include "proboard.hpp"
void
bulletin(char *data)
{
char fname[9];
for(int i=0;data[i]==' ';i++) {}
char *s = &data[i];
for(;data[i] && data[i]!=' ';i++) {}
data[i] = '\0';
String prompt;
for(i++;data[i]==' ';i++) {}
if(data[i])
prompt = &data[i];
else
prompt = S_ENTER_BULLETIN;
for(;;)
{
strcpy(fname,s);
io << '\n';
showansasc(fname);
io << "\n\7" << prompt;
io.read(&fname[strlen(fname)],8-strlen(fname),READMODE_UPALL);
if(strlen(fname) <= strlen(s)) break;
if(showansasc(fname,NULL) == ANS_NOFILE)
io << "\n\n" << S_FILE_NOT_FOUND << ' ' << S_PRESS_ENTER_TO_CONTINUE;
else
io << '\n' << S_PRESS_ENTER_TO_CONTINUE;
}
}

BIN
BULLETIN.OBJ Normal file

Binary file not shown.

122
CDROM.CPP Normal file
View File

@ -0,0 +1,122 @@
#define Use_LinkedList
#include <dir.h>
#include <ctype.h>
#include <dos.h>
#include <stdlib.h>
#include "proboard.hpp"
const word copy_bufsize = 16384;
bool
copy_file( char *s , char *d )
{
File fi,fo;
if(!fi.open(s , fmode_read)) return FALSE;
if(dos_getdiskfreespace(toupper(d[0])-'A'+1) < (fi.len() + copy_bufsize))
return FALSE;
if(!fo.open(d , fmode_create)) return FALSE;
byte *buf = new byte[ copy_bufsize ];
for(;;)
{
word copied = fi.read( buf, copy_bufsize );
if(!copied) break;
fo.write( buf , copied);
if(copied != copy_bufsize) break;
}
delete [] buf;
return TRUE;
}
void
copy_cdrom( LinkedList<DownloadFile> &files , LinkedList<String> &copied)
{
FileName copydir;
while(copied.count())
{
copied.rewind();
copied.remove();
}
if(getenv("CDTEMP") != NULL)
{
copydir = getenv("CDTEMP");
if(copydir[1] != ':')
{
LOG("Invalid path specified in CDTEMP!");
return;
}
copydir.upperCase();
}
else
{
copydir = String(mypath) + "CD_TEMP";
}
copydir.delLast('\\');
if(copydir.len() > 2)
mkdir(copydir);
copydir.appendBS();
for( files.rewind() ; !files.eol() ; files++)
{
if(files.get().copy)
{
FileName source,dest;
source = files.get().name;
source.stripPath();
int len = language_string_length(S_COPYING_FROM_CDROM((char *)source));
io << S_COPYING_FROM_CDROM((char *)source) << '\xFF';
dest = copydir + source;
source = files.get().name;
if(!copy_file( source , dest ))
{
LOG( "Error copying %s to %s" , (char *)source , (char *)dest);
io << S_ERROR_COPYING_FROM_CDROM << '\n';
}
else
{
files.get().name = dest;
copied.add(String(dest));
io << String('\b',len) << String(' ',len) << String('\b',len);
}
}
}
}
void
delete_copied(LinkedList<String> &copied)
{
for( copied.rewind() ; !copied.eol() ; copied++)
{
unlink(copied.get());
}
while(copied.count())
{
copied.rewind();
copied.remove();
}
}

BIN
CDROM.OBJ Normal file

Binary file not shown.

118
CHANGES.TXT Normal file
View File

@ -0,0 +1,118 @@
ProBoard v2.20.00
-----------------
* ProBoard now has a new registration scheme. It no longer uses the
REGKEY.PB file to store your registration information. Now, your
registration information is burned into the PROBOARD.EXE file itself.
I know there are going to be a lot of people out there who won't like
this change in the slightest, but it's really for new customers of
ProBoard. With ProBoard v2.2, new customers don't automatically get
an unlimited node license when they buy a copy. They purchase the
number of nodes they want to run. The key is the serial number and
the activation code which is used to unlock the software. This
information tells ProBoard how many nodes it will allow. Now, for all
those people who already own existing copies of ProBoard, you will
automatically be upgraded to an unlimited node license as part of your
upgrade.
How do I upgrade to v2.2, and get it registered? It's a four-step
process.
Step 1: Download ProBoard v2.2 (which you've already done, or you
wouldn't be seeing this file).
Step 2: Run the program included with ProBoard 2.2 called REGINFO.EXE.
This will read your REGKEY.PB file, and extract out the old
registration information. It will then display an eight-digit
code on the screen which is your Upgrade-ID code. This code
will be crucial in the next step.
Step 3: Visit the TeleGrafix Web site at http://www.telegrafix.com,
and purchase your upgrade. While you're filling out the
upgrade form, you'll be asked for your Upgrade-ID code, the
name of the SysOp and the BBS name as they appear in ProCFG.
The Web site will compare this information against the data
encoded in your Upgrade-ID code, and if they match, you'll
automatically be given your new registration information.
NOTE: A single BBS can only be upgraded once, to prevent pirates
from stealing your registration information!
Step 4: Run the REGISTER.EXE program, and key-in the newly assigned
serial number and activation code.
That's all there is to it. You're ready to go online with a fully
functioning ProBoard system.
* New look and feel for the main console.
* Fixed a minor centering problem in the "last caller" field.
* Added a new option to the status bar (ALT-J) to "Jump to DOS". This
option was already available in the software, but it wasn't documented
on the main console screen.
* Added five new functions to the ProBoard PEX SDK:
fileno()
getcurdir()
getdisk()
_dos_getftime()
_dos_setftime()
* Changed message 361 in the language files to make room for the expanded
year string.
* Updated ProCFG.EXE to properly handle four-byte year data entry. The
expiration date can be set to "00/00/0000" to indicate no expiration
date.
* The new user signup now allows you to select from the updated date
formats:
MM/DD/YYYY
YYYY/MM/DD
DD/MM/YYYY
* The new user signup now forces you to enter four-digit years when asked
to enter your date of birth.
* The file system now forces you to enter four-digit years when entering a
date to search for files by.
* Fixed a potentially serious bug with the birthdate asking code. There
were circumstances when it might generate a garbled birthdate.
* Added a new macro code to ".A?? File Control Codes". The new code is
"^F;" (i.e., 06-59). This code displays the user's password, or if the
"Hide Password" option is enabled in ProCFG, then this option will display
the password hiding character as defined in ProCFG.
* The default SETUP.* menu files have been changed to use the new "^F;"
macro code instead of "^FC" for the password display to properly support
the Hide Password option.
* Changed the look and feel of the SysOp functions F1 and Shift-F1 to be
more consistent with the main console appearance.
* Changed the color of the status line displayed on the main console when
a user is logged in. The new color is more like the main console.
* Changed the entire look and feel of ProCFG to be more similar to the BBS
main console.
* Fixed a bug with ProCFG where if you make changes to the system
configuration data, the inappropriate action was taken when you chose to
save or cancel the changes when you exit. I don't know if this was
present in the release version of v2.16, but in the code obtained from
the author, the exact opposite operation was performed. If you decided
to abandon the changes, they got saved instead, and vice-versa.
* Updated the PB_SDK header, and the library. Several of the data
structures in PB_SDK.H have been updated to be accurate with regard to
ProBoard v2.2 compatibility. The .LIB file has also been rebuilt to
be v2.2 compliant.
----------------------------------------------------------------------------
# # #
----------------------------------------------------------------------------

204
CHAT.CPP Normal file
View File

@ -0,0 +1,204 @@
#include <string.h>
#include <tswin.hpp>
#include "proboard.hpp"
static int near ring_bell(char *);
static void
ask_leave_message(char *subj)
{
io << "\n\n" << S_LEAVE_MESSAGE_TO_SYSOP;
if(io.ask())
{
io << "\n\xFF";
if(cfg.pageArea == 0)
cfg.pageArea = cfg.securityboard;
writemsg(form("%d /T=Sysop /S=\"%s\"",cfg.pageArea,subj));
LOG(1,"Wrote a message to the sysop");
}
}
void
pagesysop(char *data)
{
if(num_yells>=cfg.max_sysop_pages) // Paged too many times?
{
LOG(1,"Trying to page too many times");
if(showansascrip("MAXPAGE")==ANS_NOFILE) // Show ANS-file if available
{
io << '\n' << S_PAGED_TOO_MANY_TIMES << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
ask_leave_message("");
}
return; // You're out of luck mate
}
if(!cfg.pagingHours.enabled()) // Outside paging hours?
{
LOG(1,"Trying to page outside hours");
if(showansascrip("NOTAVAIL")==ANS_NOFILE)
{
io << '\n'
<< S_PAGING_NOT_ALLOWED_RIGHT_NOW
<< S_PRESS_ENTER_TO_CONTINUE;
ask_leave_message("");
}
return;
}
char reason[56];
io << '\n' << S_ASK_CHAT_REASON;
io.read(reason,55);
strip_all(reason);
if(strlen(reason)<5)
{
io << "\n\n" << S_CHAT_REASON_TOO_SHORT("5")
<< "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return; // Must be 5 chars!
}
LOG(1,"Sysop paged: %s",reason);
num_yells++; // Increment yell-count
io << "\n\n" << data << char(0xFF); // Show "Yelling..."
if(!ring_bell(reason)) // Did sysop react?
{
io << "\n\n\xFF"; // No, inform user
if(showansascrip("PAGED")==ANS_NOFILE)
{
io << S_SYSOP_NOT_RESPONDING << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
}
strcpy(page_reason,reason);
ask_leave_message(reason);
return;
}
LOG(1,"Chat started"); // yell-count
io << "\n\xFF";
chat(); // Start chat
}
void
chat()
{
if(chatflag) return; // Are we chatting already?
rip_reset();
chatflag=1; // We're chatting!
num_yells=0; // Allow yelling again
timer.suspend(); // Suspend timer
user_online uo;
uo.setstatus(UO_CHATTING); // Inform other users
if(cfg.extChat[0] && (user.uFlags & (UFLAG_ANSI|UFLAG_AVATAR)))
{
if(cfg.extChat[0] == '@')
run_sdkfile(replace_stringvars(&cfg.extChat[1]));
else
shell(replace_stringvars(cfg.extChat));
}
else
{
io << '\n' << S_SYSOP_CHAT_START << "\n\n\xFF";
int last=2; // Force color change!
String s,wrap;
for(;;)
{
byte k=io.wait();
if(k==27)
if(io.external)
continue; // Local escape pressed?
else
break; // Yep, exit
if(k=='\t') k=' '; // I don't like TABS
if(io.external!=last && (ansi_mode||avatar)) // Change color?
{
if(io.external)
io << (avatar?"\x16\x01\x07\xFF":"\xFF");
else
io << (avatar?"\x16\x01\x0B\xFF":"\xFF");
last = io.external; // Prevent color change
}
if(k != 8)
io << k << char(0xFF); // Show char
switch(k)
{
case 8:
if(s.len()>0) // Backspace pressed
{
s[s.len()-1]=0;
io << "\b \b\xFF";
}
break;
case 13:
io << "\n\xFF";
s = ""; // Enter pressed
break;
default:
s << (char)k; // Any other key
}
if(s.len()>78) // Wordwrap needed??
{
int l = wordwrap(s,wrap,78); // Yep, do it!
for(int i=0;i<l;i++) io << "\b \b\xFF"; // Delete last word
s = wrap;
io << '\n' << s << char(0xFF); // Go to next line
}
}
io << '\n' << S_SYSOP_CHAT_ENDED << "\n\xFF";
}
LOG(1,"End of chat");
timer.restart(); // Restart timer
uo.setstatus(UO_BROWSING); // User status normal again
chatflag=0; // No more chatting
}
static int near
ring_bell(char *reason)
{
Window w(11,10,70,16,0x1E,SHADOW|EXPLODE);
w.open();
tsw_centerline(12,"Chat request. Press [C] to chat , or [A] to abort");
tsw_centerline(14,reason,0x9f);
char c = playsong("PAGE","CA\x1b",cfg.pagebell_length); // Play nice song
return (c == 'C') ? 1 : 0;
}

BIN
CHAT.OBJ Normal file

Binary file not shown.

122
CLEANUP.CPP Normal file
View File

@ -0,0 +1,122 @@
#define Use_LinkedList
#define Use_Handlers
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <tswin.hpp>
#include "proboard.hpp"
void
exit_proboard(int level)
{
if(sysop_next)
{
playsong("SYSOPNXT","\x1b",0);
File f;
f.open(FileName(syspath,"SYSOPNXT.SEM"),fmode_write|fmode_create);
f.close();
}
tsw_cursoron();
SCREEN.enableCursor();
if(level)
exit(level);
if( net_entered && echo_entered ) exit(5);
if( net_entered ) exit(3);
if( echo_entered ) exit(4);
exit(0);
}
void
nomemory()
{
fatalerror("OUT OF MEMORY!!");
}
extern "C" void
cleanup()
{
io.hangup();
if(!fatal)
{
for( hangup_handlers.rewind() ; !hangup_handlers.eol() ; hangup_handlers++)
{
CallPEX( &hangup_handlers.get() );
}
}
SCREEN.clear();
tsw_cursoroff();
Window w(tsw_hsize/2 - 14 , tsw_vsize/2 - 1 , tsw_hsize/2 + 16 , tsw_vsize/2 + 1 , 0x70 , 0);
w.open();
tsw_centerline(tsw_vsize/2,"UPDATING DATA FILES",0x70);
if(!fatal && user_recnr>=0)
{
timelog tl;
tl.update();
user_online uo;
uo.clear();
user.lastDate = login_date;
user.lastTime = login_time;
user.timeUsed += timer.used();
user.totalTimeUsed += timer.online();
user.timesCalled++;
if(newFilesChecked)
user.lastNewFilesCheck = user.lastDate;
user.write(FALSE);
BinLog bl;
strcpy( bl.name , user.name );
strcpy( bl.alias , user.alias );
strcpy( bl.city , user.city );
strcpy( bl.country , user.country );
bl.timeOut.now();
bl.date = login_date;
bl.timeIn = login_time;
bl.baud = io.baud;
bl.node = node_number;
bl.kbDown = 0;
bl.kbUp = 0;
bl.yells = num_yells;
bl.uflags = user.uFlags;
if(io.baud || cfg.binloglocal) bl.append();
write_taglist();
}
if(!quiet && io.baud>0 && !fatal)
{
tsw_beep(1500,50);
msleep(50);
tsw_beep(1000,50);
}
w.close();
tsw_cursoron();
SCREEN.change(1,1,tsw_hsize,tsw_vsize);
SCREEN.attrib(7);
SCREEN.clear();
setvideomode(org_videomode);
if(org_numlines>=43 && org_videomode==3) set43();
}

BIN
CLEANUP.OBJ Normal file

Binary file not shown.

92
CLINES.BTM Normal file
View File

@ -0,0 +1,92 @@
setlocal
set total=0
set sizetotal=0
echo ----------------------------------------------------------------
echo SOURCE FILE SIZE REPORT FOR %_DATE , %_TIME
echo.
echos PROBOARD.EXE...
cd \cpp\pb\proboard
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp *.asm) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echos PROCFG.EXE.....
cd \cpp\pb\procfg
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echos PBUTIL.EXE.....
cd \cpp\pb\pbutil
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echos PBLIB.LIB......
cd \cpp\pb\lib
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echos CONVERT.EXE....
cd \cpp\pb\convert
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echos TSLIB.LIB......
cd \cpp\lib\tslib
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp *.asm) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echos TSWIN.LIB......
cd \cpp\lib\tswin
set subtotal=0
set sizesubtotal=0
for %a in (*.cpp *.hpp *.asm) do (
set subtotal=%@eval[%subtotal+%@lines[%a]+1]
set sizesubtotal=%@eval[%sizesubtotal+%@filesize[%a,b]]
)
echo %@substr[ ,0,%@eval[6-%@len[%subtotal]]] %subtotal (%@substr[ ,0,%@eval[4-%@len[%@int[%@eval[%sizesubtotal/1024]]]]]%@int[%@eval[%sizesubtotal/1024]]k)
set total=%@eval[%total+%subtotal]
set sizetotal=%@eval[%sizetotal+%sizesubtotal]
echo.
echo TOTAL LINES..... %total
echo TOTAL SIZE...... %@int[%@eval[%sizetotal/1024]] Kb
endlocal

138
COMBINED.CPP Normal file
View File

@ -0,0 +1,138 @@
#define Use_MsgBase
#include <string.h>
#include <stdlib.h>
#include "proboard.hpp"
void
combined_select(char *data)
{
MsgArea ma;
bool mailcheck = FALSE;
if(String(data) == "/M") mailcheck = TRUE;
for(;;)
{
io << "\f\n\7";
if(mailcheck)
{
io << S_SELECT_AREAS_TO_SCAN_TITLE << "\n\n";
}
else
{
io << S_SELECT_COMBINED_AREAS_TITLE << "\n\n";
}
linecounter(4);
io.enablestop();
for(int i=1,count=0;i<=MsgArea::highAreaNum() && i<=1000;i++)
{
String checked = ' ';
if(!ma.read(i))
continue;
if(!check_access(ma.readLevel,ma.readFlags,ma.readFlagsNot) && !ma.sysopAccess())
continue;
if(mailcheck)
{
if(user.mailCheckBoards.connected(i))
checked = 'û';
}
else
{
if(user.combinedBoards.connected(i))
checked = 'û';
}
io << form(" \3%3d. \2%s \6%-30.30s ",i,(char *)checked,ma.name);
if(stopped) break;
if(!((++count)%2))
{
io << '\n';
if(linecounter()) break;
}
}
if(count%2) io << '\n';
io << '\n' << S_SELECT_AREAS_TO_TOGGLE;
char s[41];
io.read(s,40);
if(!s[0]) break;
char *ptr = strtok(s," ,");
while(ptr)
{
int area = atoi(ptr);
if(area>=1 && area<=1000)
{
if(mailcheck)
{
user.mailCheckBoards.toggle(area);
LOG(3,"Area #%d toggled for mailcheck",area);
}
else
{
user.combinedBoards.toggle(area);
LOG(3,"Combined area #%d toggled",area);
}
}
ptr = strtok(NULL," ,");
}
}
}
void
combined_clear(char *data)
{
int i;
bool mailcheck = FALSE;
if(String(data) == "/M") mailcheck = TRUE;
io << '\n' << S_ENABLE_OR_DISABLE_ALL_AREAS;
switch(wait_language_hotkeys(K_ENABLE_OR_DISABLE_ALL_AREAS))
{
case 1:
{
for(i=1;i<=1000;i++)
{
if(mailcheck)
user.mailCheckBoards.disconnect(i);
else
user.combinedBoards.disconnect(i);
}
io << S_ALL_AREAS_DISABLED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
}
break;
case 0:
{
for(i=1;i<=1000;i++)
{
if(mailcheck)
user.mailCheckBoards.connect(i);
else
user.combinedBoards.connect(i);
}
io << S_ALL_AREAS_ENABLED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
}
break;
}
}

BIN
COMBINED.OBJ Normal file

Binary file not shown.

BIN
Copyright Files.doc Normal file

Binary file not shown.

339
DECKEY.CPP Normal file
View File

@ -0,0 +1,339 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <tslib.hpp>
static byte *inbuf;
static byte *outbuf;
static int inputsize,outputsize;
static int input_ptr;
static int output_ptr;
#define N 4096 /* buffer size */
#define F 60 /* lookahead buffer size */
#define THRESHOLD 2
#define NIL N /* leaf of tree */
static byte *text_buf;
/* Huffman coding */
#define N_CHAR (256 - THRESHOLD + F)
/* kinds of characters (character code = 0..N_CHAR-1) */
#define T (N_CHAR * 2 - 1) /* size of table */
#define R (T - 1) /* position of root */
#define MAX_FREQ 0x8000 /* updates tree when the */
/* table for encoding and decoding the upper 6 bits of position */
/* for decoding */
static byte d_code[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
};
static byte d_len[256] = {
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
};
static word freq[T + 1]; /* frequency table */
static int prnt[T + N_CHAR]; /* pointers to parent nodes, except for the */
/* elements [T..T + N_CHAR - 1] which are used to get */
/* the positions of leaves corresponding to the codes. */
static int son[T]; /* pointers to child nodes (son[], son[] + 1) */
static word getbuf;
static byte getlen;
static int GetBit(void) /* get one bit */
{
word i;
while (getlen <= 8) {
if(input_ptr >= inputsize)
{
i = 0;
}
else
{
i = inbuf[input_ptr++];
}
getbuf |= i << (8 - getlen);
getlen += 8;
}
i = getbuf;
getbuf <<= 1;
getlen--;
return (int)((i & 0x8000) >> 15);
}
static int GetByte(void) /* get one byte */
{
word i;
while (getlen <= 8) {
if(input_ptr >= inputsize)
{
i = 0;
}
else
{
i = inbuf[input_ptr++];
}
getbuf |= i << (8 - getlen);
getlen += 8;
}
i = getbuf;
getbuf <<= 8;
getlen -= 8;
return (int)((i & 0xff00) >> 8);
}
/* initialization of tree */
static void StartHuff(void)
{
int i, j;
for (i = 0; i < N_CHAR; i++) {
freq[i] = 1;
son[i] = i + T;
prnt[i + T] = i;
}
i = 0; j = N_CHAR;
while (j <= R) {
freq[j] = freq[i] + freq[i + 1];
son[j] = i;
prnt[i] = prnt[i + 1] = j;
i += 2; j++;
}
freq[T] = 0xffff;
prnt[R] = 0;
}
/* reconstruction of tree */
static void reconst(void)
{
int i, j, k;
word f, l;
/* collect leaf nodes in the first half of the table */
/* and replace the freq by (freq + 1) / 2. */
j = 0;
for (i = 0; i < T; i++) {
if (son[i] >= T) {
freq[j] = (freq[i] + 1) / 2;
son[j] = son[i];
j++;
}
}
/* begin constructing tree by connecting sons */
for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
k = i + 1;
f = freq[j] = freq[i] + freq[k];
for (k = j - 1; f < freq[k]; k--);
k++;
l = (j - k) * 2;
memmove(&freq[k + 1], &freq[k], l);
freq[k] = f;
memmove(&son[k + 1], &son[k], l);
son[k] = i;
}
/* connect prnt */
for (i = 0; i < T; i++) {
if ((k = son[i]) >= T) {
prnt[k] = i;
} else {
prnt[k] = prnt[k + 1] = i;
}
}
}
/* increment frequency of given code by one, and update tree */
static void update(int c)
{
int i, j, k, l;
if (freq[R] == MAX_FREQ) {
reconst();
}
c = prnt[c + T];
do {
k = ++freq[c];
/* if the order is disturbed, exchange nodes */
if ((word)k > freq[l = c + 1]) {
while ((word)k > freq[++l]);
l--;
freq[c] = freq[l];
freq[l] = k;
i = son[c];
prnt[i] = l;
if (i < T) prnt[i + 1] = l;
j = son[l];
son[l] = i;
prnt[j] = c;
if (j < T) prnt[j + 1] = c;
son[c] = j;
c = l;
}
} while ((c = prnt[c]) != 0); /* repeat up to root */
}
static int DecodeChar(void)
{
word c;
c = son[R];
/* travel from root to leaf, */
/* choosing the smaller child node (son[]) if the read bit is 0, */
/* the bigger (son[]+1} if 1 */
while (c < T) {
c += GetBit();
c = son[c];
}
c -= T;
update(c);
return (int)c;
}
static int DecodePosition(void)
{
word i, j, c;
/* recover upper 6 bits from table */
i = GetByte();
c = (word)d_code[i] << 6;
j = d_len[i];
/* read lower 6 bits verbatim */
j -= 2;
while (j--) {
i = (i << 1) + GetBit();
}
return (int)(c | (i & 0x3f));
}
static void Decode(void) /* recover */
{
int i, j, k, r, c;
int count;
StartHuff();
for (i = 0; i < N - F; i++)
text_buf[i] = 0x20;
r = N - F;
for (count = 0; count < outputsize; ) {
c = DecodeChar();
if (c < 256) {
outbuf[output_ptr++] = c;
text_buf[r++] = (byte)c;
r &= (N - 1);
count++;
} else {
i = (r - DecodePosition() - 1) & (N - 1);
j = c - 255 + THRESHOLD;
for (k = 0; k < j; k++) {
c = text_buf[(i + k) & (N - 1)];
outbuf[output_ptr++] = c;
text_buf[r++] = (byte)c;
r &= (N - 1);
count++;
}
}
}
}
void
decompress_data(byte *input,byte *output,int insize,int outsize)
{
text_buf = new byte[N + F - 1];
inputsize = insize;
outputsize = outsize;
inbuf = input;
outbuf = output;
input_ptr = 0;
output_ptr = 0;
getbuf = 0;
getlen = 0;
Decode();
delete [] text_buf;
}

BIN
DECKEY.OBJ Normal file

Binary file not shown.

50
DESQVIEW.ASM Normal file
View File

@ -0,0 +1,50 @@
% MODEL MEM_MOD
public _DV_timeslice
public _DV_start_critical
public _DV_end_critical
extrn _desqview : WORD
CODESEG
PROC API near
push ax
cmp [_desqview],0
je no
mov ax,101Ah
int 15h
mov ax,bx
int 15h
mov ax,1025h
int 15h
jmp short end_api
no:
mov ax,1680h
int 2fh
end_api:
pop ax
ret
ENDP API
PROC _DV_timeslice
mov bx,1000h
call API
ret
ENDP _DV_timeslice
PROC _DV_start_critical
mov bx,101Bh
call API
ret
ENDP _DV_start_critical
PROC _DV_end_critical
mov bx,101Bh
call API
ret
ENDP _DV_end_critical
END

6
DESQVIEW.HPP Normal file
View File

@ -0,0 +1,6 @@
extern "C"
{
void DV_timeslice();
void DV_start_critical();
void DV_end_critical();
}

96
DESQVIEW.LST Normal file
View File

@ -0,0 +1,96 @@
Turbo Assembler Version 3.1 05/19/99 18:58:12 Page 1
desqview.asm
1
2 % MODEL MEM_MOD
1 3 0000 MODEL LARGE
4
5 public _DV_timeslice
6 public _DV_start_critical
7 public _DV_end_critical
8
9 extrn _desqview : WORD
10
11 0000 CODESEG
12
13 0000 PROC API near
14 0000 50 push ax
15 0001 83 3E 0000e 00 cmp [_desqview],0
16 0006 74 10 je no
17 0008 B8 101A mov ax,101Ah
18 000B CD 15 int 15h
19 000D 8B C3 mov ax,bx
20 000F CD 15 int 15h
21 0011 B8 1025 mov ax,1025h
22 0014 CD 15 int 15h
23 0016 EB 05 jmp short end_api
24 0018 no:
25 0018 B8 1680 mov ax,1680h
26 001B CD 2F int 2fh
27 001D end_api:
28 001D 58 pop ax
29 001E C3 ret
30 001F ENDP API
31
32 001F PROC _DV_timeslice
33 001F BB 1000 mov bx,1000h
34 0022 E8 FFDB call API
35 0025 CB ret
36 0026 ENDP _DV_timeslice
37
38 0026 PROC _DV_start_critical
39 0026 BB 101B mov bx,101Bh
40 0029 E8 FFD4 call API
41 002C CB ret
42 002D ENDP _DV_start_critical
43
44 002D PROC _DV_end_critical
45 002D BB 101B mov bx,101Bh
46 0030 E8 FFCD call API
47 0033 CB ret
48 0034 ENDP _DV_end_critical
49
50 END
Turbo Assembler Version 3.1 05/19/99 18:58:12 Page 2
Symbol Table
Symbol Name Type Value
??DATE Text "05/19/99"
??FILENAME Text "desqview"
??TIME Text "18:58:12"
??VERSION Number 030A
@32BIT Text 0
@CODE Text DESQVIEW_TEXT
@CODESIZE Text 1
@CPU Text 0101H
@CURSEG Text DESQVIEW_TEXT
@DATA Text DGROUP
@DATASIZE Text 1
@FILENAME Text DESQVIEW
@INTERFACE Text 00H
@MODEL Text 5
@STACK Text DGROUP
@WORDSIZE Text 2
API (API) Near DESQVIEW_TEXT:0000
END_API Near DESQVIEW_TEXT:001D
MEM_MOD Text LARGE
NO Near DESQVIEW_TEXT:0018
_DESQVIEW (_desqview) Word ----:---- Extern
_DV_END_CRITICAL + Far DESQVIEW_TEXT:002D
(_DV_end_critical)
_DV_START_CRITICAL + Far DESQVIEW_TEXT:0026
(_DV_start_critical)
_DV_TIMESLICE (_DV_timeslice) Far DESQVIEW_TEXT:001F
Groups & Segments Bit Size Align Combine Class
DESQVIEW_TEXT 16 0034 Word Public CODE
DGROUP Group
_DATA 16 0000 Word Public DATA

BIN
DESQVIEW.OBJ Normal file

Binary file not shown.

759
DL.CPP Normal file
View File

@ -0,0 +1,759 @@
#define Use_TagList
#define Use_LinkedList
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include "proboard.hpp"
struct InputFile
{
int area;
String name;
InputFile();
InputFile(char *s);
InputFile(char *s , int area);
};
const int MAX_DOWNLOADS = 100;
void create_dirlist(int area,char *firstdir,LinkedList<String>& dirlist);
bool is_freefile(char *fname);
bool send_files( protocol& p , LinkedList<DownloadFile>& files ,LinkedList<String>& downloads , LinkedList<String>& uploads);
void read_personal_files( LinkedList<InputFile>& files );
void delete_personal_file( char *name );
void copy_cdrom( LinkedList<DownloadFile> &files , LinkedList<String> &copied);
void delete_copied ( LinkedList<String> &copied);
void process_uploads(protocol& p , char *dir , LinkedList<String>& uploads , bool pvt , bool ask_desc , bool no_log , bool quiet_dl , String extra_log );
bool check_dszlog(protocol& p , LinkedList<String>& downloads , LinkedList<String>& uploads);
bool create_dszctl(protocol& p , LinkedList<DownloadFile>& files);
static void
read_from_file(LinkedList<InputFile>& input_files , char *fn)
{
TextFile f(fn);
if(f.opened())
{
while(!f.eof())
{
String s = f.readLine();
s.delLast('\n');
s.trim();
if(!s.len()) continue;
input_files.add(InputFile(s));
}
}
}
void
download(char *data)
{
bool no_input = FALSE;
bool any_file = FALSE;
bool private_download = FALSE;
bool free_time = FALSE;
char protocol_key = '\0';
bool quiet_download = FALSE;
bool goodbye = FALSE;
bool ignore_kbytes = FALSE;
bool no_log = FALSE;
bool ask_description = TRUE;
int npara;
int i;
long total_bytes;
long free_bytes;
String param[20];
BitArray arealist(MAX_FILE_AREAS,1);
LinkedList<DownloadFile> files;
LinkedList<InputFile> input_files;
LinkedList<String> copied_to_cd;
protocol prot;
FileName extra_log;
npara = parse_data(data,param); // Parse command line
create_arealist(param,npara,arealist); // Create list of selected file areas
adjust_limits();
for(i=0 ; i<npara ; i++)
{
if(param[i][0]=='/')
switch(toupper(param[i][1]))
{
case 'F': if(param[i][2] == '=')
{
if(param[i][3] == '@')
read_from_file(input_files,&param[i][4]);
else
input_files.add(InputFile(&param[i][3]));
}
else
{
input_files.add(InputFile(&param[i][2]));
}
no_input = TRUE;
case 'A': any_file = TRUE;
break;
case 'P': private_download = TRUE;
no_input = TRUE;
break;
case 'T': free_time = TRUE;
break;
case 'K': protocol_key = param[i][3];
break;
case 'Q': quiet_download = TRUE;
break;
case 'I': ignore_kbytes = TRUE;
break;
case 'N': no_log = TRUE;
break;
case 'L': extra_log = &param[i][3];
break;
case 'D': ask_description = FALSE;
break;
}
}
if(user.uFlags & UFLAG_IGNORE)
ignore_kbytes = TRUE;
if(!quiet_download)
{
io << "\n\f" << S_DOWNLOAD_TITLE << "\n\n";
if(timer.online()<download_delay && !(user.uFlags & UFLAG_IGNORE) && !private_download)
{
if(showansascrip("DLDELAY") == ANS_NOFILE)
{
io << S_DOWNLOAD_DELAY(form("%d",download_delay)) << "\n\n";
}
io << S_PRESS_ENTER_TO_CONTINUE;
return;
}
if(!cfg.downloadHours.enabled() && !(user.uFlags & UFLAG_IGNORE) && !private_download)
{
io << S_DOWNLOAD_NOT_NOW;
return;
}
}
if(!user.defaultProtocol || !select_protocol(prot,user.defaultProtocol))
{
if(!select_protocol(prot,protocol_key))
return;
}
else
{
io << S_PROTOCOL_SELECTED(prot.name);
}
if(!any_file && !no_input)
for(taglist.rewind() ; !taglist.eol() ; taglist++)
{
input_files.add( InputFile(taglist.get().name , taglist.get().area) );
}
for(input_files.rewind() ; !input_files.eol() ; input_files++)
{
if(input_files.get().area)
arealist.set(input_files.get().area);
}
if(!quiet_download && !no_input)
{
char s[80];
io << "\n\n" << S_ENTER_FILES_TO_DOWNLOAD << "\n\n";
int file_count = 1;
for( input_files.rewind() ; !input_files.eol() ; input_files++ , file_count++)
{
io << S_ENTER_DOWNLOAD_FILENAME(form("%d",file_count));
io << input_files.get().name << '\n';
}
for(;;file_count++)
{
io << S_ENTER_DOWNLOAD_FILENAME(form("%d",file_count));
io.read(s,(any_file ? 60:13),READMODE_UPALL);
if(!s[0]) break;
char *tmp = strtok(s," ");
for(i=0 ; tmp != NULL ; tmp = strtok(NULL," "))
{
if(strchr(tmp,'\\') && !any_file) continue;
input_files.add(InputFile(tmp));
}
io << "\n";
}
if(!input_files.count())
return;
io << '\n';
}
if(!quiet_download)
io << '\n' << S_SEARCHING_FILE_DATABASE << '\xFF';
if(private_download)
{
read_personal_files(input_files);
if(!input_files.count())
{
io << S_NO_PERSONAL_FILES_FOUND << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
}
// At this point we have a list of files that have to be download in the
// linked list called 'input_files'. If a path name is specified, it
// should not be looked for in the file areas
int files_found = 0;
for( input_files.rewind() ; !input_files.eol() && files_found < MAX_DOWNLOADS; )
{
DownloadFile cur_file;
if(strchr(input_files.get().name , '\\')) // Explicit path found?
{
DirScan scan(input_files.get().name);
while(int(scan) && files_found < MAX_DOWNLOADS)
{
FileName fn(input_files.get().name);
fn.stripName();
fn.appendBS();
cur_file.area = 0;
cur_file.free = FALSE;
cur_file.copy = FALSE;
cur_file.size = scan.size();
cur_file.name = fn + scan.name();
files.add(cur_file);
files_found++;
scan++;
}
input_files.remove();
}
else
{
input_files++;
}
}
if(input_files.count())
{
File fidx;
FilesIdx idx;
FileArea fa;
if(fidx.open(FileName(syspath,"FILESIDX.PB") , fmode_read , cfg.fastmode ? 8192:2048))
{
long idx_size = fidx.len() / sizeof(idx);
long step = idx_size / 50;
long count = 0;
if(step <= 1)
step = 1;
fidx.seek(0);
if(!quiet_download)
{
if(!ansi_mode && !avatar)
{
io << "\n\n";
}
io << "\6³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³";
if(ansi_mode || avatar)
{
io << "\x1b[51D\3";
}
else
{
io << '\r';
}
}
String firstchars;
bool wildcard_found = FALSE;
for( input_files.rewind() ; !input_files.eol() ; input_files++)
{
firstchars << char(toupper(input_files.get().name[0]));
}
if(strpbrk(firstchars,"*?")) wildcard_found = TRUE;
while(files_found < MAX_DOWNLOADS)
{
if(fidx.read(&idx,sizeof(idx)) != sizeof(idx))
break;
if(!((count++) % step) && !quiet_download) io << "±\xFF";
if(!wildcard_found && !strchr(firstchars,toupper(idx.name[0]))) continue;
if(!arealist[idx.area]) continue;
for( input_files.rewind() ; !input_files.eol() && files_found < MAX_DOWNLOADS ; input_files++)
{
if(input_files.get().area && idx.area != input_files.get().area) continue;
if(!matchfile(input_files.get().name,idx.name)) continue;
if(!fa.read(idx.area) || !check_access(fa.level,fa.flags,fa.flagsNot)) continue;
LinkedList<String> dirlist;
create_dirlist(idx.area,fa.filepath,dirlist);
for( dirlist.rewind() ; !dirlist.eol() && files_found < MAX_DOWNLOADS ; dirlist++)
{
String wildcard = dirlist.get();
wildcard << idx.name;
DirScan scan(wildcard);
while(int(scan) && files_found < MAX_DOWNLOADS)
{
DownloadFile tmpfile;
tmpfile.area = idx.area;
tmpfile.size = scan.size();
tmpfile.free = FALSE;
tmpfile.copy = !!fa.cdrom;
tmpfile.name = dirlist.get() + scan.name();
files.add(tmpfile);
files_found++;
scan++;
}
}
}
}
}
else
{
LOG("Error opening FILESIDX.PB");
}
}
total_bytes = 0;
free_bytes = 0;
if(!quiet_download)
{
io << '\n';
if(files.count())
{
io << '\n' << S_DOWNLOAD_FILES_FOUND_HEADER << '\n';
}
for(files.rewind() ; !files.eol() ; )
{
FileArea fa;
FileName fn;
String area_name;
fn = files.get().name;
fn.stripPath();
if(files.get().area)
{
fa.read(files.get().area);
area_name = fa.name;
}
else
{
if(private_download)
area_name = "Personal Files";
else
area_name = "Global";
}
io << S_DOWNLOAD_FILE_FOUND_ENTRY((char *)fn,form("%ld",(files.get().size+512L) / 1024L),(char *)area_name);
files.get().free = (fa.free || is_freefile((char *)fn));
if((total_bytes - free_bytes + files.get().size + user.kbToday*1024L) > (1024L*download_limit) && !files.get().free)
{
io << S_FILE_EXCEEDS_LIMIT(form("%u",download_limit)) << '\n';
files.remove();
}
else
{
if(upload_needed > 0 && !files.get().free)
{
io << S_UPLOAD_REQUIRED(form("%u",upload_needed)) << '\n';
files.remove();
}
else
{
io << S_FILE_FOUND_ACTION_PROMPT;
char action = wait_language_hotkeys(K_FILE_FOUND_ACTION_PROMPT);
int prompt_len = language_string_length(S_FILE_FOUND_ACTION_PROMPT);
io << String('\b',prompt_len) << String(' ',prompt_len) << String('\b',prompt_len);
switch(action)
{
case '\r':
case 0:
{
io << S_ACTION_DOWNLOAD << ' ';
if(files.get().free)
{
io << S_FREE_FILE;
free_bytes += files.get().size;
}
total_bytes += files.get().size;
io << '\n';
files++;
}
break;
case 1 :
{
io << S_ACTION_FILE_SKIPPED << '\n';
files.remove();
}
break;
case 2 :
{
io << S_ACTION_FILE_QUIT << '\n';
while(!files.eol()) files.remove();
}
break;
}
}
}
}
if(!files.count())
{
io << '\n' << S_NO_FILES_FOUND << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
word estimated = word(total_bytes / ((io.baud ? io.baud:115200L) * (prot.efficiency?prot.efficiency:100)/1000L));
if(prot.flags & PROT_LOCAL)
estimated = 0;
io << '\n' << S_X_FILES_SELECTED(form("%d",files.count()),form("%d",int(total_bytes/1024)),form("%02u:%02u",estimated/60,estimated%60)) << '\n';
if(!free_time && estimated/60>timer.left())
{
io << '\n' << S_NOT_ENOUGH_TIME_LEFT_FOR_DOWNLOAD << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
io << '\n' << S_START_DOWNLOAD_PROMPT;
char k = wait_language_hotkeys(K_START_DOWNLOAD_PROMPT);
if(k==2)
return;
if(k==1)
{
io << S_DOWNLOAD_ACTION_GOODBYE;
goodbye = TRUE;
}
io << "\n\n";
copy_cdrom( files , copied_to_cd);
io << "\n\n" << S_ACTIVATING_PROTOCOL << '\xFF';
}
LinkedList<String> downloads,uploads;
if(free_time) timer.suspend();
if(!send_files(prot , files , downloads , uploads))
{
delete_copied(copied_to_cd);
return;
}
delete_copied(copied_to_cd);
if(free_time) timer.restart();
total_bytes = 0;
free_bytes = 0;
files_found = 0;
for(downloads.rewind() ; !downloads.eol() ; downloads++)
{
for(files.rewind() ; !files.eol() ; )
{
FileName fn(files.get().name);
fn.stripPath();
if(downloads.get() == fn)
{
total_bytes += files.get().size;
if(files.get().free)
free_bytes += files.get().size;
remove_tag(fn,files.get().area);
if(private_download)
delete_personal_file(files.get().name);
files_found++;
File f;
if(extra_log.len())
{
f.open(extra_log,fmode_copen | fmode_text | fmode_append | fmode_write);
f.printf("D %d %s %ld %s\n",files.get().area,(char *)files.get().name,files.get().size,files.get().free ? "YES":"NO");
f.close();
}
if(!no_log)
{
f.open(FileName(syspath,"DOWNLOAD.LOG"),fmode_write | fmode_append |
fmode_copen | fmode_text);
f.printf("%05d %s\n",files.get().area,(char *)files.get().name);
f.close();
LOG(1,"Download-%c %s",prot.key,(char *)fn);
}
files.remove();
}
else
{
files++;
}
}
}
if(!ignore_kbytes)
{
user.numDownloads += files_found;
user.kbDownloaded += int((total_bytes-free_bytes) / 1024L);
user.kbToday += int((total_bytes-free_bytes) / 1024L);
}
if(!quiet_download)
{
io << "\n\f\n" << S_X_FILES_DOWNLOADED_SUCCESSFULLY(form("%d",files_found),form("%ld",total_bytes/1024L)) << "\n\n";
if(files.count())
io << S_X_FILES_NOT_DOWNLOADED(form("%d",files.count())) << "\n\n";
if(goodbye && !files.count() && !uploads.count())
{
unlink(prot.logfile);
unlink(prot.ctlfile);
io << "\n\n" << S_HANGUP_AFTER_DOWNLOAD_PROMPT << "10";
for(int i=10;i>0;i--)
{
io << form("\b\b%2d\xFF",i);
char c = toupper(io.readkey());
if(c==K_HANGUP_AFTER_DOWNLOAD_PROMPT[0]) return;
if(c==K_HANGUP_AFTER_DOWNLOAD_PROMPT[1]) break;
sleep(1);
}
LOG("Hanging up after download.");
showansascrip("DLHANGUP");
exit_proboard();
}
if(uploads.count())
process_uploads(prot,cfg.uploadpath,uploads,private_download , ask_description , no_log , quiet_download , extra_log );
io << S_PRESS_ENTER_TO_CONTINUE;
}
}
void
read_personal_files( LinkedList<InputFile>& files )
{
File f(FN_PVTFILES_PB);
if(!f.opened()) return;
f.rewind();
for(;;)
{
_PrivateFile pvt;
if(f.read(&pvt,sizeof(pvt)) != sizeof(pvt))
break;
if(strcmpl(pvt.to,user.name) || !pvt.fname[0]) continue;
String fname;
if(!strchr(pvt.fname,'\\'))
fname = String(cfg.pvtuploadpath) + pvt.fname;
else
fname = pvt.fname;
DirScan scan(fname);
if(int(scan))
files.add( InputFile(fname) );
}
}
void
delete_personal_file( char *name )
{
File f(FN_PVTFILES_PB,fmode_rw | fmode_excl);
if(!f.opened())
return;
FileName fn;
FileName fn_full( name );
_PrivateFile pvt;
int num_found = 0;
for(;;)
{
if(f.read(&pvt,sizeof(pvt))!=sizeof(pvt)) break;
if(!pvt.fname[0])
continue;
if(!strchr(pvt.fname,'\\'))
fn = String(cfg.pvtuploadpath) + pvt.fname;
else
fn = pvt.fname;
if(fn == fn_full)
num_found++;
}
f.rewind();
for(;;)
{
if(f.read(&pvt,sizeof(pvt))!=sizeof(pvt)) break;
if(!pvt.fname[0] || stricmp(pvt.to,user.name))
continue;
if(!strchr(pvt.fname,'\\'))
fn = String(cfg.pvtuploadpath) + pvt.fname;
else
fn = pvt.fname;
if(fn_full == fn)
{
pvt.fname[0]=0;
f.seek(-long(sizeof(pvt)),seek_cur);
f.write(&pvt,sizeof(pvt));
if(pvt.attr & PVTFILE_KEEP)
continue;
if(num_found < 2) // Only kill file if not waiting for oher user
unlink(fn_full);
}
}
}
InputFile::InputFile()
{
area = 0;
}
InputFile::InputFile(char *s)
{
area = 0;
if(s[0] == '[')
{
area = atoi(&s[1]);
for(int i=0; s[i] ; i++)
{
if(s[i] == ']')
{
name = &s[i+1];
return;
}
}
}
name = s;
}
InputFile::InputFile(char *s,int a)
{
name = s;
area = a;
}

BIN
DL.OBJ Normal file

Binary file not shown.

10
DSZCTL.TXT Normal file
View File

@ -0,0 +1,10 @@
P:\BBS\FILES\PROBOARD\PB_201.ZIP
P:\BBS\FILES\PROBOARD\GSZ0203.ZIP
P:\BBS\FILES\PROBOARD\HCOM_108.ZIP
P:\BBS\FILES\PROBOARD\HS121.ZIP
P:\BBS\FILES\PROBOARD\IZMBETA1.ZIP
P:\BBS\FILES\PROBOARD\MPMOD160.ZIP
P:\BBS\FILES\PROBOARD\MPT110.ZIP
P:\BBS\FILES\PROBOARD\SDP101G.ZIP
P:\BBS\FILES\PROBOARD\SDPF101G.ZIP
P:\BBS\FILES\PROBOARD\SZMOD160.ZIP

0
DSZLOG.TXT Normal file
View File

68
EGA.ASM Normal file
View File

@ -0,0 +1,68 @@
% MODEL MEM_MOD
public _set43,_set25,_setvideomode,_getvideomode
CODESEG
PROC _set43
push bp
push si
push di
mov ax,1112h
xor bx,bx
int 10h
pop di
pop si
pop bp
ret
ENDP _set43
PROC _set25
push bp
push si
push di
mov ax,3
int 10h
pop di
pop si
pop bp
ret
ENDP _set25
PROC _getvideomode
push bp
push si
push di
mov ax,0f00h
int 10h
xor ah,ah
pop di
pop si
pop bp
ret
ENDP _getvideomode
PROC _setvideomode
ARG mode:WORD
push bp
mov bp,sp
push si
push di
mov ax,[mode]
int 10h
pop di
pop si
pop bp
ret
ENDP _setvideomode
END

BIN
EGA.OBJ Normal file

Binary file not shown.

73
EVENT.CPP Normal file
View File

@ -0,0 +1,73 @@
#include "proboard.hpp"
int
event::minutesleft()
{
Date today(TODAY);
Time now(NOW);
int nowminutes=now[0]*60+now[1];
int min=10080;
if(enabled)
for(int i=0;i<7;i++)
{
int day = today.weekDay()+i;
if(day>6) day-=7;
if(!(days&(1<<day))) continue;
int m=start[0]*60+start[1]+i*60*24;
if((m+duration+1) <= nowminutes)
m += 10080;
m -= nowminutes;
if(m < min)
min = m;
}
return min;
}
int
event::nextday()
{
Date today(TODAY);
Time now(NOW);
int nowminutes=now[0]*60+now[1];
int min=10080;
int retday=0;
if(enabled)
for(int i=0;i<7;i++)
{
int day = today.weekDay()+i;
if(day>6) day -= 7;
if(!(days&(1<<day))) continue;
int m = start[0]*60 + start[1] + i*60*24;
if(m<=nowminutes)
m += 10080;
m -= nowminutes;
if(m<min)
{
min = m;
retday = day;
}
}
return retday;
}

BIN
EVENT.OBJ Normal file

Binary file not shown.

959
EXEC.ASM Normal file
View File

@ -0,0 +1,959 @@
;-------------------------------------------------------------------------
; Exec function with swapping to disk. (c) 1990,1991 Philippe Leybaert
;-------------------------------------------------------------------------
% MODEL MEM_MOD
LOCALS @@
PUBLIC _swapshell
EXTRN __psp : WORD
EXTRN _shell_windowed : WORD
EXTRN _shell_updateline: WORD
EXTRN _shell_swap : WORD
EXTRN _shell_swapname : PTR
EXTRN _use_ems : BYTE
EXTRN _tsw_vsize : WORD
EXTRN _tsw_hsize : WORD
EXTRN _tsw_videobase : FAR PTR
CODESEG _TEXT
numpara dw (?) ; number of paragraphs reserved by compiler
savedpara dw (?) ; number of paragraphs to keep
swapsize dw (?) ; size of swapfile (# paragraphs)
swapseg dw (?) ; segment of start of swapregion
main_ss dw (?) ; saved for swapshell
main_sp dw (?) ; function (compiler stack saved here)
old_ss dw (?) ; saved for
old_sp dw (?) ; exec function
saved_psp dw (?) ; psp of my program
retval dw (?) ; return value of process
swapmode dw (?) ; swap code/data?
ems_handle dw (?) ; EMS swapspace handle
num_cols dw (?) ; # screen columns
num_lines dw (?) ; # screen lines
use_ems db (?) ; Use EMS?
data_seg dw (?)
prgname db 128 DUP (0)
swapname db 13 DUP (0)
old_dir db '\'
db 69 DUP (0)
old_disk dw 0
displayline dw 132 dup (?)
EVEN
cur_x dw 0
cur_y dw 0
LABEL old21 DWORD
old21_off dw 0
old21_seg dw 0
LABEL old1c DWORD
old1c_off dw 0
old1c_seg dw 0
LABEL videoptr DWORD
video_off dw 0
video_seg dw 0
dw 99 DUP (?) ; new stack (100 words)
newstackptr dw 0
parablock dw 0
dw offset comlen
dw @Code
dd 0FFFFFFFFh
dd 0FFFFFFFFh
comlen db 0
comline db 127 dup (0)
PROC exec NEAR
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
mov [cs:old_ss],ss ; save stack
mov [cs:old_sp],sp ; (exec function destroys ss an sp)
push cs ; es <- cs
pop es
mov dx,offset prgname ; get program name
mov bx,offset parablock ; get parameter block
mov ax,4B00h ;
int 21h ; call DOS EXEC function
cli
mov ss,[cs:old_ss] ; restore stack pointer
mov sp,[cs:old_sp]
sti
mov ah,4Dh
int 21h
xor ah,ah
mov [cs:retval],ax
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
ret
ENDP exec
PROC shrink_exec NEAR ; ES: segment , BX: # para's to allocate
assume ds:@Code
cmp [swapmode],0
je @@noshrink
mov ax,4a00h ; shrink memory size to minimum
int 21h ; (only this module remains)
@@noshrink:
call near exec ; shell
mov ah,0Eh ;
mov dl,[byte old_disk] ; Restore current disk
int 21h ;
mov ah,3Bh ;
mov dx,offset old_dir ; Restore current directory
int 21h ;
cmp [swapmode],0
je @@noexpand
mov ax,[saved_psp]
mov es,ax
mov bx,[numpara]
mov ax,4A00h
int 21h ; give back memory we stole
push ds ; save data segment
mov cx,[swapsize]
mov ax,[swapseg]
mov ds,ax
call read_para
pop ds ; restore data segment
@@noexpand:
ret
ENDP shrink_exec
PROC read_para NEAR ; read cx paragraphs to ds:0
push ds
push ax
push bx
push cx
push dx
push si
push di
push es
cmp [cs:use_ems],0
je @@use_file
mov ah,40h
int 67h
or ah,ah
jnz @@use_file
mov dx,[cs:ems_handle]
mov ah,41h
int 67h
push ds
pop es
mov ds,bx ; es = page frame
xor bx,bx ; bx = logical page index
@@ems_loop:
cmp cx,0400h
jb @@ems_remainder
push cx
mov ax,4400h
int 67h ; map page bx to phys.page 0
mov cx,02000h
cld
xor si,si
xor di,di
rep movsw ; transfer data to page frame
inc bx
pop cx
sub cx,0400h
mov ax,es
add ax,0400h
mov es,ax
jmp short @@ems_loop
@@ems_remainder:
mov ax,4400h
int 67h ; map page bx to phys.page 0
shl cx,1 ; Convert # paragraphs -> #words
shl cx,1
shl cx,1
cld
xor si,si
xor di,di
rep movsw ; transfer data to page frame
mov ah,45h
int 67h ; Free EMS
jmp short @@quit
@@use_file:
push ds
mov ax,cs
mov ds,ax
assume ds:@Code
mov ax,3D00h
mov dx,offset swapname
int 21h ; open swap-file
mov bx,ax
pop ds
@@loopke:
cmp cx,0F00h
jb @@remainder
push cx
mov cx,0F000h
xor dx,dx
mov ax,3F00h
int 21h
pop cx
sub cx,0F00h
mov ax,ds
add ax,0F00h
mov ds,ax
jmp short @@loopke
@@remainder:
shl cx,1
shl cx,1
shl cx,1
shl cx,1
xor dx,dx
mov ax,3F00h
int 21h
mov ax,3E00h
int 21h ; close file
mov ax,cs
mov ds,ax
mov dx,offset swapname
mov ax,4100h
int 21h
@@quit:
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop ds
ret
ENDP read_para
PROC disp NEAR
push cx
push si
push di
push bp
cmp al,0ah
jne no_lf
mov cx,[cs:num_lines]
dec cx
inc [cs:cur_y]
cmp [cs:cur_y],cx ; At bottom of screen?
jne upd_cursor
dec [cs:cur_y] ; Yep, scroll up
jmp short scroll_up
no_lf:
cmp al,0dh
jne no_cr
mov [cs:cur_x],0
jmp short upd_cursor
no_cr:
cmp al,8
jne no_bs
cmp [cs:cur_x],0
je @@ok
dec [cs:cur_x]
jmp short upd_cursor
no_bs:
mov ah,0eh
xor bx,bx
int 10h
mov cx,[cs:num_cols]
inc [cs:cur_x]
cmp [cs:cur_x],cx ; At right of window?
jne @@ok
mov [cs:cur_x],0 ; Yep, linefeed
inc [cs:cur_y]
mov cx,[cs:num_lines]
dec cx
cmp [cs:cur_y],cx ; At bottom of screen
jne upd_cursor
dec [cs:cur_y]
scroll_up:
mov ax,0601h
mov cx,0000h
mov dl,4Fh
mov dh,[byte cs:num_lines]
dec dh
dec dh
mov bh,7
int 10h
upd_cursor:
mov ah,2
mov bh,0
mov dh,[byte cs:cur_y]
mov dl,[byte cs:cur_x]
int 10h
@@ok:
pop bp
pop di
pop si
pop cx
ret
ENDP disp
PROC new21
cmp ah,2
je catch
cmp ah,6
jne test_9
cmp dl,0ffh
jne catch
test_9:
cmp ah,9
je catch
cmp ah,40h
jne nocatch
cmp bx,1
je catch
cmp bx,2
je catch
nocatch:
jmp [cs:old21]
catch:
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
cmp ah,2
jne no_2
mov al,dl
call disp
jmp short done_catch
no_2:
cmp ah,6
jne no_6
mov al,dl
call disp
jmp short done_catch
no_6:
cmp ah,9
jne no_9
mov si,dx
@@l: mov al,[ds:si]
cmp al,'$'
je done_catch
call disp
inc si
jmp short @@l
no_9:
mov si,dx
@@l2:
or cx,cx
jz ret_40
mov al,[ds:si]
call disp
inc si
dec cx
jmp short @@l2
ret_40:
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov ax,cx
clc
iret
done_catch:
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
ENDP new21
timer_val dw 0
PROC new1c
push ax
inc [cs:timer_val]
mov ax,[cs:timer_val]
and ax,7
jnz @@nodisp
push cx
push si
push di
push bp
push ds
push es
push cs
pop ds
assume ds:@Code
les di,[videoptr]
mov si,offset displayline
cld
mov cx,80
rep movsw
pop es
pop ds
pop bp
pop di
pop si
pop cx
@@nodisp:
pop ax
jmp [cs:old1c]
ENDP new1c
startswap: ; all data/code past this point can be
; swapped (who cares!)
PROC _swapshell
ARG command:PTR
push bp
mov bp,sp
push ds
push si
push di
mov ax,ds
mov [cs:data_seg],ax
mov ax,[_tsw_vsize]
mov [cs:num_lines],ax
mov ax,[_tsw_hsize]
mov [cs:num_cols],ax
mov ax,[_shell_swap]
mov [cs:swapmode],ax
mov al,[_use_ems]
mov [cs:use_ems],al
call near install_isr
mov ax,[__psp] ; store psp for future use
mov [cs:saved_psp],ax
mov si,offset _shell_swapname
push cs
pop es
mov di,offset swapname
mov cx,13
cld
rep movsb
lds si,[command]
mov di,offset prgname
@@lp:
mov al,[si]
cmp al,' '
je @@qt
or al,al
je @@qt
mov [cs:di],al
inc si
inc di
jmp short @@lp
@@qt:
mov [byte cs:di],0
mov al,[si]
inc si
cmp al,' '
je @@qt
dec si
mov cx,0
mov di,offset comline
@@lp2:
mov al,[si]
or al,al
je @@qt2
mov [cs:di],al
inc si
inc di
inc cx
jmp short @@lp2
@@qt2:
mov [byte cs:di],13
mov di,offset comlen
mov [cs:di],cl
mov ax,@Code ; ds = code segment
mov ds,ax
assume ds:@Code ; tell Tasm where ds points to
mov [main_ss],ss ; save compiler stack
mov [main_sp],sp
mov ax,cs
cli
mov ss,ax ; set my own stack
mov sp,offset newstackptr
sti
mov ax,[saved_psp] ; get psp address
dec ax ; get address of MCB
mov es,ax
mov ax,[es:3] ; get number of paragraphs reserved
mov [numpara],ax ; and store it
mov bx,offset startswap ; we can swap from this point
mov cl,4
shr bx,cl ; convert to # paragraphs
add bx,@Code
mov ax,[saved_psp] ; how many paragraphs
sub bx,ax ; must remain?
add bx,2 ; 2 extra paragraphs (safe!)
mov es,ax ; es <- psp
mov [savedpara],bx ; store it
push bx ; push number of paragraphs
push es ; push psp address
mov cx,[numpara] ; get number of paragraphs reserved
sub cx,bx ; calculate # paragraphs to save
mov [swapsize],cx ; store for later use
mov ax,es ; get psp
add ax,bx ; calculate address for swap-start
mov [swapseg],ax ; store for later use
push ds ; save data segment
cmp [swapmode],0
je @@nowrite
mov ds,ax ; set ds to region to save
call near write_para ; save file
@@nowrite:
pop ds
mov ah,19h ;
int 21h ; Save current disk
mov [byte old_disk],al ;
mov si,offset old_dir+1 ;
mov dl,0 ; Save current directory
mov ah,47h ;
int 21h ;
pop es
pop bx
call near shrink_exec
cli
mov ss,[main_ss] ; restore compiler stack
mov sp,[main_sp]
sti
call near remove_isr
pop di
pop si
pop ds
pop bp
mov ax,[cs:retval] ; set return value
ret
ENDP _swapshell
PROC write_para NEAR ; write cx paragraphs from ds:0
push ds
push ax
push bx
push cx
push dx
push si
push di
push es
cmp [cs:use_ems],0
je @@use_file
mov ah,40h
int 67h
or ah,ah
jnz @@use_file
push cx
mov bx,cx
mov cl,10
shr bx,cl
inc bx
pop cx
mov ah,43h
int 67h
or ah,ah
jnz @@use_file
mov [cs:ems_handle],dx
mov ah,41h
int 67h
mov es,bx ; es = page frame
xor bx,bx ; bx = logical page index
@@ems_loop:
cmp cx,0400h
jb @@ems_remainder
push cx
mov ax,4400h
int 67h ; map page bx to phys.page 0
mov cx,02000h
cld
xor si,si
xor di,di
rep movsw ; transfer data to page frame
inc bx
pop cx
sub cx,0400h
mov ax,ds
add ax,0400h
mov ds,ax
jmp short @@ems_loop
@@ems_remainder:
mov ax,4400h
int 67h ; map page bx to phys.page 0
shl cx,1 ; Convert # paragraphs -> #words
shl cx,1
shl cx,1
cld
xor si,si
xor di,di
rep movsw ; transfer data to page frame
jmp short @@quit
@@use_file:
mov [cs:use_ems],0
push ds
push cx
push cs
pop ds
mov dx,offset swapname
mov ax,3c00h ; Create
xor cx,cx ; swap-file
int 21h
pop cx
pop ds
mov bx,ax
@@loopke:
cmp cx,0F00h
jb @@remainder
push cx
mov cx,0F000h
xor dx,dx
mov ax,4000h
int 21h
pop cx
sub cx,0F00h
mov ax,ds
add ax,0F00h
mov ds,ax
jmp short @@loopke
@@remainder:
shl cx,1
shl cx,1
shl cx,1
shl cx,1
xor dx,dx
mov ax,4000h
int 21h
mov ax,3E00h
int 21h
@@quit:
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop ds
ret
ENDP write_para
PROC install_isr NEAR
push ax
push bx
push cx
push dx
push ds
push es
push si
push di
push bp
mov ax,[cs:data_seg]
mov ds,ax
cmp [_shell_windowed],0
je @@nowindow
mov ax,3521h
int 21h
mov ax,es
mov [cs:old21_seg],ax
mov [cs:old21_off],bx
mov ax,2521h
mov dx,offset new21
push ds
push cs
pop ds
int 21h
pop ds
mov [cs:cur_x],0
mov [cs:cur_y],0
mov ax,0600h
mov cx,0
mov dl,4Fh
mov dh,[byte cs:num_lines]
dec dh
dec dh
mov bh,7
int 10h
mov dx,0
mov bh,0
mov ah,2
int 10h
@@nowindow:
cmp [_shell_updateline],0
je @@notupdated
mov ax,351Ch
int 21h
mov ax,es
mov [cs:old1c_seg],ax
mov [cs:old1c_off],bx
mov ax,251Ch
mov dx,offset new1c
push ds
push cs
pop ds
int 21h
pop ds
push ds
mov ax,[_shell_updateline]
dec ax
mov cx,[cs:num_cols]
shl cx,1
mul cx
lds si,[_tsw_videobase]
add si,ax
mov ax,ds
mov [cs:video_seg],ax
mov [cs:video_off],si
mov ax,[cs:num_lines]
dec ax
mov cx,[cs:num_cols]
shl cx,1
mul cx
mov si,ax ; SI = (num_lines-1) * num_cols * 2
push cs
pop es
mov di,offset displayline
mov cx,[cs:num_cols]
cld
rep movsw
pop ds
@@notupdated:
cmp [_shell_windowed],0
jne @@done
mov ax,0600h
mov cx,0
mov dl,[byte cs:num_cols]
dec dl
mov dh,[byte cs:num_lines]
dec dh
mov bh,7
int 10h
mov dx,0
mov bh,0
mov ah,2
int 10h
@@done:
pop bp
pop di
pop si
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
ret
ENDP install_isr
PROC remove_isr NEAR
push ds
mov ax,[cs:data_seg]
mov ds,ax
cmp [_shell_windowed],0
je @@nowindowrestore
push ds
mov ax,2521h
lds dx,[cs:old21]
int 21h
pop ds
@@nowindowrestore:
cmp [_shell_updateline],0
je @@noupdaterestore
mov ax,251Ch
lds dx,[cs:old1c]
int 21h
@@noupdaterestore:
pop ds
ret
ENDP remove_isr
ENDS
END

BIN
EXEC.OBJ Normal file

Binary file not shown.

97
EXECHECK.CPP Normal file
View File

@ -0,0 +1,97 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "proboard.hpp"
#pragma warn -rch
const long CHECKFREQ = 50;
struct
{
char string[15];
dword checksum;
} execheck = { "#`&$%#$%@%&^%E",0L };
void
check_exe(char */*fname*/)
{
/*
File f;
bool first_time = FALSE;
dword checksum = 0L;
long offset;
// #ifndef RELEASE
return;
// #endif
#if __OVERLAY__
return;
#endif
if(!execheck.checksum)
{
int c;
if(!f.open(fname,fmode_rw,512)) exit(ERRLVL_FATALERR);
first_time = TRUE;
for(;;)
{
c = f.readByte();
if(c<0) exit(ERRLVL_FATALERR);
if(char(c) == execheck.string[0])
{
char buf[14];
f.read(buf,13);
buf[13] = '\0';
if(!strcmp(buf,&execheck.string[1]))
{
offset = f.pos() + 1;
break;
}
f.seek(-12,seek_cur);
}
}
}
SCRAMBLE();
if(clockticks()%CHECKFREQ && !first_time) return;
if(!first_time) if(!f.open(fname,fmode_read,1024)) exit(ERRLVL_FATALERR);
f.rewind();
for(;;)
{
int c = f.readByte();
if(c<0) break;
checksum += byte(c);
SCRAMBLE();
}
if(first_time)
{
f.seek(offset);
f.write(&checksum,4);
}
else
{
byte *p = (byte *)&execheck.checksum;
for(int i=0;i<sizeof(execheck.checksum);i++) checksum -= p[i];
SCRAMBLE();
if(checksum != execheck.checksum)
{
LOG("PROBOARD.EXE CRC ERROR");
exit(ERRLVL_FATALERR);
}
}
*/
}

BIN
EXECHECK.OBJ Normal file

Binary file not shown.

219
FILEAREA.CPP Normal file
View File

@ -0,0 +1,219 @@
#define Use_MsgBase
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "proboard.hpp"
File FileArea::f;
int FileArea::lastAreaNum = -1;
int FileArea::numAreas = -1;
FileArea *FileArea::lastArea = NULL;
void
FileArea::open()
{
if(!f.opened())
{
if(!f.open(FileName(syspath,"FILECFG.PRO"),fmode_read,cfg.fastmode ? BUFSIZE_FAST:BUFSIZE_SLOW))
file_error("FILECFG.PRO");
numAreas = int(f.len() / sizeof(_FileArea));
}
}
bool
FileArea::read(int a)
{
open();
if(a<1 || a>numAreas) return FALSE;
if(lastArea == NULL)
{
lastArea = new FileArea;
lastAreaNum = -1;
}
if(a != lastAreaNum)
{
f.seek(long(a-1) * sizeof(_FileArea));
if( f.read(lastArea,sizeof(_FileArea)) != sizeof(_FileArea)
|| lastArea->name[0] == '\0' )
{
lastAreaNum = -1;
return FALSE;
}
}
(*this) = (*lastArea);
append_backspace(filepath);
strip_trailing( listpath );
strip_leading( listpath );
if(listpath[0] == '\0')
{
strcpy(listpath , filepath);
strcat(listpath , "FILES.BBS");
}
lastAreaNum = a;
areaNum = a;
strip_trailing( name );
strip_leading( name );
return (name[0]) ? TRUE:FALSE;
}
void
FileArea::close()
{
f.close();
if(lastArea != NULL) delete lastArea;
lastAreaNum = -1;
numAreas = -1;
lastArea = NULL;
}
int
FileArea::highAreaNum()
{
open();
return numAreas;
}
void
create_arealist(String param[],int numpara,BitArray& arealist,bool msgareas)
{
FileArea fa;
MsgArea ma;
int MAX;
if(msgareas)
MAX = MsgArea::highAreaNum();
else
MAX = FileArea::highAreaNum();
for(int i=0;i<numpara;i++)
{
char *ptr=param[i];
int incl=1,offset=0;
int kindfilter = 0;
if(ptr[0]=='/') continue;
if(ptr[0]=='-') { incl=0; offset=1; }
if(ptr[0]=='+') { incl=1; offset=1; }
switch(toupper(ptr[offset]))
{
case 'E': kindfilter = MSG_ECHO; break;
case 'N': kindfilter = MSG_NET; break;
case 'L': kindfilter = MSG_LOCAL; break;
}
switch(toupper(ptr[offset]))
{
case '*':
{
for(int j=1;j<=MAX;j++)
if(incl)
arealist.set(j);
else
arealist.clear(j);
}
break;
case 'C':
{
if(msgareas) break;
for(int j=1;j<=MAX;j++)
{
if(fa.read(j))
if(fa.cdrom)
if(incl)
arealist.set(j);
else
arealist.clear(j);
}
}
break;
case 'X':
{
if(msgareas)
{
if(incl)
arealist.set(user.msgArea);
else
arealist.clear(user.msgArea);
}
else
{
if(incl)
arealist.set(user.fileArea);
else
arealist.clear(user.fileArea);
}
}
break;
case 'N':
case 'L':
case 'E':
{
if(!msgareas) break;
for(int j=1;j<=MAX;j++)
{
if(ma.read(j))
if(ma.msgKind == kindfilter)
if(incl)
arealist.set(j);
else
arealist.clear(j);
}
}
break;
default:
{
if(strchr(ptr+offset,'-'))
{
int from = atoi(strtok(ptr+offset,"-"));
int to = atoi(strtok(NULL,"-"));
for(int j=from;j<=to;j++)
{
if(incl)
arealist.set(j);
else
arealist.clear(j);
}
}
else
{
int j = atoi(ptr+offset);
if(incl)
arealist.set(j);
else
arealist.clear(j);
}
}
break;
}
}
}

BIN
FILEAREA.OBJ Normal file

Binary file not shown.

148
FORWARD.CPP Normal file
View File

@ -0,0 +1,148 @@
#define Use_MsgBase
#include <string.h>
#include "proboard.hpp"
void
Message::forward()
{
int areanum = 0;
MsgArea ma;
char newto[ 36 ];
if ( msgArea->msgKind == MSG_LOCAL )
{
io << "\n\n"
<< S_FORWARD_IN_SAME_AREA;
}
if ( msgArea->msgKind != MSG_LOCAL ||
! io.ask( TRUE ) )
{
io << "\n\f\n";
linecounter( 0 );
set_msgarea( "* -N /L" );
io << '\n'
<< S_SELECT_MSG_AREA_TO_FORWARD_MESSAGE_IN;
io.read( areanum, 5 );
if ( areanum < 1 )
{
return;
}
}
else
{
areanum = areaNum();
}
if ( ! ma.read( areanum ) )
{
io << "\n\n"
<< S_UNKNOWN_MESSAGE_AREA
<< "\n\n"
<< S_PRESS_ENTER_TO_CONTINUE;
return;
}
for ( ; ; )
{
User tuser;
io << "\n\n"
<< S_FORWARD_MESSAGE_TO;
io.read( newto,
35,
READMODE_UPFIRST );
if ( ! newto[ 0 ] )
{
return;
}
if ( ! strcmpl( newto, "Sysop" ) )
{
strcpy( newto, msgArea->sysop );
}
if ( ma.msgKind != MSG_LOCAL ||
tuser.search( newto ) )
{
break;
}
io << "\n\n"
<< S_USER_NOT_LOCATED
<< '\n';
}
io << "\n\n"
<< S_FORWARDING_MESSAGE;
File tmpf;
if ( ! tmpf.open( "MSGTMP", fmode_create ) )
{
return;
}
tmpf << "----------------------------------------------------------------------\r\n";
tmpf << form( " ** Original message to : %s\r\n\r\n",
to );
tmpf << form( " ** Original post date/time : %d-%s-%02d %02d:%02d\r\n\r\n",
postDate[ 0 ],
months_short[ postDate[ 1 ] ],
postDate[ 2 ] % 100, // Y2K FIX: JDR
// postDate[ 2 ], // Y2K BUG! FIXED
postTime[ 0 ],
postTime[ 1 ] );
tmpf << form( " ** Forwarded by %s using ProBoard v" VERSION "\r\n",
user.name);
tmpf << "----------------------------------------------------------------------\r\n\r\n";
tmpf.close();
createMsgTextFile( "MSGTMP", TRUE );
if ( post_message( from,
newto,
subj,
areanum,
( attr & MSGATTR_PRIVATE )
? TRUE
: FALSE ) < 0 )
{
io << S_SAVING_MESSAGE_ERROR;
}
io << "\n\n"
<< S_PRESS_ENTER_TO_CONTINUE;
}

BIN
FORWARD.OBJ Normal file

Binary file not shown.

241
FOSSIL.ASM Normal file
View File

@ -0,0 +1,241 @@
% MODEL MEM_MOD
PUBLIC _fos_setbps
PUBLIC _fos_init
PUBLIC _fos_deinit
PUBLIC _fos_purgeoutput
PUBLIC _fos_purgeinput
PUBLIC _fos_status
PUBLIC _fos_setdtr
PUBLIC _fos_send
PUBLIC _fos_sendnw
PUBLIC _fos_flowctl
PUBLIC _fos_getch
PUBLIC _fos_getchnw
PUBLIC _fos_break
PUBLIC _fos_sendblock
PUBLIC _fos_readblock
CODESEG
nofossil_err DB 'FOSSIL driver not installed!',13,10,'$'
EVEN
PROC _fos_setbps
arg port:WORD,baud:BYTE
push bp
mov bp,sp
mov ah,0
mov al,[baud]
mov dx,[port]
int 14h
pop bp
ret
ENDP _fos_setbps
PROC _fos_status
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ah,3
int 14h
pop bp
ret
ENDP _fos_status
PROC _fos_init
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ah,4
int 14h
cmp ax,1954h
je foss_ok
push cs
pop ds
mov dx,offset nofossil_err
mov ah,9
int 21h
mov ax,4cffh
int 21h
foss_ok: pop bp
ret
ENDP _fos_init
PROC _fos_deinit
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ah,5
int 14h
pop bp
ret
ENDP _fos_deinit
PROC _fos_setdtr
arg port:WORD,state:BYTE
push bp
mov bp,sp
mov dx,[port]
mov al,[state]
mov ah,6
int 14h
pop bp
ret
ENDP _fos_setdtr
PROC _fos_purgeoutput
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ah,9
int 14h
pop bp
ret
ENDP _fos_purgeoutput
PROC _fos_purgeinput
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ah,0Ah
int 14h
pop bp
ret
ENDP _fos_purgeinput
PROC _fos_sendnw
arg port:WORD,char:BYTE
push bp
mov bp,sp
mov dx,[port]
mov al,[char]
mov ah,0Bh
int 14h
pop bp
ret
ENDP _fos_sendnw
PROC _fos_send
arg port:WORD,char:BYTE
push bp
mov bp,sp
mov dx,[port]
mov al,[char]
mov ah,1
int 14h
pop bp
ret
ENDP _fos_send
PROC _fos_flowctl
arg port:WORD,ctl:BYTE
push bp
mov bp,sp
mov dx,[port]
mov al,[ctl]
mov ah,0Fh
int 14h
pop bp
ret
ENDP _fos_flowctl
PROC _fos_getchnw
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ax,0c00h
int 14h
cmp ax,0FFFFh
je @@exit
mov dx,[port]
mov ax,200h
int 14h
xor ah,ah
@@exit: pop bp
ret
ENDP _fos_getchnw
PROC _fos_getch
arg port:WORD
push bp
mov bp,sp
mov dx,[port]
mov ax,200h
int 14h
xor ah,ah
pop bp
ret
ENDP _fos_getch
PROC _fos_sendblock
arg port:WORD,block:PTR,numbytes:WORD
push bp
mov bp,sp
push di
mov dx,[port]
mov cx,[numbytes]
if @DataSize
les di,[block]
else
push ds
pop es
mov di,[block]
endif
mov ah,19h
int 14h
pop di
pop bp
ret
ENDP _fos_sendblock
PROC _fos_readblock
arg port:WORD,block:PTR,numbytes:WORD
push bp
mov bp,sp
push di
mov dx,[port]
mov cx,[numbytes]
if @DataSize
les di,[block]
else
push ds
pop es
mov di,[block]
endif
mov ah,18h
int 14h
pop di
pop bp
ret
ENDP _fos_readblock
PROC _fos_break
arg port:WORD, mode:BYTE
push bp
mov bp,sp
mov dx,[port]
mov ah,1ah
cmp [mode],0
je @@stop
mov al,1
jmp @@exit
@@stop: xor al,al
@@exit: int 14h
pop bp
ret
ENDP _fos_break
ENDS
END

338
FOSSIL.CHT Normal file
View File

@ -0,0 +1,338 @@
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ³ ³ ³ ³
³ 00h ³ Set BaudRate ³ AL = Baud/Parity/SB ³ AX = Status bits ³ BaudRate code in AL: ³
³ ³ ³ DX = Port number ³ (See function 03h) ³ Bits [7:5] 000 = 19200, 001 = 38400, ³
³ ³ ³ (NOP if DX=00FFh) ³ ³ 010 = 300, 011 = 600, 100 = 1200, ³
³ ³ ³ ³ ³ 101 = 2400, 110 = 4800, 111 = 9600. ³
³ ³ ³ ³ ³ Parity: [4:3] 00 or 10 = none, ³
³ ³ ³ ³ ³ 01 = odd, 11 = even. ³
³ ³ ³ ³ ³ StopBits: [2:2] 0 = 1, 1 = 2 ³
³ ³ ³ ³ ³ CharLength: 5 bits plus value [1:0] ³
³ ³ ³ ³ ³ Support for [4:0] = 00011 required of ³
³ ³ ³ ³ ³ driver, others optional ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 01h ³ Transmit ³ AL = Character ³ AX = Status bits ³ Character is queued for transmission. ³
³ ³ character ³ DX = Port number ³ (See function 03h) ³ If there is room in the transmitter ³
³ ³ (wait for ³ (NOP if DX=00FFh) ³ ³ buffer when this call is made, the ³
³ ³ room in the ³ ³ ³ character will be stored and control ³
³ ³ buffer) ³ ³ ³ returned to caller. If the buffer is ³
³ ³ ³ ³ ³ full, the driver will wait for room. ³
³ ³ ³ ³ ³ This can be dangerous when used in ³
³ ³ ³ ³ ³ combination with flow control (see ³
³ ³ ³ ³ ³ Function 0Fh) ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 02h ³ Receive ³ DX = Port number ³ AH = 00h ³ The next character in the input ring ³
³ ³ character ³ (NOP if DX=00FFh) ³ AL = Input character ³ buffer is returned to the caller. If ³
³ ³ (wait for ³ ³ ³ none available, the driver will wait ³
³ ³ available) ³ ³ ³ for input. ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 03h ³ StatusRequest ³ DX = Port number ³ AX = Status bits ³ Bits are: ³
³ ³ ³ (NOP if DX=00FFh) ³ ³ AH[6:6] 1 = Output buffer empty ³
³ ³ ³ ³ ³ AH[5:5] 1 = Output buffer not full ³
³ ³ ³ ³ ³ AH[1:1] 1 = Input buffer overrun ³
³ ³ ³ ³ ³ AH[0:0] 1 = Characters in input buffer³
³ ³ ³ ³ ³ AL[7:7] 1 = Carrier Detect signal ³
³ ³ ³ ³ ³ AL[3:3] 1 = Always (never 0) ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 04h ³ Initialize ³ DX = Port number ³ AX = 1954h (success) ³ Required before I/O can take place on ³
³ ³ driver (port) ³ (DX=00FFh special) ³ BL = Max function ³ comm port. When DX = 00FFh, then ³
³ ³ ³ ³ supported, not ³ any initialization needed to make the ³
³ ³ ³ ³ incl. 7Eh - BFh ³ keyboard/display available for FOSSIL ³
³ ³ ³ {BX = 4F50H ³ BH = FOSSIL revision ³ use should be performed. BX = 4F50h ³
³ ³ ³ ES:CX = ^C flag byte}³ level of driver ³ signals that ES:CX points to a flag ³
³ ³ ³ (Optional) ³ ³ byte in the application that the ³
³ ³ ³ ³ DTR raised on port ³ driver should increment when its ³
³ ³ ³ ³ BaudRate preserved ³ keyboard routines detect a Ctl-C. ³
³ ³ ³ ³ ³ ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ³ ³ ³ ³
³ 05h ³ Deinitialize ³ DX = Port number ³ None ³ Disengages driver from comm port. ³
³ ³ driver (port) ³ (DX=00FFh special) ³ ³ Should be done when operations on the ³
³ ³ ³ ³ DTR not changed ³ port are complete. IF DX = 00FFh, ³
³ ³ ³ ³ ³ then the initialization that was ³
³ ³ ³ ³ ³ performed when FOSSIL function 04h ³
³ ³ ³ ³ ³ with DX = 00FFh should be undone. ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 06h ³ Raise/lower ³ AL = 01h - Raise DTR ³ None ³ Used to control Data Terminal Ready ³
³ ³ DTR ³ = 00h - Lower DTR ³ ³ signal line on com port. This line ³
³ ³ ³ DX = Port number ³ DTR TRUE if AL = 01h ³ usually has some effect on modem ³
³ ³ ³ (NOP if DX=00FFh) ³ FALSE if AL = 00h ³ operation (most modems will drop ³
³ ³ ³ ³ ³ carrier if DTR is lowered, for ³
³ ³ ³ ³ ³ example). ³
³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 07h ³ Return system ³ None ³ AL = timer tick ³ Returns statistics needed to do some ³
³ ³ timer params ³ ³ interrupt number ³ critical timing in any MS-DOS system. ³
³ ³ ³ ³ (NOT vector) ³ The interrupt number in AL can be ³
³ ³ ³ ³ AH = number of ticks ³ used to intercept a timer interrupt ³
³ ³ ³ ³ per second ³ that happens (AH) times per second. ³
³ ³ ³ ³ DX = (apx.) number ³ DX is essentially 1000/AH. Function ³
³ ³ ³ ³ of mS / tick ³ 16h is the preferred way to install ³
³ ³ ³ ³ ³ timer tick code. AH and DX should ³
³ ³ ³ ³ ³ be accurate for the 16h timer tick. ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 08h ³ Flush output ³ DX = Port number ³ None ³ This is used to wait for all output ³
³ ³ buffer ³ (NOP if DX=00FFh) ³ ³ to complete. If flow control is active³
³ ³ ³ ³ ³ it is possible for this code never to ³
³ ³ (wait for all ³ ³ ³ return control to the caller. (See ³
³ ³ output to end)³ ³ ³ function 0Fh) ³
³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 09h ³ Purge output ³ DX = Port number ³ None ³ Zero the output buffer. Returns to ³
³ ³ buffer ³ (NOP if DX=00FFh) ³ ³ the caller immediately. Characters ³
³ ³ ³ ³ ³ that have not been transmitted yet ³
³ ³ (immediately ³ ³ ³ are lost. ³
³ ³ zero buffer) ³ ³ ³ ³
³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ³ ³ ³ ³
³ 0Ah ³ Purge input ³ DX = Port number ³ None ³ Zeroes the input buffer. If any flow ³
³ ³ buffer ³ (NOP of DX=00FFh) ³ ³ control restraint has been employed ³
³ ³ ³ ³ ³ (dropping RTS or transmitting XOFF) ³
³ ³ ³ ³ ³ the port will be "released" (by doing ³
³ ³ ³ ³ ³ the reverse, raising RTS or sending ³
³ ³ ³ ³ ³ XON). Returns to caller immediately. ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 0Bh ³ Transmit ³ AL = Character ³ AX = 0001h if sent ³ Character is queued for transmission. ³
³ ³ character ³ DX = Port number ³ = 0000h if not ³ If there is room in the transmitter ³
³ ³ ("no wait") ³ (NOP if DX=00FFh) ³ sent ³ buffer when this call is made, the ³
³ ³ ³ ³ ³ character will be stored and control ³
³ ³ ³ ³ ³ returned to caller with AX=1. If the ³
³ ³ ³ ³ ³ buffer is full, control is returned ³
³ ³ ³ ³ ³ to caller with AX=0. This allows the ³
³ ³ ³ ³ ³ application to make its own decisions ³
³ ³ ³ ³ ³ on how to deal with "buffer full". ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 0Ch ³ "Peek ahead" ³ DX = Port number ³ AH = 00h ³ The next character in the input ring ³
³ ³ input buffer ³ (NOP if DX=00FFh) ³ AL = input character ³ buffer is returned to the caller. If ³
³ ³ (non-dest ³ ³ (if available) ³ none available, the driver returns a ³
³ ³ read-ahead) ³ ³ AX = FFFFh (if none ³ value of FFFFH. This "read" does not ³
³ ³ ³ ³ (available) ³ actually remove a character from the ³
³ ³ ³ ³ ³ input buffer! ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 0Dh ³ "Peek ahead" ³ None ³ AX = keyboard char ³ The next character in the keyboard ³
³ ³ KB buffer ³ ³ (if available) ³ buffer is returned to the caller. If ³
³ ³ (non-dest ³ ³ AX = FFFFh (if none ³ none available, the driver returns a ³
³ ³ read-ahead) ³ ³ available) ³ value of FFFFH. This "read" does not ³
³ ³ ³ ³ ³ actually remove a character from the ³
³ ³ ³ ³ ³ input buffer! For function keys, IBM ³
³ ³ ³ ³ ³ PC scan codes must be returned. ³
³ ³ ³ ³ ³ ³
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ ³
³ 0Eh ³ Read Keyboard ³ None ³ AX = keyboard char ³ Return the next character from the ³
³ ³ (wait if no ³ ³ ³ keyboard buffer. Wait for a keystroke ³
³ ³ char avail) ³ ³ ³ if the buffer is empty. For function ³
³ ³ ³ ³ ³ keys, IBM PC scan codes are required. ³
³ ³ ³ ³ ³ ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ³ ³ ³ ³ |
³ 0Fh ³ Enable/Disable³ AL = Flow control ³ None ³ AL[0:0] 1= enables remote to restrain |
³ ³ com port flow ³ bit mask ³ ³ FOSSIL transmitter using XON/XOFF; |
³ ³ control ³ DX = Port number ³ ³ AL[1:1] 1= enables modem restraint of |
³ ³ ³ (NOP if DX=00FFh) ³ ³ FOSSIL transmitter using CTS and |
³ ³ ³ ³ ³ FOSSIL restraint of modem using RTS |
³ ³ ³ ³ ³ AL[3:3] 1= enables FOSSIL to restrain |
³ ³ ³ ³ ³ remote using XON/XOFF. |
³ ³ ³ ³ ³ |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 10h ³ Enable/disable³ AL = Flags byte ³ AX = 0001h - CtlC/K ³ AL[0:0] 1 = enable/disable CtlC/CtlK |
³ ³ Ctl-C/Ctl-K ³ DX = Port number ³ detected since ³ check (driver will set internal flag|
³ ³ check, ³ (NOP if DX=00FFh) ³ last call ³ which is returned by this function |
³ ³ Enable/disable³ ³ = 0000h - CtlC/K ³ when it detects a CtlC/CtlK). |
³ ³ transmitter ³ ³ not detected ³ AL[1:1] 1 = stop transmitter |
³ ³ ³ ³ since last ³ 0 = release previous stop |
³ ³ ³ ³ call ³ This is used primarily for programs |
³ ³ ³ ³ ³ that can't trust XON/XOFF at FOSSIL |
³ ³ ³ ³ ³ level (such as BBS software). |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 11h ³ Set cursor ³ DH = Row (0-based) ³ None ³ Identical to IBM PC BIOS INT 10h, |
³ ³ location ³ DL = Col (0-based) ³ ³ subfunction 02h. FOSSIL should do |
³ ³ ³ ³ ³ sanity checks but software should not |
³ ³ ³ ³ ³ assume that that is the case. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 12h ³ Read Cursor ³ None ³ DH = Row (0-based) ³ Identical to IBM PC BIOS INT 10h, |
³ ³ Location ³ ³ DL = Col (0-based) ³ subfunction 03h. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 13h ³ Write char ³ AL = Character ³ None ³ ANSI processing is a requirement of |
³ ³ (ANSI support)³ ³ ³ this call. It therefore should not be |
³ ³ ³ ³ ³ considered re-entrant, since DOS |
³ ³ ³ ³ ³ might be used (via ANSI.SYS) |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 14h ³ Enable/disable³ AL = 01h - Enable ³ None ³ FOSSIL will force the system to reboot³
³ ³ "watchdog" ³ watchdog ³ ³ if Carrier Detect on the specified ³
³ ³ ³ = 00h - Disable ³ ³ port drops while "watchdog" is ON. ³
³ ³ ³ watchdog ³ ³ ³
³ ³ ³ DX = Port number ³ ³ It is not necessary for the port to ³
³ ³ ³ (NOP if DX=00FFh) ³ ³ be "active" (Function 04h) for this ³
³ ³ ³ ³ ³ function to be used. ³
³ ³ ³ ³ ³ ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ³ ³ ³ ³ |
³ 15h ³ Write char ³ AL = Character ³ None ³ Write character to screen using |
³ ³ (re-entrant) ³ ³ ³ re-entrant code. ANSI processing may |
³ ³ ³ ³ ³ not be assumed. This call may be used |
³ ³ ³ ³ ³ by DOS device drivers. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 16h ³ Insert/delete ³ AL = 01h - Insert ³ AX = 0000h - operation³ Allows FOSSIL to manage timer tick |
³ ³ function from ³ = 00h - Delete ³ was successful ³ chain, which provides some measure of |
³ ³ timer tick ³ ES = Function segment ³ = FFFFh - operation³ security over just snagging the |
³ ³ ³ DX = Function offset ³ was unsuccessful ³ interrupt. Use "insert" instead of |
³ ³ ³ ³ ³ grabbing the vector and "remove" in |
³ ³ ³ ³ ³ place of restoring it. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 17h ³ Reboot system ³ AL = 00h - Cold boot ³ None (hopefully!) ³ Provides a machine-independent way |
³ ³ ³ = 01h - Warm boot ³ ³ for a "troubled" application to reset |
³ ³ ³ ³ ³ the system. Some machines may not |
³ ³ ³ ³ ³ support both "flavors" of bootstrap, |
³ ³ ³ ³ ³ in which case the setting of AL will |
³ ³ ³ ³ ³ not have any effect. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 18h ³ Read block ³ CX = Count ³ AX = Number of chars ³ Transfer as many characters as are |
³ ³ ³ ES = Segment of ³ actually moved ³ available into the specified user |
³ ³ ³ user buffer ³ ³ buffer, up to the maximum specified |
³ ³ ³ DI = Offset of ³ ³ in CX. ES and DI will not be modified |
³ ³ ³ user buffer ³ ³ by this call. The actual number of |
³ ³ ³ DX = Port number ³ ³ characters transferred will be in AX. |
³ ³ ³ (NOP if DX=00FFh) ³ ³ This function does not wait for more |
³ ³ ³ ³ ³ characters to become available if the |
³ ³ ³ ³ ³ number in CX exceeds the number of |
³ ³ ³ ³ ³ characters currently stored. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 19h ³ Write block ³ CX = Count ³ AX = number of chars ³ Transfer as many characters as will |
³ ³ ³ ES = Segment of ³ actually moved ³ fit, from the specified user buffer ³
³ ³ ³ user buffer ³ ³ into the output buffer, up to the ³
³ ³ ³ DI = Offset of ³ ³ maximum specified in CX. ES and DI ³
³ ³ ³ user buffer ³ ³ will not be modified by this call. ³
³ ³ ³ DX = Port number ³ ³ The actual number of characters ³
³ ³ ³ (NOP if DX=00FFh) ³ ³ transferred will be in AX. ³
³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ³ ³ ³ ³ |
³ 1Ah ³ Start/stop ³ AL = 01h - Start break³ None ³ Used for special applications such as |
³ ³ sending break ³ 001 - Stop break ³ ³ certain high speed modems. Resets |
³ ³ ³ DX = Port number ³ ³ all transmit flow control restraints |
³ ³ ³ (NOP if DX=00FFh) ³ ³ (such as an XOFF received from remote)|
³ ³ ³ ³ ³ Init (Function 4) or UnInit (Function |
³ ³ ³ ³ ³ 5) will stop an in-progress Break. |
³ ³ ³ ³ ³ Note: the application must determine |
³ ³ ³ ³ ³ the "length" of the BREAK. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 1Bh ³ GetDriverInfo ³ CX = Size of buffer ³ AX = Number of bytes ³ Offset 0 (word) = Structure size |
³ ³ ³ ES = Segment of ³ transferred ³ 2 (byte) = FOSSIL spec version |
³ ³ ³ user buffer ³ ³ 3 (byte) = Driver rev level |
³ ³ ³ DI = Offset of ³ User buffer contains ³ 4 (dwrd) = Pointer to ASCII ID |
³ ³ ³ user buffer ³ info structure (used ³ 8 (word) = Input buffer size |
³ ³ ³ DX = Port number ³ to get special data ³ 0A (word) = Bytes avail (input) |
³ ³ ³ (If DX=00FF, ³ from the driver) ³ 0C (word) = Output buffer size |
³ ³ ³ port data will ³ ³ 0E (word) = Bytes avail (output)³
³ ³ ³ not be valid). ³ ³ 10 (byte) = Screen width, chars ³
³ ³ ³ For port data to be ³ ³ 11 (byte) = Screen height, chars³
³ ³ ³ accurate, port must ³ ³ 12 (byte) = Baud rate mask ³
³ ³ ³ be active. ³ ³ (See call 00h) ³
³ ³ ³ ³ ³ ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Code ³ Function ³ Function Parameters ³ Returned by Function ³ Explanation ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ³ ³ ³ ³ |
³ 7Eh ³ Install user ³ AL = Appendage code ³ AX = 1954h - FOSSIL ³ Used to install user appendages into |
³ ³ appendage ³ ES = Segment of user ³ driver present ³ the INT 14h dispatcher. Appendage |
³ ³ ³ appendage entry ³ = Anything but ³ codes 80h - BF are supported. Codes |
³ ³ ³ point ³ 1954h - FOSSIL ³ 80h - 83h are reserved. The error |
³ ³ ³ DX = Offset of user ³ driver not ³ return, BH = 00h and AX = 1954h, |
³ ³ ³ appendage entry ³ present ³ should mean that another appendage |
³ ³ ³ point ³ BL = Code assigned to ³ has already been installed with the |
³ ³ ³ ³ appendage (same ³ code specified in AL. The appendage |
³ ³ ³ ³ as AL at entry) ³ will be entered via a far call when- |
³ ³ ³ ³ BH = 01h - Operation ³ ever INT 14h call is made with AL |
³ ³ ³ ³ successful ³ equal to the appendage code. The |
³ ³ ³ ³ = 00h - Operation ³ appendage should return to the INT |
³ ³ ³ ³ unsuccessful ³ 14h dispatcher via a far return. The |
³ ³ ³ ³ ³ INT 14h dispatcher should not modify |
³ ³ ³ ³ ³ any registers prior to making the far |
³ ³ ³ ³ ³ call to the appendage and after the |
³ ³ ³ ³ ³ appendage returns control to the |
³ ³ ³ ³ ³ dispatcher. |
³ ³ ³ ³ ³ |
ÆÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵
³ ³ ³ ³ ³ |
³ 7Fh ³ Remove user ³ AL = Appendage code ³ AX = 1954h ³ Used to remove a user appendage that |
³ ³ appendage ³ ES = Segment of user ³ BL = Code assigned to ³ was installed using function 7Fh. An |
³ ³ ³ appendage entry ³ appendage (same ³ error return means that either the |
³ ³ ³ point ³ as AL at entry) ³ entry point specified in ES:DX did |
³ ³ ³ DX = Offset of user ³ BH = 01h - Operation ³ not match the entry point currently |
³ ³ ³ appendage entry ³ successful ³ in the dispatcher table for the code |
³ ³ ³ point ³ = 00h - Operation ³ given in AL, or that no entry for |
³ ³ ³ ³ unsuccessful ³ the code given in AL currently exits. |
³ ³ ³ ³ ³ |
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

831
FOSSIL.DOC Normal file
View File

@ -0,0 +1,831 @@
Fundamentals of FOSSIL implementation and use
Version 5, February 11, 1988
Rick Moore, Solar Wind Computing
FidoNet Address: 1:115/333
FidoNet Standards Committee index: FSC-0015
This document supersedes/obsoletes: FSC-0008
Copyright (C) 1987, VEP Software, Naugatuck, CT 06770. All rights reserved.
Copyright (C) 1988, Rick Moore, Homewood, IL, 60430. All rights reserved.
This document may be freely used or copied by anyone interested in the data
contained herein. No fees may be charged for distribution of this document.
You will be held accountable for all such charges, and expected to either
reimburse those persons or organizations so charged, or to make a donation
in the exact amount of those fees to the International FidoNet Association,
to assist them in their efforts to advance the technology of personal
computer telecommunications.
Fundamentals of FOSSIL implementation and use FSC-0015
Introduction Page 2
A. Objectives of this document
This document is directed at implementors or intellectuals. It is meant
for use in implementing applications that can use FOSSIL drivers, or for
details needed to implement a new FOSSIL. As such it won't always go out
of its way to explain itself to the neophyte.
This document will have served its purpose to you if you are able to use
the data contained within to perform either of the above tasks. If you
feel that necessary data has been omitted please contact Rick Moore
at the above listed address so that the appropriate changes can be made.
Any lines changed in the current version are marked with "|" in the left
margin.
B. Historical perspective
For those people who were not lucky enough to have an IBM PC or a system
nearly completely compatible, the world has not been very friendly. With
his implementation of the Generic Fido(tm) driver, Tom Jennings made it
possible for systems that had nothing in common with an IBM PC except an
808x-class processor, and the ability to run MS-DOS Version 2 and above,
to run his Fido(tm) software. That was a lot to ask, and a lot of people
thought it was enough.
But not everyone. While Thom Henderson was debugging Version 4.0 of his
SEAdog(tm) mail package, an "extended" Generic driver was designed (in
cooperation with Bob Hartman) as a quick kludge to help him get past a
problem with certain UART chips.The new hook was quickly pounced upon by
Vince Perriello, who, with almost DAILY prodding (ouch! it still hurts)
by Ken Kaplan,had been working with Henderson to get DEC Rainbow support
into SEAdog. Vince then coded a driver to use this hook and - Voila! -
SEAdog 4.0 started working like a champ on the Rainbow.
At the same time something was rotten in the state of Texas. Wynn Wagner
started encountering some serious difficulties in his Opus development
effort. Specifically, he couldn't force the Greenleaf(tm) Communications
Libraries to behave in exactly the way he felt Opus required. Enter Bob
Hartman.Having already enjoyed success in the effort with Thom Henderson,
he suggested to Wynn that with very few extensions, any driver that was
already SEAdog(tm) 4.0 compatible could drive Opus as well. About that
time, Vince called Wynn to discuss porting Opus to the DEC Rainbow. Wynn
called Bob, Bob called Vince, and the FOSSIL driver came into existence.
FOSSIL is an acronym for "Fido/Opus/SEAdog Standard Interface Layer". To
say that the concept has gained wide acceptance in the FidoNet community
would be an understatement. Henk Wevers' DUTCHIE package uses the FOSSIL
communications services. Ron Bemis' OUTER package uses FOSSIL services
for everything it does and as a result it is completely generic. There
are already FOSSIL implementations for the Tandy 2000, Heath/Zenith 100,
Sanyo 555 and other "non-IBM" architectures. With each new 'port' of the
spec, the potential of a properly coded FOSSIL application grows!
Fundamentals of FOSSIL implementation and use FSC-0015
Basic conventions and calling method Page 3
C. Basic principles of a FOSSIL driver
1) Interrupt 14h.
The one basic rule that the driver depends upon, is the ability for ANY
target machine to allow the vector for INT 14h (usually pointing to BIOS
comm functions) to be "stolen" by the driver. In a system where the INT
14h vector is used already, it must be possible to replace the "builtin"
functionality with that of a FOSSIL, when an application that wants the
use of a FOSSIL is to be run on the target machine.
2) How to install a FOSSIL driver in a system
There's no hard and fast way to do this. The FOSSIL might be implemented
as part of a device driver (like Ray Gwinn's X00.SYS) and therefore gets
loaded using a line in CONFIG.SYS at bootup time. It might be done as a
TSR (terminate and stay resident) program, in which event you install it
by running the program (DECcomm by Vince Perriello and Opus!Comm by Bob
Hartman work this way, for example).
3) How an application can detect the presence of a FOSSIL
The driver has a "signature" that can be used to determine whether it is
present in memory. At offset 6 in the INT 14h service routine is a word,
1954h, followed by a byte that specifies the maximum function number
supported by the driver. This is to make it possible to determine when a
driver is present and what level of functionality it provides. Also, the
Init call (see below) returns a 1954h in AX. SEAdog(tm) looks at the
signature and Opus just goes for the Init. Fido doesn't do either.
4) How to call a FOSSIL function
The FOSSIL driver is entered by issuing a software Interrupt 14h from
the application program. The code corresponding to the desired function
should be in 8-bit register AH. For calls that relate to communications,
the port number will be passed from the application in register DX. When
DX contains a zero (0) it signifies use of COM1, or whatever the "first"
serial port on your machine is called. A one (1) in DX points the driver
at COM2, and so on. A value of 00FFh in DX is considered a special case
where the driver should do no actual processing but return SUCCESS. In
the specific case of Init/Uninit with DX=00FFh,the FOSSIL should perform
all non-communications processing necessary with such calls. In some
machines (H/Z-100 for example), the FOSSIL must assume control of the
keyboard in order to service the keyboard functions.
FOR ALL FUNCTIONS, ALL REGISTERS NOT SPECIFICALLY CONTAINING A FUNCTION
RETURN VALUE MUST BE PRESERVED ACROSS THE CALL.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 4
D. Functions currently defined for FOSSILs
AH = 00h Set baud rate
Parameters:
Entry: AL = Baud rate code
DX = Port number
| Exit: AX = Port status (see function 03h)
This works the same as the equivalent IBM PC BIOS call, except that it
ONLY selects a baud rate. This is passed in the high order 3 bits of AL
as follows:
010 = 300 baud
011 = 600 ''
100 = 1200 ''
101 = 2400 ''
110 = 4800 ''
111 = 9600 ''
000 = 19200 '' (Replaces old 110 baud mask)
001 = 38400 '' (Replaces old 150 baud mask)
The low order 5 bits can be implemented or not by the FOSSIL, but in all
cases, if the low order bits of AL are 00011, the result should be that
the communications device should be set to eight data bits, one stop bit
and no parity. This setting is a MINIMUM REQUIREMENT of Fido, Opus and
SEAdog. For purposes of completeness, here are the IBM PC "compatible"
bit settings:
Bits 4-3 define parity: 0 0 no parity
1 0 no parity
0 1 odd parity
1 1 even parity
Bit 2 defines stop bits: 0 1 stop bit;
1 1.5 bits for 5-bit char;
2 for others
Bits 1-0 character length: 0 0 5 bits
0 1 6 bits
1 0 7 bits
1 1 8 bits
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 5
AH = 01h Transmit character with wait
Parameters:
Entry: AL = Character
DX = Port number
Exit: AX = Port status (see function 03h)
AL contains the character to be sent. If there is room in the transmit
buffer the return will be immediate, otherwise it will wait until there
is room to store the character in the transmit buffer. On return, AX is
set as in a status request (see function 03h).
AH = 02h Receive character with wait
Parameters:
Entry: DX = Port number
Exit: AH = 00h
AL = Input character
If there is a character available in the receive buffer, returns with
the next character in AL. It will wait until a character is received if
none is available.
AH = 03h Request status
Parameters:
Entry: DX = Port number
Exit: AX = Status bit mask (see below)
Returns with the line and modem status in AX. Status bits returned are:
In AH:
Bit 0 = RDA - input data is available in buffer
| Bit 1 = OVRN - the input buffer has been overrun. All
| characters received after the buffer is
| full should be discarded.
Bit 5 = THRE - room is available in output buffer
Bit 6 = TSRE - output buffer is empty
In AL:
| Bit 3 = Always 1 (always return with this bit set to 1)
Bit 7 = DCD - carrier detect
This can be used by the application to determine whether carrier detect
(CD) is set, signifying the presence/absence of a remote connection, as
well as monitoring both the input and output buffer status. Bit 3 of AL
is always returned set to enable programs to use it as a carrier detect
bit on hardwired (null modem) links.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 6
AH = 04h Initialize driver
Parameters:
Entry: DX = port number
( BX = 4F50h
| ES:CX = ^C flag address --- optional )
Exit: AX = 1954h if successful
| BL = maximum function number supported
| (not counting functions 7Eh and above)
| BH = rev of FOSSIL doc supported
This is used to tell the driver to begin operations, and to check that
the driver is installed. This function should be called before any other
communications calls are made. At this point all interrupts involved in
supporting the comm port (specified in DX) should be set up for handling
by the FOSSIL, then enabled. If BX contains 4F50h, then the address
specified in ES:CX is that of a ^C flag byte in the application program,
to be incremented when ^C is detected in the keyboard service routines.
This is an optional service and only need be supported on machines where
the keyboard service can't (or won't) perform an INT 1Bh or INT 23h when
| a Control-C is entered. DTR is raised by this call. The baud rate must
| NOT be changed by this call.
NOTE: Should an additional call to this service occur (2 Inits or Init,
Read,Init, etc.) the driver should reset all buffers, flow control, etc.
to the INIT state and return SUCCESS.
AH = 05h Deinitialize driver
Parameters:
Entry: DX = Port number
Exit: None
This is used to tell the driver that comm port operations are ended. The
function should be called when no more comm port functions will be used
on the port specified in DX. DTR is NOT affected by this call.
AH = 06h Raise/lower DTR
Parameters:
Entry: DX = Port number
AL = DTR state to be set (01h = Raise, 00h = Lower)
Exit: None
This function is used to control the DTR line to the modem. AL = 00h means
lower DTR (disable the modem), and AL = 01h means to raise DTR (enable the
modem). No other function (except Init) should alter DTR.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 7
AH = 07h Return timer tick parameters
Parameters:
Entry: None
Exit: AL = Timer tick interrupt number
AH = Ticks per second on interrupt number in AL
DX = Approximate number of milliseconds per tick
This is used to determine the parameters of the timer tick on any given
machine. Three numbers are returned:
AL = Timer tick interrupt number
AH = Ticks per second on interrupt number shown in AL
DX = Milliseconds per tick (approximate)
Applications can use this for critical timing (granularity of less than
one second) or to set up code (such as a watchdog) that is executed on
every timer tick. See function 16h (add/delete function from timer tick)
for the preferred way of actually installing such code.
AH = 08h Flush output buffer
Parameters:
Entry: DX = Port number
Exit: None
This is used to force any pending output. It does not return until all
pending output has been sent. You should use this call with care. Flow
control (documented below) can make your system hang on this call in a
tight uninterruptible loop under the right circumstances.
AH = 09h Purge output buffer
Parameters:
Entry: DX = Port number
Exit: None
This is used to purge any pending output. Any output data remaining in
the output buffer (not transmitted yet) is discarded.
AH = 0Ah Purge input buffer
Parameters:
Entry: DX = Port number
Exit: None
This is used to purge any pending input. Any input data which is still
in the buffer is discarded.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 8
AH = 0Bh Transmit no wait
Parameters:
Entry: DX = Port number
Exit: AX = 0001h - Character was accepted
= 0000h - Character was not accepted
This is exactly the same as the "regular" transmit call, except that if
the driver is unable to buffer the character (the buffer is full), a
value of 0000h is returned in AX. If the driver accepts the character
(room is available), 0001h is returned in AX.
AH = 0Ch Non-destructive read-ahead
Parameters:
Entry: DX = Port number
Exit: AH = 00h - Character is
AL = Next character available
AX = FFFFh - Character is not available
Return in AL the next character in the receive buffer. If the receive
buffer is empty, return FFFFh. The character returned remains in
the receive buffer. Some applications call this "peek".
AH = 0Dh Keyboard read without wait
Parameters:
Entry: None
Exit: AX = IBM-style scan code (Character available)
= FFFFh (Character not available)
Return in AX the next character (non-destructive read ahead) from the
keyboard; if nothing is currently in the keyboard buffer, return FFFFh in
AX. Use IBM-style function key mapping in the high order byte. Scan
codes for non-"function" keys are not specifically required, but may be
included. Function keys return 00h in AL and the "scan code" in AH.
AH = 0Eh Keyboard read with wait
Parameters:
Entry: None
Exit: AX = IBM-style scan code
Return in AX the next character from the keyboard; wait if no character
is available. Keyboard mapping should be the same as function 0Dh.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 9
AH = 0Fh Enable or disable flow control
Parameters:
Entry: AL = Bit mask describing requested flow control
DX = Port number
Exit: None
TRANSMIT flow control allows the "other end" to restrain the transmitter
when you are over-running it. RECEIVE flow control tells the FOSSIL to
attempt to do just that if it is being overwhelmed.
Two kinds of basic flow control are supported:
Bit 0 = 1 Xon/Xoff on transmit
Bit 1 = 1 CTS/RTS (CTS on transmit, RTS on receive)
Bit 2 Reserved
| Bit 3 = 1 Xon/Xoff on Receive
Flow control is enabled, or disabled, by setting the appropriate bits in
AL for the types of flow control we want to ENABLE (value = 1), and/or
DISABLE (value = 0), and calling this function. Bit 2 is reserved for
DSR/DTR, but is not currently supported in any implementation.
Enabling transmit Xon/Xoff will cause the FOSSIL to stop transmitting
upon receiving an Xoff. The FOSSIL will resume transmitting when an Xon
is received.
Enabling CTS/RTS will cause the FOSSIL to cease transmitting when CTS is
lowered. Transmission will resume when CTS is raised. The FOSSIL will
drop RTS when the receive buffer reaches a predetermined percentage full
The FOSSIL will raise RTS when the receive buffer empties below the
predetermined percentage full. The point(s) at which this occurs is
left to the individual FOSSIL implementor.
| Enabling receive Xon/Xoff will cause the FOSSIL to send a Xoff when the
| receive buffer reaches a pre-determined percentage full. An Xon will be
| sent when the receive buffer empties below the pre-determined percentage
| full. The point(s) at which this occurs is left to the individual FOSSIL
| implementor.
Applications using this function should set all bits ON in the high
nibble of AL as well. There is a compatible (but not identical) FOSSIL
driver implementation that uses the high nibble as a control mask. If
your application sets the high nibble to all ones, it will always work,
regardless of the method used by any given driver.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 10
AH = 10h Extended Control-C / Control-K checking and transmit on/off
Parameters:
Entry: AL = Bit mask (see below)
DX = Port number
Exit: AX = 0001h - Control-C/K has been received
= 0000h - Control-C/K has not been received
This is used for BBS operation, primarily. A bit mask is passed in AL
with the following flags:
Bit 0 Enable/disable Control-C / Control-K checking
Bit 1 Disable/enable the transmitter
The Enable (bit 0 = 1) and Disable (Bit 0 = 0) Control-C/Control-K check
function is meant primarily for BBS use. When the checking is enabled, a
Control-C or Control-K received from the communications port will set a
flag internal to the FOSSIL driver, but will not be stored in the input
buffer. The next use of this function will return the value of this flag
in register AX then clear the flag for the next occurrence. The returned
value is used by the BBS software to determine whether output should be
halted or not.
The Disable (Bit 1 = 1) and Enable (Bit 1 = 0) Transmitter function lets
the application restrain the asynchronous driver from output in much the
same way as XON/XOFF would.
AH = 11h Set current cursor location.
Parameters:
Entry: DH = Row (line)
DL = Column
Exit: None
This function looks exactly like like INT 10h, subfunction 2, on the IBM
PC. The cursor location is passed in DX: row in DH and column in DL. The
function treats the screen as a coordinate system whose origin (0,0) is
the upper left hand corner of the screen.
AH = 12h Read current cursor location.
Parameters:
Entry: None
Exit: DH = Row (line)
DL = Column
Looks exactly like INT 10h, subfunction 3, on the IBM PC. The current
cursor location (using the same coordinate system as function 16h) is
passed back in DX.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 11
AH = 13h Single character ANSI write to screen.
Parameters:
Entry: AL = Character to display
Exit: None
The character in AL is sent to the screen by the fastest method possible
that allows ANSI processing to occur (if available). This routine should
not be used in such a way that DOS output (which is not re-entrant) can
not be employed by some FOSSIL driver to perform the function (in fact,
on the IBM PC that is likely to be how it's done). On some systems such
as the DEC Rainbow this will be a very fast method of screen writing.
AH = 14h Enable or disable watchdog processing
Parameters:
Entry: AL = 01h - Enable watchdog
= 00h - Disable watchdog
DX = Port number
Exit: None
When watchdog is enabled, the state of the carrier detect (CD) line on
the comm port specified in DX should be constantly monitored. Should the
state of that line become FALSE (carrier lost), the system should be re-
booted, to enable the BBS (or other application) to start up again. This
monitor is not affected by Init/Uninit etc.
AH = 15h Write character to screen using BIOS support routines
Parameters:
Entry: AL = Character to display
Exit: None
The character in AL is sent to the screen using BIOS-level Input/Output
routines. This differs from function 13h in that DOS I/O CAN NOT be used,
as this function might be called from driver level.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 12
AH = 16h Insert or delete a function from the timer tick chain
Parameter:
Entry: AL = 01h - Add a function
= 00h - Delete a function
| ES = Segment of function
DX = Offset of function
Exit: AX = 0000h - Operation successful
= FFFFh - Operation unsuccessful
This function is used to allow a central authority to manage the timer
interrupts, so that as code is loaded and unloaded, the integrity of the
"chain" is not compromised. Rather than using the traditional method of
saving the old contents of the timer vector, storing the address of your
routine there, and executing a far call to the "old" routine when yours
is done, instead you call this function. It manages a list of such entry
points and calls them on a timer tick (interrupt) using a FAR call. All
the usual cautions about making DOS calls apply (that is, DON'T!).
This makes it possible for a program to get in and out of the tick chain
without having to know whether another program has also done so since it
first insinuated itself. At least 4 entries should be available in the
driver's table (including one to be used by Watchdog if implemented that
way).
AH = 17h Reboot system
Parameters:
Entry: AL = 00h - "Cold boot"
= 01h - "Warm boot"
Perform the old 3-finger salute. Used in extreme emergency by code that
can't seem to find a "clean" way out of the trouble it has gotten itself
into. Hopefully it won't happen while you're computing something in the
other half of a DoubleDOS system. If your machine can make a distinction
between a "cold" (power-up, self-test and boot) and a "warm" (just boot)
bootstrap, your FOSSIL should support the flag in AL. Otherwise just do
whatever bootstrap is possible.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 13
| AH = 18h Read block (transfer from FOSSIL to user buffer)
| Parameters:
| Entry: CX = Maximum number of characters to transfer
| DX = Port number
| ES = Segment of user buffer
| DI = Offset into ES of user buffer
| Exit: AX = Number of characters actually transferred
| A "no-wait" block read of 0 to FFFFh characters from the FOSSIL inbound
| ring buffer to the calling routine's buffer. ES:DI are left unchanged by
| the call; the count of bytes actually transferred will be returned in AX.
| AH = 19h Write block (transfer from user buffer to FOSSIL)
| Parameters:
| Entry: CX = Maximum number of characters to transfer
| DX = Port number
| ES = Segment of user buffer
| DI = Offset into ES of user buffer
| Exit: AX = Number of characters actually transferred
| A "no-wait" block move of 0 to FFFFh characters from the calling
| program's buffer into the FOSSIL outbound ring buffer. ES:DI are left
| unchanged by the call; the count of bytes actually transferred will be
| returned in AX.
| AH = 1Ah Break begin or end
| Parameters:
| Entry: AL = 01h - Start sending 'break'
= 00h - Stop sending 'break'
| DX = port number
| Exit: None
| Send a break signal to the modem. If AL=01h the driver will commence the
| transmission of a break. If AL=00h the driver will end the break. This
| is useful for communications with devices that can only go into 'command
| mode' when a BREAK is received. Note: the application is responsible for
| the timing of the BREAK. Also, if the FOSSIL has been restrained by an
| Xoff received from the modem, the flag will be cleared. An Init or Un-
| Init will stop an in-progress BREAK.
Fundamentals of FOSSIL implementation and use FSC-0015
Communications functions Page 14
| AH = 1Bh Return information about the driver
| Parameters:
| Entry: CX = Size of user info buffer in bytes
| DX = Port number
| ES = Segment of user info buffer
| DI = Offset into ES of user info buffer
| Exit: AX = Number of bytes actually transferred
| Transfer information about the driver and its current status to the user
| for use in determining, at the application level, limits of the driver.
| Designed to assist "generic" applications to adjust to "foreign" gear.
| The data structure currently returned by the driver is as follows (sorry
| but you'll have to live with assembly syntax):
| info equ $ ; define begin of structure
| strsiz dw info_size ; size of the structure in bytes
| majver db curr_fossil ; FOSSIL spec driver conforms to
| minver db curr_rev ; rev level of this specific driver
| ident dd id_string ; "FAR" pointer to ASCII ID string
| ibufr dw ibsize ; size of the input buffer (bytes)
| ifree dw ? ; number of bytes left in buffer
| obufr dw obsize ; size of the output buffer (bytes)
| ofree dw ? ; number of bytes left in the buffer
| swidth db screen_width ; width of screen on this adapter
| sheight db screen_height ; height of screen " "
| baud db ? ; ACTUAL baud rate, computer to modem
| info_size equ $-info
| The ident string should be null-terminated, and NOT contain a newline.
| The baud rate byte contains the bits that Function 00h would use to set
| the port to that speed.
| The fields related to a particular port (buffer size, space left in the
| buffer, baud rate) will be undefined if port FFh or an invalid port is
| contained in DX.
| Additional information will always be passed after these, so that, for
| example, offset "sheight" will never change with FOSSIL revision changes.
Fundamentals of FOSSIL implementation and use FSC-0015
"Layered Application" services Page 15
| The functions below are not necessarily FOSSIL related. However, because
| dispatchers that support them are hooked on Interrupt 14H, it behooves
| the FOSSIL developer to support them as well to avoid fragmenting memory
| with several dispatchers.
| AH = 7Eh Install an "external application" function
| Parameters:
| Entry: AL = Code assigned to external application
| DX = Offset of application entry point
| ES = Segment of application entry point
| Exit: AX = 1954h
| BL = Code assigned to application (same as input AL)
| BH = 01h - Installation was successful
| = 00h - Installation failed
| This call is used by external application code (special screen drivers,
| modem code, database code, etc) to link into the INT 14h service for use
| by multiple applications. The "error return" (BH=0 with AX=1954h) should
| mean that another application layer has already been installed at that
| particular code. Codes 80h through BFh should be supported.
| External application codes 80h-83h are reserved by FOSSIL developers for
| re-organizing FOSSIL services by type (comm, screen, keyboard, system).
| Installed application code will be entered, via a FAR call, from the INT
| 14H dispatcher whenever it is entered with AH=(application code).
| If the value returned in AX from this function is not 1954h, the service
| code that is trying to be installed should bring up its own INT 14h code
| that can service INT 14h functions 7h-BFh (80h-BFh are "applications").
| AH = 7Fh Remove an "external application" function
| Parameters:
| Entry: AL = Code assigned to external application
| DX = Offset of application entry point
| ES = Segment of application entry point
| Exit: AX = 1954h
| BL = Code assigned to application (same as input AL)
| BH = 01h - Removal was successful
| = 00h - Removal failed
| Removes an application's entry into the table. Usually so it can remove
| itself from memory. Error return means ES:DX did not match or that there
| is no entry at the slot described by AL.
| An application that wants to remove itself from memory can issue the 7F
| function to remove itself from the table, then, if it is successful, get
| out of memory. If it had to install itself with an INT 14h dispatcher it
| may back itself out, provided no other applications have been installed
| on top of it (using its dispatcher).
Fundamentals of FOSSIL implementation and use FSC-0015
Page 16
E. Validation Suite.
Well, there is one, but it's involved. Here is a list of software that
is known to use FOSSIL calls, and the range of calls used by that
software:
Software package Fossil calls used
Fido, V11w, generic version 00h - 07h
SEAdog, V4.1b 00h - 0Eh
Opus, V1.03a 00h - 17h
BinkleyTerm, V1.30 00h - 1Bh
While there is certainly no guarantee that your FOSSIL is bug-free if
all the above software runs with it, you have probably done as much
as you can in a test environment if your FOSSIL is tested with each of
these packages.
F. Technical Discussion.
A FOSSIL echomail conference exists, for the purpose of exchanging info
and implementation details for FOSSIL drivers. It is coordinated by Ray
Gwinn at FidoNet node 1:109/639. Contact him for details on how to join.
Keep in mind though, that this conference is intended SPECIFICALLY for
implementors of FOSSIL software and not as a general Q&A conference for
people who think FOSSILs have something to do with paleontology.
G. Distribution Of This Document.
This document may be distribute freely as long as it is not modified in
any way. Please list all changes and deviations in a given FOSSIL
implementation in an addendum contained in a separate file added to the
FOSSIL archive. Also, please do not distribute this document without
the accompanying version of FOSSIL.CHT. This will help avoid confusion,
among both FOSSIL implementors and application developers.

47
FOSSIL.HPP Normal file
View File

@ -0,0 +1,47 @@
typedef unsigned FOS_STATUS;
#define FSTAT_BUFEMPTY 0x4000 // output buffer empty
#define FSTAT_NOTFULL 0x2000 // output buffer NOT full
#define FSTAT_OVERRUN 0x0200 // input buffer overrun
#define FSTAT_AVAIL 0x0100 // input available
#define FSTAT_CARRIER 0x0080 // carrier detected
extern "C"
{
FOS_STATUS fos_setbps (int port,byte baudcode); // set baudrate
FOS_STATUS fos_status (int port); // get fossil-status
void fos_init (int port); // initialize fossil
void fos_deinit (int port); // deinitialize fossil
void fos_setdtr (int port,char dtr); // set DTR on(1)/off(0)
void fos_purgeoutput (int port); // purge output buffer
void fos_purgeinput (int port); // purge input buffer
void fos_flowctl (int port,byte ctl); // set flow control (CTS/RTS)
bool fos_sendnw (int port,byte ch); // send char without wait (1=sent,0=not sent)
FOS_STATUS fos_send (int port,byte ch); // send char with wait
int fos_getchnw (int port); // get char without wait (-1 when none available)
byte fos_getch (int port); // get char with wait
byte fos_break (int port,bool mode); // Start/Stop sending break
word fos_sendblock (int port,byte *buf,word size);
word fos_readblock (int port,byte *buf,word size);
}
#define fos_byteready(port) (fos_status(port) & FSTAT_AVAIL)
#define fos_outputempty(port) (fos_status(port) & FSTAT_BUFEMPTY)
#define fos_carrier(port) (fos_status(port) & FSTAT_CARRIER)
#define status_byteready(stat) ((stat) & FSTAT_AVAIL)
#define status_outputempty(stat) ((stat) & FSTAT_BUFEMPTY)
#define status_carrier(stat) ((stat) & FSTAT_CARRIER)
/*
static void
fos_sendbreak(int port)
{
fos_break(port,TRUE);
unsigned long ticks = clockticks();
while(clockdiff(ticks)<2) {}
fos_break(port,FALSE);
}
*/

BIN
FOSSIL.OBJ Normal file

Binary file not shown.

135
FUZZY.CPP Normal file
View File

@ -0,0 +1,135 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* local, static data */
static char *Text, *Pattern; /* pointers to search strings */
static int Textloc; /* current search position in Text */
static int Plen; /* length of Pattern */
static int Degree; /* max degree of allowed mismatch */
static int *Ldiff, *Rdiff; /* dynamic difference arrays */
static int *Loff, *Roff; /* used to calculate start of match */
static int *allocated;
static void near
App_init(char *pattern, char *text, int degree)
{
int i;
/* save parameters */
Text = text;
Pattern = pattern;
Degree = degree;
/* initialize */
Plen = strlen(pattern);
Ldiff = allocated = (int *) malloc(sizeof(int) * (Plen + 1) * 4);
Rdiff = Ldiff + Plen + 1;
Loff = Rdiff + Plen + 1;
Roff = Loff + Plen + 1;
for(i = 0; i <= Plen; i++)
{
Rdiff[i] = i; /* initial values for right-hand column */
Roff[i] = 1;
}
Textloc = -1; /* current offset into Text */
}
static void near
App_next(char **start, char **end, int *howclose)
{
int *temp, a, b, c, i;
*start = NULL;
while (*start == NULL) { /* start computing columns */
if (Text[++Textloc] == '\0') /* out of text to search! */
break;
temp = Rdiff; /* move right-hand column to left ... */
Rdiff = Ldiff; /* ... so that we can compute new ... */
Ldiff = temp; /* ... right-hand column */
Rdiff[0] = 0; /* top (boundary) row */
temp = Roff; /* and swap offset arrays, too */
Roff = Loff;
Loff = temp;
Roff[1] = 0;
for (i = 0; i < Plen; i++) { /* run through pattern */
/* compute a, b, & c as the three adjacent cells ... */
if (toupper(Pattern[i]) == toupper(Text[Textloc]))
a = Ldiff[i];
else
a = Ldiff[i] + 1;
b = Ldiff[i+1] + 1;
c = Rdiff[i] + 1;
/* ... now pick minimum ... */
if (b < a)
a = b;
if (c < a)
a = c;
/* ... and store */
Rdiff[i+1] = a;
}
/* now update offset array */
/* the values in the offset arrays are added to the
current location to determine the beginning of the
mismatched substring. (see text for details) */
if (Plen > 1) for (i=2; i<=Plen; i++) {
if (Ldiff[i-1] < Rdiff[i])
Roff[i] = Loff[i-1] - 1;
else if (Rdiff[i-1] < Rdiff[i])
Roff[i] = Roff[i-1];
else if (Ldiff[i] < Rdiff[i])
Roff[i] = Loff[i] - 1;
else /* Ldiff[i-1] == Rdiff[i] */
Roff[i] = Loff[i-1] - 1;
}
/* now, do we have an approximate match? */
if (Rdiff[Plen] <= Degree) { /* indeed so! */
*end = Text + Textloc;
*start = *end + Roff[Plen];
*howclose = Rdiff[Plen];
}
}
}
void
App_End()
{
free(allocated);
}
int
fuzzy_search(char *pattern,char *text,int degree)
{
int min = 0x7FFF;
int howclose;
char *begin,*end;
degree = strlen(pattern)*(100-degree)/100;
App_init(pattern , text , degree);
App_next(&begin, &end, &howclose);
while(begin)
{
if(howclose<min) min = howclose;
App_next(&begin, &end, &howclose);
}
App_End();
if(min<=degree) return (strlen(pattern)-degree)*100/strlen(pattern);
else return -1;
}

BIN
FUZZY.OBJ Normal file

Binary file not shown.

BIN
FUZZY2.OBJ Normal file

Binary file not shown.

83
GIF.CPP Normal file
View File

@ -0,0 +1,83 @@
#include <string.h>
#include "proboard.hpp"
struct gif_header
{
char sign[6];
word xres;
word yres;
word colorbits : 3;
sword dummy : 5;
};
void
view_gif(char *data)
{
char gifname[13];
io << "\f\n" << S_SHOW_GIF_INFO_TITLE_AND_PROMPT;
io.read(gifname,12,READMODE_UPALL);
if(!gifname[0]) return;
String param[40];
BitArray arealist(MAX_FILE_AREAS,1);
int npara = parse_data(data,param);
create_arealist(param,npara,arealist);
FileArea fa;
io << form("\n\n\7 矬闡闡闡闡闡闡鐃闡闡闡闡闡闡薩闡闡闡醴\n"
" 許3 %-13.13s\7許3 %-11.11s\7許3 %-7.7s\7許n"
" ⼳迋迋迋迋迋迋阹迋迋迋迋迋迋媏迋迋迋芚\n",
S_SHOW_GIF_FILENAME ,
S_SHOW_GIF_RESOLUTION ,
S_SHOW_GIF_COLORS );
linecounter(2);
stopped=0;
io.enablestop();
for(int i=1;i<=FileArea::highAreaNum();i++)
{
if(!arealist[i] || !fa.read(i) || !check_access(fa.level,fa.flags,fa.flagsNot)) continue;
String fname(fa.filepath);
fname << gifname;
DirScan f(fname);
while(int(f))
{
File fil;
if(fil.open(FileName(fa.filepath,f.name())))
{
gif_header gif;
fil.read(&gif,sizeof(gif));
if(!strncmp(gif.sign,"GIF",3))
{
io << form(" <20> \3%-12s\7 <20>",f.name());
io << form("\6 %4d x %3d \7許2 %3d \7許n",gif.xres,gif.yres,1 << (gif.colorbits+1));
if(stopped || linecounter())
{
i = FileArea::highAreaNum();
break;
}
}
}
++f;
}
}
if(!stopped)
io << " 奜迋迋迋迋迋迋迍迋迋迋迋迋迋玵迋迋迋芴\n\n"
<< S_PRESS_ENTER_TO_CONTINUE;
}

BIN
GIF.OBJ Normal file

Binary file not shown.

7
HANDLER.CPP Normal file
View File

@ -0,0 +1,7 @@
#define Use_Handlers
#define Use_LinkedList
#include "proboard.hpp"
LinkedList<PEXhandle> sysopkey_handlers;
LinkedList<PEXhandle> hangup_handlers;

BIN
HANDLER.OBJ Normal file

Binary file not shown.

354
HELP.CPP Normal file
View File

@ -0,0 +1,354 @@
#include <tswin.hpp>
#include "proboard.hpp"
#define HELP 1
#define USER 2
#define MACRO 3
static int status = 0;
static Window win;
static int WINSIZE;
static
void near show()
{
int maxx = SCREEN.maxX;
word *buf = new word[ tsw_vsize * maxx ];
int x = SCREEN.getX();
int cursorline = SCREEN.getY();
int caplines = ( cursorline > tsw_vsize - ( WINSIZE + 2 ) )
? tsw_vsize - ( WINSIZE + 2 )
: cursorline;
tsw_gettext( buf,
1,
cursorline - caplines + 1,
maxx,
cursorline + 1 );
if ( cursorline > tsw_vsize - ( WINSIZE + 2 ) )
{
cursorline = tsw_vsize - ( WINSIZE + 2 );
}
byte att = SCREEN.attrib();
SCREEN.attrib( 7 );
SCREEN.clear();
SCREEN.change( 1,
1,
maxx,
tsw_vsize - ( WINSIZE + 1 ) );
tsw_puttext( buf,
1,
1,
maxx,
caplines );
// win.open( 1,
// tsw_vsize - WINSIZE,
// maxx,
// tsw_vsize - 1,
// 0x17,
// 0,
// SINGLE_BORDER );
win.open( 1,
tsw_vsize - WINSIZE,
maxx,
tsw_vsize - 1,
0x70,
0,
CHISEL_BORDER,
0x7F,
NULL,
0x78 );
SCREEN.setPos( x, cursorline );
SCREEN.attrib( att );
delete [] buf;
}
static
void near hide()
{
int maxx = SCREEN.maxX;
win.close();
word *buf = new word[ tsw_vsize * maxx ];
tsw_gettext( buf,
1,
1,
maxx,
tsw_vsize - ( WINSIZE + 1 ) );
byte att = SCREEN.attrib();
SCREEN.saveCursor();
SCREEN.attrib( 7 );
SCREEN.change( 1,
1,
maxx,
tsw_vsize - 1 );
SCREEN.clear();
SCREEN.restoreCursor();
SCREEN.attrib( att );
tsw_puttext( buf,
1,
1,
maxx,
tsw_vsize - ( WINSIZE + 1 ) );
delete [] buf;
}
void toggle_userinfo()
{
// if ( user_recnr < 0 )
// {
// return;
// }
//
//
// switch ( status )
// {
// case USER:
//
// hide();
//
// status = 0;
//
// break;
//
//
// case 0:
//
// WINSIZE = 5;
//
// show();
//
//
// default:
//
// if ( WINSIZE != 5 )
// {
// hide();
//
// WINSIZE = 5;
//
// show();
// }
//
//
// win.clear();
//
// win.attrib( 0x17 );
//
// win << " Handle : Flags :\n"
// " # Calls : Last call:\n"
// " Downloads: Uploads :";
//
// win.attrib( 0x1F );
//
// win.setpos( 13, 1);
// win << user.alias;
//
//
// win.setpos( 45, 1 );
//
// char s[ 33 ];
//
// user.aflags.flagstostr( s );
//
// win << s;
//
//
// win.setpos( 13, 2 );
//
// win << form( "%d", user.timescalled );
//
//
// win.setpos( 45, 2 );
//
// win << form( "%02d %3s %04d at %02d:%02d:%02d",
// user.lastdate[ 0 ],
// months_short[ user.lastdate[ 1 ] ],
// user.lastdate[ 2 ] + 1900, // Y2K FIX!
// user.lasttime[ 0 ],
// user.lasttime[ 1 ],
// user.lasttime[ 2 ] );
//
//
// win.setpos( 13, 3 );
//
// win << form( "%d (%d Kb)",
// user.numdownloads,
// user.kdownloaded );
//
//
// win.setpos( 45, 3 );
//
// win << form( "%d (%d Kb)",
// user.numuploads,
// user.kuploaded );
//
//
// SCREEN.setpos( SCREEN.getx(),
// SCREEN.gety() );
//
// status = USER;
//
// break;
// };
}
void toggle_help()
{
switch ( status )
{
case HELP:
hide();
status = 0;
break;
case 0:
WINSIZE = 7;
show();
default:
if ( WINSIZE != 7 )
{
hide();
WINSIZE = 7;
show();
}
win.clear();
win.attrib( 0x71 );
win << " [ShF1] Macro Help [AltM] Edit Current Menu [AltS] Static\n"
" [AltC] Chat [AltE] Edit User [AltH] Hang Up\n"
" [AltI] Image [AltJ] DOS Shell [AltL] Lock Out\n"
" [AltR] Reset Chat [Ctrl-Lt/Rt] Level [Up/Dn] Timer\n"
" [Home] Reset Status [F2-F10] Status [PgUp/PgDn] Cycle status";
SCREEN.setPos( SCREEN.getX(),
SCREEN.getY() );
status = HELP;
break;
}
}
void toggle_macrohelp()
{
switch ( status )
{
case MACRO:
hide();
status = 0;
break;
case 0:
WINSIZE = 7;
show();
default:
if ( WINSIZE != 7 )
{
hide();
WINSIZE = 7;
show();
}
win.clear();
for ( int i = 0; i < 10; i++ )
{
win.setPos( ( i / 5 ) * 38 + 2,
i % 5 + 1 );
//----------------------------
// JDR: REGISTRATION REFERENCE
//----------------------------
if ( registered )
{
win << form( "AF%-2d - %-27.27s",
i + 1,
cfg.sysopkeys[ i ] );
}
else
{
win << form( "AF%-2d - %-27.27s",
i + 1,
"REGISTER NOW!" );
}
}
SCREEN.setPos( SCREEN.getX(),
SCREEN.getY() );
status = MACRO;
break;
}
}

BIN
HELP.OBJ Normal file

Binary file not shown.

1429
HUDSON.CPP Normal file

File diff suppressed because it is too large Load Diff

BIN
HUDSON.OBJ Normal file

Binary file not shown.

41
IMAGE.CPP Normal file
View File

@ -0,0 +1,41 @@
#include <stdio.h>
#include "proboard.hpp"
#include <tswin.hpp>
void
screen_image()
{
File fp(form("%sIMAGE.TXT",syspath),fmode_write |
fmode_text |
fmode_copen |
fmode_append );
if(!fp.opened()) return;
String line;
for(int y=SCREEN.minY;y<=SCREEN.maxY;y++)
{
int lastchar = 0;
line = "";
for(int x=SCREEN.minX;x<=SCREEN.maxX;x++)
{
char c = tsw_whaton(x,y);
if(c!=' ') lastchar = x-SCREEN.minX+1;
line << c;
}
line << "\n\n";
line[lastchar] = '\n';
line[lastchar+1] = '\0';
fp.printf("%s",(char *)line);
}
}

336
IMAGE.HPP Normal file
View File

@ -0,0 +1,336 @@
BYTE IMAGEDATA [] = {
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0C, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F,
'Ü', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'ú', 0x0C, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'Ü', 0x0F, 'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0C, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'Ü', 0x0F, 'ß', 0x7F, ' ', 0x7F, 'þ', 0x7E, ' ', 0x7E,
' ', 0x7E, 'þ', 0x7E, ' ', 0x7E, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ú', 0x0C, ' ', 0x0C, ' ', 0x0C, ' ', 0x0C,
' ', 0x0C, 'Ü', 0x0F, 'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F, 'Ü', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Ü', 0x0F,
'Ü', 0x0F, 'Û', 0x0F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Û', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F,
'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F,
'Û', 0x0F, 'Û', 0x0F, 'Û', 0x0F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Û', 0x0F, 'Û', 0x0F, 'Û', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F,
'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F, 'Ü', 0x0F,
'Ü', 0x0F, 'Ü', 0x0F, 'Û', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Û', 0x7F, 'Ü', 0x0F, 'Ü', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Ü', 0x0F,
'ß', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ú', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'Û', 0x0F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Û', 0x7F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0C, ' ', 0x0C, ' ', 0x0C,
'ß', 0x0F, 'ß', 0x0F, 'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F, ' ', 0x7F,
'þ', 0x7E, ' ', 0x7E, ' ', 0x7E, 'þ', 0x7E, ' ', 0x7E, ' ', 0x7E,
'Ü', 0x7F, 'ß', 0x0F, 'ß', 0x0F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0C, ' ', 0x0C, ' ', 0x0C, ' ', 0x0C, ' ', 0x0C, 'Ü', 0x0F,
'ß', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Ü', 0x7F,
' ', 0x7F, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0C, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ß', 0x0F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'ú', 0x0C, ' ', 0x0C, ' ', 0x0C, ' ', 0x0C, 'Ü', 0x0F,
'ß', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'ú', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ú', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F, 'ß', 0x7F,
'Ü', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'Û', 0x7F, 'ß', 0x7F, 'ß', 0x4F, 'ß', 0x7F,
'ß', 0x7F, 'ß', 0x4F, 'ß', 0x7F, 'Û', 0x7F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Ü', 0x0F,
'ß', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0F, ' ', 0x0F,
'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Û', 0x7F,
'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F, 'Û', 0x7F, 'ß', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Ü', 0x0F,
'ß', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, 'ú', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Ü', 0x7F,
' ', 0x7F, 'ß', 0x7F, 'Ü', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Ü', 0x0F,
'Ü', 0x0F, 'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F, 'ß', 0x7F,
'ß', 0x7F, 'Ü', 0x0F, 'Ü', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Ü', 0x0F,
'ß', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ú', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D,
' ', 0x0D, 'ú', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D,
'ú', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D, 'ú', 0x0D,
' ', 0x0D, ' ', 0x0D, ' ', 0x0D, 'ú', 0x0D, ' ', 0x0D, ' ', 0x0D,
' ', 0x0D, 'ú', 0x0D, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F, 'Û', 0x0F,
'ß', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F,
'Ü', 0x7F, 'Ü', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, 'ß', 0x7F,
'Û', 0x0F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0D, ' ', 0x0D,
' ', 0x0D, ' ', 0x0D, 'ú', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D,
'ú', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D, 'ú', 0x0D,
' ', 0x0D, ' ', 0x0D, ' ', 0x0D, ' ', 0x0D, 'ú', 0x0D, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'Û', 0x7F, ' ', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x3F, 'ß', 0x3F,
' ', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F, 'ß', 0x3F, 'ß', 0x3F,
'Ü', 0x7F, ' ', 0x7F, ' ', 0x7F, 'Û', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0E, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'Û', 0x0F, ' ', 0x7F, ' ', 0x7F, 'Û', 0x7F, ' ', 0x3F,
' ', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F,
' ', 0x3F, ' ', 0x3F, ' ', 0x3F, 'Û', 0x7F, ' ', 0x7F, ' ', 0x7F,
'Û', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'ú', 0x0E, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ú', 0x0E, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F,
'ß', 0x7F, 'Ü', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F,
' ', 0x3F, ' ', 0x3F, ' ', 0x3F, ' ', 0x3F, 'Ü', 0x3F, 'ß', 0x7F,
' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0E, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0E, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'ú', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B,
'ß', 0x0F, 'Ü', 0x7F, ' ', 0x7F, ' ', 0x7F, 'ß', 0x7F, 'ß', 0x7F,
'Ü', 0x3F, 'Ü', 0x3F, 'Ü', 0x3F, 'Ü', 0x3F, 'ß', 0x7F, 'ß', 0x7F,
' ', 0x7F, ' ', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, 'ú', 0x0B, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0E,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0E, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0B, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'Ü', 0x7F,
'Ü', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F, ' ', 0x7F,
' ', 0x7F, 'Ü', 0x7F, 'Ü', 0x7F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, 'ú', 0x0B, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0E, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ú', 0x0B,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'ß', 0x0F, 'ß', 0x0F, 'ß', 0x0F,
'ß', 0x0F, 'ß', 0x0F, 'ß', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
'ú', 0x0B, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0B, 'Ü', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, 'Ü', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Ü', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, 'Ü', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Ü', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ü', 0x0B, ' ', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ü', 0x0B,
' ', 0x0B, 'Þ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ý', 0x0B, ' ', 0x0B,
'Ü', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Ü', 0x0B, ' ', 0x0B, 'Ü', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B,
'Ü', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B,
' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B,
' ', 0x0B, 'Þ', 0x0B, 'Û', 0x0B, 'Ý', 0x0B, ' ', 0x0B, ' ', 0x0B,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B,
'Ü', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B,
' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B,
'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B,
'Ü', 0x0B, 'Ü', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Ü', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B, 'Ü', 0x0B, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'ß', 0x0B,
'ß', 0x0B, 'ß', 0x0B, 'ß', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B,
'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Þ', 0x0B, 'Û', 0x0B, 'Ý', 0x0B,
' ', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'ß', 0x0B,
'ß', 0x0B, 'ß', 0x0B, 'ß', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'ß', 0x0B, 'ß', 0x0B, 'ß', 0x0B,
'ß', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B,
'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B, 'ß', 0x0B,
'ß', 0x0B, 'ß', 0x0B, 'ß', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'ß', 0x0B, 'ß', 0x0B, 'ß', 0x0B, 'ß', 0x0B,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0B, 'ß', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B,
'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B, 'Þ', 0x0B,
'Û', 0x0B, 'Ý', 0x0B, ' ', 0x0B, ' ', 0x0B, ' ', 0x0B, 'ß', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, 'ß', 0x0B,
'Û', 0x0B, 'Û', 0x0B, ' ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, 'Û', 0x0B,
'Û', 0x0B, ' ', 0x0B, ' ', 0x0B, 'ß', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
' ', 0x0B, 'Þ', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Ý', 0x0B, ' ', 0x0B,
'ß', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'ß', 0x0B, ' ', 0x0B, 'ß', 0x0B, 'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B,
'Û', 0x0B, 'Û', 0x0B, 'Û', 0x0B, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F, ' ', 0x0F,
' ', 0x0F, ' ', 0x0F};

BIN
IMAGE.OBJ Normal file

Binary file not shown.

275
INPDATE.CPP Normal file
View File

@ -0,0 +1,275 @@
#include <ctype.h>
#include <tswin.hpp>
#include "proboard.hpp"
//----------------------------------------------------------------
//
// This table identifies where the slashes should be in the date
// strings. This supports each of the international date formats:
//
// MM/DD/YYYY
// YYYY/MM/DD
// DD/MM/YYYY
//
//----------------------------------------------------------------
static
const char piSlashColumns[ 3 ] [ 2 ] =
{
{ 2, 5 },
{ 4, 7 },
{ 2, 5 },
};
//**************************************************************************
//
// Input a date value from the user
//
// Prototype: void InputDate( Date &d );
//
// Parameters: d ... Date variable to fill-in
// iDateFormat ... Format of date to be entered
//
// Returns: None
//
// Remarks:
//
// This code has to be changed to support the various international formats:
//
// MM/DD/YYYY
// YYYY/MM/DD
// DD/MM/YYYY
//
// -------------------------------------------------------------------------
//
// Created on: ??/??/?? (Philippe Leybaert)
// Last modified: 06/17/99 (Jeff Reeder)
//
//**************************************************************************
void InputDate( Date &d,
byte iDateFormat ) // JDR: Added
{
char s[ MAX_DATE_FIELD_SIZE + 1 ];
byte k;
//-------------------------------------------
// Show a MAX_DATE_FIELD_SIZE-character field
//-------------------------------------------
io.drawfield( MAX_DATE_FIELD_SIZE );
int i = 0;
//------------------------------
// Keep looping until we're done
//------------------------------
loop
{
//-------------------------------------
// Wait until the user enters something
//-------------------------------------
k = io.wait();
//-----------------
// What do we have?
//-----------------
if (
(
! isdigit( k ) and
k != CR and
k != BS
)
or k > 0x7F // This check isn't needed, but better safe
)
{
//----------------------------------------------
// If it's not a digit, CR or a BS, we ignore it
//----------------------------------------------
continue;
}
if ( k == BS )
{
//----------------------------------
// We got a backspace (BS) character
//----------------------------------
if ( i > 0 )
{
//-------------------------------------
// We have characters to backspace over
//-------------------------------------
i--;
//-------------------------------------------
// Erase the previous character - destructive
// backspace just to be on the cautious side.
//-------------------------------------------
io << "\b \b";
if ( i == piSlashColumns[ iDateFormat ][ 0 ] or
i == piSlashColumns[ iDateFormat ][ 1 ] )
{
//-----------------------------------------
// We ran over a slash/delimiter. Erase it
//-----------------------------------------
i--;
io << "\b \b";
}
}
continue;
}
if ( k == CR )
{
if ( i == 0 )
{
//-------------------------------------
// We haven't entered anything. Choose
// the default date, Jan 1, 1900
//-------------------------------------
d.set( 0, 0, 0 );
break;
}
if ( i != MAX_DATE_FIELD_SIZE )
{
//----------------------------------------------------
// We haven't maxed out our field size. Ignore the CR
//----------------------------------------------------
continue;
}
else
{
//-----------------------------------------
// We have filled our date field. Let's
// parse the date information appropriately
//-----------------------------------------
parse_date( d,
s,
user.dateFormat );
if ( d.ok() )
{
//-------------------------------------------------
// The date has legitimate values. Alright to quit
//-------------------------------------------------
break;
}
else
{
//--------------------------------------------
// The data was bogus. Keep reading more data
//--------------------------------------------
continue;
}
}
}
if ( i == MAX_DATE_FIELD_SIZE )
{
//-----------------------------------------------
// We're at the maximum field size. Ignore input
//-----------------------------------------------
continue;
}
//-----------------------------------------------------------
// Assign the current character at the current input position
//-----------------------------------------------------------
s[ i++ ] = k;
//-----------------------------
// Output the current character
//-----------------------------
io << k;
if ( i == piSlashColumns[ iDateFormat ][ 0 ] or
i == piSlashColumns[ iDateFormat ][ 1 ] )
{
//---------------------------------------------------
// We've moved to a slash position. Insert the slash
// automatically, and move to the next digit location
//---------------------------------------------------
s[ i++ ] = '/';
io << '/';
}
}
//------------------------------------------------------------
// We're all done with our date. Output a carriage return and
// make sure our buffer is NUL terminated before continuing.
//------------------------------------------------------------
io << '\r';
s[ i ] = '\0';
if ( avatar )
{
//---------------------------------------------------------------
// We're in Avatar mode. Reset our screen attributes accordingly
//---------------------------------------------------------------
io << char( 22 )
<< char( 1 )
<< char( SCREEN.attrib() & 0x0F );
}
else if ( ansi_mode )
{
//-------------------------------------------------------------
// We're in ANSI mode. Make sure we reset the background color
//-------------------------------------------------------------
io << "\x1b[40m";
}
//-------------------------------------
// Flush all output to the user's modem
//-------------------------------------
io.flush();
}

BIN
INPDATE.OBJ Normal file

Binary file not shown.

1065
IO.CPP Normal file

File diff suppressed because it is too large Load Diff

BIN
IO.OBJ Normal file

Binary file not shown.

1002
JAM.CPP Normal file

File diff suppressed because it is too large Load Diff

127
JAM.HPP Normal file
View File

@ -0,0 +1,127 @@
const dword JAM_SIGNATURE = 0x004D414ALU;
struct JamFileHeader
{
dword signature;
dword dateCreated;
dword modCounter;
dword activeMsgs;
dword passwordCrc;
dword baseMsgNum;
byte reserved[1000];
};
struct JamHeader
{
dword signature;
word revision;
word reserved;
dword subFieldLen;
dword timesRead;
dword msgidCrc;
dword replyCrc;
dword replyTo;
dword reply1St;
dword replyNext;
dword dateWritten;
dword dateReceived;
dword dateProcessed;
dword messageNumber;
dword attribute;
dword attribute2;
dword offset;
dword txtLen;
dword passwordCrc;
dword cost;
};
struct JamExtHeader
{
int fromZone;
int fromNet;
int fromNode;
int fromPoint;
int toZone;
int toNet;
int toNode;
int toPoint;
char from[36];
char to[36];
char subject[72];
char pid[80];
};
struct JamSubField
{
word loId;
word hiId;
dword datLen;
};
struct JamIndex
{
dword crc32;
dword offset;
};
struct JamLastRead
{
dword userCrc;
dword userId;
dword lastReadMsg;
dword highReadMsg;
};
const word JAMID_OADDRESS = 0;
const word JAMID_DADDRESS = 1;
const word JAMID_SENDERNAME = 2;
const word JAMID_RECEIVERNAME = 3;
const word JAMID_MSGID = 4;
const word JAMID_REPLYID = 5;
const word JAMID_SUBJECT = 6;
const word JAMID_PID = 7;
const word JAMID_TRACE = 8;
const word JAMID_ENCLOSEDFILE = 9;
const word JAMID_ENCLOSEDFILEWALIAS = 10;
const word JAMID_ENCLOSEDFREQ = 11;
const word JAMID_ENCLOSEDFILEWCARD = 12;
const word JAMID_ENCLOSEDINDIRECTFILE= 13;
const word JAMID_EMBINDAT = 1000;
const word JAMID_FTSKLUDGE = 2000;
const word JAMID_SEENBY2D = 2001;
const word JAMID_PATH2D = 2002;
const word JAMID_FLAGS = 2003;
const word JAMID_TZUTCINFO = 2004;
const dword JAM_MSG_LOCAL = 0x00000001L;
const dword JAM_MSG_INTRANSIT = 0x00000002L;
const dword JAM_MSG_PRIVATE = 0x00000004L;
const dword JAM_MSG_READ = 0x00000008L;
const dword JAM_MSG_SENT = 0x00000010L;
const dword JAM_MSG_KILLSENT = 0x00000020L;
const dword JAM_MSG_ARCHIVESENT = 0x00000040L;
const dword JAM_MSG_HOLD = 0x00000080L;
const dword JAM_MSG_CRASH = 0x00000100L;
const dword JAM_MSG_IMMEDIATE = 0x00000200L;
const dword JAM_MSG_DIRECT = 0x00000400L;
const dword JAM_MSG_GATE = 0x00000800L;
const dword JAM_MSG_FILEREQUEST = 0x00001000L;
const dword JAM_MSG_FILEATTACH = 0x00002000L;
const dword JAM_MSG_TRUNCFILE = 0x00004000L;
const dword JAM_MSG_KILLFILE = 0x00008000L;
const dword JAM_MSG_RECEIPTREQ = 0x00010000L;
const dword JAM_MSG_CONFIRMREQ = 0x00020000L;
const dword JAM_MSG_ORPHAN = 0x00040000L;
const dword JAM_MSG_ENCRYPT = 0x00080000L;
const dword JAM_MSG_COMPRESS = 0x00100000L;
const dword JAM_MSG_ESCAPED = 0x00200000L;
const dword JAM_MSG_FPU = 0x00400000L;
const dword JAM_MSG_TYPELOCAL = 0x00800000L;
const dword JAM_MSG_TYPEECHO = 0x01000000L;
const dword JAM_MSG_TYPENET = 0x02000000L;
const dword JAM_MSG_NODISP = 0x20000000L;
const dword JAM_MSG_LOCKED = 0x40000000L;
const dword JAM_MSG_DELETED = 0x80000000L;

BIN
JAM.OBJ Normal file

Binary file not shown.

286
LANGUAGE.CPP Normal file
View File

@ -0,0 +1,286 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "proboard.hpp"
LanguageFile pb_curlang;
LanguageString *pb_lang;
int pb_num_lang = 0;
static void
KillLanguage()
{
if(pb_lang)
{
delete [] pb_lang;
}
pb_lang = NULL;
pb_num_lang = 0;
}
bool
ReadLanguage( char *langname )
{
if(langname == NULL)
{
KillLanguage();
return FALSE;
}
FileName fn(syspath , langname , ".PBL");
File f;
if(!f.open(fn , fmode_read , 4096))
{
LOG("ERROR: Unable to read language file %s",(char *)fn);
return FALSE;
}
if(f.read(&pb_curlang , sizeof(LanguageFile)) != sizeof(LanguageFile))
{
LOG("Error reading language file <%s>" , (char *)fn);
return FALSE;
}
if(strlen(pb_curlang.menuPath) < 3)
pb_curlang.menuPath[0] = '\0';
if(strlen(pb_curlang.txtPath) < 3)
pb_curlang.txtPath[0] = '\0';
if(strlen(pb_curlang.questPath) < 3)
pb_curlang.questPath[0] = '\0';
if(pb_curlang.menuPath[0])
append_backspace(pb_curlang.menuPath);
if(pb_curlang.txtPath[0])
append_backspace(pb_curlang.txtPath);
if(pb_curlang.questPath[0])
append_backspace(pb_curlang.questPath);
KillLanguage();
f >> pb_num_lang;
pb_lang = new LanguageString[pb_num_lang];
for(int i=0;i<pb_num_lang;i++)
{
if(!pb_lang[i].read(f)) break;
String str;
if(!(pb_lang[i].flags & LANG_NOCOLOR))
str << char(26) << char(pb_lang[i].color);
char *s = pb_lang[i].s;
bool high = FALSE;
bool akrol_found = FALSE;
bool pex_found = FALSE;
bool ans_found = FALSE;
bool last_was_ansi=FALSE;
String ans_pex_name;
for(;*s;s++)
{
last_was_ansi = FALSE;
if(akrol_found)
{
if(*s != 'p' && *s != 'a')
{
str << '@' << *s;
}
else
{
if(*s == 'p')
pex_found = TRUE;
else
ans_found = TRUE;
ans_pex_name = "";
}
akrol_found = FALSE;
continue;
}
if(pex_found || ans_found)
{
if(*s == '@')
{
str << (pex_found ? char(24):char(25)) << char(ans_pex_name.len()) << ans_pex_name;
pex_found = ans_found = FALSE;
last_was_ansi = TRUE;
}
else
{
ans_pex_name << *s;
}
continue;
}
if(*s == '^')
{
high = !high;
if(high)
str << char(26) << char(pb_lang[i].highlight);
else
str << char(26) << char(pb_lang[i].color);
}
else
{
if(*s == '\\')
{
char c = *(++s);
if(c == '\\' || c == '^')
{
str << c;
continue;
}
else
{
byte col = 0;
if(isxdigit(c))
{
for( int i = 0; i < 2 ; i++ , s++)
{
c = *s;
if(isdigit(c))
col = col * 16 + c - '0';
else
col = col * 16 + toupper(c) - 'A' + 10;
}
str << char(26) << char(col);
s--;
continue;
}
if(c == 'H' || c == 'L')
{
switch(*(++s))
{
case 'B': col = 1;
break;
case 'G': col = 2;
break;
case 'C': col = 3;
break;
case 'R': col = 4;
break;
case 'P': col = 5;
break;
case 'Y': col = 6;
break;
case 'W': col = 7;
break;
}
if(c == 'H') col |= 8;
}
str << char(26) << char(col);
continue;
}
}
if(*s == '@')
{
akrol_found = TRUE;
continue;
}
str << (*s);
}
}
#ifdef DEBUG
if(str.find("\x11")>0)
LOG("s = '%s'",(char *)str);
#endif
if(pb_lang[i].flags & LANG_PROMPT)
{
if(!last_was_ansi)
str << ' ';
str << char(26) << char(pb_lang[i].promptcolor);
}
delete [] pb_lang[i].s;
pb_lang[i].len = str.len();
pb_lang[i].s = new char[ pb_lang[i].len + 1 ];
strcpy(pb_lang[i].s , str);
}
f.close();
S_PRESS_ENTER_TO_CONTINUE = _S_PRESS_ENTER_TO_CONTINUE;
S_PRESS_ENTER_TO_CONTINUE << '\t';
return TRUE;
}
char
wait_language_hotkeys(char *hk, bool enter)
{
String hotkeys;
hotkeys = hk;
if(enter)
hotkeys << '\r';
char k = io.wait(hotkeys);
k = hotkeys.find(String(char(k)));
if(hotkeys[k] == '\r')
return '\r';
else
return k;
}
int
language_string_length( char *str )
{
int l = 0;
for( ; *str ; str++)
{
char c = *str;
if(c == char(26))
{
str++;
continue;
}
l++;
}
return l;
}

BIN
LANGUAGE.OBJ Normal file

Binary file not shown.

8
LASTCALL.CPP Normal file
View File

@ -0,0 +1,8 @@
#include <stdlib.h>
#include "proboard.hpp"
void
lastcallers(char *data)
{
run_sdkfile(String("_LC ") + data);
}

BIN
LASTCALL.OBJ Normal file

Binary file not shown.

1330
LISTFILE.CPP Normal file

File diff suppressed because it is too large Load Diff

BIN
LISTFILE.OBJ Normal file

Binary file not shown.

2402
LOADPEX.CPP Normal file

File diff suppressed because it is too large Load Diff

BIN
LOADPEX.OBJ Normal file

Binary file not shown.

1374
LOGIN.CPP Normal file

File diff suppressed because it is too large Load Diff

BIN
LOGIN.OBJ Normal file

Binary file not shown.

322
MAILCHK.CPP Normal file
View File

@ -0,0 +1,322 @@
#define Use_MsgBase
#include <ctype.h>
#include <io.h>
#include <dos.h>
#include <string.h>
#include "proboard.hpp"
void mailcheck( char *data )
{
MsgArea ma;
String param[ 10 ];
bool checkmail = TRUE;
bool checkfiles = TRUE;
int num_para = parse_data( data, param );
for ( int i = 0; i < num_para; i++ )
{
if ( param[ i ][ 0 ] == '/' )
{
switch ( toupper( param[ i ][ 1 ] ) )
{
case 'M':
checkfiles = FALSE;
break;
case 'F':
checkmail = FALSE;
break;
}
}
}
if ( checkmail )
{
// if ( rip_mode )
// {
// rip_start_dialog( S_CHECKING_MAILBOX, 2 );
// io.fullcolor( 0x1F );
//
// io.show_remote = FALSE;
// }
io << "\n\7"
<< S_CHECKING_MAILBOX
<< char( 0xFF );
io.show_remote = TRUE;
int found = 0;
MessageIndex *msgsfound = new MessageIndex[ 200 ];
found = msgbase.scanMail( msgsfound, 200 );
// if ( rip_mode )
// {
// rip_end_dialog();
// rip_reset();
// }
if ( ! found )
{
io << "\n\n"
<< S_MAILBOX_EMPTY
<< '\xFF';
msleep( 1500 );
io << '\n';
}
else
{
io << "\n\n"
<< S_MAIL_FOUND_TITLE
<< "\n\n";
}
if ( found )
{
markedmsglist.clear();
for ( i = 1; i <= MsgArea::highAreaNum(); i++ )
{
int on1line = 0;
if ( ! ma.read( i ) )
{
continue;
}
for ( int j = 0; j < found; j++ )
{
if ( msgsfound[ j ].area == i )
{
if ( ! on1line )
{
if ( ! check_access( ma.readLevel,
ma.readFlags,
ma.readFlagsNot ) &&
! ma.sysopAccess() )
{
LOG( "Mail found in inaccessible area (%d)!!",
i );
break;
}
io << form( "\6%-33.33s: \3", ma.name );
}
if ( on1line++ == 6 )
{
io << form( "\n%-35s", "" );
on1line = 1;
}
io << form( "#%-5d ",
ma.msgNum( msgsfound[ j ].num ) );
markedmsglist.add( msgsfound[ j ] );
}
}
if ( on1line )
{
io << "\n\n";
}
}
for ( ; ; )
{
io << S_MAIL_FOUND_ACTION_PROMPT;
char k = wait_language_hotkeys( K_MAIL_FOUND_ACTION_PROMPT );
switch ( k )
{
case '\r':
case 0:
io << K_MAIL_FOUND_ACTION_PROMPT[ 0 ]
<< '\n';
readmsg( "0 /N" );
break;
case 1:
io << K_MAIL_FOUND_ACTION_PROMPT[ 1 ]
<< '\n';
qscan_msg( "0 /N" );
break;
default:
io << K_MAIL_FOUND_ACTION_PROMPT[ 2 ]
<< "\n\n"
<< S_MESSAGES_HAVE_BEEN_MARKED
<< "\n\n"
<< S_PRESS_ENTER_TO_CONTINUE;
break;
}
io << '\n';
if ( k != 1 )
{
break;
}
}
}
delete [] msgsfound;
}
if ( checkfiles )
{
File f;
int found = 0;
if ( ! checkmail )
{
io << '\n'
<< S_CHECKING_FOR_PERSONAL_FILES
<< '\xFF';
}
if ( f.open( FN_PVTFILES_PB ) )
{
_PrivateFile pvtfil;
for ( ; ; )
{
if ( f.read( & pvtfil,
sizeof( pvtfil ) ) != sizeof( pvtfil ) )
{
break;
}
if ( strcmpl( pvtfil.to, user.name ) ||
! pvtfil.fname[ 0 ] )
{
continue;
}
FileName fn;
if ( ! strchr( pvtfil.fname, '\\' ) )
{
fn = String( cfg.pvtuploadpath ) + pvtfil.fname;
}
else
{
fn = pvtfil.fname;
}
if ( access( fn, 0 ) )
{
continue;
}
fn.stripPath();
if ( ! found )
{
io << "\n\n"
<< S_PERSONAL_FILES_FOUND
<< "\n\n";
}
io << form( " \7* \3%-12s \7-\2 %02d %3s %4d\3 \7- ",
(char *) fn,pvtfil.date[ 0 ],
months_short[ pvtfil.date[ 1 ] ],
pvtfil.date[ 2 ] + 1900 ); // Y2K OKAY
io << S_PERSONAL_FILE_FROM( pvtfil.from )
<< '\n';
found++;
}
f.close();
if ( found )
{
io << '\n'
<< S_DOWNLOAD_NOW;
if ( io.ask( 0 ) )
{
download( "/P" );
}
// io << '\n'
// << S_PRESS_ENTER_TO_CONTINUE;
}
}
if ( ! found &&
! checkmail )
{
io << "\n\n"
<< S_NO_PERSONAL_FILES_FOUND
<< '\xFF';
msleep( 1500 );
io << '\n';
}
}
}

BIN
MAILCHK.OBJ Normal file

Binary file not shown.

5
MAKE0000.BAT Normal file
View File

@ -0,0 +1,5 @@
@echo off
del /q turboc.cfg
if errorlevel 1 goto m_end
echo>D:\CPP\PB\PROBOARD\make0000.err
:m_end

0
MAKE0000.LCK Normal file
View File

41
MAKEFILE Normal file
View File

@ -0,0 +1,41 @@
## Makefile for ProBoard v1.xx
## Caution!! The standard Borland C++ library has to be changed before compiling
## ProBoard v1.30 - The __NFILE__ macro in the file _nfile.h should be changed to
## 100. The files FILES.C and FILES2.C in the RTL\CLIB directory should be
## recompiled using all memory models, and updated in C?.LIB
MODEL = LARGE
OVERLAY = 1
OBJS = exec.obj io.obj fossil.obj menu.obj \
chat.obj shell.obj login.obj pbuser.obj readmsg.obj \
misc.obj timer.obj mailchk.obj msg.obj zip.obj \
writemsg.obj tops.obj forward.obj replymsg.obj timestat.obj \
msgdel.obj combined.obj question.obj aka.obj qscanmsg.obj \
showmsg.obj scanmsg.obj version.obj rawdir.obj msged.obj \
dl.obj viewfile.obj lastcall.obj desqview.obj stacking.obj \
cleanup.obj sysopkey.obj msgfind.obj binlog.obj protocol.obj \
listfile.obj ul.obj tag.obj sellang.obj proboard.obj \
nodelist.obj online.obj msgmove.obj cdrom.obj regis.obj \
mchat.obj setarea.obj usered.obj deckey.obj music.obj \
gif.obj msgexprt.obj help.obj ega.obj event.obj \
filearea.obj msgarea.obj timelog.obj wordwrap.obj showans.obj \
userset.obj usage.obj loadpex.obj image.obj postmsg.obj \
pexcall.obj strvars.obj userwin.obj bulletin.obj modem.obj \
execheck.obj language.obj fuzzy.obj terminal.obj squish.obj \
hudson.obj msgbase.obj mark.obj rip.obj jam.obj \
inpdate.obj tag_rw.obj
OVLOBJS = $(OBJS,Nexec\.obj,Nio\.obj,Nfossil\.obj,Ntimer\.obj,Nmisc\.obj)
TSLIB = 1
TSWIN = 1
SQUISH = 1
PBLIB = 1
#----------------------------------------------------------------------------#
ProBoard.exe: $(OBJS)

138
MARK.CPP Normal file
View File

@ -0,0 +1,138 @@
#define Use_MsgBase
#include "proboard.hpp"
MarkedMsgList::MarkedMsgList()
{
msgList = new MessageIndex[MAX_MARKED_MSGS];
n = 0;
}
MarkedMsgList::MarkedMsgList(const MarkedMsgList &m)
{
msgList = new MessageIndex[MAX_MARKED_MSGS];
(*this) = m;
}
MarkedMsgList::~MarkedMsgList()
{
delete [] msgList;
}
void
MarkedMsgList::operator=(const MarkedMsgList& m)
{
for(int i=0 ; i < MAX_MARKED_MSGS ; i++) msgList[i] = m.msgList[i];
n = m.n;
}
bool
MarkedMsgList::add(MessageIndex& mi)
{
if(isMarked(mi)) return TRUE;
if(n < MAX_MARKED_MSGS)
{
msgList[n++] = mi;
return TRUE;
}
else
{
return FALSE;
}
}
bool
MarkedMsgList::add(Message& msg)
{
return add(MessageIndex(msg.areaNum(),msg.id));
}
bool
MarkedMsgList::isMarked(MessageIndex& mi)
{
for(int i=0 ; i<n ; i++)
{
if(msgList[i].num == mi.num && msgList[i].area == mi.area) return TRUE;
}
return FALSE;
}
void
MarkedMsgList::sort()
{
int x,y;
for(x=0;x<n-1;x++)
for(y=x+1;y<n;y++)
if(msgList[x].area > msgList[y].area)
{
MessageIndex tmp = msgList[x];
msgList[x] = msgList[y];
msgList[y] = tmp;
}
for(x=0;x<n-1;x++)
for(y=x+1;y<n;y++)
if(msgList[x].area==msgList[y].area && msgList[x].num>msgList[y].num)
{
MessageIndex tmp = msgList[x];
msgList[x] = msgList[y];
msgList[y] = tmp;
}
}
void
get_new_msgs(MarkedMsgList& marked,int area)
{
Message msg;
MsgArea ma;
io << ' ';
int start = 1;
int end = 1000;
if(area)
{
start = end = area;
}
for(int i=start ; i <= end ; i++)
{
if( (area && area != i)
|| (!user.combinedBoards.connected(i) && !area)
|| !ma.read(i)
) continue;
if( !check_access(ma.readLevel,ma.readFlags,ma.readFlagsNot)
&& !ma.sysopAccess()) continue;
if(ma.highMsg() <= ma.lastRead(user_recnr)) continue;
bool ok = msg.readFirst(READMSG_ALL,1,ma.lastRead(user_recnr) + 1,"",i);
int cnt = 0;
while(ok)
{
if(!marked.add(MessageIndex(msg.areaNum(),msg.id))) break;
io << '\b' << (("/-\\|")[cnt]) ;
cnt = (++cnt) % 4;
ok = msg.readNext(READMSG_ALL,1,"");
}
if(ok) break;
}
io << "\b \b";
}

BIN
MARK.OBJ Normal file

Binary file not shown.

17
MC.CFG Normal file
View File

@ -0,0 +1,17 @@
-P-cpp
-c
-ml
-Y
-w-par
-w-aus
-w-use
-w-inl
-w-pin
-w-amb
-w-asm
-w-def
-w-nod
-w-pro
-w-stv
-w-pre
-w-sig

321
MCHAT.CPP Normal file
View File

@ -0,0 +1,321 @@
#include <string.h>
#include <dos.h>
#include <time.h>
#include <ctype.h>
#include "desqview.hpp"
#include "proboard.hpp"
const MAX_LOCK_TRIES = 500;
const LOCK_PAUSE = 10;
static char *lock_err_msg = "CHAT FILE LOCKING ERROR (%d)";
class chatdata
{
int online;
int head,tail;
char data[240];
static File f[2];
static int node[2];
public:
chatdata(int n1,int n2);
~chatdata();
void queue(char x);
int getnext(char *);
};
File chatdata::f[2];
int chatdata::node[2];
chatdata::chatdata(int n1,int n2)
{
node[0] = n1;
node[1] = n2;
if(!f[0].open(form("%sCHAT%d.DAT",syspath,node[0]),fmode_rw | fmode_shared | fmode_copen))
return;
memset(this,0,sizeof(*this));
f[0].write(this,sizeof(*this));
time_t t = time(NULL);
for(;;)
{
if(f[1].open(form("%sCHAT%d.DAT",syspath,node[1]),fmode_rw | fmode_shared)) break;
if((time(NULL)-t)>20)
{
LOG("File sharing error during chat!");
break;
}
}
}
chatdata::~chatdata()
{
f[0].close();
f[1].close();
}
void
chatdata::queue(char c)
{
for(int i=0;i<MAX_LOCK_TRIES;i++)
{
if(f[0].lock(0,sizeof(*this))) break;
msleep(LOCK_PAUSE);
}
if(i==MAX_LOCK_TRIES)
LOG(lock_err_msg,f[0].error());
f[0].seek(0);
f[0].read(this,sizeof(*this));
data[tail++]=c;
if(tail==240)
tail=0;
f[0].seek(0);
f[0].write(this,sizeof(*this));
f[0].unlock(0,sizeof(*this));
}
int
chatdata::getnext(char *buffer)
{
for(int i=0;i<MAX_LOCK_TRIES;i++)
{
if(f[1].lock(0,sizeof(*this))) break;
msleep(LOCK_PAUSE);
}
if(i==MAX_LOCK_TRIES)
LOG(lock_err_msg,f[1].error());
f[1].seek(0);
f[1].read(this,sizeof(*this));
for(i=0;i<240;i++)
{
if(head==tail)
break;
buffer[i] = data[head++];
if(head==240)
head=0;
}
f[1].seek(0);
f[1].write(this,sizeof(*this));
f[1].unlock(0,sizeof(*this));
return i;
}
void
multichat(char *data)
{
int node2;
io << "\n\n\f" << S_MCHAT_TITLE << "\n\n";
show_users_online(String("/MC ") + data);
io << "\n\n" << S_MCHAT_ENTER_NODE_NUMBER;
if(io.read(node2,3)<0)
return;
io << "\n\n" << S_MCHAT_CALLING_OTHER_NODE << '\xFF';
if(node2==node_number || node2>cfg.numnodes || node2<=0)
return;
user_online uo;
uo.setstatus(UO_BROWSING);
switch(uo.chatreq(node2))
{
case 1:
uo.setstatus(UO_BUSY,node2);
case 2:
io << S_MCHAT_NODE_IS_NOT_AVAILABLE << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
io << S_MCHAT_STARTED << "\n\n\xFF";
multilinechat(node2);
uo.setstatus(UO_BROWSING);
io << "\n\n" << S_MULTILINE_CHAT_ENDED << ' ' << S_PRESS_ENTER_TO_CONTINUE;
}
void
multilinechat(int n)
{
int node1,node2;
char buffer[240];
user_online uo;
int last=0;
String s;
node1 = node_number;
node2 = n;
LOG(1,"Multiline chat started");
chatdata cd(node1,node2);
uo.setstatus(UO_CHATTING);
for(int i=0;;i++)
{
char x;
if((x=io.readkey())!=0)
{
if(x<8)
continue;
if(x==27)
break;
if(last!=1)
{
if(avatar)
io << "\x16\x01\x0B\xFF";
else
if(ansi_mode)
io << "\xFF";
}
last=1;
if(x=='\t') x=' ';
if(x!=8) io << x << char(0xFF);
switch(x)
{
case 8:
if(s.len()>0)
{
s[s.len()-1]=0;
io << "\b \b\xFF";
}
break;
case 13:
io << '\n' << char(255);
s="";
break;
default:
s << (char)x;
}
if(s.len()>78)
{
String wrap;
int l = wordwrap(s,wrap,78);
for(int i=0;i<l;i++)
io << "\b \b\xFF";
s = wrap;
io << '\n' << s << char(0xFF);
}
cd.queue(x);
DV_timeslice();
msleep(10);
continue;
}
DV_timeslice();
msleep(100);
if(i>5)
{
i = uo.getstatus(node2);
if(i==UO_OFFLINE)
{
io << "\n\n" << S_MCHAT_OTHER_NODE_HUNG_UP << '\xFF';
return;
}
i=0;
}
int count = cd.getnext(buffer);
for(int i=0;i<count;i++)
{
char x=buffer[i];
if(last!=2)
{
if(avatar)
io << "\x16\x01\x07\xFF";
else
if(ansi_mode)
io << "\xFF";
}
last=2;
if(x==1) return;
if(x=='\t') x=' ';
if(x!=8)
io << x << char(0xFF);
switch(x)
{
case 8:
if(s.len()>0)
{
s[s.len()-1]=0;
io << "\b \b\xFF";
}
break;
case 13:
io << "\n\xFF";
s = "";
break;
default:
s << (char)x;
}
if(s.len()>78)
{
String wrap;
int l=wordwrap(s,wrap,78);
for(int i=0;i<l;i++) io << "\b \b\xFF";
s=wrap;
io << '\n' << s << char(0xFF);
}
}
}
cd.queue(1);
LOG(1,"Multiline chat ended");
}

BIN
MCHAT.OBJ Normal file

Binary file not shown.

766
MENU.CPP Normal file
View File

@ -0,0 +1,766 @@
#define Use_MsgBase
#define INCLUDE_REGIS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <stdlib.h>
#include "proboard.hpp"
struct MenuItem : public _MenuItem
{
bool checkAccess() const;
};
bool
MenuItem::checkAccess() const
{
if(!check_access(access.minLevel , access.flags , access.flagsNot))
return FALSE;
if(access.maxLevel && user.level > access.maxLevel)
return FALSE;
int age = -1;
if(user.birthDate.ok())
age = Date(TODAY).age(user.birthDate);
if(access.minAge || access.maxAge)
{
if(age < 0)
return FALSE;
if((access.minAge && age < access.minAge) || (access.maxAge && age > access.maxAge))
return FALSE;
}
if(access.minTimeLeft && timer.left() < access.minTimeLeft)
return FALSE;
if(access.minTimeOnline && timer.online() < access.minTimeOnline)
return FALSE;
if(!access.timeFrame.enabled())
return FALSE;
if(access.sex)
{
if(!user.sex)
return FALSE;
if(user.sex == SEX_MALE)
{
if(access.sex == 2)
return FALSE;
}
if(user.sex == SEX_FEMALE)
{
if(access.sex == 1)
return FALSE;
}
}
dword speed = io.baud;
if(speed < 1)
speed = 38400L;
if(access.minSpeed && speed < access.minSpeed)
return FALSE;
if(access.maxSpeed && speed > access.maxSpeed)
return FALSE;
if(access.nodes[(node_number-1)/8] & (1 << ((node_number-1) & 7)))
return FALSE;
return TRUE;
}
typedef char *str;
#define MAX_MENUSTACK 100
static
class menu_stack
{
str *menus;
int sp;
public:
menu_stack()
{
menus = new str[MAX_MENUSTACK];
for(int i=0;i<MAX_MENUSTACK;i++) menus[i] = new char[9];
sp=0;
}
~menu_stack()
{
for(int i=0;i<MAX_MENUSTACK;i++) delete [] menus[i];
delete [] menus;
}
void clear() { sp=0; }
void push(char *m) { if(sp<MAX_MENUSTACK) strcpy(menus[sp++],m); }
void pop(char *m) { if(sp>0) strcpy(m,menus[--sp]); }
} mstack;
void
logoff(char *data)
{
if(data==NULL || data[0]!='/') io.cls();
run_sdkfile("/I GOODBYE");
showansascrip("GOODBYE");
run_sdkfile("/I GOODBYE2");
LOG("User logged off");
if(io.baud) sleep(2);
exit_proboard();
}
static void
gotomenu(char *data)
{
String param[4];
char newmenu[20];
static int reg_counter = 0;
if(reg_counter++ == 10)
{
CHECK_REG();
reg_counter = 0;
}
int n=parse_data(data,param);
for(int i=0;i<n;i++)
{
if(param[i][0]=='/')
{
switch(toupper(param[i][1]))
{
case 'M': {
MsgArea ma;
if(param[i][3]=='+')
{
for(int i=user.msgArea+1;i<=user.msgArea+MsgArea::highAreaNum();i++)
{
int area = ((i-1)%MsgArea::highAreaNum())+1;
if(!ma.read(area) || !check_access(ma.readLevel,ma.readFlags,ma.readFlagsNot)) continue;
user.msgArea = area;
break;
}
break;
}
if(param[i][3]=='-')
{
for(int i=user.msgArea+MsgArea::highAreaNum()-1;i>=user.msgArea;i--)
{
int area = ((i-1)%MsgArea::highAreaNum())+1;
if(!ma.read(area) || !check_access(ma.readLevel,ma.readFlags,ma.readFlagsNot)) continue;
user.msgArea = area;
break;
}
break;
}
user.msgArea =atoi(&(param[i][3]));
break;
}
case 'F': {
FileArea fa;
if(param[i][3]=='+')
{
for(int i=user.fileArea+1;i<=user.fileArea+FileArea::highAreaNum();i++)
{
int area = ((i-1)%FileArea::highAreaNum())+1;
if(!fa.read(area) || !check_access(fa.level,fa.flags,fa.flagsNot)) continue;
user.fileArea = area;
break;
}
break;
}
if(param[i][3]=='-')
{
for(int i=user.fileArea+FileArea::highAreaNum()-1;i>=user.fileArea;i--)
{
int area = ((i-1)%FileArea::highAreaNum())+1;
if(!fa.read(area) || !check_access(fa.level,fa.flags,fa.flagsNot)) continue;
user.fileArea = area;
break;
}
break;
}
user.fileArea=atoi(&(param[i][3]));
break;
}
case 'P': {
char s[20];
io << '\n' << S_ENTER_MENU_PASSWORD;
io.read(s,15,READMODE_PWD);
io << "\n\xFF";
if(!s[0]) return;
if(strcmpl(&(param[i][3]),s))
{
LOG(1,"Wrong password for menu <%s> : %s",newmenu,strupr(s));
io << '\n' << S_ACCESS_DENIED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
}
break;
}
}
else strcpy(newmenu,param[i]);
}
strcpy(curmenu,newmenu);
menuchanged = TRUE;
}
static void
gosubmenu(char *data)
{
mstack.push(curmenu);
gotomenu(data);
if(!menuchanged) mstack.pop(curmenu);
}
static void
prevmenu(char *)
{
mstack.pop(curmenu);
menuchanged = TRUE;
}
static void
gotomenu_clear(char *data)
{
mstack.clear();
gotomenu(data);
}
#define MAX_ITEMS 255
struct menu_item
{
union {
char type;
char highlight;
};
unsigned level;
AccessFlags flags;
char string[76];
char key;
char data[81];
byte color;
byte attr;
};
const byte MNU_RIP_SHOW_REMOTE = 1;
const byte MNU_RIP_HIDE_LOCAL = 2;
const byte MNU_RIP_NO_RESET = 4;
static void nofunction(char *) {}
void (*menufunctions[])(char *) =
{
(void (*)(char *)) nofunction, // function 0 -> niets!! raar maar waar
(void (*)(char *)) gotomenu, // function 1 -> goto menu
(void (*)(char *)) gosubmenu, // function 2 -> gosub menu
(void (*)(char *)) prevmenu, // function 3 -> previous menu
(void (*)(char *)) gotomenu_clear, // function 4 -> clear stack and goto menu
showansasc, // function 5 -> show ans/asc file
(void (*)(char *)) change_state, // function 6 -> change state (!!)
(void (*)(char *)) shell, // function 7 -> shell
(void (*)(char *)) version_info, // function 8 -> version information
(void (*)(char *)) logoff, // function 9 -> logoff
(void (*)(char *)) usage_graph, // function 10 -> system usage graph by hour
(void (*)(char *)) pagesysop, // function 11 -> Chat request
(void (*)(char *)) questionnaire, // function 12 -> questionnaire
(void (*)(char *)) user_list, // function 13 -> user list
(void (*)(char *)) time_stat, // function 14 -> time info
(void (*)(char *)) view_ans_wait, // function 15 -> View ans/asc and wait
(void (*)(char *)) city_change, // function 16 -> change city
(void (*)(char *)) password_change, // function 17 -> change password
(void (*)(char *)) lines_change, // function 18 -> change screen size
(void (*)(char *)) cls_toggle, // function 19 -> toggle clearscreen
(void (*)(char *)) pause_toggle, // function 20 -> toggle more prompt
(void (*)(char *)) ansi_toggle, // function 21 -> toggle ANSI graphics
(void (*)(char *)) mailcheck, // function 22 -> check for mail
(void (*)(char *)) readmsg, // function 23 -> read messages
(void (*)(char *)) scan_msg, // function 24 -> scan messages
(void (*)(char *)) qscan_msg, // function 25 -> qscan messages
(void (*)(char *)) days_graph, // function 26 -> usage graph by day
(void (*)(char *)) writemsg, // function 27 -> write a message
(void (*)(char *)) combined_select, // function 28 -> combined boards select
(void (*)(char *)) weeks_graph, // function 29 -> usage graph per week
(void (*)(char *)) raw_dir, // function 30 -> show directory
(void (*)(char *)) list_files, // function 31 -> list files
(void (*)(char *)) download, // function 32 -> download a file
(void (*)(char *)) upload, // function 33 -> upload a file
(void (*)(char *)) list_archive, // function 34 -> view archive
(void (*)(char *)) keyword_search, // function 35 -> keyword search
(void (*)(char *)) filename_search, // function 36 -> filename search
(void (*)(char *)) new_files, // function 37 -> show new files
(void (*)(char *)) view_file, // function 38 -> view a file
(void (*)(char *)) view_named_file, // function 39 -> display named file
(void (*)(char *)) nofunction, // function 40 -> display ans/asc w/hotkeys
(void (*)(char *)) fsed_toggle, // function 41 -> toggle fs-editor
(void (*)(char *)) hotkey_toggle, // function 42 -> toggle hotkeys
(void (*)(char *)) clearmarked, // function 43 -> clear marked messages
(void (*)(char *)) combined_clear, // function 44 -> reset combined boards
(void (*)(char *)) view_file_wait, // function 45 -> display textfile and wait
(void (*)(char *)) change_access, // function 46 -> Change Access (flags/level)
(void (*)(char *)) logentry, // function 47 -> make a log entry
(void (*)(char *)) tops, // function 48 -> Tops
(void (*)(char *)) set_msgarea, // function 49 -> Set msg-area
(void (*)(char *)) show_users_online,// function 50 -> show users online
(void (*)(char *)) lastcallers, // function 51 -> list last callers
(void (*)(char *)) usereditor, // function 52 -> toggle no-disturb
(void (*)(char *)) multichat, // function 53 -> multi-line chat
(void (*)(char *)) set_filearea, // function 54 -> Set File Area
(void (*)(char *)) view_gif, // function 55 -> View GIF type
(void (*)(char *)) ibm_toggle, // function 56 -> Toggle IBM chars
(void (*)(char *)) phone_change, // function 57 -> Change phone #
(void (*)(char *)) dataphone_change, // function 58 -> Change data phone #
(void (*)(char *)) handle_change, // function 59 -> Change handle
(void (*)(char *)) run_sdkfile, // function 60 -> Load a ProBoard SDK File
(void (*)(char *)) bulletin, // function 61 -> Show bulletin
(void (*)(char *)) toggle_avatar, // function 62 -> Toggle AVT/0
(void (*)(char *)) toggle_avtplus, // function 63 -> Toggle AVT/0+
(void (*)(char *)) show_graph, // function 64 -> Show general usage graph
(void (*)(char *)) showansascrip, // function 65 -> Show ANS/ASC/RIP w/hotkeys
(void (*)(char *)) ripfont_change, // function 66 -> Change RIP font
(void (*)(char *)) rip_toggle, // function 67 -> Toggle RIP graphics
(void (*)(char *)) edit_taglist, // function 68 -> Edit file tags
(void (*)(char *)) select_language, // function 69 -> Select a language
(void (*)(char *)) change_dateformat,// function 70 -> Change date format
(void (*)(char *)) change_address, // function 71 -> Change address
(void (*)(char *)) change_faxphone, // function 72 -> Change fax phone
(void (*)(char *)) change_country, // function 73 -> Change country
(void (*)(char *)) change_default_protocol, // function 74 -> Change default protocol
(void (*)(char *)) select_msggroup, // function 75 -> Select message area group
(void (*)(char *)) select_filegroup // function 76 -> Select file area group
};
static void _near
execute_function(MenuItem *item)
{
rip_reset();
if( item->function>4
&& item->function != 23
&& item->function != 32
&& item->function != 33
&& !(item->attr & MNU_RIP_NO_RESET))
{
rip_textmode();
}
if(item->attr & MENU_PASSWORD)
{
char s[20];
io << '\n' << S_ENTER_SELECTION_PASSWORD;
io.read(s,15,READMODE_PWD);
io << "\n\xFF";
if(!s[0]) return;
if(stricmp(item->password,s))
{
LOG(1,"Wrong password in menu <%s>",(char *)curmenu);
io << '\n' << S_ACCESS_DENIED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
}
(*menufunctions[item->function])(replace_stringvars(item->data));
}
static char * near
colorstring(char col)
{
char cols[] = { 0,4,2,6,1,5,3,7 };
String s;
static char str[30];
str[0]=0;
char fg=col&7;
char bg=(col&0x70)>>4;
char bright=!(col&8);
if(avatar)
{
fg = cols[fg];
bg = cols[bg];
s << char(22) << char(1) << char(fg|(bg<<4)|(bright?8:0));
strcpy(str,s);
return str;
}
if(!ansi_mode) return str;
s="[";
if(bright) s << "1;";
else s << "0;";
s << form("3%d;4%dm",fg,bg);
strcpy(str,s);
return str;
}
static String near
translate_menutext(char *s,byte color,byte highlight,bool prompt)
{
String str;
bool high = FALSE;
if(*s == ';') return "";
if(*s == '\0') return "\n";
str << colorstring(color);
for(;*s;s++)
{
char c = *s;
switch(c)
{
case '^': high = !high;
if(high)
str << colorstring(highlight);
else
str << colorstring(color);
break;
case '~': str << "@<TMLEFT>@";
break;
case '`': str << "@<CURMSGAREA>@";
break;
case '@': if(*(s+1)=='<' || (*(s-1))=='>')
str << '@';
else
str << "@<CURFILEAREA>@";
break;
case '\\': c = *(s+1);
if(c>='1' && c<='7')
{
str << char(c - '0');
s++;
continue;
}
if(c=='0')
{
str << colorstring(color);
s++;
continue;
}
c = '\\';
default : str << c;
}
}
if(!prompt)
{
if(str[str.len()-1] == ';') str[str.len()-1] = '\0';
else str << '\n';
}
return replace_stringvars(str);
}
static bool
menu_show_at_all(MenuItem *item , _MenuFile *prompt)
{
return
( (item->attr & MNU_RIP_SHOW_REMOTE)
|| !(item->attr & MNU_RIP_HIDE_LOCAL)
|| !rip_mode
|| !prompt->attr
);
}
static bool
menu_show_local(MenuItem *item , _MenuFile *prompt)
{
return
(
!(item->attr & MNU_RIP_HIDE_LOCAL)
|| !rip_mode
|| !prompt->attr
);
}
static bool
menu_show_remote(MenuItem *item , _MenuFile *prompt)
{
return (
(item->attr & MNU_RIP_SHOW_REMOTE)
|| !rip_mode
|| !prompt->attr
);
}
void
menu_processor()
{
int i,j;
char hotkeys[MAX_ITEMS];
File f;
_MenuFile *menufile = NULL;
MenuItem **items = NULL;
int numallocated = 0;
int numitems = 0;
int glob_numitems = 0;
menufile = new _MenuFile;
strcpy(curmenu,"TOP");
for(;;)
{
LOG(3,"Menu: %s",curmenu);
menuchanged = FALSE;
updatemenu = FALSE;
if(f.open(FileName(cfg.mnupath,"GLOBAL.PBM")))
{
glob_numitems = int((f.len() - sizeof(_MenuFile)) / sizeof(MenuItem));
f.close();
}
if(!f.open(FileName(cfg.mnupath,curmenu,".PBM")))
{
if(!strcmpl(curmenu,"TOP")) fatalerror("NO TOP MENU");
mstack.clear();
LOG("ERROR: Menu %s not found!",curmenu);
strcpy(curmenu,"TOP");
continue;
}
if(items != NULL)
{
for(i=0;i<numallocated;i++)
delete items[i];
delete [] items;
}
numitems=int((f.len() - sizeof(_MenuFile)) / sizeof(MenuItem));
items = new MenuItem *[numitems + glob_numitems];
for(i=0;i<numitems+glob_numitems;i++)
items[i] = new MenuItem;
numallocated = i;
f.read(menufile,sizeof(_MenuFile));
for(i=0;i<numitems;i++)
f.read(items[i],sizeof(MenuItem));
f.close();
if(f.open(FileName(cfg.mnupath,"GLOBAL.PBM")))
{
f.seek(sizeof(_MenuFile));
for(i=numitems;i<numitems+glob_numitems;i++)
f.read(items[i],sizeof(MenuItem));
f.close();
numitems += glob_numitems;
}
for(i=0,j=0;i<numitems;i++)
if(items[i]->checkAccess())
if(items[i]->hotKey>13 && items[i]->function)
hotkeys[j++] = toupper(items[i]->hotKey);
hotkeys[j++]='\r';
hotkeys[j++]=';';
hotkeys[j]=0;
for(;;)
{
char k;
again:
if(updatemenu) break;
rip_reset();
k=toupper(comstack.pollnext());
if(strchr(hotkeys,k) && k!=13 && k)
{
k=toupper(comstack.getnext());
for(i=0;i<numitems;i++)
if(k==items[i]->hotKey && items[i]->checkAccess())
{
if(!stack_mode) io << k << "\n\xFF";
execute_function(items[i]);
if(menuchanged) break;
}
if(menuchanged) break;
io << "\n\xFF";
continue;
}
io.disablestop();
io << "\n\f\xFF";
if(menufile->attr)
show_rip(menufile->RIPname,FALSE);
for(i=0;i<numitems;i++)
{
if(!items[i]->checkAccess())
continue;
if(items[i]->function==40)
{
if(menu_show_at_all(items[i],menufile))
{
if(!menu_show_local(items[i],menufile)) io.show_local = FALSE;
if(!menu_show_remote(items[i],menufile)) io.show_remote = FALSE;
k=showansasc(replace_stringvars(items[i]->data),hotkeys);
io.show_local = TRUE;
io.show_remote = TRUE;
if(k>2)
{
io << " \7" << k << "\n\xFF";
for(int j=0;j<numitems;j++)
if(items[j]->hotKey==k && items[j]->checkAccess())
{
if(items[j]->function) execute_function(items[j]);
if(menuchanged) break;
}
if(menuchanged) break;
goto again;
}
}
}
else if(items[i]->hotKey==1)
{
if(items[i]->function == 5 || items[i]->function == 38)
{
if(menu_show_at_all(items[i],menufile))
{
if(!menu_show_local(items[i],menufile)) io.show_local = FALSE;
if(!menu_show_remote(items[i],menufile)) io.show_remote = FALSE;
execute_function(items[i]);
io.show_local = TRUE;
io.show_remote = TRUE;
}
}
else
{
execute_function(items[i]);
}
if(menuchanged) break;
}
k=0;
if(menu_show_at_all(items[i],menufile))
{
if(!menu_show_local(items[i],menufile)) io.show_local = FALSE;
if(!menu_show_remote(items[i],menufile)) io.show_remote = FALSE;
k = io.send(translate_menutext(items[i]->text,
items[i]->color,
menufile->highlight,
FALSE),
hotkeys);
io.show_local = TRUE;
io.show_remote = TRUE;
}
if(k==1) break;
if(k>1)
{
io << " \7" << k << "\n\xFF";
for(int j=0;j<numitems;j++)
if(items[j]->hotKey==k && items[j]->checkAccess())
{
if(items[j]->function) execute_function(items[j]);
if(menuchanged) break;
}
if(menuchanged) break;
goto again;
}
}
if(menuchanged) break;
io << '\n' << translate_menutext(menufile->prompt, // hidden constructor
menufile->color,
menufile->highlight,
TRUE);
if(!stack_mode) k=io.wait(hotkeys);
if(k==';') io << "> ";
if(k==';' || stack_mode)
{
if(k==';' || !strchr(hotkeys,k) || !k)
{
comstack.clear();
char command[60];
io.read(command,59,READMODE_NOFIELD);
if(!command[0]) { command[0]='\r'; command[1]=0; }
io << "\n\xFF";
k=toupper(command[0]);
if(!strchr(hotkeys,k)) k='\r';
else comstack.parse(&command[1]);
}
}
for(i=0;i<numitems;i++)
if(k==items[i]->hotKey && items[i]->checkAccess())
{
if(!stack_mode) io << k << "\n\xFF";
execute_function(items[i]);
if(menuchanged) break;
}
if(menuchanged) break;
io << "\n\xFF";
}
}
}

BIN
MENU.OBJ Normal file

Binary file not shown.

994
MISC.CPP Normal file
View File

@ -0,0 +1,994 @@
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <tswin.hpp>
#include "proboard.hpp"
#include "fossil.hpp"
void logentry( char *data )
{
LOG("%s",data);
}
static
void near dolog( int level,
char *str )
{
if (
(
! io.baud &&
! cfg.loglocal
)
|| user.logLevel < level )
{
return;
}
Date date( TODAY );
Time time( NOW );
File fp( "PROBOARD.LOG",
fmode_write |
fmode_text |
fmode_copen |
fmode_append );
fp.seek( fp.len() );
fp.printf( "%02d-%s-%02d %02d:%02d:%02d %s\n",
date[ 0 ],
months_short[ date[ 1 ] ],
date[ 2 ] % 100, // Y2K FIXED!
// date[ 2 ], // Y2K BUG!
time[ 0 ],
time[ 1 ],
time[ 2 ],
str );
}
void LOG( char *str ... )
{
char s[ 200 ];
va_list va;
va_start( va, str );
vsprintf( s,
str,
va );
dolog( 0, s );
}
void LOG( int level,
char *str ... )
{
char s[ 200 ];
va_list va;
va_start( va, str );
vsprintf( s,
str,
va );
dolog( level, s );
}
void fatalerror( char *s )
{
String str( "Fatal error: " );
str << s;
LOG( "%s", (char *) str );
if ( io.baud > 0 )
{
io << "\n\n"
<< S_FATAL_ERROR;
}
else
{
SCREEN << "\f\n\n"
<< str
<< '\n';
}
fatal = TRUE;
exit( ERRLVL_FATALERR );
}
//----------------------
// reset=-1 -> increment
//----------------------
int linecounter( int reset )
{
static int linecount = 0;
static bool continuous = FALSE;
if ( reset >= 0 )
{
linecount = reset;
continuous = FALSE;
return 0;
}
if ( ++linecount >= (
(
/* rip_mode
? rip_screenlines: */
user.screenLength
) - 1
)
&& !continuous
&& pause_mode )
{
char rep;
if ( io.more_func )
{
rep = char( ( *io.more_func ) () );
}
else
{
byte oldcolor = SCREEN.attrib();
// if ( rip_mode )
// {
// rip_show_more();
//
// io.show_remote = FALSE;
// }
io << S_MORE;
int prompt_len = strlen( S_MORE );
rep = wait_language_hotkeys( K_MORE );
io << '\r'
<< String( ' ', prompt_len )
<< '\r';
io.fullcolor( oldcolor );
io.show_remote = TRUE;
// if ( rip_mode )
// {
// rip_clear_status();
// rip_show_enter();
// }
}
if ( rep == '\r' )
{
rep = 0;
}
if ( rep == 2 )
{
continuous = TRUE;
rep = 0;
}
linecount = 0;
return rep;
}
return 0;
}
int check_access( unsigned level,
AccessFlags flags )
{
if ( user.level < level )
{
return 0;
}
for ( int i = 1; i <= 32; i++ )
{
if ( flags.getflag( i ) )
{
if ( ! user.aFlags.getflag( i ) )
{
return 0;
}
}
}
return 1;
}
int check_access( unsigned level,
AccessFlags flags,
AccessFlags notflags )
{
if ( user.level < level )
{
return 0;
}
for ( int i = 1; i <= 32; i++ )
{
if ( flags.getflag( i ) )
{
if ( ! user.aFlags.getflag( i ) )
{
return 0;
}
}
}
for ( i = 1; i <= 32; i++ )
{
if ( notflags.getflag( i ) )
{
if ( user.aFlags.getflag( i ) )
{
return 0;
}
}
}
return 1;
}
char *strstrl( char *s,
char *f )
{
int lf = strlen( f );
int l = strlen( s ) - lf + 1;
for ( int i = 0; i < l; i++ )
{
if ( ! memicmp( & s[ i ],
f,
lf ) )
{
return & s[ i ];
}
}
return NULL;
}
int matchstring( char *s,
char *d )
{
for ( ; *s && *d; s++, d++ )
{
switch ( *s )
{
case '?':
continue;
case '*':
return 1;
default:
if ( toupper( *s ) != toupper( *d ) )
{
return 0;
}
}
}
if ( toupper( *s ) != toupper( *d ) &&
*s!='*')
{
return 0;
}
else
{
return 1;
}
}
int matchfile( char *search,
char *file )
{
String sbody;
String sext;
String fbody;
String fext;
while ( *search != '.' &&
*search )
{
sbody << *search++;
}
if ( ! *search++ )
{
return 0;
}
while ( *search )
{
sext << *search++;
}
while ( *file != '.' &&
*file )
{
fbody << *file++;
}
if ( ! *file++ )
{
return 0;
}
while ( *file )
{
fext << *file++;
}
if ( matchstring( sbody, fbody ) &&
matchstring( sext, fext ) )
{
return 1;
}
return 0;
}
void strip_path( char *s )
{
int l = strlen( s );
for ( int i = l - 1; i >= 0; i-- )
{
if ( s[ i ] == '\\' ||
s[ i ] == '/' )
{
break;
}
}
if ( i >= 0 )
{
memmove( s,
& s[ i + 1 ],
l - i );
}
}
void strip_fname( char *s )
{
int l = strlen( s );
for ( int i = l - 1; i >= 0; i-- )
{
if ( s[ i ] == '\\' ||
s[ i ] == '/' )
{
s[ i + 1 ] = '\0';
break;
}
}
}
int parse_data( char *s,
String *param )
{
for ( int i = 0; ; i++ )
{
int inquote = 0;
while ( *s == ' ' &&
*s )
{
s++;
}
if ( *s == '\0' )
{
break;
}
param[ i ].clear();
while ( *s )
{
if ( *s == ' ' &&
! inquote )
{
break;
}
if ( *s == '\"' )
{
inquote = ! inquote;
s++;
continue;
}
param[ i ] << ( *s++ );
}
}
return i;
}
void adjust_limits()
{
long kbgranted;
int i;
int j;
for ( i = 0; i < num_limits - 1; i++ )
{
for ( j = i + 1; j < num_limits; j++ )
{
if ( limit[ i ].level < limit[ j ].level )
{
limits temp;
temp = limit[ i ];
limit[ i ] = limit[ j ];
limit[ j ] = temp;
}
}
}
for ( int n = -1; ; )
{
for ( i = num_limits - 1; i >= 0; i-- )
{
if ( user.level >= limit[ i ].level )
{
n = i;
}
}
if ( n < 0 )
{
return;
}
if ( limit[ n ].max_download &&
user.kbDownloaded > limit[ n ].max_download )
{
if ( user.level != limit[ n ].fallto )
{
user.level = limit[ n ].fallto;
continue;
}
}
if ( limit[ n ].factor )
{
kbgranted = long( user.kbUploaded ) * 100L /
limit[ n ].factor
+ long( user.msgsPosted ) * limit[ n ].msgfactor
+ limit[ n ].free;
}
else
{
kbgranted = 0x7FFFFFFFL;
}
if ( user.kbDownloaded > kbgranted )
{
if ( ! limit[ n ].factor )
{
upload_needed = 0x7FFF;
}
else
{
upload_needed = int( (
long( user.kbDownloaded ) -
kbgranted
)
* limit[ n ].factor / 100
);
}
free_download = 0;
}
else
{
free_download = int( kbgranted - user.kbDownloaded );
upload_needed = 0;
if ( free_download > limit[ n ].daily_klimit )
{
free_download = limit[ n ].daily_klimit;
}
}
break;
}
time_limit = limit[ n ].timelimit;
download_limit = limit[ n ].daily_klimit;
download_delay = limit[ n ].pre_download;
timer.changeleft( time_limit -
timer.used() -
user.timeUsed -
time_removed);
updatemenu = TRUE;
}
void change_access(char *data)
{
String param[ 40 ];
int n = parse_data( data, param );
for ( int i = 0; i < n; i++ )
{
param[ i ].upperCase();
if (
isalpha( param[ i ][ 0 ] ) ||
(
param[ i ][ 0 ] >= '1' &&
param[ i ][ 0 ] <= '6' &&
strchr( "+-", param[ i ][ 1 ] )
)
)
{
int flag;
if ( isalpha( param[ i ][ 0 ] ) )
{
flag = param[ i ][ 0 ] - 64;
}
else
{
flag = param[ i ][ 0 ] - '1' + 27;
}
if ( param[ i ][ 1 ] == '-' )
{
user.aFlags.clearflag( flag );
}
else
{
user.aFlags.setflag( flag );
}
}
else
{
user.level = word( atol( param[ i ] ) );
}
}
adjust_limits();
timer.check();
updatemenu = TRUE;
}
void file_error( int fn,
int errno )
{
String s( "Error accessing file " );
switch ( abs( fn ) )
{
case ERR_BINLOG_PB:
s << FN_BINLOG_PB;
break;
case ERR_TIMELOG_PRO:
s << FN_TIMELOG_PRO;
break;
case ERR_ONLINE_PRO:
s << FN_ONLINE_PRO;
break;
case ERR_AKA_PRO:
s << "AKA.PRO";
break;
}
if ( errno )
{
s << form( " (%d - %s)",
errno,
dos_error_message( errno ) );
}
if ( fn < 0 )
{
LOG( "%s", (char *) s );
}
else
{
fatalerror( s );
}
}
void file_error( char *fn,
int errno )
{
String s( "Error accessing file " );
s << fn;
if ( errno )
{
s << form( " (%d - %s)",
errno,
dos_error_message( errno ) );
}
fatalerror( s );
}
void file_warning( char *fn,
int errno )
{
String s( "Error accessing file " );
s << fn;
if ( errno )
{
s << form( " (%d - %s)",
errno,
dos_error_message( errno ) );
}
LOG( s );
}
int intimewindow( Time t1,
Time t2 )
{
Time now( NOW );
if ( t2 <= t1 )
{
t2[ 0 ] += 24;
}
if ( now < t1 )
{
now[ 0 ] += 24;
}
if ( now < t1 ||
now > t2 )
{
return 0;
}
else
{
return 1;
}
}
char *dos_error_message( int errno )
{
static struct
{
int no;
char *msg;
}
errmsg[] =
{
{ 1, "Invalid DOS call (SHARE not loaded?)" },
{ 2, "File not found" },
{ 3, "Directory not found" },
{ 4, "Too many open files" },
{ 5, "Access denied" },
{ 6, "Invalid handle" },
{ 7, "MCB destroyed" },
{ 8, "Not enough memory" },
{ 0, "" }
};
for ( int i = 0; errmsg[ i ].no; i++ )
{
if ( errno == errmsg[ i ].no )
{
break;
}
}
return errmsg[ i ].msg;
}
//**************************************************************************
//
// Parse a date string for the current locale
//
// Prototype: void parse_date( Date &d, char *s, int format );
//
// Parameters: d ... Date value to fill-in
// s ... String containing date data to parse
// format ... Desired date locale
//
// Returns: None
//
// Remarks:
//
// This routine parses a date string, and returns the appropriate values in
// the date value <d>.
//
// Remember:
//
// d[0] ... day
// d[1] ... month
// d[2] ... year (-1900)
//
// Year value are between 0 to 127. This means that a ProBoard Date object
// can store a year value from 1900 to 2027.
//
// -------------------------------------------------------------------------
//
// Created on: ??/??/?? (Philippe Leybaert)
// Last modified: 06/17/99 (Jeff Reeder)
// Modified to handle dates in 10-byte formats for Y2K
// compliance. Fixed a MAJOR bug in this routine where the
// original code didn't check for a proper sequence of
// three delimited numeric values. Also modified this code
// to properly handle two-byte years.
//
//**************************************************************************
void parse_date( Date &d,
char *s,
int format )
{
char str[ 11 ];
strncpy( str,
s,
10 );
str[ 10 ] = '\0';
char *fmt = date_formats[ format ];
int fmt_ar[ 3 ];
fmt_ar[ 0 ] = 0;
fmt_ar[ 1 ] = 0;
fmt_ar[ 2 ] = 0;
//-------------------------------------------------------
// Figure out what sequence the M/D/Y values should be in
//-------------------------------------------------------
if ( toupper( fmt[ 0 ] == 'D' ) ) fmt_ar[ 0 ] = DATE_DAY;
if ( toupper( fmt[ 0 ] == 'M' ) ) fmt_ar[ 0 ] = DATE_MONTH;
if ( toupper( fmt[ 0 ] == 'Y' ) ) fmt_ar[ 0 ] = DATE_YEAR;
if ( toupper( fmt[ 3 ] == 'D' ) ) fmt_ar[ 1 ] = DATE_DAY;
if ( toupper( fmt[ 3 ] == 'M' ) ) fmt_ar[ 1 ] = DATE_MONTH;
if ( toupper( fmt[ 3 ] == 'Y' ) ) fmt_ar[ 1 ] = DATE_YEAR;
if ( toupper( fmt[ 6 ] == 'D' ) ) fmt_ar[ 2 ] = DATE_DAY;
if ( toupper( fmt[ 6 ] == 'M' ) ) fmt_ar[ 2 ] = DATE_MONTH;
if ( toupper( fmt[ 6 ] == 'Y' ) ) fmt_ar[ 2 ] = DATE_YEAR;
//--------------------------
// Initialize our date value
//--------------------------
d.set( 0,
0,
0 );
//-------------------------
// Find our first delimiter
//-------------------------
s = strtok( str, "-/." );
if ( s )
{
int val;
val = atoi( s );
if ( fmt_ar[ 0 ] == DATE_YEAR )
{
d[ fmt_ar[ 0 ] ] = NormalizeYear( val );
}
else
{
d[ fmt_ar[ 0 ] ] = val;
}
s = strtok( NULL, "-/." );
if ( s )
{
val = atoi( s );
if ( fmt_ar[ 1 ] == DATE_YEAR )
{
d[ fmt_ar[ 1 ] ] = NormalizeYear( val );
}
else
{
d[ fmt_ar[ 1 ] ] = val;
}
s = strtok( NULL, "-/." );
if ( s )
{
val = atoi( s );
if ( fmt_ar[ 2 ] == DATE_YEAR )
{
d[ fmt_ar[ 2 ] ] = NormalizeYear( val );
}
else
{
d[ fmt_ar[ 2 ] ] = val;
}
}
}
}
}

BIN
MISC.OBJ Normal file

Binary file not shown.

741
MODEM.CPP Normal file
View File

@ -0,0 +1,741 @@
#define Use_MsgBase
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <time.h>
#include <io.h>
#include <tswin.hpp>
#include "fossil.hpp"
#include "desqview.hpp"
#include "proboard.hpp"
#define STAT_LINE_Y 20
#define LAST_CALLER_Y 16
#define EVENT_LABEL 0x5F
#define EVENT_DATA 0x5E
#define TITLE_COLOR 0x71
#define LABEL_COLOR 0x70
static void
fos_sendbreak(int port)
{
fos_break(port,TRUE);
unsigned long ticks = clockticks();
while(clockdiff(ticks)<2) {}
fos_break(port,FALSE);
}
struct modem_config : _ModemConfig {};
class modem
{
int port;
long baud;
int delay;
public:
modem(int p,long b);
~modem()
{
fos_deinit(port);
}
void set_delay(int d)
{
delay = d;
}
void cmd(char *s);
bool check_response(String& s);
};
modem::modem(int p,long b)
{
byte baudcode = 0;
port = p;
baud = b;
fos_init(port);
switch(baud)
{
case 300L: baudcode = 0x43; break;
case 1200L: baudcode = 0x83; break;
case 2400L: baudcode = 0xA3; break;
case 4800L: baudcode = 0xC3; break;
case 9600L: baudcode = 0xE3; break;
case 19200L: baudcode = 0x03; break;
case 38400L: baudcode = 0x23; break;
}
fos_setbps(port,baudcode);
}
void
modem::cmd(char *s)
{
for(;*s;s++)
{
char c = *s;
switch(c)
{
case '~': ::delay(500);
break;
case '`':
case '':
case 'v': fos_setdtr(port,0);
break;
case '^': fos_setdtr(port,1);
break;
case '$': fos_sendbreak(port);
break;
case '|': c = '\r';
default : fos_sendnw(port,c);
if(delay)
::delay(delay*100);
}
}
}
bool
modem::check_response(String& s)
{
static String resp;
if(!fos_byteready(port))
{
return FALSE;
}
byte c = fos_getch(port);
if(c == '\r')
{
s = resp;
resp.clear();
return (s[0]) ? TRUE:FALSE;
}
if(c != '\n') resp << char(c);
return FALSE;
}
const int STATUS_WAITING_FOR_CALL = 0;
const int STATUS_INITIALIZING = 1;
const int STATUS_WAITING_FOR_OK = 2;
bool
do_modem(modem_response *response)
{
tsw_fillscreen( '±', 0x19 );
Window dlg_win( 3,
2,
76,
22,
0x70,
SHADOW,
CHISEL_BORDER,
0x7F,
NULL,
0x78 );
Window bar_win( 1,
tsw_vsize,
tsw_hsize,
tsw_vsize,
0x4F,
NOBORDER|NOSAVE,
NULL );
Window stat_win( 6,
19,
73,
21,
0x0E, // Inner color
NOSAVE,
RECESS_BORDER,
0x08, // Bright color
NULL,
0x0F, // Dark color
0x70 ); // Outer color
Window lc_win( 6,
15,
73,
17,
0x1F,
NOSAVE,
RECESS_BORDER,
0x08,
NULL,
0x0F,
0x70 );
Window resp_win( 6,
8,
28,
13,
0x30,
NOSAVE,
RECESS_BORDER,
0x08,
NULL,
0x0F,
0x70 );
Window event_win( 30,
8,
73,
13,
EVENT_LABEL,
NOSAVE,
RECESS_BORDER,
0x08,
NULL,
0x0F,
0x70 );
dlg_win.ShadowColor( 0x10 );
dlg_win.open();
resp_win.open();
lc_win.open();
stat_win.open();
event_win.open();
bar_win.open();
if ( registered )
{
tsw_centerline( 3,
form( "ProBoard v%s (Node %d - S/N=%s)",
VERSION,
(int) node_number,
software_serial_number() ),
TITLE_COLOR );
}
else
{
tsw_centerline( 3,
form( "ProBoard v%s [Node %d - UNREGISTERED for %d day%s]",
VERSION,
(int) node_number,
pastFirstUse,
( pastFirstUse == 1 )
? ""
: "s" ),
TITLE_COLOR );
}
tsw_centerline( 4,
"Copyright (c) 1990-1999 TeleGrafix Communications, Inc.",
TITLE_COLOR );
tsw_centerline( 5,
"All Rights Reserved",
TITLE_COLOR );
tsw_maputs( 4,
6,
0x7F,
"Ã" );
tsw_maputs( 5,
6,
0x78,
"ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´" );
tsw_centerline( 14, "Last Caller" );
tsw_centerline( 18, "Current Status" );
modem_config *modem_cfg = new modem_config;
CLEAR_OBJECT(*modem_cfg);
File f;
if(!f.open(FileName(syspath,form("MODEM%03d.PB",node_number))))
if(!f.open(FileName(syspath,"MODEM.PB")))
{
LOG("Unable to open MODEM.PB");
delete modem_cfg;
return FALSE;
}
f.read(modem_cfg,sizeof(modem_config));
f.close();
modem_cfg->port--;
if(response->baud) modem_cfg->maxBps = response->baud;
if(response->port>=0) modem_cfg->port = response->port;
tsw_maputs( 8,
7,
LABEL_COLOR,
form( "Modem COM%d/%ld bps",
modem_cfg->port + 1,
modem_cfg->maxBps ) );
tsw_maputs( 43,
7,
LABEL_COLOR,
"System Statistics" );
response->port = modem_cfg->port;
modem modem(modem_cfg->port,(modem_cfg->flags & MODEM_LOCKED) ? 38400L : modem_cfg->maxBps);
modem.set_delay(modem_cfg->commandDelay);
tsw_cursoroff();
stat_win.clear();
tsw_centerline(STAT_LINE_Y,"Initializing modem",0xE);
event_win.attrib( EVENT_LABEL );
event_win << "\n # Calls: ";
event_win.attrib( EVENT_DATA );
event_win << form( "%-6ld ", totalcalls );
event_win.attrib( EVENT_LABEL );
event_win << "# Users: ";
event_win.attrib( EVENT_DATA );
event_win << form( "%d\n", num_users );
event_win.attrib( EVENT_LABEL );
event_win << "# Hudson Msgs: ";
event_win.attrib( EVENT_DATA );
event_win << form( "%-5ld\n", msgbase.totalMsgs() );
event_win.attrib( EVENT_LABEL );
if ( lastcaller.name &&
*lastcaller.name )
{
tsw_centerline( LAST_CALLER_Y,
form( "%s (%02d:%02d to %02d:%02d)",
lastcaller.name,
lastcaller.timeIn[ 0 ],
lastcaller.timeIn[ 1 ],
lastcaller.timeOut[ 0 ],
lastcaller.timeOut[ 1 ] ),
0x1E );
}
else
{
tsw_centerline( LAST_CALLER_Y,
form( "(%02d:%02d to %02d:%02d)",
lastcaller.timeIn[ 0 ],
lastcaller.timeIn[ 1 ],
lastcaller.timeOut[ 0 ],
lastcaller.timeOut[ 1 ] ),
0x1E );
}
time_t start_time = time(NULL);
time_t init_sent = 0;
int init_tries = 0;
bool initialized = FALSE;
bool blanked = FALSE;
bool init1_ok;
bool init2_ok;
bool init3_ok;
bool init1_sent = FALSE;
bool init2_sent = FALSE;
bool init3_sent = FALSE;
time_t blank_start = time(NULL);
word *blank_buf = new word[tsw_vsize*tsw_hsize];
for(;;)
{
String s;
Date date(TODAY);
Time time(NOW);
if(!blanked)
{
bar_win.direct( 57,
1,
0x4E,
form( "%02d:%02d:%02d",
time[ 0 ],
time[ 1 ],
time[ 2 ] ) );
bar_win.direct( 66,
1,
0x4E,
form( "- %02d %s %d ",
date[ 0 ],
months_short[ date[ 1 ] ],
date[ 2 ] + 1900 ) ); // Y2K OKAY!
event_win.setPos(1,1);
event_win.attrib( EVENT_LABEL );
event_win << " Next Event: ";
event_win.attrib( EVENT_DATA );
if ( nextevent.enabled )
{
event_win << form( "%s %02d:%02d (%d min) ",days_short[nextevent.nextday()],nextevent.start[0],nextevent.start[1],nextevent.minutesleft());
}
else
{
event_win << "-NONE-";
}
event_win.attrib( EVENT_LABEL );
event_win << "\n\n\n Time idle: ";
event_win.attrib( EVENT_DATA );
event_win << form( "%ld min", (::time(NULL)-start_time)/60);
}
if(init_sent && (::time(NULL)-init_sent)>5 && !initialized)
{
if(!blanked) stat_win.clear();
if(init_tries>3)
{
if(!blanked) tsw_centerline(STAT_LINE_Y,"Unable to initialize modem",0xE);
response->port = -1;
break;
}
if(!blanked) tsw_centerline(STAT_LINE_Y,form("Unable to initialize modem. Retrying (Try #%d)",init_tries+1),0x8E);
initialized = FALSE;
init1_sent = FALSE;
init2_sent = FALSE;
init3_sent = FALSE;
init_sent = 0;
}
if(!initialized)
{
if(!init1_sent)
{
if(modem_cfg->cmdInit1[0])
{
modem.cmd(modem_cfg->cmdInit1);
init1_ok = FALSE;
}
init1_sent = TRUE;
init_sent = ::time(NULL);
}
if(!init2_sent && init1_ok)
{
if(modem_cfg->cmdInit2[0])
{
modem.cmd(modem_cfg->cmdInit2);
init2_ok = FALSE;
}
else
{
init2_ok = TRUE;
}
init2_sent = TRUE;
init_sent = ::time(NULL);
}
if(!init3_sent && init2_sent && init2_ok)
{
if(modem_cfg->cmdInit3[0])
{
modem.cmd(modem_cfg->cmdInit3);
init3_ok = FALSE;
}
else
{
init3_ok = TRUE;
}
init3_sent = TRUE;
init_sent = ::time(NULL);
init_tries++;
}
}
if(!initialized && init1_ok && init2_ok && init3_ok)
{
initialized = TRUE;
stat_win.clear();
tsw_centerline(STAT_LINE_Y,"Waiting for a call",0xE);
bar_win.direct( 3, 1, 0x4E, "Alt-L" );
bar_win.direct( 8, 1, 0x4F, "=Local" );
bar_win.direct( 16, 1, 0x4E, "Alt-J" );
bar_win.direct( 21, 1, 0x4F, "=Jump to DOS" );
bar_win.direct( 35, 1, 0x4E, "Esc" );
bar_win.direct( 38, 1, 0x4F, "=Exit" );
//----------------------------------------------
// This line of code is used to show the current
// screen saver timeout (debuging only)
//----------------------------------------------
//bar_win.direct( 50, 1, form( "%ld", (long) modem_cfg->blankTime ) );
}
if(init_sent && (::time(NULL)-init_sent) > 300)
{
initialized = FALSE;
init1_sent = FALSE;
init2_sent = FALSE;
init3_sent = FALSE;
init_sent = 0;
init_tries = 0;
}
if(modem.check_response(s))
{
s << '|';
if(blanked)
{
tsw_puttext(blank_buf,1,1,tsw_hsize,tsw_vsize);
blanked = FALSE;
blank_start = ::time(NULL);
}
if(init1_sent && !init1_ok && s==modem_cfg->cmdInit1)
continue;
if(init2_sent && !init2_ok && s==modem_cfg->cmdInit2)
continue;
if(init3_sent && !init3_ok && s==modem_cfg->cmdInit3)
continue;
s.delLast();
resp_win << form("%-17.17s",(char *)s) << '\n';
s << '|';
if(strstr(s,modem_cfg->msgOk) && !initialized)
{
if(init1_sent && !init1_ok)
init1_ok = TRUE;
if(init2_sent && !init2_ok)
init2_ok = TRUE;
if(init3_sent && !init3_ok)
init3_ok = TRUE;
}
if(initialized)
{
String connect = s;
long baud = 0;
if(modem_cfg->msgRing[0] && strstr(connect,modem_cfg->msgRing) && (modem_cfg->flags & MODEM_MANUAL_ANSWER))
{
modem.cmd(modem_cfg->cmdAnswer);
}
if(!baud && modem_cfg->userConBps1 && strstr(connect,modem_cfg->msgConUser1) && modem_cfg->msgConUser1[0]) baud = modem_cfg->userConBps1;
if(!baud && modem_cfg->userConBps2 && strstr(connect,modem_cfg->msgConUser2) && modem_cfg->msgConUser2[0]) baud = modem_cfg->userConBps2;
if(!baud && modem_cfg->userConBps3 && strstr(connect,modem_cfg->msgConUser3) && modem_cfg->msgConUser3[0]) baud = modem_cfg->userConBps3;
if(!baud && modem_cfg->userConBps4 && strstr(connect,modem_cfg->msgConUser4) && modem_cfg->msgConUser4[0]) baud = modem_cfg->userConBps4;
if(!baud && modem_cfg->userConBps5 && strstr(connect,modem_cfg->msgConUser5) && modem_cfg->msgConUser5[0]) baud = modem_cfg->userConBps5;
if(!baud && modem_cfg->userConBps6 && strstr(connect,modem_cfg->msgConUser6) && modem_cfg->msgConUser6[0]) baud = modem_cfg->userConBps6;
if(!baud && strstr(connect,modem_cfg->msgCon115200)&& modem_cfg->msgCon115200[0])baud = 115200L;
if(!baud && strstr(connect,modem_cfg->msgCon64000) && modem_cfg->msgCon64000[0]) baud = 64000L;
if(!baud && strstr(connect,modem_cfg->msgCon57600) && modem_cfg->msgCon57600[0]) baud = 57600L;
if(!baud && strstr(connect,modem_cfg->msgCon38400) && modem_cfg->msgCon38400[0]) baud = 38400L;
if(!baud && strstr(connect,modem_cfg->msgCon36000) && modem_cfg->msgCon36000[0]) baud = 36000L;
if(!baud && strstr(connect,modem_cfg->msgCon33600) && modem_cfg->msgCon33600[0]) baud = 33600L;
if(!baud && strstr(connect,modem_cfg->msgCon31200) && modem_cfg->msgCon31200[0]) baud = 31200L;
if(!baud && strstr(connect,modem_cfg->msgCon28800) && modem_cfg->msgCon28800[0]) baud = 28800L;
if(!baud && strstr(connect,modem_cfg->msgCon26400) && modem_cfg->msgCon26400[0]) baud = 26400L;
if(!baud && strstr(connect,modem_cfg->msgCon24000) && modem_cfg->msgCon24000[0]) baud = 24000L;
if(!baud && strstr(connect,modem_cfg->msgCon21600) && modem_cfg->msgCon21600[0]) baud = 21600L;
if(!baud && strstr(connect,modem_cfg->msgCon19200) && modem_cfg->msgCon19200[0]) baud = 19200L;
if(!baud && strstr(connect,modem_cfg->msgCon16800) && modem_cfg->msgCon16800[0]) baud = 16800L;
if(!baud && strstr(connect,modem_cfg->msgCon14400) && modem_cfg->msgCon14400[0]) baud = 14400L;
if(!baud && strstr(connect,modem_cfg->msgCon12000) && modem_cfg->msgCon12000[0]) baud = 12000L;
if(!baud && strstr(connect,modem_cfg->msgCon9600 ) && modem_cfg->msgCon9600[0] ) baud = 9600L;
if(!baud && strstr(connect,modem_cfg->msgCon7200 ) && modem_cfg->msgCon7200[0] ) baud = 7200L;
if(!baud && strstr(connect,modem_cfg->msgCon4800 ) && modem_cfg->msgCon4800[0] ) baud = 4800L;
if(!baud && strstr(connect,modem_cfg->msgCon2400 ) && modem_cfg->msgCon2400[0] ) baud = 2400L;
if(!baud && strstr(connect,modem_cfg->msgCon1200 ) && modem_cfg->msgCon1200[0] ) baud = 1200L;
if(!baud && strstr(connect,modem_cfg->msgCon1275 ) && modem_cfg->msgCon1275[0] ) baud = 1200L;
if(!baud && strstr(connect,modem_cfg->msgCon300 ) && modem_cfg->msgCon300[0] ) baud = 300L;
if(baud)
{
stat_win.clear();
tsw_centerline(STAT_LINE_Y,form("Incoming call at %ld bps",baud),0xE);
response->baud = baud;
break;
}
if(modem_cfg->msgConExternal[0] && strstr(connect,modem_cfg->msgConExternal))
{
SCREEN.clear();
modem.modem::~modem();
exit(modem_cfg->externalErrorLevel);
}
}
}
if ( modem_cfg->blankTime &&
! blanked &&
( ::time( NULL ) - blank_start ) > modem_cfg->blankTime )
{
tsw_gettext(blank_buf,1,1,tsw_hsize,tsw_vsize);
tsw_fillscreen(' ',0);
blanked = TRUE;
}
if( nextevent.minutesleft()==0 && nextevent.start[0]==time[0]
&& nextevent.start[1]==time[1] && time[2]<=1
&& nextevent.node == node_number)
{
modem.modem::~modem();
SCREEN.clear();
if(nextevent.type)
{
String s = "*=*Q*N*C /C ";
s << nextevent.command;
shell(s);
exit(0);
}
else
{
exit(nextevent.errorlevel);
}
}
if(KB.hit())
{
if(blanked)
{
tsw_puttext(blank_buf,1,1,tsw_hsize,tsw_vsize);
blanked = FALSE;
blank_start = ::time(NULL);
}
KEY k=KB.get();
if(k==KEY_ALTL)
{
stat_win.clear();
tsw_centerline(STAT_LINE_Y,"Local login",0xE);
modem.cmd(modem_cfg->cmdOffHook);
response->baud = 0;
sleep(1);
break;
}
if(k==KEY_ESC)
{
stat_win.clear();
tsw_centerline(STAT_LINE_Y,"Exit",0xE);
modem.cmd(modem_cfg->cmdDown);
sleep(1);
modem.modem::~modem();
SCREEN.clear();
exit(99);
}
if(k==KEY_ALTJ)
{
tsw_gettext(blank_buf,1,1,tsw_hsize,tsw_vsize);
tsw_cursoron();
SCREEN.clear();
modem.cmd(modem_cfg->cmdOffHook);
shell("*X*C*N*Q");
tsw_cursoroff();
tsw_puttext(blank_buf,1,1,tsw_hsize,tsw_vsize);
initialized = FALSE;
init1_sent = FALSE;
init2_sent = FALSE;
init3_sent = FALSE;
init_sent = 0;
init_tries = 0;
}
}
if(!access(form("%sDOWN.%d",syspath,node_number),0))
{
stat_win.clear();
tsw_centerline(STAT_LINE_Y,"Going down on external request",0xE);
LOG("Going down on external request");
modem.cmd(modem_cfg->cmdDown);
sleep(1);
modem.modem::~modem();
SCREEN.clear();
File f;
f.open(form("%sISDOWN.%d",syspath,node_number),fmode_create|fmode_write);
f.close();
exit(100);
}
static int timeslice_count = 0;
if(!(++timeslice_count % 20))
DV_timeslice();
}
tsw_cursoron();
delete modem_cfg;
delete [] blank_buf;
bar_win.close();
resp_win.close();
lc_win.close();
stat_win.close();
event_win.close();
dlg_win.close();
SCREEN.clear();
return (response->port<0) ? FALSE:TRUE;
}

BIN
MODEM.OBJ Normal file

Binary file not shown.

679
MSG.CPP Normal file
View File

@ -0,0 +1,679 @@
#define Use_MsgBase
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "proboard.hpp"
Message::Message( int n )
{
clear();
msgArea = new MsgArea;
if ( n )
{
msgArea->read( n );
}
}
Message::Message( Message *p,
int n )
{
if ( p != this )
{
memcpy( this,
p,
sizeof( *p ) );
}
msgArea = new MsgArea;
if ( n )
{
msgArea->read( n );
}
}
void Message::clear()
{
MsgArea *ma = msgArea;
CLEAR_OBJECT( *this );
msgArea = ma;
}
Message::~Message()
{
delete msgArea;
}
bool Message::readAccess()
{
if ( ! check_access( msgArea->readLevel,
msgArea->readFlags,
msgArea->readFlagsNot ) &&
!msgArea->sysopAccess() )
{
return FALSE;
}
if ( attr & MSGATTR_PRIVATE )
{
return ! ( strcmpl( to, user.name ) &&
strcmpl( from, user.name ) &&
(
strcmpl( to, user.alias ) ||
! msgArea->flags
)
&&
(
strcmpl( from, user.alias ) ||
! msgArea->flags
)
&&
! msgArea->sysopAccess() );
}
else
{
return TRUE;
}
}
int Message::areaNum()
{
return msgArea->areaNum;
}
bool Message::setArea( int n )
{
bool r = msgArea->read( n );
if ( ! r )
{
msgArea->areaNum = 0;
}
return r;
}
bool Message::read( long n,
int a )
{
if ( a )
{
if ( ! msgArea->read( a ) )
{
return FALSE;
}
}
long actual_n = msgBase()->readMsg( *this, n );
return ( n == actual_n )
? TRUE
: FALSE;
}
void Message::setFlag( dword msgflag )
{
if ( msgflag & MSGATTR_RECEIVED )
{
recvDate.today();
recvTime.now();
}
attr |= msgflag;
msgBase()->updateMsg( *this );
}
void Message::clearFlag( dword msgflag )
{
attr &= ~msgflag;
msgBase()->updateMsg( *this );
}
void Message::toggleFlag( dword msgflag )
{
attr ^= msgflag;
msgBase()->updateMsg( *this );
}
void clearmarked( char * )
{
markedmsglist.clear();
io << "\n\n"
<< S_UNMARKED_ALL_MESSAGES
<< ' '
<< S_PRESS_ENTER_TO_CONTINUE;
}
void Message::addOrigin()
{
aka a;
bool echo_area = FALSE;
File fo;
File fi( "MSGTMP", fmode_text );
if ( ! fi.opened() )
{
return;
}
fo.open( "MSGTMP.$$$",
fmode_create | fmode_text );
if ( msgArea->msgKind == MSG_NET )
{
a.read( msgArea->aka );
origZone = a.zone;
origNet = a.net;
origNode = a.node;
origPoint = a.point;
if ( msgArea->msgBaseType != MSGBASE_JAM )
{
if ( origPoint )
{
fo << form( "\1FMPT %d\n",
origPoint );
}
if ( destPoint )
{
fo << form( "\1TOPT %d\n",
destPoint );
}
}
}
if ( msgArea->msgKind == MSG_ECHO ||
msgArea->msgKind == MSG_PVTECHO )
{
a.read( msgArea->aka );
origZone = destZone = a.zone;
origNet = destNet = a.net;
origNode = destNode = a.node;
origPoint = destPoint = a.point;
echo_area = TRUE;
}
bool blankline = FALSE;
for ( ; ; )
{
String line;
String copiedline;
line = fi.readLine();
if ( line[ 0 ] == '\0' )
{
break;
}
line.delLast( '\n' );
copiedline = line;
copiedline.trim();
if ( line.len() >= 4 )
{
if ( ! strncmp( copiedline,
"--- ",
4 ) )
{
//-------------------
// Get rid of tagline
//-------------------
break;
}
if ( ! strncmp( copiedline,
"* Origin",
8 ) )
{
//------------------------
// Stop when *Origin found
//------------------------
break;
}
}
if ( ! strcmp( copiedline, "---" ) )
{
line.clear();
}
if ( line[ 0 ] != '\x01' )
{
fo << line
<< '\n';
}
blankline = ( line[ 0 ] == '\0' );
}
//----------------------------
// JDR: REGISTRATION REFERENCE
//----------------------------
if ( ! registered &&
(
pastFirstUse < 0 ||
pastFirstUse > 60
)
)
{
if ( pastFirstUse < 0 )
{
pastFirstUse = 61;
}
if ( ! blankline )
{
fo << '\n';
}
char *unr_str = "...This copy of ProBoard has been unregistered for %d days!\n\n";
if ( crc32( unr_str ) != 0xB3328DC5L )
{
exit_proboard();
}
fo << form( unr_str, pastFirstUse );
blankline = TRUE;
}
if ( echo_area )
{
if ( ! blankline )
{
fo << '\n';
}
fo << "--- ProBoard v" TEARVERSION;
//----------------------------
// JDR: REGISTRATION REFERENCE
//----------------------------
if ( registered )
{
fo << " [Reg]";
}
else
{
fo << " [EVALUATION]";
}
fo << "\n * Origin: ";
if ( msgArea->origin[ 0 ] )
{
fo << msgArea->origin;
}
else
{
fo << cfg.originline;
}
fo << form( " (%d:%d/%d",
a.zone,
a.net,
a.node );
if ( a.point )
{
fo << form( ".%d)\n", a.point );
}
else
{
fo << ")\n";
}
}
fo.close();
fi.close();
unlink( "MSGTMP" );
rename( "MSGTMP.$$$", "MSGTMP" );
}
long Message::add()
{
attr |= MSGATTR_LOCAL;
switch ( msgArea->msgKind )
{
case MSG_NET:
attr |= MSGATTR_NETMAIL;
break;
case MSG_PVTECHO:
case MSG_ECHO:
attr |= MSGATTR_ECHOMAIL;
break;
}
addOrigin();
if ( msgArea->tag[ 0 ] )
{
File f( FileName( syspath, "ECHOTOSS.LOG" ),
fmode_text |
fmode_copen |
fmode_rw |
fmode_append );
if ( f.opened() )
{
f << msgArea->tag
<< '\n';
}
}
long n = msgBase()->appendMsg( *this );
if ( n < 1 )
{
return -1;
}
switch ( msgArea->msgKind )
{
case MSG_NET:
net_entered++;
break;
case MSG_PVTECHO:
case MSG_ECHO:
echo_entered++;
break;
}
return n;
}
void Message::addReply( Message &org )
{
Message msg( org.areaNum() );
long n = org.id;
if ( ! msg.read( n ) )
{
return;
}
while ( msg.next )
{
if ( ! msg.read( msg.next ) )
{
break;
}
}
prev = msg.id;
msgBase()->updateMsg( *this );
msg.next = id;
msg.msgBase()->updateMsg( msg );
}
void Message::delReply()
{
Message msg( areaNum() );
if ( prev )
{
if ( msg.read( prev ) )
{
msg.next = next;
msg.msgBase()->updateMsg( msg );
}
}
if ( next )
{
if ( msg.read( next ) )
{
msg.prev = prev;
msg.msgBase()->updateMsg( msg );
}
}
if ( next ||
prev )
{
next = 0;
prev = 0;
msgBase()->updateMsg( *this );
}
}
int Message::pointNum( int mode )
{
if ( msgArea->msgBaseType != MSGBASE_HUDSON )
{
if ( mode )
{
return destPoint;
}
else
{
return origPoint;
}
}
String s;
int inkludge = 0;
bool msgdone = FALSE;
for ( long txt_off = 0; ! msgdone; txt_off += 255 )
{
char rec[ 256 ];
int l = readText( rec,
txt_off,
255 );
if ( l < 255 )
{
msgdone = TRUE;
}
for ( int j = 0; j < l; j++ )
{
switch ( rec[ j ] )
{
case '\n':
break;
case '\r':
if ( inkludge )
{
s.upperCase();
if ( mode )
{
if ( ! strncmp( s,
"TOPT",
4 ) )
{
return atoi(&s[5]);
}
}
else
{
if ( ! strncmp( s,
"FMPT",
4 ) )
{
return atoi( & s[ 5 ] );
}
}
}
inkludge = 0;
s = "";
break;
case 1:
s = "";
inkludge = 1;
break;
default:
if ( inkludge )
{
s << char( rec[ j ] );
}
break;
}
}
}
return 0;
}
void write_msgtmp( char *s )
{
File f( "MSGTMP", fmode_create );
f << s;
}

BIN
MSG.OBJ Normal file

Binary file not shown.

119
MSGAREA.CPP Normal file
View File

@ -0,0 +1,119 @@
#define Use_MsgBase
#include <string.h>
#include "proboard.hpp"
File MsgArea::f;
int MsgArea::lastAreaNum = -1;
int MsgArea::numAreas = -1;
MsgArea *MsgArea::lastArea = NULL;
void
MsgArea::open()
{
if(!f.opened())
{
if(!f.open(FN_MSGAREAS_PRO,fmode_read,cfg.fastmode ? BUFSIZE_FAST:BUFSIZE_SLOW))
file_error(FN_MSGAREAS_PRO);
numAreas = int(f.len() / sizeof(_MsgArea));
}
}
bool
MsgArea::read(int a)
{
open();
msgBase = NULL;
if(a<1 || a>numAreas) return FALSE;
if(lastArea == NULL)
{
lastArea = new MsgArea;
lastAreaNum = -1;
}
if(a != lastAreaNum)
{
f.seek(long(a-1) * sizeof(_MsgArea));
if( f.read(lastArea,sizeof(_MsgArea)) != sizeof(_MsgArea)
|| lastArea->name[0] == '\0' )
{
lastAreaNum = -1;
return FALSE;
}
switch(lastArea->msgBaseType)
{
case MSGBASE_SDM :
case MSGBASE_SQUISH: lastArea->msgBase = squishMsgBase;
break;
case MSGBASE_JAM : lastArea->msgBase = jamMsgBase;
break;
case MSGBASE_HUDSON: lastArea->msgBase = hudsonMsgBase;
if((a<1 || a>200) && lastArea->name[0])
{
LOG("Message area %d: Hudson type not allowed",a);
return FALSE;
}
break;
default : LOG("Bad message base type for area #%d",a);
return FALSE;
}
}
(*this) = (*lastArea);
if(msgBaseType != MSGBASE_HUDSON)
{
append_backspace(path);
if(msgBaseType != MSGBASE_SDM) path[strlen(path)-1] = '\0';
}
lastAreaNum = areaNum;
if(!sysop[0]) strcpy(sysop,cfg.sysopname);
if(!replyBoard) replyBoard = areaNum;
strip_trailing( name );
strip_leading( name );
return (name[0]) ? TRUE:FALSE;
}
void
MsgArea::close()
{
f.close();
if(lastArea != NULL) delete lastArea;
lastAreaNum = -1;
numAreas = -1;
lastArea = NULL;
}
int
MsgArea::highAreaNum()
{
open();
return numAreas;
}
bool
MsgArea::sysopAccess()
{
return ( check_access(sysopLevel,sysopFlags,sysopFlagsNot)
|| !strcmpl(sysop,user.name)
|| !strcmpl(cfg.sysopname,user.name)
);
}

BIN
MSGAREA.OBJ Normal file

Binary file not shown.

82
MSGBASE.CPP Normal file
View File

@ -0,0 +1,82 @@
#define Use_MsgBase
#include "proboard.hpp"
MsgBaseList::MsgBaseList()
{
mblist[0] = NULL;
}
void
MsgBaseList::add(MsgBase *mb)
{
for(int i=0; mblist[i] ; i++) {}
mblist[i] = mb;
mblist[i+1] = NULL;
}
MsgBaseList::~MsgBaseList()
{
for(int i=0; mblist[i] ; i++) delete mblist[i];
}
void
MsgBaseList::open()
{
for(int i=0 ; mblist[i] ; i++) mblist[i]->open();
}
void
MsgBaseList::close()
{
for(int i=0 ; mblist[i] ; i++) mblist[i]->close();
MsgArea::close();
}
bool
MsgBaseList::lock()
{
for(int i=0 ; mblist[i] ; i++)
if(!mblist[i]->lock())
return FALSE;
return TRUE;
}
bool
MsgBaseList::unlock()
{
for(int i=0 ; mblist[i] ; i++)
if(!mblist[i]->unlock())
return FALSE;
return TRUE;
}
word
MsgBaseList::scanMail(MessageIndex *mi,word maxmsgs)
{
word left = maxmsgs;
for(int i=0; mblist[i] ; i++)
{
if(left>0) left -= mblist[i]->scanMail(&mi[maxmsgs-left],left);
}
return maxmsgs-left;
}
long
MsgBaseList::totalMsgs()
{
long total = 0;
for(int i=0; mblist[i] ; i++)
{
total += mblist[i]->totalMsgs();
}
return total;
}

433
MSGBASE.HPP Normal file
View File

@ -0,0 +1,433 @@
class Message;
class MsgBase;
class SquishMsgBase;
class HudsonMsgBase;
class JamMsgBase;
class MsgArea;
class MessageIndex;
class HudsonMsgIdx;
class HudsonMsgHdr;
class HudsonMsgToIdx;
class HudsonMsgInfo;
class JamFileHeader;
class JamHeader;
class JamExtHeader;
class JamIndex;
class JamLastRead;
class MsgBase
{
public:
MsgBase() {}
virtual ~MsgBase() {}
virtual bool open() = 0;
virtual void close() = 0;
virtual bool lock() { return TRUE; }
virtual bool unlock() { return TRUE; }
virtual long readMsg(Message& msg , long num) = 0;
virtual word readMsgText(Message& msg, char *text, long offset , word size) = 0;
virtual word scanMail(MessageIndex *mi,word maxmsgs) = 0;
virtual long appendMsg(Message&) = 0;
virtual bool updateMsg(Message&) = 0;
virtual long highMsg(MsgArea&) = 0;
virtual long lowMsg (MsgArea&) = 0;
virtual long numMsgs(MsgArea&) = 0;
virtual long totalMsgs() = 0;
virtual bool deleteMsg(Message&) = 0;
virtual long lastRead(MsgArea&,long rec) = 0;
virtual void setLastRead(MsgArea&,long rec,long num) = 0;
virtual long msgNum(MsgArea&,long id) = 0;
virtual long msgId (MsgArea&,long num) = 0;
};
class SquishMsgBase : public MsgBase
{
MSG *lastarea;
int lastareanum;
MSG *readArea(MsgArea&);
public:
SquishMsgBase() { open(); }
~SquishMsgBase() { close(); }
bool open();
void close();
bool lock() { return TRUE; }
bool unlock() { return TRUE; }
long readMsg(Message& msg , long num);
word readMsgText(Message& msg, char *text, long offset , word size);
word scanMail(MessageIndex *mi,word maxmsgs);
long appendMsg(Message&);
bool updateMsg(Message&);
long highMsg(MsgArea&);
long lowMsg (MsgArea&);
long numMsgs(MsgArea&);
long totalMsgs() { return 0; }
bool deleteMsg(Message&);
long lastRead(MsgArea&,long rec);
void setLastRead(MsgArea&,long rec,long num);
long msgNum(MsgArea&,long id);
long msgId (MsgArea&,long num);
};
class HudsonMsgBase : public MsgBase
{
File f_msghdr;
File f_msgtxt;
File f_msgtoidx;
File f_msgidx;
File f_msginfo;
HudsonMsgIdx *lastMsgIdx;
int *highArray;
int *lastReadArray;
long lastIndex;
long lastReadRecord;
///////////////////
void flushCache();
void readHighArray();
void readLastRead(long record);
void readInfo(HudsonMsgInfo&);
void writeInfo(HudsonMsgInfo&);
long findIdx(HudsonMsgIdx &mi,int num,int area,int order);
public:
HudsonMsgBase();
~HudsonMsgBase();
bool open();
void close();
bool lock();
bool unlock();
long readMsg(Message& msg , long num);
word readMsgText(Message& msg, char *text, long offset , word size);
word scanMail(MessageIndex *mi,word maxmsgs);
long appendMsg(Message&);
bool updateMsg(Message&);
long highMsg(MsgArea&);
long lowMsg (MsgArea&);
long numMsgs(MsgArea&);
long totalMsgs();
bool deleteMsg(Message&);
long lastRead(MsgArea&,long rec);
void setLastRead(MsgArea&,long rec,long num);
long msgNum(MsgArea&,long id);
long msgId(MsgArea& ma, long num);
};
class JamMsgBase : public MsgBase
{
File f_jhr;
File f_jdt;
File f_jdx;
File f_jlr;
int lastAreaNum;
JamFileHeader *jamHeader;
bool openArea( MsgArea& );
bool jamLock();
bool jamUnLock();
bool readHeader();
bool writeHeader();
long findIdx( JamIndex &mi,long num,int order );
public:
JamMsgBase();
~JamMsgBase();
bool open();
void close();
bool lock() { return TRUE; }
bool unlock() { return TRUE; }
long readMsg(Message& msg , long num);
word readMsgText(Message& msg, char *text, long offset , word size);
word scanMail(MessageIndex *mi,word maxmsgs);
long appendMsg(Message&);
bool updateMsg(Message&);
long highMsg(MsgArea&);
long lowMsg (MsgArea&);
long numMsgs(MsgArea&);
long totalMsgs()
{
return 0;
}
bool deleteMsg(Message&);
long lastRead(MsgArea&,long rec);
void setLastRead(MsgArea&,long rec,long num);
long msgNum(MsgArea&,long id);
long msgId (MsgArea&,long num);
};
class MsgBaseList
{
MsgBase *mblist[5];
public:
MsgBaseList();
~MsgBaseList();
void add(MsgBase *);
void close();
void open();
bool lock();
bool unlock();
word scanMail(MessageIndex *,word maxmsgs);
long totalMsgs();
};
class MsgArea : public _MsgArea
{
static File f;
static int lastAreaNum;
static MsgArea *lastArea;
static int numAreas;
static void open();
public:
MsgBase *msgBase;
bool read(int);
bool sysopAccess();
static void close();
static int highAreaNum();
long numMsgs()
{
return (msgBase==NULL) ? 0L : msgBase->numMsgs(*this);
}
long lowMsg()
{
return (msgBase==NULL) ? 0L : msgBase->lowMsg (*this);
}
long highMsg()
{
return (msgBase==NULL) ? 0L : msgBase->highMsg(*this);
}
long lastRead(long rec)
{
return (msgBase==NULL) ? 0L : msgBase->lastRead(*this,rec);
}
void setLastRead(long rec,long num)
{
if(msgBase)
msgBase->setLastRead(*this,rec,num);
}
long msgNum(long id)
{
return (msgBase==NULL) ? 0L : msgBase->msgNum(*this,id);
}
long msgId (long num)
{
return (msgBase==NULL) ? 0L : msgBase->msgId(*this,num);
}
};
const dword MSGATTR_PRIVATE = 0x00000001L;
const dword MSGATTR_RECEIVED = 0x00000002L;
const dword MSGATTR_DELETED = 0x00000004L;
const dword MSGATTR_NETMAIL = 0x00000008L;
const dword MSGATTR_UNSENT_ECHO = 0x00000010L;
const dword MSGATTR_UNSENT_NET = 0x00000020L;
const dword MSGATTR_LOCAL = 0x00000040L;
const dword MSGATTR_KILL = 0x00000080L;
const dword MSGATTR_CRASH = 0x00000100L;
const dword MSGATTR_SENT = 0x00000200L;
const dword MSGATTR_FILE = 0x00000400L;
const dword MSGATTR_FILEREQ = 0x00000800L;
const dword MSGATTR_AUDITREQ = 0x00001000L;
const dword MSGATTR_RECEIPTREQ = 0x00002000L;
const dword MSGATTR_TRANSIT = 0x00004000L;
const dword MSGATTR_HOLD = 0x00008000L;
const dword MSGATTR_IMMEDIATE = 0x00010000L;
const dword MSGATTR_DIRECT = 0x00020000L;
const dword MSGATTR_TRUNCFILE = 0x00040000L;
const dword MSGATTR_DELFILE = 0x00080000L;
const dword MSGATTR_ORPHAN = 0x00100000L;
const dword MSGATTR_ECHOMAIL = 0x00200000L;
const dword MSGATTR_NODISP = 0x00400000L;
const dword MSGATTR_LOCKED = 0x00800000L;
struct Message
{
long num;
dword id; // for Squish only, others -> == num
char from[36];
char to [36];
char subj[66];
dword attr;
Date postDate;
Time postTime;
Date recvDate;
Time recvTime;
long next;
long prev;
int origZone,
origNet,
origNode,
origPoint;
int destZone,
destNet,
destNode,
destPoint;
int cost;
/************************************************************/
static long lastIndex;
union {
MsgArea *msgArea;
int area;
};
Message(int area = 0);
Message(Message *, int area = 0);
~Message();
int areaNum() ;
MsgBase *msgBase()
{
return msgArea->msgBase;
}
void clear();
bool setArea (int num);
bool read (long num, int area = 0);
bool readFirst(int method,int order,long first,char *data,int area = 0);
bool readNext (int method,int order,char *data);
bool readPrev (int method,int order,char *data);
word readText(char *text,long offset,word size)
{
return msgBase()->readMsgText(*this, text, offset , size);
}
void createMsgTextFile(char *fname , bool append);
void createMsgTextString(char *string , word maxsize);
void export(char *fname);
void forward();
void move();
void setFlag (dword msgflag);
void clearFlag (dword msgflag);
void toggleFlag(dword msgflag);
bool testFlag (dword msgflag) { return (attr & msgflag) ? TRUE:FALSE; }
void operator=(HudsonMsgHdr&);
void addReply(Message&);
void delReply();
void remove();
byte show();
void addOrigin();
int pointNum(int mode);
long add();
long msgNum() { return msgBase()->msgNum(*msgArea,id); }
bool readAccess();
};
struct MessageIndex
{
MessageIndex() {}
MessageIndex(int a,long n) { area = a; num = n; }
int area;
long num;
};
class MarkedMsgList
{
MessageIndex *msgList;
int n;
public:
MarkedMsgList();
MarkedMsgList(const MarkedMsgList&);
~MarkedMsgList();
void operator=(const MarkedMsgList&);
bool add(MessageIndex&);
bool add(Message&);
void clear() { n = 0; }
bool remove(MessageIndex&);
void sort();
int numMarked() { return n; }
bool isMarked(MessageIndex&);
MessageIndex getMarked(int n) { return msgList[n]; }
MessageIndex operator[](int n) { return msgList[n]; }
};
const int MAX_MARKED_MSGS = 500;
extern MsgBase *squishMsgBase;
extern MsgBase *hudsonMsgBase;
extern MsgBase *jamMsgBase;
extern MsgBaseList msgbase;
extern MarkedMsgList markedmsglist;
void get_new_msgs(MarkedMsgList& marked,int area);
inline long
HudsonMsgBase::msgNum(MsgArea&,long id)
{
return id;
}
inline long
HudsonMsgBase::msgId(MsgArea&, long num)
{
return num;
}

BIN
MSGBASE.OBJ Normal file

Binary file not shown.

12
MSGDEL.CPP Normal file
View File

@ -0,0 +1,12 @@
#define Use_MsgBase
#include <string.h>
#include "proboard.hpp"
void
Message::remove()
{
if(next || prev) delReply();
if(!msgBase()->deleteMsg(*this)) LOG("Error deleting message");
}

Some files were not shown because too many files have changed in this diff Show More