home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
util
/
libs
/
fifolib
/
remcli.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-03
|
7KB
|
351 lines
/*
* REMCLI.C
*
* REMCLI <fifo_name>
*
* PUBLIC DOMAIN CODE, sample code showing how to set up a remote CLI
* through the FIFO: device, using fifo.library to handle the master
* end.
*
* WARNING: ReadFifo() returns an EOF condition (-1) only once,
* calling it again will return 0 .. blocking until a
* writer writes something then closes again to generate
* another EOF.
*/
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <devices/conunit.h>
#include <hardware/cia.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <clib/intuition_protos.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fifo.h"
typedef unsigned char ubyte;
typedef unsigned short uword;
typedef unsigned long ulong;
typedef struct MsgPort MsgPort;
typedef struct Task Task;
typedef struct Process Process;
typedef struct Window Window;
typedef struct IOStdReq Ioc;
typedef struct Message Message;
typedef struct IntuiMessage IMess;
typedef struct IORequest IORequest;
Ioc Iocr;
Ioc Iocw;
Message RMsg;
Message WMsg;
Window *Win;
char *FifoName; /* fifo */
char *FifoSlav; /* fifo_s */
char *FifoMast; /* fifo_m */
MsgPort *IoSink;
char ConBuf[32];
void *FifoR;
void *FifoW;
void *FifoBase;
void *IntuitionBase;
char IocrIP; /* console read pending*/
char IocrHold;
char FifrIP; /* read msg pending */
char FifwIP; /* write msg pending */
struct NewWindow Nw = {
0, 0, 640, 200, -1, -1,
CLOSEWINDOW|MENUPICK|GADGETUP|GADGETDOWN|NEWSIZE,
WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|
NOCAREREFRESH|ACTIVATE,
NULL, NULL, (ubyte *)"RemCLI", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN
};
void ConWriteStr(char *);
void ConWrite(void *, long);
void SendBreak(int);
void myexit(void);
void WaitMsg(Message *);
int brk(void);
main(ac, av)
char **av;
{
long imask;
long pmask;
short notDone = 1;
if (ac == 1) {
fprintf(stderr, "Demonstration Remote Shell through FIFO:\n");
fprintf(stderr, "Instructions:\n");
fprintf(stderr, " 1> NewShell FIFO:name/rwkecs\n");
fprintf(stderr, " 1> RemCLI name\n");
exit(1);
}
atexit(myexit);
onbreak(brk);
FifoName = av[1];
FifoSlav = malloc(strlen(FifoName) + 16);
FifoMast = malloc(strlen(FifoName) + 16);
sprintf(FifoMast, "%s_m", FifoName);
sprintf(FifoSlav, "%s_s", FifoName);
IoSink = CreatePort(NULL, 0);
/*
* FIFOS
*/
FifoBase = OpenLibrary(FIFONAME, 0);
if (!FifoBase) {
fprintf(stderr, "unable to open %s\n", FIFONAME);
exit(1);
}
FifoW = OpenFifo(FifoMast, 2048, FIFOF_WRITE | FIFOF_NORMAL | FIFOF_NBIO);
if (FifoW == NULL) {
fprintf(stderr, "unable to open fifo %s\n", FifoMast);
exit(1);
}
FifoR = OpenFifo(FifoSlav, 2048, FIFOF_READ | FIFOF_NORMAL | FIFOF_NBIO);
if (FifoR == NULL) {
fprintf(stderr, "unable to open fifo %s\n", FifoSlav);
exit(1);
}
RMsg.mn_ReplyPort = IoSink;
WMsg.mn_ReplyPort = IoSink;
/*
* WINDOW
*/
IntuitionBase = OpenLibrary("intuition.library", 0);
if (!IntuitionBase) {
fprintf(stderr, "unable to open intuition.library\n");
exit(1);
}
Win = OpenWindow(&Nw);
if (Win == NULL) {
fprintf(stderr, "unable to open window!\n");
exit(1);
}
imask = 1 << Win->UserPort->mp_SigBit;
pmask = 1 << IoSink->mp_SigBit;
/*
* CONSOLE DEVICE
*/
Iocw.io_Message.mn_ReplyPort = IoSink;
Iocw.io_Data = (APTR)Win;
Iocw.io_Length = sizeof(*Win);
if (OpenDevice("console.device", 0, (IORequest *)&Iocw, 0)) {
fprintf(stderr, "can't open console!\n");
exit(1);
}
Iocr = Iocw;
Iocw.io_Command = CMD_WRITE;
Iocr.io_Command = CMD_READ;
Iocr.io_Data = (APTR)ConBuf;
Iocr.io_Length = 1;
SendIO((IORequest *)&Iocr);
IocrIP = 1;
/*
* start async FIFO requests
*/
RequestFifo(FifoR, &RMsg, FREQ_RPEND);
FifrIP = 1;
/*
* start shell for slave side
*/
while (notDone) {
long mask = Wait(imask | pmask);
top:
if (mask & imask) {
IMess *im;
while (im = (IMess *)GetMsg(Win->UserPort)) {
switch(im->Class) {
case CLOSEWINDOW:
notDone = 0;
mask = 0;
break;
case NEWSIZE:
ConWriteStr("\017\233\164\233\165\233\166\233\167");
break;
}
ReplyMsg((Message *)im);
}
}
if (mask & pmask) {
Message *msg;
int n;
while (msg = (Message *)GetMsg(IoSink)) {
if (msg == (Message *)&Iocr) {
IocrIP = 0;
if (Iocr.io_Actual > 0) {
switch(*(char *)Iocr.io_Data) {
case 3:
SendBreak('C');
break;
case 4:
SendBreak('D');
break;
case 5:
SendBreak('E');
break;
case 6:
SendBreak('F');
break;
default:
n = WriteFifo(FifoW, Iocr.io_Data, Iocr.io_Actual);
if (n != Iocr.io_Actual) {
IocrHold = 1;
if (FifwIP == 0) {
RequestFifo(FifoW, &WMsg, FREQ_WAVAIL);
FifwIP = 1;
}
}
break;
}
}
if (IocrHold == 0) {
Iocr.io_Data = (APTR)ConBuf;
Iocr.io_Length = 1;
SendIO((IORequest *)&Iocr);
IocrIP = 1;
}
} else
if (msg == (Message *)&RMsg) {
char *ptr;
long n;
FifrIP = 0;
if ((n = ReadFifo(FifoR, &ptr, 0)) > 0) {
if (n > 256) /* limit size */
n = 256;
ConWrite(ptr, n);
/* clear N bytes */
n = ReadFifo(FifoR, &ptr, n);
}
if (n < 0) { /* EOF */
ConWriteStr("REMOTE EOF!\n");
notDone = 0;
} else {
RequestFifo(FifoR, &RMsg, FREQ_RPEND);
FifrIP = 1;
}
} else
if (msg == (Message *)&WMsg) {
FifwIP = 0;
if (IocrHold) { /* retry rd process */
ReplyMsg(&Iocr.io_Message);
IocrHold = 0;
}
}
goto top;
}
}
}
}
void
myexit()
{
if (IocrIP) {
AbortIO((IORequest *)&Iocr);
WaitIO((IORequest *)&Iocr);
}
if (Iocr.io_Device)
CloseDevice((IORequest *)&Iocr);
if (FifrIP) {
RequestFifo(FifoR, &RMsg, FREQ_ABORT);
WaitMsg(&RMsg);
}
if (FifwIP) {
RequestFifo(FifoW, &WMsg, FREQ_ABORT);
WaitMsg(&WMsg);
}
if (FifoR)
CloseFifo(FifoR, FIFOF_EOF);
if (FifoW)
CloseFifo(FifoW, FIFOF_EOF);
if (FifoBase)
CloseLibrary(FifoBase);
if (IntuitionBase)
CloseLibrary(IntuitionBase);
if (Win)
CloseWindow(Win);
if (IoSink)
DeletePort(IoSink);
}
void
ConWriteStr(buf)
char *buf;
{
ConWrite(buf, strlen(buf));
}
void
ConWrite(buf, len)
void *buf;
{
Iocw.io_Data = (APTR)buf;
Iocw.io_Length = len;
DoIO((IORequest *)&Iocw);
}
int
brk()
{
return(0);
}
void
WaitMsg(msg)
Message *msg;
{
while (msg->mn_Node.ln_Type == NT_MESSAGE)
Wait(1 << msg->mn_ReplyPort->mp_SigBit);
Forbid();
Remove(&msg->mn_Node);
Permit();
}
void
SendBreak(c)
int c;
{
char buf[256];
long fh;
sprintf(buf, "FIFO:%s/%c", FifoName, c);
if (fh = Open(buf, 1005))
Close(fh);
}