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