home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff294.lzh / DNet / amiga / server / sterm.c < prev    next >
C/C++ Source or Header  |  1989-12-11  |  7KB  |  311 lines

  1.  
  2. /*
  3.  *  S_TERM.C
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  Terminal window server.
  8.  *    -Echo what is received in the window.
  9.  *    -Transmit stuff typed on keyboard, echoing locally.
  10.  *
  11.  *  Use FTERM on the other Amiga to connect.
  12.  *
  13.  *  NOTE!!!!  Spawned tasks are ... TASKS, not processes.  No DOS calls
  14.  *  allowed.
  15.  */
  16.  
  17. #include "defs.h"
  18.  
  19. int NHandlers;
  20.  
  21. struct IntuitionBase *IntuitionBase;
  22. struct GfxBase *GfxBase;
  23.  
  24. PORT *HdPort;
  25. PORT *LisPort;
  26. short HandShakeSig;
  27.  
  28. int spawn_handler ARGS((void));
  29. void __saveds term_task ARGS((void));
  30. void HandleIoctl ARGS((short, short, char, WIN *, IOCON *, short*));
  31. void setsize ARGS((IOCON *, void *, WIN *));
  32.  
  33. int
  34. brk()
  35. {
  36.     return(0);
  37. }
  38.  
  39. void
  40. #ifdef LATTICE
  41. _main(str)
  42. #else
  43. _main(len,str)
  44. #endif
  45. char *str;
  46. {
  47.     MSG *msg;
  48.     long mask, pmask, hdmask;
  49.     PROC *proc = (PROC *)FindTask(NULL);
  50.  
  51.     onbreak(brk);
  52.  
  53.     if (strncmp(str, "__dnet", 6) != 0) {
  54.     Version("STerm", VERSION, STERM_VERSION);
  55.     _exit(0);
  56.     }
  57.  
  58.     LisPort= DListen(PORT_IALPHATERM);
  59.     WaitPort(&proc->pr_MsgPort);
  60.     ReplyMsg(GetMsg(&proc->pr_MsgPort));
  61.     if (!LisPort)
  62.     exit(1);
  63.     HdPort = CreatePort(NULL, 0);
  64.     HandShakeSig = AllocSignal(-1);
  65.     pmask = 1 << LisPort->mp_SigBit;
  66.     hdmask= 1 << HdPort->mp_SigBit;
  67.  
  68.     IntuitionBase   = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  69.     GfxBase        = (struct GfxBase *)OpenLibrary("graphics.library", 0);
  70.     while (mask = Wait(SIGBREAKF_CTRL_C|pmask|hdmask)) {
  71.     if (mask & SIGBREAKF_CTRL_C)
  72.         break;
  73.     if (mask & hdmask) {
  74.         while (msg = GetMsg(HdPort)) {
  75.         --NHandlers;
  76.         FreeMem(msg, sizeof(*msg));
  77.         }
  78.     }
  79.     if (mask & pmask) {
  80.         while (spawn_handler())
  81.         ;
  82.     }
  83.     }
  84.     DUnListen(LisPort);
  85.     while (NHandlers) {
  86.     WaitPort(HdPort);
  87.     msg = GetMsg(HdPort);
  88.     FreeMem(msg, sizeof(*msg));
  89.     --NHandlers;
  90.     }
  91.     DeletePort(HdPort);
  92.     CloseLibrary((LIB *)IntuitionBase);
  93.     CloseLibrary((LIB *)GfxBase);
  94. }
  95.  
  96. /*
  97.  *  Spawn a handler to accept the new connection, if any.  Task sends
  98.  *  a message to HdPort when through.
  99.  */
  100.  
  101. int
  102. spawn_handler()
  103. {
  104.     long oldhan = NHandlers;
  105.  
  106.     CreateTask("Term.channel", 0, (APTR)term_task, 2048);
  107.     Wait(1 << HandShakeSig);
  108.     return (oldhan != NHandlers);
  109. }
  110.  
  111. static NW Nw = {
  112.     64, 64, 400, 100, -1, -1,
  113.     CLOSEWINDOW|NEWSIZE,
  114.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|ACTIVATE|NOCAREREFRESH,
  115.     NULL, NULL, (unsigned char *)"DNET-Term", NULL, NULL, 32, 32, -1, -1,
  116.     WBENCHSCREEN
  117. };
  118.  
  119. void __saveds
  120. term_task()
  121. {
  122.     void *chan;
  123.     long imask, cmask, conmask;
  124.     WIN *win;
  125.     char notdone = 1;
  126.     short ignorens = 0;
  127.     char conc[4];
  128.     IOCON iocw;
  129.     IOCON iocr;
  130.  
  131. #ifndef LATTICE
  132.     geta4();
  133. #endif
  134.     chan = DAccept(LisPort);
  135.     if (chan) {
  136.     DQueue(chan, 32);
  137.     DIoctl(chan, CIO_MODE, 7, 0);
  138.     ++NHandlers;
  139.     Signal(HdPort->mp_SigTask, 1 << HandShakeSig);
  140.     if (win = OpenWindow(&Nw)) {
  141.         iocw.io_Command = CMD_WRITE;
  142.         iocw.io_Data = (APTR)win;
  143.         iocw.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  144.         iocw.io_Message.mn_ReplyPort = CreatePort(NULL,0);
  145.         conmask = 1 << iocw.io_Message.mn_ReplyPort->mp_SigBit;
  146.         OpenDevice("console.device", 0, &iocw, 0);
  147.         iocr = iocw;
  148.         iocr.io_Command = CMD_READ;
  149.         imask = 1 << win->UserPort->mp_SigBit;
  150.         cmask = 1 << ((PORT *)chan)->mp_SigBit;
  151.  
  152.         iocr.io_Data = (APTR)conc;
  153.         iocr.io_Length = sizeof(conc);
  154.         SendIO(&iocr);
  155.  
  156.         setsize(&iocw, NULL, win);
  157.         while (notdone) {
  158.         long mask;
  159.         mask = Wait(imask|cmask|conmask);
  160.  
  161.         if (mask & imask) {
  162.             IMESS *im;
  163.             while (im = (IMESS *)GetMsg(win->UserPort)) {
  164.             switch(im->Class) {
  165.             case CLOSEWINDOW:
  166.                 notdone = 0;
  167.                 break;
  168.             case NEWSIZE:
  169.                 if (ignorens) {
  170.                 --ignorens;
  171.                 setsize(&iocw, NULL, win);
  172.                 } else {
  173.                 setsize(&iocw, chan, win);
  174.                 }
  175.                 break;
  176.             }
  177.             ReplyMsg((MSG *)im);
  178.             }
  179.         }
  180.         if ((mask & conmask) && CheckIO(&iocr)) {
  181.             short i;
  182.             char *ptr;
  183.             WaitIO(&iocr);
  184.             ptr = (char *)iocr.io_Data;
  185.  
  186.             if (iocr.io_Actual > 0) {
  187.             for (i = 0; i < iocr.io_Actual; ++i) {
  188.                 if (ptr[i] == 13)
  189.                 ptr[i] = 10;
  190.             }
  191.             DWrite(chan, ptr, i);
  192.             iocw.io_Data = (APTR)ptr;
  193.             iocw.io_Length = i;
  194.             DoIO(&iocw);
  195.             }
  196.             iocr.io_Data = (APTR)conc;
  197.             iocr.io_Length = sizeof(conc);
  198.             SendIO(&iocr);
  199.         }
  200.         if (mask & cmask) {
  201.             long n;
  202.             char buf[32];
  203.             while (n = DNRead(chan, buf, sizeof(buf))) {
  204.             if (n == -2) {
  205.                 short cmd, val;
  206.                 char aux;
  207.                 cmd = DGetIoctl(chan, &val, &aux);
  208.                 if (cmd >= 0)
  209.                 HandleIoctl(cmd, val, aux, win, &iocw, &ignorens);
  210.                 continue;
  211.             }
  212.             if (n < 0) {
  213.                 notdone = 0;
  214.                 break;
  215.             }
  216.             if (buf[0] == 3)        /*  remote ^C -- done   */
  217.                 notdone = 0;
  218.             iocw.io_Data = (APTR)buf;
  219.             iocw.io_Length = n;
  220.             DoIO(&iocw);
  221.             }
  222.         }
  223.         }
  224.         AbortIO(&iocr);
  225.         WaitIO(&iocr);
  226.         CloseDevice(&iocw);
  227.         DeletePort(iocw.io_Message.mn_ReplyPort);
  228.         CloseWindow(win);
  229.     }
  230.     DClose(chan);
  231.     {
  232.         MSG *msg;
  233.         msg = AllocMem(sizeof(MSG), MEMF_PUBLIC);
  234.         Forbid();
  235.         PutMsg(HdPort, msg);
  236.     }
  237.     } else {
  238.     Forbid();
  239.     Signal(HdPort->mp_SigTask, 1 << HandShakeSig);
  240.     }
  241.     RemTask(NULL);
  242. }
  243.  
  244. void
  245. HandleIoctl(cmd, val, aux, win, iocw, igns)
  246. short cmd, val;
  247. char aux;
  248. WIN *win;
  249. IOCON *iocw;
  250. short *igns;
  251. {
  252.     static short saverows;
  253.     short height, width;
  254.     short dx, dy;
  255.  
  256.     switch(cmd) {
  257.     case CIO_SETROWS:
  258.     saverows = val;
  259.     break;
  260.     case CIO_SETCOLS:
  261.     width = val * win->RPort->TxWidth + win->BorderLeft + win->BorderRight;
  262.     height= saverows * win->RPort->TxHeight + win->BorderTop + win->BorderBottom;
  263.  
  264.     dx = win->WScreen->Width - (win->LeftEdge + width);
  265.     if (dx > 0)
  266.         dx = 0;
  267.     if (-dx > win->LeftEdge) {
  268.         dx = -win->LeftEdge;
  269.         width = win->WScreen->Width;
  270.     }
  271.  
  272.     dy = win->WScreen->Height - (win->TopEdge + height);
  273.     if (dy > 0)
  274.         dy = 0;
  275.     if (-dy > win->TopEdge) {
  276.         dy = -win->TopEdge;
  277.         height = win->WScreen->Height;
  278.     }
  279.  
  280.     if (dx || dy) {
  281.         MoveWindow(win, dx, dy);
  282.     }
  283.     if (win->Width != width || win->Height != height) {
  284.         SizeWindow(win, width - win->Width, height - win->Height);
  285.         ++*igns;
  286.     }
  287.     break;
  288.     }
  289. }
  290.  
  291. void
  292. setsize(iocw, chan, win)
  293. IOCON *iocw;
  294. void *chan;
  295. WIN *win;
  296. {
  297.     struct ConUnit *cu = (struct ConUnit *)iocw->io_Unit;
  298.     static char Term[64];
  299.  
  300.     iocw->io_Data = (APTR)"\033c\033[20h\033[t\033[u";
  301.     iocw->io_Length = 13;
  302.     DoIO(iocw);
  303.     if (chan) {
  304.     DIoctl(chan, CIO_SETROWS, (uword)(cu->cu_YMax+1), 0);
  305.     DIoctl(chan, CIO_SETCOLS, (uword)(cu->cu_XMax+1), 0);
  306.     }
  307.     sprintf(Term, "STERM   %ld x %ld", cu->cu_YMax+1, cu->cu_XMax+1);
  308.     SetWindowTitles(win, Term, (char *)-1);
  309. }
  310.  
  311.