Пример #1
0
int iswrite(const char UUFAR *data, unsigned int len)
{
   unsigned int i;
   union REGS xmtregs;

   ShowModem();

/*--------------------------------------------------------------------*/
/*       For an INT14 interface, just spit the data bytes out one     */
/*       at a time.                                                   */
/*--------------------------------------------------------------------*/

   xmtregs.h.ah = FS_XMIT1;
   xmtregs.x.dx = portNum;              /* Port number */
   xmtregs.x.bx = 0;

   for (i = 0; i < len; i++)
   {
      union REGS outregs;

      xmtregs.h.al = (unsigned char) data[i];

      int86(0x14, &xmtregs, &outregs);

#if 1 /* Richard H. Gumpertz ([email protected]), 29 September 1993 */
      if (((outregs.h.ah & 0x61) == 0x01)
          && (commBufferUsed < commBufferLength))
         isread(NULL, commBufferLength, 0); /* do some read ahead */
#endif /* RHG */
   }

   traceData( data, len, KWTrue );

/*--------------------------------------------------------------------*/
/*              Return byte count transmitted to caller               */
/*--------------------------------------------------------------------*/

   return len;

} /* iswrite */
Пример #2
0
int nswrite(const char UUFAR *input, unsigned int len)
{

   char UUFAR *data = (char UUFAR *) input;

#ifdef __OS2__
    ULONG bytes;
#else
   size_t bytes;
#endif

   APIRET rc;

   hangupNeeded = KWTrue;     /* Flag that the port is now dirty  */

/*--------------------------------------------------------------------*/
/*         Write the data out as the queue becomes available          */
/*--------------------------------------------------------------------*/

   rc = DosWrite( commHandle, data , len, &bytes);
   if (rc)
   {
      printOS2error( "DosWrite", rc );
      return bytes;
   } /*if */

/*--------------------------------------------------------------------*/
/*                        Log the data written                        */
/*--------------------------------------------------------------------*/

   traceData( data, len, KWTrue);

/*--------------------------------------------------------------------*/
/*            Return bytes written to the port to the caller          */
/*--------------------------------------------------------------------*/

   return len;

} /* nswrite */
Пример #3
0
static void readFromCgi(Cgi *cgi, int channel)
{
    HttpConn    *conn;
    HttpPacket  *packet;
    HttpTx      *tx;
    HttpQueue   *q, *writeq;
    MprCmd      *cmd;
    ssize       nbytes;
    int         err;

    cmd = cgi->cmd;
    conn = cgi->conn;
    tx = conn->tx;
    q = cgi->readq;
    writeq = conn->writeq;
    assert(conn->sock);
    assert(conn->state > HTTP_STATE_BEGIN);

    if (tx->finalized) {
        mprCloseCmdFd(cmd, channel);
    }
    while (mprGetCmdFd(cmd, channel) >= 0 && !tx->finalized && writeq->count < writeq->max) {
        if ((packet = cgi->headers) != 0) {
            if (mprGetBufSpace(packet->content) < ME_MAX_BUFFER && mprGrowBuf(packet->content, ME_MAX_BUFFER) < 0) {
                break;
            }
        } else if ((packet = httpCreateDataPacket(ME_MAX_BUFFER)) == 0) {
            break;
        }
        nbytes = mprReadCmd(cmd, channel, mprGetBufEnd(packet->content), ME_MAX_BUFFER);
        if (nbytes < 0) {
            err = mprGetError();
            if (err == EINTR) {
                continue;
            } else if (err == EAGAIN || err == EWOULDBLOCK) {
                break;
            }
            mprCloseCmdFd(cmd, channel);
            break;
            
        } else if (nbytes == 0) {
            mprCloseCmdFd(cmd, channel);
            break;

        } else {
            traceData(cmd, mprGetBufEnd(packet->content), nbytes);
            mprAdjustBufEnd(packet->content, nbytes);
        }
        if (channel == MPR_CMD_STDERR) {
            mprLog("error cgi", 0, "CGI failed uri=\"%s\", details: %s", conn->rx->uri, mprGetBufStart(packet->content));
            httpSetStatus(conn, HTTP_CODE_SERVICE_UNAVAILABLE);
            cgi->seenHeader = 1;
        }
        if (!cgi->seenHeader) {
            if (!parseCgiHeaders(cgi, packet)) {
                cgi->headers = packet;
                return;
            }
            cgi->headers = 0;
            cgi->seenHeader = 1;
        } 
        if (!tx->finalizedOutput && httpGetPacketLength(packet) > 0) {
            /* Put the data to the CGI readq, then cgiToBrowserService will take care of it */
            httpPutPacket(q, packet);
        }
    }
}
Пример #4
0
unsigned int nsread(char UUFAR *output, unsigned int wanted, unsigned int timeout)
{
   APIRET rc;
   time_t stop_time ;
   time_t now ;
   USHORT com_error;

   KWBoolean firstPass = ( currentSpeed > 2400 ) && ( wanted == 1 );
                              /* Perform extended read only on high-
                                 speed modem links when looking for
                                 packet data                         */

#ifdef __OS2__
   ULONG ParmLengthInOut;
   ULONG DataLengthInOut;
#endif

/*--------------------------------------------------------------------*/
/*                           Validate input                           */
/*--------------------------------------------------------------------*/

   if ( wanted > commBufferLength )
   {
      printmsg(0,"nsread: Overlength read, wanted %u bytes into %u buffer!",
                     (unsigned int) wanted,
                     (unsigned int) commBufferLength );
      panic();
   }

/*--------------------------------------------------------------------*/
/*           Determine if our internal buffer has the data            */
/*--------------------------------------------------------------------*/

   if (commBufferUsed >= wanted)
   {
      MEMCPY( output, commBuffer, wanted );
      commBufferUsed -= wanted;
      if ( commBufferUsed )   /* Any data left over?                 */
         MEMMOVE( commBuffer, commBuffer + wanted, commBufferUsed );
                              /* Yes --> Save it                     */
      return wanted + commBufferUsed;
   } /* if */

/*--------------------------------------------------------------------*/
/*            Reset any errors on the communications port             */
/*--------------------------------------------------------------------*/

#ifdef __OS2__

   ParmLengthInOut = 0;
   DataLengthInOut = sizeof(com_error);
   rc = DosDevIOCtl( commHandle,
                     IOCTL_ASYNC,
                     ASYNC_GETCOMMERROR,
                     NULL,
                     0L,
                     &ParmLengthInOut,
                     (PVOID) &com_error,
                     sizeof(com_error),
                     &DataLengthInOut);

#else

   rc = DosDevIOCtl( &com_error,
                     FAR_NULL,
                     ASYNC_GETCOMMERROR ,
                     IOCTL_ASYNC,
                     commHandle);

#endif

   if (rc )
   {
      printOS2error( "ASYNC_GETCOMMERROR", rc );
   } /*if */
   else if ( com_error )
      ShowError( com_error );

/*--------------------------------------------------------------------*/
/*                 Determine when to stop processing                  */
/*--------------------------------------------------------------------*/

   if ( timeout == 0 )
   {
      stop_time = 0;
      now = 1;                /* Any number greater than stop time   */
   }
   else {
      time( & now );
      stop_time = now + timeout;
   }

/*--------------------------------------------------------------------*/
/*            Try to read any needed data into the buffer             */
/*--------------------------------------------------------------------*/

   do {
      USHORT needed =  (USHORT) wanted - commBufferUsed;

      USHORT portTimeout;

#ifdef __OS2__
      ULONG received = 0;
#else
      USHORT received = 0;
#endif

/*--------------------------------------------------------------------*/
/*                     Handle an aborted program                      */
/*--------------------------------------------------------------------*/

      if ( raised )
         return 0;

      if ( terminate_processing )
      {
         static KWBoolean recurse = KWFalse;
         if ( ! recurse )
         {
            printmsg(2,"nsread: User aborted processing");
            recurse = KWTrue;
         }
         return 0;
      }

/*--------------------------------------------------------------------*/
/*           Compute a new timeout for the read, if needed            */
/*--------------------------------------------------------------------*/

      if ((stop_time <= now ) || firstPass )
      {
         portTimeout = 0;
         firstPass = KWFalse;
      }
      else {

         if ( ((stop_time - now) / needed) > (USHRT_MAX / 100 ))
            portTimeout = USHRT_MAX;
         else
            portTimeout = (USHORT) (stop_time - now) / needed * 100;

         if (portTimeout < 100)
            portTimeout = 100;

      } /* else */

      if ( portTimeout != com_dcbinfo.usReadTimeout )
      {
         com_dcbinfo.usReadTimeout = portTimeout;

#ifdef __OS2__

         ParmLengthInOut = sizeof(com_dcbinfo);
         DataLengthInOut = 0;
         rc = DosDevIOCtl( commHandle,
                           IOCTL_ASYNC,
                           ASYNC_SETDCBINFO,
                           (PVOID) &com_dcbinfo,
                           sizeof(com_dcbinfo),
                           &ParmLengthInOut,
                           NULL,
                           0L,
                           &DataLengthInOut);

#else

         rc = DosDevIOCtl(FAR_NULL,
                          &com_dcbinfo,
                          ASYNC_SETDCBINFO,
                          IOCTL_ASYNC,
                          commHandle);

#endif
         if ( rc )
         {
            printOS2error( "ASYNC_SETDCBINFO", rc );
            panic();
         } /* if */
      } /* if */

#ifdef UDEBUG
      printmsg(15,"nsread: Port time out is %ud seconds/100",
               portTimeout);
#endif

/*--------------------------------------------------------------------*/
/*                 Read the data from the serial port                 */
/*--------------------------------------------------------------------*/

      rc = DosRead( commHandle,
                    commBuffer + commBufferUsed,
                    portTimeout ? needed : commBufferLength - commBufferUsed,
                    &received );

      if ( rc == ERROR_INTERRUPT)
      {
         printmsg(2,"Read Interrupted");
         return 0;
      }
      else if ( rc != 0 )
      {
         printmsg(0,"nsread: Read from comm port for %d bytes failed.",
                  needed);
         printOS2error( "DosRead", rc );
         commBufferUsed = 0;
         return 0;
      }

#ifdef UDEBUG
      printmsg(15,"nsread: Want %d characters, received %d, total %d in buffer",
                  (int) wanted,
                  (int) received,
                  (int) commBufferUsed + received);
#endif

/*--------------------------------------------------------------------*/
/*                    Log the newly received data                     */
/*--------------------------------------------------------------------*/

      traceData( commBuffer + commBufferUsed, (unsigned) received, KWFalse );

/*--------------------------------------------------------------------*/
/*            If we got the data, return it to the caller             */
/*--------------------------------------------------------------------*/

      commBufferUsed += received;
      if ( commBufferUsed >= wanted )
      {
         MEMCPY( output, commBuffer, wanted );
         commBufferUsed -= wanted;
         if ( commBufferUsed )   /* Any data left over?              */
            MEMMOVE( commBuffer, commBuffer + wanted, commBufferUsed );

         return wanted;

      } /* if */

/*--------------------------------------------------------------------*/
/*                 Update the clock for the next pass                 */
/*--------------------------------------------------------------------*/

      if (stop_time > 0)
         time( &now );

   } while (stop_time > now);

/*--------------------------------------------------------------------*/
/*         We don't have enough data; report what we do have          */
/*--------------------------------------------------------------------*/

   return commBufferUsed;

} /*nsread*/
Пример #5
0
static void cgiEvent(MaQueue *q, MprCmd *cmd, int channel)
{
    MaConn      *conn;
    MaResponse  *resp;
    MprBuf      *buf;
    int         space, nbytes, err;

    mprLog(cmd, 6, "CGI callback channel %d", channel);
    
    buf = 0;
    conn = q->conn;
    resp = conn->response;
    mprAssert(resp);

    cmd->lastActivity = mprGetTime(cmd);

    switch (channel) {
    case MPR_CMD_STDIN:
        writeToCGI(q->pair);
        return;

    case MPR_CMD_STDOUT:
        buf = cmd->stdoutBuf;
        break;

    case MPR_CMD_STDERR:
        buf = cmd->stderrBuf;
        break;
    }
    mprAssert(buf);
    mprResetBufIfEmpty(buf);

    /*
        Come here for CGI stdout, stderr events. ie. reading data from the CGI program.
     */
    while (mprGetCmdFd(cmd, channel) >= 0) {
        /*
            Read as much data from the CGI as possible
         */
        do {
            if ((space = mprGetBufSpace(buf)) == 0) {
                mprGrowBuf(buf, MA_BUFSIZE);
                if ((space = mprGetBufSpace(buf)) == 0) {
                    break;
                }
            }
            nbytes = mprReadCmdPipe(cmd, channel, mprGetBufEnd(buf), space);
            mprLog(q, 5, "CGI: read from gateway %d on channel %d. errno %d", nbytes, channel, 
                    nbytes >= 0 ? 0 : mprGetOsError());
            if (nbytes < 0) {
                err = mprGetError();
                if (err == EINTR) {
                    continue;
                } else if (err == EAGAIN || err == EWOULDBLOCK) {
                    break;
                }
                mprLog(cmd, 5, "CGI read error %d for %", mprGetError(), (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr");
                mprCloseCmdFd(cmd, channel);
                
            } else if (nbytes == 0) {
                /*
                    This may reap the terminated child and thus clear cmd->process if both stderr and stdout are closed.
                 */
                mprLog(cmd, 5, "CGI EOF for %s", (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr");
                mprCloseCmdFd(cmd, channel);
                break;

            } else {
                mprLog(cmd, 5, "CGI read %d bytes from %s", nbytes, (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr");
                mprAdjustBufEnd(buf, nbytes);
                traceData(cmd, mprGetBufStart(buf), nbytes);
            }
        } while ((space = mprGetBufSpace(buf)) > 0);

        if (mprGetBufLength(buf) == 0) {
            return;
        }
        if (channel == MPR_CMD_STDERR) {
            /*
                If we have an error message, send that to the client
             */
            if (mprGetBufLength(buf) > 0) {
                mprAddNullToBuf(buf);
                mprLog(conn, 4, mprGetBufStart(buf));
                if (writeToClient(q, cmd, buf, channel) < 0) {
                    return;
                }
                maSetResponseCode(conn, MPR_HTTP_CODE_SERVICE_UNAVAILABLE);
                cmd->userFlags |= MA_CGI_SEEN_HEADER;
                cmd->status = 0;
            }
        } else {
            if (!(cmd->userFlags & MA_CGI_SEEN_HEADER) && !parseHeader(conn, cmd)) {
                return;
            } 
            if (cmd->userFlags & MA_CGI_SEEN_HEADER) {
                if (writeToClient(q, cmd, buf, channel) < 0) {
                    return;
                }
            }
        }
    }
}
Пример #6
0
static void readFromCgi(Cgi *cgi, int channel)
{
    HttpConn    *conn;
    HttpPacket  *packet;
    HttpTx      *tx;
    HttpQueue   *q, *writeq;
    MprCmd      *cmd;
    ssize       nbytes;
    int         err;

    cmd = cgi->cmd;
    conn = cgi->conn;
    tx = conn->tx;
    q = cgi->readq;
    writeq = conn->writeq;
    assert(conn->sock);
    assert(conn->state > HTTP_STATE_BEGIN);

    if (tx->finalized) {
        mprCloseCmdFd(cmd, channel);
    }
    while (mprGetCmdFd(cmd, channel) >= 0 && !tx->finalized && writeq->count < writeq->max) {
        if ((packet = cgi->headers) != 0) {
            if (mprGetBufSpace(packet->content) < ME_MAX_BUFFER && mprGrowBuf(packet->content, ME_MAX_BUFFER) < 0) {
                break;
            }
        } else if ((packet = httpCreateDataPacket(ME_MAX_BUFFER)) == 0) {
            break;
        }
        nbytes = mprReadCmd(cmd, channel, mprGetBufEnd(packet->content), ME_MAX_BUFFER);
        if (nbytes < 0) {
            err = mprGetError();
            if (err == EINTR) {
                continue;
            } else if (err == EAGAIN || err == EWOULDBLOCK) {
                break;
            }
            mprTrace(6, "CGI: Gateway read error %d for %s", err, (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr");
            mprCloseCmdFd(cmd, channel);
            break;
            
        } else if (nbytes == 0) {
            mprTrace(6, "CGI: Gateway EOF for %s, pid %d", (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr", cmd->pid);
            mprCloseCmdFd(cmd, channel);
            break;

        } else {
            mprTrace(6, "CGI: Gateway read %d bytes from %s", nbytes, (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr");
            traceData(cmd, mprGetBufEnd(packet->content), nbytes);
            mprAdjustBufEnd(packet->content, nbytes);
        }
        if (channel == MPR_CMD_STDERR) {
            //  FUTURE - should be an option to keep going despite stderr output
            mprError("CGI: Error for \"%s\"\n\n%s", conn->rx->uri, mprGetBufStart(packet->content));
            httpSetStatus(conn, HTTP_CODE_SERVICE_UNAVAILABLE);
            cgi->seenHeader = 1;
        }
        if (!cgi->seenHeader) {
            if (!parseCgiHeaders(cgi, packet)) {
                cgi->headers = packet;
                return;
            }
            cgi->headers = 0;
            cgi->seenHeader = 1;
        } 
        if (!tx->finalizedOutput && httpGetPacketLength(packet) > 0) {
            /* Put the data to the CGI readq, then cgiToBrowserService will take care of it */
            httpPutPacket(q, packet);
        }
    }
}
Пример #7
0
unsigned int isread(char UUFAR *buffer,
                    unsigned int wanted,
                    unsigned int timeout)
{
   union REGS rcvregs, outregs;
   time_t quit = time( NULL ) + timeout;

   size_t commBufferCached = commBufferUsed;

   if ( wanted > commBufferLength )
   {
      printmsg(0,"nsread: Overlength read, wanted %u bytes into %u buffer!",
                     (unsigned int) wanted,
                     (unsigned int) commBufferLength );
      panic();
   }

#ifdef ARTICOMM_INT14   /* Richard H. Gumpertz ([email protected]), 28 Sep 1993 */
   union REGS timregs;          /* Scratch area for interrupt calls. */

   timregs.x.ax = 0x8009;               /* Set timeouts */
   timregs.x.cx = timeout * 91 / 5;     /* Receive timeout in ticks */
   timregs.x.bx = 0x7FFF/*???*/;        /* Send timeout in ticks */
   timregs.x.dx = portNum;              /* Port number */
   int86(0x14, &timregs, &outregs);
#endif /* ARTICOMM_INT14 */

   rcvregs.h.ah = FS_RECV1;
   rcvregs.h.al = 0;
   rcvregs.x.dx = portNum;              /* Port number */
   rcvregs.x.bx = 0;

   while (commBufferUsed < wanted)
   {
      if ( terminate_processing )
      {
         static KWBoolean recurse = KWFalse;
         if ( ! recurse )
         {
            printmsg(2,"isread: User aborted processing");
            recurse = KWTrue;
         }
         commBufferUsed = 0;
         return commBufferUsed;
      }

      int86(0x14, &rcvregs, &outregs);
      if (!(outregs.h.ah & 0x80))
         commBuffer[commBufferUsed++] = (char) outregs.h.al;
      else {                                 /* the read timed out */
         if (timeout == 0)              /* If not interested in waiting */
            return commBufferUsed;      /* then get out of here fast */

         ShowModem();                   /* Report modem status */

         if ( time(NULL) >= quit )
         {
            printmsg(20, "isread: Timeout (timeout=%u, want=%u, have=%u)",
                          timeout, wanted, commBufferUsed);
            return commBufferUsed;
         }

#ifdef ARTICOMM_INT14 /* Richard H. Gumpertz ([email protected]), 28 Sep 1993 */
         timregs.x.cx = (unsigned short)(quit - now) * 91 / 5; /* Receive timeout in ticks */
         int86(0x14, &timregs, &outregs);
#endif /* ARTICOMM_INT14 */

      } /* else */
   } /* while (commBufferUsed < wanted) */

   traceData( commBuffer + commBufferCached,
              commBufferUsed - commBufferCached,
              KWFalse );

   if ( buffer != NULL )
   {
      MEMCPY(buffer, commBuffer, wanted);
      commBufferUsed -= wanted;
      if (commBufferUsed)
         MEMMOVE(commBuffer, commBuffer + wanted, commBufferUsed);
   }

   return wanted + commBufferUsed;

} /* isread */