static void
infinoted_plugin_linekeeper_remove_user(
  InfinotedPluginLinekeeperSessionInfo* info)
{
  InfSession* session;
  InfUser* user;

  g_assert(info->user != NULL);
  g_assert(info->request == NULL);

  user = info->user;
  info->user = NULL;

  g_object_get(G_OBJECT(info->proxy), "session", &session, NULL); 

  inf_session_set_user_status(session, user, INF_USER_UNAVAILABLE);
  g_object_unref(user);

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(info->buffer),
    G_CALLBACK(infinoted_plugin_linekeeper_text_inserted_cb),
    info
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(info->buffer),
    G_CALLBACK(infinoted_plugin_linekeeper_text_erased_cb),
    info
  );

  g_object_unref(session);
}
static void
infinoted_directory_sync_remove_session(InfinotedDirectorySync* dsync,
                                        InfinotedDirectorySyncSession* sess)
{
  InfTextBuffer* buffer;

  if(sess->timeout != NULL)
  {
    infinoted_directory_sync_session_save(dsync, sess);
    infinoted_directory_sync_session_stop(dsync, sess);
  }

  buffer = INF_TEXT_BUFFER(
    inf_session_get_buffer(infd_session_proxy_get_session(sess->proxy))
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(buffer),
    G_CALLBACK(infinoted_directory_sync_buffer_text_inserted_cb),
    sess
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(buffer),
    G_CALLBACK(infinoted_directory_sync_buffer_text_erased_cb),
    sess
  );

  dsync->sessions = g_slist_remove(dsync->sessions, sess);

  g_free(sess->path);
  g_slice_free(InfinotedDirectorySyncSession, sess);
}
/**
 * infinoted_directory_sync_free:
 * @directory_sync: A #InfinotedDirectorySync.
 *
 * Frees the given #InfinotedDirectorySync. 
 */
void
infinoted_directory_sync_free(InfinotedDirectorySync* dsync)
{
  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(dsync->directory),
    G_CALLBACK(infinoted_directory_sync_directory_add_session_cb),
    dsync
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(dsync->directory),
    G_CALLBACK(infinoted_directory_sync_directory_remove_session_cb),
    dsync
  );

  while(dsync->sessions != NULL)
  {
    infinoted_directory_sync_remove_session(
      dsync,
      (InfinotedDirectorySyncSession*)dsync->sessions->data
    );
  }

  g_object_unref(dsync->directory);
  g_slice_free(InfinotedDirectorySync, dsync);
}
static void
inf_text_gtk_viewport_set_user_table(InfTextGtkViewport* viewport,
                                     InfUserTable* user_table)
{
  InfTextGtkViewportPrivate* priv;
  priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(viewport);

  if(priv->user_table != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->user_table),
      G_CALLBACK(inf_text_gtk_viewport_add_user_cb),
      viewport
    );

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->user_table),
      G_CALLBACK(inf_text_gtk_viewport_remove_user_cb),
      viewport
    );

    inf_user_table_foreach_user(
      priv->user_table,
      inf_text_gtk_viewport_set_user_table_foreach_old_user_func,
      viewport
    );

    g_object_unref(priv->user_table);
  }

  priv->user_table = user_table;

  if(user_table != NULL)
  {
    g_object_ref(user_table);

    g_signal_connect(
      G_OBJECT(user_table),
      "add-user",
      G_CALLBACK(inf_text_gtk_viewport_add_user_cb),
      viewport
    );

    g_signal_connect(
      G_OBJECT(user_table),
      "remove-user",
      G_CALLBACK(inf_text_gtk_viewport_remove_user_cb),
      viewport
    );

    inf_user_table_foreach_user(
      user_table,
      inf_text_gtk_viewport_set_user_table_foreach_new_user_func,
      viewport
    );
  }

  g_object_notify(G_OBJECT(viewport), "user-table");
}
static void
inf_adopted_session_dispose(GObject* object)
{
  InfAdoptedSession* session;
  InfAdoptedSessionPrivate* priv;
  InfUserTable* user_table;

  session = INF_ADOPTED_SESSION(object);
  priv = INF_ADOPTED_SESSION_PRIVATE(session);

  user_table = inf_session_get_user_table(INF_SESSION(session));

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(user_table),
    G_CALLBACK(inf_adopted_session_add_local_user_cb),
    session
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(user_table),
    G_CALLBACK(inf_adopted_session_remove_local_user_cb),
    session
  );

  if(priv->noop_timeout != NULL)
  {
    inf_io_remove_timeout(priv->io, priv->noop_timeout);
    priv->noop_timeout = NULL;
  }

  /* This calls the close vfunc if the session is running, in which we
   * free the local users. */
  G_OBJECT_CLASS(parent_class)->dispose(object);

  g_assert(priv->local_users == NULL);

  if(priv->algorithm != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->algorithm),
      G_CALLBACK(inf_adopted_session_execute_request_cb),
      session
    );

    g_object_unref(G_OBJECT(priv->algorithm));
    priv->algorithm = NULL;
  }

  if(priv->io != NULL)
  {
    g_object_unref(G_OBJECT(priv->io));
    priv->io = NULL;
  }
}
/**
 * infinoted_plugin_manager_free:
 * @manager: A #InfinotedPluginManager.
 *
 * Unloads all plugins and releases all resources associated with @manager.
 */
void
infinoted_plugin_manager_free(InfinotedPluginManager* manager)
{
  GSList* item;

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(manager->directory),
    G_CALLBACK(infinoted_plugin_manager_connection_added_cb),
    manager
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(manager->directory),
    G_CALLBACK(infinoted_plugin_manager_connection_removed_cb),
    manager
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(manager->directory),
    G_CALLBACK(infinoted_plugin_manager_subscribe_session_cb),
    manager
  );

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(manager->directory),
    G_CALLBACK(infinoted_plugin_manager_unsubscribe_session_cb),
    manager
  );

  while(manager->plugins != NULL)
  {
    infinoted_plugin_manager_unload_plugin(
      manager,
      (InfinotedPluginInstance*)manager->plugins->data
    );
  }

  g_assert(g_hash_table_size(manager->connections) == 0);
  g_hash_table_unref(manager->connections);

  g_assert(g_hash_table_size(manager->sessions) == 0);
  g_hash_table_unref(manager->sessions);

  g_free(manager->path);

  if(manager->credentials != NULL)
    inf_certificate_credentials_unref(manager->credentials);

  g_object_unref(manager->directory);
  g_object_unref(manager->log);

  g_slice_free(InfinotedPluginManager, manager);
}
static void
infinoted_plugin_autosave_session_removed(const InfBrowserIter* iter,
                                          InfSessionProxy* proxy,
                                          gpointer plugin_info,
                                          gpointer session_info)
{
  InfinotedPluginAutosaveSessionInfo* info;
  InfSession* session;
  InfBuffer* buffer;

  info = (InfinotedPluginAutosaveSessionInfo*)session_info;

  /* Cancel autosave timeout even if session is modified. If the directory
   * removed the session, then it has already saved it anyway. */
  if(info->timeout != NULL)
    infinoted_plugin_autosave_stop(info);

  g_object_get(G_OBJECT(info->proxy), "session", &session, NULL);
  buffer = inf_session_get_buffer(session);

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(buffer),
    G_CALLBACK(infinoted_plugin_autosave_buffer_notify_modified_cb),
    info
  );

  g_object_unref(session);
  g_object_unref(info->proxy);
}
static void
infinoted_plugin_document_stream_deinitialize(gpointer plugin_info)
{
  InfinotedPluginDocumentStream* plugin;
  plugin = (InfinotedPluginDocumentStream*)plugin_info;

  while(plugin->streams != NULL)
  {
    infinoted_plugin_document_stream_close_stream(
      (InfinotedPluginDocumentStreamStream*)plugin->streams->data
    );
  }

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(infinoted_plugin_manager_get_directory(plugin->manager)),
    G_CALLBACK(infinoted_plugin_document_stream_node_removed_cb),
    plugin
  );

  if(plugin->watch != NULL)
  {
    inf_io_remove_watch(
      infinoted_plugin_manager_get_io(plugin->manager),
      plugin->watch
    );
  }

  if(plugin->socket != -1)
  {
    close(plugin->socket);
  }
}
示例#9
0
static void
inf_tcp_connection_set_resolver(InfTcpConnection* connection,
                                InfNameResolver* resolver)
{
  InfTcpConnectionPrivate* priv;
  priv = INF_TCP_CONNECTION_PRIVATE(connection);

  if(priv->resolver != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->resolver),
      G_CALLBACK(inf_tcp_connection_resolved_cb),
      connection
    );

    g_object_unref(priv->resolver);
  }

  priv->resolver = resolver;

  if(resolver != NULL)
  {
    g_object_ref(resolver);

    g_signal_connect(
      G_OBJECT(resolver),
      "resolved",
      G_CALLBACK(inf_tcp_connection_resolved_cb),
      connection
    );
  }
}
static void
inf_gtk_browser_model_filter_sync_child_model(InfGtkBrowserModelFilter* model,
                                              InfGtkBrowserModel* child_model)
{
  InfGtkBrowserModelFilterPrivate* priv;
  priv = INF_GTK_BROWSER_MODEL_FILTER_PRIVATE(model);

  if(priv->child_model != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      priv->child_model,
      G_CALLBACK(inf_gtk_browser_model_filter_set_browser_cb),
      model
    );

    g_object_unref(priv->child_model);
  }

  priv->child_model = child_model;

  if(child_model != NULL)
  {
    g_object_ref(child_model);

    g_signal_connect(
      G_OBJECT(child_model),
      "set-browser",
      G_CALLBACK(inf_gtk_browser_model_filter_set_browser_cb),
      model
    );
  }
}
static void
inf_text_gtk_viewport_user_removed(InfTextGtkViewport* viewport,
                                   InfTextUser* user)
{
  InfTextGtkViewportPrivate* priv;
  InfTextGtkViewportUser* viewport_user;

  priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(viewport);

  if(user == priv->active_user)
  {
    priv->active_user = NULL;
    g_object_notify(G_OBJECT(viewport), "active-user");
  }
  else
  {
    inf_signal_handlers_disconnect_by_func(
      user,
      G_CALLBACK(inf_text_gtk_viewport_user_notify_status_cb),
      viewport
    );

    if(inf_user_get_status(INF_USER(user)) == INF_USER_ACTIVE)
    {
      viewport_user = inf_text_gtk_viewport_find_user(viewport, user);
      g_assert(viewport_user != NULL);

      inf_text_gtk_viewport_remove_user(viewport_user);
    }
  }
}
示例#12
0
static void
inf_user_table_unref_user(InfUserTable* user_table,
                          InfUser* user)
{
  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(user),
    G_CALLBACK(inf_user_table_check_local_cb),
    user_table
  );

  g_object_unref(user);
}
static void
inf_text_gtk_viewport_remove_user(InfTextGtkViewportUser* viewport_user)
{
  InfTextGtkViewportPrivate* priv;
  priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(viewport_user->viewport);

  inf_text_gtk_viewport_user_invalidate_user_area(viewport_user);

  inf_signal_handlers_disconnect_by_func(
    viewport_user->user,
    G_CALLBACK(inf_text_gtk_viewport_user_selection_changed_cb),
    viewport_user
  );

  inf_signal_handlers_disconnect_by_func(
    viewport_user->user,
    G_CALLBACK(inf_text_gtk_viewport_user_notify_hue_cb),
    viewport_user
  );

  priv->users = g_slist_remove(priv->users, viewport_user);
  g_slice_free(InfTextGtkViewportUser, viewport_user);
}
static void
inf_gtk_certificate_manager_query_free(InfGtkCertificateManagerQuery* query)
{
  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(query->connection),
    G_CALLBACK(inf_gtk_certificate_manager_notify_status_cb),
    query
  );

  g_object_unref(query->connection);
  inf_certificate_chain_unref(query->certificate_chain);
  gtk_widget_destroy(GTK_WIDGET(query->dialog));
  g_hash_table_unref(query->known_hosts);
  g_slice_free(InfGtkCertificateManagerQuery, query);
}
static void
inf_gtk_browser_model_filter_dispose(GObject* object)
{
  InfGtkBrowserModelFilter* model_sort;
  InfGtkBrowserModelFilterPrivate* priv;

  model_sort = INF_GTK_BROWSER_MODEL_FILTER(object);
  priv = INF_GTK_BROWSER_MODEL_FILTER_PRIVATE(model_sort);

  /* Release own child model, since we won't get notified anymore when the
   * parent's dispose runs. We disconnect the signal handler before chaining
   * up. */
  inf_gtk_browser_model_filter_sync_child_model(model_sort, NULL);

  inf_signal_handlers_disconnect_by_func(
    object,
    G_CALLBACK(inf_gtk_browser_model_filter_notify_model_cb),
    NULL
  );

  G_OBJECT_CLASS(parent_class)->dispose(object);
}
static void
infinoted_plugin_transformation_protection_session_removed(
  const InfBrowserIter* iter,
  InfSessionProxy* proxy,
  gpointer plugin_info,
  gpointer session_info)
{
  InfinotedPluginTransformationProtectionSessionInfo* info;
  InfSession* session;

  info = (InfinotedPluginTransformationProtectionSessionInfo*)session_info;
  
  g_object_get(G_OBJECT(proxy), "session", &session, NULL);

  inf_signal_handlers_disconnect_by_func(
    G_OBJECT(session),
    G_CALLBACK(infinoted_plugin_transformation_protection_check_request_cb),
    info
  );

  g_object_unref(info->proxy);
  g_object_unref(session);
}
static void
infinoted_plugin_manager_set_directory(InfinotedPluginManager* manager,
                                       InfdDirectory* directory)
{
  InfinotedPluginManagerPrivate* priv;
  priv = INFINOTED_PLUGIN_MANAGER_PRIVATE(manager);

  /* Directory can only be changed while no plugins are loaded. */
  g_assert(priv->plugins == NULL);

  if(priv->directory != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->directory),
      G_CALLBACK(infinoted_plugin_manager_connection_added_cb),
      manager
    );

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->directory),
      G_CALLBACK(infinoted_plugin_manager_connection_removed_cb),
      manager
    );

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->directory),
      G_CALLBACK(infinoted_plugin_manager_subscribe_session_cb),
      manager
    );

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->directory),
      G_CALLBACK(infinoted_plugin_manager_unsubscribe_session_cb),
      manager
    );

    g_object_unref(priv->directory);
  }

  priv->directory = directory;

  if(directory != NULL)
  {
    g_object_ref(priv->directory);

    g_signal_connect_after(
      G_OBJECT(directory),
      "connection-added",
      G_CALLBACK(infinoted_plugin_manager_connection_added_cb),
      manager
    );

    g_signal_connect_after(
      G_OBJECT(directory),
      "connection-removed",
      G_CALLBACK(infinoted_plugin_manager_connection_removed_cb),
      manager
    );

    g_signal_connect_after(
      G_OBJECT(directory),
      "subscribe-session",
      G_CALLBACK(infinoted_plugin_manager_subscribe_session_cb),
      manager
    );

    g_signal_connect_after(
      G_OBJECT(directory),
      "unsubscribe-session",
      G_CALLBACK(infinoted_plugin_manager_unsubscribe_session_cb),
      manager
    );
  }

  g_object_notify(G_OBJECT(manager), "directory");
}
static void
inf_text_gtk_viewport_set_scrolled_window(InfTextGtkViewport* viewport,
                                          GtkScrolledWindow* scroll)
{
  InfTextGtkViewportPrivate* priv;
  GtkWidget* scrollbar;
  GtkAdjustment* adjustment;

  priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(viewport);

  if(priv->scroll != NULL)
  {
    scrollbar = gtk_scrolled_window_get_vscrollbar(priv->scroll);

    /* Can already be unset at this point */
    /* TODO: Should we catch that and unregister our signals before? OTOH it
     * is most likely going to be freed anyway... */
    if(scrollbar != NULL)
    {
      adjustment = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
      g_assert(adjustment != NULL);

      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(adjustment),
        G_CALLBACK(inf_text_gtk_viewport_adjustment_changed_cb),
        viewport
      );

      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(scrollbar),
        G_CALLBACK(inf_text_gtk_viewport_scrollbar_size_allocate_cb),
        viewport
      );

      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(scrollbar),
        G_CALLBACK(inf_text_gtk_viewport_scrollbar_style_set_cb),
        viewport
      );

      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(scrollbar),
#if GTK_CHECK_VERSION(2, 91, 0)
        G_CALLBACK(inf_text_gtk_viewport_scrollbar_draw_cb),
#else
        G_CALLBACK(inf_text_gtk_viewport_scrollbar_expose_event_cb),
#endif
        viewport
      );
    }

    g_object_unref(priv->scroll);
  }

  priv->scroll = scroll;

  if(scroll != NULL)
  {
    scrollbar = gtk_scrolled_window_get_vscrollbar(priv->scroll);
    /* TODO: can this happen? maybe for GTK_POLICY_NEVER? */
    g_assert(scrollbar != NULL);

    adjustment = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
    g_assert(adjustment != NULL);

    g_object_ref(scroll);

    g_signal_connect_after(
      G_OBJECT(adjustment),
      "changed",
      G_CALLBACK(inf_text_gtk_viewport_adjustment_changed_cb),
      viewport
    );

    g_signal_connect_after(
      G_OBJECT(scrollbar),
      "size-allocate",
      G_CALLBACK(inf_text_gtk_viewport_scrollbar_size_allocate_cb),
      viewport
    );

    g_signal_connect_after(
      G_OBJECT(scrollbar),
      "style-set",
      G_CALLBACK(inf_text_gtk_viewport_scrollbar_style_set_cb),
      viewport
    );

#if GTK_CHECK_VERSION(2, 91, 0)
    g_signal_connect_after(
      G_OBJECT(scrollbar),
      "draw",
      G_CALLBACK(inf_text_gtk_viewport_scrollbar_draw_cb),
      viewport
    );
#else
    g_signal_connect_after(
      G_OBJECT(scrollbar),
      "expose-event",
      G_CALLBACK(inf_text_gtk_viewport_scrollbar_expose_event_cb),
      viewport
    );
#endif
  }

  g_object_notify(G_OBJECT(viewport), "scrolled-window");
}
static void
infinoted_plugin_linekeeper_session_removed(const InfBrowserIter* iter,
                                            InfSessionProxy* proxy,
                                            gpointer plugin_info,
                                            gpointer session_info)
{
  InfinotedPluginLinekeeperSessionInfo* info;
  InfdDirectory* directory;
  InfSession* session;
  InfUserTable* user_table;

  info = (InfinotedPluginLinekeeperSessionInfo*)session_info;

  g_object_get(G_OBJECT(info->proxy), "session", &session, NULL);
  user_table = inf_session_get_user_table(session);

  g_signal_handlers_disconnect_by_func(
    G_OBJECT(user_table),
    G_CALLBACK(infinoted_plugin_linekeeper_add_available_user_cb),
    info
  );

  g_signal_handlers_disconnect_by_func(
    G_OBJECT(user_table),
    G_CALLBACK(infinoted_plugin_linekeeper_remove_available_user_cb),
    info
  );

  if(info->dispatch != NULL)
  {
    directory = infinoted_plugin_manager_get_directory(info->plugin->manager);
    inf_io_remove_dispatch(infd_directory_get_io(directory), info->dispatch);
    info->dispatch = NULL;
  }

  if(info->user != NULL)
  {
    infinoted_plugin_linekeeper_remove_user(info);
  }

  if(info->buffer != NULL)
  {
    g_object_unref(info->buffer);
    info->buffer = NULL;
  }

  if(info->request != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      info->request,
      G_CALLBACK(infinoted_plugin_linekeeper_user_join_cb),
      info
    );

    info->request = NULL;
  }

  g_assert(info->proxy != NULL);
  g_object_unref(info->proxy);

  g_object_unref(session);
}
static void
infinoted_plugin_certificate_auth_deinitialize(gpointer plugin_info)
{
  InfinotedPluginCertificateAuth* plugin;
  InfRequest* remove_acl_account_request;
  InfCertificateCredentials* creds;
  guint i;

  plugin = (InfinotedPluginCertificateAuth*)plugin_info;

  /* Remove super user account. Note that this is not strictly necessary,
   * since the acocunt is transient and therefore is not written to disk,
   * so will not be re-created at the next server start. However, to be sure,
   * we explicitly remove the account at this point. */
  if(plugin->super_id != 0)
  {
    remove_acl_account_request = inf_browser_remove_acl_account(
      INF_BROWSER(infinoted_plugin_manager_get_directory(plugin->manager)),
      plugin->super_id,
      infinoted_plugin_certificate_auth_remove_acl_account_cb,
      plugin
    );

    /* This should be instantaneous: if we are not called back within the call
     * to inf_browser_remove_acl_account(), then we don't care about the
     * result, since we are being deinitialized. */
    if(remove_acl_account_request != NULL)
    {
      inf_signal_handlers_disconnect_by_func(
        plugin->set_acl_request,
        G_CALLBACK(infinoted_plugin_certificate_auth_remove_acl_account_cb),
        plugin
      );
    }
  }

  if(plugin->set_acl_request != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      plugin->set_acl_request,
      G_CALLBACK(infinoted_plugin_certificate_auth_set_acl_cb),
      plugin
    );

    g_object_unref(plugin->set_acl_request);
  }

  creds = infinoted_plugin_manager_get_credentials(plugin->manager);
  if(creds != NULL)
    gnutls_certificate_free_cas(inf_certificate_credentials_get(creds));

  infd_directory_set_certificate(
    infinoted_plugin_manager_get_directory(plugin->manager),
    NULL,
    NULL
  );

  /* If we have a ca_key set, the certificate that belongs to the key had
   * its ownership transferred to the directory, so make sure not to free
   * it twice here. */
  for(i = 0; i < plugin->n_cas; ++i)
    if(plugin->ca_key == NULL || i != plugin->ca_key_index)
      gnutls_x509_crt_deinit(plugin->cas[i]);
  g_free(plugin->cas);

  if(plugin->ca_key != NULL)
    gnutls_x509_privkey_deinit(plugin->ca_key);

  g_free(plugin->ca_list_file);
  g_free(plugin->ca_key_file);
  g_free(plugin->super_user);
}
static void
infinoted_plugin_document_stream_stop(
  InfinotedPluginDocumentStreamStream* stream,
  gboolean send_stop)
{
  guint32 comm;
  InfSession* session;

  if(send_stop)
  {
    comm = 5; /* STOP */
    if(!infinoted_plugin_document_stream_send(stream, &comm, 4))
      return;
  }

  if(stream->user != NULL)
  {
    g_assert(stream->proxy != NULL);
    g_object_get(G_OBJECT(stream->proxy), "session", &session, NULL);
    inf_session_set_user_status(session, stream->user, INF_USER_UNAVAILABLE);
    g_object_unref(session);

    g_object_unref(stream->user);
    stream->user = NULL;
  }

  if(stream->proxy != NULL)
  {
    g_object_unref(stream->proxy);
    stream->proxy = NULL;
  }

  if(stream->buffer != NULL)
  {
    if(INF_TEXT_IS_BUFFER(stream->buffer))
    {
      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(stream->buffer),
        G_CALLBACK(infinoted_plugin_document_stream_text_inserted_cb),
        stream
      );

      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(stream->buffer),
        G_CALLBACK(infinoted_plugin_document_stream_text_erased_cb),
        stream
      );
    }
    else if(INF_IS_CHAT_BUFFER(stream->buffer))
    {
      inf_signal_handlers_disconnect_by_func(
        G_OBJECT(stream->buffer),
        G_CALLBACK(infinoted_plugin_document_stream_chat_add_message_cb),
        stream
      );
    }

    g_object_unref(stream->buffer);
    stream->buffer = NULL;
  }

  if(stream->subscribe_request != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(stream->subscribe_request),
      G_CALLBACK(infinoted_plugin_document_stream_subscribe_func),
      stream
    );

    stream->subscribe_request = NULL;
  }

  if(stream->user_request != NULL)
  {
    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(stream->user_request),
      G_CALLBACK(infinoted_plugin_document_stream_user_join_func),
      stream
    );

    stream->user_request = NULL;
  }
}
示例#22
0
static void
infd_xmpp_server_set_tcp(InfdXmppServer* xmpp,
                         InfdTcpServer* tcp)
{
  InfdXmppServerPrivate* priv;
  InfdTcpServerStatus tcp_status;

  priv = INFD_XMPP_SERVER_PRIVATE(xmpp);

  g_object_freeze_notify(G_OBJECT(xmpp));

  if(priv->tcp != NULL)
  {
    g_object_get(G_OBJECT(priv->tcp), "status", &tcp_status, NULL);

    /* This will cause a notify that will adjust the XMPP status later */
    if(tcp_status != INFD_TCP_SERVER_CLOSED)
      infd_tcp_server_close(priv->tcp);

    /* TODO: Make sure there are no connections with sasl_own_context out
     * there anymore because otherwise the SASL callback might access an
     * invalid InfdServer pointer once we get finalized. */
#if 0
    if(priv->sasl_own_context != NULL)
    {
      inf_sasl_context_unref(priv->sasl_own_context);
      priv->sasl_own_context = NULL;
    }
#endif

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->tcp),
      G_CALLBACK(infd_xmpp_server_new_connection_cb),
      xmpp
    );

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->tcp),
      G_CALLBACK(infd_xmpp_server_error_cb),
      xmpp
    );

    inf_signal_handlers_disconnect_by_func(
      G_OBJECT(priv->tcp),
      G_CALLBACK(infd_xmpp_server_notify_status_cb),
      xmpp
    );

    g_object_unref(G_OBJECT(priv->tcp));
  }

  priv->tcp = tcp;

  if(tcp != NULL)
  {
    g_object_ref(G_OBJECT(tcp));

    g_signal_connect(
      G_OBJECT(tcp),
      "new-connection",
      G_CALLBACK(infd_xmpp_server_new_connection_cb),
      xmpp
    );

    g_signal_connect(
      G_OBJECT(tcp),
      "error",
      G_CALLBACK(infd_xmpp_server_error_cb),
      xmpp
    );

    g_signal_connect(
      G_OBJECT(tcp),
      "notify::status",
      G_CALLBACK(infd_xmpp_server_notify_status_cb),
      xmpp
    );

    g_object_get(G_OBJECT(tcp), "status", &tcp_status, NULL);
    switch(tcp_status)
    {
    case INFD_TCP_SERVER_CLOSED:
    case INFD_TCP_SERVER_BOUND:
      g_assert(priv->status == INFD_XMPP_SERVER_CLOSED);
      break;
    case INFD_TCP_SERVER_OPEN:
      priv->status = INFD_XMPP_SERVER_OPEN;
      g_object_notify(G_OBJECT(xmpp), "status");
      break;
    default:
      g_assert_not_reached();
      break;
    }
  }

  infd_xmpp_server_setup_own_sasl_context(xmpp);
  g_object_thaw_notify(G_OBJECT(xmpp));
}