diff options
author | Rob Staudinger <robsta@linux.intel.com> | 2012-02-03 11:25:00 +0100 |
---|---|---|
committer | Rob Staudinger <robsta@linux.intel.com> | 2012-02-03 11:38:01 +0100 |
commit | 2d0380472367bb5435e0f689b0f5251d0bca3c56 (patch) | |
tree | 3a54151e074d7025be409b861baa43ae5256dced | |
parent | d3b84c2c71e33539e909a77f90ddf1fad0bae3f6 (diff) |
File transfer: remove old style file transfer code
Get rid of all the original file transfer code based on EmpathyTpFile,
as we are moving to the new ytstenut service-based API.
-rw-r--r-- | ytstenut/Makefile.am | 2 | ||||
-rw-r--r-- | ytstenut/empathy-tp-file.c | 1070 | ||||
-rw-r--r-- | ytstenut/empathy-tp-file.h | 131 | ||||
-rw-r--r-- | ytstenut/yts-client.c | 400 | ||||
-rw-r--r-- | ytstenut/yts-client.h | 8 | ||||
-rw-r--r-- | ytstenut/yts-contact.c | 508 | ||||
-rw-r--r-- | ytstenut/yts-contact.h | 9 | ||||
-rw-r--r-- | ytstenut/yts-roster-internal.h | 4 | ||||
-rw-r--r-- | ytstenut/yts-roster.c | 35 | ||||
-rw-r--r-- | ytstenut/ytstenut.sym | 4 |
10 files changed, 2 insertions, 2169 deletions
diff --git a/ytstenut/Makefile.am b/ytstenut/Makefile.am index 7792059..e0b4e05 100644 --- a/ytstenut/Makefile.am +++ b/ytstenut/Makefile.am @@ -41,7 +41,6 @@ libhdr_la_SOURCES = \ libsrc_la_SOURCES = \ $(srcdir)/ytstenut.c \ \ - $(srcdir)/empathy-tp-file.c \ $(srcdir)/yts-capability.c \ $(srcdir)/yts-client.c \ $(srcdir)/yts-client-status.c \ @@ -96,7 +95,6 @@ libsrc_la_SOURCES = \ libprv_la_SOURCES = \ $(srcdir)/ytstenut-internal.h \ \ - $(srcdir)/empathy-tp-file.h \ $(srcdir)/yts-adapter-factory.h \ $(srcdir)/yts-client-internal.h \ $(srcdir)/yts-client-status.h \ diff --git a/ytstenut/empathy-tp-file.c b/ytstenut/empathy-tp-file.c deleted file mode 100644 index ac11e4b..0000000 --- a/ytstenut/empathy-tp-file.c +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * Copyright (C) 2007-2009 Collabora Ltd. - * Copyright (C) 2007 Marco Barisione <marco@barisione.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Marco Barisione <marco@barisione.org> - * Jonny Lamb <jonny.lamb@collabora.co.uk> - * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> - */ - - /* 29/09/2010: modified for Ytstenut use by Tomas Frydrych <tf@linux.intel.com> - * - * - added :incoming property - * - use Yts debug macros - */ - -#include <config.h> - -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <glib.h> -#include <gio/gio.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/proxy-subclass.h> - -#ifdef G_OS_WIN32 -#include <windows.h> -#include <ws2tcpip.h> -#include <gio/gwin32inputstream.h> -#include <gio/gwin32outputstream.h> -#else -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <gio/gunixinputstream.h> -#include <gio/gunixoutputstream.h> -#endif - -#if 0 -#include <glib/gi18n-lib.h> -#else -#define _(x) (x) -#endif - -#include <telepathy-glib/util.h> -#include <telepathy-glib/interfaces.h> - -#include "empathy-tp-file.h" -#include "yts-marshal.h" - -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN PACKAGE"\0file-transfer\0"G_STRLOC - -#if 0 -#include "empathy-time.h" -#include "empathy-utils.h" -#endif - -/** - * SECTION:empathy-tp-file - * @title: EmpathyTpFile - * @short_description: Object which represents a Telepathy file channel - * @include: libempathy/empathy-tp-file.h - * - * #EmpathyTpFile is an object which represents a Telepathy file channel. - * Usually, clients do not need to deal with #EmpathyTpFile objects directly, - * and are supposed to use #EmpathyFTHandler and #EmpathyFTFactory for - * transferring files using libempathy. - */ - -/* EmpathyTpFile object */ - -typedef struct { - TpChannel *channel; - gboolean ready; - - GInputStream *in_stream; - GOutputStream *out_stream; - - /* org.freedesktop.Telepathy.Channel.Type.FileTransfer D-Bus properties */ - TpFileTransferState state; - TpFileTransferStateChangeReason state_change_reason; - TpSocketAddressType socket_address_type; - TpSocketAccessControl socket_access_control; - - /* transfer properties */ - gboolean incoming; - time_t start_time; - GArray *socket_address; - guint port; - guint64 offset; - - /* GCancellable we're passed when offering/accepting the transfer */ - GCancellable *cancellable; - - /* callbacks for the operation */ - EmpathyTpFileProgressCallback progress_callback; - gpointer progress_user_data; - EmpathyTpFileOperationCallback op_callback; - gpointer op_user_data; - - gboolean is_closed; - - gboolean dispose_run; -} EmpathyTpFilePriv; - -enum { - PROP_0, - PROP_CHANNEL, - PROP_INCOMING -}; - -#define GET_PRIV(obj) EMPATHY_TP_FILE (obj)->priv - -G_DEFINE_TYPE (EmpathyTpFile, empathy_tp_file, G_TYPE_OBJECT); - -/* private functions */ - -static void -tp_file_get_state_cb (TpProxy *proxy, - const GValue *value, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - EmpathyTpFilePriv *priv = GET_PRIV (weak_object); - - if (error != NULL) - { - /* set a default value for the state */ - priv->state = TP_FILE_TRANSFER_STATE_NONE; - return; - } - - priv->state = g_value_get_uint (value); -} - -static void -tp_file_get_available_socket_types_cb (TpProxy *proxy, - const GValue *value, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - EmpathyTpFilePriv *priv = GET_PRIV (weak_object); - GHashTable *socket_types; - GArray *access_controls; - - if (error != NULL || - !G_VALUE_HOLDS (value, TP_HASH_TYPE_SUPPORTED_SOCKET_MAP)) - { - /* set a default value */ - priv->socket_address_type = TP_SOCKET_ADDRESS_TYPE_UNIX; - priv->socket_access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST; - goto out; - } - - socket_types = g_value_get_boxed (value); - - /* here UNIX is preferred to IPV4 */ - if ((access_controls = g_hash_table_lookup (socket_types, - GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX))) != NULL) - { - priv->socket_address_type = TP_SOCKET_ADDRESS_TYPE_UNIX; - priv->socket_access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST; - goto out; - } - - if ((access_controls = g_hash_table_lookup (socket_types, - GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_IPV4))) != NULL) - { - priv->socket_address_type = TP_SOCKET_ADDRESS_TYPE_IPV4; - - /* TODO: we should prefer PORT over LOCALHOST when the CM will - * support it. - */ - - priv->socket_access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST; - } - -out: - g_message ("Socket address type: %u, access control %u", - priv->socket_address_type, priv->socket_access_control); -} - -static void -tp_file_invalidated_cb (TpProxy *proxy, - guint domain, - gint code, - gchar *message, - EmpathyTpFile *tp_file) -{ - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - g_message ("Channel invalidated: %s", message); - - if (priv->state != TP_FILE_TRANSFER_STATE_COMPLETED && - priv->state != TP_FILE_TRANSFER_STATE_CANCELLED) - { - /* The channel is not in a finished state, an error occured */ - priv->state = TP_FILE_TRANSFER_STATE_CANCELLED; - priv->state_change_reason = - TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_ERROR; - } -} - -static void -ft_operation_close_clean (EmpathyTpFile *tp_file) -{ - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - if (priv->is_closed) - return; - - g_message ("FT operation close clean"); - - priv->is_closed = TRUE; - - if (priv->op_callback != NULL) - priv->op_callback (tp_file, NULL, priv->op_user_data); -} - -static void -ft_operation_close_with_error (EmpathyTpFile *tp_file, - GError *error) -{ - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - if (priv->is_closed) - return; - - g_message ("FT operation close with error %s", error->message); - - priv->is_closed = TRUE; - - /* close the channel if it's not cancelled already */ - if (priv->state != TP_FILE_TRANSFER_STATE_CANCELLED) - empathy_tp_file_cancel (tp_file); - - if (priv->op_callback != NULL) - priv->op_callback (tp_file, error, priv->op_user_data); -} - -static void -splice_stream_ready_cb (GObject *source, - GAsyncResult *res, - gpointer user_data) -{ - EmpathyTpFile *tp_file; - GError *error = NULL; - - tp_file = user_data; - - g_output_stream_splice_finish (G_OUTPUT_STREAM (source), res, &error); - - g_message ("Splice stream ready cb, error %p", error); - - if (error != NULL) - { - ft_operation_close_with_error (tp_file, error); - g_clear_error (&error); - return; - } -} - -static void -tp_file_start_transfer (EmpathyTpFile *tp_file) -{ - gint fd, domain, res = 0; - GError *error = NULL; - struct sockaddr *my_addr = NULL; - size_t my_size = 0; - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_UNIX) - { - domain = AF_UNIX; - } - else if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_IPV4) - { - domain = AF_INET; - } - else - { - error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK, - EMPATHY_FT_ERROR_NOT_SUPPORTED, _("Socket type not supported")); - - g_message ("Socket not supported, closing channel"); - - ft_operation_close_with_error (tp_file, error); - g_clear_error (&error); - - return; - } - - fd = socket (domain, SOCK_STREAM, 0); - - if (fd < 0) - { - int code = errno; - - error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK, - EMPATHY_FT_ERROR_SOCKET, g_strerror (code)); - - g_message ("Failed to create socket, closing channel"); - - ft_operation_close_with_error (tp_file, error); - g_clear_error (&error); - - return; - } -#ifdef G_OS_UNIX - if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_UNIX) - { - struct sockaddr_un addr; - - memset (&addr, 0, sizeof (addr)); - addr.sun_family = domain; - strncpy (addr.sun_path, priv->socket_address->data, - priv->socket_address->len); - - my_addr = (struct sockaddr *) &addr; - my_size = sizeof (addr); - } -#endif - if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_IPV4) - { - struct sockaddr_in addr; - - memset (&addr, 0, sizeof (addr)); - addr.sin_family = domain; -#ifdef G_OS_WIN32 - addr.sin_addr.s_addr = inet_addr ((const char * ) priv->socket_address->data); -#else - inet_pton (AF_INET, priv->socket_address->data, &addr.sin_addr); -#endif - addr.sin_port = htons (priv->port); - - my_addr = (struct sockaddr *) &addr; - my_size = sizeof (addr); - } - - res = connect (fd, my_addr, my_size); - - if (res < 0) - { - int code = errno; - - error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK, - EMPATHY_FT_ERROR_SOCKET, g_strerror (code)); - - g_message ("Failed to connect socket, closing channel"); - - ft_operation_close_with_error (tp_file, error); - close (fd); - g_clear_error (&error); - - return; - } - - g_message ("Start the transfer"); - -#if 0 - priv->start_time = empathy_time_get_current (); -#endif - - /* notify we're starting a transfer */ - if (priv->progress_callback != NULL) - priv->progress_callback (tp_file, 0, priv->progress_user_data); - - if (priv->incoming) - { - GInputStream *socket_stream; -#ifdef G_OS_WIN32 - socket_stream = g_win32_input_stream_new (fd, TRUE); -#else - socket_stream = g_unix_input_stream_new (fd, TRUE); -#endif - g_output_stream_splice_async (priv->out_stream, socket_stream, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - G_PRIORITY_DEFAULT, priv->cancellable, - splice_stream_ready_cb, tp_file); - - g_object_unref (socket_stream); - } - else - { - GOutputStream *socket_stream; -#ifdef G_OS_WIN32 - socket_stream = g_win32_output_stream_new (fd, TRUE); -#else - socket_stream = g_unix_output_stream_new (fd, TRUE); -#endif - - g_output_stream_splice_async (socket_stream, priv->in_stream, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | - G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - G_PRIORITY_DEFAULT, priv->cancellable, - splice_stream_ready_cb, tp_file); - - g_object_unref (socket_stream); - } -} - -static GError * -error_from_state_change_reason (TpFileTransferStateChangeReason reason) -{ - const char *string; - GError *retval = NULL; - - string = NULL; - - switch (reason) - { - case TP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE: - string = _("No reason was specified"); - break; - case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED: - string = _("The change in state was requested"); - break; - case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_STOPPED: - string = _("You canceled the file transfer"); - break; - case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_STOPPED: - string = _("The other participant canceled the file transfer"); - break; - case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_ERROR: - string = _("Error while trying to transfer the file"); - break; - case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_ERROR: - string = _("The other participant is unable to transfer the file"); - break; - default: - string = _("Unknown reason"); - break; - } - - retval = g_error_new_literal (EMPATHY_FT_ERROR_QUARK, - EMPATHY_FT_ERROR_TP_ERROR, string); - - return retval; -} - -static void -tp_file_state_changed_cb (TpChannel *proxy, - guint state, - guint reason, - gpointer user_data, - GObject *weak_object) -{ - EmpathyTpFilePriv *priv = GET_PRIV (weak_object); - GError *error = NULL; - - if (state == priv->state) - return; - - g_message ("File transfer state changed:\n" - "old state = %u, state = %u, reason = %u\n" - "\tincoming = %s, in_stream = %s, out_stream = %s", - priv->state, state, reason, - priv->incoming ? "yes" : "no", - priv->in_stream ? "present" : "not present", - priv->out_stream ? "present" : "not present"); - - priv->state = state; - priv->state_change_reason = reason; - - /* If the channel is open AND we have the socket path, we can start the - * transfer. The socket path could be NULL if we are not doing the actual - * data transfer but are just an observer for the channel. - */ - if (state == TP_FILE_TRANSFER_STATE_OPEN && - priv->socket_address != NULL) - tp_file_start_transfer (EMPATHY_TP_FILE (weak_object)); - - if (state == TP_FILE_TRANSFER_STATE_COMPLETED) - ft_operation_close_clean (EMPATHY_TP_FILE (weak_object)); - - if (state == TP_FILE_TRANSFER_STATE_CANCELLED) - { - error = error_from_state_change_reason (priv->state_change_reason); - ft_operation_close_with_error (EMPATHY_TP_FILE (weak_object), error); - g_clear_error (&error); - } -} - -static void -tp_file_transferred_bytes_changed_cb (TpChannel *proxy, - guint64 count, - gpointer user_data, - GObject *weak_object) -{ - EmpathyTpFilePriv *priv = GET_PRIV (weak_object); - - /* don't notify for 0 bytes count */ - if (count == 0) - return; - - /* notify clients */ - if (priv->progress_callback != NULL) - priv->progress_callback (EMPATHY_TP_FILE (weak_object), - count, priv->progress_user_data); -} - -static void -ft_operation_provide_or_accept_file_cb (TpChannel *proxy, - const GValue *address, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - EmpathyTpFile *tp_file = EMPATHY_TP_FILE (weak_object); - GError *myerr = NULL; - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - g_cancellable_set_error_if_cancelled (priv->cancellable, &myerr); - - if (error != NULL) - { - if (myerr != NULL) - { - /* if we were both cancelled and failed when calling the method, - * report the method error. - */ - g_clear_error (&myerr); - } - - myerr = g_error_copy (error); - } - - if (myerr != NULL) - { - g_message ("Error: %s", myerr->message); - ft_operation_close_with_error (tp_file, myerr); - g_clear_error (&myerr); - return; - } - - if (G_VALUE_TYPE (address) == DBUS_TYPE_G_UCHAR_ARRAY) - { - priv->socket_address = g_value_dup_boxed (address); - } - else if (G_VALUE_TYPE (address) == G_TYPE_STRING) - { - /* Old bugged version of telepathy-salut used to store the address - * as a 's' instead of an 'ay' */ - const gchar *path; - - path = g_value_get_string (address); - priv->socket_address = g_array_sized_new (TRUE, FALSE, sizeof (gchar), - strlen (path)); - g_array_insert_vals (priv->socket_address, 0, path, strlen (path)); - } - else if (G_VALUE_TYPE (address) == TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4) - { - GValueArray *val_array; - GValue *v; - const char *addr; - - val_array = g_value_get_boxed (address); - - /* IPV4 address */ - v = g_value_array_get_nth (val_array, 0); - addr = g_value_get_string (v); - priv->socket_address = g_array_sized_new (TRUE, FALSE, sizeof (gchar), - strlen (addr)); - g_array_insert_vals (priv->socket_address, 0, addr, strlen (addr)); - - /* port number */ - v = g_value_array_get_nth (val_array, 1); - priv->port = g_value_get_uint (v); - } - - g_message ("Got socket address: %s, port (not zero if IPV4): %d", - priv->socket_address->data, priv->port); - - /* if the channel is already open, start the transfer now, otherwise, - * wait for the state change signal. - */ - if (priv->state == TP_FILE_TRANSFER_STATE_OPEN) - tp_file_start_transfer (tp_file); -} - -static void -initialize_empty_ac_variant (TpSocketAccessControl ac, - GValue *val) -{ - /* TODO: we will add more types here once we support PORT access control. */ - if (ac == TP_SOCKET_ACCESS_CONTROL_LOCALHOST) - { - g_value_init (val, G_TYPE_STRING); - g_value_set_static_string (val, ""); - } -} - -static void -file_read_async_cb (GObject *source, - GAsyncResult *res, - gpointer user_data) -{ - GValue nothing = { 0 }; - EmpathyTpFile *tp_file = user_data; - EmpathyTpFilePriv *priv; - GFileInputStream *in_stream; - GError *error = NULL; - - priv = GET_PRIV (tp_file); - - in_stream = g_file_read_finish (G_FILE (source), res, &error); - - if (error != NULL) - { - ft_operation_close_with_error (tp_file, error); - g_clear_error (&error); - return; - } - - priv->in_stream = G_INPUT_STREAM (in_stream); - - /* we don't impose specific interface/port requirements even - * if we're not using UNIX sockets. - */ - initialize_empty_ac_variant (priv->socket_access_control, ¬hing); - - tp_cli_channel_type_file_transfer_call_provide_file ( - priv->channel, -1, - priv->socket_address_type, priv->socket_access_control, - ¬hing, ft_operation_provide_or_accept_file_cb, - NULL, NULL, G_OBJECT (tp_file)); -} - -static void -file_replace_async_cb (GObject *source, - GAsyncResult *res, - gpointer user_data) -{ - GValue nothing = { 0 }; - EmpathyTpFile *tp_file = user_data; - EmpathyTpFilePriv *priv; - GError *error = NULL; - GFileOutputStream *out_stream; - - priv = GET_PRIV (tp_file); - - out_stream = g_file_replace_finish (G_FILE (source), res, &error); - - if (error != NULL) - { - ft_operation_close_with_error (tp_file, error); - g_clear_error (&error); - - return; - } - - priv->out_stream = G_OUTPUT_STREAM (out_stream); - - /* we don't impose specific interface/port requirements even - * if we're not using UNIX sockets. - */ - initialize_empty_ac_variant (priv->socket_access_control, ¬hing); - - tp_cli_channel_type_file_transfer_call_accept_file (priv->channel, - -1, priv->socket_address_type, priv->socket_access_control, - ¬hing, priv->offset, - ft_operation_provide_or_accept_file_cb, NULL, NULL, G_OBJECT (tp_file)); -} - -static void -channel_closed_cb (TpChannel *proxy, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - EmpathyTpFile *tp_file = EMPATHY_TP_FILE (weak_object); - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - gboolean cancel = GPOINTER_TO_INT (user_data); - - g_message ("Channel is closed, should cancel %s", - cancel ? "True" : "False"); - - if (priv->cancellable != NULL && - !g_cancellable_is_cancelled (priv->cancellable) && cancel) - g_cancellable_cancel (priv->cancellable); -} - -static void -close_channel_internal (EmpathyTpFile *tp_file, - gboolean cancel) -{ - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - g_message ("Closing channel, should cancel %s", cancel ? - "True" : "False"); - - tp_cli_channel_call_close (priv->channel, -1, - channel_closed_cb, GINT_TO_POINTER (cancel), NULL, G_OBJECT (tp_file)); -} - -/* GObject methods */ - -static void -empathy_tp_file_init (EmpathyTpFile *tp_file) -{ - EmpathyTpFilePriv *priv; - - priv = G_TYPE_INSTANCE_GET_PRIVATE ((tp_file), - EMPATHY_TYPE_TP_FILE, EmpathyTpFilePriv); - - tp_file->priv = priv; -} - -static void -do_dispose (GObject *object) -{ - EmpathyTpFilePriv *priv = GET_PRIV (object); - - if (priv->dispose_run) - return; - - priv->dispose_run = TRUE; - - if (priv->channel != NULL) - { - g_signal_handlers_disconnect_by_func (priv->channel, - tp_file_invalidated_cb, object); - g_object_unref (priv->channel); - priv->channel = NULL; - } - - if (priv->in_stream != NULL) - g_object_unref (priv->in_stream); - - if (priv->out_stream != NULL) - g_object_unref (priv->out_stream); - - if (priv->cancellable != NULL) - g_object_unref (priv->cancellable); - - G_OBJECT_CLASS (empathy_tp_file_parent_class)->dispose (object); -} - -static void -do_finalize (GObject *object) -{ - EmpathyTpFilePriv *priv = GET_PRIV (object); - - if (priv->socket_address != NULL) - { - g_array_free (priv->socket_address, TRUE); - priv->socket_address = NULL; - } - - G_OBJECT_CLASS (empathy_tp_file_parent_class)->finalize (object); -} - -static void -do_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - EmpathyTpFilePriv *priv = GET_PRIV (object); - - switch (param_id) - { - case PROP_CHANNEL: - g_value_set_object (value, priv->channel); - break; - case PROP_INCOMING: - g_value_set_boolean (value, priv->incoming); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - }; -} - -static void -do_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - EmpathyTpFilePriv *priv = GET_PRIV (object); - switch (param_id) - { - case PROP_CHANNEL: - priv->channel = g_object_ref (g_value_get_object (value)); - break; - case PROP_INCOMING: - priv->incoming = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - }; -} - -static void -do_constructed (GObject *object) -{ - EmpathyTpFile *tp_file; - EmpathyTpFilePriv *priv; - - tp_file = EMPATHY_TP_FILE (object); - priv = GET_PRIV (tp_file); - - g_signal_connect (priv->channel, "invalidated", - G_CALLBACK (tp_file_invalidated_cb), tp_file); - - tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed ( - priv->channel, tp_file_state_changed_cb, NULL, NULL, object, NULL); - - tp_cli_channel_type_file_transfer_connect_to_transferred_bytes_changed ( - priv->channel, tp_file_transferred_bytes_changed_cb, - NULL, NULL, object, NULL); - - tp_cli_dbus_properties_call_get (priv->channel, - -1, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "State", tp_file_get_state_cb, - NULL, NULL, object); - - tp_cli_dbus_properties_call_get (priv->channel, - -1, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "AvailableSocketTypes", - tp_file_get_available_socket_types_cb, NULL, NULL, object); - - priv->state_change_reason = - TP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE; -} - -static void -empathy_tp_file_class_init (EmpathyTpFileClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = do_finalize; - object_class->dispose = do_dispose; - object_class->constructed = do_constructed; - object_class->get_property = do_get_property; - object_class->set_property = do_set_property; - - /* Construct-only properties */ - - /** - * EmpathyTpFile:channel: - * - * The #TpChannel requested for the file transfer. - */ - g_object_class_install_property (object_class, - PROP_CHANNEL, - g_param_spec_object ("channel", - "telepathy channel", - "The file transfer channel", - TP_TYPE_CHANNEL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - /** - * EmpathyTpFile:incoming: - * - * %TRUE if the transfer is incoming, %FALSE if it's outgoing. - */ - g_object_class_install_property (object_class, - PROP_INCOMING, - g_param_spec_boolean ("incoming", - "direction of transfer", - "The direction of the file being transferred", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (object_class, sizeof (EmpathyTpFilePriv)); -} - -/* public methods */ - -/** - * empathy_tp_file_new: - * @channel: a #TpChannel - * @incoming: whether the file transfer is incoming or not - * - * Creates a new #EmpathyTpFile wrapping @channel, with the direction - * specified by @incoming. The returned #EmpathyTpFile should be unrefed - * with g_object_unref() when finished with. - * - * Return value: a new #EmpathyTpFile - */ -EmpathyTpFile * -empathy_tp_file_new (TpChannel *channel, - gboolean incoming) -{ - EmpathyTpFile *tp_file; - - g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL); - - tp_file = g_object_new (EMPATHY_TYPE_TP_FILE, - "channel", channel, "incoming", incoming, - NULL); - - return tp_file; -} - -/** - * empathy_tp_file_accept: - * @tp_file: an incoming #EmpathyTpFile - * @offset: the offset of @gfile where we should start writing - * @gfile: the destination #GFile for the transfer - * @cancellable: a #GCancellable - * @progress_callback: function to callback with progress information - * @progress_user_data: user_data to pass to @progress_callback - * @op_callback: function to callback when the transfer ends - * @op_user_data: user_data to pass to @op_callback - * - * Accepts an incoming file transfer, saving the result into @gfile. - * The callback @op_callback will be called both when the transfer is - * successful and in case of an error. Note that cancelling @cancellable, - * closes the socket of the file operation in progress, but doesn't - * guarantee that the transfer channel will be closed as well. Thus, - * empathy_tp_file_cancel() or empathy_tp_file_close() should be used to - * actually cancel an ongoing #EmpathyTpFile. - */ -void -empathy_tp_file_accept (EmpathyTpFile *tp_file, - guint64 offset, - GFile *gfile, - GCancellable *cancellable, - EmpathyTpFileProgressCallback progress_callback, - gpointer progress_user_data, - EmpathyTpFileOperationCallback op_callback, - gpointer op_user_data) -{ - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file)); - g_return_if_fail (G_IS_FILE (gfile)); - g_return_if_fail (G_IS_CANCELLABLE (cancellable)); - - priv->cancellable = g_object_ref (cancellable); - priv->progress_callback = progress_callback; - priv->progress_user_data = progress_user_data; - priv->op_callback = op_callback; - priv->op_user_data = op_user_data; - priv->offset = offset; - - g_file_replace_async (gfile, NULL, FALSE, G_FILE_CREATE_NONE, - G_PRIORITY_DEFAULT, cancellable, file_replace_async_cb, tp_file); -} - - -/** - * empathy_tp_file_offer: - * @tp_file: an outgoing #EmpathyTpFile - * @gfile: the source #GFile for the transfer - * @cancellable: a #GCancellable - * @progress_callback: function to callback with progress information - * @progress_user_data: user_data to pass to @progress_callback - * @op_callback: function to callback when the transfer ends - * @op_user_data: user_data to pass to @op_callback - * - * Offers an outgoing file transfer, reading data from @gfile. - * The callback @op_callback will be called both when the transfer is - * successful and in case of an error. Note that cancelling @cancellable, - * closes the socket of the file operation in progress, but doesn't - * guarantee that the transfer channel will be closed as well. Thus, - * empathy_tp_file_cancel() or empathy_tp_file_close() should be used to - * actually cancel an ongoing #EmpathyTpFile. - */ -void -empathy_tp_file_offer (EmpathyTpFile *tp_file, - GFile *gfile, - GCancellable *cancellable, - EmpathyTpFileProgressCallback progress_callback, - gpointer progress_user_data, - EmpathyTpFileOperationCallback op_callback, - gpointer op_user_data) -{ - EmpathyTpFilePriv *priv = GET_PRIV (tp_file); - - g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file)); - g_return_if_fail (G_IS_FILE (gfile)); - g_return_if_fail (G_IS_CANCELLABLE (cancellable)); - - priv->cancellable = g_object_ref (cancellable); - priv->progress_callback = progress_callback; - priv->progress_user_data = progress_user_data; - priv->op_callback = op_callback; - priv->op_user_data = op_user_data; - - g_file_read_async (gfile, G_PRIORITY_DEFAULT, cancellable, - file_read_async_cb, tp_file); -} - -/** - * empathy_tp_file_is_incoming: - * @tp_file: an #EmpathyTpFile - * - * Returns whether @tp_file is incoming. - * - * Return value: %TRUE if the @tp_file is incoming, otherwise %FALSE - */ -gboolean -empathy_tp_file_is_incoming (EmpathyTpFile *tp_file) -{ - EmpathyTpFilePriv *priv; - - g_return_val_if_fail (EMPATHY_IS_TP_FILE (tp_file), FALSE); - - priv = GET_PRIV (tp_file); - - return priv->incoming; -} - -/** - * empathy_tp_file_cancel: - * @tp_file: an #EmpathyTpFile - * - * Cancels an ongoing #EmpathyTpFile, first closing the channel and then - * cancelling any I/O operation and closing the socket. - */ -void -empathy_tp_file_cancel (EmpathyTpFile *tp_file) -{ - g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file)); - - close_channel_internal (tp_file, TRUE); -} - -/** - * empathy_tp_file_close: - * @tp_file: an #EmpathyTpFile - * - * Closes the channel for an ongoing #EmpathyTpFile. It's safe to call this - * method after the transfer has ended. - */ -void -empathy_tp_file_close (EmpathyTpFile *tp_file) -{ - g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file)); - - close_channel_internal (tp_file, FALSE); -} - -GCancellable * -empathy_tp_file_get_cancellable (EmpathyTpFile *tp_file) -{ - EmpathyTpFilePriv *priv; - - g_return_val_if_fail (EMPATHY_IS_TP_FILE (tp_file), NULL); - - priv = GET_PRIV (tp_file); - - return priv->cancellable; -} - diff --git a/ytstenut/empathy-tp-file.h b/ytstenut/empathy-tp-file.h deleted file mode 100644 index e0b6a42..0000000 --- a/ytstenut/empathy-tp-file.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2007-2009 Collabora Ltd. - * Copyright (C) 2007 Marco Barisione <marco@barisione.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Marco Barisione <marco@barisione.org> - * Jonny Lamb <jonny.lamb@collabora.co.uk> - * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> - */ - - /* - * 29/09/2010: modified for Ytstenut use by Tomas Frydrych <tf@linux.intel.com> - */ - -#ifndef __EMPATHY_TP_FILE_H__ -#define __EMPATHY_TP_FILE_H__ - -#include <gio/gio.h> -#include <glib.h> - -#include <telepathy-glib/channel.h> - -G_BEGIN_DECLS - -#define EMPATHY_TYPE_TP_FILE (empathy_tp_file_get_type ()) -#define EMPATHY_TP_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \ - EMPATHY_TYPE_TP_FILE, EmpathyTpFile)) -#define EMPATHY_TP_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), \ - EMPATHY_TYPE_TP_FILE, EmpathyTpFileClass)) -#define EMPATHY_IS_TP_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ - EMPATHY_TYPE_TP_FILE)) -#define EMPATHY_IS_TP_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \ - EMPATHY_TYPE_TP_FILE)) -#define EMPATHY_TP_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \ - EMPATHY_TYPE_TP_FILE, EmpathyTpFileClass)) - -#define EMPATHY_FT_ERROR_QUARK g_quark_from_static_string ("EmpathyFTError") - -typedef enum { - EMPATHY_FT_ERROR_FAILED, - EMPATHY_FT_ERROR_HASH_MISMATCH, - EMPATHY_FT_ERROR_TP_ERROR, - EMPATHY_FT_ERROR_SOCKET, - EMPATHY_FT_ERROR_NOT_SUPPORTED, - EMPATHY_FT_ERROR_INVALID_SOURCE_FILE, - EMPATHY_FT_ERROR_EMPTY_SOURCE_FILE -} EmpathyFTErrorEnum; - -typedef struct _EmpathyTpFile EmpathyTpFile; -typedef struct _EmpathyTpFileClass EmpathyTpFileClass; - -struct _EmpathyTpFile { - GObject parent; - gpointer priv; -}; - -struct _EmpathyTpFileClass { - GObjectClass parent_class; -}; - -/* prototypes for operation callbacks */ - -/** - * EmpathyTpFileProgressCallback: - * @tp_file: the #EmpathyTpFile being transferred - * @current_bytes: the bytes currently transferred by the operation - * @user_data: user data passed to the callback - **/ -typedef void (* EmpathyTpFileProgressCallback) - (EmpathyTpFile *tp_file, - guint64 current_bytes, - gpointer user_data); - -/** - * EmpathyTpFileOperationCallback: - * @tp_file: the #EmpathyTpFile that has been transferred - * @error: a #GError if the operation didn't succeed, %NULL otherwise - * @user_data: user data passed to the callback - **/ -typedef void (* EmpathyTpFileOperationCallback) - (EmpathyTpFile *tp_file, - const GError *error, - gpointer user_data); - -GType empathy_tp_file_get_type (void) G_GNUC_CONST; - -/* public methods */ - -EmpathyTpFile * empathy_tp_file_new (TpChannel *channel, - gboolean incoming); - -void empathy_tp_file_accept (EmpathyTpFile *tp_file, - guint64 offset, - GFile *gfile, - GCancellable *cancellable, - EmpathyTpFileProgressCallback progress_callback, - gpointer progress_user_data, - EmpathyTpFileOperationCallback op_callback, - gpointer op_user_data); - -void empathy_tp_file_offer (EmpathyTpFile *tp_file, - GFile *gfile, - GCancellable *cancellable, - EmpathyTpFileProgressCallback progress_callback, - gpointer progress_user_data, - EmpathyTpFileOperationCallback op_callback, - gpointer op_user_data); - -void empathy_tp_file_cancel (EmpathyTpFile *tp_file); -void empathy_tp_file_close (EmpathyTpFile *tp_file); - -gboolean empathy_tp_file_is_incoming (EmpathyTpFile *tp_file); - -GCancellable *empathy_tp_file_get_cancellable (EmpathyTpFile *tp_file); - -G_END_DECLS - -#endif /* __EMPATHY_TP_FILE_H__ */ diff --git a/ytstenut/yts-client.c b/ytstenut/yts-client.c index 2faee06..c65eaa6 100644 --- a/ytstenut/yts-client.c +++ b/ytstenut/yts-client.c @@ -33,7 +33,6 @@ #include <telepathy-glib/proxy-subclass.h> #include <telepathy-ytstenut-glib/telepathy-ytstenut-glib.h> -#include "empathy-tp-file.h" #include "ytstenut-internal.h" #include "yts-adapter-factory.h" #include "yts-client-internal.h" @@ -91,8 +90,6 @@ typedef struct { char *service_id; YtsProtocol protocol; - char *incoming_dir; /* destination directory for incoming files */ - /* Telepathy bits */ TpYtsAccountManager *tp_am; TpAccount *tp_account; @@ -135,7 +132,6 @@ enum DICTIONARY_MESSAGE, ERROR, INCOMING_FILE, - INCOMING_FILE_FINISHED, N_SIGNALS, }; @@ -469,262 +465,6 @@ proxy_list_destroy (ProxyList *self) * YtsClient */ -static gboolean -yts_client_channel_requested (TpChannel *proxy) -{ - GHashTable *props; - gboolean requested; - - props = tp_channel_borrow_immutable_properties ((TpChannel*)proxy); - - requested = tp_asv_get_boolean (props, TP_PROP_CHANNEL_REQUESTED, NULL); - - return requested; -} - -static void -yts_client_ft_op_cb (EmpathyTpFile *tp_file, - const GError *error, - gpointer data) -{ - if (error) - { - g_warning ("Incoming file transfer failed: %s", error->message); - } -} - -static void -yts_client_ft_accept_cb (TpProxy *proxy, - GHashTable *props, - const GError *error, - gpointer self, - GObject *weak_object) -{ - YtsClientPrivate *priv = GET_PRIVATE (self); - char const *name; - char const *contact_id; - uint64_t offset; - uint64_t size; - GHashTable *iprops; - YtsContact *item; - guint32 ihandle; - - iprops = tp_channel_borrow_immutable_properties ((TpChannel*)proxy); - - ihandle = tp_asv_get_uint32 (iprops, - TP_PROP_CHANNEL_INITIATOR_HANDLE, - NULL); - - if ((item = yts_roster_find_contact_by_handle (priv->roster, ihandle))) - { - contact_id = yts_contact_get_id (item); - } - else - { - g_warning ("Unknown originator with handle %d", ihandle); - - tp_cli_channel_call_close ((TpChannel*)proxy, - -1, - NULL, - NULL, - NULL, - NULL); - - return; - } - - tp_asv_dump (props); - - name = tp_asv_get_string (props, "Filename"); - offset = tp_asv_get_uint64 (props, "InitialOffset", NULL); - size = tp_asv_get_uint64 (props, "Size", NULL); - - if (!size || size < offset) - { - g_warning ("Meaningless file size"); - - tp_cli_channel_call_close ((TpChannel*)proxy, - -1, - NULL, - NULL, - NULL, - NULL); - - return; - } - - g_signal_emit (self, signals[INCOMING_FILE], 0, - contact_id, name, size, offset, proxy); -} - -static void -yts_client_ft_handle_state (YtsClient *self, TpChannel *proxy, guint state) -{ - YtsClientPrivate *priv = GET_PRIVATE (self); - GHashTable *props; - gboolean requested; - - props = tp_channel_borrow_immutable_properties ((TpChannel*)proxy); - if (!(requested = tp_asv_get_boolean (props, TP_PROP_CHANNEL_REQUESTED,NULL))) - { - YtsContact *item; - guint32 ihandle; - - ihandle = tp_asv_get_uint32 (props, - TP_PROP_CHANNEL_INITIATOR_HANDLE, - NULL); - item = yts_roster_find_contact_by_handle (priv->roster, ihandle); - - switch (state) - { - case 1: - { - if (item) - g_message ("Got request for FT channel from %s (%s)", - yts_contact_get_id (item), - tp_proxy_get_bus_name (proxy)); - else - g_message ("Got request for FT channel from handle %d", - ihandle); - - tp_cli_dbus_properties_call_get_all (proxy, - -1, - TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, - yts_client_ft_accept_cb, - self, - NULL, - (GObject*) self); - } - break; - case 2: - g_message ("Incoming stream state (%s) --> 'accepted'", - tp_proxy_get_bus_name (proxy)); - break; - case 3: - g_message ("Incoming stream state (%s) --> 'open'", - tp_proxy_get_bus_name (proxy)); - break; - case 4: - case 5: - g_message ("Incoming stream state (%s) --> '%s'", - tp_proxy_get_bus_name (proxy), - state == 4 ? "completed" : "cancelled"); - { - char const *name; - char const *contact_id; - - if (item) - { - contact_id = yts_contact_get_id (item); - - name = tp_asv_get_string (props, "Filename"); - - g_signal_emit (self, signals[INCOMING_FILE_FINISHED], 0, - contact_id, name, state == 4 ? TRUE : FALSE); - } - } - break; - default: - g_message ("Invalid value of stream state: %d", state); - } - } - else - g_message ("The FT channel was requested by us ... (%s)", - tp_proxy_get_bus_name (proxy)); -} - -static void -yts_client_ft_state_cb (TpChannel *proxy, - guint state, - guint reason, - gpointer data, - GObject *object) -{ - YtsClient *client = data; - - g_message ("FT channel changed status to %d (reason %d)", state, reason); - - yts_client_ft_handle_state (client, proxy, state); -} - -static void -yts_client_ft_core_cb (GObject *proxy, GAsyncResult *res, gpointer data) -{ - YtsClient *client = data; - TpChannel *channel = (TpChannel*) proxy; - GError *error = NULL; - - g_message ("FT channel ready"); - - tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed - (channel, - yts_client_ft_state_cb, - client, - NULL, - (GObject*)client, - &error); - - if (!yts_client_channel_requested (channel)) - yts_client_ft_handle_state (client, channel, 1); -} - -static void -yts_client_channel_cb (TpConnection *proxy, - char const *path, - char const *type, - guint handle_type, - guint handle, - gboolean suppress_handle, - gpointer self, - GObject *weak_object) -{ - YtsClientPrivate *priv = GET_PRIVATE (self); - - if (!path) - { - g_warning (G_STRLOC ":%s: no path!", __FUNCTION__); - return; - } - - g_message ("New channel: %s: %s: h type %d, h %d", - path, type, handle_type, handle); - - switch (handle_type) - { - case TP_HANDLE_TYPE_CONTACT: - /* FIXME -- this is where the messaging channel will go */ - if (!g_strcmp0 (type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER)) - { - GError *error = NULL; - TpChannel *ch; - GQuark features[] = { TP_CHANNEL_FEATURE_CORE, 0}; - YtsContact *item; - - ch = tp_channel_new (proxy, path, type, handle_type, handle, &error); - - if ((item = yts_roster_find_contact_by_handle (priv->roster, - handle))) - { - yts_contact_set_ft_channel (item, ch); - - tp_proxy_prepare_async (ch, features, - yts_client_ft_core_cb, self); - } - else - { - g_warning (G_STRLOC ": orphaned channel ?"); - g_object_unref (ch); - } - } - break; - case TP_HANDLE_TYPE_LIST: - break; - case TP_HANDLE_TYPE_GROUP: - break; - default:; - } -} - static void yts_client_authenticated (YtsClient *self) { @@ -858,59 +598,6 @@ yts_client_raw_message (YtsClient *self, { } -static bool -yts_client_incoming_file (YtsClient *self, - char const *from, - char const *name, - uint64_t size, - uint64_t offset, - TpChannel *proxy, - void *data) -{ - YtsClientPrivate *priv = GET_PRIVATE (self); - char *path; - GFile *gfile; - EmpathyTpFile *tp_file; - GCancellable *cancellable; - - g_message ("Incoming file from %s", from); - - if (g_mkdir_with_parents (priv->incoming_dir, 0700)) - { - g_warning ("Unable to create directory %s", priv->incoming_dir); - - tp_cli_channel_call_close (proxy, - -1, - NULL, - NULL, - NULL, - NULL); - - return FALSE; - } - - path = g_build_filename (priv->incoming_dir, name, NULL); - - gfile = g_file_new_for_path (path); - - tp_file = empathy_tp_file_new ((TpChannel*)proxy, TRUE); - - cancellable = g_cancellable_new (); - - empathy_tp_file_accept (tp_file, offset, gfile, - cancellable, - NULL /*progress_callback*/, - NULL /*progress_user_data*/, - yts_client_ft_op_cb, - self); - - g_free (path); - g_object_unref (gfile); - g_object_unref (cancellable); - - return TRUE; -} - static gboolean yts_client_stop_accumulator (GSignalInvocationHint *ihint, GValue *accumulated, @@ -1197,6 +884,8 @@ setup_tp_client (YtsClient *self, yts_client_setup_debug (self); } + /* TODO receive files */ + /* Publish capabilities */ yts_client_status_foreach_capability ( priv->client_status, @@ -1616,7 +1305,6 @@ yts_client_finalize (GObject *object) g_free (priv->account_id); g_free (priv->service_id); - g_free (priv->incoming_dir); g_object_unref (priv->client_status); G_OBJECT_CLASS (yts_client_parent_class)->finalize (object); @@ -1897,30 +1585,6 @@ yts_client_class_init (YtsClientClass *klass) G_TYPE_UINT64, G_TYPE_UINT64, TP_TYPE_CHANNEL); - - /** - * YtsClient::incoming-file-finished: - * @self: object which emitted the signal. - * @from: contact_id of the originator - * @name: name of the file - * @success: %TRUE if the transfer was completed successfully. - * - * The #YtsClient::incoming-file-finished signal is emitted when a file - * transfer is completed. - * - * Since: 0.1 - */ - signals[INCOMING_FILE_FINISHED] = - g_signal_new ("incoming-file-finished", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - yts_marshal_VOID__STRING_STRING_BOOLEAN, - G_TYPE_NONE, 3, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_BOOLEAN); } static void @@ -1928,8 +1592,6 @@ yts_client_init (YtsClient *self) { YtsClientPrivate *priv = GET_PRIVATE (self); - yts_client_set_incoming_file_directory (self, NULL); - priv->services = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, @@ -1944,9 +1606,6 @@ yts_client_init (YtsClient *self) g_str_equal, g_free, (GDestroyNotify) proxy_list_destroy); - - g_signal_connect (self, "incoming-file", - G_CALLBACK (yts_client_incoming_file), self); } YtsClient * @@ -2714,13 +2373,6 @@ yts_client_setup_account_connection (YtsClient *self) return; } - tp_cli_connection_connect_to_new_channel (priv->tp_conn, - yts_client_channel_cb, - self, - NULL, - (GObject*)self, - &error); - if (error) { g_critical (G_STRLOC ": %s: %s; no Ytstenut functionality will be " @@ -2991,54 +2643,6 @@ yts_client_emit_error (YtsClient *self, YtsError error) } /** - * yts_client_set_incoming_file_directory: - * @self: object on which to invoke this method. - * @directory: path to a directory or %NULL. - * - * Sets the directory where incoming files will be stored; if the provided path - * is %NULL, the directory will be reset to the default (~/.Ytstenut/). This - * function does not do any checks regarding validity of the path provided, - * though an attempt to create the directory before it is used, with permissions - * of 0700. - * - * To change the directory for a specific file call this function from a - * callback to the #YtsClient::incoming-file signal. - */ -void -yts_client_set_incoming_file_directory (YtsClient *self, - char const *directory) -{ - YtsClientPrivate *priv = GET_PRIVATE (self); - - g_return_if_fail (YTS_IS_CLIENT (self)); - - if (!directory || !*directory) - priv->incoming_dir = - g_build_filename (g_get_home_dir (), ".ytstenut", NULL); - else - priv->incoming_dir = g_strdup (directory); -} - -/** - * yts_client_get_incoming_file_directory: - * @self: object on which to invoke this method. - * - * Returns the directory into which any files from incoming file transfers will - * be placed. - * - * Returns: (transfer none): directory where incoming files are stored. - */ -char const * -yts_client_get_incoming_file_directory (YtsClient const *self) -{ - YtsClientPrivate *priv = GET_PRIVATE (self); - - g_return_val_if_fail (YTS_IS_CLIENT (self), NULL); - - return priv->incoming_dir; -} - -/** * yts_client_get_contact_id: * @self: object on which to invoke this method. * diff --git a/ytstenut/yts-client.h b/ytstenut/yts-client.h index 32bcfe2..2d64e3b 100644 --- a/ytstenut/yts-client.h +++ b/ytstenut/yts-client.h @@ -57,7 +57,6 @@ typedef struct { * YtsClientClass: * @authenticated: virtual function for the #YtsClient::authenticated signal. * @disconnected: virtual function for the #YtsClient::disconnected signal. - * @incoming_file: virtual function for the #YtsClient::incoming-file signal. * @raw_message: virtual function for the #YtsClient::raw-message signal. * @ready: virtual function for the #YtsClient::ready signal. * @@ -137,13 +136,6 @@ yts_client_add_capability (YtsClient *self, YtsRoster *const yts_client_get_roster (YtsClient const *self); -void -yts_client_set_incoming_file_directory (YtsClient *self, - char const *directory); - -char const * -yts_client_get_incoming_file_directory (YtsClient const *self); - char const * yts_client_get_contact_id (YtsClient const *self); diff --git a/ytstenut/yts-contact.c b/ytstenut/yts-contact.c index 045749e..b947ffb 100644 --- a/ytstenut/yts-contact.c +++ b/ytstenut/yts-contact.c @@ -27,7 +27,6 @@ #include <telepathy-glib/dbus.h> #include <telepathy-glib/channel.h> -#include "empathy-tp-file.h" #include "yts-capability.h" #include "yts-contact-impl.h" #include "yts-contact-internal.h" @@ -59,8 +58,6 @@ G_DEFINE_ABSTRACT_TYPE (YtsContact, yts_contact, G_TYPE_OBJECT) typedef struct { GHashTable *services; /* hash of YtsService instances */ TpContact *tp_contact; /* TpContact associated with YtsContact */ - GQueue *pending_files; /* files dispatched before channel open */ - GHashTable *ft_cancellables; } YtsContactPrivate; enum { @@ -81,154 +78,6 @@ enum { static unsigned _signals[N_SIGNALS] = { 0, }; -typedef struct { - YtsContact *item; - guint32 atom; -} YtsCFtOp; - -static YtsCFtOp * -yts_c_ft_op_new (YtsContact *item, guint32 atom) -{ - YtsCFtOp *o = g_slice_new (YtsCFtOp); - - o->item = item; - o->atom = atom; - - return o; -} - -static void -yts_c_ft_op_free (gpointer op) -{ - YtsCFtOp *o = op; - - g_slice_free (YtsCFtOp, o); -} - -static gboolean -yts_contact_find_cancellable_cb (gpointer key, - gpointer value, - gpointer data) -{ - gpointer *the_thing = data; - - - if (value == *the_thing) - { - *the_thing = key; - return TRUE; - } - - return FALSE; -} - -static void -yts_contact_ft_op_cb (EmpathyTpFile *tp_file, - const GError *error, - gpointer data) -{ - GCancellable *cancellable; - YtsError e; - YtsCFtOp *op = data; - YtsContact *self = op->item; - YtsContactPrivate *priv = GET_PRIVATE (self); - guint32 atom = op->atom; - - if (error) - { - e = (atom | YTS_ERROR_UNKNOWN); - g_warning ("File transfer to %s failed: %s", - yts_contact_get_id (self), error->message); - } - else - e = (atom | YTS_ERROR_SUCCESS); - - if ((cancellable = empathy_tp_file_get_cancellable (tp_file))) - { - gpointer the_thing = cancellable; - - if (g_hash_table_find (priv->ft_cancellables, - yts_contact_find_cancellable_cb, - &the_thing)) - { - g_hash_table_remove (priv->ft_cancellables, the_thing); - } - } - - yts_c_ft_op_free (op); -} - -typedef struct -{ - const YtsContact *item; - TpChannel *ft_channel; - GFile *file; - char *name; - guint32 atom; - -} YtsCPendingFile; - -static YtsCPendingFile * -yts_c_pending_file_new (const YtsContact *item, - GFile *file, - const char *name, - guint32 atom) -{ - YtsCPendingFile *m = g_slice_new (YtsCPendingFile); - - m->item = item; - m->name = g_strdup (name); - m->file = g_object_ref (file); - m->atom = atom; - m->ft_channel = NULL; - - return m; -} - -static YtsError -yts_c_dispatch_file (YtsCPendingFile *file) -{ - YtsContactPrivate *priv; - EmpathyTpFile *tp_file; - GCancellable *cancellable; - YtsCFtOp *op; - - g_return_val_if_fail (file && file->item && file->ft_channel && file->file, - YTS_ERROR_INVALID_PARAMETER); - - priv = GET_PRIVATE (file->item); - - op = yts_c_ft_op_new ((YtsContact*)file->item, file->atom); - - tp_file = empathy_tp_file_new (file->ft_channel, FALSE); - - cancellable = g_cancellable_new (); - - empathy_tp_file_offer (tp_file, - file->file, - cancellable, - NULL /*progress_callback*/, - NULL /*progress_user_data*/, - yts_contact_ft_op_cb, - (gpointer) op); - - g_hash_table_insert (priv->ft_cancellables, - g_file_get_path (file->file), - cancellable); - - return (file->atom | YTS_ERROR_PENDING); -} - -static void -yts_c_pending_file_free (gpointer file) -{ - YtsCPendingFile *m = file; - - g_object_unref (m->file); - g_free (m->name); - g_slice_free (YtsCPendingFile, m); -} - static void _tp_contact_notify_alias (GObject *tp_contact, GParamSpec *pspec, @@ -373,11 +222,6 @@ _dispose (GObject *object) static void _finalize (GObject *object) { - YtsContactPrivate *priv = GET_PRIVATE (object); - - g_queue_foreach (priv->pending_files, (GFunc)yts_c_pending_file_free, NULL); - g_queue_free (priv->pending_files); - G_OBJECT_CLASS (yts_contact_parent_class)->finalize (object); } @@ -479,13 +323,6 @@ yts_contact_init (YtsContact *self) g_str_equal, g_free, g_object_unref); - - priv->pending_files = g_queue_new (); - - priv->ft_cancellables = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); } /** @@ -548,351 +385,6 @@ yts_contact_get_tp_contact (YtsContact const *self) return priv->tp_contact; } -static void -yts_contact_ft_channel_ready_cb (TpChannel *channel, - GParamSpec *pspec, - YtsCPendingFile *file) -{ - /* - * NB: we cannot use here tp_is_proxy_prepared(), as the proxy flag is not - * yet set when this signal is emitted. - */ - if (!tp_channel_is_ready (channel)) - return; - - g_message ("The FT channel is ready"); - - yts_c_dispatch_file (file); - yts_c_pending_file_free (file); - - /* - * This is one off. - */ - g_signal_handlers_disconnect_by_func (channel, - yts_contact_ft_channel_ready_cb, file); -} - -static int -yts_contact_find_file_cb (gconstpointer a, gconstpointer b) -{ - const YtsCPendingFile *A = a; - const char *name = b; - - return g_strcmp0 (A->name, name); -} - -static void -yts_contact_do_set_ft_channel (YtsContact *self, - TpChannel *channel, - const char *name) -{ - YtsContactPrivate *priv = GET_PRIVATE (self); - YtsCPendingFile *file; - GList *l; - - if (!(l = g_queue_find_custom (priv->pending_files, - name, - yts_contact_find_file_cb))) - { - return; - } - - file = l->data; - - file->ft_channel = channel; - - g_queue_remove (priv->pending_files, file); - - /* - * If the channel is ready, push any pending messages. - */ - if (tp_proxy_is_prepared (channel, TP_CHANNEL_FEATURE_CORE)) - { - yts_c_dispatch_file (file); - yts_c_pending_file_free (file); - } - else - { - g_signal_connect (channel, "notify::channel-ready", - G_CALLBACK (yts_contact_ft_channel_ready_cb), - file); - } -} - -static void -yts_contact_ft_filename_cb (TpProxy *proxy, - const GValue *value, - const GError *error, - gpointer data, - GObject *weak_object) -{ - YtsContact *item = data; - const char *name; - - if (error) - { - g_warning ("Could not get filename: %s", error->message); - return; - } - - name = g_value_get_string (value); - - yts_contact_do_set_ft_channel (item, (TpChannel*)proxy, name); -} - -/* - * yts_contact_set_ft_channel: - * @self: object on which to invoke this method. - * @channel: #TpChannel - * - * Sets the channel file transfer item for this item. - */ -void -yts_contact_set_ft_channel (YtsContact *self, - TpChannel *channel) -{ - YtsContactPrivate *priv = GET_PRIVATE (self); - - tp_cli_dbus_properties_call_get (channel, - -1, - TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, - "Filename", - yts_contact_ft_filename_cb, - self, - NULL, - (GObject*) self); -} - -static void -yts_contact_create_ft_channel_cb (TpConnection *proxy, - const char *channel, - GHashTable *properties, - const GError *error, - gpointer data, - GObject *weak_object) -{ - if (error) - { - YtsCPendingFile *pending_file = data; - YtsError e = (YTS_ERROR_NO_ROUTE | pending_file->atom); - - g_critical ("Failed to open channel: %s", error->message); - } -} - -static YtsError -yts_contact_do_send_file (YtsContact *self, - GFile *file, - guint32 atom) -{ - YtsContactPrivate *priv = GET_PRIVATE (self); - const char *content_type = "binary"; - GFileInfo *finfo; - GError *error = NULL; - YtsCPendingFile *pending_file; - GHashTable *request; - TpConnection *conn; - guint handle; - - g_return_val_if_fail (YTS_IS_CONTACT (self) && file, - YTS_ERROR_INVALID_PARAMETER); - - g_return_val_if_fail (priv->tp_contact, YTS_ERROR_OBJECT_DISPOSED); - - if (!priv->tp_contact) - return YTS_ERROR_NO_ROUTE; - - finfo = g_file_query_info (file, - "standard::*", - 0, - NULL, - &error); - - if (error) - { - g_warning ("Unable to query file, %s", error->message); - g_clear_error (&error); - return YTS_ERROR_INVALID_PARAMETER; - } - - pending_file = yts_c_pending_file_new (self, file, - g_file_info_get_display_name (finfo), atom); - - g_queue_push_tail (priv->pending_files, pending_file); - - conn = tp_contact_get_connection (priv->tp_contact); - handle = tp_contact_get_handle (priv->tp_contact); - - request = tp_asv_new (TP_PROP_CHANNEL_CHANNEL_TYPE, - G_TYPE_STRING, - TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, - - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, - G_TYPE_UINT, - TP_HANDLE_TYPE_CONTACT, - - TP_PROP_CHANNEL_TARGET_HANDLE, - G_TYPE_UINT, - handle, - - TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE, - G_TYPE_STRING, - content_type, - - TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME, - G_TYPE_STRING, - g_file_info_get_display_name (finfo), - - TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, - G_TYPE_UINT64, - g_file_info_get_size (finfo), - NULL); - - tp_cli_connection_interface_requests_call_create_channel (conn, - -1, - request, - yts_contact_create_ft_channel_cb, - pending_file, - NULL, - (GObject*)self); - - g_object_unref (finfo); - - return (atom & YTS_ERROR_PENDING); -} - -struct YtsContactFTData -{ - GFile *gfile; - guint32 atom; -}; - -static void -yts_contact_notify_tp_contact_cb (YtsContact *contact, - GParamSpec *pspec, - struct YtsContactFTData *d) -{ - g_message ("Contact ready"); - yts_contact_do_send_file (contact, d->gfile, d->atom); - - g_signal_handlers_disconnect_by_func (contact, - yts_contact_notify_tp_contact_cb, - d); - - g_object_unref (d->gfile); - g_free (d); -} - - -/** - * yts_contact_send_file: - * @self: object on which to invoke this method. - * @file: #GFile to send - * - * Sends file to the contact represented by this item. The caller can safely - * release reference on the supplied #GFile after calling this function. - * - * Returns: %true on success. - */ -bool -yts_contact_send_file (YtsContact *self, - GFile *file, - GError **error_out) -{ - YtsContactPrivate *priv = GET_PRIVATE (self); - GFileInfo *finfo; - GError *error = NULL; - guint32 atom; - - g_return_val_if_fail (YTS_IS_CONTACT (self) && file, false); - g_return_val_if_fail (priv->tp_contact, false); - - finfo = g_file_query_info (file, - "standard::*", - 0, - NULL, - error_out); - - if (NULL == finfo) - { - char *path = g_file_get_path (file); - if (error_out && *error_out) - g_critical ("%s", (*error_out)->message); - g_critical ("%s : Unable to query file, %s", G_STRLOC, path); - g_free (path); - return false; - } - - g_object_unref (finfo); - - /* - * NB: the atom through this file is used in its shifted, rather than - * canonical form, so it can be just ored with an error code. - */ - atom = (yts_error_new_atom () << 16); - - g_message ("Sending file with atom %d", atom); - - if (priv->tp_contact) - { - yts_contact_do_send_file (self, file, atom); - } - else - { - struct YtsContactFTData *d = g_new (struct YtsContactFTData, 1); - - d->gfile = g_object_ref (file); - d->atom = atom; - - g_message ("Contact not ready, postponing message file transfer"); - - g_signal_connect (self, "notify::tp-contact", - G_CALLBACK (yts_contact_notify_tp_contact_cb), - d); - } - - return true; -} - -/** - * yts_contact_cancel_file: - * @self: object on which to invoke this method. - * @file: #GFile to cancel - * - * Cancels file transfer in progress. - * - * Returns: %TRUE if the transfer was successfully cancelled; if - * the tansfer was already completed, returns %FALSE. - */ -bool -yts_contact_cancel_file (YtsContact *self, - GFile *file) -{ - YtsContactPrivate *priv = GET_PRIVATE (self); - GCancellable *cancellable; - char *path; - - g_return_val_if_fail (YTS_IS_CONTACT (self) && file, FALSE); - g_return_val_if_fail (priv->tp_contact, FALSE); - - if (!(path = g_file_get_path (file))) - return FALSE; - - if (!(cancellable = g_hash_table_lookup (priv->ft_cancellables, path))) - { - g_free (path); - return FALSE; - } - - g_cancellable_cancel (cancellable); - - g_hash_table_remove (priv->ft_cancellables, path); - - g_free (path); - - return TRUE; -} - void yts_contact_add_service (YtsContact *self, YtsService *service) diff --git a/ytstenut/yts-contact.h b/ytstenut/yts-contact.h index 2ed1758..4d4dee3 100644 --- a/ytstenut/yts-contact.h +++ b/ytstenut/yts-contact.h @@ -72,15 +72,6 @@ yts_contact_foreach_service (YtsContact *self, YtsContactServiceIterator iterator, void *user_data); -bool -yts_contact_send_file (YtsContact *self, - GFile *file, - GError **error_out); - -bool -yts_contact_cancel_file (YtsContact *self, - GFile *file); - G_END_DECLS #endif /* YTS_CONTACT_H */ diff --git a/ytstenut/yts-roster-internal.h b/ytstenut/yts-roster-internal.h index 7f19310..e4e7721 100644 --- a/ytstenut/yts-roster-internal.h +++ b/ytstenut/yts-roster-internal.h @@ -66,10 +66,6 @@ yts_roster_remove_service_by_id (YtsRoster *roster, void yts_roster_clear (YtsRoster *roster); -YtsContact * -yts_roster_find_contact_by_handle (YtsRoster *roster, - unsigned handle); - void yts_roster_update_contact_status (YtsRoster *self, char const *constact_id, diff --git a/ytstenut/yts-roster.c b/ytstenut/yts-roster.c index 7d8f9a8..0fc957d 100644 --- a/ytstenut/yts-roster.c +++ b/ytstenut/yts-roster.c @@ -295,41 +295,6 @@ yts_roster_remove_service_by_id (YtsRoster *self, } } -/* - * yts_roster_find_contact_by_handle: - * @roster: #YtsRoster - * @handle: handle of this contact - * - * Finds contact in a roster. - * - * Return value: (transfer none): #YtsContact if found, or %NULL. - */ -YtsContact * -yts_roster_find_contact_by_handle (YtsRoster *self, - guint handle) -{ - YtsRosterPrivate *priv = GET_PRIVATE (self); - GHashTableIter iter; - gpointer key, value; - - g_return_val_if_fail (YTS_IS_ROSTER (self), NULL); - - g_hash_table_iter_init (&iter, priv->contacts); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - YtsContact *contact = value; - TpContact *tp_contact = yts_contact_get_tp_contact (contact); - guint h = tp_contact_get_handle (tp_contact); - - if (h == handle) - { - return contact; - } - } - - return NULL; -} - /** * yts_roster_find_contact_by_id: * @self: object on which to invoke this method. diff --git a/ytstenut/ytstenut.sym b/ytstenut/ytstenut.sym index 6d9d707..fea0261 100644 --- a/ytstenut/ytstenut.sym +++ b/ytstenut/ytstenut.sym @@ -6,7 +6,6 @@ yts_client_connect yts_client_disconnect yts_client_foreach_service yts_client_get_contact_id -yts_client_get_incoming_file_directory yts_client_get_roster yts_client_get_service_id yts_client_get_type @@ -14,14 +13,11 @@ yts_client_new_c2s yts_client_new_p2p yts_client_add_capability yts_client_publish_service -yts_client_set_incoming_file_directory yts_client_set_status_by_capability -yts_contact_cancel_file yts_contact_foreach_service yts_contact_get_id yts_contact_get_name yts_contact_get_type -yts_contact_send_file yts_file_transfer_get_progress yts_file_transfer_get_type yts_outgoing_file_get_type |