                                  Valence
                     Offline Mail System for Searchlight
                                version 1.7

                             Copyright (c) 1999
                             by William McBrine

             Written using the Searchlight Programmer's Library
              Portions Copyright (c) 1993 Searchlight Software



:::: INTRODUCTION ::::

This program gives your QWK users full support of Searchlight features
like included files, color codes, and metacharacters while reading
offline, as well as such QWK basics as Bulletins and Welcome, News, and
Goodbye files. It will also let you become a node or hub in a QWK network.
The setup is simple and flexible, using Squish's COMPRESS.CFG for
archivers and Searchlight's own definitions for protocols.  Valence is
also much faster than any other Searchlight offline mail door.

I won't give you an introduction to the idea of offline reading here; I
assume that if you're reading this, you know what it's about.  If not, you
may find some information in VALENCE.TXT.

I first started planning Valence in the summer of 1992, and did some of
the code then and sporadically afterwards, but most of the first version
was written in February and early March of 1993.

Valence is written in Borland Pascal 7.0, with considerable portions of
inline assembly.  It's a real-mode DOS program, which means it's
restricted to about 640K of memory usage.  (I'd put out a protected-mode
version, but first I'd have to replace the Searchlight Programmer's
Library.)  It should work on everything from an 8088 (where it was first
developed) on up.

Valence should work with all versions of Searchlight from 2.15C through
5.10 and beyond.  Of course, I assume NO responsibility if it annihilates
your board and ruins your life. :-)


:::: LICENSE AGREEMENT ::::

Valence is free software. You may make as many copies of this program as
you like, and use it on as many machines simultaneously as you like,
without paying me anything, as long as you're not making any money off of
it.  Commercial use requires a license.  This program may be freely
distributed, provided you charge no more than a minimal copying fee (say,
$5.00).  Distribution of the program at profit, or bundled with commercial
software, requires a license.  The archive must be distributed unmodified,
except for conversion to another archive format or addition of
ZIP/ARJ/etc. comments.  No files may be added within the archive, and none
of the files within the archive may be removed or modified.


:::: QUICK INSTALLATION/UPGRADE ::::

*** Upgrading from an earlier version ***

Just extract the new archive over the old files in the Valence directory,
or extract it to a temporary directory; then run:

install u

(As of version 1.6, you can omit the 'u' parameter.)

*** New installation ***

1. Extract the Valence archive.

2. Run INSTALL.EXE, and answer the questions.  That's it!  Example:

md valence
cd valence
pkunzip \fd\file\valen170
install

Unlike previous versions, Install v1.5 and later will optionally copy the
executables to a different directory, so you can extract the archive to a
temporary directory and install from there. As of 1.6, it will also create
the destination directory for you, if it doesn't already exist.

Install will create a new menu for Valence and place it on the menu of
your choice.  To make a DOORS.DEF-style installation instead (not
recommended), use the "d" parameter:

install d

Install also moves VALENCE.TXT to the Included files directory, so Valence
can send it to new users as BLT-0.0, and copies it to the text directory
as a help file.  This file uses Searchlight color codes and
metacharacters.

*** SLMAIL patch ***

Beginning in this version, Install will let you jump directly to the
SLMAIL patch, by invoking it as:

install p

It can also *undo* the patch, if you call it as:

install r

You may need to do this before upgrading from one version of Searchlight
to another, so the upgrade program won't get confused.

The patch is optional, but I recommend it.  For details, see the section
"SLMAIL.EXE/NETMAIL.EXE PATCH" below.

*** If you're using multiple conference lists ***

If you're swapping conference lists, you MUST do one of the following:

1. Combine all the lists into a single MAIN.SUB or VALENCE.SUB text file
   in the Valence directory, or

2. Install Valence separately for each list.  Repeat the basic
   installation process, making a directory for each installation, but
   make sure each new Valence menu has a DIFFERENT name.  Also be sure to
   use different BBSIDs.

   Valence will only read the file MAIN.SUB or VALENCE.SUB, and only from
   the Valence directory or the node directory.

*** If you're using ZMODEM.EXE ***

If you have the external ZMODEM program from Searchlight Software, AKA
SLZMODEM, and you've set it up as an external protocol, you need to add
"-C" to each ZMODEM.EXE command line in the protocol definitions.  This
option is only available with versions of SLZMODEM dated February 22, 1993
or later.


:::: SETUP DETAILS ::::

Valence itself may run within Searchlight's 250k minimum free memory, but
it will need more when it shells to an archiver.  Valence takes up about
140k when shelling to an archiver or protocol, and a variable amount over
243k the rest of the time.  (The amount depends on the number of
conferences you have.)  It also needs a lot of file handles to open; I
recommend setting FILES=xx in your CONFIG.SYS to some ungodly number.

*** Manual setup ***

With INSTALL.EXE, I hope you'll never have to look at the inside of a menu
file when setting up Valence.  But if you WANT to, details are as follows:

Valence should be run with com support turned ON.  On the menus, that
means either "Standard" or "Force Color".  (Force Color is used by
INSTALL.EXE.) In a DOORS.DEF-style file, it means "1" or "2" for the first
value. "Abort" should be set to NONE (0 for DOORS.DEF); Valence will
recognize when carrier is lost and recover by itself.  Needless to say,
write-protect should also be off.  For the directory setting, do NOT
specify the path to the Valence directory!  Use a "." to indicate the
current directory to Searchlight.  Then, in the "Command" field, specify
the full pathname to Valence (e.g., "C:\VALENCE\VALENCE.EXE").  Make sure
you include the ".EXE" extension, to save yourself some loading time and
memory.

Valence attempts to read CONFIG.SL2 from the current directory, then
checks the "SLBBS" environment variable.  With Valence, you DON'T NEED to
set this variable, though you may if you like.  Valence finds its own data
files in its .EXE directory, regardless what directory it was run from.

When run without parameters, Valence will pop up a simple menu.  When run
with a parameter, it will jump directly to one of the functions on that
menu.  The recognized parameters are:

'U': upload
'D': download
'O': set options
'S': edit conference list
'P': upload pointer files
'E': export to hub
'I': import from hub

Only the first letter is checked, and case is ignored.  INSTALL.EXE uses
the first five parameters to create a menu bar with six options on it (the
sixth being "Quit").  'E' and 'I' are only available from the command
line.

A sample DOORS.DEF line for Valence:

2;0;0;5;Valence QWK offline mail;.;C:\VALENCE\VALENCE.EXE

You can get variants of this by running "INSTALL D".  For a sample menu
entry, run INSTALL and examine the .MNU it produces ("VALENCE.MNU", by
default).  You can edit this like any other .MNU.  If you want to set
attributes for Valence as well as access levels, you'll also have to edit
the menu THAT menu is entered on; INSTALL.EXE doesn't ask for attributes.

*** Multiple conference lists ***

This is a tricky one.  If you're using more than one conference list, and
swapping them, you have to kludge around it.  You can either combine the
conference lists into one MAIN.SUB or VALENCE.SUB file and place it in the
Valence directory, or make separate Valence installations to correspond to
each conference list.  If you DON'T do this, you'll get people uploading
replies to the wrong conferences.

I strongly recommend combining the conference lists.  But if you want to
maintain truly separate sub-BBSes, you have make multiple installations of
Valence.  When doing this, make sure you enter a name other than "Valence"
at the "Command name [Valence]:" prompt in INSTALL.EXE for the second and
subsequent installations.  Each installation must have its own directory,
its own BBSID, and its own MAIN.SUB file in its directory.

You can mix and match these methods.  Say you have three conference lists:

LOCAL.SUB
FIDO.SUB
ADULT.SUB

And say your board is named "My BBS".  You might set up Valence twice; in
the first installation, say in directory "C:\VALENCE", you can combine
LOCAL.SUB and FIDO.SUB into the file "C:\VALENCE\MAIN.SUB", and use the
BBSID "MYBBS".  In the second installation, say in "C:\VAL-AD", you could
use the BBSID "MYADULT", and copy ADULT.SUB to "C:\VAL-AD\MAIN.SUB".

There's an option for users to turn off MAIN.SUB altogether, which avoids
the whole problem, but this could be regarded as a security breach.  My
advice is to have certain attributes required for access to each
conference not on the main list.  You're better off dividing your
conferences with attributes than with conference lists.

*** Further options ***

For advanced options, read the VALENCE.CFG section of this file (at the
end; Appendix A). This is an actual configuration file which you can cut
and paste, and use.  It explains all possible keywords for VALENCE.CFG.


:::: PROTOCOLS ::::

For external protocols, Valence uses Searchlight's own definitions.  If
they work in Searchlight, they should work in Valence.  (The one exception
to this, ironically, is ZMODEM.EXE from Searchlight Software.)  For
"internal" protocols, Valence searches the path (and the Valence
directory) for the files GSZ.EXE, DSZ.COM, DSZ.EXE, and ZMODEM.EXE, in
that order.

Bidirectional protocols are supported by scanning for uploaded .REPs after
each Download.

To work properly, your protocol driver must return a non-zero errorlevel
when a transfer fails.  If it doesn't, Valence will think the transfer has
succeeded, and update the user's pointers (and possibly delete their
mail). I've found that launching a .COM or .EXE file through COMMAND.COM
will destroy the errorlevel, so make sure you include the ".COM" or ".EXE"
extension in your setup to prevent that.  (Executing through COMMAND.COM
also takes longer and uses more memory.)  If you're using batch files,
make sure the protocol driver is called on the LAST line of the batch
file, and don't terminate that line with ^Z. Also, avoid using DSZ's
"slugbait" option.

The IntProt keyword (see VALENCE.CFG) lets you redefine any of the file
transfer protocols.


:::: ARCHIVERS ::::

For its archiver setup, Valence copies the COMPRESS.CFG used by Squish and
other programs.  INSTALL.EXE will scan the path for archiver programs and
set up COMPRESS.CFG automatically.  (Note: recent versions of Valence
incorporate this information into VALENCE.CFG instead, but you can still
use COMPRESS.CFG if you choose.)  If you're already using a COMPRESS.CFG
file with another program, you can make Valence use that one instead with
the "Compress" keyword in VALENCE.CFG.

Valence expects archivers, like protocol drivers, to return an errorlevel
of zero for success, non-zero for error.  This is less critical with
archivers than with protocol drivers.

The COMPRESS.CFG which comes with Squish doesn't include the .COM or .EXE
extensions on the archiver names, so the programs are launched through
"<comspec> /C"; if you're using it, you should add them.  Another
modification that'll speed things up is the inclusion of full pathnames
("C:\SQUEEZE\PKZIP.EXE").  Without a path, Valence will search DOS' path
for the program; with a path, it'll shell directly to it.

"View" and "End Archiver" lines are ignored by Valence.  Unlike Squish,
Valence does use the "Extension" field, but only in Text packet mode.  
Note the difference between the "Archiver" and "Extension" fields.


:::: BASIC OPERATION ::::

The basic operation is outlined in VALENCE.TXT, but there are a few
details which differ when you use it in local mode.

When Valence shells to an archiver or protocol, you'll see four numbers
displayed.  E.g.:

200840 200632

298000 298000

This isn't displayed remotely, only locally.  (Neither is the display from
the archiver or protocol.)  If Searchlight is set to BIOS display mode,
during the shell to the archiver, you won't see these numbers, nor the
archiver's output, but rather the same twirling cursor you'd see remotely.
The top two numbers are the amount of free memory and the size of the
largest free block before releasing the heap; the bottom two numbers are
the amount of free memory when shelling, and should both be the same.

*** Downloads ***

Instead of invoking a protocol to send the file, Valence will simply move
the file to the LocQWK directory, and rename it with a number appended if
need be.

*** Uploads ***

The .REP file is read from the LocREP directory.  While remote users can
use free-form names (anything with the .REP extension is accepted), local
users must use the form "<BBSID>.REP".

If you toggle on the Superuser flag, you can post messages From any user.

*** Pointers ***

Pointer files must be renamed to "<BBSID>.PTR" when used locally.  When
used remotely, "<BBSID>.PT*" are accepted.  .PTR files are retrieved from
the same directory as .REPs.


:::: USER EDITOR ::::

Valence now includes a user editor. Invoke it from the command line with
the "x" parameter, e.g. "valence\valence x". (I suggest you run it from a
directory with Searchlight's CONFIG.SL2, or have the SLBBS environment
variable defined.) This will let you change the attributes and area list
for each user, and is the only way to assign net status (see QWK
NETWORKING). (Be careful when toggling net status, as it will destroy any
options the user has set.) You can also purge all Valence users who are no
longer in the Searchlight user base, or delete or add users one at a time.
Special trick: you can use the "add user" function to jump to an existing
user by typing the name.

The user editor works much like the SubList. Mouse support is a little
different: if you click on a user that's not currently selected, the first
click only highlights that user. Click on the name to adjust options, on
the "Last Access" or "Packets Transferred" columns to edit the SubList, or
in the Net Status column to toggle net status.


:::: QWK NETWORKING ::::

Valence offers full QWK networking functions.  You can import net-status
.QWK packets and export .REPs to upload to your hub, and you can also
serve as a hub yourself.

*** QWK versus Fido ***

Two of the most popular BBS networking technologies are QWK and Fido. Many
of you are familiar with Fidonet or Fidonet-technology systems; QWK nets
may be less widespread, but are a strong second. Each system has its
advantages and disadvantages.

QWK nets are generally considered easier to set up than Fido-type nets.
QWK nets import and export directly from the message base; .PKT files,
.MSG files, extra directories, mailers, nodelists and so on aren't needed.

On the other hand, QWK networks may force you to wait online while your
hub packs your mail, running up your phone bill.  (Some QWK doors offer
prepacking, however.)  QWK nets allow no file requests or direct netmail;
you can only connect through your hub.  Private mail may be more difficult
to use than Fido netmail.  And setting up a script for a terminal program
to call your hub can be a pain, although there are a few dedicated
programs to automate it.

I'd like to say QWK-net importing and exporting with Valence is faster
than Fido importing and exporting with SLMAIL, but that hasn't
materialized.  In my benchmarks, I've found the performance to be nearly
identical.  However, with QWK nets you won't need Fido's several
intermediate steps, so overall performance may be better.  The required
disk space for QWK nets is much less, for a given message volume.


:::: NODE-LEVEL NETWORKING ::::

*** Installation, setup and operation ***

First, if you're not already in a QWK net, find a hub and get the sysop to
give you a "net-status" or "net-sysop" account.  Then, you should download
your first net-status packet.  Log in like a regular user, but using your
net-sysop account, and download a packet from the mail door, just as you
would a regular QWK packet.  Later, you'll upload .REPs the same way.

Now, if you're already using Valence as a QWK door on your system, all you
need to do is add one small config file.  You can even use Valence to
import and export without installing it as a QWK door; just edit the .CFG
file manually, and read all the documentation before you use it.

Appendix B shows an example config file.  When you join a QWK net, your
hub sysop might give you an example config file for Tnet, Trinet, or some
other QWK-net program; you must adapt it to the format shown here. You can
also read the CONTROL.DAT file from your net-status packet to see which
numbers correspond to which areas.

You must manually create the conferences named in your network .CFG file,
if they don't exist already.  Be sure to set the option "Auto Purge Old
Messages" to "Yes", and adjust the maximum number of messages.  Do NOT
fill in the echomail fields, and do NOT mix QWK and Fido messages on the
same conference.

Now, import your first .QWK packet.  To do this, run either from the home
(CONFIG.SL2) directory of a node with no one logged in, or with the SLBBS
environment variable pointing to such a node.  Use the "I" parameter for
Import, followed by the BBSID of your hub.  E.g.:

 cd\sl
 valence\valence i hubsys

It may take a while.  If you can, use a disk cache, and enable both read
and write caching, at least for the duration of the import.  It makes a
dramatic difference.  The imported .QWK packet will be deleted if
successfully imported.

*** Normal operation ***

After your first import, you'll want to automate things.  Always EXPORT
FIRST.  The exporting process is identical to importing, but uses "E"
instead of "I".

You'll probably want to create a batch file which runs as an event,
something like this:

 cd\sl
 valence\valence e hubsys
 {launch terminal program with script to call hub,}
 {upload .REP and download .QWK}
 valence\valence i hubsys

That's really all there is to the setup.  However, that middle part can be
tricky.  I can't lay out the setup for you, but your hub sysop should be
able to help.  Most QWK network hubs will have scripts for the more
popular terminal programs, or even dedicated QWK-network term programs.  
Some people never automate their sessions, and call manually for their
network transfers.  I can't recommend that, but it does work.

*** Where to connect ***

QWK networking is most widespread among Wildcat and PCBoard systems - in
fact, my experience suggests QWK nets may be more common than Fido nets on
these boards.  TriBBS is also a very popular platform for QWK nets.  If
you're interested in QWK networking, but don't know already know where you
can find a hub, try these systems first.  Even if they're not in a QWK
net, most of them have the necessary software already in place; you might
prompt them to join.

*** Some inner details ***

When imported, messages are marked with an [I] flag.  Network taglines are
added to those that don't have them.  The high-message pointers are
updated, as after a download or export.  (This is why it's critical that
you export FIRST.)  And instead of a message-by-message display, there's a
area-by-area display very similar to the one you see when downloading.
Other than that, importing works the same as uploading a .REP.  High-bit
filtering and threading are always off.

When exported, messages are marked with an [E] flag, if they don't already
have an [I] or [E] on them.  Messages without an [I] have the network
tagline added.  (Normally, the only messages in a QWK-net sub that will
have [I]'s on them are the ones downloaded from the hub, which will never
be exported; but when hubbing capability is added, messages uploaded from
nodes will also be marked with [I]'s.  This is how Valence knows if the
message already has a network tagline or not.)  The high-message pointers
are updated immediately, rather than after a successful download.  Color
codes are always stripped, metacharacters are untranslated, and no "extra"
header information is included in a message.  Otherwise, exporting is much
like downloading.

In network mode, the status line isn't displayed, protocol setup is
ignored, and no user's record is read.  Member records are created in all
network conferences with the hub's BBSID as the name.


:::: QWK NETWORK HUBBING ::::

To become a QWK hub, first, create a file called QWKNET.SUB in the Valence
directory.  This is plain text file, in the same format as MAIN.SUB, which
lists all the conferences you want to make available to your nodes, one
per line.  Valence will not operate in hub mode without QWKNET.SUB; this
is a security measure to prevent any random conference from going out in a
net-status packet.

Next, create accounts in Searchlight and in Valence for your node systems.
I recommend your nodes' sysops DON'T use the same account for QWK
networking and normal use of your BBS, though it's an option.  Then assign
"net status" to each node system in Valence's user editor.  What this does
is set certain default options different from the standard user defaults,
and create a "net-status" QWK packet whenver the user downloads.  A
net-status packet is one which is specially marked so it can be imported
by a QWK import program (e.g., Valence, running with the "I" parameter).  
Net status also allows messages in REP packets from the user to be posted
"From" any name.

From then on, node systems simply call your system and interact with
Valence just as normal users would: log in, upload REPs, download QWKs,
log off. Usually the nodes use a standard terminal program.  You may want
to help them with a script to automate the process (though it can be done
manually).

Externally, it's deceptively simple, but internally, it's quite different
from the way Valence usually works.  The most important difference is in
the handling of private mail.  In most QWK networks, private mail is mixed
in with public mail, either in certain designated conferences or in all of
them.  A QWK processor must be able to pass on the private mail in each
conference.  But Searchlight only supports private mail in one conference,
MAIL.

So how does Valence get around this? It maintains a database (in
QWKNET.USR in the Valence directory) of every "From:" name on every
network message it receives (public or private) and where it came from
(whether node or hub). (If a person posts from more than one board, this
is also handled.)  Then, when a private message is received, its recipient
is checked against this database of known network users (as well, of
course, as local users), and if found, an appropriate message is created
in MAIL.  This means you can only send private messages to people who've
already posted, but you can get around that by entering the header
manually.  (This is also the only way to send private QWKnet mail from
within Searchlight itself.)

Say that JOHN SMITH sends a private message to BILL JONES, who is a user
on your hub system, AVALON (or a system above it in the pyramid -- Valence
doesn't know the difference), in the conference "FOOBAR".  The message
will be temporarily stored in the MAIL subboard, addressed to "AVALON",
with the first lines of the text being:

Netname: BILL JONES
Area: FOOBAR

When you next export a REP for AVALON, the message will be included in the
packet, addressed to BILL JONES, and marked as being in area FOOBAR.

The beauty of this system is that it provides automatic routing -- private
messages aren't sent through the whole network, only in a direct chain to
their destination.  The downside is that QWKNET.USR might grow huge (so
far, this hasn't happened, but I haven't tested it in a real network
environment yet) and be a drag on importing performance.  Let me know your
experiences.

*** Fido/QWK Gatewaying ***

Gatewaying of conferences between Fido and QWK is currently not supported,
primarily because both Valence and SLMAIL use the [I] and [E] flags.  
There are ways around this; one option might be the popular program
"FidoQWK".


:::: BUPDATE.EXE ::::

This is a simple program to update the dates on Searchlight's bulletins
automatically.  It's intended for use with Valence, which scans for new
bulletins by date, but can be used without it.

Because the high message marker is turned off in a bulletin conference,
Valence - and your users - can only go by the date stamp of a bulletin in
judging whether it's new or not.  I know of several sysops who edit their
bulletins, and then change the title to reflect the fact it's been edited.
So when you do a bulletin list, you get something that looks like this:

10-30-92 Update 2-23

(That's from an actual bulletin on The Big Byte.)  With BUPDATE, you no
longer have to do this.  Another common way to use the bulletins is to
post included files, such as system or game statistics, which are updated
every day by the events.  BUPDATE will allow you to update the dates of
these bulletins, too.

There are two modes of operation for BUPDATE:  with parameters, and
without.  By running it with parameters, it will stamp each bulletin you
number with the current time and date.  E.g.:

BUPDATE 1 3 4

In the example above, you could edit your "Update" bulletin, then shell to
DOS and type "BUPDATE <x>".  This mode may also be useful in batch files,
running from events.

When run without parameters, BUPDATE will examine each bulletin for the
presence of "@@filename.ext" and "%%filename.ext" included files.  If
found, the date of the bulletin and the date of the file are compared; if
the file is newer, the bulletin date and time are updated.  This is
intended for use in events, and will ensure a correct date stamp on system
reports, game high score lists, etc.

Beginning with version 1.5, BUPDATE can work with conferences other than
"BULLETIN".  To use it on a different area, add the name of the area
preceeded by a slash, like this:

BUPDATE /ABOUT

or

BUPDATE /ABOUT 1 3 4

(If you don't specify an area name, it defaults to "BULLETIN".)


:::: SLMAIL.EXE/NETMAIL.EXE PATCH ::::

One thing you'll see when running INSTALL.EXE is the option to patch
SLMAIL.EXE and NETMAIL.EXE to get rid of the "soft returns".  (I'll use
"SLMAIL" to refer to both programs hereafter.)  The explanation is a bit
complex, but the bottom line is that messages originating on your system
should look better when imported to other systems.

When exporting messages, SLMAIL ends lines within "paragraphs" with a
space and a "soft return", character 8Dh.  These are ignored when the
message is imported; the whole paragraph is treated as one long line, and
the importing program wraps as it sees fit. The reasoning behind this was
an attempt to comply with Fidonet specs, which "prefer" that text be sent
in paragraphs rather than as individual lines, so it can be wrapped to
different screen widths.

The problem with that is, Searchlight doesn't store text in paragraphs,
internally -- only in individual lines. Since it has no way of knowing
where the actual paragraphs are supposed to be, SLMAIL guesses.  It
assumes a paragraph break if (and only if) it sees a blank line, or a line
indented by spaces.

This is no big deal, with a piece of text like the paragraph above.  If it
gets rewrapped, it may be a different width, but it still looks *right*.
But if you have something like this:

WM>This is a sample of text quoted by a QWK reader. This style is
WM>liable to be rewrapped.

it can get rewrapped into something like this:

WM>This is a sample of text quoted by a QWK reader. This style is WM>liable
to be rewrapped.

If you've ever been in SL-Net, you may know what I'm talking about.  
(Note that SL's internal ">" quotes don't come out this way when
reimported by SLMAIL, due to careful processing to avoid it.)  One
solution is to change the quoting style of the reader, and start every
line with a space; this fools SLMAIL into thinking each line is a new
paragraph, and it generates "hard" returns.  That's what I did for a long
time.  But a surer solution is to alter the behavior of SLMAIL itself.

What the patch does is to look for the following code:

AC           lodsb
AA           stosb
91           xchg cx,ax
30ED         xor ch,ch
F3A4         rep movsb
8EDB         mov ds,bx
807E0600     cmp byte ptr[bp+6],0
7407         jz $+7
C686FFFE0D   mov byte ptr[bp+FEFF],0D
EB05         jmp $+5
C686FFFE8D   mov byte ptr[bp+FEFF],8D

and replace it with:

AC           lodsb
807E0600     cmp byte ptr[bp+6],0
7502         jnz $+2
FEC8         dec al
AA           stosb
91           xchg cx,ax
30ED         xor ch,ch
F3A4         rep movsb
8EDB         mov ds,bx
C686FFFE0D   mov byte ptr[bp+FEFF],0D
90           nop
90           nop
90           nop
90           nop
90           nop

Since it searches for a pattern, rather than patching a fixed address, it
will work even when SLMAIL is changed, as long as this portion of the code
remains the same -- as it probably has since the first version of SLMAIL.
INSTALL should report "Updated" once for each file.  If it can't find the
code (if you've already made the change, or this block of code has been
changed in SLMAIL), it won't do any updating.

I wrote this patch in part because I was tired of being blamed for
rewrapped messages, since it's most apparent with QWK-style quoting
(though not limited to it).

Since the initial release of the SLMAIL patch, it's been found to be
incompatible with the patch-based upgrade system used by Searchlight
Software.  For that reason, the Install program now allows you to reverse
the patch, by invoking it with the 'R' parameter. You can patch and
unpatch as often as needed.


:::: TECHNICAL DETAILS ::::

VALENCE.EXE is compressed with LZEXE 0.91.

The twirling indicator during archiving works by revectoring interrupt
29h, DOS' "fast write".  This might not work for all archivers, but has
been tested with PKZIP, ARJ, and LHA.

*** User file ***

VALENCE.USR records not only the options and number of messages
transferred, but the list of message areas for each user.  This list is
used to translate area numbers on uploaded messages and to hold the
special attributes for each conference.

The user file will grow along with your system; as you add conferences,
Valence will resize it automatically when needed.  Small systems with
little drive space aren't penalized by oversized user files, but large
systems with hundreds of echos can easily be accommodated.  The user file
is only resized up, never down.

*** Errorlevels ***

There a bunch of errorlevels returned by Valence - a different one for
each error message.  These errorlevels aren't checked by Searchlight, but
some can be useful when automating QWK network operations.

Import and Export functions return an errorlevel of 0 if everything went
normally; other errorlevels are as follows:

 81: COMPRESS.CFG not found
 82: Unable to open BBS system files
 83: CONFIG.SL2 not found
 85: Error from DOS operation
 86: Error changing directories
 87: .EXE or .COM not found
 88: Error in .REP packet
 92: Error in archiving
 94: SUBBOARD.SL2 not found
 97: Unable to open VALENCE.USR
 98: VALENCE.USR: wrong version
 99: No room for packet in directory
100: No new messages
101: Disk I/O error
104: Network .CFG file not found
105: QWK packet not found
106: Error in unarcing
107: Not a net-status packet!

You might check some of these in your import/export batch file(s).  Error
100 isn't really an error; unless your users do a lot of posting, you can
expect to get this frequently when exporting.  Error 107 is what you get
if you try to import a regular .QWK packet.

*** Limitations ***

The maximum length of a single message in QWK mode is between 32k and 64k,
depending on how full the output buffer is at the time.  There's no limit
in Text mode.  (With older versions of Searchlight, a message will always
be less than 32k, not counting any Included files.  Newer versions of SL
might allow up to 80k per message.  Valence will handle this better in a
future release.)

The maximum number of conferences is now 16384.  In low-memory situations,
the effective limit may be lower.  Messages and users are limited to about
300 million each.  The QWK format limits message numbers to 9,999,999.


:::: FOR THE FUTURE ::::

*** Known flaws in the present version ***

* Although the colors in the display are read from CONFIG.SL2, the colors
  in the filelist and the headers in Text mode are hard-wired.  This
  should be changed.

* Even with ANSI wrap, included files must be saved with a width of 255 or
  less, or the part of the line beyond 255 characters is lost.

* Swapping out to disk/EMS/XMS -- There is no swapping.

* Area attributes other than Personal and Personal/All cannot be set
  remotely, only online.

* Importing is too slow.  To improve it, I'll have to write my own
  routines to replace the SLTPU's message post.  This is being done.

* Any existing network .REP file is killed on export.  There should at
  least be the option to append newly exported messages to an existing
  .REP, which is the default behavior of other QWK-net programs I've seen.
  I coded this, but couldn't get it to work due to bizarre memory
  allocation problems.  I hope to fix it for the next version, but for now
  I haven't the patience to keep beating my head against the wall.  (Note
  11/04/93 -- I haven't looked at this between 1.3 and 1.42.  I think the
  memory allocation problems are fixed, though.)

* There should probably be an option not to kill the .QWK packet after
  import, too.

* Overall number of messages imported and exported can be logged, but not
  area-by-area.

*** What you'll see in future versions ***

* Enhanced support for file attachments.

* Dupe checking.

* Automatic creation of network .CFG files.

* Prepacking.

* Carbon copies -- Put a "CC:  name, name, name" in your message and the
  header will automatically be duplicated to those people, just like in
  Searchlight.

* %% upload -- You'll be able to send a message to Valence and have it
  convert it to an included file.  This will be the easiest way to post
  ANSI.

* MAIN.SUB files configurable by each user, twit filters configurable by
  each user -- Maybe.  Not a high priority, just something I thought would
  be cool.


:::: WHERE TO REACH ME ::::

 Internet: wmcbrine@clark.net
 US Mail:  William McBrine
           8128 Fenwick Ct.
           Laurel, MD 20707-5615

The latest version of Valence is always available by anonymous FTP to:

 ftp://ftp.clark.net/pub/wmcbrine/bbs/sl/

or on the World Wide Web at:

 http://www.clark.net/~wmcbrine/sl.html

Also try the SEARCHLIGHT echo on Fidonet.


::::  ACKNOWLEDGMENTS ::::

Valence uses the Searchlight Programmer's Library.  The index number
conversion routine (longint to MSBIN) is based on one printed in the
QWKLAY document (by Patrick Lee), credited to Greg Hewgill.  The twirling
indicator during archiving is loosely based on a window-shelling routine
posted in the Fidonet PASCAL echo by Kelly Small.

Thanks to Tom Curtis and Daniel Rymer for access to their systems,
testing, and encouragement.  Thanks also to Tom for many of the files
needed to complete this project.

Thanks to Patrick Lee and Jeffery Foy for their text files on the QWK
format.

Thanks to Scott Dudley for COMPRESS.CFG.

Thanks to Tom Kihlken for the program XRAY, a valuable tool for profiling
program efficiency.

Thanks to all for suggestions and bug reports.  Special thanks to those
who've donated.


===========================================================================

; :::: Appendix A - VALENCE.CFG ::::

; This is the main config file for Valence. You can edit it with any text
; editor - "2-Sysop", "TextEdit" from Searchlight works nicely.

; The format of this file is loosely inspired by Squish's COMPRESS.CFG, and
; I use most of the same code to read both files. It's based on "keywords".
; Some keywords use the rest of the line as a parameter; some work simply
; by being there. Case of keywords and leading and trailing spaces are
; ignored. Keyword order is unimportant. They all have default values, so
; you can omit any of them. Valence will abort with an error if it can't
; find VALENCE.CFG, but will still run if it's only a single blank line.

; All comment lines (like this one) beginning with a ";" and all blank
; lines are ignored and can be removed. You can add comments to any line;
; anything after the ";" will be ignored. "Uncomment" means to remove the
; initial ";" from a line.

;---------Important Part for Quick Start----------------------------------

; All these fields should be changed to fit your BBS:

BBSID     NAKED                    ; BBS ID

; This is the filename used for QWK and REP packets. It should be a legal
; DOS filename, 1-8 characters, with no extension. I discourage the use of
; numerals. If a user has numbered packets selected, only up to six
; characters will be used for QWK packet names, but all eight will be used
; for REPs. The BBSID should reflect the name of the BBS, and should be
; unique, at least to your area. ("NAKED", is for "The Naked Singularity",
; my as-yet nonexistent BBS.)

Sysop     William McBrine          ; Sysop's name

; This name is used both in CONTROL.DAT, and in the "To:" and "From:"
; fields of message headers in place of "SYSOP" if you have Sysop Renaming
; on. Case is ignored. If you omit this keyword, and you're using
; Searchlight 3.0+, Valence will read the "Sysop's Real Name" from SL's
; Network Mail Setup.

Locale    Laurel, MD               ; City, State [, Country]
Phoneno   xxx-xxx-xxxx             ; BBS Phone #

; These two fields are optional and are only used in CONTROL.DAT. I've seen
; many systems that omit this info from their packets.

;---------You can ignore the rest if desired-----------------------------

;Welcome   LOGIN                   ; \
;News                              ;  }- Path defaults to SL's text dir
;Goodbye   LOGOFF                  ; /

; These are optional files that may be included in QWK packets. A QWK
; reader displays the "Welcome" file when a packet is opened, and "Goodbye"
; when it's closed. "News" is supposed to be important BBS news. There's no
; News feature in Searchlight, as there is in some BBSes, so you can
; implement this any way you like, or not at all. By default, the News file
; is only included if it's been updated since the last time the user read
; it. The other two files are always included, if they exist. If you omit
; the extension, Valence will first look for a file with the extension
; ".ANS", then ".TXT", and then with no extension.

; These files appear in the packet just as they would online, with full
; metacharacter and color code replacement - except that Valence has a
; 255-character-per-line limit; any excess will be truncated.

; You can add a News file to SL with internal command #160, "Display file",
; in an autoexecuting menu (like Startup) in an appropriate place (like
; before the Bulletins). Making it pop up only when updated requires a
; little more work.

; "LOGIN" and "LOGOFF" are the defaults for Welcome and Goodbye; uncomment
; and edit these keywords if you want to use different files, or none (make
; them blank for none). News defaults to none.

;LocQWK    C:\SLMR\                ; Path to local QWK files

; This is the directory where Valence puts your QWK packets when you
; "download" from a local login. The path must end in a "\". Above is a
; sample value; the default is to use the directory VALENCE.EXE is in.

;LocREP                            ; Path to local REP files

; Use this only if you want different directories for QWK and REP files;
; otherwise, the LocQWK path is used. This path is also used for local
; uploads of PTR files.

; When "uploading" locally, your REP packets must be named "<BBSID>.REP",
; you must rename your pointer files to "<BBSID>.PTR", and you can only
; upload one at a time. Remote users can upload multiple packets or pointer
; files at once and can use names of the form "*.REP" and "<BBSID>.PT*" if
; using a batch protocol.

;WorkDir                           ; Path to work directory

; If you have a large RAM disk, preferably one with over a meg free, you
; can speed Valence up a little by setting the work directory to the RAM
; disk. By default, Valence uses the directory VALENCE.EXE is in as its
; work directory. (The actual work directories branch off this directory,
; and are named for the node that creates them - "1", "2", etc. These are
; deleted when the program terminates, unless it crashes badly.)

Rename                             ; Change "SYSOP" to real name

; This changes your name in the "To:" and "From:" fields of messages from
; "SYSOP" to whatever you put after the keyword "Sysop". If you're NOT
; logging in to Searchlight under the SYSOP account, you should remove
; this, and use "RevRename".

;RevRename                         ; Reverse Rename

; If you're not logging in to Searchlight with the SYSOP account, use this
; keyword. Messages uploaded to "SYSOP" will be sent to your real-name
; account.

;ThreadOff                         ; Don't thread replies

; By default, Valence will thread replies by putting the message number of
; the original in the "replyto" field of the new message. This allows the
; "Thread" command to work online, and improves offline threading as well.
; But since QWK packets use sequential message numbers, which get changed
; when a conference is renumbered, the reference numbers will be wrong if
; the subboards are renumbered between the time of the download and the
; upload. So, if you renumber frequently, uncomment this keyword - or
; better yet, stop renumbering.

;RepKill                           ; Delete local .REPs on "upload"

; If you use this, your local .REP files will be deleted automatically
; after they're processed. This saves you from having to remember if you've
; uploaded them or not.

;MaxSub    65000                   ; Maximum possible messages per conf
;MaxTotal  65000                   ; Maximum possible messages per packet

; In Valence, users can adjust the limits on the number of messages the
; program will collect into one packet, and the number of messages it will
; collect from each conference at one time. These two keywords specify the
; MAXIMUM values they can set these limits to. 65000 is the default and
; maximum for each value; 10 is the minimum.

; Regardless of the number of messages packed, users won't be able to
; exceed their time limits, so I recommend leaving these alone. (65000 is
; essentially a non-limit.) Trying to download oversized packets is its own
; punishment; if they get too big, you can't even load them into a reader.
; However, if you do find you have a "message leech" problem, these
; keywords are here.

;DefSub    200                     ; Default maximum messages per conf
;DefTotal  400                     ; Default maximum messages per packet

; These are the defaults assigned to new users for maximum messages per
; conference and packet. Users can change these as they like, from 10 up to
; the limits specified in MaxSub and MaxTotal. The limits aren't checked
; when scanning the MAIL area, so new private mail won't be left out.

;LogFile   VALENCE%o.LOG               ; Path to Valence's Log file

; This is the text file where Valence keeps a record of who did what, for
; your perusal. No other use is made of this file, so you can turn it off
; if you like. The name above is the default, so uncomment this and edit it
; only if you want to change it. If the directory is not specified, the log
; file is created in the Valence directory. If you uncomment this keyword
; and make it blank, logging will be turned off.

; Note the use of Searchlight's "%o" metacharacter to specify the node
; number. This filename would translate to "VALENCE1.LOG", "VALENCE2.LOG",
; etc., as appropriate. Thus, you'll have separate log files for each node.
; You can combine them into one by taking out the "%o", but I don't
; recommend this, as two or more nodes might run at the same time with the
; same log file.

; The %o can be used anywhere in the name, as can all the other Searchlight
; %-codes, plus the special code "%e" I invented to represent the current
; node's home directory. Thus you could have

; LogFile   %e\VALENCE.LOG

; to create the log file for each node in the node's home directory. The
; log file need not be exclusive to Valence, except while it's running; for
; an interesting effect, try:

; LogFile   %e\ACTIVITY.LOG

; This feature is NOT available for any of the other keywords in
; VALENCE.CFG.

; :::: PROTOCOLS ::::

; Defining the protocols is simple; they work just like Searchlight's
; external protocols, with metachars, @files, and so on. They're run
; from Valence's work directory.

; In Searchlight versions under 3.0, Xmodem, Xmodem/CRC, and Xmodem/1k are
; hardwired and are always the first three protocols on the list. In
; version 3.0 and higher, they may appear anywhere in the list, or not at
; all, as you choose. In this file, "IntProt 1" corresponds to "Xmodem",
; whether you're using Searchlight 2.x or 3.0+; 2 and 3 are Xmodem/CRC and
; Xmodem/1k. Internal protocol 4, Zmodem, is only used in Searchlight 3.0+.

; Numbers 5 through 19 may be used to replace the protocol drivers defined
; in CONFIG.SL2, if you want different command lines for Searchlight and
; Valence.

; *** Definition Set 1 ***

; My default DSZ definitions work where I've tested them, but they're not
; optimized.

;IntProt    1                    ;Internal protocol 1 (Xmodem)
;  Name     Xmodem
;  SendCmd  dsz.com port %p sx %f
;  RcvCmd   dsz.com port %p rx %f

;IntProt    2                    ;Internal protocol 2 (Xmodem/CRC)
;  Name     Xmodem/CRC
;  SendCmd  dsz.com port %p sx %f
;  RcvCmd   dsz.com port %p rc %f

;IntProt    3                    ;Internal protocol 3 (Xmodem/1k)
;  Name     Xmodem/1k
;  SendCmd  dsz.com port %p sx -k %f
;  RcvCmd   dsz.com port %p rc %f

;IntProt    4                    ;Internal protocol 4 (Zmodem)
;  Name     Zmodem
;  SendCmd  dsz.com port %p sz -r %f
;  RcvCmd   dsz.com port %p rz -ry

; *** Definition Set 2 ***

; The second set uses the ZMODEM.EXE driver, which is designed to duplicate
; Searchlight's internal protocols. You must use a version dated February
; 22, 1993 or later. You can obtain this program from Searchlight BBS under
; the name SLZMODEM.ZIP.

; The simplest way to set up Valence's internal protocols is to copy
; ZMODEM.EXE to the same directory as VALENCE.EXE, if you don't already
; have it on the path.

; Notice the "%e" in the definitions below; this is a metacharacter I
; invented just for ZMODEM.EXE, which translates into the directory of the
; current node's CONFIG.SL2.

;IntProt    1
;  Name     Xmodem
;  SendCmd  zmodem.exe -c -sx -p%e %f
;  RcvCmd   zmodem.exe -c -rx -p%e %f

;IntProt    2
;  Name     Xmodem/CRC
;  SendCmd  zmodem.exe -c -sc -p%e %f
;  RcvCmd   zmodem.exe -c -rc -p%e %f

;IntProt    3
;  Name     Xmodem/1k
;  SendCmd  zmodem.exe -c -sk -p%e %f
;  RcvCmd   zmodem.exe -c -rk -p%e %f

;IntProt    4
;  Name     Zmodem
;  SendCmd  zmodem.exe -c -s -p%e %f
;  RcvCmd   zmodem.exe -c -r -p%e

; :::: ARCHIVERS ::::

; This is a modified version of Squish's COMPRESS.CFG. For more info on the
; format, please see the original.

;DefArc  ZIP                       ; Default archiver name (NOT extension)

; This is the default archiver assigned to new Valence users. ZIP is the
; default.

;Compress  C:\SQUISH\COMPRESS.CFG  ; Path to COMPRESS.CFG

; This specifies the full pathname to your COMPRESS.CFG. This is only
; useful if you're already using one with another program. The name can be
; omitted, in which case the path must end in "\".

Archiver ARC
  Extension  ARC
  Ident      0,1a
  Add        pkpak.exe -oct a %a %f
  Extract    pkunpak.exe /r %a %f

; You might want to add a "-ex" to the PKZIP "Add" command line, to create
; smaller packets.

Archiver ZIP
  Extension  ZIP
  Ident      0,504b0304
  Add        pkzip.exe -a %a %f
  Extract    pkunzip.exe -o %a %f

; This entry, "LH113", makes the new LHA archive in the old format, for
; compatibility with systems that the new LHA hasn't yet been ported to.

Archiver LH113
  Extension  LZH
  Ident      2,2d6c68
  Add        lha.exe a /o /m %a %f
  Extract    lha.exe e %a %f

Archiver LHarc
  Extension  LZH
  Ident      2,2d6c68
  Add        lha.exe a /m %a %f
  Extract    lha.exe e %a %f

; ZOO is a multiplatform archiver, common on Amigas and UNIX systems, among
; others, and available for MSDOS, too. Under MSDOS it's a bit slow.

Archiver ZOO
  Extension  ZOO
  Ident      0,5a4f4f
  Add        zoo.exe a: %a %f
  Extract    zoo.exe e:O %a %f

; ARJ needs a lot of memory to run. You might want to add a "-m4" or the
; like to the command line to squeeze it down.

Archiver ARJ
  Extension  ARJ
  Ident      0,60ea
  Add        arj.exe a -e %a %f
  Extract    arj.exe e -n %a %f

===========================================================================

; :::: Appendix B - QWKNET.CFG ::::

; The actual name of this file should be <BBSID>.CFG, where <BBSID> is the
; packet name used by your hub BBS. Numbered packets, like the ones Valence
; creates by default, should NOT be used. The name of the packet must be
; the same as the name of the config file, with the extension .QWK.

; You can have multiple hubs by creating multiple configuration files. Each
; network conference should be listed in only one config file.

HubSysop  William McBrine

; If any imported messages are To or From "SYSOP", "SYSOP" will be changed
; to the name specified here. (This should be the name of the sysop of your
; hub, NOT your name.)

ImpTag    The Naked Singularity  Laurel, MD  xxx-xxx-xxxx

; This is the default network origin "tagline" for your hub BBS, which will
; be added to imported messages which don't already have a network tag.
; Many net-status QWK doors don't add these lines when creating packets,
; and leave it to the importing program.

;NoTags

; But some net-status QWK doors - notably TriMail - create packets without
; setting the network origin line flag on messages; this will cause Valence
; to add the ImpTag to every message imported. If you have this problem,
; you can add the "NoTags" keyword to suppress the ImpTag.

ExpTag    Your BBS Name Here  Anytown, USA  xxx-xxx-xxxx

; This is your own default network tagline, added to exported messages. The
; format here is suggested, but you can use anything up to 65 characters
; long. (Note the character 254 used as a delimiter; this is customary in
; QWK nets, but not, to my knowledge, of any real importance.) In QWK nets,
; there's nothing corresponding to a Fidonet node number, so you have a
; little more room on the line.

; Many networks require you to include the name of the network in the
; tagline. E.g.:

;ExpTag    U'NI-net US  Your BBS Name Here  Anytown, USA  xxx-xxx-xxxx

; This is probably a good idea anyway, particularly if you're in more than
; one QWK net.

;ImpTagX   1 OtherNet  The Naked Singularity  Laurel, MD  xxx-xxx-xxxx
;ExpTagX   1 OtherNet  Your BBS Name Here  Anytown, USA  xxx-xxx-xxxx

; These commands specify an alternate tagline, by number. ("ImpTagX 0" and
; "ExpTagX 0" are equivalent to "ImpTag" and "ExpTag".) These are primarily
; for when you get a feed for more than one net from the same hub, but you
; can use them to specify a different tagline for every conference, if you
; want. You can have up to 256 taglines each for Import and Export.

Conf      2 CHAT      ;Local chat conference
Conf      3 MORE      ;Another area
Conf      4 OFFLINE 1 ;OtherNet OFFLINE conference

; The above are examples of conference definitions. After the keyword
; "Conf", the first number specifies the conference number used in the .QWK
; packet downloaded from your hub. The next field is the name of the
; corresponding Searchlight conference on your board. If there's a second
; number after that, it specifies the Import/Export taglines to use; if
; not, the defaults are used.

; Any number of "Conf" lines may be used, and they may appear in any order.
; Each of these areas will be scanned at export time.

;IdxName   OTHERID

; This lets you specify a name to be used for the high message pointers, so
; that two .CFG files can use the same pointers - one for export, and one
; for import. (I'm told this is useful for Planet Connect.) Normally the
; hub's BBSID (which is also the name of the .CFG) is used in the
; conference member records; to have two .CFGs use the same pointers, put
; "IdxName <BBSID1>" in the second config file, where <BBSID1> is the name
; of the first .CFG. (It doesn't matter which is first, and you could set
; both to a third name, or even use this feature with a single .CFG.) This
; keyword should not be needed in normal use.

; At a minimum, you must have one "ImpTag", one "ExpTag", and one "Conf"
; line defined in this file.

;-------------------------------------------------------------------------

; In addition to these keywords, you can use any of the VALENCE.CFG
; keywords in each network .CFG file. Settings here will override those in
; VALENCE.CFG. Some keywords you might use here are:

;Archiver  ZIP

; This archiver will be used when creating .REP packets. The format of
; network .QWK packets is autodetected, as with uploaded .REPs, but you
; must set the archiver for network .REPs explicitly to use one other than
; the default.

;Sysop     My Other Name

; You might use a different name in the network than you do locally.

;LogFile   QWKNET.LOG

; You can set up a separate logfile for network transfers.

;LocQWK    C:\ROBOCOMM\
;LocREP    C:\ROBOCOMM\

; Network .QWK packets downloaded from your hub are retrieved from the
; LocQWK directory. Network .REPs are placed in the LocREP directory.
; Remember, these paths must end in "\".

; You can also put any of the network keywords in the main VALENCE.CFG
; file, but I recommend against it. <BBSID>.CFG must exist for Valence to
; import and export, even if it's only one blank line.

===========================================================================
