home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / util / libs / fifolib / remcli.c < prev    next >
C/C++ Source or Header  |  1993-10-03  |  7KB  |  351 lines

  1.  
  2. /*
  3.  *  REMCLI.C
  4.  *
  5.  *  REMCLI <fifo_name>
  6.  *
  7.  *  PUBLIC DOMAIN CODE, sample code showing how to set up a remote CLI
  8.  *  through the FIFO: device, using fifo.library to handle the master
  9.  *  end.
  10.  *
  11.  *  WARNING:    ReadFifo() returns an EOF condition (-1) only once,
  12.  *        calling it again will return 0 .. blocking until a
  13.  *        writer writes something then closes again to generate
  14.  *        another EOF.
  15.  */
  16.  
  17. #include <exec/types.h>
  18. #include <exec/io.h>
  19. #include <exec/memory.h>
  20. #include <devices/serial.h>
  21. #include <devices/timer.h>
  22. #include <devices/conunit.h>
  23. #include <hardware/cia.h>
  24. #include <intuition/intuition.h>
  25. #include <libraries/dos.h>
  26. #include <clib/intuition_protos.h>
  27. #include <clib/alib_protos.h>
  28. #include <clib/exec_protos.h>
  29. #include <clib/dos_protos.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "fifo.h"
  34.  
  35. typedef unsigned char    ubyte;
  36. typedef unsigned short    uword;
  37. typedef unsigned long    ulong;
  38. typedef struct MsgPort        MsgPort;
  39.  
  40. typedef struct Task        Task;
  41. typedef struct Process        Process;
  42. typedef struct Window        Window;
  43. typedef struct IOStdReq     Ioc;
  44. typedef struct Message        Message;
  45. typedef struct IntuiMessage IMess;
  46. typedef struct IORequest    IORequest;
  47.  
  48. Ioc    Iocr;
  49. Ioc    Iocw;
  50. Message RMsg;
  51. Message WMsg;
  52. Window    *Win;
  53. char    *FifoName;    /*  fifo    */
  54. char    *FifoSlav;    /*  fifo_s  */
  55. char    *FifoMast;    /*  fifo_m  */
  56. MsgPort *IoSink;
  57. char    ConBuf[32];
  58. void    *FifoR;
  59. void    *FifoW;
  60. void    *FifoBase;
  61. void    *IntuitionBase;
  62.  
  63. char    IocrIP;     /*  console read pending*/
  64. char    IocrHold;
  65. char    FifrIP;     /*  read msg pending    */
  66. char    FifwIP;     /*  write msg pending    */
  67.  
  68. struct NewWindow Nw = {
  69.     0, 0, 640, 200, -1, -1,
  70.     CLOSEWINDOW|MENUPICK|GADGETUP|GADGETDOWN|NEWSIZE,
  71.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|
  72.     NOCAREREFRESH|ACTIVATE,
  73.     NULL, NULL, (ubyte *)"RemCLI", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN
  74. };
  75.  
  76. void ConWriteStr(char *);
  77. void ConWrite(void *, long);
  78. void SendBreak(int);
  79. void myexit(void);
  80. void WaitMsg(Message *);
  81. int  brk(void);
  82.  
  83. main(ac, av)
  84. char **av;
  85. {
  86.     long imask;
  87.     long pmask;
  88.     short notDone = 1;
  89.  
  90.     if (ac == 1) {
  91.     fprintf(stderr, "Demonstration Remote Shell through FIFO:\n");
  92.     fprintf(stderr, "Instructions:\n");
  93.     fprintf(stderr, "  1> NewShell FIFO:name/rwkecs\n");
  94.     fprintf(stderr, "  1> RemCLI name\n");
  95.     exit(1);
  96.     }
  97.     atexit(myexit);
  98.     onbreak(brk);
  99.  
  100.     FifoName = av[1];
  101.     FifoSlav = malloc(strlen(FifoName) + 16);
  102.     FifoMast = malloc(strlen(FifoName) + 16);
  103.     sprintf(FifoMast, "%s_m", FifoName);
  104.     sprintf(FifoSlav, "%s_s", FifoName);
  105.  
  106.     IoSink = CreatePort(NULL, 0);
  107.  
  108.     /*
  109.      *    FIFOS
  110.      */
  111.  
  112.     FifoBase = OpenLibrary(FIFONAME, 0);
  113.     if (!FifoBase) {
  114.     fprintf(stderr, "unable to open %s\n", FIFONAME);
  115.     exit(1);
  116.     }
  117.     FifoW = OpenFifo(FifoMast, 2048, FIFOF_WRITE | FIFOF_NORMAL | FIFOF_NBIO);
  118.     if (FifoW == NULL) {
  119.     fprintf(stderr, "unable to open fifo %s\n", FifoMast);
  120.     exit(1);
  121.     }
  122.     FifoR = OpenFifo(FifoSlav, 2048, FIFOF_READ  | FIFOF_NORMAL | FIFOF_NBIO);
  123.     if (FifoR == NULL) {
  124.     fprintf(stderr, "unable to open fifo %s\n", FifoSlav);
  125.     exit(1);
  126.     }
  127.     RMsg.mn_ReplyPort = IoSink;
  128.     WMsg.mn_ReplyPort = IoSink;
  129.  
  130.     /*
  131.      *    WINDOW
  132.      */
  133.  
  134.     IntuitionBase = OpenLibrary("intuition.library", 0);
  135.     if (!IntuitionBase) {
  136.     fprintf(stderr, "unable to open intuition.library\n");
  137.     exit(1);
  138.     }
  139.  
  140.     Win = OpenWindow(&Nw);
  141.     if (Win == NULL) {
  142.     fprintf(stderr, "unable to open window!\n");
  143.     exit(1);
  144.     }
  145.     imask = 1 << Win->UserPort->mp_SigBit;
  146.     pmask = 1 << IoSink->mp_SigBit;
  147.  
  148.     /*
  149.      *    CONSOLE DEVICE
  150.      */
  151.  
  152.     Iocw.io_Message.mn_ReplyPort = IoSink;
  153.     Iocw.io_Data = (APTR)Win;
  154.     Iocw.io_Length = sizeof(*Win);
  155.     if (OpenDevice("console.device", 0, (IORequest *)&Iocw, 0)) {
  156.     fprintf(stderr, "can't open console!\n");
  157.     exit(1);
  158.     }
  159.     Iocr = Iocw;
  160.     Iocw.io_Command = CMD_WRITE;
  161.     Iocr.io_Command = CMD_READ;
  162.  
  163.     Iocr.io_Data = (APTR)ConBuf;
  164.     Iocr.io_Length = 1;
  165.     SendIO((IORequest *)&Iocr);
  166.     IocrIP = 1;
  167.  
  168.     /*
  169.      *    start async FIFO requests
  170.      */
  171.  
  172.     RequestFifo(FifoR, &RMsg, FREQ_RPEND);
  173.     FifrIP = 1;
  174.  
  175.     /*
  176.      * start shell for slave side
  177.      */
  178.  
  179.     while (notDone) {
  180.     long mask = Wait(imask | pmask);
  181.  
  182. top:
  183.     if (mask & imask) {
  184.         IMess *im;
  185.  
  186.         while (im = (IMess *)GetMsg(Win->UserPort)) {
  187.         switch(im->Class) {
  188.         case CLOSEWINDOW:
  189.             notDone = 0;
  190.             mask = 0;
  191.             break;
  192.         case NEWSIZE:
  193.             ConWriteStr("\017\233\164\233\165\233\166\233\167");
  194.             break;
  195.         }
  196.         ReplyMsg((Message *)im);
  197.         }
  198.     }
  199.     if (mask & pmask) {
  200.         Message *msg;
  201.         int n;
  202.  
  203.         while (msg = (Message *)GetMsg(IoSink)) {
  204.         if (msg == (Message *)&Iocr) {
  205.             IocrIP = 0;
  206.             if (Iocr.io_Actual > 0) {
  207.             switch(*(char *)Iocr.io_Data) {
  208.             case 3:
  209.                 SendBreak('C');
  210.                 break;
  211.             case 4:
  212.                 SendBreak('D');
  213.                 break;
  214.             case 5:
  215.                 SendBreak('E');
  216.                 break;
  217.             case 6:
  218.                 SendBreak('F');
  219.                 break;
  220.             default:
  221.                 n = WriteFifo(FifoW, Iocr.io_Data, Iocr.io_Actual);
  222.                 if (n != Iocr.io_Actual) {
  223.                 IocrHold = 1;
  224.                 if (FifwIP == 0) {
  225.                     RequestFifo(FifoW, &WMsg, FREQ_WAVAIL);
  226.                     FifwIP = 1;
  227.                 }
  228.                 }
  229.                 break;
  230.             }
  231.             }
  232.             if (IocrHold == 0) {
  233.             Iocr.io_Data = (APTR)ConBuf;
  234.             Iocr.io_Length = 1;
  235.             SendIO((IORequest *)&Iocr);
  236.             IocrIP = 1;
  237.             }
  238.         } else
  239.         if (msg == (Message *)&RMsg) {
  240.             char *ptr;
  241.             long n;
  242.  
  243.             FifrIP = 0;
  244.  
  245.             if ((n = ReadFifo(FifoR, &ptr, 0)) > 0) {
  246.             if (n > 256)                /*  limit size      */
  247.                 n = 256;
  248.             ConWrite(ptr, n);
  249.                             /*    clear N bytes    */
  250.             n = ReadFifo(FifoR, &ptr, n);
  251.             }
  252.             if (n < 0) {            /*  EOF */
  253.             ConWriteStr("REMOTE EOF!\n");
  254.             notDone = 0;
  255.             } else {
  256.             RequestFifo(FifoR, &RMsg, FREQ_RPEND);
  257.             FifrIP = 1;
  258.             }
  259.         } else
  260.         if (msg == (Message *)&WMsg) {
  261.             FifwIP = 0;
  262.             if (IocrHold) {                 /*  retry rd process */
  263.             ReplyMsg(&Iocr.io_Message);
  264.             IocrHold = 0;
  265.             }
  266.         }
  267.         goto top;
  268.         }
  269.     }
  270.     }
  271. }
  272.  
  273. void
  274. myexit()
  275. {
  276.     if (IocrIP) {
  277.     AbortIO((IORequest *)&Iocr);
  278.     WaitIO((IORequest *)&Iocr);
  279.     }
  280.     if (Iocr.io_Device)
  281.     CloseDevice((IORequest *)&Iocr);
  282.  
  283.     if (FifrIP) {
  284.     RequestFifo(FifoR, &RMsg, FREQ_ABORT);
  285.     WaitMsg(&RMsg);
  286.     }
  287.     if (FifwIP) {
  288.     RequestFifo(FifoW, &WMsg, FREQ_ABORT);
  289.     WaitMsg(&WMsg);
  290.     }
  291.     if (FifoR)
  292.     CloseFifo(FifoR, FIFOF_EOF);
  293.     if (FifoW)
  294.     CloseFifo(FifoW, FIFOF_EOF);
  295.     if (FifoBase)
  296.     CloseLibrary(FifoBase);
  297.     if (IntuitionBase)
  298.     CloseLibrary(IntuitionBase);
  299.  
  300.     if (Win)
  301.     CloseWindow(Win);
  302.     if (IoSink)
  303.     DeletePort(IoSink);
  304. }
  305.  
  306. void
  307. ConWriteStr(buf)
  308. char *buf;
  309. {
  310.     ConWrite(buf, strlen(buf));
  311. }
  312.  
  313. void
  314. ConWrite(buf, len)
  315. void *buf;
  316. {
  317.     Iocw.io_Data = (APTR)buf;
  318.     Iocw.io_Length = len;
  319.     DoIO((IORequest *)&Iocw);
  320. }
  321.  
  322. int
  323. brk()
  324. {
  325.     return(0);
  326. }
  327.  
  328. void
  329. WaitMsg(msg)
  330. Message *msg;
  331. {
  332.     while (msg->mn_Node.ln_Type == NT_MESSAGE)
  333.     Wait(1 << msg->mn_ReplyPort->mp_SigBit);
  334.     Forbid();
  335.     Remove(&msg->mn_Node);
  336.     Permit();
  337. }
  338.  
  339. void
  340. SendBreak(c)
  341. int c;
  342. {
  343.     char buf[256];
  344.     long fh;
  345.  
  346.     sprintf(buf, "FIFO:%s/%c", FifoName, c);
  347.     if (fh = Open(buf, 1005))
  348.     Close(fh);
  349. }
  350.  
  351.