static int pkg_string(struct pkg *pkg, ucl_object_t *obj, int attr) { int ret = EPKG_OK; const char *str; str = ucl_object_tostring_forced(obj); switch (attr) { case PKG_LICENSE_LOGIC: if (!strcmp(str, "single")) pkg_set(pkg, PKG_LICENSE_LOGIC, (int64_t) LICENSE_SINGLE); else if (!strcmp(str, "or") || !strcmp(str, "dual")) pkg_set(pkg, PKG_LICENSE_LOGIC, (int64_t)LICENSE_OR); else if (!strcmp(str, "and") || !strcmp(str, "multi")) pkg_set(pkg, PKG_LICENSE_LOGIC, (int64_t)LICENSE_AND); else { pkg_emit_error("Unknown license logic: %s", str); ret = EPKG_FATAL; } break; default: if (attr == PKG_DESC) ret = urldecode(str, &pkg->fields[attr]); else ret = pkg_set(pkg, attr, str); break; } return (ret); }
void parse_conf(jail_conf_t *jail_conf, uint8_t *buf, size_t len) { struct ucl_parser *parser = ucl_parser_new(UCL_PARSER_NO_TIME); ucl_parser_add_chunk(parser, buf, len); if (ucl_parser_get_error(parser)) die("Config: Could not parse"); // TODO: output the error ucl_object_t *root = ucl_parser_get_object(parser); jail_conf->hostname = NULL; jail_conf->jailname = NULL; jail_conf->net_iface = NULL; jail_conf->script = NULL; jail_conf->securelevel = 3; jail_conf->devfs_ruleset = 4; bzero(jail_conf->ipv4, sizeof(jail_conf->ipv4)); bzero(jail_conf->ipv6, sizeof(jail_conf->ipv6)); bzero(jail_conf->limits, sizeof(jail_conf->limits)); bzero(jail_conf->mounts, sizeof(jail_conf->mounts)); ucl_iterate(root, true, ^(ucl_object_t *cur) { char *key = ucl_object_key(cur); if (strcmp(key, "hostname") == 0) { STR_TO_ARENA(jail_conf->hostname, ucl_object_tostring_forced(cur)); } else if (strcmp(key, "jailname") == 0) { STR_TO_ARENA(jail_conf->jailname, ucl_object_tostring_forced(cur)); } else if (strcmp(key, "script") == 0) { STR_TO_ARENA(jail_conf->script, ucl_object_tostring_forced(cur)); } else if (strcmp(key, "net_iface") == 0) { STR_TO_ARENA(jail_conf->net_iface, ucl_object_tostring_forced(cur)); } else if (strcmp(key, "securelevel") == 0) { int64_t int_val = -1; if (ucl_object_toint_safe(cur, &int_val) != true) die("Config: securelevel is not a number"); jail_conf->securelevel = (int8_t)int_val; } else if (strcmp(key, "devfs_ruleset") == 0) { int64_t int_val = -1; if (ucl_object_toint_safe(cur, &int_val) != true) die("Config: devfs_ruleset is not a number"); jail_conf->devfs_ruleset = (int16_t)int_val; } else if (strcmp(key, "ipv4") == 0) { __block size_t i = 0; ucl_iterate(cur, false, ^(ucl_object_t *val) { if (i > IPV4_ADDRS_LEN) die("Config: Too many IPv4 addresses"); STR_TO_ARENA(jail_conf->ipv4[i], ucl_object_tostring_forced(val)); i++; });
const char * pkg_object_string(const pkg_object *o) { const char *ret; if (o == NULL) return (NULL); ret = ucl_object_tostring_forced(o); if (ret && *ret == '\0') return (NULL); return (ret); }
static int pkg_set_files_from_object(struct pkg *pkg, ucl_object_t *obj) { ucl_object_t *cur; ucl_object_iter_t it = NULL; const char *sum = NULL; const char *uname = NULL; const char *gname = NULL; void *set = NULL; mode_t perm = 0; struct sbuf *fname = NULL; const char *key, *okey; okey = ucl_object_key(obj); if (okey == NULL) return (EPKG_FATAL); urldecode(okey, &fname); while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); if (key == NULL) continue; if (!strcasecmp(key, "uname") && cur->type == UCL_STRING) uname = ucl_object_tostring(cur); else if (!strcasecmp(key, "gname") && cur->type == UCL_STRING) gname = ucl_object_tostring(cur); else if (!strcasecmp(key, "sum") && cur->type == UCL_STRING && strlen(ucl_object_tostring(cur)) == 64) sum = ucl_object_tostring(cur); else if (!strcasecmp(key, "perm") && (cur->type == UCL_STRING || cur->type == UCL_INT)) { if ((set = setmode(ucl_object_tostring_forced(cur))) == NULL) pkg_emit_error("Not a valid mode: %s", ucl_object_tostring(cur)); else perm = getmode(set, 0); } else { pkg_emit_error("Skipping unknown key for file(%s): %s", sbuf_data(fname), ucl_object_tostring(cur)); } } pkg_addfile_attr(pkg, sbuf_data(fname), sum, uname, gname, perm, false); sbuf_delete(fname); return (EPKG_OK); }
static gint lua_statfile_get_param (lua_State *L) { struct rspamd_statfile_config *st = lua_check_statfile (L); const gchar *param; const ucl_object_t *value; param = luaL_checkstring (L, 2); if (st != NULL && param != NULL) { value = ucl_object_lookup (st->opts, param); if (value != NULL) { lua_pushstring (L, ucl_object_tostring_forced (value)); return 1; } } lua_pushnil (L); return 1; }
static int pkg_set_dirs_from_object(struct pkg *pkg, ucl_object_t *obj) { ucl_object_t *cur; ucl_object_iter_t it = NULL; const char *uname = NULL; const char *gname = NULL; void *set; mode_t perm = 0; bool try = false; struct sbuf *dirname = NULL; const char *key, *okey; okey = ucl_object_key(obj); if (okey == NULL) return (EPKG_FATAL); urldecode(okey, &dirname); while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); if (key == NULL) continue; if (!strcasecmp(key, "uname") && cur->type == UCL_STRING) uname = ucl_object_tostring(cur); else if (!strcasecmp(key, "gname") && cur->type == UCL_STRING) gname = ucl_object_tostring(cur); else if (!strcasecmp(key, "perm") && (cur->type == UCL_STRING || cur->type == UCL_INT)) { if ((set = setmode(ucl_object_tostring_forced(cur))) == NULL) pkg_emit_error("Not a valid mode: %s", ucl_object_tostring(cur)); else perm = getmode(set, 0); } else if (!strcasecmp(key, "try") && cur->type == UCL_BOOLEAN) { try = ucl_object_toint(cur); } else { pkg_emit_error("Skipping unknown key for dir(%s): %s", sbuf_data(dirname), key); } }
int pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags) { struct ucl_parser *p = NULL; size_t i; const char *val = NULL; const char *buf, *walk, *value, *key, *k; const char *evkey = NULL; const char *nsname = NULL; const char *evpipe = NULL; const ucl_object_t *cur, *object; ucl_object_t *obj = NULL, *o, *ncfg; ucl_object_iter_t it = NULL; struct sbuf *ukey = NULL; bool fatal_errors = false; k = NULL; o = NULL; pkg_get_myarch(myabi, BUFSIZ); pkg_get_myarch_legacy(myabi_legacy, BUFSIZ); if (parsed != false) { pkg_emit_error("pkg_init() must only be called once"); return (EPKG_FATAL); } if (((flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4) && ((flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)) { pkg_emit_error("Invalid flags for pkg_init()"); return (EPKG_FATAL); } config = ucl_object_typed_new(UCL_OBJECT); for (i = 0; i < c_size; i++) { switch (c[i].type) { case PKG_STRING: obj = ucl_object_fromstring_common( c[i].def != NULL ? c[i].def : "", 0, UCL_STRING_TRIM); ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; case PKG_INT: ucl_object_insert_key(config, ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_INT), c[i].key, strlen(c[i].key), false); break; case PKG_BOOL: ucl_object_insert_key(config, ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_BOOLEAN), c[i].key, strlen(c[i].key), false); break; case PKG_OBJECT: obj = ucl_object_typed_new(UCL_OBJECT); if (c[i].def != NULL) { walk = buf = c[i].def; while ((buf = strchr(buf, ',')) != NULL) { key = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } ucl_object_insert_key(obj, ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM), key, value - key, false); buf++; walk = buf; } key = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } if (o == NULL) o = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM), key, value - key, false); } ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; case PKG_ARRAY: obj = ucl_object_typed_new(UCL_ARRAY); if (c[i].def != NULL) { walk = buf = c[i].def; while ((buf = strchr(buf, ',')) != NULL) { ucl_array_append(obj, ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM)); buf++; walk = buf; } ucl_array_append(obj, ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM)); } ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; } } if (path == NULL) path = PREFIX"/etc/pkg.conf"; p = ucl_parser_new(0); errno = 0; obj = NULL; if (!ucl_parser_add_file(p, path)) { if (errno != ENOENT) pkg_emit_error("Invalid configuration file: %s", ucl_parser_get_error(p)); } else { obj = ucl_parser_get_object(p); } ncfg = NULL; while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) { sbuf_init(&ukey); key = ucl_object_key(cur); for (i = 0; key[i] != '\0'; i++) sbuf_putc(ukey, toupper(key[i])); sbuf_finish(ukey); object = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey)); if (strncasecmp(sbuf_data(ukey), "PACKAGESITE", sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey), "PUBKEY", sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey), "MIRROR_TYPE", sbuf_len(ukey)) == 0) { pkg_emit_error("%s in pkg.conf is no longer " "supported. Convert to the new repository style." " See pkg.conf(5)", sbuf_data(ukey)); fatal_errors = true; continue; } /* ignore unknown keys */ if (object == NULL) continue; if (object->type != cur->type) { pkg_emit_error("Malformed key %s, ignoring", key); continue; } if (ncfg == NULL) ncfg = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(ncfg, ucl_object_copy(cur), sbuf_data(ukey), sbuf_len(ukey), true); } if (fatal_errors) { ucl_object_unref(ncfg); ucl_parser_free(p); return (EPKG_FATAL); } if (ncfg != NULL) { it = NULL; while (( cur = ucl_iterate_object(ncfg, &it, true))) { key = ucl_object_key(cur); ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true); } ucl_object_unref(ncfg); } ncfg = NULL; it = NULL; while ((cur = ucl_iterate_object(config, &it, true))) { o = NULL; key = ucl_object_key(cur); val = getenv(key); if (val == NULL) continue; switch (cur->type) { case UCL_STRING: o = ucl_object_fromstring_common(val, 0, UCL_STRING_TRIM); break; case UCL_INT: o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_INT); if (o->type != UCL_INT) { pkg_emit_error("Invalid type for environment " "variable %s, got %s, while expecting an integer", key, val); ucl_object_unref(o); continue; } break; case UCL_BOOLEAN: o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_BOOLEAN); if (o->type != UCL_BOOLEAN) { pkg_emit_error("Invalid type for environment " "variable %s, got %s, while expecting a boolean", key, val); ucl_object_unref(o); continue; } break; case UCL_OBJECT: o = ucl_object_typed_new(UCL_OBJECT); walk = buf = val; while ((buf = strchr(buf, ',')) != NULL) { k = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM), k, value - k, false); buf++; walk = buf; } key = walk; value = walk; while (*value != '\0') { if (*value == '=') break; value++; } ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM), k, value - k, false); break; case UCL_ARRAY: o = ucl_object_typed_new(UCL_ARRAY); walk = buf = val; while ((buf = strchr(buf, ',')) != NULL) { ucl_array_append(o, ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM)); buf++; walk = buf; } ucl_array_append(o, ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM)); break; default: /* ignore other types */ break; } if (o != NULL) { if (ncfg == NULL) ncfg = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(ncfg, o, key, strlen(key), true); } } if (ncfg != NULL) { it = NULL; while (( cur = ucl_iterate_object(ncfg, &it, true))) { key = ucl_object_key(cur); ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true); } ucl_object_unref(ncfg); } disable_plugins_if_static(); parsed = true; ucl_object_unref(obj); ucl_parser_free(p); if (strcmp(pkg_object_string(pkg_config_get("ABI")), "unknown") == 0) { pkg_emit_error("Unable to determine ABI"); return (EPKG_FATAL); } pkg_debug(1, "%s", "pkg initialized"); /* Start the event pipe */ evpipe = pkg_object_string(pkg_config_get("EVENT_PIPE")); if (evpipe != NULL) connect_evpipe(evpipe); debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL")); it = NULL; object = ucl_object_find_key(config, "PKG_ENV"); while ((cur = ucl_iterate_object(object, &it, true))) { evkey = ucl_object_key(cur); pkg_debug(1, "Setting env var: %s", evkey); if (evkey != NULL && evkey[0] != '\0') setenv(evkey, ucl_object_tostring_forced(cur), 1); } /* load the repositories */ load_repositories(reposdir, flags); setenv("HTTP_USER_AGENT", "pkg/"PKGVERSION, 1); /* bypass resolv.conf with specified NAMESERVER if any */ nsname = pkg_object_string(pkg_config_get("NAMESERVER")); if (nsname != NULL) set_nameserver(ucl_object_tostring_forced(o)); return (EPKG_OK); }
void ucl_obj_dump (const ucl_object_t *obj, unsigned int shift) { int num = shift * 4 + 5; char *pre = (char *) malloc (num * sizeof(char)); const ucl_object_t *cur, *tmp; ucl_object_iter_t it = NULL, it_obj = NULL; pre[--num] = 0x00; while (num--) pre[num] = 0x20; tmp = obj; while ((obj = ucl_iterate_object (tmp, &it, false))) { printf ("%sucl object address: %p\n", pre + 4, obj); if (obj->key != NULL) { printf ("%skey: \"%s\"\n", pre, ucl_object_key (obj)); } printf ("%sref: %u\n", pre, obj->ref); printf ("%slen: %u\n", pre, obj->len); printf ("%sprev: %p\n", pre, obj->prev); printf ("%snext: %p\n", pre, obj->next); if (obj->type == UCL_OBJECT) { printf ("%stype: UCL_OBJECT\n", pre); printf ("%svalue: %p\n", pre, obj->value.ov); it_obj = NULL; while ((cur = ucl_iterate_object (obj, &it_obj, true))) { ucl_obj_dump (cur, shift + 2); } } else if (obj->type == UCL_ARRAY) { printf ("%stype: UCL_ARRAY\n", pre); printf ("%svalue: %p\n", pre, obj->value.av); it_obj = NULL; while ((cur = ucl_iterate_object (obj, &it_obj, true))) { ucl_obj_dump (cur, shift + 2); } } else if (obj->type == UCL_INT) { printf ("%stype: UCL_INT\n", pre); printf ("%svalue: %jd\n", pre, (intmax_t)ucl_object_toint (obj)); } else if (obj->type == UCL_FLOAT) { printf ("%stype: UCL_FLOAT\n", pre); printf ("%svalue: %f\n", pre, ucl_object_todouble (obj)); } else if (obj->type == UCL_STRING) { printf ("%stype: UCL_STRING\n", pre); printf ("%svalue: \"%s\"\n", pre, ucl_object_tostring (obj)); } else if (obj->type == UCL_BOOLEAN) { printf ("%stype: UCL_BOOLEAN\n", pre); printf ("%svalue: %s\n", pre, ucl_object_tostring_forced (obj)); } else if (obj->type == UCL_TIME) { printf ("%stype: UCL_TIME\n", pre); printf ("%svalue: %f\n", pre, ucl_object_todouble (obj)); } else if (obj->type == UCL_USERDATA) { printf ("%stype: UCL_USERDATA\n", pre); printf ("%svalue: %p\n", pre, obj->value.ud); } } free (pre); }
static int pkg_object(struct pkg *pkg, ucl_object_t *obj, int attr) { struct sbuf *tmp = NULL; ucl_object_t *cur; ucl_object_iter_t it = NULL; pkg_script script_type; const char *key, *buf; size_t len; pkg_debug(3, "%s", "Manifest: parsing object"); while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); if (key == NULL) continue; switch (attr) { case PKG_DEPS: if (cur->type != UCL_OBJECT && cur->type != UCL_ARRAY) pkg_emit_error("Skipping malformed dependency %s", key); else pkg_set_deps_from_object(pkg, cur); break; case PKG_DIRS: if (cur->type != UCL_OBJECT) pkg_emit_error("Skipping malformed dirs %s", key); else pkg_set_dirs_from_object(pkg, cur); break; case PKG_USERS: if (cur->type == UCL_STRING) pkg_adduid(pkg, key, ucl_object_tostring(cur)); else pkg_emit_error("Skipping malformed users %s", key); break; case PKG_GROUPS: if (cur->type == UCL_STRING) pkg_addgid(pkg, key, ucl_object_tostring(cur)); else pkg_emit_error("Skipping malformed groups %s", key); break; case PKG_DIRECTORIES: if (cur->type == UCL_BOOLEAN) { urldecode(key, &tmp); pkg_adddir(pkg, sbuf_data(tmp), ucl_object_toboolean(cur), false); } else if (cur->type == UCL_OBJECT) { pkg_set_dirs_from_object(pkg, cur); } else if (cur->type == UCL_STRING) { urldecode(key, &tmp); if (ucl_object_tostring(cur)[0] == 'y') pkg_adddir(pkg, sbuf_data(tmp), 1, false); else pkg_adddir(pkg, sbuf_data(tmp), 0, false); } else { pkg_emit_error("Skipping malformed directories %s", key); } break; case PKG_FILES: if (cur->type == UCL_STRING) { buf = ucl_object_tolstring(cur, &len); urldecode(key, &tmp); pkg_addfile(pkg, sbuf_get(tmp), len == 64 ? buf : NULL, false); } else if (cur->type == UCL_OBJECT) pkg_set_files_from_object(pkg, cur); else pkg_emit_error("Skipping malformed files %s", key); break; case PKG_OPTIONS: if (cur->type != UCL_STRING && cur->type != UCL_BOOLEAN) pkg_emit_error("Skipping malformed option %s", key); else pkg_addoption(pkg, key, ucl_object_tostring_forced(cur)); break; case PKG_OPTION_DEFAULTS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed option default %s", key); else pkg_addoption_default(pkg, key, ucl_object_tostring(cur)); break; case PKG_OPTION_DESCRIPTIONS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed option description %s", key); else pkg_addoption_description(pkg, key, ucl_object_tostring(cur)); break; case PKG_SCRIPTS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed scripts %s", key); else { script_type = script_type_str(key); if (script_type == PKG_SCRIPT_UNKNOWN) { pkg_emit_error("Skipping unknown script " "type: %s", key); break; } urldecode(ucl_object_tostring(cur), &tmp); pkg_addscript(pkg, sbuf_data(tmp), script_type); } break; case PKG_ANNOTATIONS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed annotation %s", key); else pkg_addannotation(pkg, key, ucl_object_tostring(cur)); break; } } sbuf_free(tmp); return (EPKG_OK); }