int parse_acl(const char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) { _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not freed */ _cleanup_strv_free_ char **split; char **entry; int r = -EINVAL; _cleanup_(acl_freep) acl_t a_acl = NULL, d_acl = NULL; split = strv_split(text, ","); if (!split) return -ENOMEM; STRV_FOREACH(entry, split) { char *p; p = startswith(*entry, "default:"); if (!p) p = startswith(*entry, "d:"); if (p) r = strv_push(&d, p); else r = strv_push(&a, *entry); if (r < 0) return r; }
static int load_env_file_push_pairs( const char *filename, unsigned line, const char *key, char *value, void *userdata, int *n_pushed) { char ***m = userdata; int r; r = check_utf8ness_and_warn(filename, line, key, value); if (r < 0) return r; r = strv_extend(m, key); if (r < 0) return -ENOMEM; if (!value) { r = strv_extend(m, ""); if (r < 0) return -ENOMEM; } else { r = strv_push(m, value); if (r < 0) return r; } if (n_pushed) (*n_pushed)++; return 0; }
static int load_env_file_push(const char *filename, unsigned line, const char *key, char *value, void *userdata) { char ***m = userdata; char *p; int r; if (!utf8_is_valid(key)) { log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", filename, line, key); return -EINVAL; } if (value && !utf8_is_valid(value)) { /* FIXME: filter UTF-8 */ log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", filename, line, key, value); return -EINVAL; } p = strjoin(key, "=", strempty(value), NULL); if (!p) return -ENOMEM; r = strv_push(m, p); if (r < 0) { free(p); return r; } free(value); return 0; }
static int unit_file_find_dir( const char *original_root, const char *path, char ***dirs) { _cleanup_free_ char *chased = NULL; int r; assert(path); r = chase_symlinks(path, original_root, 0, &chased); if (r == -ENOENT) /* Ignore -ENOENT, after all most units won't have a drop-in dir. */ return 0; if (r == -ENAMETOOLONG) { /* Also, ignore -ENAMETOOLONG but log about it. After all, users are not even able to create the * drop-in dir in such case. This mostly happens for device units with an overly long /sys path. */ log_debug_errno(r, "Path '%s' too long, couldn't canonicalize, ignoring.", path); return 0; } if (r < 0) return log_warning_errno(r, "Failed to canonicalize path '%s': %m", path); r = strv_push(dirs, chased); if (r < 0) return log_oom(); chased = NULL; return 0; }
int strv_consume(char ***l, char *value) { int r; r = strv_push(l, value); if (r < 0) free(value); return r; }
int strv_extend(char ***l, const char *value) { char *v; int r; if (!value) return 0; v = strdup(value); if (!v) return -ENOMEM; r = strv_push(l, v); if (r < 0) free(v); return r; }
static int load_env_file_push(const char *key, char *value, void *userdata) { char ***m = userdata; char *p; int r; p = strjoin(key, "=", strempty(value), NULL); if (!p) return -ENOMEM; r = strv_push(m, p); if (r < 0) { free(p); return r; } free(value); return 0; }
static int load_env_file_push_pairs( const char *filename, unsigned line, const char *key, char *value, void *userdata, int *n_pushed) { char ***m = userdata; int r; if (!utf8_is_valid(key)) { _cleanup_free_ char *t = utf8_escape_invalid(key); log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t); return -EINVAL; } if (value && !utf8_is_valid(value)) { _cleanup_free_ char *t = utf8_escape_invalid(value); log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t); return -EINVAL; } r = strv_extend(m, key); if (r < 0) return -ENOMEM; if (!value) { r = strv_extend(m, ""); if (r < 0) return -ENOMEM; } else { r = strv_push(m, value); if (r < 0) return r; } if (n_pushed) (*n_pushed)++; return 0; }
static int driver_list_queued_owners(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) { struct kdbus_cmd_name_list cmd = {}; struct kdbus_name_list *name_list; struct kdbus_cmd_name *name; _cleanup_strv_free_ char **owners = NULL; char *arg0; int r; r = sd_bus_message_read(m, "s", &arg0); if (r < 0) return r; assert_return(service_name_is_valid(arg0), -EINVAL); cmd.flags = KDBUS_NAME_LIST_QUEUED; r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd); if (r < 0) return -errno; name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset); KDBUS_ITEM_FOREACH(name, name_list, names) { char *n; if (name->size <= sizeof(*name)) continue; if (!streq(name->name, arg0)) continue; if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) return -ENOMEM; r = strv_push(&owners, n); if (r < 0) { free(n); return -ENOMEM; } }
static int parse_argv(int argc, char *argv[]) { enum { ARG_NO_PAGER = 0x100, ARG_VERSION, ARG_USER_UNIT, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "all", no_argument, NULL, 'a' }, { "full", no_argument, NULL, 'l' }, { "machine", required_argument, NULL, 'M' }, { "unit", optional_argument, NULL, 'u' }, { "user-unit", optional_argument, NULL, ARG_USER_UNIT }, {} }; int c; assert(argc >= 1); assert(argv); while ((c = getopt_long(argc, argv, "-hkalM:u::", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_NO_PAGER: arg_no_pager = true; break; case 'a': arg_all = true; break; case 'u': arg_show_unit = SHOW_UNIT_SYSTEM; if (strv_push(&arg_names, optarg) < 0) /* push optarg if not empty */ return log_oom(); break; case ARG_USER_UNIT: arg_show_unit = SHOW_UNIT_USER; if (strv_push(&arg_names, optarg) < 0) /* push optarg if not empty */ return log_oom(); break; case 1: /* positional argument */ if (strv_push(&arg_names, optarg) < 0) return log_oom(); break; case 'l': arg_full = true; break; case 'k': arg_kernel_threads = true; break; case 'M': arg_machine = optarg; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } if (arg_machine && arg_show_unit != SHOW_UNIT_NONE) { log_error("Cannot combine --unit or --user-unit with --machine=."); return -EINVAL; } return 1; }