Exemple #1
0
HRESULT rapi_context_connect(RapiContext* context)
{
    HRESULT result = E_FAIL;
    SynceInfo* info = NULL;

    if (context->is_initialized)
    {
        /* Fail immediately */
            return CERAPI_E_ALREADYINITIALIZED;
    }

    if (context->info)
        info = context->info;
    else
        info = synce_info_new(NULL);
    if (!info)
    {
        synce_error("Failed to get connection info");
        goto fail;
    }

    const char *transport = synce_info_get_transport(info);
    /*
     *  original dccm or vdccm, sanity checking
     */
    if (transport == NULL || ( strcmp(transport, "odccm") != 0 && strcmp(transport, "udev") != 0 ) ) {
        pid_t dccm_pid = 0;
        if (!(dccm_pid = synce_info_get_dccm_pid(info)))
        {
            synce_error("DCCM PID entry not found for current connection");
            goto fail;
        }

        if (kill(dccm_pid, 0) < 0)
        {
            if (errno != EPERM)
            {
                synce_error("DCCM not running with pid %i", synce_info_get_dccm_pid(info));
                goto fail;
            }
        }

        if (!synce_info_get_device_ip(info))
        {
            synce_error("IP entry not found for current connection");
            goto fail;
        }
    }

    /*
     *  original dccm or vdccm
     */
    if (transport == NULL || strncmp(transport,  "ppp", 3) == 0) {
        /*
         *  original dccm or vdccm
         */
        if ( !synce_socket_connect(context->socket, synce_info_get_device_ip(info), RAPI_PORT) )
        {
            synce_error("failed to connect to %s", synce_info_get_device_ip(info));
            goto fail;
        }

        const char *password = synce_info_get_password(info);
        if (password && strlen(password))
        {
            bool password_correct = false;

            if (!synce_password_send(context->socket, password, (unsigned char)synce_info_get_key(info)))
            {
                synce_error("failed to send password");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!synce_password_recv_reply(context->socket, 1, &password_correct))
            {
                synce_error("failed to get password reply");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!password_correct)
            {
                synce_error("invalid password");
                result = E_ACCESSDENIED;
                goto fail;
            }
        }
        context->rapi_ops = &rapi_ops;
    } else {
        /*
         *  odccm, udev, or proxy ?
         */
#if ENABLE_ODCCM_SUPPORT
        if (strcmp(transport, "odccm") == 0) {
	  int fd = -1;
	  HRESULT fd_result = get_connection_from_udev_or_odccm(info, &fd);
	  if (fd_result != S_OK)
	  {
	    synce_error("failed to get context fd from odccm: %08x: %s", fd_result, synce_strerror(HRESULT_CODE(fd_result)));
	    result = fd_result;
	    goto fail;
	  }
	  synce_socket_take_descriptor(context->socket, fd);
        }
        else
#endif
#if ENABLE_UDEV_SUPPORT
        if (strcmp(transport, "udev") == 0) {
	  int fd = -1;
	  HRESULT fd_result = get_connection_from_udev_or_odccm(info, &fd);
	  if (fd_result != S_OK)
	  {
	    synce_error("failed to get context fd from udev: %08x: %s", fd_result, synce_strerror(HRESULT_CODE(fd_result)));
	    result = fd_result;
	    goto fail;
	  }
	  synce_socket_take_descriptor(context->socket, fd);
        }
        else
#endif
	if ( !synce_socket_connect_proxy(context->socket, synce_info_get_device_ip(info)) )
        {
            synce_error("failed to connect to proxy for %s", synce_info_get_device_ip(info));
            goto fail;
        }

	/* rapi 2 seems to be used on devices with OS version of 5.1 or greater */

        unsigned int os_major = 0, os_minor = 0;
        synce_info_get_os_version(info, &os_major, &os_minor);
	if ((os_major > 4) && (os_minor > 0))
	  context->rapi_ops = &rapi2_ops;
	else
	  context->rapi_ops = &rapi_ops;
    }

    if (!context->info)
    {
      context->info = info;
      context->own_info = true;
    }

    context->is_initialized = true;
    result = S_OK;

fail:
    if (!context->info)
        synce_info_destroy(info);
    return result;
}
HRESULT rapi_context_connect(RapiContext* context)
{
	HRESULT result = E_FAIL;
  SynceInfo* info = NULL;

	if (context->is_initialized)
	{
		/* Fail immediately */
		return CERAPI_E_ALREADYINITIALIZED;
	}

  if (context->info)
    info = context->info;
  else
    info = synce_info_new(NULL);
  if (!info)
	{
		synce_error("Failed to get connection info");
		goto fail;
	}

	if (!info->dccm_pid)
	{
		synce_error("DCCM PID entry not found for current connection");
		goto fail;
	}

	if (kill(info->dccm_pid, 0) < 0)
	{
		if (errno != EPERM)
		{
			synce_error("DCCM not running with pid %i", info->dccm_pid);
			goto fail;
		}
	}

	if (!info->ip)
	{
		synce_error("IP entry not found for current connection");
		goto fail;
	}

    if (info->transport == NULL || strncmp(info->transport,  "ppp", 3) == 0) {
        if ( !synce_socket_connect(context->socket, info->ip, RAPI_PORT) )
        {
            synce_error("failed to connect to %s", info->ip);
		  goto fail;
        }

        if (info->password && strlen(info->password))
        {
            bool password_correct = false;

            if (!synce_password_send(context->socket, info->password, info->key))
            {
                synce_error("failed to send password");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!synce_password_recv_reply(context->socket, 1, &password_correct))
            {
                synce_error("failed to get password reply");
                result = E_ACCESSDENIED;
                goto fail;
            }

            if (!password_correct)
            {
                synce_error("invalid password");
                result = E_ACCESSDENIED;
                goto fail;
            }
        }
        context->rapi_ops = &rapi_ops;
    } else {
        if ( !synce_socket_connect_proxy(context->socket, info->ip) )
        {
            synce_error("failed to connect to proxy for %s", info->ip);
            goto fail;
        }
        context->rapi_ops = &rapi2_ops;
    }

	context->is_initialized = true;
	result = S_OK;

fail:
  if (!context->info)
    synce_info_destroy(info);
	return result;
}