			       WinFlex
		  A WinSock based client for FlexFax
			 Version 0.2 (Alpha)


	  Copyright 1993 by Peter Bentley <pete@tecc.co.uk>

Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Peter Bentley not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  Peter Bentley
makes no representations about the suitability of this software for
any purpose.  It is provided "as is" without express or implied
warranty.

PETER BENTLEY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 
NO EVENT SHALL PETER BENTLEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR 
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE 
USE OR PERFORMANCE OF THIS SOFTWARE. 


What is WinFlex?

WinFlex is a simple Windows 3 client for the Unix based FlexFax
network fax system.  The current version allows single PostScript
files to be spooled to a FlexFax host for faxing to a single
destination across a TCP/IP network.  WinFlex can be set up to
automatically fax all data sent to a specific file, on the assumption
that this file has been set up as a Windows printer 'port'.  WinFlex
interacts with the Print Manager to try and ensure data is collected
from this file at the correct time.  WinFlex can also generate cover
sheets to go with the document you are faxing.  Like the Unix FlexFax,
cover sheets are produced from a PostScript template file.  WinFlex
fills in some of the details, and provides a dialogue box for the user
to fill in the rest.  

Version 

This document describes version 0.2, an ALPHA release.  It works for
me in as much as it submits PostScript files to my local FlexFax
server. Your mileage may vary.  If WinFlex runs amok, nukes your hard
disk, has sex with your cat, or anything like that then you are on
your own.  Don't forget to scan the executable for viruses before you
run it. I know I haven't got any, but you shouldn't take my word for
it...

Installation

WinFlex is distributed as two ZIP files.  WFLX02X.ZIP contains the
executable and this document in Word for Windows format (WINFLEX.DOC)
and in ASCII (WINFLEX.TXT).  WFLX02S.ZIP contains another copy of this
document and the source code Before you start, you will need a working
Winsock DLL, and a FlexFax host which your machine has permission to
use.  You must configure your Winsock DLL so that it knows that port
4557 is the fax service (or whatever you use).  For a Winsock DLL that
uses a BSD-style services file, add a line like:-

fax		4557/tcp	flexfax	#Fax transmission service 

Note also that your Winsock DLL file must either be in a directory on
your PATH, your Windows directory, or your Windows System directory
(often C:\WINDOWS\SYSTEM) To install WinFlex itself, put the
executable (WINFLEX.EXE) in a directory somewhere and add an entry for
it in a Program Manager group (or whatever shell you use in its
place). Run it and select File|Settings to set up the name of your fax
host, your username on the fax host machine, your full name and Email
address. These settings will be saved in your WIN.INI, so you only
need to enter them once.  If you wish to generate cover pages locally,
then you will need to fill in the "Template File" box in the dialogue
to point at a suitable cover sheet template.  If you do not know how
FlexFax cover templates work, ask your local FlexFax administrator.
If you are the local administrator, then RTFM, as this is something
you should know...


Printing directly to FlexFax

WinFlex can be set up to allow you to print PostScript from your
applications that will be spooled directly to your FlexFax server.  To
do this you need to dedicate a directory on your computer for spooling
PostScript files to.  Then you set up an entry in the [ports] section
of your WIN.INI which will allow you to connect a PostScript printer
directly to a file in that directory.  Finally you tell FlexFax the
name of the directory and the name of the spool file, and it will
monitor the Print Manager and when appropriate move the contents of
the spool file to a safe place, and pop up the usual 'Send Fax'
dialogue for you to specify the recipient.  In fact, WinFlex can
handle most of this setup for you.  Decide the name of the directory
you wish to use (eg C:\SPOOL) and a spool file name (eg FLEXFAX.SPL).
Type these entries into the WinFlex setup dialogue.  When you click
OK, WinFlex will offer to create the directory if it does not already
exist, and will also offer to create the entry in your WIN.INI.  You
can then go straight to the Control Panel, and use the
Connect... dialogue to attach a PostScript printer to the new port.
It is imperative that you check the 'Use Print Manager'' box on the
Control Panel's Printers dialogue, or nothing will work...

Usage

If you have selected auto-print in the setup dialogue box, then simply
run WinFlex minimised.  Now go into an application and print something
to the PostScript printer attached to WinFlex' spool file.  After the
application has finished printing, WinFlex will pop up a dialogue box
to fill in the destination fax number.  If you have installed a cover
sheet template, you may also fill in the cover sheet related fields in
the dialogue, and they will be incorporated into the cover sheet.
WinFlex will automatically fill in the Date, Number of Pages and
Sender fields.  Click OK, and the fax should get sent.  If everything
goes will, the last thing you will see on the status dialogue is the
job ID that FlexFax (on the fax server) has allocated for your fax.
Select OK, and WinFlex will remove the status dialogue and remove the
PostScript file from your local hard disk.  If it doesn't work, and
the reason is not obvious, mail me with as much information as you can
(especially the contents of the various status fields).
Unfortunately, WinFlex may occaisionally leave an incorrect status
message in the dialogue (just to confuse you).  If you have a
PostScript file on your disk that you wish to fax manually, just
select the File|Fax option in WinFlex, and enter the name of the
file.  The rest of the process is as for an auto-print file.

Getting the Server Status

Select Status|Send to look at the server send queue, and
Status|Receive to see the received faxes (if they are publically
viewable).  The status code is extremely flakey.  Sorry.  In fact, the
receive queue status isn't parsed at all, so will probably make no
sense to any sane human.

Limitations (numerous)

	o	No translation of Winsock error codes to human readable text
	o	Only a single PostScript file can be faxed at a time
	o	Only a single destination can be specified
	o	No way of specifying submission time etc etc
	o	No support for file formats other than PostScript
	o	No online help, poor documentation
	o	No equivalent to FAXRM to kill jobs
	o	Fax server status code is very very preliminary
	o	No way of viewing or retrieving faxes, even if the receive queue is public
	o	Error messages will be mailed to you on the Unix host
	o	No way of selecting different fax modems on Unix hosts
	o	No database of available FlexFax hosts
	o	No local database of fax numbers, names, companies etc
	o	Not terribly efficient socket code
I plan to fix all of these deficiencies, probably more or less in the
order they're listed.  If I get requests for a particular feature,
I'll move it up the list.

Feedback

Email me (pete@tecc.co.uk) if WinFlex works on your machine.  In
particular I would like to know things like:-
	o	Brand of Winsock.DLL, 
	o	Hardware (ethernet card, packet driver etc) 
	o	Version of FlexFax on the Unix host. 

If I get no feedback, I will assume no-one is using this program, and
adjust the time I spend developing it accordingly...

If WinFlex doesn't work on your machine, then I would be even more
interested in hearing from you so I can fix it.

Copyright

Do what you like with this program apart from removing the copyright
notices.

This program is "beerware".  If you find it useful, then the next time
you meet the author in a pub, you should seriously consider buying him
a beer.

Building From Source Code

You will need the zApp application framework and a Borland C++
compiler (Turbo C for Windows/BC++3.0/BC++3.).  I have not yet found a
free class library for Windows that saves me from the pain of the
Windows C API.  I rather like zApp (I chose it after writing the same
little application using OWL, zApp and Zinc for comparison), but I am
not associated with Inmark (its authors) in any way.  Anyway, building
from source should be as easy as getting the source code, loading the
.PRJ file into your C++ compiler and hitting 'make'. Check the
directories in the project file first, though...

The enclosed winsock.h came directly from rhino.microsoft.com. The
enclosed winsock.lib came by running IMPLIB on a Winsock DLL.

Source Code Layout

The application is split into three main parts:- 
	tcSock.h/tcSock.cpp	TECC Winsock classes
	ffClient.h/ffClient.cpp	FlexFax client classes
	WinFlex.h/WinFlex.cpp	The WinFlex application code

The TECC sockets classes are something I did as an experiment.  They
use the WSA...() asynchronous Winsock calls.  User code is added by
deriving from tcSocket and overriding appropriate member functions (eg
the Connected() member is called when a connect() completes). The
derived classes tcBufSocket and tcLineBufSocket provide buffering on
top of a tcSocket and different callbacks (eg
tcLineBufSocket::lineRead() is called when a complete line of text is
available on the socket).  The buffering in these classes isn't very
well done, and I shall probably restructure it soon to get rid of a
load of redundant data copying, so don't rely on this interface
staying the same.  I shall also try and do something to make accept()
work a little better for server sockets...

Whenever at least one instance of a tcSocket is created, then a
tcSocketManager is also created.  This tells the top level zApp window
to pass any WM_SOCKET messages to it.  It then maintains a list of
active tcSockets.  WM_SOCKET is defined in tcSocket.h, and if it
clashes with a message number you are using, just redefine it.  Each
tcSocket keeps a mask of events it is interested in (eg FD_READ and
FD_CLOSE), and whenever this mask is changed using the addMask() or
delMask() member function, it calls WSAAsynchSelect() telling Winsock
to pass a WM_SOCKET message to the zApp base window when the event
occurs.  zApp will then invoke the socket manager's sockHandler()
member, which will find the corresponding tcSocket from its list, and
will invoke a suitable member function.

The ffClient stuff is basically a load of structs to hold the data
describing a fax job (ffJob), and ffSocket, a tcSocket which 'knows'
the FlexFax protocol and can use it to submit a job to a FlexFax
server.  The ffSocket works as a simple state machine.  Its current
state determines what it will do next (eg transmit some more data).
State transitions are triggered either from callbacks from
tcLineBufSocket, or by running out of data to transmit in the current
state.

The WinFlex application is mostly just a top-level shell which handles
the menus, some simple dialogues to put a ffJob together and creation
of an ffSocket to submit the job to the server.  Possibly of interest
is the code which handles auto-printing to FlexFax.  It uses zApp to
invoke a handler when a WM_SPOOLERSTATUS message is delivered.  When
this message indicates that the Print Manager's queue is empty, then
we can be nearly certain that if there is any data in out spool file,
then it is a complete print job, and that the Print Manager will
remain idle until we return from the message handler.  So, we look for
data in the spool file, and if we find some that looks valid, we
rename the file and create an ffJob to send it to the FlexFax server.
Then we delete the file...

Porting to other Application Frameworks

Currently the tcSocket classes require zApp for message handling, but
this is pretty localised to the tcSockManager class.  Also the
ffJobDialogue class uses a zApp dialogue class, but this is also
pretty localised.  Everything else could probably be ported to another
Windowing framework.  If you do this, then please let me have the code
so I can merge it into WinFlex.  If you add any useful
enhancements/bug fixes to any of this, then please pass any feedback
to me as pete@tecc.co.uk...
