int tar_pull_start(TarPull *i, const char *url, const char *local, bool force_local, ImportVerify verify) { int r; assert(i); if (!http_url_is_valid(url)) return -EINVAL; if (local && !machine_name_is_valid(local)) return -EINVAL; if (i->tar_job) return -EBUSY; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->verify = verify; r = pull_job_new(&i->tar_job, url, i->glue, i); if (r < 0) return r; i->tar_job->on_finished = tar_pull_job_on_finished; i->tar_job->on_open_disk = tar_pull_job_on_open_disk; i->tar_job->on_progress = tar_pull_job_on_progress; i->tar_job->calc_checksum = verify != IMPORT_VERIFY_NO; i->tar_job->grow_machine_directory = i->grow_machine_directory; r = pull_find_old_etags(url, i->image_root, DT_DIR, ".tar-", NULL, &i->tar_job->old_etags); if (r < 0) return r; r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, tar_pull_job_on_finished, i); if (r < 0) return r; r = pull_job_begin(i->tar_job); if (r < 0) return r; if (i->checksum_job) { i->checksum_job->on_progress = tar_pull_job_on_progress; r = pull_job_begin(i->checksum_job); if (r < 0) return r; } if (i->signature_job) { i->signature_job->on_progress = tar_pull_job_on_progress; r = pull_job_begin(i->signature_job); if (r < 0) return r; } return 0; }
int config_parse_dnssd_service_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { DnssdService *s = userdata; int r; assert(filename); assert(lvalue); assert(rvalue); assert(s); if (isempty(rvalue)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Service type can't be empty. Ignoring."); return -EINVAL; } if (!dnssd_srv_type_is_valid(rvalue)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Service type is invalid. Ignoring."); return -EINVAL; } r = free_and_strdup(&s->type, rvalue); if (r < 0) return log_oom(); return 0; }
int config_parse_hostname( const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { char **s = data; assert(rvalue); assert(s); if (!hostname_is_valid(rvalue, false)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue); return 0; } if (free_and_strdup(s, empty_to_null(rvalue)) < 0) return log_oom(); return 0; }
int config_parse_routing_policy_rule_device( const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { _cleanup_routing_policy_rule_free_ RoutingPolicyRule *n = NULL; Network *network = userdata; int r; assert(filename); assert(section); assert(lvalue); assert(rvalue); assert(data); r = routing_policy_rule_new_static(network, filename, section_line, &n); if (r < 0) return r; if (!ifname_valid(rvalue)) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse '%s' interface name, ignoring: %s", lvalue, rvalue); return 0; } if (streq(lvalue, "IncomingInterface")) { r = free_and_strdup(&n->iif, rvalue); if (r < 0) return log_oom(); } else { r = free_and_strdup(&n->oif, rvalue); if (r < 0) return log_oom(); } n = NULL; return 0; }
static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) { Context *c = userdata; const char *name; int interactive; int r; assert(m); assert(c); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; name = empty_to_null(name); if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); if (!isempty(name) && !hostname_is_valid(name, false)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name); r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = free_and_strdup(&c->data[PROP_STATIC_HOSTNAME], name); if (r < 0) return r; r = context_update_kernel_hostname(c); if (r < 0) { log_error_errno(r, "Failed to set host name: %m"); return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %m"); } r = context_write_data_static_hostname(c); if (r < 0) { log_error_errno(r, "Failed to write static host name: %m"); return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %m"); } log_info("Changed static host name to '%s'", strna(c->data[PROP_STATIC_HOSTNAME])); (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "StaticHostname", NULL); return sd_bus_reply_method_return(m, NULL); }
int raw_export_start(RawExport *e, const char *path, int fd, ImportCompressType compress) { _cleanup_close_ int sfd = -1, tfd = -1; int r; assert(e); assert(path); assert(fd >= 0); assert(compress < _IMPORT_COMPRESS_TYPE_MAX); assert(compress != IMPORT_COMPRESS_UNKNOWN); if (e->output_fd >= 0) return -EBUSY; r = fd_nonblock(fd, true); if (r < 0) return r; r = free_and_strdup(&e->path, path); if (r < 0) return r; sfd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY); if (sfd < 0) return -errno; if (fstat(sfd, &e->st) < 0) return -errno; r = stat_verify_regular(&e->st); if (r < 0) return r; /* Try to take a reflink snapshot of the file, if we can t make the export atomic */ tfd = reflink_snapshot(sfd, path); if (tfd >= 0) e->input_fd = TAKE_FD(tfd); else e->input_fd = TAKE_FD(sfd); r = import_compress_init(&e->compress, compress); if (r < 0) return r; r = sd_event_add_io(e->event, &e->output_event_source, fd, EPOLLOUT, raw_export_on_output, e); if (r == -EPERM) { r = sd_event_add_defer(e->event, &e->output_event_source, raw_export_on_defer, e); if (r < 0) return r; r = sd_event_source_set_enabled(e->output_event_source, SD_EVENT_ON); } if (r < 0) return r; e->output_fd = fd; return r; }
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { int r; if (proc_cmdline_key_streq(key, "systemd.verity")) { r = value ? parse_boolean(value) : 1; if (r < 0) log_warning("Failed to parse verity= kernel command line switch %s. Ignoring.", value); else arg_enabled = r; } else if (proc_cmdline_key_streq(key, "roothash")) { if (proc_cmdline_value_missing(key, value)) return 0; r = free_and_strdup(&arg_root_hash, value); if (r < 0) return log_oom(); } else if (proc_cmdline_key_streq(key, "systemd.verity_root_data")) { if (proc_cmdline_value_missing(key, value)) return 0; r = free_and_strdup(&arg_data_what, value); if (r < 0) return log_oom(); } else if (proc_cmdline_key_streq(key, "systemd.verity_root_hash")) { if (proc_cmdline_value_missing(key, value)) return 0; r = free_and_strdup(&arg_hash_what, value); if (r < 0) return log_oom(); } return 0; }
int get_proc_cmdline_key(const char *key, char **value) { _cleanup_free_ char *line = NULL, *ret = NULL; bool found = false; const char *p; int r; assert(key); r = proc_cmdline(&line); if (r < 0) return r; p = line; for (;;) { _cleanup_free_ char *word = NULL; const char *e; r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX); if (r < 0) return r; if (r == 0) break; /* Filter out arguments that are intended only for the * initrd */ if (!in_initrd() && startswith(word, "rd.")) continue; if (value) { e = startswith(word, key); if (!e) continue; r = free_and_strdup(&ret, e); if (r < 0) return r; found = true; } else { if (streq(word, key)) found = true; } } if (value) { *value = ret; ret = NULL; } return found; }
static void test_vconsole_convert_to_x11(void) { _cleanup_(context_free) Context c = {}; log_info("/*** %s ***/", __func__); log_info("/* test emptying first (:) */"); assert_se(free_and_strdup(&c.x11_layout, "foo") >= 0); assert_se(free_and_strdup(&c.x11_variant, "bar") >= 0); assert_se(vconsole_convert_to_x11(&c) == 1); assert_se(c.x11_layout == NULL); assert_se(c.x11_variant == NULL); log_info("/* test emptying second (:) */"); assert_se(vconsole_convert_to_x11(&c) == 0); assert_se(c.x11_layout == NULL); assert_se(c.x11_variant == NULL); log_info("/* test without variant, new mapping (es:) */"); assert_se(free_and_strdup(&c.vc_keymap, "es") >= 0); assert_se(vconsole_convert_to_x11(&c) == 1); assert_se(streq(c.x11_layout, "es")); assert_se(c.x11_variant == NULL); log_info("/* test with known variant, new mapping (es:dvorak) */"); assert_se(free_and_strdup(&c.vc_keymap, "es-dvorak") >= 0); assert_se(vconsole_convert_to_x11(&c) == 0); // FIXME assert_se(streq(c.x11_layout, "es")); assert_se(c.x11_variant == NULL); // FIXME: "dvorak" log_info("/* test with old mapping (fr:latin9) */"); assert_se(free_and_strdup(&c.vc_keymap, "fr-latin9") >= 0); assert_se(vconsole_convert_to_x11(&c) == 1); assert_se(streq(c.x11_layout, "fr")); assert_se(streq(c.x11_variant, "latin9")); log_info("/* test with a compound mapping (ru,us) */"); assert_se(free_and_strdup(&c.vc_keymap, "ru") >= 0); assert_se(vconsole_convert_to_x11(&c) == 1); assert_se(streq(c.x11_layout, "ru,us")); assert_se(c.x11_variant == NULL); log_info("/* test with a simple mapping (us) */"); assert_se(free_and_strdup(&c.vc_keymap, "us") >= 0); assert_se(vconsole_convert_to_x11(&c) == 1); assert_se(streq(c.x11_layout, "us")); assert_se(c.x11_variant == NULL); }
static int locale_read_data(Context *c) { int r; context_free_locale(c); r = parse_env_file("/etc/locale.conf", NEWLINE, "LANG", &c->locale[VARIABLE_LANG], "LANGUAGE", &c->locale[VARIABLE_LANGUAGE], "LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE], "LC_NUMERIC", &c->locale[VARIABLE_LC_NUMERIC], "LC_TIME", &c->locale[VARIABLE_LC_TIME], "LC_COLLATE", &c->locale[VARIABLE_LC_COLLATE], "LC_MONETARY", &c->locale[VARIABLE_LC_MONETARY], "LC_MESSAGES", &c->locale[VARIABLE_LC_MESSAGES], "LC_PAPER", &c->locale[VARIABLE_LC_PAPER], "LC_NAME", &c->locale[VARIABLE_LC_NAME], "LC_ADDRESS", &c->locale[VARIABLE_LC_ADDRESS], "LC_TELEPHONE", &c->locale[VARIABLE_LC_TELEPHONE], "LC_MEASUREMENT", &c->locale[VARIABLE_LC_MEASUREMENT], "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION], NULL); if (r == -ENOENT) { int p; /* Fill in what we got passed from systemd. */ for (p = 0; p < _VARIABLE_LC_MAX; p++) { const char *name; name = locale_variable_to_string(p); assert(name); r = free_and_strdup(&c->locale[p], empty_to_null(getenv(name))); if (r < 0) return r; } r = 0; } locale_simplify(c); return r; }
static int kbdctx_refresh_compose_table(kbdctx *kc, const char *lang) { kbdtbl *kt; idev_session *s; idev_device *d; Iterator i, j; int r; if (!lang) lang = "C"; if (streq_ptr(kc->locale_lang, lang)) return 0; r = free_and_strdup(&kc->locale_lang, lang); if (r < 0) return r; log_debug("idev-keyboard: new default compose table: [ %s ]", lang); r = kbdtbl_new_from_locale(&kt, kc, lang); if (r < 0) { /* TODO: We need to catch the case where no compose-file is * available. xkb doesn't tell us so far.. so we must not treat * it as a hard-failure but just continue. Preferably, we want * xkb to tell us exactly whether compilation failed or whether * there is no compose file available for this locale. */ log_debug_errno(r, "idev-keyboard: cannot load compose-table for '%s': %m", lang); r = 0; kt = NULL; } kbdtbl_unref(kc->kbdtbl); kc->kbdtbl = kt; HASHMAP_FOREACH(s, kc->context->session_map, i) HASHMAP_FOREACH(d, s->device_map, j) if (idev_is_keyboard(d)) keyboard_update_kbdtbl(keyboard_from_device(d)); return 0; }
static int specifier_instance(char specifier, void *data, void *userdata, char **ret) { const UnitFileInstallInfo *i = userdata; char *instance; int r; assert(i); r = unit_name_to_instance(i->name, &instance); if (r < 0) return r; if (isempty(instance)) { r = free_and_strdup(&instance, strempty(i->default_instance)); if (r < 0) return r; } *ret = instance; return 0; }
int raw_import_start(RawImport *i, int fd, const char *local, bool force_local, bool read_only) { int r; assert(i); assert(fd >= 0); assert(local); if (!machine_name_is_valid(local)) return -EINVAL; if (i->input_fd >= 0) return -EBUSY; r = fd_nonblock(fd, true); if (r < 0) return r; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->read_only = read_only; if (fstat(fd, &i->st) < 0) return -errno; r = sd_event_add_io(i->event, &i->input_event_source, fd, EPOLLIN, raw_import_on_input, i); if (r == -EPERM) { /* This fd does not support epoll, for example because it is a regular file. Busy read in that case */ r = sd_event_add_defer(i->event, &i->input_event_source, raw_import_on_defer, i); if (r < 0) return r; r = sd_event_source_set_enabled(i->input_event_source, SD_EVENT_ON); } if (r < 0) return r; i->input_fd = fd; return r; }
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) { Condition *c; int r; assert(type >= 0); assert(type < _CONDITION_TYPE_MAX); assert((!parameter) == (type == CONDITION_NULL)); c = new0(Condition, 1); if (!c) return NULL; c->type = type; c->trigger = trigger; c->negate = negate; r = free_and_strdup(&c->parameter, parameter); if (r < 0) { return mfree(c); } return c; }
int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { static const Specifier specifier_table[] = { { 'b', specifier_boot_id, NULL }, { 'H', specifier_host_name, NULL }, { 'm', specifier_machine_id, NULL }, { 'v', specifier_kernel_release, NULL }, {} }; DnssdService *s = userdata; _cleanup_free_ char *name = NULL; int r; assert(filename); assert(lvalue); assert(rvalue); assert(s); if (isempty(rvalue)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name can't be empty. Ignoring."); return -EINVAL; } r = free_and_strdup(&s->name_template, rvalue); if (r < 0) return log_oom(); r = specifier_printf(s->name_template, specifier_table, NULL, &name); if (r < 0) return log_debug_errno(r, "Failed to replace specifiers: %m"); if (!dns_service_name_is_valid(name)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name template renders to invalid name '%s'. Ignoring.", name); return -EINVAL; } return 0; }
static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { Scope *s = SCOPE(u); int r; assert(u); assert(key); assert(value); assert(fds); if (streq(key, "state")) { ScopeState state; state = scope_state_from_string(value); if (state < 0) log_unit_debug(u, "Failed to parse state value: %s", value); else s->deserialized_state = state; } else if (streq(key, "was-abandoned")) { int k; k = parse_boolean(value); if (k < 0) log_unit_debug(u, "Failed to parse boolean value: %s", value); else s->was_abandoned = k; } else if (streq(key, "controller")) { r = free_and_strdup(&s->controller, value); if (r < 0) log_oom(); } else log_unit_debug(u, "Unknown serialization key: %s", key); return 0; }
static void test_x11_convert_to_vconsole(void) { _cleanup_(context_free) Context c = {}; int r; log_info("/*** %s ***/", __func__); log_info("/* test emptying first (:) */"); assert_se(free_and_strdup(&c.vc_keymap, "foobar") >= 0); assert_se(x11_convert_to_vconsole(&c) == 1); assert_se(c.vc_keymap == NULL); log_info("/* test emptying second (:) */"); assert_se(x11_convert_to_vconsole(&c) == 0); assert_se(c.vc_keymap == NULL); log_info("/* test without variant, new mapping (es:) */"); assert_se(free_and_strdup(&c.x11_layout, "es") >= 0); assert_se(x11_convert_to_vconsole(&c) == 1); assert_se(streq(c.vc_keymap, "es")); log_info("/* test with unknown variant, new mapping (es:foobar) */"); assert_se(free_and_strdup(&c.x11_variant, "foobar") >= 0); assert_se(x11_convert_to_vconsole(&c) == 0); assert_se(streq(c.vc_keymap, "es")); log_info("/* test with known variant, new mapping (es:dvorak) */"); assert_se(free_and_strdup(&c.x11_variant, "dvorak") >= 0); r = x11_convert_to_vconsole(&c); if (r == 0) { log_info("Skipping rest of %s: keymaps are not installed", __func__); return; } assert_se(r == 1); assert_se(streq(c.vc_keymap, "es-dvorak")); log_info("/* test with old mapping (fr:latin9) */"); assert_se(free_and_strdup(&c.x11_layout, "fr") >= 0); assert_se(free_and_strdup(&c.x11_variant, "latin9") >= 0); assert_se(x11_convert_to_vconsole(&c) == 1); assert_se(streq(c.vc_keymap, "fr-latin9")); log_info("/* test with a compound mapping (us,ru:) */"); assert_se(free_and_strdup(&c.x11_layout, "us,ru") >= 0); assert_se(free_and_strdup(&c.x11_variant, NULL) >= 0); assert_se(x11_convert_to_vconsole(&c) == 1); assert_se(streq(c.vc_keymap, "us")); log_info("/* test with a compound mapping (ru,us:) */"); assert_se(free_and_strdup(&c.x11_layout, "ru,us") >= 0); assert_se(free_and_strdup(&c.x11_variant, NULL) >= 0); assert_se(x11_convert_to_vconsole(&c) == 1); assert_se(streq(c.vc_keymap, "ru")); /* https://bugzilla.redhat.com/show_bug.cgi?id=1333998 */ log_info("/* test with a simple new mapping (ru:) */"); assert_se(free_and_strdup(&c.x11_layout, "ru") >= 0); assert_se(free_and_strdup(&c.x11_variant, NULL) >= 0); assert_se(x11_convert_to_vconsole(&c) == 0); assert_se(streq(c.vc_keymap, "ru")); }
int raw_pull_start( RawPull *i, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings, bool roothash) { int r; assert(i); assert(verify < _IMPORT_VERIFY_MAX); assert(verify >= 0); if (!http_url_is_valid(url)) return -EINVAL; if (local && !machine_name_is_valid(local)) return -EINVAL; if (i->raw_job) return -EBUSY; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->verify = verify; i->settings = settings; i->roothash = roothash; /* Queue job for the image itself */ r = pull_job_new(&i->raw_job, url, i->glue, i); if (r < 0) return r; i->raw_job->on_finished = raw_pull_job_on_finished; i->raw_job->on_open_disk = raw_pull_job_on_open_disk_raw; i->raw_job->on_progress = raw_pull_job_on_progress; i->raw_job->calc_checksum = verify != IMPORT_VERIFY_NO; i->raw_job->grow_machine_directory = i->grow_machine_directory; r = pull_find_old_etags(url, i->image_root, DT_REG, ".raw-", ".raw", &i->raw_job->old_etags); if (r < 0) return r; if (roothash) { r = pull_make_auxiliary_job(&i->roothash_job, url, raw_strip_suffixes, ".roothash", i->glue, raw_pull_job_on_finished, i); if (r < 0) return r; i->roothash_job->on_open_disk = raw_pull_job_on_open_disk_roothash; i->roothash_job->on_progress = raw_pull_job_on_progress; i->roothash_job->calc_checksum = verify != IMPORT_VERIFY_NO; } if (settings) { r = pull_make_auxiliary_job(&i->settings_job, url, raw_strip_suffixes, ".nspawn", i->glue, raw_pull_job_on_finished, i); if (r < 0) return r; i->settings_job->on_open_disk = raw_pull_job_on_open_disk_settings; i->settings_job->on_progress = raw_pull_job_on_progress; i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO; } r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, raw_pull_job_on_finished, i); if (r < 0) return r; r = pull_job_begin(i->raw_job); if (r < 0) return r; if (i->roothash_job) { r = pull_job_begin(i->roothash_job); if (r < 0) return r; } if (i->settings_job) { r = pull_job_begin(i->settings_job); if (r < 0) return r; } if (i->checksum_job) { i->checksum_job->on_progress = raw_pull_job_on_progress; i->checksum_job->style = VERIFICATION_PER_FILE; r = pull_job_begin(i->checksum_job); if (r < 0) return r; } if (i->signature_job) { i->signature_job->on_progress = raw_pull_job_on_progress; r = pull_job_begin(i->signature_job); if (r < 0) return r; } return 0; }
/* find device node of device with highest priority */ static int link_find_prioritized(sd_device *dev, bool add, const char *stackdir, char **ret) { _cleanup_closedir_ DIR *dir = NULL; _cleanup_free_ char *target = NULL; struct dirent *dent; int r, priority = 0; assert(!add || dev); assert(stackdir); assert(ret); if (add) { const char *devnode; r = device_get_devlink_priority(dev, &priority); if (r < 0) return r; r = sd_device_get_devname(dev, &devnode); if (r < 0) return r; target = strdup(devnode); if (!target) return -ENOMEM; } dir = opendir(stackdir); if (!dir) { if (target) { *ret = TAKE_PTR(target); return 0; } return -errno; } FOREACH_DIRENT_ALL(dent, dir, break) { _cleanup_(sd_device_unrefp) sd_device *dev_db = NULL; const char *devnode, *id_filename; int db_prio = 0; if (dent->d_name[0] == '\0') break; if (dent->d_name[0] == '.') continue; log_device_debug(dev, "Found '%s' claiming '%s'", dent->d_name, stackdir); if (device_get_id_filename(dev, &id_filename) < 0) continue; /* did we find ourself? */ if (streq(dent->d_name, id_filename)) continue; if (sd_device_new_from_device_id(&dev_db, dent->d_name) < 0) continue; if (sd_device_get_devname(dev_db, &devnode) < 0) continue; if (device_get_devlink_priority(dev_db, &db_prio) < 0) continue; if (target && db_prio <= priority) continue; log_device_debug(dev_db, "Device claims priority %i for '%s'", db_prio, stackdir); r = free_and_strdup(&target, devnode); if (r < 0) return r; priority = db_prio; } if (!target) return -ENOENT; *ret = TAKE_PTR(target); return 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_ADDRESS, ARG_CONFIGURATION, ARG_MACHINE, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "address", required_argument, NULL, ARG_ADDRESS }, { "configuration", required_argument, NULL, ARG_CONFIGURATION }, { "machine", required_argument, NULL, ARG_MACHINE }, {}, }; int c, r; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_ADDRESS: r = free_and_strdup(&arg_address, optarg); if (r < 0) return log_oom(); break; case ARG_CONFIGURATION: r = strv_extend(&arg_configuration, optarg); if (r < 0) return log_oom(); break; case ARG_MACHINE: { _cleanup_free_ char *e = NULL; char *a; e = bus_address_escape(optarg); if (!e) return log_oom(); a = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL); if (!a) return log_oom(); free(arg_address); arg_address = a; break; } case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } if (argc > optind) { log_error("Too many arguments"); return -EINVAL; } if (!arg_address) { arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS); if (!arg_address) return log_oom(); } return 1; }
static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_message_handler_t cb, sd_bus_error *error) { int interactive; const char *name; int r; assert(c); assert(m); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; name = empty_to_null(name); if (streq_ptr(name, c->data[prop])) return sd_bus_reply_method_return(m, NULL); if (!isempty(name)) { /* The icon name might ultimately be used as file * name, so better be safe than sorry */ if (prop == PROP_ICON_NAME && !filename_is_valid(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name); if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name); if (prop == PROP_CHASSIS && !valid_chassis(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name); if (prop == PROP_DEPLOYMENT && !valid_deployment(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name); if (prop == PROP_LOCATION && string_has_cc(name, NULL)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name); } /* Since the pretty hostname should always be changed at the * same time as the static one, use the same policy action for * both... */ r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : "org.freedesktop.hostname1.set-machine-info", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = free_and_strdup(&c->data[prop], name); if (r < 0) return r; r = context_write_data_machine_info(c); if (r < 0) { log_error_errno(r, "Failed to write machine info: %m"); return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %m"); } log_info("Changed %s to '%s'", prop == PROP_PRETTY_HOSTNAME ? "pretty host name" : prop == PROP_DEPLOYMENT ? "deployment" : prop == PROP_LOCATION ? "location" : prop == PROP_CHASSIS ? "chassis" : "icon name", strna(c->data[prop])); (void) sd_bus_emit_properties_changed( sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", prop == PROP_PRETTY_HOSTNAME ? "PrettyHostname" : prop == PROP_DEPLOYMENT ? "Deployment" : prop == PROP_LOCATION ? "Location" : prop == PROP_CHASSIS ? "Chassis" : "IconName" , NULL); return sd_bus_reply_method_return(m, NULL); }
static int parse_proc_cmdline_item(const char *key, const char *value) { int r; /* root=, usr=, usrfstype= and roofstype= may occur more than once, the last * instance should take precedence. In the case of multiple rootflags= * or usrflags= the arguments should be concatenated */ if (STR_IN_SET(key, "fstab", "rd.fstab") && value) { r = parse_boolean(value); if (r < 0) log_warning("Failed to parse fstab switch %s. Ignoring.", value); else arg_fstab_enabled = r; } else if (streq(key, "root") && value) { if (free_and_strdup(&arg_root_what, value) < 0) return log_oom(); } else if (streq(key, "rootfstype") && value) { if (free_and_strdup(&arg_root_fstype, value) < 0) return log_oom(); } else if (streq(key, "rootflags") && value) { char *o; o = arg_root_options ? strjoin(arg_root_options, ",", value, NULL) : strdup(value); if (!o) return log_oom(); free(arg_root_options); arg_root_options = o; } else if (streq(key, "mount.usr") && value) { if (free_and_strdup(&arg_usr_what, value) < 0) return log_oom(); } else if (streq(key, "mount.usrfstype") && value) { if (free_and_strdup(&arg_usr_fstype, value) < 0) return log_oom(); } else if (streq(key, "mount.usrflags") && value) { char *o; o = arg_usr_options ? strjoin(arg_usr_options, ",", value, NULL) : strdup(value); if (!o) return log_oom(); free(arg_usr_options); arg_usr_options = o; } else if (streq(key, "rw") && !value) arg_root_rw = true; else if (streq(key, "ro") && !value) arg_root_rw = false; return 0; }
int tar_pull_start( TarPull *i, const char *url, const char *local, bool force_local, ImportVerify verify, bool settings) { int r; assert(i); assert(verify < _IMPORT_VERIFY_MAX); assert(verify >= 0); if (!http_url_is_valid(url)) return -EINVAL; if (local && !machine_name_is_valid(local)) return -EINVAL; if (i->tar_job) return -EBUSY; r = free_and_strdup(&i->local, local); if (r < 0) return r; i->force_local = force_local; i->verify = verify; i->settings = settings; /* Set up download job for TAR file */ r = pull_job_new(&i->tar_job, url, i->glue, i); if (r < 0) return r; i->tar_job->on_finished = tar_pull_job_on_finished; i->tar_job->on_open_disk = tar_pull_job_on_open_disk_tar; i->tar_job->on_progress = tar_pull_job_on_progress; i->tar_job->calc_checksum = verify != IMPORT_VERIFY_NO; i->tar_job->grow_machine_directory = i->grow_machine_directory; r = pull_find_old_etags(url, i->image_root, DT_DIR, ".tar-", NULL, &i->tar_job->old_etags); if (r < 0) return r; /* Set up download job for the settings file (.nspawn) */ if (settings) { r = pull_make_auxiliary_job(&i->settings_job, url, tar_strip_suffixes, ".nspawn", i->glue, tar_pull_job_on_finished, i); if (r < 0) return r; i->settings_job->on_open_disk = tar_pull_job_on_open_disk_settings; i->settings_job->on_progress = tar_pull_job_on_progress; i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO; } /* Set up download of checksum/signature files */ r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, tar_pull_job_on_finished, i); if (r < 0) return r; r = pull_job_begin(i->tar_job); if (r < 0) return r; if (i->settings_job) { r = pull_job_begin(i->settings_job); if (r < 0) return r; } if (i->checksum_job) { i->checksum_job->on_progress = tar_pull_job_on_progress; i->checksum_job->style = VERIFICATION_PER_FILE; r = pull_job_begin(i->checksum_job); if (r < 0) return r; } if (i->signature_job) { i->signature_job->on_progress = tar_pull_job_on_progress; r = pull_job_begin(i->signature_job); if (r < 0) return r; } return 0; }
int vconsole_convert_to_x11(Context *c) { const char *map; int modified = -1; map = systemd_kbd_model_map(); if (isempty(c->vc_keymap)) { modified = !isempty(c->x11_layout) || !isempty(c->x11_model) || !isempty(c->x11_variant) || !isempty(c->x11_options); context_free_x11(c); } else { _cleanup_fclose_ FILE *f = NULL; unsigned n = 0; f = fopen(map, "re"); if (!f) return -errno; for (;;) { _cleanup_strv_free_ char **a = NULL; int r; r = read_next_mapping(map, 5, UINT_MAX, f, &n, &a); if (r < 0) return r; if (r == 0) break; if (!streq(c->vc_keymap, a[0])) continue; if (!streq_ptr(c->x11_layout, strnulldash(a[1])) || !streq_ptr(c->x11_model, strnulldash(a[2])) || !streq_ptr(c->x11_variant, strnulldash(a[3])) || !streq_ptr(c->x11_options, strnulldash(a[4]))) { if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 || free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 || free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 || free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0) return -ENOMEM; modified = true; } break; } } if (modified > 0) log_info("Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'", strempty(c->x11_layout), strempty(c->x11_model), strempty(c->x11_variant), strempty(c->x11_options)); else if (modified < 0) log_notice("X11 keyboard layout was not modified: no conversion found for \"%s\".", c->vc_keymap); else log_debug("X11 keyboard layout did not need to be modified."); return modified > 0; }
static int parse_proc_cmdline_item(const char *key, const char *value) { int r; assert(key); if (streq(key, "systemd.mask")) { if (!value) log_error("Missing argument for systemd.mask= kernel command line parameter."); else { char *n; r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n); if (r < 0) return log_error_errno(r, "Failed to glob unit name: %m"); r = strv_consume(&arg_mask, n); if (r < 0) return log_oom(); } } else if (streq(key, "systemd.wants")) { if (!value) log_error("Missing argument for systemd.want= kernel command line parameter."); else { char *n; r = unit_name_mangle(value, UNIT_NAME_NOGLOB, &n); if (r < 0) return log_error_errno(r, "Failed to glob unit name: %m"); r = strv_consume(&arg_wants, n); if (r < 0) return log_oom(); } } else if (streq(key, "systemd.debug-shell")) { if (value) { r = parse_boolean(value); if (r < 0) log_error("Failed to parse systemd.debug-shell= argument '%s', ignoring.", value); else arg_debug_shell = r; } else arg_debug_shell = true; } else if (streq(key, "systemd.unit")) { if (!value) log_error("Missing argument for systemd.unit= kernel command line parameter."); else { r = free_and_strdup(&arg_default_unit, value); if (r < 0) return log_error_errno(r, "Failed to set default unit %s: %m", value); } } else if (!value) { const char *target; target = runlevel_to_target(key); if (target) { r = free_and_strdup(&arg_default_unit, target); if (r < 0) return log_error_errno(r, "Failed to set default unit %s: %m", target); } } return 0; }
static int vconsole_convert_to_x11(Context *c, sd_bus *bus) { bool modified = false; assert(bus); if (isempty(c->vc_keymap)) { modified = !isempty(c->x11_layout) || !isempty(c->x11_model) || !isempty(c->x11_variant) || !isempty(c->x11_options); context_free_x11(c); } else { _cleanup_fclose_ FILE *f = NULL; unsigned n = 0; f = fopen(SYSTEMD_KBD_MODEL_MAP, "re"); if (!f) return -errno; for (;;) { _cleanup_strv_free_ char **a = NULL; int r; r = read_next_mapping(f, &n, &a); if (r < 0) return r; if (r == 0) break; if (!streq(c->vc_keymap, a[0])) continue; if (!streq_ptr(c->x11_layout, strnulldash(a[1])) || !streq_ptr(c->x11_model, strnulldash(a[2])) || !streq_ptr(c->x11_variant, strnulldash(a[3])) || !streq_ptr(c->x11_options, strnulldash(a[4]))) { if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 || free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 || free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 || free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0) return -ENOMEM; modified = true; } break; } } if (modified) { int r; r = x11_write_data(c); if (r < 0) return log_error_errno(r, "Failed to set X11 keyboard layout: %m"); log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'", strempty(c->x11_layout), strempty(c->x11_model), strempty(c->x11_variant), strempty(c->x11_options)); sd_bus_emit_properties_changed(bus, "/org/freedesktop/locale1", "org.freedesktop.locale1", "X11Layout", "X11Model", "X11Variant", "X11Options", NULL); } else log_debug("X11 keyboard layout was not modified."); return 0; }
int locale_read_data(Context *c, sd_bus_message *m) { struct stat st; int r; /* Do not try to re-read the file within single bus operation. */ if (m) { if (m == c->locale_cache) return 0; sd_bus_message_unref(c->locale_cache); c->locale_cache = sd_bus_message_ref(m); } r = stat("/etc/locale.conf", &st); if (r < 0 && errno != ENOENT) return -errno; if (r >= 0) { usec_t t; /* If mtime is not changed, then we do not need to re-read the file. */ t = timespec_load(&st.st_mtim); if (c->locale_mtime != USEC_INFINITY && t == c->locale_mtime) return 0; c->locale_mtime = t; context_free_locale(c); r = parse_env_file(NULL, "/etc/locale.conf", NEWLINE, "LANG", &c->locale[VARIABLE_LANG], "LANGUAGE", &c->locale[VARIABLE_LANGUAGE], "LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE], "LC_NUMERIC", &c->locale[VARIABLE_LC_NUMERIC], "LC_TIME", &c->locale[VARIABLE_LC_TIME], "LC_COLLATE", &c->locale[VARIABLE_LC_COLLATE], "LC_MONETARY", &c->locale[VARIABLE_LC_MONETARY], "LC_MESSAGES", &c->locale[VARIABLE_LC_MESSAGES], "LC_PAPER", &c->locale[VARIABLE_LC_PAPER], "LC_NAME", &c->locale[VARIABLE_LC_NAME], "LC_ADDRESS", &c->locale[VARIABLE_LC_ADDRESS], "LC_TELEPHONE", &c->locale[VARIABLE_LC_TELEPHONE], "LC_MEASUREMENT", &c->locale[VARIABLE_LC_MEASUREMENT], "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION], NULL); if (r < 0) return r; } else { int p; c->locale_mtime = USEC_INFINITY; context_free_locale(c); /* Fill in what we got passed from systemd. */ for (p = 0; p < _VARIABLE_LC_MAX; p++) { const char *name; name = locale_variable_to_string(p); assert(name); r = free_and_strdup(&c->locale[p], empty_to_null(getenv(name))); if (r < 0) return r; } } locale_simplify(c->locale); return 0; }
int sd_netlink_slot_set_description(sd_netlink_slot *slot, const char *description) { assert_return(slot, -EINVAL); return free_and_strdup(&slot->description, description); }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_ROOT, ARG_LOCALE, ARG_LOCALE_MESSAGES, ARG_TIMEZONE, ARG_HOSTNAME, ARG_MACHINE_ID, ARG_ROOT_PASSWORD, ARG_ROOT_PASSWORD_FILE, ARG_PROMPT, ARG_PROMPT_LOCALE, ARG_PROMPT_TIMEZONE, ARG_PROMPT_HOSTNAME, ARG_PROMPT_ROOT_PASSWORD, ARG_COPY, ARG_COPY_LOCALE, ARG_COPY_TIMEZONE, ARG_COPY_ROOT_PASSWORD, ARG_SETUP_MACHINE_ID, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "root", required_argument, NULL, ARG_ROOT }, { "locale", required_argument, NULL, ARG_LOCALE }, { "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES }, { "timezone", required_argument, NULL, ARG_TIMEZONE }, { "hostname", required_argument, NULL, ARG_HOSTNAME }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, { "root-password", required_argument, NULL, ARG_ROOT_PASSWORD }, { "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE }, { "prompt", no_argument, NULL, ARG_PROMPT }, { "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE }, { "prompt-timezone", no_argument, NULL, ARG_PROMPT_TIMEZONE }, { "prompt-hostname", no_argument, NULL, ARG_PROMPT_HOSTNAME }, { "prompt-root-password", no_argument, NULL, ARG_PROMPT_ROOT_PASSWORD }, { "copy", no_argument, NULL, ARG_COPY }, { "copy-locale", no_argument, NULL, ARG_COPY_LOCALE }, { "copy-timezone", no_argument, NULL, ARG_COPY_TIMEZONE }, { "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD }, { "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID }, {} }; int r, c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_ROOT: free(arg_root); arg_root = path_make_absolute_cwd(optarg); if (!arg_root) return log_oom(); path_kill_slashes(arg_root); if (path_equal(arg_root, "/")) arg_root = mfree(arg_root); break; case ARG_LOCALE: if (!locale_is_valid(optarg)) { log_error("Locale %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_locale, optarg); if (r < 0) return log_oom(); break; case ARG_LOCALE_MESSAGES: if (!locale_is_valid(optarg)) { log_error("Locale %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_locale_messages, optarg); if (r < 0) return log_oom(); break; case ARG_TIMEZONE: if (!timezone_is_valid(optarg)) { log_error("Timezone %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_timezone, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD: r = free_and_strdup(&arg_root_password, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD_FILE: arg_root_password = mfree(arg_root_password); r = read_one_line_file(optarg, &arg_root_password); if (r < 0) return log_error_errno(r, "Failed to read %s: %m", optarg); break; case ARG_HOSTNAME: if (!hostname_is_valid(optarg, true)) { log_error("Host name %s is not valid.", optarg); return -EINVAL; } hostname_cleanup(optarg); r = free_and_strdup(&arg_hostname, optarg); if (r < 0) return log_oom(); break; case ARG_MACHINE_ID: if (sd_id128_from_string(optarg, &arg_machine_id) < 0) { log_error("Failed to parse machine id %s.", optarg); return -EINVAL; } break; case ARG_PROMPT: arg_prompt_locale = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true; break; case ARG_PROMPT_LOCALE: arg_prompt_locale = true; break; case ARG_PROMPT_TIMEZONE: arg_prompt_timezone = true; break; case ARG_PROMPT_HOSTNAME: arg_prompt_hostname = true; break; case ARG_PROMPT_ROOT_PASSWORD: arg_prompt_root_password = true; break; case ARG_COPY: arg_copy_locale = arg_copy_timezone = arg_copy_root_password = true; break; case ARG_COPY_LOCALE: arg_copy_locale = true; break; case ARG_COPY_TIMEZONE: arg_copy_timezone = true; break; case ARG_COPY_ROOT_PASSWORD: arg_copy_root_password = true; break; case ARG_SETUP_MACHINE_ID: r = sd_id128_randomize(&arg_machine_id); if (r < 0) return log_error_errno(r, "Failed to generate randomized machine ID: %m"); break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
static int enumerate_partitions(dev_t devnum) { _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; _cleanup_udev_device_unref_ struct udev_device *d = NULL; _cleanup_blkid_free_probe_ blkid_probe b = NULL; _cleanup_udev_unref_ struct udev *udev = NULL; _cleanup_free_ char *boot = NULL, *home = NULL, *srv = NULL; struct udev_list_entry *first, *item; struct udev_device *parent = NULL; const char *name, *node, *pttype, *devtype; int boot_nr = -1, home_nr = -1, srv_nr = -1; bool home_rw = true, srv_rw = true; blkid_partlist pl; int r, k; dev_t pn; udev = udev_new(); if (!udev) return log_oom(); d = udev_device_new_from_devnum(udev, 'b', devnum); if (!d) return log_oom(); name = udev_device_get_devnode(d); if (!name) name = udev_device_get_syspath(d); if (!name) { log_debug("Device %u:%u does not have a name, ignoring.", major(devnum), minor(devnum)); return 0; } parent = udev_device_get_parent(d); if (!parent) { log_debug("%s: not a partitioned device, ignoring.", name); return 0; } /* Does it have a devtype? */ devtype = udev_device_get_devtype(parent); if (!devtype) { log_debug("%s: parent doesn't have a device type, ignoring.", name); return 0; } /* Is this a disk or a partition? We only care for disks... */ if (!streq(devtype, "disk")) { log_debug("%s: parent isn't a raw disk, ignoring.", name); return 0; } /* Does it have a device node? */ node = udev_device_get_devnode(parent); if (!node) { log_debug("%s: parent device does not have device node, ignoring.", name); return 0; } log_debug("%s: root device %s.", name, node); pn = udev_device_get_devnum(parent); if (major(pn) == 0) return 0; errno = 0; b = blkid_new_probe_from_filename(node); if (!b) { if (errno == 0) return log_oom(); return log_error_errno(errno, "%s: failed to allocate prober: %m", node); } blkid_probe_enable_partitions(b, 1); blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS); errno = 0; r = blkid_do_safeprobe(b); if (r == 1) return 0; /* no results */ else if (r == -2) { log_warning("%s: probe gave ambiguous results, ignoring", node); return 0; } else if (r != 0) return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node); errno = 0; r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL); if (r != 0) return log_error_errno(errno ?: EIO, "%s: failed to determine partition table type: %m", node); /* We only do this all for GPT... */ if (!streq_ptr(pttype, "gpt")) { log_debug("%s: not a GPT partition table, ignoring.", node); return 0; } errno = 0; pl = blkid_probe_get_partitions(b); if (!pl) { if (errno == 0) return log_oom(); return log_error_errno(errno, "%s: failed to list partitions: %m", node); } e = udev_enumerate_new(udev); if (!e) return log_oom(); r = udev_enumerate_add_match_parent(e, parent); if (r < 0) return log_oom(); r = udev_enumerate_add_match_subsystem(e, "block"); if (r < 0) return log_oom(); r = udev_enumerate_scan_devices(e); if (r < 0) return log_error_errno(r, "%s: failed to enumerate partitions: %m", node); first = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(item, first) { _cleanup_udev_device_unref_ struct udev_device *q; unsigned long long flags; const char *stype, *subnode; sd_id128_t type_id; blkid_partition pp; dev_t qn; int nr; q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); if (!q) continue; qn = udev_device_get_devnum(q); if (major(qn) == 0) continue; if (qn == devnum) continue; if (qn == pn) continue; subnode = udev_device_get_devnode(q); if (!subnode) continue; pp = blkid_partlist_devno_to_partition(pl, qn); if (!pp) continue; nr = blkid_partition_get_partno(pp); if (nr < 0) continue; stype = blkid_partition_get_type_string(pp); if (!stype) continue; if (sd_id128_from_string(stype, &type_id) < 0) continue; flags = blkid_partition_get_flags(pp); if (sd_id128_equal(type_id, GPT_SWAP)) { if (flags & GPT_FLAG_NO_AUTO) continue; if (flags & GPT_FLAG_READ_ONLY) { log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode); continue; } k = add_swap(subnode); if (k < 0) r = k; } else if (sd_id128_equal(type_id, GPT_ESP)) { /* We only care for the first /boot partition */ if (boot && nr >= boot_nr) continue; /* Note that we do not honour the "no-auto" * flag for the ESP, as it is often unset, to * hide it from Windows. */ boot_nr = nr; r = free_and_strdup(&boot, subnode); if (r < 0) return log_oom(); } else if (sd_id128_equal(type_id, GPT_HOME)) { if (flags & GPT_FLAG_NO_AUTO) continue; /* We only care for the first /home partition */ if (home && nr >= home_nr) continue; home_nr = nr; home_rw = !(flags & GPT_FLAG_READ_ONLY), r = free_and_strdup(&home, subnode); if (r < 0) return log_oom(); } else if (sd_id128_equal(type_id, GPT_SRV)) { if (flags & GPT_FLAG_NO_AUTO) continue; /* We only care for the first /srv partition */ if (srv && nr >= srv_nr) continue; srv_nr = nr; srv_rw = !(flags & GPT_FLAG_READ_ONLY), r = free_and_strdup(&srv, subnode); if (r < 0) return log_oom(); } }