home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
WindowsWare 2 the Maxx
/
winmaxx.zip
/
winmaxx
/
WIN_NT
/
PSXRPC.ZIP
/
PSXAGENT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-20
|
7KB
|
270 lines
/*
POSIX Agent Program
(C) Copyright 1992
By John Richardson
CompuServe 70541,672
Internet jr@sni-usa.com
This program may be used freely provided that this copyright is
included in the source listings.
This program must be started by the WIN32SVR, with its STDIN and STDOUT
re-directed to pipes that the WIN32SVR monitors for RPC requests.
This program creates a pair of POSIX named pipes and listens for service
requests for the WIN32 server that started this program. This program will
then pass the requests seen on the named pipes to the WIN32 server for
execution. The results will be read back from the WIN32 server and then
returned to the requesting POSIX process through the named pipe.
The purpose of this program is to allow POSIX applications that have not
been started from the WIN32SVR and do not have their I/O re-directed to be
able to make requests of the WIN32 server.
No changes are required of this module as a user adds new RPC request
types to the WIN32SVR and the PSXCLT programs. All information is
transparently forwarded by using standard size information in the RPC
headers.
Warning: Can't use printf() without its output going across the
communications channel to the WIN32 server process.
fprintf(stderr, ...) also does not work because it appears
that stderr is connected to the pipe as well.
opening /dev/tty appears equally hopeless....
These bugs have been reported and acknowledged by Microsoft,
and currently have no fix.
The logfile is created for debugging server problems as a work
around.
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "win32psx.h"
int ReadStream(char *buf, int size);
int WriteStream(char *buf, int size);
int ReadRequestStream(char *buf, int size);
int WriteRequestStream(char *buf, int size);
void ServerLoop();
/* Hack until I can get some sort of console I/O while my
Stdin/Stdout is being re-directed.
Opening /dev/tty still points to the re-directed I/O stream
*/
FILE *logfile;
#define stderr logfile
extern int errno;
/*
Path where POSIX programs can acquire the named pipes
*/
int NamedPipeIn, NamedPipeOut;
char InNameBuf[256], OutNameBuf[256];
void CreateNamedPipes()
{
int ret;
InNameBuf[0] = 0;
OutNameBuf[0] = 0;
strcat(InNameBuf, NAMED_PIPE_PATH);
strcat(OutNameBuf, NAMED_PIPE_PATH);
strcat(InNameBuf, "RPC_REQ");
strcat(OutNameBuf, "RPC_REP");
ret = mkfifo(InNameBuf, O_RDWR);
if(ret == (-1))
{
if(errno != EEXIST)
{
fprintf(stderr,"Could not create FIFO, errno %d\n",errno);
exit(1);
}
#ifdef DEBUG
fprintf(stderr,"Attached to existing FIFO\n");
fflush(stderr);
#endif
}
ret = mkfifo(OutNameBuf, O_RDWR);
if(ret == (-1))
{
if(errno != EEXIST)
{
fprintf(stderr,"Could not create FIFO, errno %d\n",errno);
exit(1);
}
#ifdef DEBUG
fprintf(stderr,"Attached to existing FIFO\n");
fflush(stderr);
#endif
}
}
/*
Open the named pipes.
This routine will block until a POSIX client opens the other end.
In order to avoid deadlock, the request pipe is always opened first
by both the server and the client. If the server were to open the request
side and wait for the client, while the client opens the reply side, both
processes will block awaiting the completing open by the other side.
*/
void OpenNamedPipes()
{
#ifdef DEBUG
fprintf(stderr,"Waiting to open request pipe\n");
fflush(stderr);
#endif
NamedPipeIn = open(InNameBuf, O_RDONLY, 0);
if(NamedPipeIn == (-1))
{
fprintf(stderr, "Can't open Named pipe, errno %d\n",errno);
exit(1);
}
#ifdef DEBUG
fprintf(stderr,"Waiting to open reply pipe\n");
fflush(stderr);
#endif
NamedPipeOut = open(OutNameBuf, O_WRONLY, 0);
if(NamedPipeOut == (-1))
{
fprintf(stderr, "Can't open Named pipe, errno %d\n",errno);
exit(1);
}
}
/*
Close the named pipes
*/
void CloseNamedPipes()
{
close(NamedPipeIn);
close(NamedPipeOut);
}
main()
{
logfile = fopen("LOGFILE", "w");
if(logfile == (FILE *)0)
{
fprintf(stderr, "Could not create LOGFILE\n");
exit(1);
}
/* Create the named pipes */
CreateNamedPipes();
/* Perform Server Loop */
ServerLoop();
return(0);
}
/*
Loop getting requests from the WIN32_RPC_REQUEST named pipe and passing
them along to our Stdout. Read the replies from our Stdin and pass them
to the WIN32_RPC_REPLY named pipe.
Since we do not have select() or poll(), this program understands the
RPC request packet format so it knows when it has read all of the data
for a given request.
*/
void ServerLoop()
{
struct Request_Header Hd;
int ret, ret1, numxfer;
char buf[5120];
/*
This top level loop executes for each POSIX client process that opens
up the named pipes, sends one or more requests, and then closes the
named pipes.
*/
for(;;)
{
OpenNamedPipes();
/* This loop executes for each request by a given POSIX client process */
for(;;)
{
/* Get the request from the POSIX client and send it to the WIN32 server */
ret = read(NamedPipeIn, (char *)&Hd, sizeof(struct Request_Header));
if(ret == (-1))
{
fprintf(stderr,"POSIXAGENT: Error reading from REQ pipe errno %d\n",
errno);
exit(1);
}
else if(ret == 0)
{
break; /* EOF: Go to outer loop, close pipes, wait for next client */
}
numxfer = Hd.rh_size;
WriteStream((char *)&Hd, ret);
if(numxfer)
{
ret = read(NamedPipeIn, buf, numxfer);
WriteStream(buf, ret);
}
/* Get the reply from the WIN32 server and return it to the POSIX client */
ret = ReadStream((char *)&Hd, sizeof(struct Request_Header));
numxfer = Hd.rh_size;
ret1 = write(NamedPipeOut, (char *)&Hd, sizeof(struct Request_Header));
if(ret1 == (-1))
{
fprintf(stderr,"POSIXAGENT: Error writing REP pipe, errno %d\n",errno);
exit(1);
}
if(numxfer)
{
ret = ReadStream(buf, numxfer);
ret1 = write(NamedPipeOut, buf, ret);
}
}
CloseNamedPipes();
}
}
/*
read data from the communications stream
*/
int ReadStream(char *buf, int size)
{
int numxfer;
if((numxfer = read(0, buf, size)) == (-1))
{
fprintf(stderr, "POSIXAGENT: Error reading Child Stdin, %d\n", errno);
exit(1);
}
return(numxfer);
}
/*
write data to the communications stream
*/
int WriteStream(char *buf, int size)
{
int numxfer;
if((numxfer = write(1, buf, size)) == (-1))
{
fprintf(stderr, "POSIXAGENT: Error writing Child Stdout, %d\n", errno);
exit(1);
}
return(numxfer);
}