Example #1
0
int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) {
        char **m = NULL;
        int r;

        if (!newline)
                newline = NEWLINE;

        r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL);
        if (r < 0) {
                strv_free(m);
                return r;
        }

        *rl = m;
        return 0;
}
Example #2
0
static int locale_write_data(Context *c, char ***settings) {
        int r, p;
        _cleanup_strv_free_ char **l = NULL;

        /* Set values will be returned as strv in *settings on success. */

        r = load_env_file(NULL, "/etc/locale.conf", NULL, &l);
        if (r < 0 && r != -ENOENT)
                return r;

        for (p = 0; p < _LOCALE_MAX; p++) {
                _cleanup_free_ char *t = NULL;
                char **u;

                assert(names[p]);

                if (isempty(c->locale[p])) {
                        l = strv_env_unset(l, names[p]);
                        continue;
                }

                if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0)
                        return -ENOMEM;

                u = strv_env_set(l, t);
                if (!u)
                        return -ENOMEM;

                strv_free(l);
                l = u;
        }

        if (strv_isempty(l)) {
                if (unlink("/etc/locale.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        r = write_env_file_label("/etc/locale.conf", l);
        if (r < 0)
                return r;

        *settings = l;
        l = NULL;
        return 0;
}
Example #3
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;
        }
}
Example #4
0
int main(int argc, char *argv[]) {
        int r = 0;

        if (argc > 2) {
                log_error("This program expects one or no arguments.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        if (argc > 1) {
                r = apply_file(argv[1], false);
        } else {
                char **files, **f;

                /* Flush out all rules */
                write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1");

                r = conf_files_list(&files, ".conf",
                                    "/run/binfmt.d",
                                    "/etc/binfmt.d",
                                    "/usr/local/lib/binfmt.d",
                                    "/usr/lib/binfmt.d",
                                    NULL);

                if (r < 0) {
                        log_error("Failed to enumerate binfmt.d files: %s", strerror(-r));
                        goto finish;
                }

                STRV_FOREACH(f, files) {
                        int k;

                        k = apply_file(*f, true);
                        if (k < 0 && r == 0)
                                r = k;
                }

                strv_free(files);
        }
Example #5
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;
}
Example #6
0
static int uid_get_array(uid_t uid, const char *variable, char ***array) {
        _cleanup_free_ char *p = NULL, *s = NULL;
        char **a;
        int r;

        r = file_of_uid(uid, &p);
        if (r < 0)
                return r;

        r = parse_env_file(p, NEWLINE,
                           variable, &s,
                           NULL);
        if (r < 0) {
                if (r == -ENOENT) {
                        if (array)
                                *array = NULL;
                        return 0;
                }

                return r;
        }

        if (!s) {
                if (array)
                        *array = NULL;
                return 0;
        }

        a = strv_split(s, " ");

        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        if (array)
                *array = a;
        else
                strv_free(a);

        return r;
}
Example #7
0
static int uid_get_array(uid_t uid, const char *variable, char ***array) {
        _cleanup_free_ char *p = NULL, *s = NULL;
        char **a;
        int r;

        if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
                return -ENOMEM;

        r = parse_env_file(p, NEWLINE,
                           variable, &s,
                           NULL);
        if (r < 0) {
                if (r == -ENOENT) {
                        if (array)
                                *array = NULL;
                        return 0;
                }

                return r;
        }

        if (!s) {
                if (array)
                        *array = NULL;
                return 0;
        }

        a = strv_split(s, " ");

        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        if (array)
                *array = a;
        else
                strv_free(a);

        return r;
}
Example #8
0
int path_split_and_make_absolute(const char *p, char ***ret) {
        char **l;
        int r;

        assert(p);
        assert(ret);

        l = strv_split(p, ":");
        if (!l)
                return -ENOMEM;

        r = path_strv_make_absolute_cwd(l);
        if (r < 0) {
                strv_free(l);
                return r;
        }

        *ret = l;
        return r;
}
Example #9
0
void manager_etc_hosts_flush(Manager *m) {
        EtcHostsItem *item;
        EtcHostsItemByName *bn;

        while ((item = set_steal_first(m->etc_hosts_by_address))) {
                strv_free(item->names);
                free(item);
        }

        while ((bn = hashmap_steal_first(m->etc_hosts_by_name))) {
                free(bn->name);
                free(bn->items);
                free(bn);
        }

        m->etc_hosts_by_address = set_free(m->etc_hosts_by_address);
        m->etc_hosts_by_name = hashmap_free(m->etc_hosts_by_name);

        m->etc_hosts_mtime = USEC_INFINITY;
}
_public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {

        if (!c)
                return NULL;

        if (c->allocated) {
                assert(c->n_ref > 0);
                c->n_ref--;

                if (c->n_ref == 0) {
                        free(c->comm);
                        free(c->tid_comm);
                        free(c->exe);
                        free(c->cmdline);
                        free(c->cgroup);
                        free(c->capability);
                        free(c->label);
                        free(c->unique_name);
                        free(c->cgroup_root);
                        free(c->description);

                        free(c->supplementary_gids);
                        c->supplementary_gids = NULL;

                        strv_free(c->well_known_names);
                        c->well_known_names = NULL;

                        bus_creds_done(c);

                        free(c);
                }
        } else {
                sd_bus_message *m;

                m = container_of(c, sd_bus_message, creds);
                sd_bus_message_unref(m);
        }


        return NULL;
}
Example #11
0
void bus_creds_done(sd_bus_creds *c) {
        assert(c);

        /* For internal bus cred structures that are allocated by
         * something else */

        free(c->session);
        free(c->unit);
        free(c->user_unit);
        free(c->slice);
        free(c->unescaped_description);

        free(c->well_known_names); /* note that this is an strv, but
                                    * we only free the array, not the
                                    * strings the array points to. The
                                    * full strv we only free if
                                    * c->allocated is set, see
                                    * below. */

        strv_free(c->cmdline_array);
}
Example #12
0
static int read_next_mapping(FILE *f, unsigned *n, char ***a) {
        assert(f);
        assert(n);
        assert(a);

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

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

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

                        return 0;
                }

                (*n) ++;

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

                r = strv_split_quoted(&b, l, false);
                if (r < 0)
                        return r;

                if (strv_length(b) < 5) {
                        log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n);
                        strv_free(b);
                        continue;

                }

                *a = b;
                return 1;
        }
}
Example #13
0
static void test_hashmap_get_strv(void) {
        Hashmap *m;
        char **strv;
        char *val1, *val2, *val3, *val4;

        log_info("%s", __func__);

        val1 = strdup("val1");
        assert_se(val1);
        val2 = strdup("val2");
        assert_se(val2);
        val3 = strdup("val3");
        assert_se(val3);
        val4 = strdup("val4");
        assert_se(val4);

        m = hashmap_new(&string_hash_ops);

        hashmap_put(m, "key 1", val1);
        hashmap_put(m, "key 2", val2);
        hashmap_put(m, "key 3", val3);
        hashmap_put(m, "key 4", val4);

        strv = hashmap_get_strv(m);

#ifndef ORDERED
        strv = strv_sort(strv);
#endif

        assert_se(streq(strv[0], "val1"));
        assert_se(streq(strv[1], "val2"));
        assert_se(streq(strv[2], "val3"));
        assert_se(streq(strv[3], "val4"));

        strv_free(strv);

        hashmap_free(m);
}
Example #14
0
int main(int argc, char *argv[]) {
        int r;
        usec_t timeout;

        log_parse_environment();
        log_open();

        if ((r = parse_argv(argc, argv)) <= 0)
                goto finish;

        if (arg_timeout > 0)
                timeout = now(CLOCK_MONOTONIC) + arg_timeout;
        else
                timeout = 0;

        if (arg_use_tty && isatty(STDIN_FILENO)) {
                char *password = NULL;

                if ((r = ask_password_tty(arg_message, timeout, NULL, &password)) >= 0) {
                        puts(password);
                        free(password);
                }

        } else {
                char **l;

                if ((r = ask_password_agent(arg_message, arg_icon, timeout, arg_accept_cached, &l)) >= 0) {
                        char **p;

                        STRV_FOREACH(p, l) {
                                puts(*p);

                                if (!arg_multiple)
                                        break;
                        }

                        strv_free(l);
                }
Example #15
0
DkrPull* dkr_pull_unref(DkrPull *i) {
        if (!i)
                return NULL;

        if (i->tar_pid > 1) {
                (void) kill_and_sigcont(i->tar_pid, SIGKILL);
                (void) wait_for_terminate(i->tar_pid, NULL);
        }

        pull_job_unref(i->images_job);
        pull_job_unref(i->tags_job);
        pull_job_unref(i->ancestry_job);
        pull_job_unref(i->json_job);
        pull_job_unref(i->layer_job);

        curl_glue_unref(i->glue);
        sd_event_unref(i->event);

        if (i->temp_path) {
                (void) rm_rf(i->temp_path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
                free(i->temp_path);
        }

        free(i->name);
        free(i->reference);
        free(i->id);
        free(i->response_token);
        free(i->response_registries);
        strv_free(i->ancestry);
        free(i->final_path);
        free(i->index_url);
        free(i->image_root);
        free(i->local);
        free(i);

        return NULL;
}
Example #16
0
Settings* settings_free(Settings *s) {

        if (!s)
                return NULL;

        strv_free(s->parameters);
        strv_free(s->environment);
        free(s->user);
        free(s->pivot_root_new);
        free(s->pivot_root_old);
        free(s->working_directory);

        strv_free(s->network_interfaces);
        strv_free(s->network_macvlan);
        strv_free(s->network_ipvlan);
        strv_free(s->network_veth_extra);
        free(s->network_bridge);
        free(s->network_zone);
        expose_port_free_all(s->expose_ports);

        custom_mount_free_all(s->custom_mounts, s->n_custom_mounts);
        return mfree(s);
}
Example #17
0
static int read_data_x11(void) {
        FILE *f;
        char line[LINE_MAX];
        bool in_section = false;

        free_data_x11();

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

#ifdef TARGET_FEDORA
                        f = fopen("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf", "re");
                        if (!f) {
                                if (errno == ENOENT)
                                        return 0;
                                else
                                        return -errno;
                        }
#else
                        return 0;
#endif

                } else
                          return -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")) {
                        char **a;

                        a = strv_split_quoted(l);
                        if (!a) {
                                fclose(f);
                                return -ENOMEM;
                        }

                        if (strv_length(a) == 3) {

                                if (streq(a[1], "XkbLayout")) {
                                        free(state.x11_layout);
                                        state.x11_layout = a[2];
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbModel")) {
                                        free(state.x11_model);
                                        state.x11_model = a[2];
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbVariant")) {
                                        free(state.x11_variant);
                                        state.x11_variant = a[2];
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbOptions")) {
                                        free(state.x11_options);
                                        state.x11_options = a[2];
                                        a[2] = NULL;
                                }
                        }

                        strv_free(a);

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

                        a = strv_split_quoted(l);
                        if (!a) {
                                fclose(f);
                                return -ENOMEM;
                        }

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

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

        fclose(f);

        return 0;
}
Example #18
0
static int x11_read_data(Context *c) {
        FILE *f;
        char line[LINE_MAX];
        bool in_section = false;

        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")) {
                        char **a;

                        a = strv_split_quoted(l);
                        if (!a) {
                                fclose(f);
                                return -ENOMEM;
                        }

                        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;
                                }
                        }

                        strv_free(a);

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

                        a = strv_split_quoted(l);
                        if (!a) {
                                fclose(f);
                                return -ENOMEM;
                        }

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

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

        fclose(f);

        return 0;
}
Example #19
0
int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {

        _cleanup_strv_free_ char
                **suspend_mode = NULL, **suspend_state = NULL,
                **hibernate_mode = NULL, **hibernate_state = NULL,
                **hybrid_mode = NULL, **hybrid_state = NULL;
        char **modes, **states;

        const ConfigTableItem items[] = {
                { "Sleep",   "SuspendMode",      config_parse_strv,  0, &suspend_mode  },
                { "Sleep",   "SuspendState",     config_parse_strv,  0, &suspend_state },
                { "Sleep",   "HibernateMode",    config_parse_strv,  0, &hibernate_mode  },
                { "Sleep",   "HibernateState",   config_parse_strv,  0, &hibernate_state },
                { "Sleep",   "HybridSleepMode",  config_parse_strv,  0, &hybrid_mode  },
                { "Sleep",   "HybridSleepState", config_parse_strv,  0, &hybrid_state },
                {}
        };

        int r;
        _cleanup_fclose_ FILE *f;

        f = fopen(PKGSYSCONFDIR "/sleep.conf", "re");
        if (!f)
                log_full(errno == ENOENT ? LOG_DEBUG: LOG_WARNING,
                         "Failed to open configuration file " PKGSYSCONFDIR "/sleep.conf: %m");
        else {
                r = config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", f, "Sleep\0",
                                 config_item_table_lookup, (void*) items, false, false, NULL);
                if (r < 0)
                        log_warning("Failed to parse configuration file: %s", strerror(-r));
        }

        if (streq(verb, "suspend")) {
                /* empty by default */
                USE(modes, suspend_mode);

                if (suspend_state)
                        USE(states, suspend_state);
                else
                        states = strv_new("mem", "standby", "freeze", NULL);

        } else if (streq(verb, "hibernate")) {
                if (hibernate_mode)
                        USE(modes, hibernate_mode);
                else
                        modes = strv_new("platform", "shutdown", NULL);

                if (hibernate_state)
                        USE(states, hibernate_state);
                else
                        states = strv_new("disk", NULL);

        } else if (streq(verb, "hybrid-sleep")) {
                if (hybrid_mode)
                        USE(modes, hybrid_mode);
                else
                        modes = strv_new("suspend", "platform", "shutdown", NULL);

                if (hybrid_state)
                        USE(states, hybrid_state);
                else
                        states = strv_new("disk", NULL);

        } else
                assert_not_reached("what verb");

        if ((!modes && !streq(verb, "suspend")) || !states) {
                strv_free(modes);
                strv_free(states);
                return log_oom();
        }

        *_modes = modes;
        *_states = states;
        return 0;
}
Example #20
0
static void manager_free(Manager *m) {
        Session *session;
        User *u;
        Device *d;
        Seat *s;
        Inhibitor *i;
        Button *b;

        assert(m);

        while ((session = hashmap_first(m->sessions)))
                session_free(session);

        while ((u = hashmap_first(m->users)))
                user_free(u);

        while ((d = hashmap_first(m->devices)))
                device_free(d);

        while ((s = hashmap_first(m->seats)))
                seat_free(s);

        while ((i = hashmap_first(m->inhibitors)))
                inhibitor_free(i);

        while ((b = hashmap_first(m->buttons)))
                button_free(b);

        hashmap_free(m->devices);
        hashmap_free(m->seats);
        hashmap_free(m->sessions);
        hashmap_free(m->users);
        hashmap_free(m->inhibitors);
        hashmap_free(m->buttons);

        hashmap_free(m->user_units);
        hashmap_free(m->session_units);

        sd_event_source_unref(m->idle_action_event_source);
        sd_event_source_unref(m->inhibit_timeout_source);
        sd_event_source_unref(m->scheduled_shutdown_timeout_source);
        sd_event_source_unref(m->nologin_timeout_source);
        sd_event_source_unref(m->wall_message_timeout_source);

        sd_event_source_unref(m->console_active_event_source);
        sd_event_source_unref(m->udev_seat_event_source);
        sd_event_source_unref(m->udev_device_event_source);
        sd_event_source_unref(m->udev_vcsa_event_source);
        sd_event_source_unref(m->udev_button_event_source);
        sd_event_source_unref(m->lid_switch_ignore_event_source);

        safe_close(m->console_active_fd);

        udev_monitor_unref(m->udev_seat_monitor);
        udev_monitor_unref(m->udev_device_monitor);
        udev_monitor_unref(m->udev_vcsa_monitor);
        udev_monitor_unref(m->udev_button_monitor);

        udev_unref(m->udev);

        if (m->unlink_nologin)
                (void) unlink("/run/nologin");

        bus_verify_polkit_async_registry_free(m->polkit_registry);

        sd_bus_unref(m->bus);
        sd_event_unref(m->event);

        safe_close(m->reserve_vt_fd);

        strv_free(m->kill_only_users);
        strv_free(m->kill_exclude_users);

        free(m->scheduled_shutdown_type);
        free(m->scheduled_shutdown_tty);
        free(m->wall_message);
        free(m->action_job);
        free(m);
}
Example #21
0
static int show_status(DBusConnection *bus, char **args, unsigned n) {
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
        const char *interface = "";
        int r;
        DBusMessageIter iter, sub, sub2, sub3;
        StatusInfo info;

        assert(args);

        r = bus_method_call_with_reply(
                        bus,
                        "org.freedesktop.locale1",
                        "/org/freedesktop/locale1",
                        "org.freedesktop.DBus.Properties",
                        "GetAll",
                        &reply,
                        NULL,
                        DBUS_TYPE_STRING, &interface,
                        DBUS_TYPE_INVALID);
        if (r < 0)
                return r;

        if (!dbus_message_iter_init(reply, &iter) ||
            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY)  {
                log_error("Failed to parse reply.");
                return -EIO;
        }

        zero(info);
        dbus_message_iter_recurse(&iter, &sub);

        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
                const char *name;

                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
                        log_error("Failed to parse reply.");
                        return -EIO;
                }

                dbus_message_iter_recurse(&sub, &sub2);

                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
                        log_error("Failed to parse reply.");
                        return -EIO;
                }

                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT)  {
                        log_error("Failed to parse reply.");
                        return -EIO;
                }

                dbus_message_iter_recurse(&sub2, &sub3);

                r = status_property(name, &sub3, &info);
                if (r < 0) {
                        log_error("Failed to parse reply.");
                        return r;
                }

                dbus_message_iter_next(&sub);
        }

        print_status_info(&info);
        strv_free(info.locale);
        return 0;
}
Example #22
0
static int convert_x11_to_vconsole(DBusConnection *connection) {
        bool modified = false;

        assert(connection);

        if (isempty(state.x11_layout)) {

                modified =
                        !isempty(state.vc_keymap) ||
                        !isempty(state.vc_keymap_toggle);

                free_data_x11();
        } else {
                FILE *f;
                unsigned n = 0;
                unsigned best_matching = 0;
                char *new_keymap = NULL;

                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
                if (!f)
                        return -errno;

                for (;;) {
                        char **a;
                        unsigned matching = 0;
                        int r;

                        r = read_next_mapping(f, &n, &a);
                        if (r < 0) {
                                fclose(f);
                                return r;
                        }

                        if (r == 0)
                                break;

                        /* Determine how well matching this entry is */
                        if (streq_ptr(state.x11_layout, a[1]))
                                /* If we got an exact match, this is best */
                                matching = 10;
                        else {
                                size_t x;

                                x = strcspn(state.x11_layout, ",");

                                /* We have multiple X layouts, look
                                 * for an entry that matches our key
                                 * with the everything but the first
                                 * layout stripped off. */
                                if (x > 0 &&
                                    strlen(a[1]) == x &&
                                    strncmp(state.x11_layout, a[1], x) == 0)
                                        matching = 5;
                                else  {
                                        size_t w;

                                        /* If that didn't work, strip
                                         * off the other layouts from
                                         * the entry, too */

                                        w = strcspn(a[1], ",");

                                        if (x > 0 && x == w &&
                                            memcmp(state.x11_layout, a[1], x) == 0)
                                                matching = 1;
                                }
                        }

                        if (matching > 0 &&
                            streq_ptr(state.x11_model, a[2])) {
                                matching++;

                                if (streq_ptr(state.x11_variant, a[3])) {
                                        matching++;

                                        if (streq_ptr(state.x11_options, a[4]))
                                                matching++;
                                }
                        }

                        /* The best matching entry so far, then let's
                         * save that */
                        if (matching > best_matching) {
                                best_matching = matching;

                                free(new_keymap);
                                new_keymap = strdup(a[0]);

                                if (!new_keymap) {
                                        strv_free(a);
                                        fclose(f);
                                        return -ENOMEM;
                                }
                        }

                        strv_free(a);
                }

                fclose(f);

                if (!streq_ptr(state.vc_keymap, new_keymap)) {
                        free(state.vc_keymap);
                        state.vc_keymap = new_keymap;

                        free(state.vc_keymap_toggle);
                        state.vc_keymap_toggle = NULL;

                        modified = true;
                } else
                        free(new_keymap);
        }

        if (modified) {
                dbus_bool_t b;
                DBusMessage *changed;
                int r;

                r = write_data_vconsole();
                if (r < 0)
                        log_error("Failed to set virtual console keymap: %s", strerror(-r));

                changed = bus_properties_changed_new(
                                "/org/freedesktop/locale1",
                                "org.freedesktop.locale1",
                                "VConsoleKeymap\0"
                                "VConsoleKeymapToggle\0");

                if (!changed)
                        return -ENOMEM;

                b = dbus_connection_send(connection, changed, NULL);
                dbus_message_unref(changed);

                if (!b)
                        return -ENOMEM;

                return load_vconsole_keymap(connection, NULL);
        }

        return 0;
}
Example #23
0
static int convert_vconsole_to_x11(DBusConnection *connection) {
        bool modified = false;

        assert(connection);

        if (isempty(state.vc_keymap)) {

                modified =
                        !isempty(state.x11_layout) ||
                        !isempty(state.x11_model) ||
                        !isempty(state.x11_variant) ||
                        !isempty(state.x11_options);

                free_data_x11();
        } else {
                FILE *f;
                unsigned n = 0;

                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
                if (!f)
                        return -errno;

                for (;;) {
                        char **a;
                        int r;

                        r = read_next_mapping(f, &n, &a);
                        if (r < 0) {
                                fclose(f);
                                return r;
                        }

                        if (r == 0)
                                break;

                        if (!streq(state.vc_keymap, a[0])) {
                                strv_free(a);
                                continue;
                        }

                        if (!streq_ptr(state.x11_layout, strnulldash(a[1])) ||
                            !streq_ptr(state.x11_model, strnulldash(a[2])) ||
                            !streq_ptr(state.x11_variant, strnulldash(a[3])) ||
                            !streq_ptr(state.x11_options, strnulldash(a[4]))) {

                                if (free_and_set(&state.x11_layout, strnulldash(a[1])) < 0 ||
                                    free_and_set(&state.x11_model, strnulldash(a[2])) < 0 ||
                                    free_and_set(&state.x11_variant, strnulldash(a[3])) < 0 ||
                                    free_and_set(&state.x11_options, strnulldash(a[4])) < 0) {
                                        strv_free(a);
                                        fclose(f);
                                        return -ENOMEM;
                                }

                                modified = true;
                        }

                        strv_free(a);
                        break;
                }

                fclose(f);
        }

        if (modified) {
                dbus_bool_t b;
                DBusMessage *changed;
                int r;

                r = write_data_x11();
                if (r < 0)
                        log_error("Failed to set X11 keyboard layout: %s", strerror(-r));

                changed = bus_properties_changed_new(
                                "/org/freedesktop/locale1",
                                "org.freedesktop.locale1",
                                "X11Layout\0"
                                "X11Model\0"
                                "X11Variant\0"
                                "X11Options\0");

                if (!changed)
                        return -ENOMEM;

                b = dbus_connection_send(connection, changed, NULL);
                dbus_message_unref(changed);

                if (!b)
                        return -ENOMEM;
        }

        return 0;
}
Example #24
0
static void test_strv_split_empty(void) {
        _cleanup_strv_free_ char **l = NULL;

        l = strv_split("", WHITESPACE);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("", NULL);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", NULL, 0);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", WHITESPACE, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", WHITESPACE, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("    ", WHITESPACE);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("    ", NULL);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, 0);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", WHITESPACE, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_isempty(l));
}
Example #25
0
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
        static const struct option options[] = {
                { "update", no_argument, NULL, 'u' },
                { "root", required_argument, NULL, 'r' },
                { "test", required_argument, NULL, 't' },
                { "help", no_argument, NULL, 'h' },
                {}
        };
        const char *test = NULL;
        const char *root = "";
        char *udev_hwdb_path = UDEV_HWDB_BIN;
        bool update = false;
        struct trie *trie = NULL;
        int err;
        int rc = EXIT_SUCCESS;

        for (;;) {
                int option;

                option = getopt_long(argc, argv, "ut:r:h", options, NULL);
                if (option == -1)
                        break;

                switch (option) {
                case 'u':
                        update = true;
                        break;
                case 't':
                        test = optarg;
                        break;
                case 'r':
                        root = optarg;
                        break;
                case 'h':
                        help();
                        return EXIT_SUCCESS;
                }
        }

        if (!update && !test) {
                help();
                return EXIT_SUCCESS;
        }

        if (update) {
                char **files, **f;

                trie = calloc(sizeof(struct trie), 1);
                if (!trie) {
                        rc = EXIT_FAILURE;
                        goto out;
                }

                /* string store */
                trie->strings = strbuf_new();
                if (!trie->strings) {
                        rc = EXIT_FAILURE;
                        goto out;
                }

                /* index */
                trie->root = calloc(sizeof(struct trie_node), 1);
                if (!trie->root) {
                        rc = EXIT_FAILURE;
                        goto out;
                }
                trie->nodes_count++;

                err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs);
                if (err < 0) {
                        log_error("failed to enumerate hwdb files: %s\n", strerror(-err));
                        rc = EXIT_FAILURE;
                        goto out;
                }
                STRV_FOREACH(f, files) {
                        log_debug("reading file '%s'", *f);
                        import_file(udev, trie, *f);
                }
                strv_free(files);

                strbuf_complete(trie->strings);

                log_debug("=== trie in-memory ===\n");
                log_debug("nodes:            %8zu bytes (%8zu)\n",
                          trie->nodes_count * sizeof(struct trie_node), trie->nodes_count);
                log_debug("children arrays:  %8zu bytes (%8zu)\n",
                          trie->children_count * sizeof(struct trie_child_entry), trie->children_count);
                log_debug("values arrays:    %8zu bytes (%8zu)\n",
                          trie->values_count * sizeof(struct trie_value_entry), trie->values_count);
                log_debug("strings:          %8zu bytes\n",
                          trie->strings->len);
                log_debug("strings incoming: %8zu bytes (%8zu)\n",
                          trie->strings->in_len, trie->strings->in_count);
                log_debug("strings dedup'ed: %8zu bytes (%8zu)\n",
                          trie->strings->dedup_len, trie->strings->dedup_count);

                if (root) {
                    if (asprintf(&udev_hwdb_path,
                                 "%s/%s", root, udev_hwdb_path) < 0) {
                        rc = EXIT_FAILURE;
                        goto out;
                    }
                }

                mkdir_parents(udev_hwdb_path, 0755);
                err = trie_store(trie, udev_hwdb_path);

                if (root) {
                    free(udev_hwdb_path);
                }

                if (err < 0) {
                        log_error("Failure writing database %s: %s",
                            udev_hwdb_path, strerror(-err));
                        rc = EXIT_FAILURE;
                }
        }
Example #26
0
static DBusHandlerResult locale_message_handler(
                DBusConnection *connection,
                DBusMessage *message,
                void *userdata) {

        DBusMessage *reply = NULL, *changed = NULL;
        DBusError error;
        int r;

        assert(connection);
        assert(message);

        dbus_error_init(&error);

        if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetLocale")) {
                char **l = NULL, **i;
                dbus_bool_t interactive;
                DBusMessageIter iter;
                bool modified = false;
                bool passed[_PROP_MAX];
                int p;

                if (!dbus_message_iter_init(message, &iter))
                        return bus_send_error_reply(connection, message, NULL, -EINVAL);

                r = bus_parse_strv_iter(&iter, &l);
                if (r < 0) {
                        if (r == -ENOMEM)
                                goto oom;

                        return bus_send_error_reply(connection, message, NULL, r);
                }

                if (!dbus_message_iter_next(&iter) ||
                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)  {
                        strv_free(l);
                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
                }

                dbus_message_iter_get_basic(&iter, &interactive);

                zero(passed);

                /* Check whether a variable changed and if so valid */
                STRV_FOREACH(i, l) {
                        bool valid = false;

                        for (p = 0; p < _PROP_MAX; p++) {
                                size_t k;

                                k = strlen(names[p]);
                                if (startswith(*i, names[p]) && (*i)[k] == '=') {
                                        valid = true;
                                        passed[p] = true;

                                        if (!streq_ptr(*i + k + 1, data[p]))
                                                modified = true;

                                        break;
                                }
                        }

                        if (!valid) {
                                strv_free(l);
                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
                        }
                }
Example #27
0
static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
        char type;
        int r;

        r = sd_bus_message_peek_type(m, &type, NULL);
        if (r < 0)
                return r;

        switch (type) {
        case SD_BUS_TYPE_STRING: {
                const char *s;
                char *str;
                char **p = userdata;

                r = sd_bus_message_read_basic(m, type, &s);
                if (r < 0)
                        break;

                if (isempty(s))
                        break;

                str = strdup(s);
                if (!str) {
                        r = -ENOMEM;
                        break;
                }
                free(*p);
                *p = str;

                break;
        }

        case SD_BUS_TYPE_ARRAY: {
               _cleanup_strv_free_ char **l = NULL;
               char ***p = userdata;

                r = bus_message_read_strv_extend(m, &l);
                if (r < 0)
                        break;

                strv_free(*p);
                *p = l;
                l = NULL;

                break;
        }

        case SD_BUS_TYPE_BOOLEAN: {
                unsigned b;
                bool *p = userdata;

                r = sd_bus_message_read_basic(m, type, &b);
                if (r < 0)
                        break;

                *p = b;

                break;
        }

        case SD_BUS_TYPE_UINT32: {
                uint64_t u;
                uint32_t *p = userdata;

                r = sd_bus_message_read_basic(m, type, &u);
                if (r < 0)
                        break;

                *p = u;

                break;
        }

        case SD_BUS_TYPE_UINT64: {
                uint64_t t;
                uint64_t *p = userdata;

                r = sd_bus_message_read_basic(m, type, &t);
                if (r < 0)
                        break;

                *p = t;

                break;
        }

        default:
                break;
        }

        return r;
}
Example #28
0
static void push_data(DBusConnection *bus) {
        char **l_set = NULL, **l_unset = NULL, **t;
        int c_set = 0, c_unset = 0, p;
        DBusError error;
        DBusMessage *m = NULL, *reply = NULL;
        DBusMessageIter iter, sub;

        dbus_error_init(&error);

        assert(bus);

        l_set = new0(char*, _PROP_MAX);
        l_unset = new0(char*, _PROP_MAX);
        if (!l_set || !l_unset) {
                log_oom();
                goto finish;
        }

        for (p = 0; p < _PROP_MAX; p++) {
                assert(names[p]);

                if (isempty(data[p]))
                        l_unset[c_set++] = (char*) names[p];
                else {
                        char *s;

                        if (asprintf(&s, "%s=%s", names[p], data[p]) < 0) {
                                log_oom();
                                goto finish;
                        }

                        l_set[c_unset++] = s;
                }
        }

        assert(c_set + c_unset == _PROP_MAX);
        m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment");
        if (!m) {
                log_error("Could not allocate message.");
                goto finish;
        }

        dbus_message_iter_init_append(m, &iter);

        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) {
                log_oom();
                goto finish;
        }

        STRV_FOREACH(t, l_unset)
                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) {
                        log_oom();
                        goto finish;
                }

        if (!dbus_message_iter_close_container(&iter, &sub) ||
            !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) {
                log_oom();
                goto finish;
        }

        STRV_FOREACH(t, l_set)
                if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) {
                        log_oom();
                        goto finish;
                }

        if (!dbus_message_iter_close_container(&iter, &sub)) {
                log_oom();
                goto finish;
        }

        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
        if (!reply) {
                log_error("Failed to set locale information: %s", bus_error_message(&error));
                goto finish;
        }

finish:
        if (m)
                dbus_message_unref(m);

        if (reply)
                dbus_message_unref(reply);

        dbus_error_free(&error);

        strv_free(l_set);
        free(l_unset);
}
Example #29
0
int locale_setup(char ***environment) {
        char **add;
        char *variables[_VARIABLE_MAX] = {};
        int r = 0, i;

        if (detect_container(NULL) <= 0) {
                r = parse_env_file("/proc/cmdline", WHITESPACE,
                                   "locale.LANG",              &variables[VARIABLE_LANG],
                                   "locale.LANGUAGE",          &variables[VARIABLE_LANGUAGE],
                                   "locale.LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
                                   "locale.LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
                                   "locale.LC_TIME",           &variables[VARIABLE_LC_TIME],
                                   "locale.LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
                                   "locale.LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
                                   "locale.LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
                                   "locale.LC_PAPER",          &variables[VARIABLE_LC_PAPER],
                                   "locale.LC_NAME",           &variables[VARIABLE_LC_NAME],
                                   "locale.LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
                                   "locale.LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
                                   "locale.LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
                                   "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
                                   NULL);

                if (r < 0 && r != -ENOENT)
                        log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
        }

        /* Hmm, nothing set on the kernel cmd line? Then let's
         * try /etc/locale.conf */
        if (r <= 0) {
                r = parse_env_file("/etc/locale.conf", NEWLINE,
                                   "LANG",              &variables[VARIABLE_LANG],
                                   "LANGUAGE",          &variables[VARIABLE_LANGUAGE],
                                   "LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
                                   "LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
                                   "LC_TIME",           &variables[VARIABLE_LC_TIME],
                                   "LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
                                   "LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
                                   "LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
                                   "LC_PAPER",          &variables[VARIABLE_LC_PAPER],
                                   "LC_NAME",           &variables[VARIABLE_LC_NAME],
                                   "LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
                                   "LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
                                   "LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
                                   "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
                                   NULL);

                if (r < 0 && r != -ENOENT)
                        log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
        }

        if (r <= 0) {
                r = parse_env_file("/etc/default/locale", NEWLINE,
                                   "LANG",              &variables[VARIABLE_LANG],
                                   "LANGUAGE",          &variables[VARIABLE_LANGUAGE],
                                   "LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
                                   "LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
                                   "LC_TIME",           &variables[VARIABLE_LC_TIME],
                                   "LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
                                   "LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
                                   "LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
                                   "LC_PAPER",          &variables[VARIABLE_LC_PAPER],
                                   "LC_NAME",           &variables[VARIABLE_LC_NAME],
                                   "LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
                                   "LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
                                   "LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
                                   "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
                                   NULL);

                if (r < 0 && r != -ENOENT)
                        log_warning("Failed to read /etc/default/locale: %s", strerror(-r));
        }

        add = NULL;
        for (i = 0; i < _VARIABLE_MAX; i++) {
                char *s;

                if (!variables[i])
                        continue;

                s = strjoin(variable_names[i], "=", variables[i], NULL);
                if (!s) {
                        r = -ENOMEM;
                        goto finish;
                }

                if (strv_consume(&add, s) < 0) {
                        r = -ENOMEM;
                        goto finish;
                }
        }

        if (!strv_isempty(add)) {
                char **e;

                e = strv_env_merge(2, *environment, add);
                if (!e) {
                        r = -ENOMEM;
                        goto finish;
                }

                strv_free(*environment);
                *environment = e;
        }

        r = 0;

finish:
        strv_free(add);

        for (i = 0; i < _VARIABLE_MAX; i++)
                free(variables[i]);

        return r;
}
Example #30
0
static int write_data_vconsole(void) {
        int r;
        char **l = NULL;

        r = load_env_file("/etc/vconsole.conf", &l);
        if (r < 0 && r != -ENOENT)
                return r;

        if (isempty(state.vc_keymap))
                l = strv_env_unset(l, "KEYMAP");
        else {
                char *s, **u;

                s = strappend("KEYMAP=", state.vc_keymap);
                if (!s) {
                        strv_free(l);
                        return -ENOMEM;
                }

                u = strv_env_set(l, s);
                free(s);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (isempty(state.vc_keymap_toggle))
                l = strv_env_unset(l, "KEYMAP_TOGGLE");
        else  {
                char *s, **u;

                s = strappend("KEYMAP_TOGGLE=", state.vc_keymap_toggle);
                if (!s) {
                        strv_free(l);
                        return -ENOMEM;
                }

                u = strv_env_set(l, s);
                free(s);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (strv_isempty(l)) {
                strv_free(l);

                if (unlink("/etc/vconsole.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        r = write_env_file("/etc/vconsole.conf", l);
        strv_free(l);

        return r;
}