home *** CD-ROM | disk | FTP | other *** search
/ WindowsWare 2 the Maxx / winmaxx.zip / winmaxx / WIN_NT / PSXRPC.ZIP / PSXAGENT.C < prev    next >
C/C++ Source or Header  |  1992-11-20  |  7KB  |  270 lines

  1. /*
  2.  
  3.   POSIX Agent Program
  4.  
  5.   (C) Copyright 1992
  6.  
  7.       By John Richardson
  8.       CompuServe 70541,672
  9.       Internet jr@sni-usa.com
  10.  
  11.       This program may be used freely provided that this copyright is
  12.       included in the source listings.
  13.  
  14.  
  15.   This program must be started by the WIN32SVR, with its STDIN and STDOUT
  16.   re-directed to pipes that the WIN32SVR monitors for RPC requests.
  17.  
  18.   This program creates a pair of POSIX named pipes and listens for service
  19.   requests for the WIN32 server that started this program. This program will
  20.   then pass the requests seen on the named pipes to the WIN32 server for
  21.   execution. The results will be read back from the WIN32 server and then
  22.   returned to the requesting POSIX process through the named pipe.
  23.  
  24.   The purpose of this program is to allow POSIX applications that have not
  25.   been started from the WIN32SVR and do not have their I/O re-directed to be
  26.   able to make requests of the WIN32 server.
  27.  
  28.   No changes are required of this module as a user adds new RPC request
  29.   types to the WIN32SVR and the PSXCLT programs. All information is
  30.   transparently forwarded by using standard size information in the RPC
  31.   headers.
  32.  
  33.   Warning: Can't use printf() without its output going across the
  34.        communications channel to the WIN32 server process.
  35.        fprintf(stderr, ...) also does not work because it appears
  36.        that stderr is connected to the pipe as well.
  37.  
  38.        opening /dev/tty appears equally hopeless....
  39.  
  40.            These bugs have been reported and acknowledged by Microsoft,
  41.            and currently have no fix.
  42.  
  43.            The logfile is created for debugging server problems as a work
  44.            around.
  45. */
  46. #include <unistd.h>
  47. #include <stdio.h>
  48. #include <sys/stat.h>
  49. #include <fcntl.h>
  50. #include <errno.h>
  51. #include <string.h>
  52. #include "win32psx.h"
  53.  
  54. int  ReadStream(char *buf, int size);
  55. int  WriteStream(char *buf, int size);
  56. int  ReadRequestStream(char *buf, int size);
  57. int  WriteRequestStream(char *buf, int size);
  58. void ServerLoop();
  59.  
  60. /* Hack until I can get some sort of console I/O while my
  61.    Stdin/Stdout is being re-directed.
  62.    Opening /dev/tty still points to the re-directed I/O stream
  63. */
  64. FILE *logfile;
  65. #define stderr logfile
  66.  
  67. extern int errno;
  68.  
  69. /*
  70.    Path where POSIX programs can acquire the named pipes
  71. */
  72.  
  73. int NamedPipeIn, NamedPipeOut;
  74. char InNameBuf[256], OutNameBuf[256];
  75.  
  76. void CreateNamedPipes()
  77. {
  78.   int ret;
  79.   
  80.   InNameBuf[0] = 0;
  81.   OutNameBuf[0] = 0;
  82.   strcat(InNameBuf, NAMED_PIPE_PATH);
  83.   strcat(OutNameBuf, NAMED_PIPE_PATH);
  84.   strcat(InNameBuf, "RPC_REQ");
  85.   strcat(OutNameBuf, "RPC_REP");
  86.  
  87.   ret = mkfifo(InNameBuf, O_RDWR);
  88.   if(ret == (-1))
  89.   {
  90.     if(errno != EEXIST)
  91.     {
  92.       fprintf(stderr,"Could not create FIFO, errno %d\n",errno);
  93.       exit(1);
  94.     }
  95. #ifdef DEBUG
  96.       fprintf(stderr,"Attached to existing FIFO\n");
  97.       fflush(stderr);
  98. #endif
  99.   }
  100.   ret = mkfifo(OutNameBuf, O_RDWR);
  101.   if(ret == (-1))
  102.   {
  103.     if(errno != EEXIST)
  104.     {
  105.       fprintf(stderr,"Could not create FIFO, errno %d\n",errno);
  106.       exit(1);
  107.     }
  108. #ifdef DEBUG
  109.       fprintf(stderr,"Attached to existing FIFO\n");
  110.       fflush(stderr);
  111. #endif
  112.   }
  113. }
  114.  
  115. /*
  116.   Open the named pipes.
  117.   This routine will block until a POSIX client opens the other end.
  118.  
  119.   In order to avoid deadlock, the request pipe is always opened first
  120.   by both the server and the client. If the server were to open the request
  121.   side and wait for the client, while the client opens the reply side, both
  122.   processes will block awaiting the completing open by the other side.
  123. */
  124.  
  125. void OpenNamedPipes()
  126. {
  127. #ifdef DEBUG
  128.   fprintf(stderr,"Waiting to open request pipe\n");
  129.   fflush(stderr);
  130. #endif
  131.   NamedPipeIn = open(InNameBuf, O_RDONLY, 0);
  132.   if(NamedPipeIn == (-1))
  133.   {
  134.     fprintf(stderr, "Can't open Named pipe, errno %d\n",errno);
  135.     exit(1);
  136.   }
  137. #ifdef DEBUG
  138.   fprintf(stderr,"Waiting to open reply pipe\n");
  139.   fflush(stderr);
  140. #endif
  141.   NamedPipeOut = open(OutNameBuf, O_WRONLY, 0);
  142.   if(NamedPipeOut == (-1))
  143.   {
  144.     fprintf(stderr, "Can't open Named pipe, errno %d\n",errno);
  145.     exit(1);
  146.   }
  147. }
  148.  
  149. /*
  150.    Close the named pipes
  151. */
  152. void CloseNamedPipes()
  153. {
  154.   close(NamedPipeIn);
  155.   close(NamedPipeOut);
  156. }
  157.  
  158.  
  159. main()
  160. {
  161.   logfile = fopen("LOGFILE", "w");
  162.   if(logfile == (FILE *)0)
  163.   {
  164.     fprintf(stderr, "Could not create LOGFILE\n");
  165.     exit(1);
  166.   }
  167.  
  168.   /* Create the named pipes */
  169.   CreateNamedPipes();
  170.  
  171.   /* Perform Server Loop */
  172.   ServerLoop();
  173.  
  174.   return(0);
  175. }
  176.  
  177. /* 
  178.    Loop getting requests from the WIN32_RPC_REQUEST named pipe and passing
  179.    them along to our Stdout. Read the replies from our Stdin and pass them
  180.    to the WIN32_RPC_REPLY named pipe.
  181.    Since we do not have select() or poll(), this program understands the
  182.    RPC request packet format so it knows when it has read all of the data
  183.    for a given request.
  184. */
  185. void ServerLoop()
  186. {
  187.   struct Request_Header Hd;
  188.   int ret, ret1, numxfer;
  189.   char buf[5120];
  190.  
  191.  /*
  192.     This top level loop executes for each POSIX client process that opens
  193.     up the named pipes, sends one or more requests, and then closes the
  194.     named pipes.
  195.  */
  196.  for(;;)
  197.  {
  198.    OpenNamedPipes();
  199.    /* This loop executes for each request by a given POSIX client process */
  200.    for(;;)
  201.    {
  202.      /* Get the request from the POSIX client and send it to the WIN32 server */
  203.      ret = read(NamedPipeIn, (char *)&Hd, sizeof(struct Request_Header));
  204.      if(ret == (-1))
  205.      {
  206.        fprintf(stderr,"POSIXAGENT: Error reading from REQ pipe errno %d\n",
  207.         errno);
  208.        exit(1);
  209.      }
  210.      else if(ret == 0)
  211.      {
  212.        break; /* EOF: Go to outer loop, close pipes, wait for next client */
  213.      }
  214.      numxfer = Hd.rh_size;
  215.      WriteStream((char *)&Hd, ret);
  216.      if(numxfer)
  217.      {
  218.        ret = read(NamedPipeIn, buf, numxfer);
  219.        WriteStream(buf, ret);
  220.      }
  221.  
  222.      /* Get the reply from the WIN32 server and return it to the POSIX client */
  223.      ret = ReadStream((char *)&Hd, sizeof(struct Request_Header));
  224.      numxfer = Hd.rh_size;
  225.      ret1 = write(NamedPipeOut, (char *)&Hd, sizeof(struct Request_Header));
  226.      if(ret1 == (-1))
  227.      {
  228.        fprintf(stderr,"POSIXAGENT: Error writing REP pipe, errno %d\n",errno);
  229.        exit(1);
  230.      }
  231.      if(numxfer)
  232.      {
  233.        ret = ReadStream(buf, numxfer);
  234.        ret1 = write(NamedPipeOut, buf, ret);
  235.      }
  236.    }
  237.    CloseNamedPipes();
  238.  }
  239. }
  240.  
  241. /*
  242.   read data from the communications stream
  243. */
  244. int ReadStream(char *buf, int size)
  245. {
  246.   int numxfer;
  247.  
  248.   if((numxfer = read(0, buf, size)) == (-1))
  249.   {
  250.     fprintf(stderr, "POSIXAGENT: Error reading Child Stdin, %d\n", errno);
  251.     exit(1);
  252.   }
  253.   return(numxfer);
  254. }
  255.  
  256. /*
  257.   write data to the communications stream
  258. */
  259. int WriteStream(char *buf, int size)
  260. {
  261.   int numxfer;
  262.  
  263.   if((numxfer = write(1, buf, size)) == (-1))
  264.   {
  265.     fprintf(stderr, "POSIXAGENT: Error writing Child Stdout, %d\n", errno);
  266.     exit(1);
  267.   }
  268.   return(numxfer);
  269. }
  270.