page%swap@Sun.COM (Bob Page) (09/15/89)
Submitted-by: sas!walker@mcnc.org (Doug Walker)
Posting-number: Volume 89, Issue 177
Archive-name: devices/net.4
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# server/io.c
# server/lock.c
# server/main.c
# server/makefile
# server/netdnet.c
# server/server.h
# server/struct.h
# server/volume.c
# subs.c
# timer.c
# util/handd.c
# util/netmount.c
# util/netstat.c
# util/netstat.h
# util/shutdown.c
# This is archive 4 of a 4-part kit.
# This archive created: Fri Sep 15 00:24:40 1989
if `test ! -d server`
then
mkdir server
echo "mkdir server"
fi
echo "extracting server/io.c"
sed 's/^X//' << \SHAR_EOF > server/io.c
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987, 1988 The Software Distillery. All Rights */
X/* |. o.| || Reserved. This program may not be distributed without the */
X/* | . | || permission of the authors: BBS: */
X/* | o | || John Toebes Doug Walker Dave Baker */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* File Access: */
X/* RmtRead RmtWrite RmtSeek RmtWaitForChar */
X/* RmtFindwrite RmtFindin RmtFindout RmtEnd */
X
X#include "server.h"
X
Xstatic long CurrentPos U_ARGS((GLOBAL, struct DosPacket *));
X
Xstatic long CurrentPos(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X pkt->dp_Type = ACTION_SEEK;
X pkt->dp_Arg1 = ((struct FileHandle *)global->RP.Arg1)->fh_Arg1;
X pkt->dp_Arg2 = 0L;
X pkt->dp_Arg3 = OFFSET_CURRENT;
X Dispatch(global);
X return(pkt->dp_Res1);
X}
X
X/*-------------------------------------------------------------------------*/
X/* */
X/* RmtRead( global, pkt ) */
X/* */
X/*-------------------------------------------------------------------------*/
X
Xvoid RmtRead(global,pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X/* Arg1: APTR EFileHandle */
X/* Arg2: APTR Buffer */
X/* Arg3: Length */
X{
X long toread, amount, total, offset;
X
X BUG(("RmtRead of %d bytes\n", global->RP.Arg3));
X
X /* 1. Seek 0 to get current position in file
X * 2. Dispatch read (max NETBUFSIZE bytes)
X * 3. If error, seek back to original pos
X * 4. Reply to other side
X * 5. If more to read, go back to (2)
X */
X if((offset = CurrentPos(global, pkt))<0)
X {
X BUG(("RmtRead: Seek failed, code %d\n", pkt->dp_Res2));
X global->RP.Arg1 = pkt->dp_Res1;
X global->RP.Arg2 = pkt->dp_Res2;
X return;
X }
X
X BUG(("RmtRead: Seek done, position is %d\n", offset));
X
X /* Arg1 was set by the CurrentPos function to be the filehandle */
X pkt->dp_Type = ACTION_READ;
X pkt->dp_Arg2 = (LONG)global->RP.Data;
X toread = global->RP.Arg3;
X
X for(total=0; toread; total+=amount, toread-=amount)
X {
X /* If this isn't the first time, wait for confirmation */
X if(total) GetRPacket(global, global->n.devptr);
X
X pkt->dp_Arg3 = min(toread, NETBUFSIZE);
X BUG(("RmtRead: Amount is %d, to read is %d\n", pkt->dp_Arg3, toread));
X Dispatch(global);
X
X global->RP.DLen = pkt->dp_Res1;
X if(PutRPacket(global, global->n.devptr)) pkt->dp_Res1 = -1;
X
X /* If there was EOF or some kind of error, quit */
X
X if((amount=pkt->dp_Res1) == 0) break; /* Normal EOF */
X
X if(amount < 0)
X {
X if(offset >= 0)
X {
X /* Seek back to the original pos */
X pkt->dp_Type = ACTION_SEEK;
X pkt->dp_Arg2 = offset;
X pkt->dp_Arg3 = OFFSET_BEGINNING;
X Dispatch(global);
X }
X break;
X }
X }
X BUG(("RmtRead: Done reading, returning\n"));
X global->n.reply = 0; /* Don't resend the last packet */
X}
X
X/*-------------------------------------------------------------------------*/
X/* */
X/* RmtWrite( global, pkt ) */
X/* */
X/*-------------------------------------------------------------------------*/
X
Xvoid RmtWrite(global,pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X/* Arg1: APTR EFileHandle */
X/* Arg2: APTR Buffer */
X/* Arg3: Length */
X{
X long offset;
X BUG(("RmtWrite\n"));
X
X if((offset = CurrentPos(global, pkt))<0)
X {
X BUG(("RmtWrite: Seek failed, code %d\n", pkt->dp_Res2));
X global->RP.Arg1 = pkt->dp_Res1;
X global->RP.Arg2 = pkt->dp_Res2;
X return;
X }
X
X pkt->dp_Type = ACTION_WRITE;
X pkt->dp_Arg2 = (LONG)global->RP.Data;
X
X while(1)
X {
X pkt->dp_Arg3 = global->RP.Arg3;
X Dispatch(global);
X
X global->RP.DLen = 0;
X if(PutRPacket(global, global->n.devptr)) pkt->dp_Res1 = -1;
X if(pkt->dp_Res1 == -1)
X {
X if(offset >= 0)
X {
X /* Seek back to where we started */
X pkt->dp_Type = ACTION_SEEK;
X pkt->dp_Arg2 = offset;
X pkt->dp_Arg3 = OFFSET_BEGINNING;
X Dispatch(global);
X }
X break;
X }
X if(global->RP.Arg4 == 0) break; /* no more to write */
X
X GetRPacket(global, global->n.devptr);
X }
X global->n.reply = 0; /* Don't reply twice */
X}
X
X/*-------------------------------------------------------------------------*/
X/* */
X/* RmtSeek( global, pkt ) */
X/* */
X/*-------------------------------------------------------------------------*/
X
Xvoid RmtSeek(global,pkt)
XGLOBAL global;
Xstruct DosPacket *pkt; /* a pointer to the dos packet sent */
X/* Arg1: APTR EFileHandle */
X/* Arg2: Position */
X/* Arg3: Mode */
X{
X BUG(("RmtSeek\n"));
X pkt->dp_Arg1 = ((struct FileHandle *)global->RP.Arg1)->fh_Arg1;
X pkt->dp_Arg2 = global->RP.Arg2;
X pkt->dp_Arg3 = global->RP.Arg3;
X
X Dispatch(global);
X
X global->RP.DLen = 0;
X}
X
X/*-------------------------------------------------------------------------*/
X/* */
X/* RmtFindwrite( global, pkt ) */
X/* */
X/*-------------------------------------------------------------------------*/
X
Xvoid RmtFindwrite(global,pkt)
XGLOBAL global;
Xstruct DosPacket *pkt; /* a pointer to the dos packet sent */
X/* ARG1: FileHandle to fill in */
X/* ARG2: Lock for file relative to */
X/* Arg3: Name of file */
X{
X struct FileHandle *fh;
X BUG(("RmtFindwrite, lock %lx\n", global->RP.Arg2));
X BUGBSTR("Filename = ", global->RP.Data);
X
X if(!(fh=(struct FileHandle *)
X DosAllocMem(global, sizeof(struct FileHandle))))
X {
X global->RP.Arg1 = DOS_FALSE;
X global->RP.Arg2 = ERROR_NO_FREE_STORE;
X return;
X }
X BUG(("Allocated FileHandle = %lx\n", fh));
X
X pkt->dp_Arg1 = (LONG)MKBADDR(fh);
X pkt->dp_Arg2 = global->RP.Arg2;
X MBSTR(global->RP.Data, global->fib);
X pkt->dp_Arg3 = (LONG)MKBADDR(global->fib);
X
X Dispatch(global);
X
X /* If the open was successful, return the allocated filehandle as Arg3 */
X if(pkt->dp_Res1 == DOS_FALSE) DosFreeMem((char *)fh);
X else global->RP.Arg3 = (LONG)fh;
X
X global->RP.DLen = 0;
X}
X
X/*-------------------------------------------------------------------------*/
X/* */
X/* RmtEnd( global, pkt ) */
X/* */
X/*-------------------------------------------------------------------------*/
X
Xvoid RmtEnd( global, pkt )
XGLOBAL global;
Xstruct DosPacket *pkt; /* a pointer to the dos packet sent */
X{
X struct FileHandle *fh;
X BUG(("RmtEnd, freeing %lx\n", global->RP.Arg1));
X
X pkt->dp_Arg1 = (fh=(struct FileHandle *)global->RP.Arg1)->fh_Arg1;
X
X Dispatch(global);
X
X DosFreeMem((char *)fh);
X
X global->RP.DLen = 0;
X}
SHAR_EOF
echo "extracting server/lock.c"
sed 's/^X//' << \SHAR_EOF > server/lock.c
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987, 1988 The Software Distillery. All Rights */
X/* |. o.| || Reserved. This program may not be distributed without the */
X/* | . | || permission of the authors: BBS: */
X/* | o | || John Toebes Doug Walker Dave Baker */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X
X/* Lock.c - lock manipulation */
X/* RmtLock, RmtDupLock, RmtUnLock */
X
X/*-------------------------------------------------------------------------*/
X/* Structure of a Lock: */
X/* struct FileLock { */
X/* BPTR fl_Link; Next lock in the chain of device locks */
X/* LONG fl_Key; Block number of directory or file header */
X/* LONG fl_Access; Shared Read (-2) or Exclusive Write (-1) */
X/* struct MsgPort * fl_Task; Handler process for Lock (Us) */
X/* BPTR fl_Volume; Node in DevInfo structure for Lock */
X/* }; */
X/*-------------------------------------------------------------------------*/
X#include "server.h"
X
Xvoid RmtLock(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X BUG(("RmtLock: lock %lx\n", global->RP.Arg1));
X BUGBSTR("Locking filename = ", global->RP.Data);
X
X pkt->dp_Arg1 = global->RP.Arg1;
X MBSTR(global->RP.Data, global->fib);
X pkt->dp_Arg2 = (LONG)MKBADDR(global->fib);
X pkt->dp_Arg3 = global->RP.Arg3; /* Mode */
X
X Dispatch(global);
X
X global->RP.DLen = 0;
X}
X
Xvoid RmtDupLock(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X BUG(("RmtDupLock\n"));
X pkt->dp_Arg1 = global->RP.Arg1;
X
X Dispatch(global);
X
X global->RP.DLen = 0;
X}
X
Xvoid RmtUnLock(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X BUG(("RmtUnLock\n"));
X pkt->dp_Arg1 = global->RP.Arg1;
X
X Dispatch(global);
X
X global->RP.DLen = 0;
X}
SHAR_EOF
echo "extracting server/main.c"
sed 's/^X//' << \SHAR_EOF > server/main.c
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987, 1988 The Software Distillery. All Rights */
X/* |. o.| || Reserved. This program may not be distributed without the */
X/* | . | || permission of the authors: BBS: */
X/* | o | || John Toebes Doug Walker Dave Baker */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X
X#include "server.h"
X
X/* Eventually, make this table work for me - flag significant args, */
X/* flag args that point into the data table. This will take care of */
X/* everything but Examine, ExNext, Read and Write with no special funcs */
X
X/******************************************************************************/
X/******************************************************************************/
X/********************* Dispatch table to handle all packets *******************/
X/******************************************************************************/
X/******************************************************************************/
X#define BP1 1
X#define BP2 2
X#define BP3 4
X#define BP4 8
X
Xtypedef void (*ifuncp)(GLOBAL, struct DosPacket *);
Xstruct LookupTable
X {
X ifuncp subr;
X int flags;
X };
X
X#define LO_FIRST 0
X#define LO_LAST 34
Xstruct LookupTable lowork[LO_LAST+1] = {
X { NULL, 0 | 0 | 0 | 0 }, /* 0 - ACTION_NIL */
X { NULL, 0 | 0 | 0 | 0 }, /* 1 - Unknown */
X { NULL, BP1| BP2| BP3| 0 }, /* 2 - ACTION_GET_BLOCK */
X { NULL, 0 | BP2| BP3| 0 }, /* 3 - Unknown */
X { NULL, BP1| BP2| BP3| 0 }, /* 4 - ACTION_SET_MAP */
X { RmtDie, 0 | 0 | 0 | 0 }, /* 5 - ACTION_DIE */
X { NULL, 0 | 0 | 0 | 0 }, /* 6 - ACTION_EVENT */
X { NULL, BP1| 0 | 0 | 0 }, /* 7 - ACTION_CURRENT_VOLUME */
X { RmtLock, BP1| BP2| 0 | 0 }, /* 8 - ACTION_LOCATE_OBJECT */
X { NULL, BP1| BP2| 0 | 0 }, /* 9 - ACTION_RENAME_DISK */
X { NULL, 0 | 0 | 0 | 0 }, /* 10 - Unknown */
X { NULL, 0 | 0 | 0 | 0 }, /* 11 - Unknown */
X { NULL, 0 | 0 | 0 | 0 }, /* 12 - Unknown */
X { NULL, 0 | 0 | 0 | 0 }, /* 13 - Unknown */
X { NULL, 0 | 0 | 0 | 0 }, /* 14 - Unknown */
X { RmtUnLock, BP1| 0 | 0 | 0 }, /* 15 - ACTION_FREE_LOCK */
X { RmtDelete, BP1| BP2| 0 | 0 }, /* 16 - ACTION_DELETE_OBJECT */
X { RmtRename, BP1| BP2| BP3| BP4 }, /* 17 - ACTION_RENAME_OBJECT */
X { NULL, 0 | 0 | 0 | 0 }, /* 18 - ACTION_MORE_CACHE */
X { RmtDupLock, BP1| 0 | 0 | 0 }, /* 19 - ACTION_COPY_DIR */
X { NULL, 0 | 0 | 0 | 0 }, /* 20 - ACTION_WAIT_CHAR */
X { RmtSetProtection, 0 | BP2| BP3| 0 }, /* 21 - ACTION_SET_PROTECT */
X { RmtCreateDir, BP1| BP2| 0 | 0 }, /* 22 - ACTION_CREATE_DIR */
X { RmtExamine, BP1| BP2| 0 | 0 }, /* 23 - ACTION_EXAMINE_OBJECT */
X { RmtExNext, BP1| BP2| 0 | 0 }, /* 24 - ACTION_EXAMINE_NEXT */
X { NULL, BP1| 0 | 0 | 0 }, /* 25 - ACTION_DISK_INFO */
X { RmtInfo, BP1| BP2| 0 | 0 }, /* 26 - ACTION_INFO */
X { NULL, 0 | 0 | 0 | 0 }, /* 27 - ACTION_FLUSH */
X { RmtSetComment, 0 | BP2| BP3| BP4 }, /* 28 - ACTION_SET_COMMENT */
X { RmtParent, BP1| 0 | 0 | 0 }, /* 29 - ACTION_PARENT */
X { NULL, BP1| 0 | 0 | 0 }, /* 30 - ACTION_TIMER */
X { NULL, 0 | 0 | 0 | 0 }, /* 31 - ACTION_INHIBIT */
X { NULL, BP1| 0 | 0 | 0 }, /* 32 - ACTION_DISK_TYPE */
X { NULL, 0 | 0 | 0 | 0 }, /* 33 - ACTION_DISK_CHANGE */
X { NULL, 0 | 0 | 0 | 0 } /* 34 - ACTION_SET_FILE_DATE */
X };
X
X#define HI_FIRST 1004
X#define HI_LAST 1008
Xstruct LookupTable hiwork[5] = {
X { RmtFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_WRITE - 1004 */
X { RmtFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_INPUT - 1005 */
X { RmtFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_OUTPUT - 1006 */
X { RmtEnd, 0 | 0 | 0 | 0 }, /* ACTION_END - 1007 */
X { RmtSeek, 0 | 0 | 0 | 0 } /* ACTION_SEEK - 1008 */
X };
X
X#define USER_FIRST 2010
X#define USER_LAST 2012
Xstruct LookupTable userwork[3] = {
X { RmtSetDebug, 0 | 0 | 0 | 0 }, /* ACTION_HANDLER_DEBUG 2010 */
X { NULL, BP1| 0 | 0 | 0 }, /* ACTION_SET_TRANS_TYPE2011 */
X { NULL, BP1| 0 | 0 | 0 }, /* ACTION_NETWORK_HELLO 2012 */
X };
X
Xstruct DosLibrary *DOSBase;
X
Xvoid _main(x)
Xchar *x;
X{
X ifuncp subr;
X int action;
X struct global global;
X
X DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME,0);
X
X /* Initialize our global data structure */
X memset((char *)&global, 0, sizeof(struct global));
X global.n.self = (struct Process *) FindTask(0L); /* find myself */
X global.n.run = 1;
X global.n.port = &(global.n.self->pr_MsgPort);
X /* install our taskid ... */
X if(!(global.fib = (char *)
X DosAllocMem(&global, 2*sizeof(struct FileInfoBlock))))
X {
X global.n.run = 0;
X }
X
X /* Initialize the intuitext structures for the requesters we might have */
X /* to display */
X /* Because we have no scruples we can cheat and do this with a couple of */
X /* long word assignments. We leave the acual C code commented out here */
X /* so that if this structure ever changed we will still be able to work */
X#if 0
X global.n.line1.FrontPen = global.n.line1.BackPen = -1;
X global.n.line1.DrawMode = JAM1;
X global.n.line1.LeftEdge = global.n.line1.TopEdge = 4;
X global.n.line2 = global.n.line1;
X global.n.line3 = global.n.line1;
X global.n.retrytxt = global.n.line1;
X global.n.canceltxt = global.n.line1;
X#else
X *(long *)&global.n.line1.FrontPen = 0x00010000L | (JAM1<<8);
X *(long *)&global.n.line1.LeftEdge = 0x00040004L; /* 4,4 */
X *(long *)&global.n.line2.FrontPen = 0x00010000L | (JAM1<<8);
X *(long *)&global.n.line2.LeftEdge = 0x0004000EL; /* 4,14 */
X *(long *)&global.n.line3.FrontPen = 0x00010000L | (JAM1<<8);
X *(long *)&global.n.line3.LeftEdge = 0x00040018L; /* 4,24 */
X *(long *)&global.n.retrytxt.FrontPen = 0x00010000L | (JAM1<<8);
X *(long *)&global.n.retrytxt.LeftEdge = 0x00040004L;
X *(long *)&global.n.canceltxt.FrontPen = 0x00010000L | (JAM1<<8);
X *(long *)&global.n.canceltxt.LeftEdge = 0x00040004L;
X#endif
X global.n.retrytxt.IText = "Retry";
X global.n.canceltxt.IText = "Cancel";
X
X
X /* Should get startup info from external config file */
X if(InitDevice(&global))
X {
X BUG(("****** ERROR INITIALIZING\n"));
X#if DEBUG
X /* Can't use BUGR - need &global, not global */
X request(&global, REQ_GENERAL, "Can't init");
X#endif
X }
X else
X while(global.n.run) /* start of the real work */
X {
X if(GetRPacket(&global, global.n.devptr))
X {
X if(!ReSync(&global, global.n.devptr)) continue;
X break;
X }
X
X BUG(("Execute: action #%ld arg1 %lx\n",
X global.RP.Type, global.RP.Arg1));
X
X switch(action = global.pkt->dp_Type = global.RP.Type)
X {
X case ACTION_NETWORK_KLUDGE:
X subr = RmtNetKludge;
X break;
X
X case ACTION_READ:
X subr = RmtRead;
X break;
X case ACTION_WRITE:
X subr = RmtWrite;
X break;
X
X case ACTION_SET_RAW_MODE:
X subr = NULL;
X break;
X
X case ACTION_FIND_WRITE: /* 1004 */
X case ACTION_FIND_INPUT: /* 1005 */
X case ACTION_FIND_OUTPUT: /* 1006 */
X case ACTION_END: /* 1007 */
X case ACTION_SEEK: /* 1008 */
X subr = hiwork[action-HI_FIRST].subr;
X break;
X
X case ACTION_HANDLER_DEBUG: /* 2010 */
X case ACTION_SET_TRANS_TYPE: /* 2011 */
X case ACTION_NETWORK_HELLO: /* 2012 */
X subr = userwork[action-USER_FIRST].subr;
X break;
X
X default:
X if ((action >= LO_FIRST) && (action <= LO_LAST))
X {
X subr = lowork[action-LO_FIRST].subr;
X }
X else
X subr = NULL;
X }
X
X if(subr != NULL)
X {
X global.n.reply = 1;
X (*subr)(&global, global.pkt);
X }
X else
X {
X global.RP.Arg1 = DOS_FALSE;
X global.RP.Arg2 = ERROR_ACTION_NOT_KNOWN;
X BUG(("Unknown packet type %ld\n",global.RP.Type));
X }
X
X /* Now return the packet to them */
X if (global.n.reply &&
X PutRPacket(&global, global.n.devptr) &&
X ReSync(&global, global.n.devptr))
X break;
X
X BUG(("-----\n"));
X }
X
X TermDevice(&global);
X
X BUGTERM()
X}
X
X#define DEBUG_SPECIAL 0x40000000 /* Mask for handler-defined dbg type*/
X#define DEBUG_SERVER 0x20000000 /* Mask indicating server command */
X#define DEBUG_SERVWT 0x10000000 /* Wait for debugger to catch us */
X
Xvoid RmtSetDebug(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X#if DEBUG
X BUG(("RmtSetDebug: Entry, arg1 %lx\n", global->RP.Arg1))
X if(global->RP.Arg1 == DEBUG_SERVWT)
X cprwait(global);
X else if(global->RP.Arg1)
X BUGINIT()
X else
X BUGTERM()
X
X#endif
X pkt->dp_Res1 = DOS_TRUE;
X}
SHAR_EOF
echo "extracting server/makefile"
sed 's/^X//' << \SHAR_EOF > server/makefile
X#DEBUG = -dDEBUG=1
XDEBUG =
X
X#LIBS = lib:lc.lib lib:amiga.lib define _SysBase = _AbsExecBase
XLIBS = lib:lc.lib lib:amiga.lib define _SysBase = 4
X
X#LC1FLAGS = -cwusf -b -d $(DEBUG) -d2
XLC1FLAGS = -cwusf -b -d $(DEBUG) -i/
XLC2FLAGS = -v
X
Xnetdnet-server: netdnet-server.d
X @blink from $+ to $@ nodebug
X
Xnetser-server: netser-server.d
X @blink from $+ to $@ nodebug
X
Xnetpar-server: netpar-server.d
X @blink from $+ to $@ nodebug
X
Xnetsing-server: netsing-server.d
X @blink from $+ to $@ nodebug
X
Xnetdnet-server.d: main.o /subs.o file.o dir.o io.o lock.o /sendpkt.o\
X device.o volume.o dispatch.o netdnet.o /iodnet.o /dnetlib.o /debug.o\
X /timer.o /request.o
X @echo >ram:tmp.with "from $+"
X @assign blinkwith:
X @blink with ram:tmp.with SC SD VERBOSE BATCH to $@ lib $(LIBS)\
X map netdnet-server.map hx
X
Xnetsing-server.d: main.o /subs.o file.o dir.o io.o lock.o /sendpkt.o\
X device.o volume.o dispatch.o netsing.o iosing.o /debug.o\
X /timer.o /request.o
X @echo >ram:tmp.with "from $+"
X @assign blinkwith:
X @blink with ram:tmp.with SC SD VERBOSE BATCH to $@ lib $(LIBS)
X
Xnetser-server.d: main.o /subs.o file.o dir.o io.o lock.o /sendpkt.o\
X device.o volume.o dispatch.o netser.o /ioser.o /debug.o /timer.o\
X /request.o
X @echo >ram:tmp.with "from $+"
X @assign blinkwith:
X @blink with ram:tmp.with SC SD VERBOSE BATCH to $@ lib $(LIBS)
X
Xnetpar-server.d: main.o /subs.o file.o dir.o io.o lock.o /sendpkt.o\
X device.o volume.o dispatch.o netpar.o /iopar.o /debug.o /timer.o\
X /request.o
X @echo >ram:tmp.with "from $+"
X @assign blinkwith:
X @blink with ram:tmp.with SC SD VERBOSE BATCH to $@ lib $(LIBS)
X
Xmain.o : main.c server.h /netcomm.h
X @echo "Compiling $<"
X @lc1 -. $(LC1FLAGS) -oram:temp.q $<
X @lc2 -. $(LC2FLAGS) -y -o$@ ram:temp.q
X
X/dnetlib.o : /dnetlib.c
X @echo "Compiling $<"
X @lc1 -. $(LC1FLAGS) -oram:temp.q $<
X @lc2 -. $(LC2FLAGS) -y -o$@ ram:temp.q
SHAR_EOF
echo "extracting server/netdnet.c"
sed 's/^X//' << \SHAR_EOF > server/netdnet.c
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
X* |_o_o|\\ Copyright (c) 1988 The Software Distillery. All Rights Reserved *
X* |. o.| || Written by Doug Walker *
X* | . | || The Software Distillery *
X* | o | || 235 Trillingham Lane *
X* | . |// Cary, NC 27513 *
X* ====== BBS:(919)-471-6436 *
X\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X
X#include "netdnet.h"
X#include "server.h"
X
X#if CPR
Xchar *dbgwind = "CON:0/0/640/160/NETDNET-SERVER/a";
X#endif
X
X#if 0
Xint ReSync(global, ioptr)
XGLOBAL global;
XAPTR ioptr;
X{
X char c;
X BUG(("ReSync: Entry\n"))
X
X if(ioptr)
X {
X DEof((struct DChannel *)ioptr);
X
X if(DRead((struct DChannel *)ioptr, &c, 1) == 1) return(0);
X }
X WaitPort(global->n.d.LisPort);
X if(!(global->n.devptr = (APTR)DAccept(global->n.d.LisPort)) )
X {
X BUG(("Failed\n"))
X return(1);
X }
X BUG(("Succeeded!\n"))
X return(0);
X}
X#else
Xint ReSync(global, ioptr)
XGLOBAL global;
XAPTR ioptr;
X{
X return(1);
X}
X#endif
X
Xint InitRDevice(global)
XGLOBAL global;
X{
X BUGP("InitRDevice: Entry")
X
X global->n.d.LisPort = DListen(PORT_FHANDLER);
X
X WaitPort(global->n.port);
X ReplyMsg(GetMsg(global->n.port)); /* Tell DNET we are here */
X
X if(!global->n.d.LisPort)
X {
X BUG(("InitRDevice: Can't init, LisPort %lx\n", global->n.d.LisPort));
X BUGR("Null LisPort");
X return(1);
X }
X
X /* Wait for a DNET request */
X Wait(1<<global->n.d.LisPort->mp_SigBit);
X
X if(!(global->n.devptr = (APTR)DAccept(global->n.d.LisPort)))
X {
X BUG(("InitRDevice: Can't DAccept\n"))
X BUGR("No DAccept")
X }
X
X global->n.histimeout = DNETTIMEOUT;
X global->n.mytimeout = 0;
X
X BUGP("InitRDevice: Exit")
X
X return(0);
X}
X
Xint TermRDevice(global)
XGLOBAL global;
X{
X
X if(global->n.d.LisPort)
X {
X DNAAccept(global->n.d.LisPort);
X DUnListen(global->n.d.LisPort);
X }
X DeletePort(global->n.devport);
X return(0);
X}
X
SHAR_EOF
echo "extracting server/server.h"
sed 's/^X//' << \SHAR_EOF > server/server.h
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987 The Software Distillery. All Rights Reserved */
X/* |. o.| || This program may not be distributed without the permission of */
X/* | . | || the authors: BBS: */
X/* | o | || John Toebes Dave Baker John Mainwaring */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X
X#include "netcomm.h"
X
Xvoid checkdebug U_ARGS((void));
X
X#if DEBUG
X#define BUGCHECK() checkdebug();
X#define BUGINIT() initdebug(NULL);
X#else
X#define BUGCHECK()
X#define BUGINIT()
X#endif
X
Xtypedef struct global
X {
X struct NetGlobal n; /* Globals in common with handler */
X struct RPacket RP; /* Data area for remote node */
X struct DosPacket *pkt; /* the packet we are processing */
X struct StandardPacket *stdpkt; /* Packet to send to local handlers */
X struct MsgPort *dosport; /* msgport for DOS device to talk to */
X struct RPacket *rpptr; /* Points to msg for singlemachine v */
X char *fib; /* For use by RmtExamine/RmtExNext */
X struct InfoData *infodata; /* For use by RmtInfo */
X LONG rootlock; /* Lock on root of ROOT: */
X }* GLOBAL;
X
X/* main.c */
Xvoid RmtSetDebug U_ARGS((GLOBAL, struct DosPacket *));
X
X/* file.c */
Xvoid RmtDelete U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtRename U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtSetComment U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtSetProtection U_ARGS((GLOBAL, struct DosPacket *));
X
X/* io.c */
Xvoid RmtFindwrite U_ARGS((GLOBAL, struct DosPacket *));
X#define RmtFindin RmtFindWrite
X#define RmtFindout RmtFindWrite
Xvoid RmtEnd U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtRead U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtWrite U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtSeek U_ARGS((GLOBAL, struct DosPacket *));
X
X/* dir.c */
Xvoid RmtCreateDir U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtExamine U_ARGS((GLOBAL, struct DosPacket *));
X#define RmtExNext RmtExamine
Xvoid RmtParent U_ARGS((GLOBAL, struct DosPacket *));
X
X/* lock.c */
Xvoid RmtLock U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtDupLock U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtUnLock U_ARGS((GLOBAL, struct DosPacket *));
X
X/* volume.c */
Xvoid RmtInfo U_ARGS((GLOBAL, struct DosPacket *));
Xvoid RmtNetKludge U_ARGS((GLOBAL, struct DosPacket *));
X
X/* device.c */
Xint InitDevice U_ARGS((GLOBAL));
Xint TermDevice U_ARGS((GLOBAL));
Xvoid RmtDie U_ARGS((GLOBAL, struct DosPacket *));
X
X/* Dispatch.c */
Xvoid Dispatch U_ARGS((GLOBAL));
X
X/* inhibit.c */
Xint inhibit U_ARGS((struct MsgPort *, long));
Xlong sendpkt U_ARGS((struct MsgPort *, long, long*, long));
X
X/* volume.c */
Xvoid RmtInfo U_ARGS((GLOBAL, struct DosPacket *));
X
X/* net#?.c */
Xint InitRDevice U_ARGS((GLOBAL));
Xint TermRDevice U_ARGS((GLOBAL));
X
X#include "/proto.h"
SHAR_EOF
echo "extracting server/struct.h"
sed 's/^X//' << \SHAR_EOF > server/struct.h
X#ifndef DSTRUCT
X#define DSTRUCT
X
X
Xstruct BUFDATA
X{
Xstruct Gadget Gadget1;
Xstruct Gadget Gadget2;
Xstruct Gadget Gadget3;
Xstruct PropInfo Gadget1SInfo;
Xint pos;
Xint size;
Xchar buf[1];
X};
X
Xunion STDATA
X{
X APTR data;
X struct BUFDATA *bdata;
X struct FileInfoBlock *fib;
X struct FileHandle *fh;
X struct FileLock *lock;
X struct InfoData *info;
X};
X
X#define WNAMELEN 20
X
Xstruct STNODE
X{
X struct STNODE *next, *prev;
X int len; /* Length of this allocation, for convenience */
X int num; /* Number of the node within its type */
X int type; /* One of the ST_ defines above */
X union STDATA d; /* Points to the mem allocted for the struct */
X char wname[WNAMELEN]; /* Name of the window */
X char *oname; /* Name of the object associated with it */
X struct Window *w; /* Points to the window opened to display it */
X};
X
Xstruct STGLOB
X{
X struct STNODE *stlist;/* Linked list of STNODE structures */
X struct STNODE *unlist;/* Linked list of unlinked nodes */
X int count[ST_NUM]; /* How many of each type there are */
X struct MsgPort *Port; /* Message port to use for comm with Intuition */
X};
X
X#define DOTEXT(y, format, val) \
X sprintf(data, format, val); \
X PrintIText(n->w->RPort, &IText, 0, y);
X
X
Xvoid stfhnew(struct NewWindow **, struct IntuiText **, struct STNODE *);
Xvoid stlocknew(struct NewWindow **, struct IntuiText **, struct STNODE *);
Xvoid stfibnew(struct NewWindow **, struct IntuiText **, struct STNODE *);
Xvoid stinfnew(struct NewWindow **, struct IntuiText **, struct STNODE *);
Xvoid stbufnew(struct NewWindow **, struct IntuiText **, struct STNODE *);
X
X
Xint stfhdisp(struct STNODE *);
Xint stlockdisp(struct STNODE *);
Xint stfibdisp(struct STNODE *);
Xint stinfdisp(struct STNODE *);
Xint stbufdisp(struct STNODE *);
Xint stbufmove(struct STNODE *, int);
X
X
X#endif
X
SHAR_EOF
echo "extracting server/volume.c"
sed 's/^X//' << \SHAR_EOF > server/volume.c
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987 The Software Distillery. All Rights Reserved */
X/* |. o.| || This program may not be distributed without the permission of */
X/* | . | || the authors: BBS: */
X/* | o | || John Toebes Dave Baker */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* Volume Manipulation */
X/* RmtCurentVol RmtRenameDisk RmtDiskInfo RmtInfo */
X
X#include "server.h"
X
Xvoid RmtInfo(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X BUG(("RmtInfo\n"));
X
X if(!global->infodata &&
X !(global->infodata = (struct InfoData *)
X DosAllocMem(global, sizeof(struct InfoData))))
X {
X BUG(("******* OUT OF MEMORY - can't get InfoData\n"));
X global->RP.Arg1 = DOS_FALSE;
X global->RP.Arg2 = ERROR_NO_FREE_STORE;
X return;
X }
X pkt->dp_Arg1 = global->RP.Arg1;
X pkt->dp_Arg2 = (LONG)global->infodata;
X
X Dispatch(global);
X
X MQ(global->infodata, global->RP.Data, sizeof(struct InfoData));
X
X global->RP.DLen = sizeof(struct InfoData);
X}
X
Xvoid RmtNetKludge(global, pkt)
XGLOBAL global;
Xstruct DosPacket *pkt;
X{
X struct MsgPort *newport;
X
X if(!(newport=(struct MsgPort *)DeviceProc(global->RP.Data)))
X {
X BUG(("********DeviceProc of %s Failed\n", global->RP.Data));
X BUGGETC
X pkt->dp_Res1 = DOS_FALSE;
X pkt->dp_Res2 = ERROR_OBJECT_NOT_FOUND;
X return;
X }
X global->RP.RDevice = (RPTR)(global->dosport = newport);
X pkt->dp_Res1 = DOS_TRUE;
X pkt->dp_Res2 = 0L;
X
X global->n.run++;
X
X BUG(("RmtNetKludge: New RDevice %lx\n", newport));
X}
X
SHAR_EOF
echo "extracting subs.c"
sed 's/^X//' << \SHAR_EOF > subs.c
X/* Subs.c - Basic network handler support routines */
X
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987 The Software Distillery. All Rights Reserved */
X/* |. o.| || This program may not be distributed without the permission of */
X/* | . | || the author. BBS: */
X/* | o | || John Toebes (919)-471-6436 */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X#define NETCOMMON
X#include "netcomm.h"
X#include "proto.h"
X/* misc.c - support routines - Phillip Lindsay (C) Commodore 1986
X * You may freely distribute this source and use it for Amiga Development -
X * as long as the Copyright notice is left intact.
X *
X * 30-SEP-86
X */
X
X/* returnpkt() - packet support routine
X * here is the guy who sends the packet back to the sender...
X */
X
Xvoid retpkt(global, packet)
XNGLOBAL global;
Xstruct DosPacket *packet;
X{
X struct Message *mess;
X struct MsgPort *replyport;
X
X replyport = packet->dp_Port;
X mess = packet->dp_Link;
X packet->dp_Port = global->n.port;
X
X PutMsg(replyport,mess);
X}
X
X/*
X * taskwait() ... Waits for a message to arrive at your port and
X * extracts the packet address which is returned to you.
X */
X
Xstruct DosPacket *taskwait(global)
XNGLOBAL global;
X{
X struct Message *mymess;
X
X WaitPort(global->n.port); /* wait for packet */
X mymess = (struct Message *) GetMsg(global->n.port);
X
X global->pkt = (struct DosPacket *) mymess->mn_Node.ln_Name;
X
X return(global->pkt);
X}
X
Xchar *DosAllocMem(global, len)
XNGLOBAL global;
Xlong len;
X{
Xlong *p;
X
Xif (( p = (long *)AllocMem(len+4, MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
X {
X if (global->pkt != NULL)
X {
X global->pkt->dp_Res1 = DOS_FALSE;
X global->pkt->dp_Res2 = ERROR_NO_FREE_STORE;
X }
X else
X {
X /* Gee. Out of memory AND there is nobody to tell about it ... */
X /* Only choice is to GURU. Maybe we could do something clever */
X /* but I doubt it... */
X BUG(("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"));
X BUG(("!!!!!!!!!!!! !!!!!!!!\n"));
X BUG(("!!!!!!!!!!!! OUT OF MEMORY !!!!!!!!\n"));
X BUG(("!!!!!!!!!!!! !!!!!!!!\n"));
X BUG(("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"));
X }
X }
Xelse
X *p++ = len;
X
Xreturn((char *)p);
X}
X
Xvoid DosFreeMem(p)
Xchar *p;
X{
Xlong *lp;
Xlong len;
X
X lp = (long *)p;
X len = *--lp;
X FreeMem((char *)lp, len);
X}
X
XLONG checksum(c, len)
Xchar *c;
Xint len;
X{
X int i, l;
X LONG sum, *lptr;
X unsigned char *uc;
X
X l = len/sizeof(LONG);
X lptr = (LONG *)c;
X for(i=0, sum=0; i<l; i++, lptr++) sum += *lptr;
X
X l = len % sizeof(LONG);
X uc = (unsigned char *)lptr;
X for(i=0; i<l; i++, uc++) sum += *uc;
X
X return(sum);
X}
X
Xvoid CheckRP(r)
Xstruct RPacket *r;
X{
X#ifndef SMALLPACKET
X /* Get checksum for RP */
X if(r->DLen)
X r->DCheck = checksum(r->Data, r->DLen);
X else
X r->DCheck = 0L;
X
X r->checksum = 0L;
X r->checksum = checksum((char *)r, RPSIZE);
X#endif
X}
X
SHAR_EOF
echo "extracting timer.c"
sed 's/^X//' << \SHAR_EOF > timer.c
X/* Timer.c - Timer support routines */
X
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X/* |_o_o|\\ Copyright (c) 1987 The Software Distillery. All Rights Reserved */
X/* |. o.| || This program may not be distributed without the permission of */
X/* | . | || the author. BBS: */
X/* | o | || John Toebes Dave Baker (919)-471-6436 */
X/* | . |// */
X/* ====== */
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X#define NETCOMMON
X#include "netcomm.h"
X#include "proto.h"
X
Xint OpenTimer(global, port)
XNGLOBAL global;
Xstruct MsgPort *port;
X{
X int error;
X
X /* assumes that a msg port has been allocated */
X
X if ((global->n.timerpkt = (struct TimerPacket *)
X CreateExtIO(port, sizeof(struct TimerPacket)))== NULL)
X return(1);
X
X global->n.timerpkt->tm_req.tr_node.io_Message.mn_Node.ln_Name =
X (char *)&(global->n.timerpkt->tm_pkt);
X global->n.timerpkt->tm_pkt.dp_Link =
X &(global->n.timerpkt->tm_req.tr_node.io_Message);
X global->n.timerpkt->tm_pkt.dp_Port = port;
X
X error = OpenDevice(TIMERNAME, UNIT_MICROHZ,
X (struct IORequest *)&(global->n.timerpkt->tm_req), 0);
X
X return(error);
X}
X
Xvoid CloseTimer(global)
XNGLOBAL global;
X{
X if (global->n.timerpkt != NULL)
X {
X CloseDevice((struct IORequest *)&(global->n.timerpkt->tm_req));
X DeleteExtIO((struct IORequest *)global->n.timerpkt,
X sizeof(struct TimerPacket));
X global->n.timerpkt = NULL;
X }
X
X}
X
Xvoid PostTimerReq(global, time)
XNGLOBAL global;
Xint time; /* tenths of a second */
X{
X /* Fill in the timer packet values */
X /* that is the fields required for the timer device timerequest struct */
X /* and the necessary fields of the DosPacket struct */
X /* nothing like using 35 meg of store to accomplish a simple task */
X /* oh well ! this is a 68K machine right ? */
X /* some of them get trampled on so fill them all */
X
X if (global->n.timerpkt != NULL)
X {
X time *= 100000;
X global->n.timerpkt->tm_req.tr_node.io_Command = TR_ADDREQUEST;
X global->n.timerpkt->tm_req.tr_time.tv_secs = time/100000;
X global->n.timerpkt->tm_req.tr_time.tv_micro = time%100000;
X
X global->n.timerpkt->tm_pkt.dp_Type = ACTION_TIMER;
X
X /* Async IO so we don't sleep here for the msg */
X
X SendIO((struct IORequest *)&global->n.timerpkt->tm_req);
X }
X}
SHAR_EOF
if `test ! -d util`
then
mkdir util
echo "mkdir util"
fi
echo "extracting util/handd.c"
sed 's/^X//' << \SHAR_EOF > util/handd.c
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X#include <string.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <proto/exec.h>
X#include <proto/dos.h>
X
X#undef GLOBAL
X/* my version of BADDR() has no problems with casting */
X#undef BADDR
X#define BADDR(x) ((APTR)((long)x << 2))
X#define MKBADDR(x) ((BPTR)((long)x >> 2))
X
X#define ACTION_HANDLER_DEBUG 2010L
X#define DEBUG_SPECIAL 0x40000000
X#define DEBUG_WAIT 0x40000001
X#define DEBUG_SERVER 0x20000000
X#define DEBUG_SERVWT 0x10000000
X
Xchar windowname[50] = "CON:0/1/640/160/Debug ";
X
XLONG sendpkt(struct MsgPort *, long, long*, long, long*);
X
Xvoid main(argc, argv)
Xint argc;
Xchar **argv;
X{
X struct MsgPort *proc;
X long myargs[8];
X long myres[2];
X char *filename, *cmdname, *devname;
X int freeflag, server, handler;
X
X cmdname = argv[0];
X if(argc != 3 && argc != 4 && argc != 5)
X {
XUSAGE:
X fprintf(stderr,
X "Usage: %s device <SERVER|BOTH> [OPEN|CLOSE|WAIT] <logfile>\n",
X cmdname);
X return;
X }
X devname = argv[1];
X
X if ((proc = (struct MsgPort *)DeviceProc(devname)) == NULL)
X {
X fprintf(stderr, "Unable to get a device proc for %s\n", devname);
X goto USAGE;
X }
X
X handler = 0;
X if((server=(!stricmp(argv[2], "SERVER"))) ||
X (server=handler=(!stricmp(argv[2], "BOTH"))))
X {
X if(argc < 4) goto USAGE;
X argc--, argv++;
X }
X else
X handler = 1;
X
X if(!stricmp(argv[2], "WAIT"))
X {
X freeflag = 0;
X myargs[0] = DEBUG_WAIT;
X }
X else if(!stricmp(argv[2], "CLOSE"))
X {
X freeflag = 1;
X myargs[0] = 0;
X }
X else if(!stricmp(argv[2], "OPEN"))
X {
X freeflag = 1;
X myargs[0] = 1;
X if(handler)
X {
X if(argc == 4) filename = argv[3];
X else
X {
X strcat(windowname, devname);
X strcat(windowname, "/a");
X filename = windowname;
X }
X if(!(myargs[1] = (long)Open(filename, 1006)))
X {
X fprintf(stderr, "Can't open output %s '%s'\n",
X (argc == 4 ? "file" : "window"), filename);
X goto USAGE;
X }
X }
X }
X else
X {
X fprintf(stderr, "Unknown debugging command '%s'\n", argv[2]);
X goto USAGE;
X }
X
X if(handler)
X {
X sendpkt(proc,ACTION_HANDLER_DEBUG,myargs,2,myres);
X if(freeflag && myres[0] != 0 && myres[1])
X Close((BPTR)myres[1]);
X }
X
X if(server)
X {
X myargs[0] |= (DEBUG_SERVER|DEBUG_SPECIAL);
X sendpkt(proc,ACTION_HANDLER_DEBUG,myargs,2,myres);
X }
X
X}
X
XLONG sendpkt(pid,action,args,nargs,res)
Xstruct MsgPort *pid; /* process indentifier ... (handlers message port ) */
XLONG action, /* packet type ... (what you want handler to do ) */
X args[], /* a pointer to a argument list */
X nargs, /* number of arguments in list */
X res[]; /* pointer to 2 longs for result, or NULL */
X {
X struct MsgPort *replyport;
X struct StandardPacket *packet;
X
X LONG count, lres, *pargs;
X
X replyport = (struct MsgPort *) CreatePort(NULL,0);
X if(!replyport) return(0L);
X
X packet = (struct StandardPacket *)
X AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
X if(!packet)
X {
X DeletePort(replyport);
X return(0L);
X }
X
X packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X packet->sp_Pkt.dp_Port = replyport;
X packet->sp_Pkt.dp_Type = action;
X
X /* copy the args into the packet */
X pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
X for(count=0;count < nargs;count++)
X pargs[count]=args[count];
X
X PutMsg(pid,(struct Message *)packet); /* send packet */
X
X WaitPort(replyport);
X GetMsg(replyport);
X
X if(res)
X {
X lres = res[0] = packet->sp_Pkt.dp_Res1;
X res[1] = packet->sp_Pkt.dp_Res2;
X }
X
X FreeMem((char *)packet,(long)sizeof(struct StandardPacket));
X DeletePort(replyport);
X
X return(lres);
X}
SHAR_EOF
echo "extracting util/netmount.c"
sed 's/^X//' << \SHAR_EOF > util/netmount.c
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X#include <string.h>
X#include <stdlib.h>
X#include <proto/exec.h>
X#include <proto/dos.h>
X
X#undef GLOBAL
X/* my version of BADDR() has no problems with casting */
X#undef BADDR
X#define BADDR(x) ((APTR)((long)x << 2))
X#define MKBADDR(x) ((BPTR)((long)x >> 2))
X
X#define ACTION_NETWORK_KLUDGE 4674764L
X
Xlong sendpkt(struct MsgPort *, long, long*, long);
X
Xvoid main(argc, argv)
Xint argc;
Xchar **argv;
X{
Xstruct MsgPort *proc;
Xlong myargs[8];
Xint len1, len2;
Xunsigned char *nodename;
Xchar *devname;
X
X if (argc != 4)
X {
X printf("Usage: %s <netdevice> <nodename> <rmtdevice>\n", argv[0]);
X return;
X }
X
X if(!(nodename = AllocMem(len1=strlen(argv[2])+2, 0)) ||
X !(devname = AllocMem(len2=strlen(argv[3]+1), 0)))
X {
X printf("Error: No memory\n");
X return;
X }
X
X nodename[0] = strlen(argv[2]);
X strcpy(nodename+1, argv[2]);
X
X strcpy(devname, argv[3]);
X
X myargs[0]=(long)MKBADDR(nodename);
X myargs[1]=(long)MKBADDR(devname);
X
X if ((proc = (struct MsgPort *)DeviceProc(argv[1])) == NULL)
X {
X printf("Unable to get a device proc for %s\n", argv[1]);
X return;
X }
X
X sendpkt(proc,ACTION_NETWORK_KLUDGE,myargs,2);
X
X FreeMem(nodename, len1);
X FreeMem(devname, len2);
X}
X
XLONG sendpkt(pid,action,args,nargs)
Xstruct MsgPort *pid; /* process indentifier ... (handlers message port ) */
XLONG action, /* packet type ... (what you want handler to do ) */
X args[], /* a pointer to a argument list */
X nargs; /* number of arguments in list */
X {
X struct MsgPort *replyport;
X struct StandardPacket *packet;
X
X LONG count, *pargs, res1;
X
X replyport = (struct MsgPort *) CreatePort(NULL,0);
X if(!replyport) return(NULL);
X
X packet = (struct StandardPacket *)
X AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
X if(!packet)
X {
X DeletePort(replyport);
X return(NULL);
X }
X
X packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X packet->sp_Pkt.dp_Port = replyport;
X packet->sp_Pkt.dp_Type = action;
X
X /* copy the args into the packet */
X pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
X for(count=0;count < nargs;count++)
X pargs[count]=args[count];
X
X PutMsg(pid,(struct Message *)packet); /* send packet */
X
X WaitPort(replyport);
X GetMsg(replyport);
X
X res1 = packet->sp_Pkt.dp_Res1;
X
X FreeMem((char *)packet,(long)sizeof(struct StandardPacket));
X DeletePort(replyport);
X
X return(res1);
X}
SHAR_EOF
echo "extracting util/netstat.c"
sed 's/^X//' << \SHAR_EOF > util/netstat.c
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <intuition/intuition.h>
X#include <graphics/gfxmacros.h>
X#include <graphics/rastport.h>
X#include <libraries/dos.h>
X#include <proto/intuition.h>
X#include <proto/dos.h>
X#include <proto/exec.h>
X#include <proto/graphics.h>
X#include <string.h>
X#include "netstat.h"
X
X#define MAXSTATS 300
X#define XOFF 10
X#define YOFF 40
X#define TIMEINTERVAL 1
X#define YMARGIN 12
X#define MINPEAK 400
X#define TEXT1 (6*8)
X#define TEXT2 (25*8)
X#define XMARGIN 12
X#define MKBADDR(x) ((BPTR)((long)x >> 2))
X
Xstruct NewWindow NewWindowStructure1 = {
X 0,0,
X XOFF+MAXSTATS+XMARGIN, YOFF+YMARGIN+50,
X 0,1,
X MENUPICK+CLOSEWINDOW+REFRESHWINDOW+NEWSIZE,
X WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+WINDOWSIZING+SIMPLE_REFRESH,
X NULL,
X NULL,
X "Software Distillery NET: Status",
X NULL,
X NULL,
X XOFF+MAXSTATS+XMARGIN,YOFF+YMARGIN+20,
X 9999,9999,
X WBENCHSCREEN
X};
X
Xint xsize = 300;
Xint ysize = 100;
Xint yscale = 100;
Xlong peak = 0;
X
Xvoid main(int, char **);
Xvoid MemCleanup(void);
Xvoid refresh(void);
Xvoid QueueTimer(struct timerequest *, ULONG);
Xvoid setscale(void);
Xvoid update(void);
Xint dispvals(void);
Xvoid DeleteIOReq(struct IOStdReq *);
Xlong sendpkt(struct MsgPort *, long, long*, long);
Xstruct IOStdReq *CreateIOReq(struct MsgPort *, int);
X
X/* Global variables */
X
Xstruct Window *Window;
Xstruct TmpRas tmpras;
Xlong wstats[MAXSTATS], rstats[MAXSTATS];
Xint statpos;
X
X
Xvoid main(argc, argv)
Xint argc;
Xchar **argv;
X{
X WORD areabuffer[300];
X struct IntuiMessage *message;
X int run;
X ULONG portmask, waitmask, windmask, timemask;
X/* struct MenuItem *item; */
X struct MsgPort *port;
X struct AreaInfo myAreaInfo;
X struct statmsg *statmsg;
X struct MsgPort *proc;
X long args[8];
X struct timerequest *timerreq;
X struct MsgPort *timerport;
X
X timerreq = NULL;
X timerport = NULL;
X proc = NULL;
X Window = NULL;
X port = NULL;
X args[0] = 0;
X if ((IntuitionBase = (struct IntuitionBase *)
X OpenLibrary("intuition.library", 0)) == NULL) goto done;
X if ((GfxBase = (struct GfxBase *)
X OpenLibrary("graphics.library", 0)) == NULL) goto done;
X if ((Window = OpenWindow(&NewWindowStructure1)) == NULL) goto done;
X
X if ((port = CreatePort("netstat_port", 0)) == NULL) goto done;
X if ((timerport = CreatePort(NULL, 0)) == NULL) goto done;
X if ((timerreq = (struct timerequest *)
X CreateIOReq(timerport, sizeof(struct timerequest))) == NULL)
X goto done;
X if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0))
X goto done;
X
X InitArea(&myAreaInfo, areabuffer, 175);
X Window->RPort->AreaInfo = &myAreaInfo;
X Window->RPort->TmpRas = InitTmpRas(&tmpras, AllocRaster(600, 175),
X RASSIZE(600, 175));
X if ((argc > 1) &&
X ((proc = (struct MsgPort *)DeviceProc(argv[1])) != NULL))
X {
X args[0] = 0x40000002;
X args[1] = MKBADDR(port);
X sendpkt(proc, 2010, args, 2);
X }
X
X memset((char *)wstats, 0, sizeof(wstats));
X memset((char *)rstats, 0, sizeof(rstats));
X statpos = 0;
X peak = 0;
X ysize = Window->Height-(YOFF+YMARGIN);
X if (ysize < 20) ysize = 20;
X setscale();
X refresh();
X
X run = 0;
X
X windmask = 1 << Window->UserPort->mp_SigBit;
X portmask = 1 << port->mp_SigBit;
X timemask = (1 << timerport->mp_SigBit);
X QueueTimer(timerreq, TIMEINTERVAL);
X while(run == 0)
X {
X waitmask = Wait(windmask | portmask | timemask);
X if (waitmask & timemask)
X {
X /* get rid of the message */
X (void)GetMsg(timerport);
X QueueTimer(timerreq, TIMEINTERVAL);
X /* Also, we want to scroll the entire thing left one pixel */
X update();
X
X statpos ++;
X if (statpos >= MAXSTATS)
X statpos = 0;
X wstats[statpos] = rstats[statpos] = 0;
X }
X if (waitmask & portmask)
X {
X statmsg = (struct statmsg *)GetMsg(port);
X if (statmsg->direction)
X rstats[statpos] += statmsg->count;
X else
X wstats[statpos] += statmsg->count;
X ReplyMsg((struct Message *)statmsg);
X }
X if (waitmask & windmask)
X {
X while ((message = (struct IntuiMessage *)
X GetMsg(Window->UserPort)) != NULL)
X {
X switch(message->Class)
X {
X case CLOSEWINDOW:
X run = -1;
X break;
X#if 0
X case MENUPICK:
X item = ItemAddress(&MenuList1, message->Code);
X switch(item->Command)
X {
X case 1:
X run = 1;
X default:
X run = 1;
X break;
X }
X break;
X#endif
X
X case NEWSIZE:
X case REFRESHWINDOW:
X ysize = Window->Height-(YOFF+YMARGIN);
X if (ysize < 20) ysize = 20;
X setscale();
X refresh();
X break;
X
X default:
X break;
X }
X ReplyMsg((struct Message *)message);
X }
X }
X }
X
X Wait(timemask);
X
X Window->RPort->TmpRas = NULL;
X FreeRaster(tmpras.RasPtr, 600, 175);
X
Xdone:
X if (args[0] && proc != NULL)
X {
X args[1] = 0;
X sendpkt(proc,2010,args,2);
X }
X
X /* Reply to any outstanding messages */
X while(statmsg = (struct statmsg *)GetMsg(port))
X ReplyMsg((struct Message *)statmsg);
X
X if (timerreq != NULL)
X {
X if (timerreq->tr_node.io_Device != NULL)
X {
X AbortIO( (struct IORequest *)timerreq );
X CloseDevice((struct IORequest *)timerreq);
X }
X DeleteIOReq((struct IOStdReq *)timerreq);
X }
X if (timerport != NULL) DeletePort(timerport);
X if (Window != NULL) CloseWindow(Window);
X if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase);
X if (GfxBase != NULL) CloseLibrary((struct Library *)GfxBase);
X if (port != NULL) DeletePort(port);
X XCEXIT(0L);
X}
X
Xvoid setscale()
X{
X/* Now recalculate the scale */
Xif (peak < MINPEAK)
X yscale = MINPEAK/ysize;
Xelse
X yscale = (peak*5)/(ysize*4);
X
X}
Xint dispvals()
X{
Xchar buf[80];
Xlong reads, writes, perf;
Xstruct RastPort *rp = Window->RPort;
Xstatic long lr, lw, lp, lk;
X
Xreads = rstats[statpos];
Xwrites = wstats[statpos];
Xperf = reads+writes;
X
X/* Have we hit a new high? */
Xif (perf > peak)
X {
X peak = perf;
X /* Will this shoot off the end of the graph ? */
X if ((peak/yscale) > ysize)
X {
X setscale();
X return(1);
X }
X }
X
XSetAPen(rp, 0);
Xif (lp != perf || lr != reads)
X RectFill(rp, XOFF+TEXT1, YOFF-28, XOFF+TEXT1+(7*8), YOFF-1);
Xif (lk != peak || lw != writes)
X RectFill(rp, XOFF+TEXT2, YOFF-28, XOFF+TEXT2+(7*8), YOFF-1);
X
Xlp = perf;
Xlr = reads;
Xlk = peak;
Xlw = writes;
X
XSetAPen(rp, 3);
Xsprintf(buf, "%7d", perf);
XMove(rp, XOFF+TEXT1, YOFF-20);
XText(rp, buf, 7);
X
Xsprintf(buf, "%7d", peak);
XMove(rp, XOFF+TEXT2, YOFF-20);
XText(rp, buf, 7);
X
Xsprintf(buf, "%7d", reads);
XMove(rp, XOFF+TEXT1, YOFF-10);
XText(rp, buf, 7);
X
Xsprintf(buf, "%7d", writes);
XMove(rp, XOFF+TEXT2, YOFF-10);
XText(rp, buf, 7);
Xreturn(0);
X}
X
Xvoid update()
X{
Xshort rsize, wsize;
Xstruct RastPort *rp = Window->RPort;
X
Xif (dispvals())
X {
X refresh();
X return;
X }
X
XScrollRaster(rp, 1, 0, XOFF, YOFF, XOFF+xsize, YOFF+ysize);
X/* Now update the data for the one we just finished */
Xrsize = rstats[statpos]/yscale;
Xwsize = wstats[statpos]/yscale;
X/* Now display the line at the right place for the read and then the write */
XMove(rp, XOFF+MAXSTATS, YOFF+ysize);
Xif (rsize)
X {
X SetAPen(rp, 2);
X Draw(rp, XOFF+MAXSTATS, YOFF+ysize-rsize);
X }
Xif (wsize)
X {
X SetAPen(rp, 3);
X Draw(rp, XOFF+MAXSTATS, YOFF+ysize-rsize-wsize);
X }
X/* And put a point where the limit is */
XSetAPen(rp, 1);
XWritePixel(rp, XOFF+MAXSTATS, YOFF+ysize-(peak/yscale));
X}
X
Xvoid refresh()
X{
Xint i, j;
Xshort rsize, wsize;
Xstruct RastPort *rp = Window->RPort;
Xchar *p;
X
XSetAPen(rp, 0);
XRectFill(rp, XOFF, YOFF, XOFF+MAXSTATS+1, YOFF+ysize);
X
Xp = "Total: Bps Peak: Bps";
XSetAPen(rp, 1);
XMove(rp, XOFF, YOFF-20);
XText(rp, p, strlen(p));
X
Xp = "Reads: Bps Writes: Bps";
XMove(rp, XOFF, YOFF-10);
XText(rp, p, strlen(p));
X
XSetAPen(rp, 3);
Xp = " ) 1989 The Software Distillery";
XMove(rp, XOFF, YOFF+ysize+9);
XText(rp, p, strlen(p));
Xdispvals();
X
XSetAPen(rp, 1);
XSetDrMd(rp, JAM1);
XMove(rp, XOFF-1, YOFF);
XDraw(rp, XOFF-1, YOFF+1+ysize);
XDraw(rp, XOFF+1+xsize, YOFF+1+ysize);
X
Xi = statpos+1;
Xfor (j = 0; j < MAXSTATS; j++)
X {
X if (i >= MAXSTATS) i = 0;
X rsize = rstats[i]/yscale;
X wsize = wstats[i]/yscale;
X /* Now display the line at the right place for the read and then the write */
X Move(rp, XOFF+j, YOFF+ysize);
X if (rsize)
X {
X SetAPen(rp, 2);
X Draw(rp, XOFF+j, YOFF+ysize-rsize);
X }
X if (wsize)
X {
X SetAPen(rp, 3);
X Draw(rp, XOFF+j, YOFF+ysize-rsize-wsize);
X }
X i++;
X }
XSetAPen(rp, 1);
XMove(rp, XOFF, YOFF+ysize-(peak/yscale));
XDraw(rp, XOFF+MAXSTATS, YOFF+ysize-(peak/yscale));
X}
X
X/************************************************************************/
X/* Queue a timer to go off in a given number of seconds */
X/************************************************************************/
Xvoid QueueTimer(tr, seconds)
Xstruct timerequest *tr;
XULONG seconds;
X{
X tr->tr_node.io_Command = TR_ADDREQUEST; /* add a new timer request */
X tr->tr_time.tv_secs = seconds; /* seconds */
X tr->tr_time.tv_micro = 0;
X SendIO( (struct IORequest *)tr );
X}
X
X
Xstruct IOStdReq *CreateIOReq(port, size)
Xstruct MsgPort *port;
Xint size;
X{
X register struct IOStdReq *ioReq;
X
X if ((ioReq = (struct IOStdReq *)
X AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
X {
X ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE;
X ioReq->io_Message.mn_Node.ln_Pri = 0;
X ioReq->io_Message.mn_Length = size;
X ioReq->io_Message.mn_ReplyPort = port;
X }
X return(ioReq);
X}
X
Xvoid DeleteIOReq(ioReq)
Xregister struct IOStdReq *ioReq;
X{
X ioReq->io_Message.mn_Node.ln_Type = 0xff;
X ioReq->io_Device = (struct Device *) -1;
X ioReq->io_Unit = (struct Unit *) -1;
X
X FreeMem( (char *)ioReq, ioReq->io_Message.mn_Length);
X}
X
XLONG sendpkt(pid,action,args,nargs)
Xstruct MsgPort *pid; /* process indentifier ... (handlers message port ) */
XLONG action, /* packet type ... (what you want handler to do ) */
X args[], /* a pointer to a argument list */
X nargs; /* number of arguments in list */
X {
X struct MsgPort *replyport;
X struct StandardPacket *packet;
X
X LONG count, *pargs, res1;
X
X replyport = (struct MsgPort *) CreatePort(NULL,0);
X if(!replyport) return(NULL);
X
X packet = (struct StandardPacket *)
X AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
X if(!packet)
X {
X DeletePort(replyport);
X return(NULL);
X }
X
X packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X packet->sp_Pkt.dp_Port = replyport;
X packet->sp_Pkt.dp_Type = action;
X
X /* copy the args into the packet */
X pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
X for(count=0;count < nargs;count++)
X pargs[count]=args[count];
X
X PutMsg(pid,(struct Message *)packet); /* send packet */
X
X WaitPort(replyport);
X GetMsg(replyport);
X
X res1 = packet->sp_Pkt.dp_Res1;
X
X FreeMem((char *)packet,(long)sizeof(struct StandardPacket));
X DeletePort(replyport);
X
X return(res1);
X}
X
Xvoid MemCleanup(){}
SHAR_EOF
echo "extracting util/netstat.h"
sed 's/^X//' << \SHAR_EOF > util/netstat.h
Xstruct statmsg
X {
X struct Message msg;
X long count;
X int direction;
X };SHAR_EOF
echo "extracting util/shutdown.c"
sed 's/^X//' << \SHAR_EOF > util/shutdown.c
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X#include <string.h>
X#include <stdlib.h>
X#include <proto/exec.h>
X#include <proto/dos.h>
X
X#undef GLOBAL
X/* my version of BADDR() has no problems with casting */
X#undef BADDR
X#define BADDR(x) ((APTR)((long)x << 2))
X#define MKBADDR(x) ((BPTR)((long)x >> 2))
X
Xlong sendpkt(struct MsgPort *, long, long*, long);
X
Xvoid main(argc, argv)
Xint argc;
Xchar **argv;
X{
Xstruct MsgPort *proc;
Xlong myargs[8];
X
Xif (argc != 2)
X {
X printf("Usage: %s <device>\n", argv[0]);
X return;
X }
X
Xmyargs[0]=1;
X
Xif ((proc = (struct MsgPort *)DeviceProc(argv[1])) == NULL)
X {
X printf("Unable to get a device proc for %s\n", argv[1]);
X return;
X }
X
Xsendpkt(proc,ACTION_DIE,myargs,1);
X}
X
XLONG sendpkt(pid,action,args,nargs)
Xstruct MsgPort *pid; /* process indentifier ... (handlers message port ) */
XLONG action, /* packet type ... (what you want handler to do ) */
X args[], /* a pointer to a argument list */
X nargs; /* number of arguments in list */
X {
X struct MsgPort *replyport;
X struct StandardPacket *packet;
X
X LONG count, *pargs, res1;
X
X replyport = (struct MsgPort *) CreatePort(NULL,0);
X if(!replyport) return(NULL);
X
X packet = (struct StandardPacket *)
X AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
X if(!packet)
X {
X DeletePort(replyport);
X return(NULL);
X }
X
X packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X packet->sp_Pkt.dp_Port = replyport;
X packet->sp_Pkt.dp_Type = action;
X
X /* copy the args into the packet */
X pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
X for(count=0;count < nargs;count++)
X pargs[count]=args[count];
X
X PutMsg(pid,(struct Message *)packet); /* send packet */
X
X WaitPort(replyport);
X GetMsg(replyport);
X
X res1 = packet->sp_Pkt.dp_Res1;
X
X FreeMem((char *)packet,(long)sizeof(struct StandardPacket));
X DeletePort(replyport);
X
X return(res1);
X}
SHAR_EOF
echo "End of archive 4 (of 4)"
# if you want to concatenate archives, remove anything after this line
exit