Updated to 2.22 and now Freeware! Four year date formats for birth dates
This commit is contained in:
parent
ccaec1e634
commit
d5afd506b8
|
@ -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;
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
# # #
|
||||
----------------------------------------------------------------------------
|
|
@ -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":"[0;37m\xFF");
|
||||
else
|
||||
io << (avatar?"\x16\x01\x0B\xFF":"[1;36m\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;
|
||||
}
|
|
@ -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();
|
||||
}
|
Binary file not shown.
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
extern "C"
|
||||
{
|
||||
void DV_timeslice();
|
||||
void DV_start_critical();
|
||||
void DV_end_critical();
|
||||
}
|
|
@ -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
|
||||
|
Binary file not shown.
|
@ -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,¶m[i][4]);
|
||||
else
|
||||
input_files.add(InputFile(¶m[i][3]));
|
||||
}
|
||||
else
|
||||
{
|
||||
input_files.add(InputFile(¶m[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 = ¶m[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;
|
||||
}
|
|
@ -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,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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
|
Binary file not shown.
|
@ -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
|
||||
|
|
@ -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. |
|
||||
³ ³ ³ ³ ³ |
|
||||
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||||
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
*/
|
Binary file not shown.
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#define Use_Handlers
|
||||
#define Use_LinkedList
|
||||
|
||||
#include "proboard.hpp"
|
||||
|
||||
LinkedList<PEXhandle> sysopkey_handlers;
|
||||
LinkedList<PEXhandle> hangup_handlers;
|
Binary file not shown.
|
@ -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( "[0;34;47mAF%-2d - [0;31;47m%-27.27s[1;33;47m",
|
||||
i + 1,
|
||||
cfg.sysopkeys[ i ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
win << form( "[0;34;47mAF%-2d - [33;47m%-27.27s[1;33;47m",
|
||||
i + 1,
|
||||
"REGISTER NOW!" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SCREEN.setPos( SCREEN.getX(),
|
||||
SCREEN.getY() );
|
||||
|
||||
status = MACRO;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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};
|
||||
|
|
@ -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();
|
||||
}
|
Binary file not shown.
|
@ -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;
|
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
#include <stdlib.h>
|
||||
#include "proboard.hpp"
|
||||
|
||||
void
|
||||
lastcallers(char *data)
|
||||
{
|
||||
run_sdkfile(String("_LC ") + data);
|
||||
}
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -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';
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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,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)
|
|
@ -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";
|
||||
}
|
|
@ -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
|
|
@ -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 << "[1;36m\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 << "[0;37m\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");
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
Binary file not shown.
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -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
Loading…
Reference in New Issue