return readlinkat_malloc(AT_FDCWD, p, ret);
}
+int readlink_value(const char *p, char **ret) {
+ _cleanup_free_ char *link = NULL;
+ char *value;
+ int r;
+
+ r = readlink_malloc(p, &link);
+ if (r < 0)
+ return r;
+
+ value = basename(link);
+ if (!value)
+ return -ENOENT;
+
+ value = strdup(value);
+ if (!value)
+ return -ENOMEM;
+
+ *ret = value;
+
+ return 0;
+}
+
int readlink_and_make_absolute(const char *p, char **r) {
_cleanup_free_ char *target = NULL;
char *k;
if (k < 0)
return k;
- snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
+ sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
k = readlink_malloc(fn, &s);
if (k < 0) {
return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
}
+static int file_is_priv_sticky(const char *p) {
+ struct stat st;
+
+ assert(p);
+
+ if (lstat(p, &st) < 0)
+ return -errno;
+
+ return
+ (st.st_uid == 0 || st.st_uid == getuid()) &&
+ (st.st_mode & S_ISVTX);
+}
+
static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
int fd, r;
struct statfs s;
if (e) {
int r;
- r = strv_split_quoted(&m, e);
+ r = strv_split_quoted(&m, e, true);
if (r < 0) {
ret[k] = NULL;
strv_free(ret);
}
char *normalize_env_assignment(const char *s) {
- _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
- char *eq, *r;
+ _cleanup_free_ char *value = NULL;
+ const char *eq;
+ char *p, *name;
eq = strchr(s, '=');
if (!eq) {
- char *t;
+ char *r, *t;
r = strdup(s);
if (!r)
return NULL;
t = strstrip(r);
- if (t == r)
- return r;
+ if (t != r)
+ memmove(r, t, strlen(t) + 1);
- memmove(r, t, strlen(t) + 1);
return r;
}
- name = strndup(s, eq - s);
- if (!name)
- return NULL;
-
- p = strdup(eq + 1);
- if (!p)
- return NULL;
+ name = strndupa(s, eq - s);
+ p = strdupa(eq + 1);
value = unquote(strstrip(p), QUOTES);
if (!value)
return NULL;
- if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
- r = NULL;
-
- return r;
+ return strjoin(strstrip(name), "=", value, NULL);
}
int wait_for_terminate(pid_t pid, siginfo_t *status) {
return -ENOENT;
}
-int file_is_priv_sticky(const char *p) {
- struct stat st;
-
- assert(p);
-
- if (lstat(p, &st) < 0)
- return -errno;
-
- return
- (st.st_uid == 0 || st.st_uid == getuid()) &&
- (st.st_mode & S_ISVTX);
-}
-
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
int shall_restore_state(void) {
_cleanup_free_ char *line = NULL;
- const char *word, *state;
- size_t l;
+ const char *p;
int r;
r = proc_cmdline(&line);
return r;
r = 1;
- FOREACH_WORD_QUOTED(word, l, line, state) {
+ p = line;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
const char *e;
- char n[l+1];
int k;
- memcpy(n, word, l);
- n[l] = 0;
+ k = unquote_first_word(&p, &word, true);
+ if (k < 0)
+ return k;
+ if (k == 0)
+ break;
- e = startswith(n, "systemd.restore_state=");
+ e = startswith(word, "systemd.restore_state=");
if (!e)
continue;
int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
_cleanup_free_ char *line = NULL;
- const char *w, *state;
- size_t l;
+ const char *p;
int r;
assert(parse_item);
if (r < 0)
return r;
- FOREACH_WORD_QUOTED(w, l, line, state) {
- char word[l+1], *value;
+ p = line;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ char *value = NULL;
- memcpy(word, w, l);
- word[l] = 0;
+ r = unquote_first_word(&p, &word, true);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
/* Filter out arguments that are intended only for the
* initrd */
return !!S_ISDIR(st.st_mode);
}
-int unquote_first_word(const char **p, char **ret) {
+int unquote_first_word(const char **p, char **ret, bool relax) {
_cleanup_free_ char *s = NULL;
size_t allocated = 0, sz = 0;
break;
case VALUE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
break;
case SINGLE_QUOTE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
- else if (c == '\'')
+ } else if (c == '\'')
state = VALUE;
else if (c == '\\')
state = SINGLE_QUOTE_ESCAPE;
break;
case SINGLE_QUOTE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
break;
case DOUBLE_QUOTE_ESCAPE:
- if (c == 0)
+ if (c == 0) {
+ if (relax)
+ goto finish;
return -EINVAL;
+ }
if (!GREEDY_REALLOC(s, allocated, sz+2))
return -ENOMEM;
l = newa0(char*, n);
for (c = 0; c < n; c++) {
- r = unquote_first_word(p, &l[c]);
+ r = unquote_first_word(p, &l[c], false);
if (r < 0) {
int j;