Beispiel #1
0
static int x11_read_data(Context *c) {
        _cleanup_fclose_ FILE *f;
        char line[LINE_MAX];
        bool in_section = false;
        int r;

        context_free_x11(c);

        f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
        if (!f)
                return errno == ENOENT ? 0 : -errno;

        while (fgets(line, sizeof(line), f)) {
                char *l;

                char_array_0(line);
                l = strstrip(line);

                if (l[0] == 0 || l[0] == '#')
                        continue;

                if (in_section && first_word(l, "Option")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                        if (r < 0)
                                return r;

                        if (strv_length(a) == 3) {
                                if (streq(a[1], "XkbLayout")) {
                                        free_and_replace(&c->x11_layout, a[2]);
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbModel")) {
                                        free_and_replace(&c->x11_model, a[2]);
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbVariant")) {
                                        free_and_replace(&c->x11_variant, a[2]);
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbOptions")) {
                                        free_and_replace(&c->x11_options, a[2]);
                                        a[2] = NULL;
                                }
                        }

                } else if (!in_section && first_word(l, "Section")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                        if (r < 0)
                                return -ENOMEM;

                        if (strv_length(a) == 2 && streq(a[1], "InputClass"))
                                in_section = true;

                } else if (in_section && first_word(l, "EndSection"))
                        in_section = false;
        }

        return 0;
}
Beispiel #2
0
static void test_invalid_unquote(const char *quoted) {
        char **s = NULL;
        int r;

        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
        assert_se(s == NULL);
        assert_se(r == -EINVAL);
}
Beispiel #3
0
static void test_strv_split_extract(void) {
        _cleanup_strv_free_ char **l = NULL;
        const char *str = ":foo\\:bar::waldo:";
        int r;

        r = strv_split_extract(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
        assert_se(r == (int) strv_length(l));
        assert_se(streq_ptr(l[0], ""));
        assert_se(streq_ptr(l[1], "foo:bar"));
        assert_se(streq_ptr(l[2], ""));
        assert_se(streq_ptr(l[3], "waldo"));
        assert_se(streq_ptr(l[4], ""));
        assert_se(streq_ptr(l[5], NULL));
}
Beispiel #4
0
static int read_next_mapping(const char* filename,
                             unsigned min_fields, unsigned max_fields,
                             FILE *f, unsigned *n, char ***a) {
        assert(f);
        assert(n);
        assert(a);

        for (;;) {
                char line[LINE_MAX];
                char *l, **b;
                int r;
                size_t length;

                errno = 0;
                if (!fgets(line, sizeof(line), f)) {

                        if (ferror(f))
                                return errno > 0 ? -errno : -EIO;

                        return 0;
                }

                (*n)++;

                l = strstrip(line);
                if (IN_SET(l[0], 0, '#'))
                        continue;

                r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
                if (r < 0)
                        return r;

                length = strv_length(b);
                if (length < min_fields || length > max_fields) {
                        log_error("Invalid line %s:%u, ignoring.", filename, *n);
                        strv_free(b);
                        continue;

                }

                *a = b;
                return 1;
        }
}
Beispiel #5
0
static void test_strv_unquote(const char *quoted, char **list) {
        _cleanup_strv_free_ char **s;
        _cleanup_free_ char *j;
        unsigned i = 0;
        char **t;
        int r;

        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
        assert_se(r == (int) strv_length(list));
        assert_se(s);
        j = strv_join(s, " | ");
        assert_se(j);
        puts(j);

        STRV_FOREACH(t, s)
                assert_se(streq(list[i++], *t));

        assert_se(list[i] == NULL);
}
Beispiel #6
0
static int read_next_mapping(const char* filename,
                             unsigned min_fields, unsigned max_fields,
                             FILE *f, unsigned *n, char ***a) {
        assert(f);
        assert(n);
        assert(a);

        for (;;) {
                _cleanup_free_ char *line = NULL;
                size_t length;
                char *l, **b;
                int r;

                r = read_line(f, LONG_LINE_MAX, &line);
                if (r < 0)
                        return r;
                if (r == 0)
                        break;

                (*n)++;

                l = strstrip(line);
                if (IN_SET(l[0], 0, '#'))
                        continue;

                r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
                if (r < 0)
                        return r;

                length = strv_length(b);
                if (length < min_fields || length > max_fields) {
                        log_error("Invalid line %s:%u, ignoring.", filename, *n);
                        strv_free(b);
                        continue;

                }

                *a = b;
                return 1;
        }

        return 0;
}
Beispiel #7
0
static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
        _cleanup_free_ char *p;
        _cleanup_strv_free_ char **s = NULL;
        char **t;
        int r;

        p = strv_join_quoted((char **)split);
        assert_se(p);
        printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
        assert_se(p);
        assert_se(streq(p, quoted));

        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
        assert_se(r == (int) strv_length(s));
        assert_se(s);
        STRV_FOREACH(t, s) {
                assert_se(*t);
                assert_se(streq(*t, *split));
                split++;
        }
Beispiel #8
0
int x11_read_data(Context *c, sd_bus_message *m) {
        _cleanup_fclose_ FILE *f = NULL;
        bool in_section = false;
        char line[LINE_MAX];
        struct stat st;
        usec_t t;
        int r;

        /* Do not try to re-read the file within single bus operation. */
        if (m) {
                if (m == c->x11_cache)
                        return 0;

                sd_bus_message_unref(c->x11_cache);
                c->x11_cache = sd_bus_message_ref(m);
        }

        if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) < 0) {
                if (errno != ENOENT)
                        return -errno;

                c->x11_mtime = USEC_INFINITY;
                context_free_x11(c);
                return 0;
        }

        /* If mtime is not changed, then we do not need to re-read */
        t = timespec_load(&st.st_mtim);
        if (c->x11_mtime != USEC_INFINITY && t == c->x11_mtime)
                return 0;

        c->x11_mtime = t;
        context_free_x11(c);

        f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
        if (!f)
                return -errno;

        while (fgets(line, sizeof(line), f)) {
                char *l;

                char_array_0(line);
                l = strstrip(line);

                if (IN_SET(l[0], 0, '#'))
                        continue;

                if (in_section && first_word(l, "Option")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                        if (r < 0)
                                return r;

                        if (strv_length(a) == 3) {
                                char **p = NULL;

                                if (streq(a[1], "XkbLayout"))
                                        p = &c->x11_layout;
                                else if (streq(a[1], "XkbModel"))
                                        p = &c->x11_model;
                                else if (streq(a[1], "XkbVariant"))
                                        p = &c->x11_variant;
                                else if (streq(a[1], "XkbOptions"))
                                        p = &c->x11_options;

                                if (p) {
                                        free_and_replace(*p, a[2]);
                                }
                        }

                } else if (!in_section && first_word(l, "Section")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                        if (r < 0)
                                return -ENOMEM;

                        if (strv_length(a) == 2 && streq(a[1], "InputClass"))
                                in_section = true;

                } else if (in_section && first_word(l, "EndSection"))
                        in_section = false;
        }

        return 0;
}