/**
 * Frees a DBusWatchList.
 *
 * @param watch_list the watch list.
 */
void
_dbus_watch_list_free (DBusWatchList *watch_list)
{
  /* free watch_data and removes watches as a side effect */
  _dbus_watch_list_set_functions (watch_list,
                                  NULL, NULL, NULL, NULL, NULL);
  _dbus_list_foreach (&watch_list->watches,
                      (DBusForeachFunction) _dbus_watch_unref,
                      NULL);
  _dbus_list_clear (&watch_list->watches);

  dbus_free (watch_list);
}
/**
 * Frees a DBusTimeoutList.
 *
 * @param timeout_list the timeout list.
 */
void
_dbus_timeout_list_free (DBusTimeoutList *timeout_list)
{
  /* free timeout_data and remove timeouts as a side effect */
  _dbus_timeout_list_set_functions (timeout_list,
				    NULL, NULL, NULL, NULL, NULL);

  _dbus_list_foreach (&timeout_list->timeouts,
		      (DBusForeachFunction) _dbus_timeout_unref,
		      NULL);
  _dbus_list_clear (&timeout_list->timeouts);

  dbus_free (timeout_list);
}
示例#3
0
static void
free_rule_list_func (void *data)
{
    DBusList **list = data;

    if (list == NULL) /* DBusHashTable is on crack */
        return;

    _dbus_list_foreach (list, free_rule_func, NULL);

    _dbus_list_clear (list);

    dbus_free (list);
}
void
bus_config_parser_unref (BusConfigParser *parser)
{
  _dbus_string_free (&parser->user);
  _dbus_string_free (&parser->service_helper);
  _dbus_string_free (&parser->bus_type);

  _dbus_list_foreach (&parser->service_dirs,
                      (DBusForeachFunction) dbus_free,
                      NULL);

  _dbus_list_clear (&parser->service_dirs);

  dbus_free (parser);
}
示例#5
0
void
bus_policy_unref (BusPolicy *policy)
{
    _dbus_assert (policy->refcount > 0);

    policy->refcount -= 1;

    if (policy->refcount == 0)
    {
        _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
        _dbus_list_clear (&policy->default_rules);

        _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
        _dbus_list_clear (&policy->mandatory_rules);

        _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
        _dbus_list_clear (&policy->at_console_true_rules);

        _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
        _dbus_list_clear (&policy->at_console_false_rules);

        if (policy->rules_by_uid)
        {
            _dbus_hash_table_unref (policy->rules_by_uid);
            policy->rules_by_uid = NULL;
        }

        if (policy->rules_by_gid)
        {
            _dbus_hash_table_unref (policy->rules_by_gid);
            policy->rules_by_gid = NULL;
        }

        dbus_free (policy);
    }
}
/**
 * Sets the timeout functions. This function is the "backend"
 * for dbus_connection_set_timeout_functions().
 *
 * @param timeout_list the timeout list
 * @param add_function the add timeout function.
 * @param remove_function the remove timeout function.
 * @param toggled_function toggle notify function, or #NULL
 * @param data the data for those functions.
 * @param free_data_function the function to free the data.
 * @returns #FALSE if no memory
 *
 */
dbus_bool_t
_dbus_timeout_list_set_functions (DBusTimeoutList           *timeout_list,
				  DBusAddTimeoutFunction     add_function,
				  DBusRemoveTimeoutFunction  remove_function,
                                  DBusTimeoutToggledFunction toggled_function,
				  void                      *data,
				  DBusFreeFunction           free_data_function)
{
  /* Add timeouts with the new function, failing on OOM */
  if (add_function != NULL)
    {
      DBusList *link;
      
      link = _dbus_list_get_first_link (&timeout_list->timeouts);
      while (link != NULL)
        {
          DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
                                                     link);
      
          if (!(* add_function) (link->data, data))
            {
              /* remove it all again and return FALSE */
              DBusList *link2;
              
              link2 = _dbus_list_get_first_link (&timeout_list->timeouts);
              while (link2 != link)
                {
                  DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
                                                             link2);

                  (* remove_function) (link2->data, data);
                  
                  link2 = next;
                }

              return FALSE;
            }
      
          link = next;
        }
    }
  
  /* Remove all current timeouts from previous timeout handlers */

  if (timeout_list->remove_timeout_function != NULL)
    {
      _dbus_list_foreach (&timeout_list->timeouts,
			  (DBusForeachFunction) timeout_list->remove_timeout_function,
			  timeout_list->timeout_data);
    }

  if (timeout_list->timeout_free_data_function != NULL)
    (* timeout_list->timeout_free_data_function) (timeout_list->timeout_data);

  timeout_list->add_timeout_function = add_function;
  timeout_list->remove_timeout_function = remove_function;
  timeout_list->timeout_toggled_function = toggled_function;
  timeout_list->timeout_data = data;
  timeout_list->timeout_free_data_function = free_data_function;

  return TRUE;
}
示例#7
0
/**
 * 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;
}
/**
 * _dbus_shell_parse_argv:
 *
 * Parses a command line into an argument vector, in much the same way
 * the shell would, but without many of the expansions the shell would
 * perform (variable expansion, globs, operators, filename expansion,
 * etc. are not supported). The results are defined to be the same as
 * those you would get from a UNIX98 /bin/sh, as long as the input
 * contains none of the unsupported shell expansions. If the input
 * does contain such expansions, they are passed through
 * literally. Free the returned vector with dbus_free_string_array().
 *
 * @command_line: command line to parse
 * @argcp: return location for number of args
 * @argvp: return location for array of args
 * @error: error information
 **/
dbus_bool_t
_dbus_shell_parse_argv (const char *command_line,
                        int        *argcp,
                        char     ***argvp,
                        DBusError  *error)
{
    /* Code based on poptParseArgvString() from libpopt */
    int argc = 0;
    char **argv = NULL;
    DBusList *tokens = NULL;
    int i;
    DBusList *tmp_list;

    if (!command_line)
    {
        _dbus_verbose ("Command line is NULL\n");
        return FALSE;
    }

    tokens = tokenize_command_line (command_line, error);
    if (tokens == NULL)
    {
        _dbus_verbose ("No tokens for command line '%s'\n", command_line);
        return FALSE;
    }

    /* Because we can't have introduced any new blank space into the
     * tokens (we didn't do any new expansions), we don't need to
     * perform field splitting. If we were going to honor IFS or do any
     * expansions, we would have to do field splitting on each word
     * here. Also, if we were going to do any expansion we would need to
     * remove any zero-length words that didn't contain quotes
     * originally; but since there's no expansion we know all words have
     * nonzero length, unless they contain quotes.
     *
     * So, we simply remove quotes, and don't do any field splitting or
     * empty word removal, since we know there was no way to introduce
     * such things.
     */

    argc = _dbus_list_get_length (&tokens);
    argv = dbus_new (char *, argc + 1);
    if (!argv)
    {
        _DBUS_SET_OOM (error);
        goto error;
    }

    i = 0;
    tmp_list = tokens;
    while (tmp_list)
    {
        argv[i] = _dbus_shell_unquote (tmp_list->data);

        if (!argv[i])
        {
            int j;
            for (j = 0; j < i; j++)
                dbus_free(argv[j]);

            dbus_free (argv);
            _DBUS_SET_OOM (error);
            goto error;
        }

        tmp_list = _dbus_list_get_next_link (&tokens, tmp_list);
        ++i;
    }
    argv[argc] = NULL;

    _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL);
    _dbus_list_clear (&tokens);

    if (argcp)
        *argcp = argc;

    if (argvp)
        *argvp = argv;
    else
        dbus_free_string_array (argv);

    return TRUE;

error:
    _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL);
    _dbus_list_clear (&tokens);

    return FALSE;

}
static DBusList*
tokenize_command_line (const char *command_line, DBusError *error)
{
    char current_quote;
    const char *p;
    DBusString current_token;
    DBusList *retval = NULL;
    dbus_bool_t quoted;;

    current_quote = '\0';
    quoted = FALSE;
    p = command_line;

    if (!_dbus_string_init (&current_token))
    {
        _DBUS_SET_OOM (error);
        return NULL;
    }

    while (*p)
    {
        if (current_quote == '\\')
        {
            if (*p == '\n')
            {
                /* we append nothing; backslash-newline become nothing */
            }
            else
            {
                if (!_dbus_string_append_byte (&current_token, '\\') ||
                        !_dbus_string_append_byte (&current_token, *p))
                {
                    _DBUS_SET_OOM (error);
                    goto error;
                }
            }

            current_quote = '\0';
        }
        else if (current_quote == '#')
        {
            /* Discard up to and including next newline */
            while (*p && *p != '\n')
                ++p;

            current_quote = '\0';

            if (*p == '\0')
                break;
        }
        else if (current_quote)
        {
            if (*p == current_quote &&
                    /* check that it isn't an escaped double quote */
                    !(current_quote == '"' && quoted))
            {
                /* close the quote */
                current_quote = '\0';
            }

            /* Everything inside quotes, and the close quote,
             * gets appended literally.
             */

            if (!_dbus_string_append_byte (&current_token, *p))
            {
                _DBUS_SET_OOM (error);
                goto error;
            }
        }
        else
        {
            switch (*p)
            {
            case '\n':
                if (!delimit_token (&current_token, &retval, error))
                    goto error;

                _dbus_string_free (&current_token);

                if (!_dbus_string_init (&current_token))
                {
                    _DBUS_SET_OOM (error);
                    goto init_error;
                }

                break;

            case ' ':
            case '\t':
                /* If the current token contains the previous char, delimit
                 * the current token. A nonzero length
                 * token should always contain the previous char.
                 */
                if (_dbus_string_get_length (&current_token) > 0)
                {
                    if (!delimit_token (&current_token, &retval, error))
                        goto error;

                    _dbus_string_free (&current_token);

                    if (!_dbus_string_init (&current_token))
                    {
                        _DBUS_SET_OOM (error);
                        goto init_error;
                    }

                }

                /* discard all unquoted blanks (don't add them to a token) */
                break;


            /* single/double quotes are appended to the token,
             * escapes are maybe appended next time through the loop,
             * comment chars are never appended.
             */

            case '\'':
            case '"':
                if (!_dbus_string_append_byte (&current_token, *p))
                {
                    _DBUS_SET_OOM (error);
                    goto error;
                }

            /* FALL THRU */

            case '#':
            case '\\':
                current_quote = *p;
                break;

            default:
                /* Combines rules 4) and 6) - if we have a token, append to it,
                 * otherwise create a new token.
                 */
                if (!_dbus_string_append_byte (&current_token, *p))
                {
                    _DBUS_SET_OOM (error);
                    goto error;
                }
                break;
            }
        }

        /* We need to count consecutive backslashes mod 2,
         * to detect escaped doublequotes.
         */
        if (*p != '\\')
            quoted = FALSE;
        else
            quoted = !quoted;

        ++p;
    }

    if (!delimit_token (&current_token, &retval, error))
        goto error;

    if (current_quote)
    {
        dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "Unclosed quotes in command line");
        goto error;
    }

    if (retval == NULL)
    {
        dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "No tokens found in command line");
        goto error;
    }

    _dbus_string_free (&current_token);

    return retval;

error:
    _dbus_string_free (&current_token);

init_error:
    if (retval)
    {
        _dbus_list_foreach (&retval, (DBusForeachFunction) dbus_free, NULL);
        _dbus_list_clear (&retval);
    }

    return NULL;
}
示例#10
0
/**
 * Sets the watch functions. This function is the "backend"
 * for dbus_connection_set_watch_functions() and
 * dbus_server_set_watch_functions().
 *
 * @param watch_list the watch list.
 * @param add_function the add watch function.
 * @param remove_function the remove watch function.
 * @param toggled_function function on toggling enabled flag, or #NULL
 * @param data the data for those functions.
 * @param free_data_function the function to free the data.
 * @returns #FALSE if not enough memory
 *
 */
dbus_bool_t
_dbus_watch_list_set_functions (DBusWatchList           *watch_list,
                                DBusAddWatchFunction     add_function,
                                DBusRemoveWatchFunction  remove_function,
                                DBusWatchToggledFunction toggled_function,
                                void                    *data,
                                DBusFreeFunction         free_data_function)
{
  /* Add watches with the new watch function, failing on OOM */
  if (add_function != NULL)
    {
      DBusList *link;
      
      link = _dbus_list_get_first_link (&watch_list->watches);
      while (link != NULL)
        {
          DBusList *next = _dbus_list_get_next_link (&watch_list->watches,
                                                     link);

#ifdef DBUS_ENABLE_VERBOSE_MODE
          {
            const char *watch_type;
            int flags;

            flags = dbus_watch_get_flags (link->data);
            if ((flags & DBUS_WATCH_READABLE) &&
                (flags & DBUS_WATCH_WRITABLE))
              watch_type = "readwrite";
            else if (flags & DBUS_WATCH_READABLE)
              watch_type = "read";
            else if (flags & DBUS_WATCH_WRITABLE)
              watch_type = "write";
            else
              watch_type = "not read or write";
            
            _dbus_verbose ("Adding a %s watch on fd %d using newly-set add watch function\n",
                           watch_type,
                           dbus_watch_get_socket (link->data));
          }
#endif /* DBUS_ENABLE_VERBOSE_MODE */
          
          if (!(* add_function) (link->data, data))
            {
              /* remove it all again and return FALSE */
              DBusList *link2;
              
              link2 = _dbus_list_get_first_link (&watch_list->watches);
              while (link2 != link)
                {
                  DBusList *next = _dbus_list_get_next_link (&watch_list->watches,
                                                             link2);
                  
                  _dbus_verbose ("Removing watch on fd %d using newly-set remove function because initial add failed\n",
                                 dbus_watch_get_socket (link2->data));
                  
                  (* remove_function) (link2->data, data);
                  
                  link2 = next;
                }

              return FALSE;
            }
      
          link = next;
        }
    }
  
  /* Remove all current watches from previous watch handlers */

  if (watch_list->remove_watch_function != NULL)
    {
      _dbus_verbose ("Removing all pre-existing watches\n");
      
      _dbus_list_foreach (&watch_list->watches,
                          (DBusForeachFunction) watch_list->remove_watch_function,
                          watch_list->watch_data);
    }

  if (watch_list->watch_free_data_function != NULL)
    (* watch_list->watch_free_data_function) (watch_list->watch_data);
  
  watch_list->add_watch_function = add_function;
  watch_list->remove_watch_function = remove_function;
  watch_list->watch_toggled_function = toggled_function;
  watch_list->watch_data = data;
  watch_list->watch_free_data_function = free_data_function;

  return TRUE;
}
示例#11
0
文件: dbus-watch.c 项目: d-bus/dbus
/**
 * Sets the watch functions. This function is the "backend"
 * for dbus_connection_set_watch_functions() and
 * dbus_server_set_watch_functions().
 *
 * @param watch_list the watch list.
 * @param add_function the add watch function.
 * @param remove_function the remove watch function.
 * @param toggled_function function on toggling enabled flag, or #NULL
 * @param data the data for those functions.
 * @param free_data_function the function to free the data.
 * @returns #FALSE if not enough memory
 *
 */
dbus_bool_t
_dbus_watch_list_set_functions (DBusWatchList           *watch_list,
                                DBusAddWatchFunction     add_function,
                                DBusRemoveWatchFunction  remove_function,
                                DBusWatchToggledFunction toggled_function,
                                void                    *data,
                                DBusFreeFunction         free_data_function)
{
  /* Add watches with the new watch function, failing on OOM */
  if (add_function != NULL)
    {
      DBusList *link;
      
      link = _dbus_list_get_first_link (&watch_list->watches);
      while (link != NULL)
        {
          DBusList *next = _dbus_list_get_next_link (&watch_list->watches,
                                                     link);
#ifdef DBUS_ENABLE_VERBOSE_MODE
          DBusWatch *watch = link->data;

          _dbus_verbose ("Adding a %s watch on fd %" DBUS_POLLABLE_FORMAT " using newly-set add watch function\n",
                         watch_flags_to_string (dbus_watch_get_flags (link->data)),
                         _dbus_pollable_printable (watch->fd));
#endif
          
          if (!(* add_function) (link->data, data))
            {
              /* remove it all again and return FALSE */
              DBusList *link2;
              
              link2 = _dbus_list_get_first_link (&watch_list->watches);
              while (link2 != link)
                {
                  DBusList *next2 = _dbus_list_get_next_link (&watch_list->watches,
                                                              link2);
#ifdef DBUS_ENABLE_VERBOSE_MODE
                  DBusWatch *watch2 = link2->data;
                  
                  _dbus_verbose ("Removing watch on fd %" DBUS_POLLABLE_FORMAT " using newly-set remove function because initial add failed\n",
                                 _dbus_pollable_printable (watch2->fd));
#endif
                  
                  (* remove_function) (link2->data, data);
                  
                  link2 = next2;
                }

              return FALSE;
            }
      
          link = next;
        }
    }
  
  /* Remove all current watches from previous watch handlers */

  if (watch_list->remove_watch_function != NULL)
    {
      _dbus_verbose ("Removing all pre-existing watches\n");
      
      _dbus_list_foreach (&watch_list->watches,
                          (DBusForeachFunction) watch_list->remove_watch_function,
                          watch_list->watch_data);
    }

  if (watch_list->watch_free_data_function != NULL)
    (* watch_list->watch_free_data_function) (watch_list->watch_data);
  
  watch_list->add_watch_function = add_function;
  watch_list->remove_watch_function = remove_function;
  watch_list->watch_toggled_function = toggled_function;
  watch_list->watch_data = data;
  watch_list->watch_free_data_function = free_data_function;

  return TRUE;
}