home *** CD-ROM | disk | FTP | other *** search
- /*
-
- 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);
- }
-