bool iSocket::ReceiveUntil( char *buffer, u32 recvCount, u32 bufferSize, u32 bufferOffset /* = 0 */ )
{
  u32 writeCount = bufferSize - bufferOffset;
  if( recvCount > writeCount )
    // to do: throw something
    return false;

  buffer += bufferOffset;
  u32 totalBytesRead = 0;
  u32 bytesRead = 0;

  while( totalBytesRead < recvCount )
  {
    int eCode = recv( socket_, buffer, writeCount, 0 );
  
    if( eCode == 0 )
    {
      disconnect_ = true;
      throw( SockErr( 0, "Remote end point has shutdown the connection." ) );
    }
    else if( eCode == SOCKET_ERROR )
    {
      eCode = WSAGetLastError();

      if( eCode == WSAEWOULDBLOCK )
        return false;

      throw( SockErr( WSAGetLastError(), "Failure to receive." ) );
    }

    bytesRead = eCode;
    totalBytesRead += bytesRead;
    buffer += bytesRead;
    writeCount -= bytesRead;
  }

/*
  if( totalBytesRead > recvCount )
    return false;
  else if( totalBytesRead < recvCount )
    // to do: this is bad, throw something
    return false;
  else
    return true;
*/

  return true;
}
extern int
ExternalRead(int h, char *pch, size_t cch)
{

    char *p = pch, *pEnd;
#ifndef WIN32
    ssize_t n;
    psighandler sh;
#else
    int n;
#endif

    while (cch) {
        ProcessEvents();

        if (fInterrupt)
            return -2;

#ifndef WIN32
        PortableSignal(SIGPIPE, SIG_IGN, &sh, FALSE);
#endif

#ifdef WIN32
        /* reading from sockets doesn't work on Windows
         * use recv instead */
        n = recv((SOCKET) h, p, cch, 0);
#else
        n = read(h, p, cch);
#endif

#ifndef WIN32
        PortableSignalRestore(SIGPIPE, &sh);
#endif

        if (!n) {
            outputl(_("External connection closed."));
            return -1;
        } else if (n < 0) {
            if (errno == EINTR)
                continue;

            SockErr(_("reading from external connection"));
            return -1;
        }

        if ((pEnd = memchr(p, '\n', n))) {
            *pEnd = 0;
            return 0;
        }

        cch -= n;
        p += n;

    }

    p[cch - 1] = 0;
    return 0;
}
void iSocket::Close( void )
{
  int eCode = closesocket( socket_ );

  if( eCode == SOCKET_ERROR )
  {
    throw( SockErr( WSAGetLastError(), "Failure to close socket" ) );
  }
}
Exemple #4
0
CBtComm::CBtComm(QWidget *parent)
    : QWidget(parent)
{
    connect(&m_clientSock, SIGNAL(connected()), this, SLOT(ConnectedSlot()));
    connect(&m_clientSock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SockErr()));
    connect(&m_clientSock, SIGNAL(disconnected()), this, SLOT(ConnLost()));

    m_clientSock.connectToHost("localhost", BT_COMM_SOCKET_PORT);

}
void iSocket::Shutdown( void )
{
  Sleep( 100 );
  int eCode = shutdown( socket_, SD_BOTH );

  if( eCode == SOCKET_ERROR )
  {
    throw( SockErr( WSAGetLastError(), "Failed to shutdown on sending socket." ) );
  }
}
Exemple #6
0
CVisionComm::CVisionComm(QWidget *parent)
    : QWidget(parent)
    , localSocket(this)
{
    connect(&localSocket, SIGNAL(connected()), this, SLOT(ConnedToServ()));
    connect(&localSocket, SIGNAL(error(QLocalSocket::LocalSocketError)),
            this, SLOT(SockErr()));
    connect(&localSocket, SIGNAL(disconnected()), this, SLOT(ConnLost()));

    localSocket.connectToServer(VISION_SOCK_NAME);
}
extern int
ExternalWrite(int h, char *pch, size_t cch)
{

    char *p = pch;
#ifndef WIN32
    ssize_t n;
    psighandler sh;
#else
    int n;
#endif

    while (cch) {
        ProcessEvents();

        if (fInterrupt)
            return -1;

#ifndef WIN32
        PortableSignal(SIGPIPE, SIG_IGN, &sh, FALSE);
#endif

#ifdef WIN32
        /* writing to sockets doesn't work on Windows
         * use send instead */
        n = send((SOCKET) h, (const char *) p, cch, 0);
#else
        n = write(h, p, cch);
#endif

#ifndef WIN32
        PortableSignalRestore(SIGPIPE, &sh);
#endif

        if (!n)
            return 0;
        else if (n < 0) {
            if (errno == EINTR)
                continue;

            SockErr(_("writing to external connection"));
            return -1;
        }

        cch -= n;
        p += n;
    }

    return 0;
}
extern void
CommandExternal(char *sz)
{

#if !HAVE_SOCKETS
    outputl(_("This installation of GNU Backgammon was compiled without\n"
              "socket support, and does not implement external controllers."));
#else
    int h, hPeer, cb;
    struct sockaddr *psa;
    char szCommand[256];
    char *szResponse = NULL;
    struct sockaddr_in saRemote;
    socklen_t saLen;
    scancontext scanctx;
    int fExit;
    int fRestart = TRUE;
    int retval;

    sz = NextToken(&sz);

    if (!sz || !*sz) {
        outputl(_("You must specify the name of the socket to the external controller."));
        return;
    }

    memset(&scanctx, 0, sizeof(scanctx));
    ExtInitParse(&scanctx.scanner);

  listenloop:
    {
        fExit = FALSE;
        scanctx.fDebug = FALSE;
        scanctx.fNewInterface = FALSE;

        if ((h = ExternalSocket(&psa, &cb, sz)) < 0) {
            SockErr(sz);
            ExtDestroyParse(scanctx.scanner);
            return;
        }

        if (bind(h, psa, cb) < 0) {
            SockErr(sz);
            closesocket(h);
            free(psa);
            ExtDestroyParse(scanctx.scanner);
            return;
        }

        free(psa);

        if (listen(h, 1) < 0) {
            SockErr("listen");
            closesocket(h);
            ExternalUnbind(sz);
            ExtDestroyParse(scanctx.scanner);
            return;
        }
        outputf(_("Waiting for a connection from %s...\n"), sz);
        outputx();
        ProcessEvents();

        /* Must set length when using windows */
        saLen = sizeof(struct sockaddr);
        while ((hPeer = accept(h, (struct sockaddr *) &saRemote, &saLen)) < 0) {
            if (errno == EINTR) {
                ProcessEvents();

                if (fInterrupt) {
                    closesocket(h);
                    ExternalUnbind(sz);
                    ExtDestroyParse(scanctx.scanner);
                    return;
                }

                continue;
            }

            SockErr("accept");
            closesocket(h);
            ExternalUnbind(sz);
            ExtDestroyParse(scanctx.scanner);
            return;
        }

        closesocket(h);
        ExternalUnbind(sz);

        /* print info about remove client */

        outputf(_("Accepted connection from %s.\n"), inet_ntoa(saRemote.sin_addr));
        outputx();
        ProcessEvents();

        while (!fExit && !(retval = ExternalRead(hPeer, szCommand, sizeof(szCommand)))) {

            if ((ExtParse(&scanctx, szCommand)) == 0) {
                /* parse error */
                szResponse = scanctx.szError;
            } else {
                ProcessedFIBSBoard processedBoard;
                GValue *optionsmapgv;
                GValue *boarddatagv;
                GString *dbgStr;
                int anScore[2];
                int fCrawford, fJacoby;
                char *asz[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
                char szBoard[10000];
                char **aszLines;
                char **aszLinesOrig;
                char *szMatchID;
                gchar *szOptStr;

                switch (scanctx.ct) {
                case COMMAND_HELP:
                    szResponse = g_strdup("\tNo help information available\n");
                    break;

                case COMMAND_SET:
                    szOptStr = g_value_get_gstring_gchar(g_list_nth_data(scanctx.pCmdData, 0));
                    if (g_ascii_strcasecmp(szOptStr, KEY_STR_DEBUG) == 0) {
                        scanctx.fDebug = g_value_get_int(g_list_nth_data(scanctx.pCmdData, 1));
                        szResponse = g_strdup_printf("Debug output %s\n", scanctx.fDebug ? "ON" : "OFF");
                    } else if (g_ascii_strcasecmp(szOptStr, KEY_STR_NEWINTERFACE) == 0) {
                        scanctx.fNewInterface = g_value_get_int(g_list_nth_data(scanctx.pCmdData, 1));
                        szResponse = g_strdup_printf("New interface %s\n", scanctx.fNewInterface ? "ON" : "OFF");
                    } else {
                        szResponse = g_strdup_printf("Error: set option '%s' not supported\n", szOptStr);
                    }
                    g_list_gv_boxed_free(scanctx.pCmdData);

                    break;

                case COMMAND_VERSION:
                    szResponse = g_strdup("Interface: " EXTERNAL_INTERFACE_VERSION "\n"
                                          "RFBF: " RFBF_VERSION_SUPPORTED "\n"
                                          "Engine: " WEIGHTS_VERSION "\n" "Software: " VERSION "\n");

                    break;

                case COMMAND_NONE:
                    szResponse = g_strdup("Error: no command given\n");
                    break;

                case COMMAND_FIBSBOARD:
                case COMMAND_EVALUATION:
                    if (scanctx.fDebug) {
                        optionsmapgv = (GValue *) g_list_nth_data(g_value_get_boxed(scanctx.pCmdData), 1);
                        boarddatagv = (GValue *) g_list_nth_data(g_value_get_boxed(scanctx.pCmdData), 0);
                        dbgStr = g_string_new(DEBUG_PREFIX);
                        g_value_tostring(dbgStr, optionsmapgv, 0);
                        g_string_append(dbgStr, "\n" DEBUG_PREFIX);
                        g_value_tostring(dbgStr, boarddatagv, 0);
                        g_string_append(dbgStr, "\n" DEBUG_PREFIX "\n");
                        ExternalWrite(hPeer, dbgStr->str, strlen(dbgStr->str));
                        ProcessFIBSBoardInfo(&scanctx.bi, &processedBoard);

                        anScore[0] = processedBoard.nScoreOpp;
                        anScore[1] = processedBoard.nScore;
                        /* If the session isn't using Crawford rule, set crawford flag to false */
                        fCrawford = scanctx.fCrawfordRule ? processedBoard.fCrawford : FALSE;
                        /* Set the Jacoby flag appropriately from the external interface settings */
                        fJacoby = scanctx.fJacobyRule;

                        szMatchID = MatchID((unsigned int *) processedBoard.anDice, 1, processedBoard.nResignation,
                                            processedBoard.fDoubled, 1, processedBoard.fCubeOwner, fCrawford,
                                            processedBoard.nMatchTo, anScore, processedBoard.nCube, fJacoby,
                                            GAME_PLAYING);

                        DrawBoard(szBoard, (ConstTanBoard) & processedBoard.anBoard, 1, asz, szMatchID, 15);

                        aszLines = g_strsplit(&szBoard[0], "\n", 32);
                        aszLinesOrig = aszLines;
                        while (*aszLines) {
                            ExternalWrite(hPeer, DEBUG_PREFIX, strlen(DEBUG_PREFIX));
                            ExternalWrite(hPeer, *aszLines, strlen(*aszLines));
                            ExternalWrite(hPeer, "\n", 1);
                            aszLines++;
                        }

                        dbgStr = g_string_assign(dbgStr, "");
                        g_string_append_printf(dbgStr, DEBUG_PREFIX "X is %s, O is %s\n", processedBoard.szPlayer,
                                               processedBoard.szOpp);
                        if (processedBoard.nMatchTo) {
                            g_string_append_printf(dbgStr, DEBUG_PREFIX "Match Play %s Crawford Rule\n",
                                                   scanctx.fCrawfordRule ? "with" : "without");
                            g_string_append_printf(dbgStr, DEBUG_PREFIX "Score: %d-%d/%d%s, ", processedBoard.nScore,
                                                   processedBoard.nScoreOpp, processedBoard.nMatchTo,
                                                   fCrawford ? "*" : "");
                        } else {
                            g_string_append_printf(dbgStr, DEBUG_PREFIX "Money Session %s Jacoby Rule, %s Beavers\n",
                                                   scanctx.fJacobyRule ? "with" : "without",
                                                   scanctx.fBeavers ? "with" : "without");
                            g_string_append_printf(dbgStr, DEBUG_PREFIX "Score: %d-%d, ", processedBoard.nScore,
                                                   processedBoard.nScoreOpp);
                        }
                        g_string_append_printf(dbgStr, "Roll: %d%d\n",
                                               processedBoard.anDice[0], processedBoard.anDice[1]);
                        g_string_append_printf(dbgStr,
                                               DEBUG_PREFIX
                                               "CubeOwner: %d, Cube: %d, Turn: %c, Doubled: %d, Resignation: %d\n",
                                               processedBoard.fCubeOwner, processedBoard.nCube, 'X',
                                               processedBoard.fDoubled, processedBoard.nResignation);
                        g_string_append(dbgStr, DEBUG_PREFIX "\n");
                        ExternalWrite(hPeer, dbgStr->str, strlen(dbgStr->str));

                        g_string_free(dbgStr, TRUE);
                        g_strfreev(aszLinesOrig);
                    }
                    g_value_unsetfree(scanctx.pCmdData);

                    if (scanctx.ct == COMMAND_EVALUATION)
                        szResponse = ExtEvaluation(&scanctx);
                    else
                        szResponse = ExtFIBSBoard(&scanctx);

                    break;

                case COMMAND_EXIT:
                    closesocket(hPeer);
                    fExit = TRUE;
                    break;

                default:
                    szResponse = g_strdup("Unsupported Command\n");
                }
                unset_scan_context(&scanctx, FALSE);
            }

            if (szResponse) {
                if (ExternalWrite(hPeer, szResponse, strlen(szResponse)))
                    break;

                g_free(szResponse);
                szResponse = NULL;
            }

        }
        /* Interrupted : get out of listen loop */
        if (retval == -2) {
            ProcessEvents();
            fRestart = FALSE;
        }

        closesocket(hPeer);
        if (szResponse)
            g_free(szResponse);

        szResponse = NULL;
        scanctx.szError = NULL;
    }
    if (fRestart)
        goto listenloop;

    unset_scan_context(&scanctx, TRUE);
#endif
}
Exemple #9
0
extern void CommandExternal( char *sz ) {

#if !HAVE_SOCKETS
    outputl( _("This installation of GNU Backgammon was compiled without\n"
	     "socket support, and does not implement external controllers.") );
#else
    int h, hPeer, cb;
    struct sockaddr *psa;
    char szCommand[ 256 ];
    char *szResponse = NULL;
    struct sockaddr_in saRemote;
    socklen_t saLen;
    extcmd *pec;
    
    sz = NextToken( &sz );
    
    if( !sz || !*sz ) {
	outputl( _("You must specify the name of the socket to the external controller.") );
	return;
    }

listenloop:
	{

      if( ( h = ExternalSocket( &psa, &cb, sz ) ) < 0 ) {
	SockErr( sz );
	return;
      }
      
      if( bind( h, psa, cb ) < 0 ) {
	SockErr( sz );
	closesocket( h );
	free( psa );
	return;
      }
      
      free( psa );
      
      if( listen( h, 1 ) < 0 ) {
	SockErr( "listen" );
	closesocket( h );
	ExternalUnbind( sz );
	return;
      }
      outputf( _("Waiting for a connection from %s...\n"), sz);
      outputx();
      ProcessEvents();

      /* Must set length when using windows */
      saLen = sizeof(struct sockaddr);
      while( ( hPeer = accept( h, (struct sockaddr*)&saRemote, &saLen ) ) < 0 )
	  {
		if( errno == EINTR )
		{
			ProcessEvents();

          if( fInterrupt ) {
            closesocket( h );
            ExternalUnbind( sz );
            return;
          }
	    
          continue;
	}
	
	SockErr( "accept" );
	closesocket( h );
	ExternalUnbind( sz );
	return;
      }

      closesocket( h );
      ExternalUnbind( sz );

      /* print info about remove client */

      outputf(_("Accepted connection from %s.\n"),
                 inet_ntoa( saRemote.sin_addr ) );
      outputx();
      ProcessEvents();

      while( !ExternalRead( hPeer, szCommand, sizeof( szCommand ) ) ) {

        if ( ( pec = ExtParse( szCommand ) ) == 0 ) {
          /* parse error */
          szResponse = szError;
        }
        else {

          switch ( pec->ct ) {
          case COMMAND_NONE:
            szResponse = g_strdup( "Error: no command given\n" );
            break;
          
          case COMMAND_FIBSBOARD:
          
            szResponse = ExtFIBSBoard( pec );
            break;
          
          case COMMAND_EVALUATION:
          
            szResponse = ExtEvaluation( pec );
            break;
          
          }

        }

        if ( szResponse ) {
          if ( ExternalWrite( hPeer, szResponse, strlen( szResponse ) ) )
            break;

          g_free( szResponse );
        }

      }
      closesocket( hPeer );
    }
	goto listenloop;
#endif
}