home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / misc / fifolib38_1.lha / remcli.c < prev    next >
C/C++ Source or Header  |  1995-12-20  |  8KB  |  387 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.  *        Huh? Clearing FIFOF_EOF is commented out in fifo.c so
  16.  *        that EOF is reported every time.  See TODO (Jörg Höhle)
  17.  */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/io.h>
  21. #include <exec/memory.h>
  22. #include <devices/conunit.h>
  23. #include <intuition/intuition.h>
  24. #include <libraries/dos.h>
  25. #include <libraries/fifo.h>
  26. #if defined(_DCC) /*  at least the very old DICE 2.06 */
  27. #include <clib/exec_protos.h>
  28. #include <clib/dos_protos.h>
  29. #include <clib/intuition_protos.h>
  30. #else
  31. #include <proto/exec.h>
  32. #include <proto/dos.h>
  33. #include <proto/intuition.h>
  34. #endif
  35. #include <clib/alib_protos.h>
  36. #include <proto/fifo.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <fcntl.h>        /*  write() */
  41. #if defined(__GNUC__)
  42. #include <unistd.h>        /*  write() */
  43. #endif
  44. #ifdef USE_SIGNAL
  45. #include <signal.h>
  46. #endif
  47.  
  48. typedef unsigned char    ubyte;
  49. typedef unsigned short    uword;
  50. typedef unsigned long    ulong;
  51. typedef struct MsgPort        MsgPort;
  52.  
  53. typedef struct Task        Task;
  54. typedef struct Process        Process;
  55. typedef struct Window        Window;
  56. typedef struct IOStdReq     Ioc;
  57. typedef struct Message        Message;
  58. typedef struct IntuiMessage IMess;
  59. typedef struct IORequest    IORequest;
  60.  
  61. Ioc    Iocr;
  62. Ioc    Iocw;
  63. Message RMsg;
  64. Message WMsg;
  65. Window    *Win;
  66. char    *FifoName;    /*  fifo    */
  67. char    *FifoSlav;    /*  fifo_s  */
  68. char    *FifoMast;    /*  fifo_m  */
  69. char    *ErrBuf;
  70. MsgPort *IoSink;
  71. char    ConBuf[32];
  72. void    *FifoR;
  73. void    *FifoW;
  74. struct Library *FifoBase;
  75. struct IntuitionBase *IntuitionBase;
  76.  
  77. char    IocrIP;     /*  console read pending*/
  78. char    IocrHold;
  79. char    FifrIP;     /*  read msg pending    */
  80. char    FifwIP;     /*  write msg pending    */
  81.  
  82. struct NewWindow Nw = {
  83.     0, 0, 640, 200, -1, -1,
  84.     CLOSEWINDOW|MENUPICK|GADGETUP|GADGETDOWN|NEWSIZE,
  85.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|
  86.     NOCAREREFRESH|ACTIVATE,
  87.     NULL, NULL, (ubyte *)"RemCLI", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN
  88. };
  89.  
  90. const char verstring[] = "\0$VER: RemCLI 38.1 (20.12.95)\r\n";
  91.  
  92. #define errline(s,len) write(2, s, len)
  93. #define errmsg(s) errline(s, sizeof(s)-1)
  94. #define errmsg1(s,v) {int errlen = sprintf(ErrBuf, s, v); errline(ErrBuf, errlen);}
  95.  
  96. void ConWriteStr(char *);
  97. void ConWrite(void *, long);
  98. void SendBreak(int);
  99. void myexit(void);
  100. void WaitMsg(Message *);
  101. #ifndef USE_SIGNAL
  102. #ifdef _DCC
  103. int  brk(void);
  104. #endif
  105. #if defined(__GNUC__)        /*  actually libnix only */
  106. void __chkabort(void);
  107. #endif
  108. #endif
  109.  
  110. int main(int ac, char **av)
  111. {
  112.     long imask;
  113.     long pmask;
  114.     short notDone = 1;
  115.  
  116.     if (ac != 2) {
  117.     errmsg("Demonstration Remote Shell through FIFO:\n");
  118.     errmsg("Instructions:\n");
  119.     errmsg("  1> NewShell FIFO:name/rwkecs\n");
  120.     errmsg("  1> Run >NIL: RemCLI name\n");
  121.     exit(1);
  122.     }
  123.     atexit(myexit);
  124. #ifndef USE_SIGNAL
  125. #ifdef _DCC
  126.     onbreak(brk);        /*  onbreak() generates shorter code than signal() */
  127. #endif
  128. #else
  129.     signal(SIGINT, SIG_IGN);
  130. #endif
  131.  
  132.     FifoName = av[1];
  133.     {
  134.     int len  = strlen(FifoName);
  135.  
  136.     FifoSlav = malloc(len + (len<<1) + (3 + 3 + 35));
  137.     FifoMast = FifoSlav + len + 3;
  138.     ErrBuf   = FifoMast + len + 3;
  139.     }
  140.     sprintf(FifoMast, "%s_m", FifoName);
  141.     sprintf(FifoSlav, "%s_s", FifoName);
  142.  
  143.     IoSink = CreatePort(NULL, 0);
  144.  
  145.     /*
  146.      *    FIFOS
  147.      */
  148.  
  149.     FifoBase = OpenLibrary(FIFONAME, 0);
  150.     if (!FifoBase) {
  151.     errmsg1("unable to open %s\n", FIFONAME);
  152.     exit(1);
  153.     }
  154.     FifoW = OpenFifo(FifoMast, 2048, FIFOF_WRITE | FIFOF_NORMAL | FIFOF_NBIO);
  155.     if (FifoW == NULL) {
  156.     errmsg1("unable to open fifo %s\n", FifoMast);
  157.     exit(1);
  158.     }
  159.     FifoR = OpenFifo(FifoSlav, 2048, FIFOF_READ  | FIFOF_NORMAL | FIFOF_NBIO);
  160.     if (FifoR == NULL) {
  161.     errmsg1("unable to open fifo %s\n", FifoSlav);
  162.     exit(1);
  163.     }
  164.     RMsg.mn_ReplyPort = IoSink;
  165.     WMsg.mn_ReplyPort = IoSink;
  166.  
  167.     /*
  168.      *    WINDOW
  169.      */
  170.  
  171.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  172.     if (!IntuitionBase) {
  173.     errmsg("unable to open intuition.library\n");
  174.     exit(1);
  175.     }
  176.  
  177.     Win = OpenWindow(&Nw);
  178.     if (Win == NULL) {
  179.     errmsg("unable to open window!\n");
  180.     exit(1);
  181.     }
  182.     imask = 1 << Win->UserPort->mp_SigBit;
  183.     pmask = 1 << IoSink->mp_SigBit;
  184.  
  185.     /*
  186.      *    CONSOLE DEVICE
  187.      */
  188.  
  189.     Iocw.io_Message.mn_ReplyPort = IoSink;
  190.     Iocw.io_Data = (APTR)Win;
  191.     Iocw.io_Length = sizeof(*Win);
  192.     if (OpenDevice("console.device", 0, (IORequest *)&Iocw, 0)) {
  193.     errmsg("can't open console!\n");
  194.     exit(1);
  195.     }
  196.     Iocr = Iocw;
  197.     Iocw.io_Command = CMD_WRITE;
  198.     Iocr.io_Command = CMD_READ;
  199.  
  200.     Iocr.io_Data = (APTR)ConBuf;
  201.     Iocr.io_Length = 1;
  202.     SendIO((IORequest *)&Iocr);
  203.     IocrIP = 1;
  204.  
  205.     /*
  206.      *    start async FIFO requests
  207.      */
  208.  
  209.     RequestFifo(FifoR, &RMsg, FREQ_RPEND);
  210.     FifrIP = 1;
  211.  
  212.     /*
  213.      * start shell for slave side
  214.      */
  215.  
  216.     while (notDone) {
  217.     long mask = Wait(imask | pmask);
  218.  
  219. top:
  220.     if (mask & imask) {
  221.         IMess *im;
  222.  
  223.         while ((im = (IMess *)GetMsg(Win->UserPort))) {
  224.         switch(im->Class) {
  225.         case CLOSEWINDOW:
  226.             notDone = 0;
  227.             mask = 0;
  228.             break;
  229.         case NEWSIZE:
  230.             ConWriteStr("\017\233\164\233\165\233\166\233\167");
  231.             break;
  232.         }
  233.         ReplyMsg((Message *)im);
  234.         }
  235.     }
  236.     if (mask & pmask) {
  237.         Message *msg;
  238.         int n;
  239.  
  240.         while ((msg = (Message *)GetMsg(IoSink))) {
  241.         if (msg == (Message *)&Iocr) {
  242.             IocrIP = 0;
  243.             if (Iocr.io_Actual > 0) {
  244.             switch(*(char *)Iocr.io_Data) {
  245.             case 3:
  246.                 SendBreak('C');
  247.                 break;
  248.             case 4:
  249.                 SendBreak('D');
  250.                 break;
  251.             case 5:
  252.                 SendBreak('E');
  253.                 break;
  254.             case 6:
  255.                 SendBreak('F');
  256.                 break;
  257.             default:
  258.                 n = WriteFifo(FifoW, Iocr.io_Data, Iocr.io_Actual);
  259.                 if (n != Iocr.io_Actual) {
  260.                 IocrHold = 1;
  261.                 if (FifwIP == 0) {
  262.                     RequestFifo(FifoW, &WMsg, FREQ_WAVAIL);
  263.                     FifwIP = 1;
  264.                 }
  265.                 }
  266.                 break;
  267.             }
  268.             }
  269.             if (IocrHold == 0) {
  270.             Iocr.io_Data = (APTR)ConBuf;
  271.             Iocr.io_Length = 1;
  272.             SendIO((IORequest *)&Iocr);
  273.             IocrIP = 1;
  274.             }
  275.         } else
  276.         if (msg == (Message *)&RMsg) {
  277.             char *ptr;
  278.             long n;
  279.  
  280.             FifrIP = 0;
  281.  
  282.             if ((n = ReadFifo(FifoR, &ptr, 0)) > 0) {
  283.             if (n > 256)                /*  limit size      */
  284.                 n = 256;
  285.             ConWrite(ptr, n);
  286.                             /*    clear N bytes    */
  287.             n = ReadFifo(FifoR, &ptr, n);
  288.             }
  289.             if (n < 0) {            /*  EOF */
  290.             ConWriteStr("REMOTE EOF!\n");
  291.             notDone = 0;
  292.             } else {
  293.             RequestFifo(FifoR, &RMsg, FREQ_RPEND);
  294.             FifrIP = 1;
  295.             }
  296.         } else
  297.         if (msg == (Message *)&WMsg) {
  298.             FifwIP = 0;
  299.             if (IocrHold) {                 /*  retry rd process */
  300.             ReplyMsg(&Iocr.io_Message);
  301.             IocrHold = 0;
  302.             }
  303.         }
  304.         goto top;
  305.         }
  306.     }
  307.     }
  308. }
  309.  
  310. void myexit(void)
  311. {
  312.     if (IocrIP) {
  313.     AbortIO((IORequest *)&Iocr);
  314.     WaitIO((IORequest *)&Iocr);
  315.     }
  316.     if (Iocr.io_Device)
  317.     CloseDevice((IORequest *)&Iocr);
  318.  
  319.     if (FifrIP) {
  320.     RequestFifo(FifoR, &RMsg, FREQ_ABORT);
  321.     WaitMsg(&RMsg);
  322.     }
  323.     if (FifwIP) {
  324.     RequestFifo(FifoW, &WMsg, FREQ_ABORT);
  325.     WaitMsg(&WMsg);
  326.     }
  327.     if (FifoR)
  328.     CloseFifo(FifoR, FIFOF_EOF);
  329.     if (FifoW)
  330.     CloseFifo(FifoW, FIFOF_EOF);
  331.     if (FifoBase)
  332.     CloseLibrary(FifoBase);
  333.     if (IntuitionBase)
  334.     CloseLibrary((struct Library *)IntuitionBase);
  335.  
  336.     if (Win)
  337.     CloseWindow(Win);
  338.     if (IoSink)
  339.     DeletePort(IoSink);
  340. }
  341.  
  342. void ConWriteStr(char *buf)
  343. {
  344.     ConWrite(buf, strlen(buf));
  345. }
  346.  
  347. void ConWrite(void *buf, long len)
  348. {
  349.     Iocw.io_Data = (APTR)buf;
  350.     Iocw.io_Length = len;
  351.     DoIO((IORequest *)&Iocw);
  352. }
  353.  
  354. #ifndef USE_SIGNAL
  355. #ifdef _DCC
  356. int brk(void)
  357. {
  358.     return(0);            /*  ignore ^C */
  359. }
  360. #endif
  361. #if defined(__GNUC__)        /*  libnix internal function */
  362. void __chkabort(void)
  363. {
  364. }
  365. #endif
  366. #endif
  367.  
  368. void WaitMsg(Message *msg)
  369. {
  370.     while (msg->mn_Node.ln_Type == NT_MESSAGE)
  371.     Wait(1 << msg->mn_ReplyPort->mp_SigBit);
  372.     Forbid();
  373.     Remove(&msg->mn_Node);
  374.     Permit();
  375. }
  376.  
  377. void SendBreak(int c)
  378. {
  379.     char buf[256];
  380.     long fh;
  381.  
  382.     sprintf(buf, "FIFO:%s/%c", FifoName, c);
  383.     if ((fh = Open(buf, 1005)))
  384.     Close(fh);
  385. }
  386.  
  387.