/* * WINDOW.C * * DNET interactive terminal window. */ #include "dnet.h" #include #include #include "/server/servers.h" long IntuitionBase; long 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, ipc_mask; IOCON *iocr, *iocw; char notdone = 1; sprintf(Title, "DNET V%s%s", VERSION, DNET_VERSION); setparity(0xFF, 0x00, 1); IntuitionBase = (long)OpenLibrary("intuition.library", 0); GfxBase = (long)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(&Cto); WaitIO(&Cto); Cto_act = 0; } if (Wto_act) { AbortIO(&Wto); WaitIO(&Wto); Wto_act = 0; } SetBaudRate(oldbaud); if (OpenCfgFile()) { /* Automatic enviroment reset. */ char *env; char *get = (AutoAnswer) ? "ENVA" : ((DialOut) ? "ENVO" : "ENVM"); while (env = GetCfgLine(get)) { register 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()) { register 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(&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(&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(&Cto); NetWrite("ATS0=1\r", 7, 0); /* auto answer on */ } } iocr->io_Data = (APTR)&Cc; iocr->io_Length = 1; SendIO(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; ipc_mask= 1 << IPCPort->mp_SigBit; LoadConnectList(); Signal(FindTask(NULL), imask|smask|conmask|dnet_mask|ipc_mask); while (!Quit && OnLine == 0) { mask = Wait(imask|smask|conmask|dnet_mask|ipc_mask); if (mask & ipc_mask) handle_ipc(); if (mask & dnet_mask) { register IOR *ior; while (ior = (IOR *)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(IOR)); ior = NULL; } break; } if (ior) ReplyMsg(ior); } } if (mask & imask) { struct IntuiMessage *im; while (im = 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(im); } } if (mask & smask) { register IOSER *ios; if (ios = NetReadReady()) { int n; register ubyte *ptr; WaitIO(ios); NetReadReturned(); if (ios->IOSer.io_Actual > 0) { ptr = (ubyte *)ios->IOSer.io_Data; if (RSync && *ptr == PKCMD_RESTART) { OnLine = 1; notdone = 0; } RSync = (*ptr == SYNC); for (n = 0; n < ios->IOSer.io_Actual; ++n) ptr[n] &= 0x7F; oldbaud = CheckConnect(oldbaud, ptr, n); iocw->io_Data = (APTR)ptr; iocw->io_Length = n; DoIO(iocw); } if ((n = NetReady()) >= sizeof(RcvBuf)) n = sizeof(RcvBuf) - 1; if (n <= 0) n = 1; NetStartRead(RcvBuf, n); } } if (mask & conmask) { if (CheckIO(iocr)) { WaitIO(iocr); if (!Master8) addparity(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(iocr); } } if (AutoAnswer && Cd) break; } UnLoadConnectList(); { register IOSER *ios = NetAbortRead(); if (ios->IOSer.io_Actual > 0) { register ubyte *ptr = (ubyte *)ios->IOSer.io_Data; register 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(&Cto); } NetStartRead(&Raux->sync, 3); AbortIO(iocr); WaitIO(iocr); CloseConsole(iocr, iocw); e3: CloseWindow(win); e1: if (IntuitionBase) CloseLibrary(IntuitionBase); if (GfxBase) CloseLibrary(GfxBase); if (Quit) puts("DNET EXITING"); else puts("DNET RUNNING"); return; } /* * PARITY ROUTINES */ static ubyte Party[256/8]; setparity(pand, por, peven) { register 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); } } addparity(buf, bytes) register ubyte *buf; { register short i; for (i = bytes - 1; i >= 0; --i) { if (Party[buf[i]>>3] & (1 << (buf[i]&7))) buf[i] |= 0x80; } } 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, &iocr, 0); if (!error) { iocw = iocr; iocw.io_Command = CMD_WRITE; *piocr = &iocr; *piocw = &iocw; } else { *piocr = *piocw = NULL; } } CloseConsole(iocr, iocw) IOCON *iocr; IOCON *iocw; { CloseDevice(iocr); DeletePort(iocr->io_Message.mn_ReplyPort); } InitDeemuNW(ary, nw) register short *ary; register NW *nw; { register short alen = ary[3]; SCR Scr; if (GetScreenData(&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; LoadConnectList() { char *ptr; NODE *node; NewList(&CList); OpenCfgFile(); while (ptr = GetCfgLine("AUTA")) { long baudrate = atoi(ptr); while (*ptr && *ptr != '\"') ++ptr; if (*ptr == '\"') { register char *en; register NODE *node; for (en = ++ptr; *en && *en != '\"'; ++en); *en = 0; if (node = malloc(sizeof(NODE)+strlen(ptr)+1)) { AddTail(&CList, node); node->ln_Name = (char *)baudrate; strcpy(node + 1, ptr); } } } CloseCfgFile(); } UnLoadConnectList() { NODE *node; while (node = RemHead(&CList)) free(node); } CheckConnect(oldbaud, ptr, n) register char *ptr; { static char tmpbuf[64]; static short tlen; register short i; register NODE *node; long newbaud = oldbaud; for (i = 0; i < n; ++i) { if (ptr[i] == 13 || ptr[i] == 10) { register char *ptr; tmpbuf[tlen++] = 0; if (tlen < 2) { tlen = 0; continue; } tlen = 0; for (node = GetHead(&CList); node; node = GetSucc(node)) { if (strcmp(tmpbuf, 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); }