bool mount_point_is_api(const char *path) { unsigned i; /* Checks if this mount point is considered "API", and hence * should be ignored */ for (i = 0; i < ELEMENTSOF(mount_table); i ++) if (path_equal(path, mount_table[i].where)) return true; return path_startswith(path, "/sys/fs/cgroup/"); }
static int create_dirs(const char *esp_path) { int r; unsigned i; for (i = 0; i < ELEMENTSOF(efi_subdirs); i++) { r = mkdir_one(esp_path, efi_subdirs[i]); if (r < 0) return r; } return 0; }
void udev_builtin_exit(struct udev *udev) { unsigned int i; if (!initialized) return; for (i = 0; i < ELEMENTSOF(builtins); i++) if (builtins[i]->exit) builtins[i]->exit(udev); initialized = false; }
static int adm_help(struct udev *udev, int argc, char *argv[]) { unsigned int i; printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n" "Send control commands or test the device manager.\n\n" "Commands:\n" , program_invocation_short_name); for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) if (udevadm_cmds[i]->help != NULL) printf(" %-12s %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help); return 0; }
int catalog_compare_func(const void *a, const void *b) { const CatalogItem *i = a, *j = b; unsigned k; for (k = 0; k < ELEMENTSOF(j->id.bytes); k++) { if (i->id.bytes[k] < j->id.bytes[k]) return -1; if (i->id.bytes[k] > j->id.bytes[k]) return 1; } return strcmp(i->language, j->language); }
static void test_prefixes_cb(sd_icmp6_nd *nd, int event, void *userdata) { sd_event *e = userdata; struct { struct in6_addr addr; uint8_t prefixlen; bool success; } addrs[] = { { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 63, true }, { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64, false }, { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60, true }, { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64, true }, { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }, 63, false }, }; uint8_t prefixlen; unsigned int i; for (i = 0; i < ELEMENTSOF(addrs); i++) { printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x", __FUNCTION__, addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1], addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3], addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5], addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]); if (addrs[i].success) { assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, &prefixlen) >= 0); assert_se(addrs[i].prefixlen == prefixlen); printf("/%d onlink\n", prefixlen); } else { assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr, &prefixlen) == -EADDRNOTAVAIL); printf("/128 offlink\n"); } } send_ra_function = send_ra_short_prefix; assert_se(sd_icmp6_nd_set_callback(nd, test_short_prefix_cb, e) >= 0); assert_se(sd_icmp6_nd_stop(nd) >= 0); assert_se(sd_icmp6_router_solicitation_start(nd) >= 0); }
static void test_term_char_packing(void) { uint32_t seqs[][1024] = { { -1 }, { 0, -1 }, { 'A', '~', -1 }, { 'A', '~', 0, -1 }, { 'A', '~', 'a', -1 }, }; term_char_t res[] = { TERM_CHAR_NULL, PACK1(0), PACK2('A', '~'), PACK3('A', '~', 0), PACK3('A', '~', 'a'), }; uint32_t next; unsigned int i, j; term_char_t c = TERM_CHAR_NULL; /* * This creates term_char_t objects based on the data in @seqs and * compares the result to @res. Only basic packed types are tested, no * allocations are done. */ for (i = 0; i < ELEMENTSOF(seqs); ++i) { for (j = 0; j < ELEMENTSOF(seqs[i]); ++j) { next = seqs[i][j]; if (next == (uint32_t)-1) break; c = term_char_merge(c, next); } assert_se(!memcmp(&c, &res[i], sizeof(c))); c = term_char_free(c); } }
enum udev_builtin_cmd udev_builtin_lookup(const char *command) { char name[UTIL_PATH_SIZE]; enum udev_builtin_cmd i; char *pos; strscpy(name, sizeof(name), command); pos = strchr(name, ' '); if (pos) pos[0] = '\0'; for (i = 0; i < ELEMENTSOF(builtins); i++) if (builtins[i] && streq(builtins[i]->name, name)) return i; return UDEV_BUILTIN_MAX; }
int kmod_setup(void) { unsigned i; struct kmod_ctx *ctx = NULL; struct kmod_module *mod; int err; for (i = 0; i < ELEMENTSOF(kmod_table); i += 2) { if (access(kmod_table[i+1], F_OK) >= 0) continue; log_debug("Your kernel apparently lacks built-in %s support. Might be a good idea to compile it in. " "We'll now try to work around this by loading the module...", kmod_table[i]); if (!ctx) { ctx = kmod_new(NULL, NULL); if (!ctx) { log_error("Failed to allocate memory for kmod"); return -ENOMEM; } kmod_set_log_fn(ctx, systemd_kmod_log, NULL); kmod_load_resources(ctx); } err = kmod_module_new_from_name(ctx, kmod_table[i], &mod); if (err < 0) { log_error("Failed to load module '%s'", kmod_table[i]); continue; } err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); if (err == 0) log_info("Inserted module '%s'", kmod_module_get_name(mod)); else if (err == KMOD_PROBE_APPLY_BLACKLIST) log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); else log_error("Failed to insert '%s'", kmod_module_get_name(mod)); kmod_module_unref(mod); } if (ctx) kmod_unref(ctx); return 0; }
static int get_current_runlevel(Context *c) { static const struct { const int runlevel; const char *special; } table[] = { /* The first target of this list that is active or has * a job scheduled wins. We prefer runlevels 5 and 3 * here over the others, since these are the main * runlevels used on Fedora. It might make sense to * change the order on some distributions. */ { '5', SPECIAL_RUNLEVEL5_TARGET }, { '3', SPECIAL_RUNLEVEL3_TARGET }, { '4', SPECIAL_RUNLEVEL4_TARGET }, { '2', SPECIAL_RUNLEVEL2_TARGET }, { '1', SPECIAL_RESCUE_TARGET }, }; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; int r; unsigned i; assert(c); for (i = 0; i < ELEMENTSOF(table); i++) { _cleanup_free_ char *state = NULL, *path = NULL; path = unit_dbus_path_from_name(table[i].special); if (!path) return log_oom(); r = sd_bus_get_property_string( c->bus, "org.freedesktop.systemd1", path, "org.freedesktop.systemd1.Unit", "ActiveState", &error, &state); if (r < 0) { log_warning("Failed to get state: %s", bus_error_message(&error, -r)); return r; } if (streq(state, "active") || streq(state, "reloading")) return table[i].runlevel; } return 0; }
static void test_hashmap_free_with_destructor(void) { Hashmap *m; struct Item items[4] = {}; unsigned i; assert_se(m = hashmap_new(NULL)); for (i = 0; i < ELEMENTSOF(items) - 1; i++) assert_se(hashmap_put(m, INT_TO_PTR(i), items + i) == 1); m = hashmap_free_with_destructor(m, item_seen); assert_se(items[0].seen == 1); assert_se(items[1].seen == 1); assert_se(items[2].seen == 1); assert_se(items[3].seen == 0); }
static char* extract_multiplier(char *p, usec_t *multiplier) { static const struct { const char *suffix; usec_t usec; } table[] = { { "seconds", USEC_PER_SEC }, { "second", USEC_PER_SEC }, { "sec", USEC_PER_SEC }, { "s", USEC_PER_SEC }, { "minutes", USEC_PER_MINUTE }, { "minute", USEC_PER_MINUTE }, { "min", USEC_PER_MINUTE }, { "months", USEC_PER_MONTH }, { "month", USEC_PER_MONTH }, { "M", USEC_PER_MONTH }, { "msec", USEC_PER_MSEC }, { "ms", USEC_PER_MSEC }, { "m", USEC_PER_MINUTE }, { "hours", USEC_PER_HOUR }, { "hour", USEC_PER_HOUR }, { "hr", USEC_PER_HOUR }, { "h", USEC_PER_HOUR }, { "days", USEC_PER_DAY }, { "day", USEC_PER_DAY }, { "d", USEC_PER_DAY }, { "weeks", USEC_PER_WEEK }, { "week", USEC_PER_WEEK }, { "w", USEC_PER_WEEK }, { "years", USEC_PER_YEAR }, { "year", USEC_PER_YEAR }, { "y", USEC_PER_YEAR }, { "usec", 1ULL }, { "us", 1ULL }, }; unsigned i; for (i = 0; i < ELEMENTSOF(table); i++) { char *e; e = startswith(p, table[i].suffix); if (e) { *multiplier = table[i].usec; return e; } } return p; }
static void format_weekdays(FILE *f, const CalendarSpec *c) { static const char *const days[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; int l, x; bool need_colon = false; assert(f); assert(c); assert(c->weekdays_bits > 0 && c->weekdays_bits <= 127); for (x = 0, l = -1; x < (int) ELEMENTSOF(days); x++) { if (c->weekdays_bits & (1 << x)) { if (l < 0) { if (need_colon) fputc(',', f); else need_colon = true; fputs(days[x], f); l = x; } } else if (l >= 0) { if (x > l + 1) { fputc(x > l + 2 ? '-' : ',', f); fputs(days[x-1], f); } l = -1; } } if (l >= 0 && x > l + 1) { fputc(x > l + 2 ? '-' : ',', f); fputs(days[x-1], f); } }
static int output_short( FILE *f, sd_journal *j, OutputMode mode, unsigned n_columns, OutputFlags flags, Set *output_fields, const size_t highlight[2]) { int r; const void *data; size_t length; size_t n = 0; _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL, *unit = NULL, *user_unit = NULL; size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0, unit_len = 0, user_unit_len = 0; int p = LOG_INFO; bool ellipsized = false; const ParseFieldVec fields[] = { PARSE_FIELD_VEC_ENTRY("_PID=", &pid, &pid_len), PARSE_FIELD_VEC_ENTRY("_COMM=", &comm, &comm_len), PARSE_FIELD_VEC_ENTRY("MESSAGE=", &message, &message_len), PARSE_FIELD_VEC_ENTRY("PRIORITY=", &priority, &priority_len), PARSE_FIELD_VEC_ENTRY("_HOSTNAME=", &hostname, &hostname_len), PARSE_FIELD_VEC_ENTRY("SYSLOG_PID=", &fake_pid, &fake_pid_len), PARSE_FIELD_VEC_ENTRY("SYSLOG_IDENTIFIER=", &identifier, &identifier_len), PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len), PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len), PARSE_FIELD_VEC_ENTRY("_SYSTEMD_UNIT=", &unit, &unit_len), PARSE_FIELD_VEC_ENTRY("_SYSTEMD_USER_UNIT=", &user_unit, &user_unit_len), }; size_t highlight_shifted[] = {highlight ? highlight[0] : 0, highlight ? highlight[1] : 0}; assert(f); assert(j); /* Set the threshold to one bigger than the actual print * threshold, so that if the line is actually longer than what * we're willing to print, ellipsization will occur. This way * we won't output a misleading line without any indication of * truncation. */ sd_journal_set_data_threshold(j, flags & (OUTPUT_SHOW_ALL|OUTPUT_FULL_WIDTH) ? 0 : PRINT_CHAR_THRESHOLD + 1); JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) { r = parse_fieldv(data, length, fields, ELEMENTSOF(fields)); if (r < 0) return r; }
int main(int argc, char *argv[]) { unsigned int i; test_invalid_buffer_length(); test_cookie(); test_options(NULL); for (i = 0; i < ELEMENTSOF(option_tests); i++) test_options(&option_tests[i]); test_option_set(); return 0; }
int main(int argc, const char *argv[]) { unsigned int i; for (i = 0; i < ELEMENTSOF(af_names); i++) { if (af_names[i]) { assert_se(streq(af_to_name(i), af_names[i])); assert_se(af_from_name(af_names[i]) == (int) i); } } assert_se(af_to_name(af_max()) == NULL); assert_se(af_to_name(-1) == NULL); assert_se(af_from_name("huddlduddl") == AF_UNSPEC); return 0; }
static bool skip_attribute(const char *name) { static const char* const skip[] = { "uevent", "dev", "modalias", "resource", "driver", "subsystem", "module", }; unsigned int i; for (i = 0; i < ELEMENTSOF(skip); i++) if (streq(name, skip[i])) return true; return false; }
static double percent(int pass, unsigned long cur, unsigned long max) { /* Values stolen from e2fsck */ static const int pass_table[] = { 0, 70, 90, 92, 95, 100 }; if (pass <= 0) return 0.0; if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0) return 100.0; return (double) pass_table[pass-1] + ((double) pass_table[pass] - (double) pass_table[pass-1]) * (double) cur / (double) max; }
static void test_clock_is_localtime(void) { char adjtime[] = "/tmp/test-adjtime.XXXXXX"; int fd = -1; _cleanup_fclose_ FILE* f = NULL; static const struct scenario { const char* contents; int expected_result; } scenarios[] = { /* adjtime configures UTC */ {"0.0 0 0\n0\nUTC\n", 0}, /* adjtime configures local time */ {"0.0 0 0\n0\nLOCAL\n", 1}, /* no final EOL */ {"0.0 0 0\n0\nUTC", 0}, {"0.0 0 0\n0\nLOCAL", 1}, /* empty value -> defaults to UTC */ {"0.0 0 0\n0\n", 0}, /* unknown value -> defaults to UTC */ {"0.0 0 0\n0\nFOO\n", 0}, /* no third line */ {"0.0 0 0", 0}, {"0.0 0 0\n", 0}, {"0.0 0 0\n0", 0}, }; /* without an adjtime file we default to UTC */ assert_se(clock_is_localtime("/nonexisting/adjtime") == 0); fd = mkostemp_safe(adjtime); assert_se(fd >= 0); log_info("adjtime test file: %s", adjtime); f = fdopen(fd, "w"); assert_se(f); for (size_t i = 0; i < ELEMENTSOF(scenarios); ++i) { log_info("scenario #%zu:, expected result %i", i, scenarios[i].expected_result); log_info("%s", scenarios[i].contents); rewind(f); ftruncate(fd, 0); assert_se(write_string_stream(f, scenarios[i].contents, WRITE_STRING_FILE_AVOID_NEWLINE) == 0); assert_se(clock_is_localtime(adjtime) == scenarios[i].expected_result); } unlink(adjtime); }
int mount_setup_early(void) { unsigned i; int r = 0; assert_cc(N_EARLY_MOUNT <= ELEMENTSOF(mount_table)); /* Do a minimal mount of /proc and friends to enable the most * basic stuff, such as SELinux */ for (i = 0; i < N_EARLY_MOUNT; i ++) { int j; j = mount_one(mount_table + i, false); if (r == 0) r = j; } return r; }
static bool mask_contains(unsigned a[], unsigned n) { unsigned i, j; for (i = 0; i < ELEMENTSOF(mask); i++) { bool found = false; for (j = 0; j < n; j++) if (a[j] == i) { found = true; break; } if (found != mask[i]) return false; } return true; }
static void test_hexdump(void) { uint8_t data[146]; unsigned i; hexdump(stdout, NULL, 0); hexdump(stdout, "", 0); hexdump(stdout, "", 1); hexdump(stdout, "x", 1); hexdump(stdout, "x", 2); hexdump(stdout, "foobar", 7); hexdump(stdout, "f\nobar", 7); hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23); for (i = 0; i < ELEMENTSOF(data); i++) data[i] = i*2; hexdump(stdout, data, sizeof(data)); }
int udev_builtin_init(struct udev *udev) { unsigned int i; int err = 0; if (initialized) return 0; for (i = 0; i < ELEMENTSOF(builtins); i++) { if (builtins[i]->init) { err = builtins[i]->init(udev); if (err < 0) break; } } initialized = true; return err; }
static int remove_binaries(const char *esp_path) { char *p; int r, q; unsigned i; p = strjoina(esp_path, "/EFI/systemd"); r = rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL); q = remove_boot_efi(esp_path); if (q < 0 && r == 0) r = q; for (i = ELEMENTSOF(efi_subdirs); i > 0; i--) { q = rmdir_one(esp_path, efi_subdirs[i-1]); if (q < 0 && r == 0) r = q; } return r; }
static int print_home(const char *n) { uint64_t i = 0; int r; for (i = 0; i < ELEMENTSOF(path_table); i++) { if (streq(path_table[i], n)) { _cleanup_free_ char *p = NULL; r = sd_path_home(i, arg_suffix, &p); if (r < 0) return log_error_errno(r, "Failed to query %s: %m", n); printf("%s\n", p); return 0; } } log_error("Path %s not known.", n); return -EOPNOTSUPP; }
_const_ static usec_t when_wall(usec_t n, usec_t elapse) { usec_t left; unsigned int i; static const int wall_timers[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 40, 55, 70, 100, 130, 150, 180, }; /* If the time is already passed, then don't announce */ if (n >= elapse) return 0; left = elapse - n; for (i = 1; i < ELEMENTSOF(wall_timers); i++) if (wall_timers[i] * USEC_PER_MINUTE >= left) return left - wall_timers[i-1] * USEC_PER_MINUTE; return left % USEC_PER_HOUR; }
char *format_bytes(char *buf, size_t l, uint64_t t) { unsigned i; /* This only does IEC units so far */ static const struct { const char *suffix; uint64_t factor; } table[] = { { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) }, { "M", UINT64_C(1024)*UINT64_C(1024) }, { "K", UINT64_C(1024) }, }; if (t == (uint64_t) -1) return NULL; for (i = 0; i < ELEMENTSOF(table); i++) { if (t >= table[i].factor) { snprintf(buf, l, "%" PRIu64 ".%" PRIu64 "%s", t / table[i].factor, ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10), table[i].suffix); goto finish; } } snprintf(buf, l, "%" PRIu64 "B", t); finish: buf[l-1] = 0; return buf; }
static int fake_filesystems(void) { static const struct fakefs { const char *src; const char *target; const char *error; } fakefss[] = { { "test/sys", "/sys", "failed to mount test /sys" }, { "test/dev", "/dev", "failed to mount test /dev" }, { "test/run", UDEV_ROOT_RUN, "failed to mount test " UDEV_ROOT_RUN }, { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" }, { "test/run", "/lib/udev/rules.d", "failed to mount empty /lib/udev/rules.d" }, }; unsigned int i; int err; err = unshare(CLONE_NEWNS); if (err < 0) { err = -errno; fprintf(stderr, "failed to call unshare(): %m\n"); goto out; } if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) { err = -errno; fprintf(stderr, "failed to mount / as private: %m\n"); goto out; } for (i = 0; i < ELEMENTSOF(fakefss); i++) { err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL); if (err < 0) { err = -errno; fprintf(stderr, "%s %m", fakefss[i].error); return err; } } out: return err; }
static int list_homes(void) { uint64_t i = 0; int r = 0; for (i = 0; i < ELEMENTSOF(path_table); i++) { _cleanup_free_ char *p = NULL; int q; q = sd_path_home(i, arg_suffix, &p); if (q == -ENXIO) continue; if (q < 0) { log_error("Failed to query %s: %s", path_table[i], strerror(-r)); r = q; continue; } printf("%s: %s\n", path_table[i], p); } return r; }
int mac_selinux_init(const char *prefix) { int r = 0; #ifdef HAVE_SELINUX usec_t before_timestamp, after_timestamp; struct mallinfo before_mallinfo, after_mallinfo; if (!mac_selinux_use()) return 0; if (label_hnd) return 0; before_mallinfo = mallinfo(); before_timestamp = now(CLOCK_MONOTONIC); if (prefix) { struct selinux_opt options[] = { { .type = SELABEL_OPT_SUBSET, .value = prefix }, }; label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options)); } else