static void
ft_transfer_operation_callback (EmpathyTpFile *tp_file,
    const GError *error,
    gpointer user_data)
{
  EmpathyFTHandler *handler = user_data;
  EmpathyFTHandlerPriv *priv = GET_PRIV (handler);

  DEBUG ("Transfer operation callback, error %p", error);

  if (error != NULL)
    {
      emit_error_signal (handler, error);
    }
  else
    {
      priv->is_completed = TRUE;
      g_signal_emit (handler, signals[TRANSFER_DONE], 0, tp_file);

      empathy_tp_file_close (tp_file);

      if (empathy_ft_handler_is_incoming (handler) && priv->use_hash)
        {
          check_hash_incoming (handler);
        }
    }
}
Beispiel #2
0
static void
ft_transfer_state_cb (TpFileTransferChannel *channel,
    GParamSpec *pspec,
    EmpathyFTHandler *handler)
{
  EmpathyFTHandlerPriv *priv = handler->priv;
  TpFileTransferStateChangeReason reason;
  TpFileTransferState state = tp_file_transfer_channel_get_state (
      channel, &reason);

  (void)pspec;      /* suppress unused-parameter warning */

  if (state == TP_FILE_TRANSFER_STATE_COMPLETED)
    {
      priv->is_completed = TRUE;
      g_signal_emit (handler, signals[TRANSFER_DONE], 0, channel);

      tp_channel_close_async (TP_CHANNEL (channel), NULL, NULL);

      if (empathy_ft_handler_is_incoming (handler) && priv->use_hash)
        {
          check_hash_incoming (handler);
        }
    }
  else if (state == TP_FILE_TRANSFER_STATE_CANCELLED)
    {
      GError *error = error_from_state_change_reason (reason);
      emit_error_signal (handler, error);
      g_clear_error (&error);
    }
}
Beispiel #3
0
static void
ft_transfer_accept_cb (GObject *source,
    GAsyncResult *result,
    gpointer user_data)
{
  TpFileTransferChannel *channel = TP_FILE_TRANSFER_CHANNEL (source);
  EmpathyFTHandler *handler = user_data;
  GError *error = NULL;

  if (!tp_file_transfer_channel_accept_file_finish (channel, result, &error))
    {
      emit_error_signal (handler, error);
      g_clear_error (&error);
    }
}
Beispiel #4
0
static void
ft_handler_read_async_cb (GObject *source,
    GAsyncResult *res,
    gpointer user_data)
{
  GFileInputStream *stream;
  GError *error = NULL;
  HashingData *hash_data;
  EmpathyFTHandler *handler = user_data;
  EmpathyFTHandlerPriv *priv = handler->priv;

  (void)source;     /* suppress unused-parameter warning */

  DEBUG ("GFile read async CB.");

  stream = g_file_read_finish (priv->gfile, res, &error);
  if (error != NULL)
    {
      emit_error_signal (handler, error);
      g_clear_error (&error);

      return;
    }

  hash_data = g_slice_new0 (HashingData);
  hash_data->stream = G_INPUT_STREAM (stream);
  hash_data->total_bytes = priv->total_bytes;
  hash_data->handler = g_object_ref (handler);
  /* FIXME: MD5 is the only ContentHashType supported right now */
  hash_data->checksum = g_checksum_new (G_CHECKSUM_MD5);

  tp_asv_set_uint32 (priv->request,
      TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH_TYPE,
      TP_FILE_HASH_TYPE_MD5);

  g_signal_emit (handler, signals[HASHING_STARTED], 0);

  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  g_io_scheduler_push_job (do_hash_job, hash_data, NULL,
      G_PRIORITY_DEFAULT, priv->cancellable);
  #pragma GCC diagnostic pop
}
Beispiel #5
0
static void
ft_handler_create_channel_cb (GObject *source,
    GAsyncResult *result,
    gpointer user_data)
{
  EmpathyFTHandler *handler = user_data;
  EmpathyFTHandlerPriv *priv = handler->priv;
  GError *error = NULL;
  TpChannel *channel;

  DEBUG ("Dispatcher create channel CB");

  channel = tp_account_channel_request_create_and_handle_channel_finish (
        TP_ACCOUNT_CHANNEL_REQUEST (source), result, NULL, &error);

  if (channel == NULL)
    DEBUG ("Failed to request FT channel: %s", error->message);
  else
    g_cancellable_set_error_if_cancelled (priv->cancellable, &error);

  if (error != NULL)
    {
      emit_error_signal (handler, error);

      g_clear_object (&channel);
      g_error_free (error);
      return;
    }

  priv->channel = TP_FILE_TRANSFER_CHANNEL (channel);

  tp_g_signal_connect_object (priv->channel, "notify::state",
      G_CALLBACK (ft_transfer_state_cb), handler, 0);
  tp_g_signal_connect_object (priv->channel, "notify::transferred-bytes",
      G_CALLBACK (ft_transfer_transferred_bytes_cb), handler, 0);

  tp_file_transfer_channel_provide_file_async (priv->channel, priv->gfile,
      ft_transfer_provide_cb, handler);
}
static void
ft_handler_create_channel_cb (GObject *source,
    GAsyncResult *result,
    gpointer user_data)
{
  EmpathyFTHandler *handler = user_data;
  EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
  GError *error = NULL;
  TpChannel *channel = NULL;

  DEBUG ("Dispatcher create channel CB");

  channel = tp_account_channel_request_create_and_handle_channel_finish (
        TP_ACCOUNT_CHANNEL_REQUEST (source), result, NULL, &error);

  if (channel == NULL)
    DEBUG ("Failed to request FT channel: %s", error->message);
  else
    g_cancellable_set_error_if_cancelled (priv->cancellable, &error);

  if (error != NULL)
    {
      emit_error_signal (handler, error);

      g_error_free (error);
      goto out;
    }

  priv->tpfile = empathy_tp_file_new (channel);

  empathy_tp_file_offer (priv->tpfile, priv->gfile, priv->cancellable,
      ft_transfer_progress_callback, handler,
      ft_transfer_operation_callback, handler);

out:
  tp_clear_object (&channel);
}
static gboolean
hash_job_done (gpointer user_data)
{
  HashingData *hash_data = user_data;
  EmpathyFTHandler *handler = hash_data->handler;
  EmpathyFTHandlerPriv *priv;
  GError *error = NULL;

  DEBUG ("Closing stream after hashing.");

  priv = GET_PRIV (handler);

  if (hash_data->error != NULL)
    {
      error = hash_data->error;
      hash_data->error = NULL;
      goto cleanup;
    }

  DEBUG ("Got file hash %s", g_checksum_get_string (hash_data->checksum));

  if (empathy_ft_handler_is_incoming (handler))
    {
      if (g_strcmp0 (g_checksum_get_string (hash_data->checksum),
                     priv->content_hash))
        {
          DEBUG ("Hash mismatch when checking incoming handler: "
                 "received %s, calculated %s", priv->content_hash,
                 g_checksum_get_string (hash_data->checksum));

          error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
              EMPATHY_FT_ERROR_HASH_MISMATCH,
              _("File transfer completed, but the file was corrupted"));
          goto cleanup;
        }
      else
        {
          DEBUG ("Hash verification matched, received %s, calculated %s",
                 priv->content_hash,
                 g_checksum_get_string (hash_data->checksum));
        }
    }
  else
    {
      /* set the checksum in the request...
       * org.freedesktop.Telepathy.Channel.Type.FileTransfer.ContentHash
       */
      tp_asv_set_string (priv->request,
          TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH,
          g_checksum_get_string (hash_data->checksum));
    }

cleanup:

  if (error != NULL)
    {
      emit_error_signal (handler, error);
      g_clear_error (&error);
    }
  else
    {
      g_signal_emit (handler, signals[HASHING_DONE], 0);

      if (!empathy_ft_handler_is_incoming (handler))
        /* the request is complete now, push it to the dispatcher */
        ft_handler_push_to_dispatcher (handler);
    }

  hash_data_free (hash_data);

  return FALSE;
}