Exemple #1
0
/**
 * Adds a new watch to the watch list, invoking the
 * application DBusAddWatchFunction if appropriate.
 *
 * @param watch_list the watch list.
 * @param watch the watch to add.
 * @returns #TRUE on success, #FALSE if no memory.
 */
dbus_bool_t
_dbus_watch_list_add_watch (DBusWatchList *watch_list,
                            DBusWatch     *watch)
{
  if (!_dbus_list_append (&watch_list->watches, watch))
    return FALSE;
  
  _dbus_watch_ref (watch);

  if (watch_list->add_watch_function != NULL)
    {
      _dbus_verbose ("Adding watch on fd %" DBUS_POLLABLE_FORMAT "\n",
                     _dbus_pollable_printable (watch->fd));
      
      if (!(* watch_list->add_watch_function) (watch,
                                               watch_list->watch_data))
        {
          _dbus_list_remove_last (&watch_list->watches, watch);
          _dbus_watch_unref (watch);
          return FALSE;
        }
    }
  
  return TRUE;
}
/**
 * Adds a new watch to the watch list, invoking the
 * application DBusAddWatchFunction if appropriate.
 *
 * @param watch_list the watch list.
 * @param watch the watch to add.
 * @returns #TRUE on success, #FALSE if no memory.
 */
dbus_bool_t
_dbus_watch_list_add_watch (DBusWatchList *watch_list,
                            DBusWatch     *watch)
{
  if (!_dbus_list_append (&watch_list->watches, watch))
    return FALSE;
  
  _dbus_watch_ref (watch);

  if (watch_list->add_watch_function != NULL)
    {
      _dbus_verbose ("Adding watch on fd %d\n",
                     dbus_watch_get_socket (watch));
      
      if (!(* watch_list->add_watch_function) (watch,
                                               watch_list->watch_data))
        {
          _dbus_list_remove_last (&watch_list->watches, watch);
          _dbus_watch_unref (watch);
          return FALSE;
        }
    }
  
  return TRUE;
}
/**
 * Copies a list. This is a linear-time operation.  If there isn't
 * enough memory to copy the entire list, the destination list will be
 * set to #NULL.
 *
 * @param list address of the head of the list to copy.
 * @param dest address where the copied list should be placed.
 * @returns #TRUE on success, #FALSE if not enough memory.
 */
dbus_bool_t
_dbus_list_copy (DBusList **list,
                 DBusList **dest)
{
  DBusList *link;

  _dbus_assert (list != dest);

  *dest = NULL;
  
  link = *list;
  while (link != NULL)
    {
      if (!_dbus_list_append (dest, link->data))
        {
          /* free what we have so far */
          _dbus_list_clear (dest);
          return FALSE;
        }
      
      link = _dbus_list_get_next_link (list, link);
    }

  return TRUE;
}
Exemple #4
0
dbus_bool_t 
bus_service_list_queued_owners (BusService *service,
                                DBusList  **return_list,
                                DBusError  *error)
{
  DBusList *link;

  _dbus_assert (*return_list == NULL);

  link = _dbus_list_get_first_link (&service->owners);
  _dbus_assert (link != NULL);
  
  while (link != NULL)
    {
      BusOwner *owner;
      const char *uname;

      owner = (BusOwner *) link->data;
      uname = bus_connection_get_name (owner->conn);

      if (!_dbus_list_append (return_list, (char *)uname))
        goto oom;

      link = _dbus_list_get_next_link (&service->owners, link);
    }
  
  return TRUE;
  
 oom:
  _dbus_list_clear (return_list);
  BUS_SET_OOM (error);
  return FALSE;
}
static dbus_bool_t
_dbus_condvar_wait_win32 (DBusCondVar *cond,
			  DBusCMutex *mutex,
			  int milliseconds)
{
  DWORD retval;
  dbus_bool_t ret;
  HANDLE event = TlsGetValue (dbus_cond_event_tls);

  if (!event)
    {
      event = CreateEvent (0, FALSE, FALSE, NULL);
      if (event == 0)
	return FALSE;
      TlsSetValue (dbus_cond_event_tls, event);
    }

  EnterCriticalSection (&cond->lock);

  /* The event must not be signaled. Check this */
  _dbus_assert (WaitForSingleObject (event, 0) == WAIT_TIMEOUT);

  ret = _dbus_list_append (&cond->list, event);
  
  LeaveCriticalSection (&cond->lock);
  
  if (!ret)
    return FALSE; /* Prepend failed */

  _dbus_platform_cmutex_unlock (mutex);
  retval = WaitForSingleObject (event, milliseconds);
  _dbus_platform_cmutex_lock (mutex);
  
  if (retval == WAIT_TIMEOUT)
    {
      EnterCriticalSection (&cond->lock);
      _dbus_list_remove (&cond->list, event);

      /* In the meantime we could have been signaled, so we must again
       * wait for the signal, this time with no timeout, to reset
       * it. retval is set again to honour the late arrival of the
       * signal */
      retval = WaitForSingleObject (event, 0);

      LeaveCriticalSection (&cond->lock);
    }

#ifndef DBUS_DISABLE_ASSERT
  EnterCriticalSection (&cond->lock);

  /* Now event must not be inside the array, check this */
  _dbus_assert (_dbus_list_remove (&cond->list, event) == FALSE);

  LeaveCriticalSection (&cond->lock);
#endif /* !G_DISABLE_ASSERT */

  return retval != WAIT_TIMEOUT;
}
Exemple #6
0
dbus_bool_t
bus_policy_append_mandatory_rule (BusPolicy      *policy,
                                  BusPolicyRule  *rule)
{
    if (!_dbus_list_append (&policy->mandatory_rules, rule))
        return FALSE;

    bus_policy_rule_ref (rule);

    return TRUE;
}
Exemple #7
0
dbus_bool_t
_dbus_loop_queue_dispatch (DBusLoop       *loop,
                           DBusConnection *connection)
{
    if (_dbus_list_append (&loop->need_dispatch, connection))
    {
        dbus_connection_ref (connection);
        return TRUE;
    }
    else
        return FALSE;
}
Exemple #8
0
void 
_dbus_condvar_new_at_location (DBusCondVar **location_p)
{
  *location_p = _dbus_condvar_new();

  if (thread_init_generation != _dbus_current_generation && *location_p)
    {
      if (!_dbus_list_append (&uninitialized_condvar_list, location_p))
        {
          _dbus_condvar_free (*location_p);
          *location_p = NULL;
        }
    }
}
Exemple #9
0
/**
 * This does the same thing as _dbus_mutex_new.  It however
 * gives another level of indirection by allocating a pointer
 * to point to the mutex location.  This allows the threading
 * module to swap out dummy mutexes for real a real mutex so libraries
 * can initialize threads even after the D-Bus API has been used.
 *
 * @param location_p the location of the new mutex, can return #NULL on OOM
 */
void
_dbus_mutex_new_at_location (DBusMutex **location_p)
{
  _dbus_assert (location_p != NULL);

  *location_p = _dbus_mutex_new();

  if (thread_init_generation != _dbus_current_generation && *location_p)
    {
      if (!_dbus_list_append (&uninitialized_mutex_list, location_p))
        {
	  _dbus_mutex_free (*location_p);
	  *location_p = NULL;
	}
    }
}
Exemple #10
0
/**
 * Inserts data into the list before the given existing link.
 * 
 * @param list the list to modify
 * @param before_this_link existing link to insert before, or #NULL to append
 * @param data the value to insert
 * @returns #TRUE on success, #FALSE if memory allocation fails
 */
dbus_bool_t
_dbus_list_insert_before (DBusList **list,
                          DBusList  *before_this_link,
                          void      *data)
{
  DBusList *link;
  
  if (before_this_link == NULL)
    return _dbus_list_append (list, data);
  else
    {
      link = alloc_link (data);
      if (link == NULL)
        return FALSE;
  
      link_before (list, before_this_link, link);
    }
  
  return TRUE;
}
Exemple #11
0
static dbus_bool_t
add_callback (DBusLoop  *loop,
              Callback *cb)
{
    if (!_dbus_list_append (&loop->callbacks, cb))
        return FALSE;

    loop->callback_list_serial += 1;

    switch (cb->type)
    {
    case CALLBACK_WATCH:
        loop->watch_count += 1;
        break;
    case CALLBACK_TIMEOUT:
        loop->timeout_count += 1;
        break;
    }

    return TRUE;
}
/**
 * Adds a new timeout to the timeout list, invoking the
 * application DBusAddTimeoutFunction if appropriate.
 *
 * @param timeout_list the timeout list.
 * @param timeout the timeout to add.
 * @returns #TRUE on success, #FALSE If no memory.
 */
dbus_bool_t
_dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list,
				DBusTimeout     *timeout)
{
  if (!_dbus_list_append (&timeout_list->timeouts, timeout))
    return FALSE;

  _dbus_timeout_ref (timeout);

  if (timeout_list->add_timeout_function != NULL)
    {
      if (!(* timeout_list->add_timeout_function) (timeout,
                                                   timeout_list->timeout_data))
        {
          _dbus_list_remove_last (&timeout_list->timeouts, timeout);
          _dbus_timeout_unref (timeout);
          return FALSE;
        }
    }

  return TRUE;
}
static dbus_bool_t
delimit_token (DBusString *token,
               DBusList **retval,
               DBusError *error)
{
    char *str;

    str = _dbus_strdup (_dbus_string_get_data (token));
    if (!str)
    {
        _DBUS_SET_OOM (error);
        return FALSE;
    }

    if (!_dbus_list_append (retval, str))
    {
        dbus_free (str);
        _DBUS_SET_OOM (error);
        return FALSE;
    }

    return TRUE;
}
Exemple #14
0
dbus_bool_t
bus_setup_debug_client (DBusConnection *connection)
{
  dbus_bool_t retval;

  if (!dbus_connection_add_filter (connection,
                                   client_disconnect_filter,
                                   NULL, NULL))
    return FALSE;

  retval = FALSE;

  if (client_loop == NULL)
    {
      client_loop = _dbus_loop_new ();
      if (client_loop == NULL)
        goto out;
    }

  if (!dbus_connection_set_watch_functions (connection,
                                            add_client_watch,
                                            remove_client_watch,
                                            toggle_client_watch,
                                            connection,
                                            NULL))
    goto out;

  if (!dbus_connection_set_timeout_functions (connection,
                                              add_client_timeout,
                                              remove_client_timeout,
                                              NULL,
                                              connection, NULL))
    goto out;

  if (!_dbus_list_append (&clients, connection))
    goto out;

  retval = TRUE;

 out:
  if (!retval)
    {
      dbus_connection_remove_filter (connection,
                                     client_disconnect_filter,
                                     NULL);

      dbus_connection_set_watch_functions (connection,
                                           NULL, NULL, NULL, NULL, NULL);
      dbus_connection_set_timeout_functions (connection,
                                             NULL, NULL, NULL, NULL, NULL);

      _dbus_list_remove_last (&clients, connection);

      if (clients == NULL)
        {
          _dbus_loop_unref (client_loop);
          client_loop = NULL;
        }
    }

  return retval;
}
Exemple #15
0
/**
 * @ingroup DBusListInternals
 * Unit test for DBusList
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_list_test (void)
{
  DBusList *list1;
  DBusList *list2;
  DBusList *link1;
  DBusList *link2;
  DBusList *copy1;
  DBusList *copy2;
  int i;
  
  list1 = NULL;
  list2 = NULL;

  /* Test append and prepend */
  
  i = 0;
  while (i < 10)
    {
      if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)))
        _dbus_assert_not_reached ("could not allocate for append");
      
      if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)))
        _dbus_assert_not_reached ("count not allocate for prepend");
      ++i;

      verify_list (&list1);
      verify_list (&list2);
      
      _dbus_assert (_dbus_list_get_length (&list1) == i);
      _dbus_assert (_dbus_list_get_length (&list2) == i);
    }

  _dbus_assert (is_ascending_sequence (&list1));
  _dbus_assert (is_descending_sequence (&list2));

  /* Test list clear */
  _dbus_list_clear (&list1);
  _dbus_list_clear (&list2);

  verify_list (&list1);
  verify_list (&list2);

  /* Test get_first, get_last, pop_first, pop_last */
  
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;
    }

  --i;
  while (i >= 0)
    {
      void *got_data1;
      void *got_data2;
      
      void *data1;
      void *data2;

      got_data1 = _dbus_list_get_last (&list1);
      got_data2 = _dbus_list_get_first (&list2);
      
      data1 = _dbus_list_pop_last (&list1);
      data2 = _dbus_list_pop_first (&list2);

      _dbus_assert (got_data1 == data1);
      _dbus_assert (got_data2 == data2);
      
      _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
      _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);

      verify_list (&list1);
      verify_list (&list2);

      _dbus_assert (is_ascending_sequence (&list1));
      _dbus_assert (is_descending_sequence (&list2));
      
      --i;
    }

  _dbus_assert (list1 == NULL);
  _dbus_assert (list2 == NULL);

  /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */
  
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;
    }

  --i;
  while (i >= 0)
    {
      DBusList *got_link1;
      DBusList *got_link2;

      DBusList *link1;
      DBusList *link2;
      
      void *data1;
      void *data2;
      
      got_link1 = _dbus_list_get_last_link (&list1);
      got_link2 = _dbus_list_get_first_link (&list2);
      
      link1 = _dbus_list_pop_last_link (&list1);
      link2 = _dbus_list_pop_first_link (&list2);

      _dbus_assert (got_link1 == link1);
      _dbus_assert (got_link2 == link2);

      data1 = link1->data;
      data2 = link2->data;

      _dbus_list_free_link (link1);
      _dbus_list_free_link (link2);
      
      _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
      _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);

      verify_list (&list1);
      verify_list (&list2);

      _dbus_assert (is_ascending_sequence (&list1));
      _dbus_assert (is_descending_sequence (&list2));
      
      --i;
    }

  _dbus_assert (list1 == NULL);
  _dbus_assert (list2 == NULL);
  
  /* Test iteration */
  
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;

      verify_list (&list1);
      verify_list (&list2);
      
      _dbus_assert (_dbus_list_get_length (&list1) == i);
      _dbus_assert (_dbus_list_get_length (&list2) == i);
    }

  _dbus_assert (is_ascending_sequence (&list1));
  _dbus_assert (is_descending_sequence (&list2));

  --i;
  link2 = _dbus_list_get_first_link (&list2);
  while (link2 != NULL)
    {
      verify_list (&link2); /* pretend this link is the head */
      
      _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);
      
      link2 = _dbus_list_get_next_link (&list2, link2);
      --i;
    }

  i = 0;
  link1 = _dbus_list_get_first_link (&list1);
  while (link1 != NULL)
    {
      verify_list (&link1); /* pretend this link is the head */
      
      _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
      
      link1 = _dbus_list_get_next_link (&list1, link1);
      ++i;
    }

  --i;
  link1 = _dbus_list_get_last_link (&list1);
  while (link1 != NULL)
    {
      verify_list (&link1); /* pretend this link is the head */

      _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
      
      link1 = _dbus_list_get_prev_link (&list1, link1);
      --i;
    }

  _dbus_list_clear (&list1);
  _dbus_list_clear (&list2);

  /* Test remove */
  
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;
    }

  --i;
  while (i >= 0)
    {
      if ((i % 2) == 0)
        {
          if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
            _dbus_assert_not_reached ("element should have been in list");
          if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
            _dbus_assert_not_reached ("element should have been in list");

          verify_list (&list1);
          verify_list (&list2);
        }
      --i;
    }

  _dbus_assert (all_odd_values (&list1));
  _dbus_assert (all_odd_values (&list2));

  _dbus_list_clear (&list1);
  _dbus_list_clear (&list2);

  /* test removing the other half of the elements */
  
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;
    }

  --i;
  while (i >= 0)
    {
      if ((i % 2) != 0)
        {
          if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i)))
            _dbus_assert_not_reached ("element should have been in list");
          if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i)))
            _dbus_assert_not_reached ("element should have been in list");

          verify_list (&list1);
          verify_list (&list2);
        }
      --i;
    }

  _dbus_assert (all_even_values (&list1));
  _dbus_assert (all_even_values (&list2));

  /* clear list using remove_link */
  while (list1 != NULL)
    {
      _dbus_list_remove_link (&list1, list1);
      verify_list (&list1);
    }
  while (list2 != NULL)
    {
      _dbus_list_remove_link (&list2, list2);
      verify_list (&list2);
    }

  /* Test remove link more generally */
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;
    }

  --i;
  link2 = _dbus_list_get_first_link (&list2);
  while (link2 != NULL)
    {
      DBusList *next = _dbus_list_get_next_link (&list2, link2);
      
      _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i);

      if ((i % 2) == 0)
        _dbus_list_remove_link (&list2, link2);

      verify_list (&list2);
      
      link2 = next;
      --i;
    }

  _dbus_assert (all_odd_values (&list2));  
  _dbus_list_clear (&list2);
  
  i = 0;
  link1 = _dbus_list_get_first_link (&list1);
  while (link1 != NULL)
    {
      DBusList *next = _dbus_list_get_next_link (&list1, link1);

      _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);

      if ((i % 2) != 0)
        _dbus_list_remove_link (&list1, link1);

      verify_list (&list1);
      
      link1 = next;
      ++i;
    }

  _dbus_assert (all_even_values (&list1));
  _dbus_list_clear (&list1);

  /* Test copying a list */
  i = 0;
  while (i < 10)
    {
      _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
      _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
      ++i;
    }

  /* bad pointers, because they are allowed in the copy dest */
  copy1 = _DBUS_INT_TO_POINTER (0x342234);
  copy2 = _DBUS_INT_TO_POINTER (23);
  
  _dbus_list_copy (&list1, &copy1);
  verify_list (&list1);
  verify_list (&copy1);
  _dbus_assert (lists_equal (&list1, &copy1));
  
  _dbus_list_copy (&list2, &copy2);
  verify_list (&list2);
  verify_list (&copy2);
  _dbus_assert (lists_equal (&list2, &copy2));

  /* Now test copying empty lists */
  _dbus_list_clear (&list1);
  _dbus_list_clear (&list2);
  _dbus_list_clear (&copy1);
  _dbus_list_clear (&copy2);
  
  /* bad pointers, because they are allowed in the copy dest */
  copy1 = _DBUS_INT_TO_POINTER (0x342234);
  copy2 = _DBUS_INT_TO_POINTER (23);
  
  _dbus_list_copy (&list1, &copy1);
  verify_list (&list1);
  verify_list (&copy1);
  _dbus_assert (lists_equal (&list1, &copy1));
  
  _dbus_list_copy (&list2, &copy2);
  verify_list (&list2);
  verify_list (&copy2);
  _dbus_assert (lists_equal (&list2, &copy2));

  _dbus_list_clear (&list1);
  _dbus_list_clear (&list2);
  
  /* insert_before on empty list */
  _dbus_list_insert_before (&list1, NULL,
                            _DBUS_INT_TO_POINTER (0));
  verify_list (&list1);

  /* inserting before first element */
  _dbus_list_insert_before (&list1, list1,
                            _DBUS_INT_TO_POINTER (2));
  verify_list (&list1);
  _dbus_assert (is_descending_sequence (&list1));

  /* inserting in the middle */
  _dbus_list_insert_before (&list1, list1->next,
                            _DBUS_INT_TO_POINTER (1));
  verify_list (&list1);
  _dbus_assert (is_descending_sequence (&list1));  

  /* using insert_before to append */
  _dbus_list_insert_before (&list1, NULL,
                            _DBUS_INT_TO_POINTER (-1));
  verify_list (&list1);
  _dbus_assert (is_descending_sequence (&list1));
  
  _dbus_list_clear (&list1);

  /* insert_after on empty list */
  _dbus_list_insert_after (&list1, NULL,
                           _DBUS_INT_TO_POINTER (0));
  verify_list (&list1);

  /* inserting after first element */
  _dbus_list_insert_after (&list1, list1,
                           _DBUS_INT_TO_POINTER (1));
  verify_list (&list1);
  _dbus_assert (is_ascending_sequence (&list1));

  /* inserting at the end */
  _dbus_list_insert_after (&list1, list1->next,
                           _DBUS_INT_TO_POINTER (2));
  verify_list (&list1);
  _dbus_assert (is_ascending_sequence (&list1));

  /* using insert_after to prepend */
  _dbus_list_insert_after (&list1, NULL,
                           _DBUS_INT_TO_POINTER (-1));
  verify_list (&list1);
  _dbus_assert (is_ascending_sequence (&list1));
  
  _dbus_list_clear (&list1);

  /* using remove_last */
  _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2));
  _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1));
  _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3));

  _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2));
  
  verify_list (&list1);
  _dbus_assert (is_ascending_sequence (&list1));
  
  _dbus_list_clear (&list1);
  
  return TRUE;
}
Exemple #16
0
/* this function is self-cancelling if you cancel the transaction */
dbus_bool_t
bus_service_add_owner (BusService     *service,
                       DBusConnection *connection,
                       dbus_uint32_t  flags,
                       BusTransaction *transaction,
                       DBusError      *error)
{
  BusOwner *bus_owner;
  DBusList *bus_owner_link;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
 /* Send service acquired message first, OOM will result
  * in cancelling the transaction
  */
  if (service->owners == NULL)
    {
      if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
        return FALSE;
    }
  
  bus_owner_link = _bus_service_find_owner_link (service, connection);
  
  if (bus_owner_link == NULL)
    {
      bus_owner = bus_owner_new (service, connection, flags);
      if (bus_owner == NULL)
        {
          BUS_SET_OOM (error);
          return FALSE;
        }

      bus_owner_set_flags (bus_owner, flags);
      if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
        {
          if (!_dbus_list_append (&service->owners,
                                  bus_owner))
            {
              bus_owner_unref (bus_owner);
              BUS_SET_OOM (error);
              return FALSE;
            }
        }
      else
        {
          if (!_dbus_list_insert_after (&service->owners,
                                         _dbus_list_get_first_link (&service->owners),
                                         bus_owner))
            {
              bus_owner_unref (bus_owner);
              BUS_SET_OOM (error);
              return FALSE;
            }
        }      
    } 
  else 
    {
      /* Update the link since we are already in the queue
       * No need for operations that can produce OOM
       */

      bus_owner = (BusOwner *) bus_owner_link->data;
      if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
        {
	  DBusList *link;
          _dbus_list_unlink (&service->owners, bus_owner_link);
	  link = _dbus_list_get_first_link (&service->owners);
	  _dbus_assert (link != NULL);
	  
          _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
        }
      
      bus_owner_set_flags (bus_owner, flags);
      return TRUE;
    }

  if (!add_cancel_ownership_to_transaction (transaction,
                                            service,
                                            bus_owner))
    {
      bus_service_unlink_owner (service, bus_owner);
      BUS_SET_OOM (error);
      return FALSE;
    }

  return TRUE;
}
dbus_bool_t
bus_config_parser_content (BusConfigParser   *parser,
                           const DBusString  *content,
                           DBusError         *error)
{
  DBusString content_sane;
  dbus_bool_t retval;

  retval = FALSE;

  if (!_dbus_string_init (&content_sane))
    {
      BUS_SET_OOM (error);
      goto out;
    }
  if (!_dbus_string_copy (content, 0, &content_sane, 0))
    {
      BUS_SET_OOM (error);
      goto out_content;
    }

  /* rip out white space */
  _dbus_string_chop_white (&content_sane);
  if (_dbus_string_get_length (&content_sane) == 0)
    {
      /* optimise, there is no content */
      retval = TRUE;
      goto out_content;
    }

  switch (parser->type)
    {
    case ELEMENT_SERVICEDIR:
      {
      	char *cpath;

        /* copy the sane data into a char array */
        if (!_dbus_string_copy_data(&content_sane, &cpath))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }

        /* append the dynamic char string to service dirs */
        if (!_dbus_list_append (&parser->service_dirs, cpath))
          {
            dbus_free (cpath);
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;

    case ELEMENT_SERVICEHELPER:
      {
        if (!_dbus_string_copy (&content_sane, 0, &parser->service_helper, 0))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;

    case ELEMENT_USER:
      {
        if (!_dbus_string_copy (&content_sane, 0, &parser->user, 0))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;

    case ELEMENT_TYPE:
      {
        if (!_dbus_string_copy (&content_sane, 0, &parser->bus_type, 0))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;
    default:
      {
        /* we don't care about the others... really */
        _dbus_verbose (" CONTENTS We dont care '%s' type '%i'\n", _dbus_string_get_const_data (&content_sane), parser->type);
        break;
      }
    }

  /* woot! */
  retval = TRUE;

out_content:
  _dbus_string_free (&content_sane);
out:
  return retval;
}
Exemple #18
0
dbus_bool_t
bus_expire_list_test (const DBusString *test_data_dir)
{
  DBusLoop *loop;
  BusExpireList *list;
  long tv_sec, tv_usec;
  long tv_sec_not_expired, tv_usec_not_expired;
  long tv_sec_expired, tv_usec_expired;
  long tv_sec_past, tv_usec_past;
  TestExpireItem *item;
  int next_interval;
  dbus_bool_t result = FALSE;


  loop = _dbus_loop_new ();
  _dbus_assert (loop != NULL);

#define EXPIRE_AFTER 100
  
  list = bus_expire_list_new (loop, EXPIRE_AFTER,
                              test_expire_func, NULL);
  _dbus_assert (list != NULL);

  _dbus_get_current_time (&tv_sec, &tv_usec);

  tv_sec_not_expired = tv_sec;
  tv_usec_not_expired = tv_usec;
  time_add_milliseconds (&tv_sec_not_expired,
                         &tv_usec_not_expired, EXPIRE_AFTER - 1);

  tv_sec_expired = tv_sec;
  tv_usec_expired = tv_usec;
  time_add_milliseconds (&tv_sec_expired,
                         &tv_usec_expired, EXPIRE_AFTER);
  

  tv_sec_past = tv_sec - 1;
  tv_usec_past = tv_usec;

  item = dbus_new0 (TestExpireItem, 1);

  if (item == NULL)
    goto oom;

  item->item.added_tv_sec = tv_sec;
  item->item.added_tv_usec = tv_usec;
  if (!_dbus_list_append (&list->items, item))
    _dbus_assert_not_reached ("out of memory");

  next_interval =
    do_expiration_with_current_time (list, tv_sec_not_expired,
                                     tv_usec_not_expired);
  _dbus_assert (item->expire_count == 0);
  _dbus_verbose ("next_interval = %d\n", next_interval);
  _dbus_assert (next_interval == 1);
  
  next_interval =
    do_expiration_with_current_time (list, tv_sec_expired,
                                     tv_usec_expired);
  _dbus_assert (item->expire_count == 1);
  _dbus_verbose ("next_interval = %d\n", next_interval);
  _dbus_assert (next_interval == -1);

  next_interval =
    do_expiration_with_current_time (list, tv_sec_past,
                                     tv_usec_past);
  _dbus_assert (item->expire_count == 1);
  _dbus_verbose ("next_interval = %d\n", next_interval);
  _dbus_assert (next_interval == 1000 + EXPIRE_AFTER);

  _dbus_list_clear (&list->items);
  dbus_free (item);
  
  bus_expire_list_free (list);
  _dbus_loop_unref (loop);
  
  result = TRUE;

 oom:
  return result;
}
/**
 * Verifies that the range of type_str from type_pos to type_end is a
 * valid signature.  If this function returns #TRUE, it will be safe
 * to iterate over the signature with a types-only #DBusTypeReader.
 * The range passed in should NOT include the terminating
 * nul/DBUS_TYPE_INVALID.
 *
 * @param type_str the string
 * @param type_pos where the typecodes start
 * @param len length of typecodes
 * @returns #DBUS_VALID if valid, reason why invalid otherwise
 */
DBusValidity
_dbus_validate_signature_with_reason (const DBusString *type_str,
                                      int               type_pos,
                                      int               len)
{
  const unsigned char *p;
  const unsigned char *end;
  int last;
  int struct_depth;
  int array_depth;
  int dict_entry_depth;
  DBusValidity result;

  int element_count;
  DBusList *element_count_stack;

  result = DBUS_VALID;
  element_count_stack = NULL;

  if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0)))
    {
      result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
      goto out;
    }

  _dbus_assert (type_str != NULL);
  _dbus_assert (type_pos < _DBUS_INT32_MAX - len);
  _dbus_assert (len >= 0);
  _dbus_assert (type_pos >= 0);

  if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH)
    {
      result = DBUS_INVALID_SIGNATURE_TOO_LONG;
      goto out;
    }

  p = _dbus_string_get_const_data_len (type_str, type_pos, 0);

  end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0);
  struct_depth = 0;
  array_depth = 0;
  dict_entry_depth = 0;
  last = DBUS_TYPE_INVALID;

  while (p != end)
    {
      switch (*p)
        {
        case DBUS_TYPE_BYTE:
        case DBUS_TYPE_BOOLEAN:
        case DBUS_TYPE_INT16:
        case DBUS_TYPE_UINT16:
        case DBUS_TYPE_INT32:
        case DBUS_TYPE_UINT32:
        case DBUS_TYPE_INT64:
        case DBUS_TYPE_UINT64:
        case DBUS_TYPE_DOUBLE:
        case DBUS_TYPE_STRING:
        case DBUS_TYPE_OBJECT_PATH:
        case DBUS_TYPE_SIGNATURE:
        case DBUS_TYPE_VARIANT:
          break;

        case DBUS_TYPE_ARRAY:
          array_depth += 1;
          if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
            {
              result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
              goto out;
            }
          break;

        case DBUS_STRUCT_BEGIN_CHAR:
          struct_depth += 1;

          if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
            {
              result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
              goto out;
            }
          
          if (!_dbus_list_append (&element_count_stack, 
                             _DBUS_INT_TO_POINTER (0)))
            {
              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
              goto out;
            }

          break;

        case DBUS_STRUCT_END_CHAR:
          if (struct_depth == 0)
            {
              result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
              goto out;
            }

          if (last == DBUS_STRUCT_BEGIN_CHAR)
            {
              result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
              goto out;
            }

          _dbus_list_pop_last (&element_count_stack);

          struct_depth -= 1;
          break;

        case DBUS_DICT_ENTRY_BEGIN_CHAR:
          if (last != DBUS_TYPE_ARRAY)
            {
              result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
              goto out;
            }
            
          dict_entry_depth += 1;

          if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
            {
              result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
              goto out;
            }

          if (!_dbus_list_append (&element_count_stack, 
                             _DBUS_INT_TO_POINTER (0)))
            {
              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
              goto out;
            }

          break;

        case DBUS_DICT_ENTRY_END_CHAR:
          if (dict_entry_depth == 0)
            {
              result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
              goto out;
            }
            
          dict_entry_depth -= 1;

          element_count = 
            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));

          if (element_count != 2)
            {
              if (element_count == 0)
                result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
              else if (element_count == 1)
                result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD;
              else
                result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS;
              
              goto out;
            }
          break;
          
        case DBUS_TYPE_STRUCT:     /* doesn't appear in signatures */
        case DBUS_TYPE_DICT_ENTRY: /* ditto */
        default:
          result = DBUS_INVALID_UNKNOWN_TYPECODE;
	  goto out;
        }

      if (*p != DBUS_TYPE_ARRAY && 
          *p != DBUS_DICT_ENTRY_BEGIN_CHAR && 
	  *p != DBUS_STRUCT_BEGIN_CHAR) 
        {
          element_count = 
            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));

          ++element_count;

          if (!_dbus_list_append (&element_count_stack, 
                             _DBUS_INT_TO_POINTER (element_count)))
            {
              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
              goto out;
            }
        }
      
      if (array_depth > 0)
        {
          if (*p == DBUS_TYPE_ARRAY && p != end)
            {
	       const char *p1;
	       p1 = p + 1;
               if (*p1 == DBUS_STRUCT_END_CHAR ||
                   *p1 == DBUS_DICT_ENTRY_END_CHAR)
                 {
                   result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
                   goto out;
                 }
            }
          else
	    {
              array_depth = 0;
	    }
        }

      if (last == DBUS_DICT_ENTRY_BEGIN_CHAR &&
          !dbus_type_is_basic (*p))
        {
          result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
          goto out;
        }
        
      last = *p;
      ++p;
    }


  if (array_depth > 0)
    {
      result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
      goto out;
    }
    
  if (struct_depth > 0)
    {
       result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
       goto out;
    }
    
  if (dict_entry_depth > 0)
    {
      result =  DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
      goto out;
    }
    
  _dbus_assert (last != DBUS_TYPE_ARRAY);
  _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR);
  _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR);

  result = DBUS_VALID;

out:
  _dbus_list_clear (&element_count_stack);
  return result;
}
/**
 * Split paths into a list of char strings
 * 
 * @param dirs string with pathes 
 * @param suffix string concated to each path in dirs
 * @param dir_list contains a list of splitted pathes
 * return #TRUE is pathes could be splittes,#FALSE in oom case 
 */
dbus_bool_t
_dbus_split_paths_and_append (DBusString *dirs, 
                              const char *suffix, 
                              DBusList  **dir_list)
{
   int start;
   int i;
   int len;
   char *cpath;
   DBusString file_suffix;

   start = 0;
   i = 0;

   _dbus_string_init_const (&file_suffix, suffix);

   len = _dbus_string_get_length (dirs);

   while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
     {
       DBusString path;

       if (!_dbus_string_init (&path))
          goto oom;

       if (!_dbus_string_copy_len (dirs,
                                   start,
                                   i - start,
                                   &path,
                                   0))
          {
            _dbus_string_free (&path);
            goto oom;
          }

        _dbus_string_chop_white (&path);

        /* check for an empty path */
        if (_dbus_string_get_length (&path) == 0)
          goto next;

        if (!_dbus_concat_dir_and_file (&path,
                                        &file_suffix))
          {
            _dbus_string_free (&path);
            goto oom;
          }

        if (!_dbus_string_copy_data(&path, &cpath))
          {
            _dbus_string_free (&path);
            goto oom;
          }

        if (!_dbus_list_append (dir_list, cpath))
          {
            _dbus_string_free (&path);              
            dbus_free (cpath);
            goto oom;
          }

       next:
        _dbus_string_free (&path);
        start = i + 1;
    } 
      
  if (start != len)
    { 
      DBusString path;

      if (!_dbus_string_init (&path))
        goto oom;

      if (!_dbus_string_copy_len (dirs,
                                  start,
                                  len - start,
                                  &path,
                                  0))
        {
          _dbus_string_free (&path);
          goto oom;
        }

      if (!_dbus_concat_dir_and_file (&path,
                                      &file_suffix))
        {
          _dbus_string_free (&path);
          goto oom;
        }

      if (!_dbus_string_copy_data(&path, &cpath))
        {
          _dbus_string_free (&path);
          goto oom;
        }

      if (!_dbus_list_append (dir_list, cpath))
        {
          _dbus_string_free (&path);              
          dbus_free (cpath);
          goto oom;
        }

      _dbus_string_free (&path); 
    }

  return TRUE;

 oom:
  _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 
  _dbus_list_clear (dir_list);
  return FALSE;
}
static dbus_bool_t
bus_driver_handle_list_queued_owners (DBusConnection *connection,
				      BusTransaction *transaction,
				      DBusMessage    *message,
				      DBusError      *error)
{
  const char *text;
  DBusList *base_names;
  DBusList *link;
  DBusString str;
  BusRegistry *registry;
  BusService *service;
  DBusMessage *reply;
  DBusMessageIter iter, array_iter;
  char *dbus_service_name = DBUS_SERVICE_DBUS;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  registry = bus_connection_get_registry (connection);

  base_names = NULL;
  text = NULL;
  reply = NULL;

  if (! dbus_message_get_args (message, error,
			       DBUS_TYPE_STRING, &text,
			       DBUS_TYPE_INVALID))
      goto failed;

  _dbus_string_init_const (&str, text);
  service = bus_registry_lookup (registry, &str);
  if (service == NULL &&
      _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
    {
      /* ORG_FREEDESKTOP_DBUS owns itself */
      if (! _dbus_list_append (&base_names, dbus_service_name))
        goto oom;
    }
  else if (service == NULL)
    {
      dbus_set_error (error, 
                      DBUS_ERROR_NAME_HAS_NO_OWNER,
                      "Could not get owners of name '%s': no such name", text);
      goto failed;
    }
  else
    {
      if (!bus_service_list_queued_owners (service, 
                                           &base_names,
                                           error))
        goto failed;
    }

  _dbus_assert (base_names != NULL);

  reply = dbus_message_new_method_return (message);
  if (reply == NULL)
    goto oom;

  dbus_message_iter_init_append (reply, &iter);
  if (!dbus_message_iter_open_container (&iter,
                                         DBUS_TYPE_ARRAY,
                                         DBUS_TYPE_STRING_AS_STRING,
                                         &array_iter))
    goto oom;
  
  link = _dbus_list_get_first_link (&base_names);
  while (link != NULL)
    {
      char *uname;

      _dbus_assert (link->data != NULL);
      uname = (char *)link->data;
    
      if (!dbus_message_iter_append_basic (&array_iter, 
                                           DBUS_TYPE_STRING,
                                           &uname))
        goto oom;

      link = _dbus_list_get_next_link (&base_names, link);
    }

  if (! dbus_message_iter_close_container (&iter, &array_iter))
    goto oom;
                                    
 
  if (! bus_transaction_send_from_driver (transaction, connection, reply))
    goto oom;

  dbus_message_unref (reply);

  return TRUE;

 oom:
  BUS_SET_OOM (error);

 failed:
  _DBUS_ASSERT_ERROR_IS_SET (error);
  if (reply)
    dbus_message_unref (reply);

  if (base_names)
    _dbus_list_clear (&base_names);

  return FALSE;
}
Exemple #22
0
static dbus_bool_t
test_command_line (const char *arg1, ...)
{
  int i, original_argc, shell_argc;
  char **shell_argv;
  char **original_argv;
  char *command_line, *tmp;
  DBusString str;
  DBusList *list = NULL, *node;
  va_list var_args;
  DBusError error;

  va_start (var_args, arg1);
  _dbus_list_append (&list, (char *)arg1);
  do
    {
      tmp = va_arg (var_args, char *);
      if (!tmp)
        break;
      _dbus_list_append (&list, tmp);
    } while (tmp);
  va_end (var_args);

  original_argc = _dbus_list_get_length (&list);
  original_argv = dbus_new (char *, original_argc);
  _dbus_string_init (&str);
  for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node;
       i++, node = _dbus_list_get_next_link (&list, node))
    {
      original_argv[i] = node->data;
      if (i > 0)
        _dbus_string_append_byte (&str, ' ');
      _dbus_string_append (&str, original_argv[i]);
    }
  
  _dbus_list_clear (&list);
  command_line = _dbus_string_get_data (&str);
  printf ("\n\nTesting command line '%s'\n", command_line);

  dbus_error_init (&error);
  if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error))
    {
      fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : "");
      return FALSE;
    }
  else
    {
      if (shell_argc != original_argc)
        {
          printf ("Number of arguments returned (%d) don't match original (%d)\n",
                  shell_argc, original_argc);
          return FALSE;
        } 
      printf ("Number of arguments: %d\n", shell_argc);
      for (i = 0; i < shell_argc; i++)
        {
          char *unquoted;
          
          unquoted = _dbus_shell_unquote (original_argv[i]);
          if (strcmp (unquoted ? unquoted : "",
                      shell_argv[i] ? shell_argv[i] : ""))
            {
              printf ("Position %d, returned argument (%s) does not match original (%s)\n",
                      i, shell_argv[i], unquoted);
              dbus_free (unquoted);
              return FALSE;
            }
          dbus_free (unquoted);
          if (shell_argv[i])
            printf ("Argument %d = %s\n", i, shell_argv[i]);
        }
      
      dbus_free_string_array (shell_argv);
    }
  
  _dbus_string_free (&str);
  
  return TRUE;
}