/* * WINDOW.C * * DNET interactive terminal window. */ #include "dnet.h" #include "/server/servers.h" #include "/dnet/channel.h" #include "/lib/dnetlib.h" void setparity(); void addparity(); void OpenConsole(); void CloseConsole(); void InitDeemuNW(); void LoadConnectList(); void UnLoadConnectList(); IOSER *NetReadReady(); IOSER *NetAbortRead(); typedef struct TextAttr TA; typedef struct IntuiText ITEXT; typedef struct IntuiMessage IMESS; typedef struct Screen SCR; typedef struct Library LIB; typedef struct Menu MENU; typedef struct MenuItem ITEM; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; TA Ta = { (ubyte *)"topaz", 8 }; ITEXT IText[] = { { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"SendBreak" }, { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"StartDNET" }, { 0, 1, JAM2, 0, 0, &Ta, (ubyte *)"QUIT" } }; ITEM Item[] = { { &Item[1], 0, 0, 120, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[0], NULL, 'b' }, { &Item[2], 0,10, 120, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[1], NULL, 's' }, { NULL , 0,20, 120, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText[2], NULL, 'q' } }; MENU Menu[] = { { NULL , 0, 0, 120, 20, MENUENABLED, "DnetControl", &Item[0] } }; ubyte Title[80]; void do_dnetwindow(oldbaud) { static struct NewWindow Nw = { 50, 50, 320, 100, -1, -1, CLOSEWINDOW|MENUPICK, WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|ACTIVATE, NULL, NULL, Title, NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN }; struct Window *win; char RcvBuf[128]; char Cc; char RSync = 0; long imask, smask, conmask, mask, dnet_mask; #ifdef NOTDEF long ipc_mask; #endif IOCON *iocr, *iocw; char notdone = 1; sprintf(Title, "DNET V%s%s", VERSION, DNET_VERSION); setparity(0xFF, 0x00, 1); IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0); GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0); if (IntuitionBase == NULL || GfxBase == NULL) goto e1; InitDeemuNW(Deemu+DMNWOFF, &Nw); win = OpenWindow(&Nw); if (win == NULL) goto e1; SetMenuStrip(win, Menu); OpenConsole(win, &iocr, &iocw); if (iocr == NULL) goto e3; if (Cto_act) { AbortIO((IOR *)&Cto); WaitIO((IOR *)&Cto); Cto_act = 0; } if (Wto_act) { AbortIO((IOR *)&Wto); WaitIO((IOR *)&Wto); Wto_act = 0; } SetBaudRate(oldbaud); if (OpenCfgFile()) { /* Automatic enviroment reset. */ char *env; char *get = (AutoAnswer) ? "ENVA" : ((DialOut) ? "ENVO" : "ENVM"); while (env = GetCfgLine(get)) { char *ptr; for (ptr = env; *ptr && *ptr != ' ' && *ptr != 9; ++ptr); if (*ptr) { *ptr = 0; for (++ptr; *ptr == ' ' || *ptr == 9; ++ptr); SetDEnv(env, ptr); } } } if (Cd == 0 && AutoAnswer) { if (OpenCfgFile()) { char *str; while (str = GetCfgLine("RESM")) { /* RESM MODEM-CMD */ short len = strlen(str); str[len++] = '\r'; NetWrite(str, len, 0); Cto.tr_time.tv_secs = 1; Cto.tr_time.tv_micro= 0; DoIO((IOR *)&Cto); } CloseCfgFile(); } else { NetWrite("AT\r", 3, 0); /* cause modem to reset baud rate */ Cto.tr_time.tv_secs = 1; Cto.tr_time.tv_micro= 0; DoIO((IOR *)&Cto); NetWrite("AT\r", 3, 0); /* cause modem to reset baud rate */ Cto.tr_time.tv_secs = 1; Cto.tr_time.tv_micro= 0; DoIO((IOR *)&Cto); NetWrite("ATS0=1\r", 7, 0); /* auto answer on */ } } iocr->io_Data = (APTR)&Cc; iocr->io_Length = 1; SendIO((IOR *)iocr); imask = 1 << win->UserPort->mp_SigBit; smask = 1 << IOSink->mp_SigBit; conmask = 1 << iocr->io_Message.mn_ReplyPort->mp_SigBit; dnet_mask = 1 << DNetPort->mp_SigBit; #ifdef NOTDEF ipc_mask= 1 << IPCPort->mp_SigBit; #endif LoadConnectList(); Signal(FindTask(NULL), imask|smask|conmask|dnet_mask/*|ipc_mask*/); StartWriteTimeout(1); while (!Quit && OnLine == 0) { mask = Wait(imask|smask|conmask|dnet_mask/*|ipc_mask*/); #ifdef NOTDEF if (mask & ipc_mask) handle_ipc(); #endif if (mask & dnet_mask) { IOSTD *ior; while (ior = (IOSTD *)GetMsg(DNetPort)) { switch(ior->io_Command) { default: case DNCMD_WRITE: case DNCMD_EOF: case DNCMD_IOCTL: case DNCMD_QUIT: case DNCMD_OPEN: ior->io_Error = 1; break; case DNCMD_CLOSE: Chan[(ulong)ior->io_Unit].state = CHAN_FREE; break; case DNCMD_SOPEN: { uword chan = (ulong)ior->io_Unit; Chan[chan].state = CHAN_FREE; if (!ior->io_Error) { Chan[chan].state = CHAN_CLOSE; Chan[chan].port = (PORT *)ior->io_Offset; Chan[chan].flags = CHANF_RCLOSE; WritePort(Chan[chan].port, DNCMD_CLOSE, NULL, 0, PKT_REQ, chan); } if (ior->io_Length) FreeMem(ior->io_Data, ior->io_Length); FreeMem(ior, sizeof(IOSTD)); ior = NULL; } break; case DNCMD_EXEC: Execute((char *)ior->io_Offset, NULL, NULL); break; } if (ior) ReplyMsg((MSG *)ior); } } if (mask & imask) { struct IntuiMessage *im; while (im = (IMESS *)GetMsg(win->UserPort)) { switch(im->Class) { case CLOSEWINDOW: notdone = 0; Quit = 1; break; case MENUPICK: switch((uword)((MENUNUM(im->Code)<<8)|ITEMNUM(im->Code))) { case 0x0000: /* menu 0 item 0 */ NetBreak(); break; case 0x0001: /* menu 0 item 1 */ notdone = 0; OnLine = 1; break; case 0x0002: /* menu 0 item 2 */ notdone = 0; Quit = 1; break; case 0x0100: /* menu 1 item 0 */ break; } break; } ReplyMsg((MSG *)im); } } if (mask & smask) { IOSER *ios; if (ios = NetReadReady()) { int n; int actual; ubyte *ptr; WaitIO((IOR *)ios); actual = NetReadReturned(&ptr); if (actual > 0) { if (RSync && *ptr == PKCMD_RESTART) { OnLine = 1; notdone = 0; } RSync = (*ptr == SYNC); for (n = 0; n < actual; ++n) ptr[n] &= 0x7F; oldbaud = CheckConnect(oldbaud, ptr, n); iocw->io_Data = (APTR)ptr; iocw->io_Length = n; DoIO((IOR *)iocw); } if ((n = NetReady()) >= sizeof(RcvBuf)) n = sizeof(RcvBuf) - 1; if (n <= 0) n = 1; NetStartRead(n); } if (CheckIO(&Wto)) { StartWriteTimeout(1); NetReady(); } } if (mask & conmask) { if (CheckIO((IOR *)iocr)) { WaitIO((IOR *)iocr); if (!Master8) addparity((ubyte *)iocr->io_Data, iocr->io_Actual); NetWrite(iocr->io_Data, iocr->io_Actual, 0); NetWaitWrite(); iocr->io_Data = (APTR)&Cc; iocr->io_Length = 1; SendIO((IOR *)iocr); } } NetReady(); if (Getty && !Cd) { Quit = 1; notdone = 0; break; } if (AutoAnswer && Cd) break; } StartWriteTimeout(0); UnLoadConnectList(); { IOSER *ios = NetAbortRead(); if (ios->IOSer.io_Actual > 0) { ubyte *ptr = (ubyte *)ios->IOSer.io_Data; short n; for (n = 0; n < ios->IOSer.io_Actual; ++n) ptr[n] &= 0x7F; oldbaud = CheckConnect(oldbaud, ptr, n); } } if (DDebug) printf("SETTING BAUD RATE TO %d\n", oldbaud); if (AutoAnswer && Cd) { char *msg = "\r\nDNET AutoAnswer, Protocol Start\r\n"; OnLine = 1; NetWrite(msg, strlen(msg), 0); Cto.tr_time.tv_secs = 3; Cto.tr_time.tv_micro= 0; DoIO((IOR *)&Cto); } NetStartRead(3); AbortIO((IOR *)iocr); WaitIO((IOR *)iocr); CloseConsole(iocr, iocw); e3: CloseWindow(win); e1: if (IntuitionBase) CloseLibrary((LIB *)IntuitionBase); if (GfxBase) CloseLibrary((LIB *)GfxBase); if (Quit) puts("DNET EXITING"); else puts("DNET RUNNING"); return; } /* * PARITY ROUTINES */ static ubyte Party[256/8]; void setparity(pand, por, peven) int pand, por, peven; { short i, j, k, l; BZero(Party, sizeof(Party)); for (i = 0; i < 128; ++i) { for (j = (~i & 127), k = 0; j; j >>= 1) { /* k = count # of 0's */ if (j & 1) ++k; } k ^= peven; l = (((k & 1) ? 0x01 : 0) | por) & pand; Party[i >> 3] |= l << (i & 7); } } void addparity(buf, bytes) ubyte *buf; int bytes; { short i; for (i = bytes - 1; i >= 0; --i) { if (Party[buf[i]>>3] & (1 << (buf[i]&7))) buf[i] |= 0x80; } } void OpenConsole(win, piocr, piocw) IOCON **piocr, **piocw; struct Window *win; { PORT *port; static IOCON iocr, iocw; int error; port = CreatePort(NULL, 0); iocr.io_Command = CMD_READ; iocr.io_Data = (APTR)win; iocr.io_Message.mn_Node.ln_Type = NT_MESSAGE; iocr.io_Message.mn_ReplyPort = port; error = OpenDevice("console.device", 0, (IOR *)&iocr, 0); if (!error) { iocw = iocr; iocw.io_Command = CMD_WRITE; *piocr = &iocr; *piocw = &iocw; } else { *piocr = *piocw = NULL; } } void CloseConsole(iocr, iocw) IOCON *iocr; IOCON *iocw; { CloseDevice((IOR *)iocr); DeletePort(iocr->io_Message.mn_ReplyPort); } void InitDeemuNW(ary, nw) short *ary; NW *nw; { short alen = ary[3]; SCR Scr; if (GetScreenData((char *)&Scr, sizeof(Scr), nw->Type, nw->Screen) == 0) { Scr.Width = 320; Scr.Height= 200; } if (alen >= 8) { if ((nw->Width = ary[6]) < 0) nw->Width += Scr.Width; if ((nw->Height = ary[7]) < 0) nw->Height+= Scr.Height; } if (alen >= 4) { if ((nw->LeftEdge= ary[4]) < 0) nw->LeftEdge += Scr.Width - nw->Width; if ((nw->TopEdge = ary[5]) < 0) nw->TopEdge += Scr.Height - nw->Height; } if (nw->LeftEdge < 0 || nw->TopEdge < 0 || nw->Width < 0 || nw->Height < 0 || nw->LeftEdge + nw->Width > Scr.Width || nw->TopEdge + nw->Height > Scr.Height) { nw->LeftEdge = nw->TopEdge = 0; nw->Width = 320; nw->Height= 100; } if (alen >= 9) nw->DetailPen = ary[8] >> 8; if (alen >= 10) nw->BlockPen = ary[8]; } /* * */ static MLIST CList; void LoadConnectList() { char *ptr; NewList((LIST *)&CList); OpenCfgFile(); while (ptr = GetCfgLine("AUTA")) { long baudrate = atoi(ptr); while (*ptr && *ptr != '\"') ++ptr; if (*ptr == '\"') { char *en; NODE *node; for (en = ++ptr; *en && *en != '\"'; ++en); *en = 0; if (node = (NODE *)malloc(sizeof(NODE)+strlen(ptr)+1)) { AddTail((LIST *)&CList, node); node->ln_Name = (char *)baudrate; strcpy((char *)(node + 1), ptr); } } } CloseCfgFile(); } void UnLoadConnectList() { NODE *node; while (node = RemHead((LIST *)&CList)) free(node); } int CheckConnect(oldbaud, ptr, n) int oldbaud; char *ptr; int n; { static char tmpbuf[64]; static short tlen; short i; NODE *node; long newbaud = oldbaud; for (i = 0; i < n; ++i) { if (ptr[i] == 13 || ptr[i] == 10) { tmpbuf[tlen++] = 0; if (tlen < 2) { tlen = 0; continue; } tlen = 0; for (node = (NODE *)GetHead(&CList); node; node = (NODE *)GetSucc(node)) { if (strcmp(tmpbuf, (char *)(node + 1)) == 0) { newbaud = (long)node->ln_Name; if (DDebug) printf("Successful compare, baud -> %d\n", newbaud); break; } } if (GetHead(&CList) == NULL) { if (strncmp(tmpbuf, "CONNECT", 7) == 0) { newbaud = atoi(tmpbuf + 7); if (newbaud == 0) newbaud = 300; } } continue; } tmpbuf[tlen++] = ptr[i]; if (tlen == sizeof(tmpbuf)) tlen = 0; } if (oldbaud != newbaud) SetBaudRate(newbaud); return(newbaud); }