Logo Search packages:      
Sourcecode: galago-daemon version File versions  Download package

account.c

Go to the documentation of this file.
/**
 * @file account.c Galago Account message processor
 *
 * Copyright (C) 2004-2006 Christian Hammond.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA  02111-1307  USA
 */
#include "filter.h"
#include "meta-account.h"
#include "meta-presence.h"
#include "utils.h"

static void
_galagod_dbus_account_emit(GalagoAccount *account, const char *signal_name)
{
      DBusMessage *message;

      g_return_if_fail(account != NULL);

      message = dbus_message_new_signal(
            galago_object_get_dbus_path(GALAGO_OBJECT(account)),
            GALAGO_DBUS_ACCOUNT_INTERFACE,
            signal_name);
      dbus_connection_send(galago_get_dbus_conn(), message, NULL);
      dbus_message_unref(message);
}

static void
_galagod_dbus_account_emit_with_object(GalagoAccount *account,
                                                         const char *signal_name, void *obj)
{
      DBusMessage *message;
      DBusMessageIter iter;

      g_return_if_fail(account != NULL);
      g_return_if_fail(obj != NULL && GALAGO_IS_OBJECT(obj));

      message = dbus_message_new_signal(
            galago_object_get_dbus_path(GALAGO_OBJECT(account)),
            GALAGO_DBUS_ACCOUNT_INTERFACE,
            signal_name);

      dbus_message_iter_init_append(message, &iter);
      galago_dbus_message_iter_append_object(&iter, GALAGO_OBJECT(obj));

      dbus_connection_send(galago_get_dbus_conn(), message, NULL);
      dbus_message_unref(message);
}

static void
_append_display_name(DBusMessage *message, GalagoAccount *account)
{
      DBusMessageIter iter;

      dbus_message_iter_init_append(message, &iter);

      galago_dbus_message_iter_append_string_or_nil(&iter,
            galago_account_get_display_name(account));
}

static void
_galagod_dbus_account_emit_display_name_changed(GalagoAccount *account)
{
      DBusMessage *message;

      g_return_if_fail(account != NULL);

      message = dbus_message_new_signal(
            galago_object_get_dbus_path(GALAGO_OBJECT(account)),
            GALAGO_DBUS_ACCOUNT_INTERFACE,
            "DisplayNameChanged");
      _append_display_name(message, account);
      dbus_connection_send(galago_get_dbus_conn(), message, NULL);
      dbus_message_unref(message);
}

static DBusHandlerResult
account_set_attribute(DBusConnection *dbus_conn, DBusMessage *message,
                                GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));

      return common_object_set_attribute(dbus_conn, message,
                                                         GALAGO_DBUS_ACCOUNT_INTERFACE,
                                                         GALAGO_OBJECT(account),
                                                         GALAGO_OBJECT(main_account));
}

static DBusHandlerResult
account_remove_attribute(DBusConnection *dbus_conn, DBusMessage *message,
                                     GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));

      return common_object_remove_attribute(dbus_conn, message,
                                                              GALAGO_DBUS_ACCOUNT_INTERFACE,
                                                              GALAGO_OBJECT(account),
                                                              GALAGO_OBJECT(main_account));
}

static DBusHandlerResult
account_get_attribute(DBusConnection *dbus_conn, DBusMessage *message,
                                GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));

      return common_object_get_attribute(dbus_conn, message,
                                                         GALAGO_OBJECT(main_account));
}

static DBusHandlerResult
account_get_attributes(DBusConnection *dbus_conn, DBusMessage *message,
                                 GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));

      return common_object_get_attributes(dbus_conn, message,
                                                            GALAGO_OBJECT(main_account));
}

static DBusHandlerResult
account_set_connected(DBusConnection *dbus_conn, DBusMessage *message,
                                GalagodCoCo *coco, GalagoAccount *account)
{
      const GList *l;
      GalagodMetaAccount *meta_account;
      GalagoAccount *main_account;
      DBusMessageIter iter;
      gboolean connected, old_connected;
      int connected_weight = 0;

      meta_account = GALAGOD_META_ACCOUNT(account);
      main_account = galagod_meta_account_get_account(meta_account);

      dbus_message_iter_init(message, &iter);
      dbus_message_iter_get_basic(&iter, &connected);

      if (connected == galago_account_is_connected(account))
            return DBUS_HANDLER_RESULT_HANDLED;

      galago_account_set_connected(account, connected);

      for (l = galagod_meta_account_get_accounts(meta_account);
             l != NULL;
             l = l->next)
      {
            GalagoAccount *temp_account = (GalagoAccount *)l->data;

            if (galago_account_is_connected(temp_account))
                  connected_weight++;
            else
                  connected_weight--;
      }

      old_connected = galago_account_is_connected(main_account);

      if (connected_weight > 0)
            connected = TRUE;
      else if (connected_weight < 0)
            connected = FALSE;
      else if (connected_weight == 0 && !connected)
            return DBUS_HANDLER_RESULT_HANDLED;

      if (old_connected != connected)
      {
            galago_account_set_connected(main_account, connected);

            if (connected)
                  _galagod_dbus_account_emit(main_account, "Connected");
            else
                  _galagod_dbus_account_emit(main_account, "Disconnected");
      }

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_add_contact(DBusConnection *dbus_conn, DBusMessage *message,
                              GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *contact;
      DBusMessageIter iter;

      dbus_message_iter_init(message, &iter);

      contact = galago_dbus_message_iter_get_object(&iter, GALAGO_TYPE_ACCOUNT);
      galago_account_add_contact(
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account)),
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(contact)));

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_remove_contact(DBusConnection *dbus_conn, DBusMessage *message,
                                 GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *contact;
      DBusMessageIter iter;

      dbus_message_iter_init(message, &iter);

      contact = galago_dbus_message_iter_get_object(&iter, GALAGO_TYPE_ACCOUNT);
      galago_account_remove_contact(
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account)),
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(contact)));

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_get_contact(DBusConnection *dbus_conn, DBusMessage *message,
                              GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *contact;
      GalagoAccount *main_account;
      DBusMessageIter iter;
      DBusMessage *reply;
      const char *username;

      dbus_message_iter_init(message, &iter);
      dbus_message_iter_get_basic(&iter, &username);

      main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));
      contact = galago_account_get_contact(main_account, username, FALSE);

      if (contact == NULL)
      {
            GalagoService *service = galago_account_get_service(main_account);

            reply = galagod_object_not_found_error_new(message,
                  "The contact '%s' on account '%s' on service '%s' "
                  "could not be found.",
                  username, galago_account_get_username(main_account),
                  galago_service_get_id(service));
      }
      else
      {
            reply = dbus_message_new_method_return(message);
            dbus_message_iter_init_append(reply, &iter);
            galago_dbus_message_iter_append_object(&iter, GALAGO_OBJECT(contact));
      }

      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_get_contacts(DBusConnection *dbus_conn, DBusMessage *message,
                               GalagodCoCo *coco, GalagoAccount *account)
{
      GalagodMetaAccount *meta_account;
      GalagoAccount *main_account;
      DBusMessageIter iter;
      DBusMessage *reply;

      meta_account = GALAGOD_META_ACCOUNT(account);
      main_account = galagod_meta_account_get_account(meta_account);

      reply = dbus_message_new_method_return(message);
      dbus_message_iter_init_append(reply, &iter);
      galago_dbus_message_iter_append_object_list(&iter, GALAGO_TYPE_ACCOUNT,
            galago_account_get_contacts(main_account, FALSE));
      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_get_contacts_count(DBusConnection *dbus_conn, DBusMessage *message,
                                       GalagodCoCo *coco, GalagoAccount *account)
{
      GalagodMetaAccount *meta_account;
      GalagoAccount *main_account;
      DBusMessageIter iter;
      DBusMessage *reply;
      size_t contact_count;

      meta_account = GALAGOD_META_ACCOUNT(account);
      main_account = galagod_meta_account_get_account(meta_account);

      reply = dbus_message_new_method_return(message);
      dbus_message_iter_init_append(reply, &iter);

      contact_count = g_list_length(galago_account_get_contacts(main_account,
                                                                                            FALSE));
      dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &contact_count);
      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_create_presence(DBusConnection *dbus_conn, DBusMessage *message,
                                    GalagodCoCo *coco, GalagoAccount *account)
{
      DBusMessage *reply;
      DBusMessageIter iter;
      GalagodMetaAccount *meta_account;
      GalagodMetaPresence *meta_presence = NULL;
      GalagoAccount *main_account;
      GalagoPresence *main_presence;
      GalagoPresence *presence;
      const char *obj_path;
      gboolean new_presence = FALSE;

      meta_account  = GALAGOD_META_ACCOUNT(account);
      main_account  = galagod_meta_account_get_account(meta_account);
      main_presence = galago_account_get_presence(main_account, FALSE);

      presence = galago_account_get_presence(account, FALSE);

      if (main_presence != NULL)
            meta_presence = GALAGOD_META_PRESENCE(main_presence);

      if (presence == NULL)
      {
            char *new_obj_path;

            presence = galago_account_create_presence(account);
            g_object_set_data(G_OBJECT(presence), "coco", coco);
            new_obj_path = galagod_presence_generate_path(presence);
            galago_object_set_dbus_path(GALAGO_OBJECT(presence), new_obj_path);
            g_free(new_obj_path);

            new_presence = TRUE;
      }

      if (meta_presence == NULL)
      {
            meta_presence = galagod_meta_presence_new(meta_account);
            main_presence = galago_account_get_presence(main_account, FALSE);
            new_presence = TRUE;
      }

      if (new_presence)
      {
            galagod_meta_presence_add_presence(meta_presence, presence);
            _galagod_dbus_account_emit_with_object(main_account, "PresenceCreated",
                                                                     main_presence);
      }

      reply = dbus_message_new_method_return(message);
      dbus_message_iter_init_append(reply, &iter);
      obj_path = galago_object_get_dbus_path(GALAGO_OBJECT(presence));
      dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &obj_path);
      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_destroy_presence(DBusConnection *dbus_conn, DBusMessage *message,
                                     GalagodCoCo *coco, GalagoAccount *account)
{
      GalagodMetaAccount *meta_account;
      GalagodMetaPresence *meta_presence = NULL;
      GalagoAccount *main_account;
      GalagoPresence *main_presence = NULL;
      GalagoPresence *old_presence;

      meta_account  = GALAGOD_META_ACCOUNT(account);
      main_account  = galagod_meta_account_get_account(meta_account);
      main_presence = galago_account_get_presence(main_account, FALSE);

      if (main_presence != NULL)
            meta_presence = GALAGOD_META_PRESENCE(main_presence);

      old_presence = galago_account_get_presence(account, FALSE);

      if (meta_presence != NULL && old_presence != NULL)
      {
            galagod_meta_presence_remove_presence(meta_presence, old_presence);

            if (galagod_meta_presence_get_presences(meta_presence) == NULL)
            {
                  galagod_meta_presence_destroy(meta_presence);
                  _galagod_dbus_account_emit(main_account, "PresenceDeleted");
            }
      }

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_get_presence(DBusConnection *dbus_conn, DBusMessage *message,
                               GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *main_account;
      GalagoPresence *presence;
      DBusMessage *reply;
      DBusMessageIter iter;

      main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));
      presence = galago_account_get_presence(main_account, FALSE);
      printf("-- Looking up presence for account %p\n", main_account);

      if (presence == NULL)
      {
            GalagoService *service = galago_account_get_service(main_account);

            printf("Returning error: no presence\n");
            reply = galagod_object_not_found_error_new(message,
                  "The presence on account '%s' on service '%s' could not be found.",
                  galago_account_get_username(main_account),
                  galago_service_get_id(service));
      }
      else
      {
            printf("Returning presence\n");
            reply = dbus_message_new_method_return(message);
            dbus_message_iter_init_append(reply, &iter);
            galago_dbus_message_iter_append_object(&iter, GALAGO_OBJECT(presence));
      }

      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
set_unset_avatar(DBusConnection *dbus_conn, DBusMessage *message,
                         GalagodCoCo *coco, GalagoAccount *account,
                         GalagoImage *avatar)
{
      GalagoAccount *main_account;

      main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));

      if (avatar != galago_account_get_avatar(main_account, FALSE))
      {
            galago_account_set_avatar(main_account, avatar);

            galagod_dbus_send_empty_reply(dbus_conn, message);

            if (avatar == NULL)
                  _galagod_dbus_account_emit(main_account, "AvatarUnset");
            else
            {
                  _galagod_dbus_account_emit_with_object(main_account, "AvatarSet",
                                                                           avatar);
            }
      }

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_set_avatar(DBusConnection *dbus_conn, DBusMessage *message,
                           GalagodCoCo *coco, GalagoAccount *account)
{
      DBusMessageIter iter;
      GalagoImage *avatar;

      dbus_message_iter_init(message, &iter);
      avatar = galago_dbus_message_iter_get_object(&iter, GALAGO_TYPE_IMAGE);

      return set_unset_avatar(dbus_conn, message, coco, account, avatar);
}

static DBusHandlerResult
account_unset_avatar(DBusConnection *dbus_conn, DBusMessage *message,
                               GalagodCoCo *coco, GalagoAccount *account)
{
      return set_unset_avatar(dbus_conn, message, coco, account, NULL);
}

static DBusHandlerResult
account_get_avatar(DBusConnection *dbus_conn, DBusMessage *message,
                           GalagodCoCo *coco, GalagoAccount *account)
{
      GalagoAccount *main_account;
      GalagoImage *avatar;
      DBusMessage *reply;
      DBusMessageIter iter;

      main_account =
            galagod_meta_account_get_account(GALAGOD_META_ACCOUNT(account));
      avatar = galago_account_get_avatar(main_account, FALSE);

      if (avatar == NULL)
      {
            GalagoService *service = galago_account_get_service(main_account);

            reply = galagod_object_not_found_error_new(message,
                  "The avatar on account '%s' on service '%s' could not be found.",
                  galago_account_get_username(main_account),
                  galago_service_get_id(service));
      }
      else
      {
            reply = dbus_message_new_method_return(message);
            dbus_message_iter_init_append(reply, &iter);
            galago_dbus_message_iter_append_object(&iter, GALAGO_OBJECT(avatar));
      }

      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_set_display_name(DBusConnection *dbus_conn, DBusMessage *message,
                                     GalagodCoCo *coco, GalagoAccount *account)
{
      GalagodMetaAccount *meta_account;
      GalagoAccount *main_account;
      const char *display_name = NULL;
      DBusMessageIter iter;

      meta_account = GALAGOD_META_ACCOUNT(account);
      main_account = galagod_meta_account_get_account(meta_account);

      dbus_message_iter_init(message, &iter);
      display_name = galago_dbus_message_iter_get_string_or_nil(&iter);

      galago_account_set_display_name(account,      display_name);
      galago_account_set_display_name(main_account, display_name);

      _galagod_dbus_account_emit_display_name_changed(main_account);

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
account_get_display_name(DBusConnection *dbus_conn, DBusMessage *message,
                                     GalagodCoCo *coco, GalagoAccount *account)
{
      DBusMessage *reply;

      reply = dbus_message_new_method_return(message);
      _append_display_name(reply, account);
      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static const GalagodCommand commands[] =
{
      GALAGOD_COMMAND("SetAttribute",     account_set_attribute),
      GALAGOD_COMMAND("RemoveAttribute",  account_remove_attribute),
      GALAGOD_COMMAND("GetAttribute",     account_get_attribute),
      GALAGOD_COMMAND("GetAttributes",    account_get_attributes),
      GALAGOD_COMMAND("SetConnected",     account_set_connected),
      GALAGOD_COMMAND("AddContact",       account_add_contact),
      GALAGOD_COMMAND("RemoveContact",    account_remove_contact),
      GALAGOD_COMMAND("GetContact",       account_get_contact),
      GALAGOD_COMMAND("GetContacts",      account_get_contacts),
      GALAGOD_COMMAND("GetContactsCount", account_get_contacts_count),
      GALAGOD_COMMAND("GetPresence",      account_get_presence),
      GALAGOD_COMMAND("CreatePresence",   account_create_presence),
      GALAGOD_COMMAND("DestroyPresence",  account_destroy_presence),
      GALAGOD_COMMAND("SetAvatar",        account_set_avatar),
      GALAGOD_COMMAND("GetAvatar",        account_get_avatar),
      GALAGOD_COMMAND("UnsetAvatar",      account_unset_avatar),
      GALAGOD_COMMAND("SetDisplayName",   account_set_display_name),
      GALAGOD_COMMAND("GetDisplayName",   account_get_display_name),
      GALAGOD_COMMAND_LAST
};

char *
galagod_account_generate_path(GalagoAccount *account)
{
      return g_strdup_printf("%s/%s",
            galago_object_get_dbus_path(
                  GALAGO_OBJECT(galago_account_get_service(account))),
            galagod_dbus_normalize_name(galago_account_get_username(account)));
}

void
galagod_account_add_filter(GalagoAccount *account)
{
      galagod_filters_add(account, commands, GALAGO_DBUS_ACCOUNT_INTERFACE);
}

void
galagod_account_remove_filter(GalagoAccount *account)
{
      galagod_filters_remove(account);
}

Generated by  Doxygen 1.6.0   Back to index