/* * S_TERM.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. * * Terminal window server. * -Echo what is received in the window. * -Transmit stuff typed on keyboard, echoing locally. * * Use FTERM on the other Amiga to connect. */ #include #include #include "servers.h" #include "/include/typedefs.h" int Enable_Abort; int NHandlers; long IntuitionBase; long GfxBase; extern struct MsgPort *DListen(); extern struct MsgPort *DAccept(); extern struct Window *OpenWindow(); extern void *GetMsg(), *CreatePort(), *AllocMem(); extern PROC *FindTask(); struct MsgPort *HdPort; struct MsgPort *LisPort; short HandShakeSig; _main() { struct Message *msg; long mask, pmask, hdmask; PROC *proc = FindTask(NULL); Enable_Abort = 0; LisPort= DListen(PORT_IALPHATERM); WaitPort(&proc->pr_MsgPort); ReplyMsg(GetMsg(&proc->pr_MsgPort)); if (!LisPort) exit(1); HdPort = CreatePort(NULL, 0); HandShakeSig = AllocSignal(-1); pmask = 1 << LisPort->mp_SigBit; hdmask= 1 << HdPort->mp_SigBit; IntuitionBase = OpenLibrary("intuition.library", 0); GfxBase = OpenLibrary("graphics.library", 0); while (mask = Wait(SIGBREAKF_CTRL_C|pmask|hdmask)) { if (mask & SIGBREAKF_CTRL_C) break; if (mask & hdmask) { while (msg = GetMsg(HdPort)) { --NHandlers; FreeMem(msg, sizeof(*msg)); } } if (mask & pmask) { while (spawn_handler()) ; } } DUnListen(LisPort); while (NHandlers) { WaitPort(HdPort); msg = GetMsg(HdPort); FreeMem(msg, sizeof(*msg)); --NHandlers; } DeletePort(HdPort); CloseLibrary(IntuitionBase); CloseLibrary(GfxBase); } /* * Spawn a handler to accept the new connection, if any. Task sends * a message to HdPort when through. */ spawn_handler() { extern void term_task(); long oldhan = NHandlers; CreateTask("Term.channel", 0, term_task, 2048); Wait(1 << HandShakeSig); return (oldhan != NHandlers); } static NW Nw = { 64, 64, 400, 100, -1, -1, VANILLAKEY|CLOSEWINDOW, WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|ACTIVATE|NOCAREREFRESH, NULL, NULL, (unsigned char *)"DNET-Term", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN }; void term_task() { struct MsgPort *chan; /* actually only the front end is a msgport */ IMESS *im; long n; long imask, cmask; struct Message *msg; struct Window *win; char notdone = 1; char buf[32]; IOCON ioc; geta4(); chan = (struct MsgPort *)DAccept(LisPort); if (chan) { DQueue(chan, 32); ++NHandlers; Signal(HdPort->mp_SigTask, 1 << HandShakeSig); if (win = OpenWindow(&Nw)) { ioc.io_Command = CMD_WRITE; ioc.io_Data = (APTR)win; ioc.io_Message.mn_Node.ln_Type = NT_MESSAGE; ioc.io_Message.mn_ReplyPort = win->UserPort; OpenDevice("console.device", 0, &ioc, 0); imask = 1 << win->UserPort->mp_SigBit; cmask = 1 << chan->mp_SigBit; while (notdone) { Wait(imask|cmask); while (im = (IMESS *)GetMsg(win->UserPort)) { switch(im->Class) { case VANILLAKEY: n = 1; buf[0] = im->Code; if (buf[0] == 13) { buf[1] = 10; ++n; } DWrite(chan, buf, n); ioc.io_Data = (APTR)buf; ioc.io_Length = n; DoIO(&ioc); break; case CLOSEWINDOW: notdone = 0; break; } ReplyMsg(im); } while (n = DNRead(chan, buf, sizeof(buf))) { if (n < 0) { notdone = 0; break; } DWrite(chan, buf, n); /* echo back */ if (buf[0] == 3) /* remote ^C -- done */ notdone = 0; ioc.io_Data = (APTR)buf; ioc.io_Length = n; DoIO(&ioc); } } CloseDevice(&ioc); CloseWindow(win); } DClose(chan); msg = AllocMem(sizeof(*msg), MEMF_PUBLIC); Forbid(); PutMsg(HdPort, msg); } else { Forbid(); Signal(HdPort->mp_SigTask, 1 << HandShakeSig); } RemTask(NULL); }