コード例 #1
0
ファイル: fwupdate.c プロジェクト: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void QueryVersion
(
    void
)
{
    TryConnect(le_info_ConnectService, "modemService");

    // Connected to service so continue
    le_result_t result;
    char version[LE_INFO_MAX_VERS_BYTES];
    struct utsname linuxInfo;

    result = le_info_GetFirmwareVersion(version, sizeof(version));
    if ( result == LE_OK )
    {
        printf("Firmware Version: %s\n", version);
    }

    result = le_info_GetBootloaderVersion(version, sizeof(version));
    if ( result == LE_OK )
    {
        printf("Bootloader Version: %s\n", version);
    }

    if ( uname(&linuxInfo) == 0 )
    {
        printf("Linux Version: %s %s\n", linuxInfo.release, linuxInfo.version);
    }
}
コード例 #2
0
int XLSocket::Start()
{
	m_Config.Print();
	int ErrorCode = RESULT_OK;
	if(m_bServerMode)
	{
		if((ErrorCode = ListenOnPort()) != RESULT_OK)
		{
			return ErrorCode;
		}
		if(!AcceptConnection())
		{
			return RESULT_FAIL;
		}
		m_bActive = true;
	}
	else
	{
		if((ErrorCode = TryConnect()) != RESULT_OK)
		{
			return ErrorCode;
		}
		m_bActive = true;
	}
	return ErrorCode;
}
コード例 #3
0
void CToxProto::CheckConnection(int &retriesCount)
{
	if (!isConnected)
	{
		TryConnect();
	}
	else if (tox_self_get_connection_status(tox) != TOX_CONNECTION_NONE)
	{
		if (retriesCount < TOX_MAX_DISCONNECT_RETRIES)
		{
			debugLogA(__FUNCTION__": restored connection with DHT");
			retriesCount = TOX_MAX_DISCONNECT_RETRIES;
		}
	}
	else
	{
		if (retriesCount == TOX_MAX_DISCONNECT_RETRIES)
		{
			retriesCount--;
			debugLogA(__FUNCTION__": lost connection with DHT");
		}
		else if (retriesCount % 50 == 0)
		{
			retriesCount--;
			BootstrapNodes();
		}
		else if (!(--retriesCount))
		{
			isConnected = false;
			debugLogA(__FUNCTION__": disconnected from DHT");
			SetStatus(ID_STATUS_OFFLINE);
		}
	}
}
コード例 #4
0
ファイル: EWMicroRecorder.cpp プロジェクト: hnpilot/XCSoar
bool
EWMicroRecorderDevice::Declare(const Declaration *decl)
{
  // Must have at least two, max 12 waypoints
  if (decl->size() < 2 || decl->size() > 12)
    return false;

  port->StopRxThread();

  port->SetRxTimeout(500);                     // set RX timeout to 500[ms]

  if (!TryConnect())
    return false;

  port->Write('\x18');         // start to upload file
  port->Write(user_data);
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
               _T("Pilot Name:"), decl->PilotName);
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
               _T("Competition ID:"), decl->AircraftRego);
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
               _T("Aircraft Type:"), decl->AircraftType);
  port->Write("Description:      Declaration\r\n");

  for (unsigned i = 0; i < 11; i++) {
    if (i+1>= decl->size()) {
      EWMicroRecorderPrintf(port, _T("%-17s %s\r\n"),
               _T("TP LatLon:"), _T("0000000N00000000E TURN POINT\r\n"));
    } else {
      const Waypoint &wp = decl->waypoints[i];
      if (i == 0) {
        EWMicroRecorderWriteWayPoint(port, wp, _T("Take Off LatLong:"));
        EWMicroRecorderWriteWayPoint(port, wp, _T("Start LatLon:"));
      } else if (i + 1 < decl->size()) {
        EWMicroRecorderWriteWayPoint(port, wp, _T("TP LatLon:"));
      }
    }
  }

  const Waypoint &wp = decl->waypoints[decl->size() - 1];
  EWMicroRecorderWriteWayPoint(port, wp, _T("Finish LatLon:"));
  EWMicroRecorderWriteWayPoint(port, wp, _T("Land LatLon:"));

  port->Write('\x03');         // finish sending user file

  bool success = ExpectStringWait(port, "uploaded successfully");

  port->Write("!!\r\n");         // go back to NMEA mode

  port->SetRxTimeout(0);                       // clear timeout
  port->StartRxThread();                       // restart RX thread

  return success;
}
コード例 #5
0
ファイル: EWMicroRecorder.cpp プロジェクト: XCame/XCSoar
static bool
TryConnectRetry(Port &port, char *user_data, size_t max_user_data,
                OperationEnvironment &env)
{
  int retries=10;

  while (--retries)
    if (TryConnect(port, user_data, max_user_data, env))
      return true;

  return false;
}
コード例 #6
0
ファイル: XSocketClientInServer.cpp プロジェクト: xahgo/tama
/**
 소켓을 새로열고 커넥션 스레드를 새로 열어 재접속 한다. 
 재접속했을때 서버주소나 포트가 바꼈을수 있으므로 반드시 인자로 받는걸로 
 재 세팅해야한다.
*/
bool XESocketClientInServer::DoReconnectTry()
{
	// 소켓을 다시 생성함.
	if( CreateSocket() ) {
		// 커넥션 스레드 다시 열어서 스레드내에서 계속 접속시도.
		m_bReadyServer = FALSE;
		SetbReconnected( TRUE );
		TryConnect();
		m_timerReconnect.Off();
	} else {
		// 소켓생성에 실패했다면 x초후에 다시 시도.
		return false;
	}
	return true;
}
コード例 #7
0
ファイル: irc.cpp プロジェクト: ekumlin/Cubyx-IRC
bool IRC::Think() {
	if (IRCState == DISABLED) {
		// Nothing!
	} else if (IRCState == DISCONNECTED) {
		// Reconnect?
	} else if (IRCState == CONNECTING) {
		TryConnect();
	} else if (IRCState == CONNECTED || IRCState == INSESSION) {
		std::string buf;
		int Success = Sock.ReceiveLine(buf);
		if (Success == -1) { Disconnect(); }
		else if (Success != 0) { HandleMessage(buf); }
	}
	return false;
}
コード例 #8
0
ファイル: fwupdate.c プロジェクト: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void DownloadFirmware
(
    const char* fileName    ///< Name of file containing firmware image
)
{
    int fd;

    if ( strcmp(fileName, "-") == 0 )
    {
        // Use stdin
        fd = STDIN_FILENO;
    }
    else
    {
        // Open the file
        fd = open( fileName, O_RDONLY);
        LE_PRINT_VALUE("%d", fd);

        if ( fd == -1 )
        {
            // Inform the user of the error; it's also useful to log this info
            printf("Can't open file '%s' : %m\n", fileName);
            LE_FATAL("Can't open file '%s' : %m", fileName);
        }
    }

    TryConnect(le_fwupdate_ConnectService, "fwupdateService");

    // Connected to service so continue
    printf("Download started ...\n");
    fflush(stdout);

    LE_PRINT_VALUE("%d", fd);
    if ( le_fwupdate_Download(fd) == LE_OK )
    {
        printf("Download successful; please wait for modem to reset\n");
    }
    else
    {
        printf("Error in download\n");
    }
}
コード例 #9
0
SleepyApi::Impl::Impl()
:	m_conv(NULL)
{
	assert(m_instance==NULL);
	m_instance=this;

	m_appId=0;
	if (DdeInitializeA(&m_appId,OnDdeCallback,APPCMD_CLIENTONLY,0)!=DMLERR_NO_ERROR)
	{
		m_appId=0;
	}
	else
	{
		m_service=DdeCreateStringHandleA(m_appId,"VerySleepyProfilerServer",CP_WINANSI);
		m_topic=DdeCreateStringHandleA(m_appId,"Control.1",CP_WINANSI);
		m_paused=DdeCreateStringHandleA(m_appId,"paused",CP_WINANSI);

		TryConnect();
	}
}
コード例 #10
0
ファイル: irc.cpp プロジェクト: ekumlin/Cubyx-IRC
void IRC::UpdateState(State S) {
	IRCState = S;
	if (S == DISCONNECTED) {
		ServerManager->GetServerByID(m_info.m_ServerID)->ProcessEvent(SERVER_DISCONNECT);
	} else if (S == CONNECTING) {
		TryConnect();
	} else if (S == CONNECTED) {
		ServerManager->GetServerByID(m_info.m_ServerID)->ProcessEvent(SERVER_CONNECT);

		if (ServerManager->GetServerByID(m_info.m_ServerID)->m_Data.m_Password.Len() > 0) {
			Throw("PASS %s",ServerManager->GetServerByID(m_info.m_ServerID)->m_Data.m_Password.c_str());
		}
		Throw("NICK %s",ServerManager->GetServerByID(m_info.m_ServerID)->m_Data.m_Nick.c_str());

		TCHAR szHostName[MAX_PATH];
		DWORD cbHostName = sizeof(szHostName);
		GetComputerName(szHostName,&cbHostName);

		Throw("USER %s %s %s :%s",ServerManager->GetServerByID(m_info.m_ServerID)->m_Data.m_UserID.c_str(),szHostName,"server",ServerManager->GetServerByID(m_info.m_ServerID)->m_Data.m_FullName.c_str());

		// Set Window Title for Server
	} else if (S == INSESSION) {
	}
}
コード例 #11
0
ファイル: EW.cpp プロジェクト: DRIZO/xcsoar
bool
EWDevice::DeclareInner(const struct Declaration &declaration,
                       OperationEnvironment &env)
{
  char sTmp[72];

  ewDecelTpIndex = 0;

  if (!TryConnect(env))
    return false;

  // send SetPilotInfo
  WriteWithChecksum(port, "#SPI");
  env.Sleep(50);

  char sPilot[13], sGliderType[9], sGliderID[9];
  convert_string(sPilot, sizeof(sPilot), declaration.pilot_name);
  convert_string(sGliderType, sizeof(sGliderType), declaration.aircraft_type);
  convert_string(sGliderID, sizeof(sGliderID), declaration.aircraft_registration);

  // build string (field 4-5 are GPS info, no idea what to write)
  sprintf(sTmp, "%-12s%-8s%-8s%-12s%-12s%-6s\r", sPilot, sGliderType, sGliderID,
          "" /* GPS Model */, "" /* GPS Serial No. */, "" /* Flight Date */
          /* format unknown, left blank (GPS has a RTC) */);
  port.Write(sTmp);

  if (!port.ExpectString("OK\r", env))
    return false;

  /*
  sprintf(sTmp, "#SUI%02d", 0);           // send pilot name
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port.Write(PilotsName);
  port.Write('\r');

  if (!port.ExpectString("OK\r"))
    return false;

  sprintf(sTmp, "#SUI%02d", 1);           // send type of aircraft
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port.Write(Class);
  port.Write('\r');

  if (!port.ExpectString("OK\r"))
    nDeclErrorCode = 1;

  sprintf(sTmp, "#SUI%02d", 2);           // send aircraft ID
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port.Write(ID);
  port.Write('\r');

  if (!port.ExpectString("OK\r"))
    return false;
  */

  // clear all 6 TP's
  for (int i = 0; i < 6; i++) {
    sprintf(sTmp, "#CTP%02d", i);
    WriteWithChecksum(port, sTmp);
    if (!port.ExpectString("OK\r", env))
      return false;
  }

  for (unsigned j = 0; j < declaration.Size(); ++j)
    if (!AddWaypoint(declaration.GetWaypoint(j), env))
      return false;

  return true;
}
コード例 #12
0
ファイル: ipcConnectionUnix.cpp プロジェクト: miguelinux/vbox
nsresult
IPC_Connect(const char *daemonPath)
{
    // synchronous connect, spawn daemon if necessary.

    PRFileDesc *fd = NULL;
    nsresult rv = NS_ERROR_FAILURE;

    if (gConnState)
        return NS_ERROR_ALREADY_INITIALIZED;

    //
    // here's the connection algorithm:  try to connect to an existing daemon.
    // if the connection fails, then spawn the daemon (wait for it to be ready),
    // and then retry the connection.  it is critical that the socket used to
    // connect to the daemon not be inherited (this causes problems on RH9 at
    // least).
    //

    rv = TryConnect(&fd);
    if (NS_FAILED(rv))
    {
        rv = IPC_SpawnDaemon(daemonPath);
        if (NS_SUCCEEDED(rv))
            rv = TryConnect(&fd);
    }

    if (NS_FAILED(rv))
        goto end;

    //
    // ok, we have a connection to the daemon!
    //

    // build connection state object
    gConnState = ConnCreate(fd);
    if (!gConnState)
    {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto end;
    }
    fd = NULL; // connection state now owns the socket

    gConnThread = PR_CreateThread(PR_USER_THREAD,
                                  ConnThread,
                                  gConnState,
                                  PR_PRIORITY_NORMAL,
                                  PR_GLOBAL_THREAD,
                                  PR_JOINABLE_THREAD,
                                  0);
    if (!gConnThread)
    {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto end;
    }

#ifdef DEBUG
    gMainThread = PR_GetCurrentThread();
#endif
    return NS_OK;

end:
    if (gConnState)
    {
        ConnDestroy(gConnState);
        gConnState = NULL;
    }
    if (fd)
        PR_Close(fd);
    return rv;
}
コード例 #13
0
static bool
DeclareInner(Port &port, const Declaration &declaration,
             OperationEnvironment &env)
{
  assert(declaration.size() >= 2);
  assert(declaration.size() <= 12);

  char user_data[2500];

  if (!TryConnect(port, user_data) || env.IsCancelled())
    return false;

  char *p = strstr(user_data, "USER DETAILS");
  if (p != NULL)
    *p = 0;

  port.Write('\x18');         // start to upload file
  port.Write(user_data);

  port.Write("USER DETAILS\r\n--------------\r\n\r\n");
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Pilot Name:"), declaration.PilotName.c_str());
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Competition ID:"),
                        declaration.CompetitionId.c_str());
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Aircraft Type:"),
                        declaration.AircraftType.c_str());
  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Aircraft ID:"), declaration.AircraftReg.c_str());
  port.Write("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n");

  EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"),
                        _T("Description:"), _T("XCSoar task declaration"));

  for (unsigned i = 0; i < 11; i++) {
    if (env.IsCancelled())
      return false;

    if (i+1>= declaration.size()) {
      EWMicroRecorderPrintf(port, _T("%-17s %s\r\n"),
               _T("TP LatLon:"), _T("0000000N00000000E TURN POINT"));
    } else {
      const Waypoint &wp = declaration.get_waypoint(i);
      if (i == 0) {
        EWMicroRecorderWriteWaypoint(port, wp, _T("Take Off LatLong:"));
        EWMicroRecorderWriteWaypoint(port, wp, _T("Start LatLon:"));
      } else if (i + 1 < declaration.size()) {
        EWMicroRecorderWriteWaypoint(port, wp, _T("TP LatLon:"));
      }
    }
  }

  const Waypoint &wp = declaration.get_last_waypoint();
  EWMicroRecorderWriteWaypoint(port, wp, _T("Finish LatLon:"));
  EWMicroRecorderWriteWaypoint(port, wp, _T("Land LatLon:"));

  if (env.IsCancelled())
      return false;

  port.Write('\x03');         // finish sending user file

  return port.ExpectString("uploaded successfully");
}
コード例 #14
0
ファイル: EW.cpp プロジェクト: Mrdini/XCSoar
bool
EWDevice::DeclareInner(const struct Declaration *decl,
                       OperationEnvironment &env)
{
  char sTmp[72];

  ewDecelTpIndex = 0;

  if (!TryConnect())
    return false;

  WriteWithChecksum(port, "#SPI"); // send SetPilotInfo
  env.Sleep(50);

  char sPilot[13], sGliderType[9], sGliderID[9];
  convert_string(sPilot, sizeof(sPilot), decl->PilotName);
  convert_string(sGliderType, sizeof(sGliderType), decl->AircraftType);
  convert_string(sGliderID, sizeof(sGliderID), decl->AircraftReg);

  // build string (field 4-5 are GPS info, no idea what to write)
  sprintf(sTmp, "%-12s%-8s%-8s%-12s%-12s%-6s\r",
          sPilot,
          sGliderType,
          sGliderID,
          "", // GPS Model
          "", // GPS Serial No.
          "" // Flight Date,
                                                  // format unknown,
                                                  // left blank (GPS
                                                  // has a RTC)
  );
  port->Write(sTmp);

  if (!port->ExpectString("OK\r"))
    return false;

  /*
  sprintf(sTmp, "#SUI%02d", 0);           // send pilot name
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port->Write(PilotsName);
  port->Write('\r');

  if (!port->ExpectString("OK\r"))
    return false;

  sprintf(sTmp, "#SUI%02d", 1);           // send type of aircraft
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port->Write(Class);
  port->Write('\r');

  if (!port->ExpectString("OK\r"))
    nDeclErrorCode = 1;

  sprintf(sTmp, "#SUI%02d", 2);           // send aircraft ID
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port->Write(ID);
  port->Write('\r');

  if (!port->ExpectString("OK\r"))
    return false;
  */

  for (int i=0; i<6; i++){                        // clear all 6 TP's
    sprintf(sTmp, "#CTP%02d", i);
    WriteWithChecksum(port, sTmp);
    if (!port->ExpectString("OK\r"))
      return false;
  }
  for (unsigned j = 0; j < decl->size(); ++j)
    if (!AddWayPoint(decl->get_waypoint(j)))
      return false;

  return true;
}
コード例 #15
0
ファイル: net.c プロジェクト: bahamat/debian-cfengine3
/**
   Tries to connect() to server #host, returns the socket descriptor and the
   IP address that succeeded in #txtaddr.

   @param #connect_timeout how long to wait for connect(), zero blocks forever
   @param #txtaddr If connected successfully return the IP connected in
                   textual representation
   @return Connected socket descriptor or -1 in case of failure.
*/
int SocketConnect(const char *host, const char *port,
                  unsigned int connect_timeout, bool force_ipv4,
                  char *txtaddr, size_t txtaddr_size)
{
    struct addrinfo *response = NULL, *ap;
    bool connected = false;
    int sd = -1;

    struct addrinfo query = {
        .ai_family = force_ipv4 ? AF_INET : AF_UNSPEC,
        .ai_socktype = SOCK_STREAM
    };

    int ret = getaddrinfo(host, port, &query, &response);
    if (ret != 0)
    {
        Log(LOG_LEVEL_INFO,
              "Unable to find host '%s' service '%s' (%s)",
              host, port, gai_strerror(ret));
        if (response != NULL)
        {
            freeaddrinfo(response);
        }
        return -1;
    }

    for (ap = response; !connected && ap != NULL; ap = ap->ai_next)
    {
        /* Convert address to string. */
        getnameinfo(ap->ai_addr, ap->ai_addrlen,
                    txtaddr, txtaddr_size,
                    NULL, 0, NI_NUMERICHOST);
        Log(LOG_LEVEL_VERBOSE,
            "Connecting to host %s, port %s as address %s",
            host, port, txtaddr);

        sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
        if (sd == -1)
        {
            Log(LOG_LEVEL_ERR, "Couldn't open a socket to '%s' (socket: %s)",
                txtaddr, GetErrorStr());
        }
        else
        {
            /* Bind socket to specific interface, if requested. */
            if (BINDINTERFACE[0] != '\0')
            {
                struct addrinfo query2 = {
                    .ai_family = force_ipv4 ? AF_INET : AF_UNSPEC,
                    .ai_socktype = SOCK_STREAM,
                    /* returned address is for bind() */
                    .ai_flags = AI_PASSIVE
                };

                struct addrinfo *response2 = NULL, *ap2;
                int ret2 = getaddrinfo(BINDINTERFACE, NULL, &query2, &response2);
                if (ret2 != 0)
                {
                    Log(LOG_LEVEL_ERR,
                        "Unable to lookup interface '%s' to bind. (getaddrinfo: %s)",
                        BINDINTERFACE, gai_strerror(ret2));

                    if (response2 != NULL)
                    {
                        freeaddrinfo(response2);
                    }
                    assert(response);   /* first getaddrinfo was successful */
                    freeaddrinfo(response);
                    cf_closesocket(sd);
                    return -1;
                }

                for (ap2 = response2; ap2 != NULL; ap2 = ap2->ai_next)
                {
                    if (bind(sd, ap2->ai_addr, ap2->ai_addrlen) == 0)
                    {
                        break;
                    }
                }
                if (ap2 == NULL)
                {
                    Log(LOG_LEVEL_ERR,
                        "Unable to bind to interface '%s'. (bind: %s)",
                        BINDINTERFACE, GetErrorStr());
                }
                assert(response2);     /* second getaddrinfo was successful */
                freeaddrinfo(response2);
            }

            connected = TryConnect(sd, connect_timeout * 1000,
                                   ap->ai_addr, ap->ai_addrlen);
            if (!connected)
            {
                Log(LOG_LEVEL_VERBOSE, "Unable to connect to address %s (%s)",
                    txtaddr, GetErrorStr());
                cf_closesocket(sd);
                sd = -1;
            }
        }
    }

    assert(response != NULL);           /* first getaddrinfo was successful */
    freeaddrinfo(response);

    if (connected)
    {
        Log(LOG_LEVEL_VERBOSE,
            "Connected to host %s address %s port %s",
            host, txtaddr, port);
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE,
            "Unable to connect to host %s port %s",
            host, port);
    }

    return sd;
}


#if !defined(__MINGW32__)

#if defined(__hpux) && defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
// HP-UX GCC type-pun warning on FD_SET() macro:
// While the "fd_set" type is defined in /usr/include/sys/_fd_macros.h as a
// struct of an array of "long" values in accordance with the XPG4 standard's
// requirements, the macros for the FD operations "pretend it is an array of
// int32_t's so the binary layout is the same for both Narrow and Wide
// processes," as described in _fd_macros.h. In the FD_SET, FD_CLR, and
// FD_ISSET macros at line 101, the result is cast to an "__fd_mask *" type,
// which is defined as int32_t at _fd_macros.h:82.
//
// This conflict between the "long fds_bits[]" array in the XPG4-compliant
// fd_set structure, and the cast to an int32_t - not long - pointer in the
// macros, causes a type-pun warning if -Wstrict-aliasing is enabled.
// The warning is merely a side effect of HP-UX working as designed,
// so it can be ignored.
#endif

/**
 * Tries to connect for #timeout_ms milliseconds. On success sets the recv()
 * timeout to #timeout_ms as well.
 *
 * @param #timeout_ms How long to wait for connect(), if zero wait forever.
 * @return true on success, false otherwise.
 **/
bool TryConnect(int sd, unsigned long timeout_ms,
                const struct sockaddr *sa, socklen_t sa_len)
{
    assert(sa != NULL);

    if (sd >= FD_SETSIZE)
    {
        Log(LOG_LEVEL_ERR, "Open connections exceed FD_SETSIZE limit of %d",
            FD_SETSIZE);
        return false;
    }

    /* set non-blocking socket */
    int arg = fcntl(sd, F_GETFL, NULL);
    int ret = fcntl(sd, F_SETFL, arg | O_NONBLOCK);
    if (ret == -1)
    {
        Log(LOG_LEVEL_ERR,
            "Failed to set socket to non-blocking mode (fcntl: %s)",
            GetErrorStr());
    }

    ret = connect(sd, sa, sa_len);
    if (ret == -1)
    {
        if (errno != EINPROGRESS)
        {
            Log(LOG_LEVEL_INFO, "Failed to connect to server (connect: %s)",
                GetErrorStr());
            return false;
        }

        int errcode;
        socklen_t opt_len = sizeof(errcode);
        fd_set myset;
        FD_ZERO(&myset);
        FD_SET(sd, &myset);

        Log(LOG_LEVEL_VERBOSE, "Waiting to connect...");

        struct timeval tv, *tvp;
        if (timeout_ms > 0)
        {
            tv.tv_sec = timeout_ms / 1000;
            tv.tv_usec = (timeout_ms % 1000) * 1000;
            tvp = &tv;
        }
        else
        {
            tvp = NULL;                                /* wait indefinitely */
        }

        ret = select(sd + 1, NULL, &myset, NULL, tvp);
        if (ret == 0)
        {
            Log(LOG_LEVEL_INFO, "Timeout connecting to server");
            return false;
        }
        if (ret == -1)
        {
            if (errno == EINTR)
            {
                Log(LOG_LEVEL_ERR,
                    "Socket connect was interrupted by signal");
            }
            else
            {
                Log(LOG_LEVEL_ERR,
                    "Failure while connecting (select: %s)",
                    GetErrorStr());
            }
            return false;
        }

        ret = getsockopt(sd, SOL_SOCKET, SO_ERROR,
                              (void *) &errcode, &opt_len);
        if (ret == -1)
        {
            Log(LOG_LEVEL_ERR,
                "Could not check connection status (getsockopt: %s)",
                GetErrorStr());
            return false;
        }

        if (errcode != 0)
        {
            Log(LOG_LEVEL_INFO, "Failed to connect to server: %s",
                GetErrorStrFromCode(errcode));
            return false;
        }
    }

    /* Connection succeeded, return to blocking mode. */
    ret = fcntl(sd, F_SETFL, arg);
    if (ret == -1)
    {
        Log(LOG_LEVEL_ERR,
            "Failed to set socket back to blocking mode (fcntl: %s)",
            GetErrorStr());
    }

    if (timeout_ms > 0)
    {
        SetReceiveTimeout(sd, timeout_ms);
    }

    return true;
}

#if defined(__hpux) && defined(__GNUC__)
#pragma GCC diagnostic warning "-Wstrict-aliasing"
#endif

#endif /* !defined(__MINGW32__) */



/**
 * Set timeout for recv(), in milliseconds.
 * @param ms must be > 0.
 */
int SetReceiveTimeout(int fd, unsigned long ms)
{
    assert(ms > 0);

    Log(LOG_LEVEL_VERBOSE, "Setting socket timeout to %lu seconds.", ms/1000);

/* On windows SO_RCVTIMEO is set by a DWORD indicating the timeout in
 * milliseconds, on UNIX it's a struct timeval. */

#if !defined(__MINGW32__)
    struct timeval tv = {
        .tv_sec = ms / 1000,
        .tv_usec = (ms % 1000) * 1000
    };
    int ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
#else
    int ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &ms, sizeof(ms));
#endif

    if (ret != 0)
    {
        Log(LOG_LEVEL_INFO,
            "Failed to set socket timeout to %lu milliseconds.", ms);
        return -1;
    }

    return 0;
}