/** * 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); }
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); }
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; }
/** * 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 (¤t_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 (¤t_token, '\\') || !_dbus_string_append_byte (¤t_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 (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } } else { switch (*p) { case '\n': if (!delimit_token (¤t_token, &retval, error)) goto error; _dbus_string_free (¤t_token); if (!_dbus_string_init (¤t_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 (¤t_token) > 0) { if (!delimit_token (¤t_token, &retval, error)) goto error; _dbus_string_free (¤t_token); if (!_dbus_string_init (¤t_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 (¤t_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 (¤t_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 (¤t_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 (¤t_token); return retval; error: _dbus_string_free (¤t_token); init_error: if (retval) { _dbus_list_foreach (&retval, (DBusForeachFunction) dbus_free, NULL); _dbus_list_clear (&retval); } return NULL; }
/** * 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; }
/** * 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; }