[comp.sys.amiga.tech] I wanna have a DOSGate!

ddave@pnet02.cts.com (David Donley) (05/22/89)

Help!  I desperatly need to be able to fake a filehandle.  I ams trying to put
a dosgate into a BBS.  I have a dosgate of sorts, but only the text from the
internal commands goes out to the modem.  How can I fake normal standard
programs into sending their stdio into my BBS code?

                    Call the Bug Eyes BBS at (213) 372-4494
     ddave@pnet02.CTS.COM                      killer!gryphon!pnet02!ddave

mcp@ziebmef.uucp (Marc Plumb) (05/29/89)

In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>Help!  I desperatly need to be able to fake a filehandle.  I ams trying to put
>a dosgate into a BBS.  I have a dosgate of sorts, but only the text from the
>internal commands goes out to the modem.  How can I fake normal standard
>programs into sending their stdio into my BBS code?

Write a DOS handler.  I know one fellow (bradch@microsoft, I think) who's
doing it in an editor, allowing him to connect CLI's to editor windows,
and to compile a program that hasn't been saved to disk.  Just
"cc editor:buffername"!  Add "-S editor:asmbuffer" if you like.

Matt Dillon's sample ram disk is a good place to start.  Basically, you
need to accept packets that ask you to perform read, write, seek, open,
close, etc. operations.  There's also useful information in TransAmi 2.2
with parts 2-4 of the series in 2.3, 2.4, and 2.5.

You don't need to create a separate process to be the handler; you can
just build a MsgPort and install a volume node in DOS's device list.
To add the node, there is an AddDosNode call in the expansion.library;
to remove it, you'll have to Forbid(), traverse the list and remove your
node, and Permit().  You can also add nodes that way.

Then all you have to do is respond to packets that arrive at that port.
There's a lot of BPTR messiness, butit's not too difficult, just very
annoying.  In an editor, your main event loop could just wait on both
the IDCMP and DOS ports.

One further note: it is a particularly fond wish of mine that a lot of the
BPTR stuff here will be totally scrapped in a few revs of the OS, so while
the basic idea (add device to system, handle service requests, remove device)
is unlikely to change, with luck the details will change dramatically.
-- 
	-Colin Plumb

deven@rpi.edu (Deven Corzine) (05/30/89)

In article <1989May28.171344.4525@ziebmef.uucp> mcp@ziebmef.uucp (Marc Plumb) writes:

> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
> >Help!  I desperatly need to be able to fake a filehandle.  [...]
> >How can I fake normal standard programs into sending their stdio
> >into my BBS code?

> Write a DOS handler.  [...]

Well, I'm sure you could do something much more easily, and perhaps
flexible and reliable enough...  using ConMan's CNX: handler...

Execute("run >nil: <nil: prog <cnx:serial.device >cnx:serial.device",0,0);

or some such...

Just a thought.

Deven
--
shadow@[128.113.10.2]   <shadow@pawl.rpi.edu> Deven T. Corzine (518) 272-5847
shadow@[128.113.10.201] <shadow@acm.rpi.edu>  2346 15th St.    Pi-Rho America
deven@rpitsmts.bitnet   <userfxb6@rpitsmts>   Troy, NY 12180-2306  <<tionen>>
"Simple things should be simple and complex things should be possible." - A.K.

peter@sugar.hackercorp.com (Peter da Silva) (05/31/89)

In article <1989May28.171344.4525@ziebmef.uucp>, mcp@ziebmef.uucp (Marc Plumb) writes:
> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
> >How can I fake normal standard programs into sending their stdio into
> >my BBS code?

> Write a DOS handler.

What's wrong with using a PIPE: type of device?
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

ddave@pnet02.cts.com (David Donley) (06/01/89)

peter@sugar.hackercorp.com (Peter da Silva) writes:
>In article <1989May28.171344.4525@ziebmef.uucp>, mcp@ziebmef.uucp (Marc Plumb) writes:
>> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>> >How can I fake normal standard programs into sending their stdio into
>> >my BBS code?
>
>> Write a DOS handler.
>
>What's wrong with using a PIPE: type of device?
>-- 
>Peter "Have you hugged your wolf today" da Silva      `-_-'
>...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

I can't use a pipe, the BBS must handle many events, it can't just wait for
data to come from a file.
                    Call the Bug Eyes BBS at (213) 372-4494
     ddave@pnet02.CTS.COM                      killer!gryphon!pnet02!ddave

bmacintyre@watcgl.waterloo.edu (Blair MacIntyre) (06/01/89)

In article <16317@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>peter@sugar.hackercorp.com (Peter da Silva) writes:
>>In article <1989May28.171344.4525@ziebmef.uucp>, mcp@ziebmef.uucp (Marc Plumb) writes:
>>> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>>> >How can I fake normal standard programs into sending their stdio into
>>> >my BBS code?
>>> Write a DOS handler.
>>What's wrong with using a PIPE: type of device?
>I can't use a pipe, the BBS must handle many events, it can't just wait for
>data to come from a file.


Well being as this is a multitasking computer ( you remember, we brag about
it all the time! ) why not write a little program that reads a file and
sends the appropriate message ( whatever that is ) to your BBS.

Then, you just redirect your output to a pipe: and read the pipe: with
that program.  I'm assuming that you know what kind of messages it is
you want to send, so this should be trivial ...

A DOS handler seems a bit extreme in this case.  I'm personally into the
"use existing tools" mentality that Peter ( I assume ) is into too, judging 
by his suggestion to use a pipe:

Blair
-- 
= Blair MacIntyre, bmacintyre@watcgl.{waterloo.edu, UWaterloo.ca}          // =
=   now appearing at the Computer Graphics Lab, U of Waterloo!           \X/  =
= "There's nothing the matter with BR that a shot gun blast wouldn't fix" cge =
= "It's not my fault, fatboy!" - Felder, pilot of TL Student Driver On Board  =

ddave@pnet02.cts.com (David Donley) (06/02/89)

bmacintyre@watcgl.waterloo.edu (Blair MacIntyre) writes:
>In article <16317@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>>peter@sugar.hackercorp.com (Peter da Silva) writes:
>>>In article <1989May28.171344.4525@ziebmef.uucp>, mcp@ziebmef.uucp (Marc Plumb) writes:
>>>> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>>>> >How can I fake normal standard programs into sending their stdio into
>>>> >my BBS code?
>>>> Write a DOS handler.
>>>What's wrong with using a PIPE: type of device?
>>I can't use a pipe, the BBS must handle many events, it can't just wait for
>>data to come from a file.
>
>
>Well being as this is a multitasking computer ( you remember, we brag about
>it all the time! ) why not write a little program that reads a file and
>sends the appropriate message ( whatever that is ) to your BBS.
>
>Then, you just redirect your output to a pipe: and read the pipe: with
>that program.  I'm assuming that you know what kind of messages it is
>you want to send, so this should be trivial ...
>
>A DOS handler seems a bit extreme in this case.  I'm personally into the
>"use existing tools" mentality that Peter ( I assume ) is into too, judging 
>by his suggestion to use a pipe:
>
>Blair
>-- 
>= Blair MacIntyre, bmacintyre@watcgl.{waterloo.edu, UWaterloo.ca}          // =
>=   now appearing at the Computer Graphics Lab, U of Waterloo!           \X/  =
>= "There's nothing the matter with BR that a shot gun blast wouldn't fix" cge =
>= "It's not my fault, fatboy!" - Felder, pilot of TL Student Driver On Board  =


Ya know, that's a good idea there!  But if I can find out how to do it
otherwise, I probably will, I hate programs with tons and tons of tiny files
(Workbench comes to mind) and also programs with tons and tons of tasks (All
of which have lots of overhead) Also, I don't want to have to depend on
somebody having a certain pipe, so I'll have to have all the filenames
user-configable, and then I have to depend on people setting it up right... 
It is definatly something to consider though...  After all, a handler process
will probably take up more RAM than a little reporter for the main program... 
:-)

                    Call the Bug Eyes BBS at (213) 372-4494
     ddave@pnet02.CTS.COM                      killer!gryphon!pnet02!ddave

elg@killer.DALLAS.TX.US (Eric Green) (06/02/89)

in article <3889@sugar.hackercorp.com>, peter@sugar.hackercorp.com (Peter da Silva) says:
> In article <1989May28.171344.4525@ziebmef.uucp>, mcp@ziebmef.uucp (Marc Plumb) writes:
>> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>> >How can I fake normal standard programs into sending their stdio into
>> >my BBS code?
>> Write a DOS handler.
> What's wrong with using a PIPE: type of device?

Nothing, for many programs. A lot, for some. Console packets,
y'know... PIPE: implements disk drive packets, not console packets. 

Matt Dillon's Dpipe or maybe Bill Hawes's PIP: might do the trick.
Matt certainly does open remote CLI's using dpipe...

--
    Eric Lee Green              P.O. Box 92191, Lafayette, LA 70509     
     ..!{ames,decwrl,mit-eddie,osu-cis}!killer!elg     (318)989-9849    

elg@killer.DALLAS.TX.US (Eric Green) (06/02/89)

in article <16317@gryphon.COM>, ddave@pnet02.cts.com (David Donley) says:
> peter@sugar.hackercorp.com (Peter da Silva) writes:
>>> In article <16031@gryphon.COM> ddave@pnet02.cts.com (David Donley) writes:
>>> >How can I fake normal standard programs into sending their stdio into
>>> >my BBS code?
>>What's wrong with using a PIPE: type of device?
> I can't use a pipe, the BBS must handle many events, it can't just wait for
> data to come from a file.

So use asynchronous I/O, and Wait() on both the pipe-handler and your
events (I assume menupicks and timers and such?). See the latest
AmyTransactor for John Toebes/et. al.'s excellent article on the
subject. Also, Matt Dillon has a library somewhere for doing async
I/O, to go with his libraries to do just about everything else under
the sun :-). 

Someone else suggested multitasking it off as a seperate task, but
that won't work here. If the person doesn't type anything in the past,
say, 5 minutes, the BBS has to assume he's gone to lunch, i.e. we have
to be waiting on a timer as well as on file and modem i/o. Might as
well just do it in the BBS instead of spawning it off. 

--
    Eric Lee Green              P.O. Box 92191, Lafayette, LA 70509     
     ..!{ames,decwrl,mit-eddie,osu-cis}!killer!elg     (318)989-9849    
"I have seen or heard 'designer of the 68000' attached to so many names that
 I can only guess that the 68000 was produced by Cecil B. DeMille." -- Bcase

limonce@pilot.njin.net (Tom Limoncelli) (06/02/89)

How about a newer version of AUX: that could be told things like "on
loss of CD exit" and "after xxx minutes of idle time exit" and "in xxx
minutes exit" and then can be told what to do to "exit" (could be the
command to that program or it could simulate a close-box press, etc).

I guess it's a bit complicated.  But that's what's needed for a BBS.
I assume that eventually someone will write something and set the
standard, but it would be nice for someone to come out with a REALLY
good BBS program at all :-)

-Tom
-- 
 Tom Limoncelli -- tlimonce@drunivac.Bitnet -- limonce@pilot.njin.net
       Drew University -- Box 1060, Madison, NJ -- 201-408-5389
   Standard Disclaimer: I am not the mouth-piece of Drew University

bradch@microsoft.UUCP (Bradford Christian ms1) (06/06/89)

[is the line eater still alive???]

I think I'm confused about what is really wanted here...  You have a BBS and
want to let the user run a CLI-style program, right?  You can't use AUX:
because you need to be doing other things like checking for carrier and
time-up, etc. (and besides, AUX: doesn't do raw), right?  If so, then I
guess I'm not confused.  If that's not it, quickly press N now :-)

I am about to do something similar for the Amiga port of Citadel which I'm
working on.  I also want the ability to log everything the user does with
said program (which might be a shell).  Something similar to the Unix tee
would be real nice.

I'll be writing a DOS device handler that can simulate CON: (including the
special packet to switch to RAW: and back).  This handler will allow a 
program to be run with all of its output going to the serial port and the
console and it's input coming from the serial port or keyboard.

The handler will be handled the same way the window, serial port, and timer
are already handled (GetMsg(), DealWithMsg(), etc.) and the host (BBS) will
be able to simulate ^C-^F to stop the program if necessary.

There is really nothing magical about doing this (unless you don't own an
Amiga ;^)  and if I understand the problem here, this is (IMHO) the
BEST solution.  I don't have it in front of me, but I believe the DOS
handler I put into my editor was only about 30-40 lines of C.

I expect to have this written and working in a couple of weeks (it's a
background project) so if anyone is interested in the code, send me
mail and you'll get it as soon as it's done.  If there is enough interest,
I'll just post it...
					 ***
		   This has nothing	* | * "It's not just a sign,
	BradCh	      to do with	*/|\*    it's a way of life."
		      Microsoft.	 ***

jms@tardis.Tymnet.COM (Joe Smith) (06/07/89)

In article <5866@microsoft.UUCP> bradch@microsoft.UUCP (Bradford Christian ms1) writes:
>...  I also want the ability to log everything the user does with
>said program (which might be a shell).  Something similar to the Unix tee
>would be real nice.
>I'll be writing a DOS device handler that can simulate CON: (including the
>special packet to switch to RAW: and back).  This handler will allow a 
>program to be run with all of its output going to the serial port and the
>console and it's input coming from the serial port or keyboard.

Another place to look for ideas: try HARDCOPY.C on Fish Disk #75.
The following is an excerpt from its DOC file.

OVERVIEW:

HARDCOPY is a program that "clones" the CLI output stream and sends it to two
places at one time:  the normal CLI window, and a file.  With it, you can
create a hardcopy listing of all the activity that went on in a CLI window. 
This can be useful for documentation purposes, error analysis, and error
reporting.  The advantage of using HARDCOPY instead of output-redirection is
that you still see the output in the CLI window (as well as capture it in a 
file).  This makes getting a hardcopy listing of an interactive session much 
easier.  HARDCOPY's major drawback is that it only copies text that goes to 
or from the CLI window; it does not record any of the activity that occurs in 
programs that open their own Intuition windows.  It will, however, record all 
data entered in CON and RAW windows opened from the CLI window from which a
HARDCOPY is being made.


USING HARDCOPY:

To use HARDCOPY, type:

    1> HARCOPY TO <file>

where <file> is the name of a file where HARDCOPY will record your CLI
session.  This can be on disk, in RAM:, or even directly to PRT:.

If you are running a program that sets up its own screen and eventually
crashes, you can have it use printf() to send diagnostic messages to the CLI
window, and have them recorded to a file even if the program crashes before
you can flip the screen to look at the CLI window.

You can use HARDCOPY to capture the exact input you used to produce an error,
so that you can report the error easier (and so people will believe that it
really occured).

You can HARDCOPY TO PRT: to produce a printed listing of your work as it
happens.  

TECHNICAL NOTES:

HARDCOPY is based on MONPROC by Phillip Lindsay of Commodore-Amiga, and is an
example of a real-life program that uses his method to monitor the AmigaDOS
activity of a process.  It was the simplest and most useful example I could
think of, but undoubtedly there are others.

Phillip pointed out that the pr_PktWait field of the Process structure is used
for an alternate taskwait() routine.  AmigaDOS calls this routine whenever a
process is waiting for AmigaDOS messages to be issued or returned.  HARDCOPY
installs its own code in this field.  This code waits for AmigaDOS packets to
arrive, and then signals a monitoring process.  This process checks to see if
the packet is to or from the CLI window.  If it is, it writes the contents of
the packet's data buffer to the output file.  Then it signals the pr_PktWait
routine that it is through writing (via a semaphore).  At that point, the
packet wait routine returns the packet to the process for its own use.

AUTHOR:

Davide P. Cervone                                   DPVC@UORDBV.BITNET
University of Rochester Computing Center            dpvc@tut.cc.rochester.EDU
Taylor Hall                                         dpvc@ur-tut.UUCP
Rochester New York  14627
(716) 275-2811
-- 
Joe Smith (408)922-6220 | SMTP: JMS@F74.TYMNET.COM or jms@tymix.tymnet.com
McDonnell Douglas FSCO  | UUCP: ...!{ames,pyramid}!oliveb!tymix!tardis!jms
PO Box 49019, MS-D21    | PDP-10 support: My car's license plate is "POPJ P,"
San Jose, CA 95161-9019 | narrator.device: "I didn't say that, my Amiga did!"

aaron@madnix.UUCP (Aaron Avery) (06/09/89)

In article <5866@microsoft.UUCP> bradch@microsoft.UUCP (Bradford Christian ms1) writes:
>I think I'm confused about what is really wanted here...  You have a BBS and
>want to let the user run a CLI-style program, right?  You can't use AUX:
>because you need to be doing other things like checking for carrier and
>time-up, etc. (and besides, AUX: doesn't do raw), right?  If so, then I
>guess I'm not confused.  If that's not it, quickly press N now :-)

AUX: does do raw mode. It understands the ACTION_SCREEN_MODE packet, and if
you put the line 'Startup = raw' in the mountlist entry for AUX:, it should
default to raw mode.

I'm sure your method of writing your own AUX: handler to support things like
carrier checking and timeouts is the proper way to go.

I have to warn you, though, that doing it right (like supporting asynchronous
reads and writes) is not trivial. I'd suggest finding the 1988 DevCon software
disks which include an excellent example to work from written by Andy Finkel.
This is a SER: type example, and not an AUX:, so there are many more CON:-like
issues you need to worry about.

Since you're doing work on a BBS which should, I believe, support multiple
lines, please include support for drivers other than serial.device, and unit
numbers. Multiple serial port hardware is here now, and the public deserves
good multi-line BBS support for this multi-tasking computer.

-- 
Aaron Avery, ASDG Inc.         "A mime is a terrible thing to waste."
                                                             -- Robin Williams
ARPA: madnix!aaron@cs.wisc.edu   {uunet|ncoast}!marque!
UUCP:   {harvard|rutgers|ucbvax}!uwvax!astroatc!nicmad!madnix!aaron

dillon@HERMES.BERKELEY.EDU (Matt Dillon) (06/13/89)

:So use asynchronous I/O, and Wait() on both the pipe-handler and your
:events (I assume menupicks and timers and such?). See the latest
:AmyTransactor for John Toebes/et. al.'s excellent article on the
:subject. Also, Matt Dillon has a library somewhere for doing async
:I/O, to go with his libraries to do just about everything else under
:the sun :-). 
:
:Someone else suggested multitasking it off as a seperate task, but
:that won't work here. If the person doesn't type anything in the past,
:say, 5 minutes, the BBS has to assume he's gone to lunch, i.e. we have
:to be waiting on a timer as well as on file and modem i/o. Might as
:well just do it in the BBS instead of spawning it off. 

	Yes, it is in my suplib link library.  The code is pretty old and
not all that pretty, but here it is (below)

	Note that various system #include's are missing (I use a 
precompiled include file for all the system stuff).  There are references
to other routines in suplib but what they do ought to be obvious.

	I also just noticed (not having looked at the routines for
a year or two) that it doesn't error check the buffer allocations.. oops.
	

					-Matt


/*
 *  XFIO.C
 *
 *  Simple File IO with asyncronous READ and WRITE capability
 *  Perfect for protocol transfer applications
 *
 *  xfi = xfopen(name, modes, bufsize)  ("r", "w", "w+")
 *   n	= xfread(xfi, buf, bytes)   ASYNCRONOUS READ
 *  err = xfwrite(xfi, buf, bytes)  ASYNCRONOUS WRITE
 *  err = xfclose(xfi)
 *
 *  RESTRICTIONS:   NO seeking.  You can do one of xfread() or xfwrite()
 *  for a given open XFIle handle (not both).
 *
 *  xfwrite() returns a cumulative error (once an error occurs, it will not
 *  do any more writes).  xfclose() returns the cumulative write error
 *  (since the last write may have been asyncronous and thus the error
 *  unknown at the time).
 *
 *  Two buffers are created each bufsize/2 bytes in size.  for writing,
 *  one buffers is sent asyncronously while the other fills.  For reading,
 *  one buffer is filling while the other is being read.
 */

#define XFI	    struct _XFI
#define XFBUF	    struct _XFBUF
#define MSGPORT     struct MsgPort
#define FH	    struct FileHandle
#define STDPKT	    struct StandardPacket


XFBUF {
    long   bufsize;
    long   idx;
    long   max;
    char    buf[4];	/*  actually bufsize bytes long */
};

XFI {
    char    ro; 	/*  read only, else write only	*/
    char    pend;	/*  packet pending		*/
    char    err;	/*  cumulative error		*/
    char    reserved;
    XFBUF   *asbuf;
    XFBUF   *usbuf;
    FH	    *fh;
    STDPKT  sp; 	/*  asyncronous message 	*/
    MSGPORT rp; 	/*  reply port for pending pkts */
};

extern FH *Open();
extern void *malloc(), *FindTask();

/*BREAKUP   xfopen.c	*/

void *
xfopen(file, mode, bytes)
char *file;
char *mode;
{
    register XFI *xfi = malloc(sizeof(XFI));
    register long nbytes = bytes >> 1;
    int ap = 0;

    BZero(xfi, sizeof(XFI));
    if (mode[0] == 'w') {
	if (mode[1] == '+') {
	    ap = 1;
	    if ((xfi->fh = Open(file, 1005)) == NULL)
		xfi->fh = Open(file, 1006);
	    goto ok;
	}
	xfi->fh = Open(file, 1006);
	goto ok;
    }
    xfi->fh = Open(file, 1005);
ok:
    if (xfi->fh) {
	if (ap)
	    Seek(xfi->fh, 0, 1);
	xfi->fh = (FH *)((long)xfi->fh << 2);		/* BTOC()	    */
	xfi->asbuf = malloc(sizeof(XFBUF) + nbytes);    /* a little more    */
	xfi->usbuf = malloc(sizeof(XFBUF) + nbytes);    /* then we need     */
	BZero(xfi->asbuf, sizeof(XFBUF));
	BZero(xfi->usbuf, sizeof(XFBUF));
	xfi->ro = (mode[0] == 'r');
	xfi->asbuf->bufsize = xfi->usbuf->bufsize = nbytes;
	xfi->rp.mp_Node.ln_Type = NT_MSGPORT;
	xfi->rp.mp_Node.ln_Name = "XFIO-Async";
	xfi->rp.mp_Flags = PA_SIGNAL;
	xfi->rp.mp_SigBit = AllocSignal(-1);
	xfi->rp.mp_SigTask = FindTask(NULL);
	NewList(&xfi->rp.mp_MsgList);
	if (xfi->ro)
	    __xfstartasync(xfi, ACTION_READ);
    } else {
	free(xfi);
	xfi = NULL;
    }
    return(xfi);
}

/*BREAKUP   xfclose.c	*/


xfclose(xfi)
register XFI *xfi;
{
    int err = 1;
    if (xfi) {
	if (xfi->pend) {
	    xfi->pend = 0;
	    WaitPort (&xfi->rp);
	    GetMsg   (&xfi->rp);
	}
	if (!xfi->ro && xfi->usbuf->idx)
	    Write((long)xfi->fh >> 2, xfi->usbuf->buf, xfi->usbuf->idx);
	err = xfi->err;
	Close((long)xfi->fh >> 2);
	free(xfi->asbuf);
	free(xfi->usbuf);
	FreeSignal(xfi->rp.mp_SigBit);
	free(xfi);
    }
    return(err);
}

/*BREAKUP   xfseek.c	*/

xfseek(xfi, pos)	/* may not work */
XFI *xfi;
long pos;
{
    if (xfi) {
	if (xfi->pend) {
	    WaitPort (&xfi->rp);
	    GetMsg   (&xfi->rp);
	    xfi->pend = 0;
	    if (!xfi->ro) {
		if (xfi->sp.sp_Pkt.dp_Res1 != xfi->sp.sp_Pkt.dp_Arg3) {
		    xfi->err = 1;
		    return(1);
		}
	    }
	}
	if (!xfi->ro && xfi->usbuf->idx) {
	    Write((long)xfi->fh >> 2, xfi->usbuf->buf, xfi->usbuf->idx);
	    xfi->usbuf->idx = 0;
	}
	Seek((long)xfi->fh >> 2, pos, -1);
	if (xfi->ro) {
	    XFBUF *asbuf = xfi->asbuf;
	    xfi->asbuf = xfi->usbuf;
	    xfi->usbuf = asbuf;
	    xfi->usbuf->idx = xfi->usbuf->max = 0;
	    __xfstartasync(xfi, ACTION_READ);
	}
    }
}

/*BREAKUP xfgets.c  */

xfgets(xfi, buf, n)
XFI *xfi;
char *buf;
{
    register XFBUF *usbuf = xfi->usbuf;
    register int i, idx;
    if (!xfi->ro)
	return(-1);
    --n;
    for (i = 0;;) {
	for (idx = usbuf->idx; idx < usbuf->max && i < n; ++idx, ++i) {
	    if ((buf[i] = usbuf->buf[idx]) == '\n') {
		buf[i] = 0;
		usbuf->idx = idx+1;
		return(i);
	    }
	}
	usbuf->idx = idx;
	buf[i] = 0;
	if (i == n)
	    return(i);
	if (xfi->pend == 0)                             /* EOF      */
	    return(-1);
	WaitPort (&xfi->rp);
	GetMsg	 (&xfi->rp);
	xfi->pend = 0;
	if (xfi->sp.sp_Pkt.dp_Res1 <= 0) {              /* EOF      */
	    if (i == 0)
		return(-1);
	    return(i);
	}
	xfi->asbuf->max = xfi->sp.sp_Pkt.dp_Res1;
	xfi->asbuf->idx = 0;
	usbuf = xfi->asbuf;				/* swap bufs*/
	xfi->asbuf = xfi->usbuf;
	xfi->usbuf = usbuf;
	__xfstartasync(xfi, ACTION_READ);                 /* new async*/
    }
}

/*BREAKUP xfread.c  */

xfread(xfi, buf, n)
XFI *xfi;
char *buf;
{
    register XFBUF *usbuf = xfi->usbuf;
    register int orig = n;
    register int diff;

    if (!xfi->ro)
	return(0);
    while ((diff = usbuf->max - usbuf->idx) < n) {
	movmem(usbuf->buf + usbuf->idx, buf, diff);     /* copy entire buf */
	buf += diff;
	n -= diff;
	if (xfi->pend == 0) {
	    xfi->usbuf->idx = xfi->usbuf->max;
	    return(orig - n);
	}
	WaitPort (&xfi->rp);
	GetMsg	 (&xfi->rp);
	xfi->pend = 0;
	if (xfi->sp.sp_Pkt.dp_Res1 <= 0) {              /* EOF      */
	    xfi->usbuf->idx = xfi->usbuf->max;
	    return(orig - n);
	}
	xfi->asbuf->max = xfi->sp.sp_Pkt.dp_Res1;
	xfi->asbuf->idx = 0;
	usbuf = xfi->asbuf;				/* swap bufs*/
	xfi->asbuf = xfi->usbuf;
	xfi->usbuf = usbuf;
	__xfstartasync(xfi, ACTION_READ);                 /* new async*/
    }
    movmem(usbuf->buf + usbuf->idx, buf, n);
    usbuf->idx += n;
    return(orig);
}

/*BREAKUP   xfwrite.c	*/

xfwrite(xfi, buf, n)
XFI *xfi;
char *buf;
{
    register XFBUF *usbuf = xfi->usbuf;
    register int diff;

    if (xfi->ro || xfi->err)
	return(1);
    while ((diff = usbuf->bufsize - usbuf->idx) < n) {
	movmem(buf, usbuf->buf + usbuf->idx, diff);     /*  copy buf    */
	buf += diff;
	n -= diff;
	if (xfi->pend) {
	    WaitPort(&xfi->rp);
	    GetMsg  (&xfi->rp);
	    xfi->pend = 0;
	    if (xfi->sp.sp_Pkt.dp_Res1 != xfi->sp.sp_Pkt.dp_Arg3) {
		xfi->err = 1;
		return(1);
	    }
	}
	usbuf = xfi->asbuf;
	xfi->asbuf = xfi->usbuf;
	xfi->usbuf = usbuf;
	usbuf->idx = 0;
	__xfstartasync(xfi, ACTION_WRITE);
    }
    movmem(buf, usbuf->buf + usbuf->idx, n);
    usbuf->idx += n;
    return(xfi->err);
}

/*BREAKUP   xfstartasync.c  */

__xfstartasync(xfi, action)
register XFI *xfi;
{
    xfi->sp.sp_Msg.mn_Node.ln_Name = (char *)&(xfi->sp.sp_Pkt);
    xfi->sp.sp_Pkt.dp_Link = &(xfi->sp.sp_Msg);
    xfi->sp.sp_Pkt.dp_Port = &xfi->rp;
    xfi->sp.sp_Pkt.dp_Type = action;
    xfi->sp.sp_Pkt.dp_Arg1 = xfi->fh->fh_Arg1;
    xfi->sp.sp_Pkt.dp_Arg2 = (long)xfi->asbuf->buf;
    xfi->sp.sp_Pkt.dp_Arg3 = xfi->asbuf->bufsize;
    PutMsg (xfi->fh->fh_Type, &xfi->sp);
    xfi->pend = 1;
}

bradch@microsoft.UUCP (Bradford Christian ms1) (06/13/89)

In article <682@madnix.UUCP> aaron@madnix.UUCP (Aaron Avery) writes:
>AUX: does do raw mode. It understands the ACTION_SCREEN_MODE packet, and if
>you put the line 'Startup = raw' in the mountlist entry for AUX:, it should
>default to raw mode.

Hmmm..  I guess I have a different problem.  All I know is I tried running
ARC from a CLI connected to AUX: and when it asked me a question (and expected
a single Y/N character response), it just started printing the question over
and over (as if I typed something other than Y or N).

>I'm sure your method of writing your own AUX: handler to support things like
>carrier checking and timeouts is the proper way to go.

Thanks, me too!

>I have to warn you, though, that doing it right (like supporting asynchronous
>reads and writes) is not trivial. I'd suggest finding the 1988 DevCon software
>disks which include an excellent example to work from written by Andy Finkel.
>This is a SER: type example, and not an AUX:, so there are many more CON:-like
>issues you need to worry about.

To tell you the truth, I was going to punt asynch requests.  I don't know of
any programs that use async I/O with the console.  If this does turn out to
be a problem, I'll just queue requests...  Hopefully, there aren't too many
things that I need to do to "do it right" that I haven't thought of (although
there usually are :-)  Thanks for the pointer, I'll look for that example.

>Since you're doing work on a BBS which should, I believe, support multiple
>lines, please include support for drivers other than serial.device, and unit
>numbers. Multiple serial port hardware is here now, and the public deserves
>good multi-line BBS support for this multi-tasking computer.

Actually two BBSs.  An Amiga port of Citadel and my own design.  The Citadel
port is being done at the request of a local sysop and I hope to see it reduce
the number of BBS-PC boards around here.  I really doubt that I'll ever even
think about supporting multiple users with the Citadel code I have, however,
as it was never intended to run multiple users at once..  It will, of course, 
work with any named device and unit number provided said device acts like 
serial.device.  

My own program is a different story.  It was designed from the start with
multiple ports in mind.  Unfortunatly, I'm too stingy to buy a multi-port
board at their current price :-(  I don't even know if my program will 
ever be publicly available, anyway.

I agree, it is definatly time for multi-user boards.  Anyone creating a new
BBS program on the Amiga without this feature may as well write it for a
lesser machine.

>-- 
>Aaron Avery, ASDG Inc.         "A mime is a terrible thing to waste."
>                                                             -- Robin Williams
>ARPA: madnix!aaron@cs.wisc.edu   {uunet|ncoast}!marque!
>UUCP:   {harvard|rutgers|ucbvax}!uwvax!astroatc!nicmad!madnix!aaron

	BradCh

new@udel.EDU (Darren New) (06/14/89)

>I agree, it is definatly time for multi-user boards.  Anyone creating a new
>BBS program on the Amiga without this feature may as well write it for a
>lesser machine.
>
Am I correct in assuming that all the multi-port serial boards available
now or in the near future will have an interface identical to the 
serial.device except for possibly the name and/or unit number on the
Open() call? In my BBS I plan to go multi-user by having multiple
copies of the BBS running at once, possibly after writing the
code to be residentable (seemed obvious to me :-). However, I don't
have a multiport board (yet) and was to have tested it by allowing
console.device access as well. If different boards need different
intefaces, it's probably not worth my time. -- Darren

papa@pollux.usc.edu (Marco Papa) (06/14/89)

In article <17575@louie.udel.EDU> new@udel.EDU (Darren New) writes:
>Am I correct in assuming that all the multi-port serial boards available
>now or in the near future will have an interface identical to the 
>serial.device except for possibly the name and/or unit number on the
>Open() call?

Yes. If they don't have an interface identical to the serial.device, then they
do not conform to CBM published multi-serial standard.

-- Marco Papa 'Doc'
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uucp:...!pollux!papa       BIX:papa       ARPAnet:pollux!papa@oberon.usc.edu
 "There's Alpha, Beta, Gamma and Diga!" -- Leo Schwab [quoting Rick Unland]
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

bradch@microsoft.UUCP (Bradford Christian ms1) (06/16/89)

In article <17575@louie.udel.EDU> new@udel.EDU (Darren New) writes:
> [...] In my BBS I plan to go multi-user by having multiple
>copies of the BBS running at once, possibly after writing the
>code to be residentable (seemed obvious to me :-).  [...]

I don't know if you've thought about this yet or not so I thought I'd
bring it up: multiple instances do not a multi-user program make.  If
your program has any sort of data-base (like messages, mail, etc.), then
you will have to coordinate access to the data base.  For example, if
your message base is one big file (a good thing to do to avoid wasted
bytes at the end of blocks), then one user reading the file will prevent
another user from adding a message to it.  Running totaly separate
instances will probably also make a CB mode (where two users can chat
with each other directly) difficult.

My solution to this problem is to have one instance of the program handle
any number of users.  The main process manages the data base and is the
only thing that has access to these files.  Each port has it's own process
which sends messages to the main process when it needs to read or write
an item in the data base.  This solution not only solves the data base
access problem, but also makes it real easy to allow two (or more) users
to chat.

I hope this doesn't mess up your plans, but if you hadn't thought of this
and haven't started coding yet, it should be worth thinking about.  A
possible alternative to the method I use would be to write a multi-user
data base handler as a separate program.  You could then run multiple
instances of you BBS program, one for each user, which would access the
data base by sending messages to the handler.

Good luck with your program!

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (06/17/89)

In <6043@microsoft.UUCP>, bradch@microsoft.UUCP (Bradford Christian ms1) writes:
>In article <17575@louie.udel.EDU> new@udel.EDU (Darren New) writes:
>> [...] In my BBS I plan to go multi-user by having multiple
>>copies of the BBS running at once, possibly after writing the
>>code to be residentable (seemed obvious to me :-).  [...]
>
>I don't know if you've thought about this yet or not so I thought I'd
>bring it up: multiple instances do not a multi-user program make.
> [ ... ]
>Running totaly separate instances will probably also make a CB mode (where two
>users can chat with each other directly) difficult.

It is just as easy to connect users in a 'CB' mode via interprocess messaging
as it is to connect them within a single program.

>My solution to this problem is to have one instance of the program handle
>any number of users.  The main process manages the data base and is the
>only thing that has access to these files.  Each port has it's own process
>which sends messages to the main process when it needs to read or write
>an item in the data base.  This solution not only solves the data base
>access problem, but also makes it real easy to allow two (or more) users
>to chat.

Think modularity. A 'dispatcher' that watches the serial port and kicks off a
module that talks to the serial port. A messaging and mail handler, protocol
modules, and so on. Modularity brings generality if the moduels are well thought
out, with the attendant ease of going to more lines or a different
manufacturer's board. Messaging, up/downloads, and CB become a simple matter of
routing messages.

>I hope this doesn't mess up your plans, but if you hadn't thought of this
>and haven't started coding yet, it should be worth thinking about.  A
>possible alternative to the method I use would be to write a multi-user
>data base handler as a separate program.  You could then run multiple
>instances of you BBS program, one for each user, which would access the
>data base by sending messages to the handler.
>
>Good luck with your program!

While there can be some advantages in having a 'main process', it is certainly
not a requirement, especially in te sense that one process is 'boss'.
Peer-to-peer modularity can be every bit as effective, and offer some unique
advantages, some of which may have nothing to do with the BBS itself.

-larry

--
Van Roy's Law:  An unbreakable toy is useful for breaking other toys.
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

ddave@pnet02.cts.com (David Donley) (06/19/89)

aaron@madnix.UUCP (Aaron Avery) writes:
>Since you're doing work on a BBS which should, I believe, support multiple
>lines, please include support for drivers other than serial.device, and unit
>numbers. Multiple serial port hardware is here now, and the public deserves
>good multi-line BBS support for this multi-tasking computer.
>
>-- 
>Aaron Avery, ASDG Inc.         "A mime is a terrible thing to waste."
>                                                             -- Robin Williams
>ARPA: madnix!aaron@cs.wisc.edu   {uunet|ncoast}!marque!
>UUCP:   {harvard|rutgers|ucbvax}!uwvax!astroatc!nicmad!madnix!aaron

I think it should support multiple lines too...  But I probably won't be
working on it much longer.  Anyhow, I support different device numbers, but
not multiple drivers as of now.  What the public needs is a company to make a
good multi-serial port box for the '500 that can accept 1 meg memory chips...
:-)
 _               _
| \ _   ___ _   | \ _    | _    Call THE Bug Eyes BBS at (213) 372-4494.
|_//-\\/_|_|_)  |_/(_)/\/||_-\/ Life is too short for copy-protection-
^[33m^[41mANSI is my life!^[m/  and should be even shorter for pirates!
Send mail to: ddave@pnet02.CTS.COM or killer!gryphon!pnet02!ddave NO FLAMES!