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