int write_env_file(const char *fname, char **l) { char **i; _cleanup_free_ char *p = NULL; _cleanup_fclose_ FILE *f = NULL; int r; r = fopen_temporary(fname, &f, &p); if (r < 0) return r; fchmod_umask(fileno(f), 0644); errno = 0; STRV_FOREACH(i, l) write_env_var(f, *i); fflush(f); if (ferror(f)) r = errno ? -errno : -EIO; else { if (rename(p, fname) < 0) r = -errno; else r = 0; } if (r < 0) unlink(p); return r; }
static int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) { char _cleanup_strv_free_ **l = NULL; char **i; keymaps = set_new(string_hash_func, string_compare_func); if (!keymaps) return log_oom(); nftw("/usr/share/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); nftw("/usr/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); nftw("/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS); l = set_get_strv(keymaps); if (!l) { set_free_free(keymaps); return log_oom(); } set_free(keymaps); if (strv_isempty(l)) { log_error("Couldn't find any console keymaps."); return -ENOENT; } strv_sort(l); pager_open_if_enabled(); STRV_FOREACH(i, l) puts(*i); return 0; }
static void print_status_info(StatusInfo *i) { assert(i); if (strv_isempty(i->locale)) puts(" System Locale: n/a\n"); else { char **j; printf(" System Locale: %s\n", i->locale[0]); STRV_FOREACH(j, i->locale + 1) printf(" %s\n", *j); } printf(" VC Keymap: %s\n", strna(i->vconsole_keymap)); if (!isempty(i->vconsole_keymap_toggle)) printf("VC Toggle Keymap: %s\n", i->vconsole_keymap_toggle); printf(" X11 Layout: %s\n", strna(i->x11_layout)); if (!isempty(i->x11_model)) printf(" X11 Model: %s\n", i->x11_model); if (!isempty(i->x11_variant)) printf(" X11 Variant: %s\n", i->x11_variant); if (!isempty(i->x11_options)) printf(" X11 Options: %s\n", i->x11_options); }
int write_env_file(const char *fname, char **l) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; char **i; int r; assert(fname); r = fopen_temporary(fname, &f, &p); if (r < 0) return r; fchmod_umask(fileno(f), 0644); STRV_FOREACH(i, l) write_env_var(f, *i); r = fflush_and_check(f); if (r >= 0) { if (rename(p, fname) >= 0) return 0; r = -errno; } unlink(p); return r; }
static void test_get_timezones(void) { _cleanup_strv_free_ char **zones = NULL; int r; char **zone; log_info("/* %s */", __func__); r = get_timezones(&zones); assert_se(r == 0); STRV_FOREACH(zone, zones) assert_se(timezone_is_valid(*zone, LOG_ERR)); }
static void list_modes(struct rtcwake_control *ctl) { size_t i; char **modes = get_sys_power_states(ctl), **m; if (!modes) errx(EXIT_FAILURE, _("could not read: %s"), SYS_POWER_STATE_PATH); STRV_FOREACH(m, modes) printf("%s ", *m); for (i = 0; i < ARRAY_SIZE(rtcwake_mode_string); i++) printf("%s ", rtcwake_mode_string[i]); putchar('\n'); }
static void test_strv_unquote(const char *quoted, char **list) { _cleanup_strv_free_ char **s; _cleanup_free_ char *j; unsigned i = 0; char **t; int r; r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES); assert_se(r == (int) strv_length(list)); assert_se(s); j = strv_join(s, " | "); assert_se(j); puts(j); STRV_FOREACH(t, s) assert_se(streq(list[i++], *t)); assert_se(list[i] == NULL); }
static void test_parse_env_file(void) { char t[] = "/tmp/test-fileio-in-XXXXXX", p[] = "/tmp/test-fileio-out-XXXXXX"; int fd, r; FILE *f; _cleanup_free_ char *one = NULL, *two = NULL, *three = NULL, *four = NULL, *five = NULL, *six = NULL, *seven = NULL, *eight = NULL, *nine = NULL, *ten = NULL; _cleanup_strv_free_ char **a = NULL, **b = NULL; char **i; unsigned k; fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC); assert_se(fd >= 0); close(fd); fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC); assert_se(fd >= 0); f = fdopen(fd, "w"); assert_se(f); fputs("one=BAR \n" "# comment\n" " # comment \n" " ; comment \n" " two = bar \n" "invalid line\n" "invalid line #comment\n" "three = \"333\n" "xxxx\"\n" "four = \'44\\\"44\'\n" "five = \'55\\\'55\' \"FIVE\" cinco \n" "six = seis sechs\\\n" " sis\n" "seven=\"sevenval\" #nocomment\n" "eight=eightval #nocomment\n" "export nine=nineval\n" "ten=", f); fflush(f); fclose(f); r = load_env_file(t, NULL, &a); assert_se(r >= 0); STRV_FOREACH(i, a) log_info("Got: <%s>", *i); assert_se(streq_ptr(a[0], "one=BAR")); assert_se(streq_ptr(a[1], "two=bar")); assert_se(streq_ptr(a[2], "three=333\nxxxx")); assert_se(streq_ptr(a[3], "four=44\"44")); assert_se(streq_ptr(a[4], "five=55\'55FIVEcinco")); assert_se(streq_ptr(a[5], "six=seis sechs sis")); assert_se(streq_ptr(a[6], "seven=sevenval#nocomment")); assert_se(streq_ptr(a[7], "eight=eightval #nocomment")); assert_se(streq_ptr(a[8], "export nine=nineval")); assert_se(streq_ptr(a[9], "ten=")); assert_se(a[10] == NULL); strv_env_clean_log(a, "test"); k = 0; STRV_FOREACH(i, b) { log_info("Got2: <%s>", *i); assert_se(streq(*i, a[k++])); }
static int list_locales(DBusConnection *bus, char **args, unsigned n) { /* Stolen from glibc... */ struct locarhead { uint32_t magic; /* Serial number. */ uint32_t serial; /* Name hash table. */ uint32_t namehash_offset; uint32_t namehash_used; uint32_t namehash_size; /* String table. */ uint32_t string_offset; uint32_t string_used; uint32_t string_size; /* Table with locale records. */ uint32_t locrectab_offset; uint32_t locrectab_used; uint32_t locrectab_size; /* MD5 sum hash table. */ uint32_t sumhash_offset; uint32_t sumhash_used; uint32_t sumhash_size; }; struct namehashent { /* Hash value of the name. */ uint32_t hashval; /* Offset of the name in the string table. */ uint32_t name_offset; /* Offset of the locale record. */ uint32_t locrec_offset; }; const struct locarhead *h; const struct namehashent *e; const void *p = MAP_FAILED; _cleanup_close_ int fd = -1; _cleanup_strv_free_ char **l = NULL; char **j; Set *locales; size_t sz = 0; struct stat st; unsigned i; int r; locales = set_new(string_hash_func, string_compare_func); if (!locales) return log_oom(); fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC); if (fd < 0) { log_error("Failed to open locale archive: %m"); r = -errno; goto finish; } if (fstat(fd, &st) < 0) { log_error("fstat() failed: %m"); r = -errno; goto finish; } if (!S_ISREG(st.st_mode)) { log_error("Archive file is not regular"); r = -EBADMSG; goto finish; } if (st.st_size < (off_t) sizeof(struct locarhead)) { log_error("Archive has invalid size"); r = -EBADMSG; goto finish; } p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { log_error("Failed to map archive: %m"); r = -errno; goto finish; } h = (const struct locarhead *) p; if (h->magic != 0xde020109 || h->namehash_offset + h->namehash_size > st.st_size || h->string_offset + h->string_size > st.st_size || h->locrectab_offset + h->locrectab_size > st.st_size || h->sumhash_offset + h->sumhash_size > st.st_size) { log_error("Invalid archive file."); r = -EBADMSG; goto finish; } e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset); for (i = 0; i < h->namehash_size; i++) { char *z; if (e[i].locrec_offset == 0) continue; z = strdup((char*) p + e[i].name_offset); if (!z) { r = log_oom(); goto finish; } r = set_put(locales, z); if (r < 0) { free(z); log_error("Failed to add locale: %s", strerror(-r)); goto finish; } } l = set_get_strv(locales); if (!l) { r = log_oom(); goto finish; } set_free(locales); locales = NULL; strv_sort(l); pager_open_if_enabled(); STRV_FOREACH(j, l) puts(*j); r = 0; finish: if (p != MAP_FAILED) munmap((void*) p, sz); set_free_free(locales); return r; }
static int list_timezones(DBusConnection *bus, char **args, unsigned n) { _cleanup_fclose_ FILE *f = NULL; _cleanup_strv_free_ char **zones = NULL; size_t n_zones = 0; char **i; assert(args); assert(n == 1); f = fopen("/usr/share/zoneinfo/zone.tab", "re"); if (!f) { log_error("Failed to open timezone database: %m"); return -errno; } for (;;) { char l[LINE_MAX], *p, **z, *w; size_t k; if (!fgets(l, sizeof(l), f)) { if (feof(f)) break; log_error("Failed to read timezone database: %m"); return -errno; } p = strstrip(l); if (isempty(p) || *p == '#') continue; /* Skip over country code */ p += strcspn(p, WHITESPACE); p += strspn(p, WHITESPACE); /* Skip over coordinates */ p += strcspn(p, WHITESPACE); p += strspn(p, WHITESPACE); /* Found timezone name */ k = strcspn(p, WHITESPACE); if (k <= 0) continue; w = strndup(p, k); if (!w) return log_oom(); z = realloc(zones, sizeof(char*) * (n_zones + 2)); if (!z) { free(w); return log_oom(); } zones = z; zones[n_zones++] = w; } if (zones) zones[n_zones] = NULL; pager_open_if_enabled(); strv_sort(zones); STRV_FOREACH(i, zones) puts(*i); return 0; }