summaryrefslogtreecommitdiff
path: root/src/tmpfiles
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-03-23 18:55:36 +0700
committerLennart Poettering <lennart@poettering.net>2015-03-26 11:56:22 +0100
commit4034a06ddb82ec9868cd52496fef2f5faa25575f (patch)
treea832cd56abb7830985f3e7e9dff7451b96478c24 /src/tmpfiles
parentbe3ce3014eacd66fa292fc9e4e6b3d3b0ef7de23 (diff)
util: rework word parsing and c unescaping code
When parsing words from input files, optionally automatically unescape the passed strings, controllable via a new flags parameter. Make use of this in tmpfiles, and port everything else over, too. This improves parsing quite a bit, since we no longer have to process the same string multiple times with different calls, where an earlier call might corrupt the input for a later call.
Diffstat (limited to 'src/tmpfiles')
-rw-r--r--src/tmpfiles/tmpfiles.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index c4c6d8e693..494fd1ac21 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -620,7 +620,6 @@ static int path_set_perms(Item *i, const char *path) {
}
static int get_xattrs_from_arg(Item *i) {
- char *xattr;
const char *p;
int r;
@@ -629,35 +628,33 @@ static int get_xattrs_from_arg(Item *i) {
p = i->argument;
- while ((r = unquote_first_word(&p, &xattr, false)) > 0) {
- _cleanup_free_ char *tmp = NULL, *name = NULL,
- *value = NULL, *value2 = NULL, *_xattr = xattr;
+ for (;;) {
+ _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL;
+
+ r = unquote_first_word(&p, &xattr, UNQUOTE_CUNESCAPE);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse extended attribute, ignoring: %s", p);
+ if (r <= 0)
+ break;
r = split_pair(xattr, "=", &name, &value);
if (r < 0) {
- log_warning("Illegal xattr found: \"%s\" - ignoring.", xattr);
+ log_warning_errno(r, "Failed to parse extended attribute, ignoring: %s", xattr);
continue;
}
- if (strempty(name) || strempty(value)) {
- log_warning("Malformed xattr found: \"%s\" - ignoring.", xattr);
+ if (isempty(name) || isempty(value)) {
+ log_warning("Malformed xattr found, ignoring: %s", xattr);
continue;
}
- tmp = unquote(value, "\"");
- if (!tmp)
- return log_oom();
-
- value2 = cunescape(tmp);
- if (!value2)
+ if (strv_push_pair(&i->xattrs, name, value) < 0)
return log_oom();
- if (strv_push_pair(&i->xattrs, name, value2) < 0)
- return log_oom();
- name = value2 = NULL;
+ name = value = NULL;
}
- return r;
+ return 0;
}
static int path_set_xattrs(Item *i, const char *path) {
@@ -690,8 +687,7 @@ static int get_acls_from_arg(Item *item) {
* afterwards, so the mask can be added now if necessary. */
r = parse_acl(item->argument, &item->acl_access, &item->acl_default, !item->force);
if (r < 0)
- log_warning_errno(r, "Failed to parse ACL \"%s\": %m. Ignoring",
- item->argument);
+ log_warning_errno(r, "Failed to parse ACL \"%s\": %m. Ignoring", item->argument);
#else
log_warning_errno(ENOSYS, "ACLs are not supported. Ignoring");
#endif
@@ -918,8 +914,7 @@ static int write_one_file(Item *i, const char *path) {
if (i->argument) {
_cleanup_free_ char *unescaped;
- log_debug("%s to \"%s\".",
- i->type == CREATE_FILE ? "Appending" : "Writing", path);
+ log_debug("%s to \"%s\".", i->type == CREATE_FILE ? "Appending" : "Writing", path);
unescaped = cunescape(i->argument);
if (!unescaped)
@@ -1651,15 +1646,16 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
assert(line >= 1);
assert(buffer);
- r = unquote_many_words(&buffer,
- &action,
- &path,
- &mode,
- &user,
- &group,
- &age,
- &i.argument,
- NULL);
+ r = unquote_many_words(
+ &buffer,
+ 0,
+ &action,
+ &path,
+ &mode,
+ &user,
+ &group,
+ &age,
+ NULL);
if (r < 0)
return log_error_errno(r, "[%s:%u] Failed to parse line: %m", fname, line);
else if (r < 2) {
@@ -1667,6 +1663,12 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
return -EIO;
}
+ if (!isempty(buffer)) {
+ i.argument = strdup(buffer);
+ if (!i.argument)
+ return log_oom();
+ }
+
if (isempty(action)) {
log_error("[%s:%u] Command too short '%s'.", fname, line, action);
return -EINVAL;