home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * SUBS.C
- *
- * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
- *
- */
-
- #include "dnet.h"
- #include <stdio.h>
-
- /*
- * Add the high-level command to the queue of commands to be sent to
- * the remote DNET.
- */
-
- WriteStream(sdcmd, buf, len, chan)
- uword chan;
- {
- register IOR *ior = (IOR *)AllocMem(sizeof(IOR), MEMF_PUBLIC);
-
- if (DDebug)
- printf("WriteStream: cmd %ld buflen %ld chan %ld\n", sdcmd, len, chan);
- ior->io_Message.mn_Node.ln_Name = (char *)PKT_REQ;
- ior->io_Message.mn_ReplyPort = IOSink;
- ior->io_Data = (APTR)AllocMem(len, MEMF_PUBLIC);
- ior->io_Length = len;
- ior->io_Actual = 0;
- ior->io_Command = sdcmd;
- ior->io_Error = 0;
- ior->io_Message.mn_Node.ln_Pri = (chan > MAXCHAN) ? 126 : Chan[chan].pri;
- CopyMem(buf, ior->io_Data, len);
- Enqueue(&TxList, ior);
- do_wupdate();
- }
-
- /*
- * Send a packet to a port. Used to send data/eof/close to channel
- * ports, and to relay open requests to server ports.
- */
-
- WritePort(port, scmd, buf, len, rettype, unit)
- PORT *port;
- ubyte *buf;
- {
- register IOR *ior = (IOR *)AllocMem(sizeof(IOR), MEMF_PUBLIC);
-
- if (DDebug)
- printf("WritePort: cmd %ld buflen %ld rt %ld unit %ld\n", scmd, len, rettype, unit);
- ior->io_Message.mn_Node.ln_Name = (char *)rettype;
- ior->io_Message.mn_ReplyPort = (rettype) ? IOSink : DNetPort;
- ior->io_Unit = (struct Unit *)unit;
- ior->io_Command = scmd;
- ior->io_Error = 0;
- ior->io_Data = NULL;
- ior->io_Length = 0;
- ior->io_Actual = 0;
- if (buf) {
- ior->io_Data = (APTR)AllocMem(len, MEMF_PUBLIC);
- ior->io_Length = len;
- CopyMem(buf, ior->io_Data, len);
- }
- PutMsg(port, ior);
- if (rettype == PKT_REQ)
- ++NumCon;
- }
-
- /*
- * ALLOC_CHANNEL()
- *
- * Allocate a channel. Starting at a random point, find the first
- * free channel. Return -1 if no free channels found.
- */
-
- alloc_channel()
- {
- static ulong ran = 13;
- long stamp[3];
- register uword i;
-
- DateStamp(stamp);
- ran = ((ran * 13) + 1) ^ (ran >> 9) + stamp[0] + stamp[1] + stamp[2];
- for (i = ran % MAXCHAN; i < MAXCHAN; ++i) {
- if (Chan[i].state == 0) {
- return(i);
- }
- }
- for (i = ran % MAXCHAN; i != 0xFFFF; --i) { /* Fixed 28 September 1988 */
- if (Chan[i].state == 0) {
- return(i);
- }
- }
- return(-1);
- }
-
- /*
- * Get next node in a linked list. If a pointer to a list base
- * is passed, gets the first node in the linked list. Returns
- * NULL if no further nodes in the list.
- */
-
- GetNext(node)
- NODE *node;
- {
- register NODE *next = node->ln_Succ;
- if (*(long *)next)
- return((long)next);
- return(NULL);
- }
-
- /*
- * CHKBUF
- *
- * Generate a two-byte checksum for data. Uses a very simple, but
- * effective algorithm.
- */
-
- chkbuf(buf, bytes)
- register ubyte *buf;
- register uword bytes;
- {
- register uword i;
- register ubyte c1,c2;
-
- for (i = c1 = c2 = 0; i < bytes; ++i) {
- c1 += buf[i];
- c2 += c1;
- }
- c1 = -(c1 + c2);
- return((c1<<8)|c2);
- }
-
-
- TimerOpen(req, sink)
- IOT *req;
- PORT *sink;
- {
- if (OpenDevice("timer.device", UNIT_VBLANK, req, 0))
- dneterror("timer.device");
- req->tr_node.io_Message.mn_ReplyPort = sink;
- req->tr_node.io_Command = TR_ADDREQUEST;
- }
-
- TimerClose(req)
- IOT *req;
- {
- CloseDevice(req);
- req->tr_node.io_Device = NULL;
- }
-
-
- /*
- * RUNSERVER
- *
- * Search the file [S:]DNET.SERVERS for the specified server and
- * attempt to LoadSeg()/CreateProc() it. The port number must be
- * non-zero (allows commening out lines in DNET.SERVERS), and
- * regardless of whether the server is able to DListen(), it must
- * perform a small handshake sequence with DNET.
- */
-
- void
- RunServer(portnum)
- uword portnum;
- {
- FILE *fi;
- char buf[128];
- char s1[64], s2[64];
- long v1;
- long seg;
-
- if (!portnum)
- return;
- if ((fi = fopen("dnet.servers", "r")) == NULL)
- fi = fopen("s:dnet.servers", "r");
- if (fi) {
- while (fgets(buf, 128, fi)) {
- if (sscanf(buf, "%ld %s %s", &v1, s1, s2) == 3 && v1 == portnum)
- goto success;
- }
- fclose(fi);
- }
- return;
- success:
- fclose(fi);
- if (seg = LoadSeg(s1)) {
- PNODE *pnode;
- PROC *myproc;
- PROC *proc;
- char *name;
- MSG msg;
-
- myproc = (PROC *)FindTask(NULL);
- pnode = AllocMem(sizeof(PNODE), MEMF_PUBLIC);
- sprintf(pnode->name, "DNET.SERVER.%ld", portnum);
- pnode->seg = seg;
- if (proc = CreateProc(pnode->name, 0, pnode->seg, 4096)) {
- proc = (PROC *)((char *)proc - OFFSET(proc,pr_MsgPort));
- msg.mn_ReplyPort = &myproc->pr_MsgPort;
- msg.mn_Node.ln_Name = s2;
- printf("Starting Server: %s %s\n", s1, pnode->name);
- PutMsg(&proc->pr_MsgPort, &msg); /* startup handshake */
- WaitPort(&myproc->pr_MsgPort);
- GetMsg(&myproc->pr_MsgPort);
- AddTail(&SvList, pnode);
- } else {
- printf("Unable to start server: %s %s\n", s1, pnode->name);
- FreeMem(pnode, sizeof(PNODE));
- }
- } else {
- printf("Server not found: %s\n", s1);
- }
- }
-
- /*
- * This cleans up as best as possible, but if there are still ACTIVE
- * servers or any CLIENTS, this call will not completely get rid of
- * them...
- *
- * Note that this call will KILL any servers automatically started up
- * by DNET and then UnLoadSeg() them. If the server has already exited,
- * it simply unloads the server's segment.
- */
-
- dneterror(str)
- char *str;
- {
- register short i;
- if (str)
- puts(str);
- if (DNetPort) {
- register IOR *ior;
- Forbid();
- while ((ior = (IOR *)RemHead(&TxList)) || (ior = (IOR *)GetMsg(DNetPort))) {
- ior->io_Error = -1;
- ReplyMsg(ior);
- }
- DeletePort(DNetPort);
- Permit();
- DNetPort = NULL;
- }
- if (Wto.tr_node.io_Device) {
- if (Wto_act) {
- AbortIO(&Wto);
- WaitIO(&Wto);
- Wto_act = 0;
- }
- TimerClose(&Wto);
- }
- if (Rto.tr_node.io_Device) {
- if (Rto_act) {
- AbortIO(&Rto);
- WaitIO(&Rto);
- Rto_act = 0;
- }
- TimerClose(&Rto);
- }
- if (Cto.tr_node.io_Device) {
- if (Cto_act) {
- AbortIO(&Cto);
- WaitIO(&Cto);
- Cto_act = 0;
- }
- TimerClose(&Cto);
- }
-
- NetClose();
- if (IOSink)
- DeletePort(IOSink);
- IOSink = NULL;
- for (i = 0; i < MAXCHAN; ++i) {
- if (Chan[i].state != CHAN_FREE && Chan[i].ior) {
- Chan[i].ior->io_Error = -1;
- Chan[i].state = CHAN_FREE;
- ReplyMsg(Chan[i].ior);
- }
- }
- {
- register PNODE *pnode;
- register PROC *proc;
- while (pnode = (PNODE *)RemHead(&SvList)) {
- Forbid();
- while (proc = (PROC *)FindTask(pnode->name)) {
- Signal(proc, SIGBREAKF_CTRL_C);
- Permit();
- printf("Waiting for server %s to exit\n", pnode->name);
- Forbid();
- }
- Permit();
- UnLoadSeg(pnode->seg);
- FreeMem(pnode, sizeof(PNODE));
- }
- }
- if (IPCPort)
- CloseIPC(IPCPort);
- if (DResBase)
- CloseLibrary(DResBase);
- exit(1);
- }
-
- bzero(ptr, bytes)
- register ubyte *ptr;
- register long bytes;
- {
- while (bytes--)
- *ptr++ = 0;
- }
-
- fixsignal(port)
- register PORT *port;
- {
- if ((long)port->mp_MsgList.lh_Head != (long)&port->mp_MsgList.lh_Tail)
- Signal(port->mp_SigTask, 1 << port->mp_SigBit);
- }
-
- SetTimeouts(baud)
- {
- WTimeoutVal = ((MAXPKT * 2) * 1000 / (baud / 10 + 1));
- RTimeoutVal = ((MAXPKT + 50) * 1000 / (baud / 10 + 1));
- WTimeoutVal *= 1000;
- RTimeoutVal *= 1000;
- }
-
-