/* * Syncdaemon API * * Authors: Rodrigo Moya * * Copyright 2010 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * */ #include "config.h" #include #ifdef HAVE_GDBUS #include #else #include #endif #include "syncdaemon-daemon.h" #include "syncdaemon-config-interface.h" #include "syncdaemon-events-interface.h" #include "syncdaemon-filesystem-interface.h" #include "syncdaemon-folders-interface.h" #include "syncdaemon-publicfiles-interface.h" #include "syncdaemon-shares-interface.h" #include "syncdaemon-status-interface.h" #include "syncdaemon-marshal.h" G_DEFINE_TYPE(SyncdaemonDaemon, syncdaemon_daemon, G_TYPE_OBJECT) struct _SyncdaemonDaemonPrivate { #ifdef HAVE_GDBUS GDBusConnection *bus; #else DBusGConnection *bus; #endif GObject *dbus_proxy; /* Interfaces */ GObject *daemon_interface; GHashTable *subinterfaces; /* Status */ gboolean ready; gboolean connected; gchar *root_dir; SyncdaemonAuthentication *auth; }; /* Signals */ enum { READY_SIGNAL, CONNECTED_SIGNAL, DISCONNECTED_SIGNAL, STATUS_CHANGED_SIGNAL, ERROR_SIGNAL, EVENT_SIGNAL, FOLDER_CREATED_SIGNAL, FOLDER_DELETED_SIGNAL, FOLDER_SUBSCRIBED_SIGNAL, FOLDER_UNSUBSCRIBED_SIGNAL, FILE_PUBLISHED_SIGNAL, GOT_PUBLISHED_FILES_SIGNAL, SHARE_CREATED_SIGNAL, SHARE_DELETED_SIGNAL, DOWNLOAD_STARTED_SIGNAL, DOWNLOAD_FILE_PROGRESS_SIGNAL, DOWNLOAD_FINISHED_SIGNAL, UPLOAD_STARTED_SIGNAL, UPLOAD_FILE_PROGRESS_SIGNAL, UPLOAD_FINISHED_SIGNAL, QUOTA_EXCEEDED_SIGNAL, LAST_SIGNAL }; static guint daemon_signals[LAST_SIGNAL] = { 0, }; static void syncdaemon_daemon_finalize (GObject *object) { SyncdaemonDaemon *daemon = SYNCDAEMON_DAEMON (object); if (daemon->priv != NULL) { g_hash_table_destroy (daemon->priv->subinterfaces); if (daemon->priv->dbus_proxy != NULL) g_object_unref (daemon->priv->dbus_proxy); if (daemon->priv->bus != NULL) { #ifdef HAVE_GDBUS g_object_unref (G_OBJECT (daemon->priv->bus)); #else dbus_g_connection_unref (daemon->priv->bus); #endif } if (daemon->priv->root_dir != NULL) g_free (daemon->priv->root_dir); if (daemon->priv->auth != NULL) g_object_unref (G_OBJECT (daemon->priv->auth)); g_free (daemon->priv); } G_OBJECT_CLASS (syncdaemon_daemon_parent_class)->finalize (object); } static void syncdaemon_daemon_class_init (SyncdaemonDaemonClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = syncdaemon_daemon_finalize; /* Register signals */ daemon_signals[READY_SIGNAL] = g_signal_new ("ready", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, ready), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); daemon_signals[CONNECTED_SIGNAL] = g_signal_new ("connected", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, connected), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); daemon_signals[DISCONNECTED_SIGNAL] = g_signal_new ("disconnected", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, disconnected), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); daemon_signals[STATUS_CHANGED_SIGNAL] = g_signal_new ("status_changed", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, status_changed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); daemon_signals[EVENT_SIGNAL] = g_signal_new ("event", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, event), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); daemon_signals[ERROR_SIGNAL] = g_signal_new ("error", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, error), NULL, NULL, _syncdaemon_marshal_VOID__STRING_POINTER, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER); daemon_signals[FOLDER_CREATED_SIGNAL] = g_signal_new ("folder_created", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_created), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[FOLDER_DELETED_SIGNAL] = g_signal_new ("folder_deleted", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_deleted), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[FOLDER_SUBSCRIBED_SIGNAL] = g_signal_new ("folder_subscribed", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_subscribed), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[FOLDER_UNSUBSCRIBED_SIGNAL] = g_signal_new ("folder_unsubscribed", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_unsubscribed), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[FILE_PUBLISHED_SIGNAL] = g_signal_new ("file_published", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, file_published), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[GOT_PUBLISHED_FILES_SIGNAL] = g_signal_new ("got_published_files", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, got_published_files), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_POINTER, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_POINTER); daemon_signals[SHARE_CREATED_SIGNAL] = g_signal_new ("share_created", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, share_created), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[SHARE_DELETED_SIGNAL] = g_signal_new ("share_deleted", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, share_deleted), NULL, NULL, _syncdaemon_marshal_VOID__BOOLEAN_OBJECT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_OBJECT); daemon_signals[DOWNLOAD_STARTED_SIGNAL] = g_signal_new ("download_started", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, download_started), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); daemon_signals[DOWNLOAD_FILE_PROGRESS_SIGNAL] = g_signal_new ("download_file_progress", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, download_file_progress), NULL, NULL, _syncdaemon_marshal_VOID__STRING_OBJECT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_OBJECT); daemon_signals[DOWNLOAD_FINISHED_SIGNAL] = g_signal_new ("download_finished", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, download_finished), NULL, NULL, _syncdaemon_marshal_VOID__STRING_OBJECT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_OBJECT); daemon_signals[UPLOAD_STARTED_SIGNAL] = g_signal_new ("upload_started", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, upload_started), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); daemon_signals[UPLOAD_FILE_PROGRESS_SIGNAL] = g_signal_new ("upload_file_progress", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, upload_file_progress), NULL, NULL, _syncdaemon_marshal_VOID__STRING_OBJECT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_OBJECT); daemon_signals[UPLOAD_FINISHED_SIGNAL] = g_signal_new ("upload_finished", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, upload_finished), NULL, NULL, _syncdaemon_marshal_VOID__STRING_OBJECT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_OBJECT); daemon_signals[QUOTA_EXCEEDED_SIGNAL] = g_signal_new ("quota_exceeded", G_TYPE_FROM_CLASS (klass), (GSignalFlags) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SyncdaemonDaemonClass, quota_exceeded), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } static void quota_exceeded_cb (DBusGProxy *proxy, GHashTable *volume_info, gpointer user_data) { SyncdaemonDaemon *daemon = SYNCDAEMON_DAEMON (user_data); if (daemon != NULL) g_signal_emit_by_name (daemon, "quota_exceeded", volume_info); } static void setup_daemon_interface (SyncdaemonDaemon *daemon) { GObject *proxy = NULL; daemon->priv->daemon_interface = g_object_new (SYNCDAEMON_TYPE_INTERFACE, "daemon", daemon, NULL); proxy = syncdaemon_interface_setup_proxy (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface), "com.ubuntuone.SyncDaemon", "/", "com.ubuntuone.SyncDaemon.SyncDaemon"); if (proxy != NULL) { dbus_g_proxy_add_signal (DBUS_G_PROXY (proxy), "QuotaExceeded", dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING), G_TYPE_INVALID); dbus_g_proxy_connect_signal (DBUS_G_PROXY (proxy), "QuotaExceeded", G_CALLBACK (quota_exceeded_cb), daemon, NULL); } } static void name_owner_changed_cb (DBusGProxy *proxy, const char *name, const char *old_owner, const char *new_owner, gpointer user_data) { SyncdaemonDaemon *daemon = SYNCDAEMON_DAEMON (user_data); if (g_strcmp0 (name, "com.ubuntuone.Syncdaemon") == 0) { if (new_owner != NULL && strlen (new_owner) > 0) { daemon->priv->ready = TRUE; setup_daemon_interface (daemon); g_signal_emit (daemon, daemon_signals[READY_SIGNAL], 0); } else { daemon->priv->ready = FALSE; g_debug ("Syncdaemon service died"); if (daemon->priv->daemon_interface != NULL) { g_object_unref (daemon->priv->daemon_interface); daemon->priv->daemon_interface = NULL; } g_hash_table_remove_all (daemon->priv->subinterfaces); daemon->priv->connected = FALSE; } } } static void service_started_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { guint return_code; GError *error = NULL; SyncdaemonDaemon *daemon = SYNCDAEMON_DAEMON (user_data); if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_UINT, &return_code, G_TYPE_INVALID)) { if (return_code == DBUS_START_REPLY_SUCCESS || return_code == DBUS_START_REPLY_ALREADY_RUNNING) { daemon->priv->ready = TRUE; setup_daemon_interface (daemon); g_signal_emit (daemon, daemon_signals[READY_SIGNAL], 0); } else g_warning ("Error starting SyncDaemon service: %d", return_code); } else { g_warning ("Error starting SyncDaemon service: %s", error->message); g_error_free (error); } } static void syncdaemon_daemon_init (SyncdaemonDaemon *daemon) { GError *error = NULL; daemon->priv = g_new0 (SyncdaemonDaemonPrivate, 1); daemon->priv->ready = FALSE; daemon->priv->connected = FALSE; daemon->priv->subinterfaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); daemon->priv->auth = g_object_new (SYNCDAEMON_TYPE_AUTHENTICATION, NULL); /* Initialize DBus */ #ifdef HAVE_GDBUS daemon->priv->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); #else daemon->priv->bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); #endif if (error != NULL) { g_warning ("Couldn't get session bus: %s", error->message); g_error_free (error); return; } /* Listen to DBus for syncdaemon restarts */ daemon->priv->dbus_proxy = (GObject *) dbus_g_proxy_new_for_name (daemon->priv->bus, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus"); dbus_g_proxy_add_signal (DBUS_G_PROXY (daemon->priv->dbus_proxy), "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); dbus_g_proxy_connect_signal (DBUS_G_PROXY (daemon->priv->dbus_proxy), "NameOwnerChanged", G_CALLBACK (name_owner_changed_cb), daemon, NULL); /* Start syncdaemon to avoid DBus timeouts */ dbus_g_proxy_begin_call (DBUS_G_PROXY (daemon->priv->dbus_proxy), "StartServiceByName", service_started_cb, daemon, NULL, G_TYPE_STRING, "com.ubuntuone.SyncDaemon", G_TYPE_UINT, 0, G_TYPE_INVALID); } /** * syncdaemon_daemon_new: * * Create a new #SyncdaemonDaemon object, which provides access to the * Syncdaemon daemon. * * Return value: A new #SyncdaemonDaemon object. */ SyncdaemonDaemon * syncdaemon_daemon_new (void) { return g_object_new (SYNCDAEMON_TYPE_DAEMON, NULL); } /** * syncdaemon_daemon_is_ready: */ gboolean syncdaemon_daemon_is_ready (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE); return daemon->priv->ready; } static void connect_response_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { GError *error = NULL; SyncdaemonDaemon *daemon = (SyncdaemonDaemon *) user_data; if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { daemon->priv->connected = TRUE; g_signal_emit (daemon, daemon_signals[CONNECTED_SIGNAL], 0); } else { g_warning ("Syncdaemon cannot connect: %s", error->message); g_error_free (error); } } /** * syncdaemon_daemon_connect: */ gboolean syncdaemon_daemon_connect (SyncdaemonDaemon *daemon) { GObject *proxy; g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE); proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface)); if (proxy != NULL) { #ifdef HAVE_GDBUS #else if (!dbus_g_proxy_begin_call (DBUS_G_PROXY (proxy), "connect", connect_response_cb, daemon, NULL, G_TYPE_INVALID)) { g_warning ("Call to 'connect' method failed"); return FALSE; } #endif } return TRUE; } static void disconnect_response_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { GError *error = NULL; SyncdaemonDaemon *daemon = (SyncdaemonDaemon *) user_data; if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { daemon->priv->connected = FALSE; g_signal_emit (daemon, daemon_signals[DISCONNECTED_SIGNAL], 0); } else { g_warning ("Syncdaemon cannot disconnect: %s", error->message); g_error_free (error); } } /** * syncdaemon_daemon_interface_disconnect: */ gboolean syncdaemon_daemon_disconnect (SyncdaemonDaemon *daemon) { GObject *proxy; g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE); proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface)); if (proxy != NULL) { #ifdef HAVE_GDBUS #else if (!dbus_g_proxy_begin_call (DBUS_G_PROXY (proxy), "disconnect", disconnect_response_cb, daemon, NULL, G_TYPE_INVALID)) { g_warning ("Call to 'disconnect' method failed"); return FALSE; } #endif } return TRUE; } /** * syncdaemon_daemon_interface_quit: */ gboolean syncdaemon_daemon_quit (SyncdaemonDaemon *daemon) { GObject *proxy; g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE); proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface)); if (proxy != NULL) { GError *error = NULL; #ifdef HAVE_GDBUS #else if (!dbus_g_proxy_call (DBUS_G_PROXY (proxy), "quit", &error, G_TYPE_INVALID, G_TYPE_INVALID)) { g_warning ("Could not quit syncdaemon: %s", error->message); g_error_free (error); return FALSE; } #endif } return TRUE; } /** * syncdaemon_daemon_get_root_dir: */ const gchar * syncdaemon_daemon_get_root_dir (SyncdaemonDaemon *daemon) { GObject *proxy; g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); if (daemon->priv->root_dir != NULL) return (const gchar *) daemon->priv->root_dir; proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface)); if (proxy != NULL) { gchar *new_root_dir; GError *error = NULL; #ifdef HAVE_GDBUS #else if (!dbus_g_proxy_call (DBUS_G_PROXY (proxy), "get_rootdir", &error, G_TYPE_INVALID, G_TYPE_STRING, &new_root_dir, G_TYPE_INVALID)) { g_warning ("Could not get syncdaemon's root dir: %s", error->message); g_error_free (error); return NULL; } #endif daemon->priv->root_dir = new_root_dir; return (const gchar *) daemon->priv->root_dir; } return NULL; } /** * syncdaemon_daemon_has_network: */ gboolean syncdaemon_daemon_has_network (SyncdaemonDaemon *daemon) { SyncdaemonInterface *interface; gboolean result = FALSE; g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE); interface = syncdaemon_daemon_get_status_interface (daemon); if (SYNCDAEMON_IS_STATUS_INTERFACE (interface)) { SyncdaemonStatusInfo *status_info; status_info = syncdaemon_status_interface_get_current_status (SYNCDAEMON_STATUS_INTERFACE (interface)); if (g_strrstr (syncdaemon_status_info_get_connection (status_info), "With Network") != NULL) result = TRUE; g_object_unref (G_OBJECT (status_info)); } return result; } /** * syncdaemon_daemon_get_authentication: */ SyncdaemonAuthentication * syncdaemon_daemon_get_authentication (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return daemon->priv->auth; } static SyncdaemonInterface * get_interface (SyncdaemonDaemon *daemon, const gchar *path, SyncdaemonInterface * (* new_func) (SyncdaemonDaemon *daemon)) { SyncdaemonInterface *interface; interface = g_hash_table_lookup (daemon->priv->subinterfaces, path); if (interface == NULL) { interface = new_func (daemon); if (SYNCDAEMON_IS_INTERFACE (interface)) g_hash_table_insert (daemon->priv->subinterfaces, g_strdup (path), interface); } return interface; } /** * syncdaemon_daemon_get_config_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_config_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/config", syncdaemon_config_interface_new); } /** * syncdaemon_daemon_get_events_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_events_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/events", syncdaemon_events_interface_new); } /** * syncdaemon_daemon_get_filesystem_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_filesystem_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/filesystem", syncdaemon_filesystem_interface_new); } /** * syncdaemon_daemon_get_folders_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_folders_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/folders", syncdaemon_folders_interface_new); } /** * syncdaemon_daemon_get_publicfiles_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_publicfiles_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/publicfiles", syncdaemon_publicfiles_interface_new); } /** * syncdaemon_daemon_get_shares_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_shares_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/shares", syncdaemon_shares_interface_new); } /** * syncdaemon_daemon_get_status_interface: */ SyncdaemonInterface * syncdaemon_daemon_get_status_interface (SyncdaemonDaemon *daemon) { g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL); return get_interface (daemon, "/status", syncdaemon_status_interface_new); }