+ ret = mmap_full_file(cf, O_RDONLY, &map, &sz, NULL);
+ if (ret < 0) {
+ if (ret != -E_EMPTY && ret != -ERRNO_TO_PARA_ERROR(ENOENT))
+ goto free_cf;
+ if (ret == -ERRNO_TO_PARA_ERROR(ENOENT) && OPT_GIVEN(CONFIG_FILE))
+ goto free_cf;
+ } else {
+ int cf_argc;
+ char **cf_argv;
+ struct lls_parse_result *cf_lpr, *merged_lpr;
+ ret = lls(lls_convert_config(map, sz, NULL, &cf_argv, &errctx));
+ para_munmap(map, sz);
+ if (ret < 0)
+ goto free_cf;
+ cf_argc = ret;
+ ret = lls(lls_parse(cf_argc, cf_argv, CMD_PTR, &cf_lpr, &errctx));
+ lls_free_argv(cf_argv);
+ if (ret < 0)
+ goto free_cf;
+ ret = lls(lls_merge(lpr, cf_lpr, CMD_PTR, &merged_lpr,
+ &errctx));
+ lls_free_parse_result(cf_lpr, CMD_PTR);
+ if (ret < 0)
+ goto free_cf;
+ lls_free_parse_result(lpr, CMD_PTR);
+ lpr = merged_lpr;
+ }
+ daemon_set_loglevel(ENUM_STRING_VAL(LOGLEVEL));
+ if (OPT_GIVEN(USER_ALLOW)) {
+ uint32_t n = OPT_GIVEN(USER_ALLOW);
+ int i;
+
+ uid_whitelist = para_malloc(n * sizeof(uid_t));
+ for (i = 0; i < n; i++) {
+ const char *arg = lls_string_val(i,
+ OPT_RESULT(USER_ALLOW));
+ int32_t val;
+ struct passwd *pw;
+ ret = para_atoi32(arg, &val);
+ if (ret >= 0) {
+ uid_whitelist[i] = val;
+ continue;
+ }
+ errno = 0; /* see getpwnam(3) */
+ pw = getpwnam(arg);
+ if (!pw) {
+ PARA_EMERG_LOG("invalid username: %s\n", arg);
+ free(uid_whitelist);
+ goto free_cf;
+ }
+ uid_whitelist[i] = pw->pw_uid;
+ }