home *** CD-ROM | disk | FTP | other *** search
- /*
- * DNETLIB.C
- *
- * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
- *
- * Library Interface for DNET.
- */
-
- #define NOEXT
- #define NETCOMMON
- #include "dnet.h"
- #include "netcomm.h"
- #include "proto.h"
-
- static struct DChannel *MakeChannel U_ARGS((IOR *, char *));
- static void DeleteChannel U_ARGS((struct DChannel *));
- static void FixSignal U_ARGS((struct DChannel *));
-
- #define NAMELEN sizeof("DNET.PORT.XXXXX")
- #define NAMEPAT "DNET.PORT.%ld"
-
- PORT *DListen(portnum)
- uword portnum;
- {
- PORT *port;
- char *ptr;
-
- port = NULL;
- ptr = AllocMem(NAMELEN, MEMF_PUBLIC); /* memory the the name */
- sprintf(ptr, NAMEPAT, portnum);
- Forbid(); /* task-atomic operation */
- if (FindPort(ptr) || !(port = CreatePort(ptr,0)))
- FreeMem(ptr, NAMELEN);
- Permit();
- return(port);
- }
-
- void
- DUnListen(lisport)
- PORT *lisport;
- {
- register char *ptr;
- ptr = lisport->mp_Node.ln_Name;
-
- if (lisport)
- {
- Forbid(); /* task-atomic operation */
- while (DNAAccept(lisport)); /* remove all pending requests */
- DeletePort(lisport); /* gone! */
- Permit();
- FreeMem(ptr, NAMELEN);
- }
- }
-
- /*
- * DAccept()
- *
- * Note: This call will work even if called by a task which does not
- * own the listen port.
- */
-
- PORT *
- DAccept(lisport)
- PORT *lisport;
- {
- register IOR *ior;
- register struct DChannel * chan;
-
- BUG(("DAccept: Entry, port %lx\n", lisport))
-
- chan = NULL;
- while (!chan && (ior = (IOR *)GetMsg(lisport))) {
- switch(ior->io_Command) {
- case DNCMD_SOPEN:
- BUG(("DAccept: SOPEN command\n"))
- chan = MakeChannel(ior, NULL);
- break;
- default:
- BUG(("DAccept: Unrecognized command '%d'\n", ior->io_Command))
- ior->io_Error = 1;
- break;
- }
- BUG(("DAccept: Replying\n"))
- ReplyMsg(&ior->io_Message);
- }
- BUG(("DAccept: After while loop\n"))
- if (lisport->mp_MsgList.lh_Head != (NODE *)&lisport->mp_MsgList.lh_Tail)
- SetSignal(1 << lisport->mp_SigBit, 1 << lisport->mp_SigBit);
-
- return(chan ? &chan->port : NULL);
- }
-
- /*
- * Refuse a connection
- */
-
- DNAAccept(lisport)
- PORT *lisport;
- {
- IOR *ior;
-
- if (ior = (IOR *)GetMsg(lisport)) {
- ior->io_Error = 1;
- ReplyMsg(&ior->io_Message);
- }
- if (lisport->mp_MsgList.lh_Head != (NODE *)&lisport->mp_MsgList.lh_Tail)
- SetSignal(1 << lisport->mp_SigBit, 1 << lisport->mp_SigBit);
- return(ior != NULL);
- }
-
- void DPri(chan, pri)
- struct DChannel * chan;
- int pri;
- {
- }
-
-
- PORT *
- DOpen(host, portnum, txpri, rxpri)
- char *host;
- char txpri, rxpri;
- uword portnum;
- {
- IOR ior;
- struct DChannel *chan;
-
- if (!host)
- host = "0";
- chan = MakeChannel(&ior, host);
- if (rxpri > 126)
- rxpri = 126;
- if (rxpri < -127)
- rxpri = -127;
- if (txpri > 126)
- txpri = 126;
- if (txpri < -127)
- txpri = -127;
- if (chan->dnetport) {
- ior.io_Command = DNCMD_OPEN;
- ior.io_Unit = (void *)portnum;
- ior.io_Offset = (long)chan;
- ior.io_Message.mn_ReplyPort = &chan->port;
- ior.io_Message.mn_Node.ln_Pri = txpri;
- ior.io_Message.mn_Node.ln_Name= (char *)rxpri;
-
- PutMsg(chan->dnetport, &ior.io_Message);
- WaitMsg(&ior);
- if (ior.io_Error == 0) {
- chan->chan = (long)ior.io_Unit;
- FixSignal(chan);
- return(&chan->port);
- }
- }
- DeleteChannel(chan);
- return(NULL);
- }
-
-
- DNRead(chan, buf, bytes)
- struct DChannel * chan;
- char *buf;
- int bytes;
- {
- register IOR *ior;
- int len;
- long n;
-
- len = 0;
- if (chan->eof)
- return(-1);
- while (bytes && ((ior = (IOR *)
- RemHead((struct List *)&chan->rdylist)) ||
- (ior = (IOR *)GetMsg(&chan->port)))) {
- if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG)
- {
- if (!chan->queued)
- {
- BUG(("DNRead: Software Error"));
- }
- else
- --chan->queued;
- if (ior->io_Length)
- FreeMem((char *)ior->io_Data, (long)ior->io_Length);
- FreeMem((char *)ior, (long)sizeof(IOR));
- continue;
- }
- switch(ior->io_Command)
- {
- case DNCMD_CLOSE:
- case DNCMD_EOF:
- chan->eof = 1;
- ReplyMsg(&ior->io_Message);
- break;
-
- case DNCMD_WRITE:
- n = ior->io_Length - ior->io_Actual;
- if (n <= bytes)
- {
- memcpy(buf, ((char *)ior->io_Data) + ior->io_Actual, n);
- bytes -= n;
- len += n;
- buf += n;
- ReplyMsg(&ior->io_Message);
- }
- else
- {
- memcpy(buf, (char *)ior->io_Data + ior->io_Actual, bytes);
- len += bytes;
- ior->io_Actual += bytes;
- bytes = 0;
- Forbid(); /* DNET device is a task, no need to Disable() */
- ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
- AddHead(&chan->port.mp_MsgList, (struct Node *)ior);
- Permit();
- }
- break;
- default:
- ior->io_Error = 1;
- ReplyMsg(&ior->io_Message);
- }
- }
- FixSignal(chan);
- if (chan->eof)
- SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit);
- return(len);
- }
-
- int DRead(chan, buf, bytes)
- char *buf;
- struct DChannel * chan;
- int bytes;
- {
- long len;
- long n;
-
- len = 0;
- if (chan->eof)
- {
- BUG(("****DNET EOF!!!\n"));
- return(-1);
- }
-
- while (bytes)
- {
- WaitPort(&chan->port);
- n = DNRead(chan, buf, bytes);
- len += n;
- if (n < 0) break;
- buf += n;
- bytes -= n;
- if (chan->eof) break;
- }
- return(len);
- }
-
- void DQueue(chan, n)
- struct DChannel * chan;
- int n;
- {
- chan->qlen = n;
- }
-
- DWrite(chan, buf, bytes)
- struct DChannel * chan;
- char *buf;
- int bytes;
- {
- IOR tmpior;
- IOR *ior;
- int error;
-
- error = bytes;
- if (chan->qlen)
- {
- if (WaitQueue(chan, NULL) >= 0)
- {
- ior = (IOR *)AllocMem(sizeof(IOR), MEMF_CLEAR|MEMF_PUBLIC);
- ior->io_Command = DNCMD_WRITE;
- ior->io_Unit = (void *)chan->chan;
- ior->io_Offset = (long)chan;
- ior->io_Message.mn_ReplyPort = &chan->port;
- ior->io_Data = (APTR)AllocMem(bytes, MEMF_PUBLIC);
- ior->io_Length = bytes;
- memcpy((char *)ior->io_Data, buf, (int)bytes);
- PutMsg(chan->dnetport, &ior->io_Message);
- ++chan->queued;
- }
- else
- {
- error = -1;
- }
- }
- else
- {
- tmpior.io_Command = DNCMD_WRITE;
- tmpior.io_Unit = (void *)chan->chan;
- tmpior.io_Offset = (long)chan;
- tmpior.io_Message.mn_ReplyPort = &chan->port;
- tmpior.io_Data = (APTR)buf;
- tmpior.io_Length = bytes;
- PutMsg(chan->dnetport, &tmpior.io_Message);
- WaitMsg(&tmpior);
- if (tmpior.io_Error)
- {
- error = -1;
- BUG(("*****DWrite: io_Error %d\n", tmpior.io_Error));
- BUGGETC
- }
- }
- FixSignal(chan);
- return(error);
- }
-
- void DEof(chan)
- struct DChannel * chan;
- {
- IOR ior;
-
- ior.io_Command = DNCMD_EOF;
- ior.io_Unit = (void *)chan->chan;
- ior.io_Offset = (long)chan;
- ior.io_Message.mn_ReplyPort = &chan->port;
- PutMsg(chan->dnetport, &ior.io_Message);
- WaitMsg(&ior);
- FixSignal(chan);
- }
-
- void DIoctl(chan, cmd, val, aux)
- struct DChannel * chan;
- ubyte cmd;
- uword val;
- ubyte aux;
- {
- IOR ior;
-
- ior.io_Command = DNCMD_IOCTL;
- ior.io_Unit = (void *)chan->chan;
- ior.io_Offset = (long)chan;
- ior.io_Message.mn_ReplyPort = &chan->port;
- ior.io_Data = (APTR)(long)((val<<16)|(aux<<8)|cmd);
- PutMsg(chan->dnetport, &ior.io_Message);
- WaitMsg(&ior);
- FixSignal(chan);
- }
-
- int DQuit(host)
- char *host;
- {
- IOR ior;
- char buf[sizeof(DNETPORTNAME)+32];
- PORT *replyport;
- PORT *dnetport;
-
- if (!host)
- host = "0";
- sprintf(buf, "%s%s", DNETPORTNAME, host);
- if (dnetport = FindPort(buf)) {
- replyport = CreatePort(NULL, 0);
- ior.io_Command = DNCMD_QUIT;
- ior.io_Unit = 0;
- ior.io_Offset = 0;
- ior.io_Message.mn_ReplyPort = replyport;
- PutMsg(dnetport, &ior.io_Message);
- WaitMsg(&ior);
- DeletePort(replyport);
- }
- return(dnetport != NULL);
- }
-
-
- void DClose(chan)
- struct DChannel * chan;
- {
- IOR ior;
- IOR *io;
-
- BUG(("DClose: Enter\n"))
-
- ior.io_Command = DNCMD_CLOSE;
- ior.io_Unit = (void *)chan->chan;
- ior.io_Offset = (long)chan;
- ior.io_Message.mn_ReplyPort = &chan->port;
- PutMsg(chan->dnetport, &ior.io_Message);
- ++chan->queued;
- chan->qlen = 0;
- WaitQueue(chan, &ior);
- while ((io = (IOR *)RemHead((struct List *)&chan->rdylist)) ||
- (io = (IOR *)GetMsg(&chan->port))) {
- io->io_Error = 1;
- ReplyMsg(&io->io_Message);
- }
- DeleteChannel(chan);
- }
-
- void WaitMsg(ior)
- IOR *ior;
- {
- while (ior->io_Message.mn_Node.ln_Type != NT_REPLYMSG)
- Wait(1 << ior->io_Message.mn_ReplyPort->mp_SigBit);
- Forbid();
- Remove((struct Node *)ior);
- Permit();
- }
-
- int WaitQueue(chan, skipior)
- struct DChannel * chan;
- IOR *skipior;
- {
- register IOR *io;
- short error;
-
- error = 0;
- while (chan->queued > chan->qlen) { /* until done */
- WaitPort(&chan->port); /* something */
- io = (IOR *)GetMsg(&chan->port);
- if (io->io_Message.mn_Node.ln_Type == NT_REPLYMSG) {
- if (error == 0)
- error = io->io_Error;
- if (io != skipior) {
- if (io->io_Length)
- FreeMem((char *)io->io_Data, io->io_Length);
- FreeMem((char *)io, sizeof(IOR));
- }
- --chan->queued;
- } else {
- AddTail(&chan->rdylist, (struct Node *)io);
- }
- }
- return(error);
- }
-
- static struct DChannel *MakeChannel(ior, host)
- register IOR *ior;
- char *host;
- {
- struct DChannel * chan;
- char buf[sizeof(DNETPORTNAME)+32];
-
- BUG(("MakeChannel: Entry\n"))
-
- chan = (struct DChannel *)AllocMem(sizeof(struct DChannel),
- MEMF_PUBLIC|MEMF_CLEAR);
-
- /* Name, Pri */
- chan->port.mp_Node.ln_Type = NT_MSGPORT;
- chan->port.mp_SigBit = AllocSignal(-1);
- chan->port.mp_SigTask = FindTask(NULL);
- NewList(&chan->port.mp_MsgList);
- NewList(&chan->rdylist);
- chan->chan = (long)ior->io_Unit;
- ior->io_Offset = (long)chan;
- if (host) {
- sprintf(buf, "%s%s", DNETPORTNAME, host);
- ior->io_Message.mn_ReplyPort = FindPort(buf);
- }
- chan->dnetport = ior->io_Message.mn_ReplyPort;
- return(chan);
- }
-
- static void
- DeleteChannel(chan)
- struct DChannel * chan;
- {
- FreeSignal(chan->port.mp_SigBit);
- FreeMem((char *)chan, (long)sizeof(struct DChannel));
- }
-
- static void
- FixSignal(chan)
- register struct DChannel * chan;
- {
- if (chan->port.mp_MsgList.lh_Head !=
- (NODE *)&chan->port.mp_MsgList.lh_Tail ||
- chan->rdylist.lh_Head != (NODE *)&chan->rdylist.lh_Tail)
- SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit);
- }
-
-