19950eceeSBaptiste Daroussin /*- 2*1de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*1de7b4b8SPedro F. Giffuni * 40ad5dbacSBaptiste Daroussin * Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> 5f12db248SBryan Drewery * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org> 69950eceeSBaptiste Daroussin * All rights reserved. 79950eceeSBaptiste Daroussin * 89950eceeSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 99950eceeSBaptiste Daroussin * modification, are permitted provided that the following conditions 109950eceeSBaptiste Daroussin * are met: 119950eceeSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 129950eceeSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 139950eceeSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 149950eceeSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 159950eceeSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 169950eceeSBaptiste Daroussin * 179950eceeSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 189950eceeSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 199950eceeSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 209950eceeSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 219950eceeSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 229950eceeSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 239950eceeSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 249950eceeSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 259950eceeSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 269950eceeSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 279950eceeSBaptiste Daroussin * SUCH DAMAGE. 289950eceeSBaptiste Daroussin */ 299950eceeSBaptiste Daroussin 309950eceeSBaptiste Daroussin #include <sys/cdefs.h> 319950eceeSBaptiste Daroussin __FBSDID("$FreeBSD$"); 329950eceeSBaptiste Daroussin 339950eceeSBaptiste Daroussin #include <sys/param.h> 34a351c93dSBaptiste Daroussin #include <sys/queue.h> 359950eceeSBaptiste Daroussin #include <sys/sbuf.h> 3660b9a1fcSNathan Whitehorn #include <sys/utsname.h> 3760b9a1fcSNathan Whitehorn #include <sys/sysctl.h> 389950eceeSBaptiste Daroussin 39eb31a574SBryan Drewery #include <dirent.h> 408a7d859eSBaptiste Daroussin #include <ucl.h> 419950eceeSBaptiste Daroussin #include <err.h> 429950eceeSBaptiste Daroussin #include <errno.h> 439950eceeSBaptiste Daroussin #include <stdbool.h> 449950eceeSBaptiste Daroussin #include <unistd.h> 459950eceeSBaptiste Daroussin 469950eceeSBaptiste Daroussin #include "config.h" 479950eceeSBaptiste Daroussin 489950eceeSBaptiste Daroussin #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ 499950eceeSBaptiste Daroussin 50eb31a574SBryan Drewery struct config_value { 51eb31a574SBryan Drewery char *value; 52eb31a574SBryan Drewery STAILQ_ENTRY(config_value) next; 53eb31a574SBryan Drewery }; 54eb31a574SBryan Drewery 559950eceeSBaptiste Daroussin struct config_entry { 569950eceeSBaptiste Daroussin uint8_t type; 579950eceeSBaptiste Daroussin const char *key; 589950eceeSBaptiste Daroussin const char *val; 599950eceeSBaptiste Daroussin char *value; 60eb31a574SBryan Drewery STAILQ_HEAD(, config_value) *list; 619950eceeSBaptiste Daroussin bool envset; 6297c3a766SBryan Drewery bool main_only; /* Only set in pkg.conf. */ 639950eceeSBaptiste Daroussin }; 649950eceeSBaptiste Daroussin 659950eceeSBaptiste Daroussin static struct config_entry c[] = { 669950eceeSBaptiste Daroussin [PACKAGESITE] = { 679950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 689950eceeSBaptiste Daroussin "PACKAGESITE", 6962940ea9SBryan Drewery URL_SCHEME_PREFIX "http://pkg.FreeBSD.org/${ABI}/latest", 709950eceeSBaptiste Daroussin NULL, 71eb31a574SBryan Drewery NULL, 729950eceeSBaptiste Daroussin false, 7397c3a766SBryan Drewery false, 749950eceeSBaptiste Daroussin }, 759950eceeSBaptiste Daroussin [ABI] = { 769950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 779950eceeSBaptiste Daroussin "ABI", 789950eceeSBaptiste Daroussin NULL, 799950eceeSBaptiste Daroussin NULL, 80eb31a574SBryan Drewery NULL, 819950eceeSBaptiste Daroussin false, 8297c3a766SBryan Drewery true, 839950eceeSBaptiste Daroussin }, 849950eceeSBaptiste Daroussin [MIRROR_TYPE] = { 859950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 869950eceeSBaptiste Daroussin "MIRROR_TYPE", 879950eceeSBaptiste Daroussin "SRV", 889950eceeSBaptiste Daroussin NULL, 89eb31a574SBryan Drewery NULL, 909950eceeSBaptiste Daroussin false, 9197c3a766SBryan Drewery false, 929950eceeSBaptiste Daroussin }, 939950eceeSBaptiste Daroussin [ASSUME_ALWAYS_YES] = { 949950eceeSBaptiste Daroussin PKG_CONFIG_BOOL, 959950eceeSBaptiste Daroussin "ASSUME_ALWAYS_YES", 969950eceeSBaptiste Daroussin "NO", 979950eceeSBaptiste Daroussin NULL, 98eb31a574SBryan Drewery NULL, 999950eceeSBaptiste Daroussin false, 10097c3a766SBryan Drewery true, 101f12db248SBryan Drewery }, 102f12db248SBryan Drewery [SIGNATURE_TYPE] = { 103f12db248SBryan Drewery PKG_CONFIG_STRING, 104f12db248SBryan Drewery "SIGNATURE_TYPE", 105f12db248SBryan Drewery NULL, 106f12db248SBryan Drewery NULL, 107eb31a574SBryan Drewery NULL, 108f12db248SBryan Drewery false, 10997c3a766SBryan Drewery false, 110f12db248SBryan Drewery }, 111f12db248SBryan Drewery [FINGERPRINTS] = { 112f12db248SBryan Drewery PKG_CONFIG_STRING, 113f12db248SBryan Drewery "FINGERPRINTS", 114f12db248SBryan Drewery NULL, 115f12db248SBryan Drewery NULL, 116eb31a574SBryan Drewery NULL, 117eb31a574SBryan Drewery false, 11897c3a766SBryan Drewery false, 119eb31a574SBryan Drewery }, 120eb31a574SBryan Drewery [REPOS_DIR] = { 121eb31a574SBryan Drewery PKG_CONFIG_LIST, 122eb31a574SBryan Drewery "REPOS_DIR", 123eb31a574SBryan Drewery NULL, 124eb31a574SBryan Drewery NULL, 125eb31a574SBryan Drewery NULL, 126f12db248SBryan Drewery false, 12797c3a766SBryan Drewery true, 128f12db248SBryan Drewery }, 12961acb458SBaptiste Daroussin [PUBKEY] = { 13061acb458SBaptiste Daroussin PKG_CONFIG_STRING, 13161acb458SBaptiste Daroussin "PUBKEY", 13261acb458SBaptiste Daroussin NULL, 13361acb458SBaptiste Daroussin NULL, 13461acb458SBaptiste Daroussin NULL, 13561acb458SBaptiste Daroussin false, 13661acb458SBaptiste Daroussin false 13761acb458SBaptiste Daroussin } 1389950eceeSBaptiste Daroussin }; 1399950eceeSBaptiste Daroussin 1409950eceeSBaptiste Daroussin static int 1419950eceeSBaptiste Daroussin pkg_get_myabi(char *dest, size_t sz) 1429950eceeSBaptiste Daroussin { 14360b9a1fcSNathan Whitehorn struct utsname uts; 14460b9a1fcSNathan Whitehorn char machine_arch[255]; 14560b9a1fcSNathan Whitehorn size_t len; 14660b9a1fcSNathan Whitehorn int error; 1479950eceeSBaptiste Daroussin 14860b9a1fcSNathan Whitehorn error = uname(&uts); 14960b9a1fcSNathan Whitehorn if (error) 15060b9a1fcSNathan Whitehorn return (errno); 1519950eceeSBaptiste Daroussin 15260b9a1fcSNathan Whitehorn len = sizeof(machine_arch); 15360b9a1fcSNathan Whitehorn error = sysctlbyname("hw.machine_arch", machine_arch, &len, NULL, 0); 15460b9a1fcSNathan Whitehorn if (error) 15560b9a1fcSNathan Whitehorn return (errno); 15660b9a1fcSNathan Whitehorn machine_arch[len] = '\0'; 1579950eceeSBaptiste Daroussin 15840274a2dSBaptiste Daroussin /* 15960b9a1fcSNathan Whitehorn * Use __FreeBSD_version rather than kernel version (uts.release) for 16060b9a1fcSNathan Whitehorn * use in jails. This is equivalent to the value of uname -U. 16140274a2dSBaptiste Daroussin */ 16260b9a1fcSNathan Whitehorn snprintf(dest, sz, "%s:%d:%s", uts.sysname, __FreeBSD_version/100000, 16360b9a1fcSNathan Whitehorn machine_arch); 16440274a2dSBaptiste Daroussin 16560b9a1fcSNathan Whitehorn return (error); 1669950eceeSBaptiste Daroussin } 1679950eceeSBaptiste Daroussin 1689950eceeSBaptiste Daroussin static void 1699950eceeSBaptiste Daroussin subst_packagesite(const char *abi) 1709950eceeSBaptiste Daroussin { 1719950eceeSBaptiste Daroussin struct sbuf *newval; 1729950eceeSBaptiste Daroussin const char *variable_string; 1739950eceeSBaptiste Daroussin const char *oldval; 1749950eceeSBaptiste Daroussin 1759950eceeSBaptiste Daroussin if (c[PACKAGESITE].value != NULL) 1769950eceeSBaptiste Daroussin oldval = c[PACKAGESITE].value; 1779950eceeSBaptiste Daroussin else 1789950eceeSBaptiste Daroussin oldval = c[PACKAGESITE].val; 1799950eceeSBaptiste Daroussin 1809950eceeSBaptiste Daroussin if ((variable_string = strstr(oldval, "${ABI}")) == NULL) 1819950eceeSBaptiste Daroussin return; 1829950eceeSBaptiste Daroussin 1839950eceeSBaptiste Daroussin newval = sbuf_new_auto(); 1849950eceeSBaptiste Daroussin sbuf_bcat(newval, oldval, variable_string - oldval); 1859950eceeSBaptiste Daroussin sbuf_cat(newval, abi); 1869950eceeSBaptiste Daroussin sbuf_cat(newval, variable_string + strlen("${ABI}")); 1879950eceeSBaptiste Daroussin sbuf_finish(newval); 1889950eceeSBaptiste Daroussin 1899950eceeSBaptiste Daroussin free(c[PACKAGESITE].value); 1909950eceeSBaptiste Daroussin c[PACKAGESITE].value = strdup(sbuf_data(newval)); 1919950eceeSBaptiste Daroussin } 1929950eceeSBaptiste Daroussin 193eb31a574SBryan Drewery static int 194eb31a574SBryan Drewery boolstr_to_bool(const char *str) 195eb31a574SBryan Drewery { 196eb31a574SBryan Drewery if (str != NULL && (strcasecmp(str, "true") == 0 || 197eb31a574SBryan Drewery strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0 || 198eb31a574SBryan Drewery str[0] == '1')) 199eb31a574SBryan Drewery return (true); 200eb31a574SBryan Drewery 201eb31a574SBryan Drewery return (false); 202eb31a574SBryan Drewery } 203eb31a574SBryan Drewery 2049950eceeSBaptiste Daroussin static void 205b04a7a0bSBaptiste Daroussin config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype) 2069950eceeSBaptiste Daroussin { 2079950eceeSBaptiste Daroussin struct sbuf *buf = sbuf_new_auto(); 208b04a7a0bSBaptiste Daroussin const ucl_object_t *cur, *seq; 2098a7d859eSBaptiste Daroussin ucl_object_iter_t it = NULL, itseq = NULL; 210eb31a574SBryan Drewery struct config_entry *temp_config; 211eb31a574SBryan Drewery struct config_value *cv; 2128a7d859eSBaptiste Daroussin const char *key; 2139950eceeSBaptiste Daroussin int i; 2149950eceeSBaptiste Daroussin size_t j; 2159950eceeSBaptiste Daroussin 216eb31a574SBryan Drewery /* Temporary config for configs that may be disabled. */ 217eb31a574SBryan Drewery temp_config = calloc(CONFIG_SIZE, sizeof(struct config_entry)); 218eb31a574SBryan Drewery 2198a7d859eSBaptiste Daroussin while ((cur = ucl_iterate_object(obj, &it, true))) { 2208a7d859eSBaptiste Daroussin key = ucl_object_key(cur); 2218a7d859eSBaptiste Daroussin if (key == NULL) 2229950eceeSBaptiste Daroussin continue; 2239950eceeSBaptiste Daroussin sbuf_clear(buf); 2249950eceeSBaptiste Daroussin 225bc5e9ac0SBryan Drewery if (conftype == CONFFILE_PKG) { 2268a7d859eSBaptiste Daroussin for (j = 0; j < strlen(key); ++j) 2278a7d859eSBaptiste Daroussin sbuf_putc(buf, key[j]); 2289950eceeSBaptiste Daroussin sbuf_finish(buf); 229bc5e9ac0SBryan Drewery } else if (conftype == CONFFILE_REPO) { 2308a7d859eSBaptiste Daroussin if (strcasecmp(key, "url") == 0) 231bc5e9ac0SBryan Drewery sbuf_cpy(buf, "PACKAGESITE"); 2328a7d859eSBaptiste Daroussin else if (strcasecmp(key, "mirror_type") == 0) 233bc5e9ac0SBryan Drewery sbuf_cpy(buf, "MIRROR_TYPE"); 2348a7d859eSBaptiste Daroussin else if (strcasecmp(key, "signature_type") == 0) 235f12db248SBryan Drewery sbuf_cpy(buf, "SIGNATURE_TYPE"); 2368a7d859eSBaptiste Daroussin else if (strcasecmp(key, "fingerprints") == 0) 237f12db248SBryan Drewery sbuf_cpy(buf, "FINGERPRINTS"); 23861acb458SBaptiste Daroussin else if (strcasecmp(key, "pubkey") == 0) 23961acb458SBaptiste Daroussin sbuf_cpy(buf, "PUBKEY"); 2408a7d859eSBaptiste Daroussin else if (strcasecmp(key, "enabled") == 0) { 2418a7d859eSBaptiste Daroussin if ((cur->type != UCL_BOOLEAN) || 2428a7d859eSBaptiste Daroussin !ucl_object_toboolean(cur)) 243eb31a574SBryan Drewery goto cleanup; 2448a7d859eSBaptiste Daroussin } else 245bc5e9ac0SBryan Drewery continue; 246bc5e9ac0SBryan Drewery sbuf_finish(buf); 247bc5e9ac0SBryan Drewery } 248bc5e9ac0SBryan Drewery 2499950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 2509950eceeSBaptiste Daroussin if (strcmp(sbuf_data(buf), c[i].key) == 0) 2519950eceeSBaptiste Daroussin break; 2529950eceeSBaptiste Daroussin } 2539950eceeSBaptiste Daroussin 254bc5e9ac0SBryan Drewery /* Silently skip unknown keys to be future compatible. */ 2558a7d859eSBaptiste Daroussin if (i == CONFIG_SIZE) 2569950eceeSBaptiste Daroussin continue; 2579950eceeSBaptiste Daroussin 2589950eceeSBaptiste Daroussin /* env has priority over config file */ 2598a7d859eSBaptiste Daroussin if (c[i].envset) 2609950eceeSBaptiste Daroussin continue; 2619950eceeSBaptiste Daroussin 262eb31a574SBryan Drewery /* Parse sequence value ["item1", "item2"] */ 263eb31a574SBryan Drewery switch (c[i].type) { 264eb31a574SBryan Drewery case PKG_CONFIG_LIST: 2658a7d859eSBaptiste Daroussin if (cur->type != UCL_ARRAY) { 2668a7d859eSBaptiste Daroussin warnx("Skipping invalid array " 267eb31a574SBryan Drewery "value for %s.\n", c[i].key); 268eb31a574SBryan Drewery continue; 269eb31a574SBryan Drewery } 270eb31a574SBryan Drewery temp_config[i].list = 271eb31a574SBryan Drewery malloc(sizeof(*temp_config[i].list)); 272eb31a574SBryan Drewery STAILQ_INIT(temp_config[i].list); 273eb31a574SBryan Drewery 2748a7d859eSBaptiste Daroussin while ((seq = ucl_iterate_object(cur, &itseq, true))) { 2758a7d859eSBaptiste Daroussin if (seq->type != UCL_STRING) 276eb31a574SBryan Drewery continue; 277eb31a574SBryan Drewery cv = malloc(sizeof(struct config_value)); 278eb31a574SBryan Drewery cv->value = 2798a7d859eSBaptiste Daroussin strdup(ucl_object_tostring(seq)); 280eb31a574SBryan Drewery STAILQ_INSERT_TAIL(temp_config[i].list, cv, 281eb31a574SBryan Drewery next); 282eb31a574SBryan Drewery } 283eb31a574SBryan Drewery break; 284197372c2SBryan Drewery case PKG_CONFIG_BOOL: 285197372c2SBryan Drewery temp_config[i].value = 286197372c2SBryan Drewery strdup(ucl_object_toboolean(cur) ? "yes" : "no"); 287197372c2SBryan Drewery break; 288eb31a574SBryan Drewery default: 289eb31a574SBryan Drewery /* Normal string value. */ 2908a7d859eSBaptiste Daroussin temp_config[i].value = strdup(ucl_object_tostring(cur)); 291eb31a574SBryan Drewery break; 292eb31a574SBryan Drewery } 2939950eceeSBaptiste Daroussin } 2949950eceeSBaptiste Daroussin 295eb31a574SBryan Drewery /* Repo is enabled, copy over all settings from temp_config. */ 296eb31a574SBryan Drewery for (i = 0; i < CONFIG_SIZE; i++) { 297eb31a574SBryan Drewery if (c[i].envset) 298eb31a574SBryan Drewery continue; 29997c3a766SBryan Drewery /* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */ 30097c3a766SBryan Drewery if (conftype != CONFFILE_PKG && c[i].main_only == true) 30197c3a766SBryan Drewery continue; 302eb31a574SBryan Drewery switch (c[i].type) { 303eb31a574SBryan Drewery case PKG_CONFIG_LIST: 304eb31a574SBryan Drewery c[i].list = temp_config[i].list; 305eb31a574SBryan Drewery break; 306eb31a574SBryan Drewery default: 307eb31a574SBryan Drewery c[i].value = temp_config[i].value; 308eb31a574SBryan Drewery break; 309eb31a574SBryan Drewery } 310eb31a574SBryan Drewery } 311eb31a574SBryan Drewery 312eb31a574SBryan Drewery cleanup: 313eb31a574SBryan Drewery free(temp_config); 3149950eceeSBaptiste Daroussin sbuf_delete(buf); 3159950eceeSBaptiste Daroussin } 3169950eceeSBaptiste Daroussin 317bc5e9ac0SBryan Drewery /*- 318bc5e9ac0SBryan Drewery * Parse new repo style configs in style: 319bc5e9ac0SBryan Drewery * Name: 320bc5e9ac0SBryan Drewery * URL: 321bc5e9ac0SBryan Drewery * MIRROR_TYPE: 322bc5e9ac0SBryan Drewery * etc... 323bc5e9ac0SBryan Drewery */ 324bc5e9ac0SBryan Drewery static void 3258a7d859eSBaptiste Daroussin parse_repo_file(ucl_object_t *obj) 326bc5e9ac0SBryan Drewery { 3278a7d859eSBaptiste Daroussin ucl_object_iter_t it = NULL; 328b04a7a0bSBaptiste Daroussin const ucl_object_t *cur; 3298a7d859eSBaptiste Daroussin const char *key; 330bc5e9ac0SBryan Drewery 3318a7d859eSBaptiste Daroussin while ((cur = ucl_iterate_object(obj, &it, true))) { 3328a7d859eSBaptiste Daroussin key = ucl_object_key(cur); 333bc5e9ac0SBryan Drewery 3348a7d859eSBaptiste Daroussin if (key == NULL) 335bc5e9ac0SBryan Drewery continue; 336bc5e9ac0SBryan Drewery 3378a7d859eSBaptiste Daroussin if (cur->type != UCL_OBJECT) 338bc5e9ac0SBryan Drewery continue; 339bc5e9ac0SBryan Drewery 3408a7d859eSBaptiste Daroussin config_parse(cur, CONFFILE_REPO); 341bc5e9ac0SBryan Drewery } 342bc5e9ac0SBryan Drewery } 343bc5e9ac0SBryan Drewery 344bc5e9ac0SBryan Drewery 345bc5e9ac0SBryan Drewery static int 346bc5e9ac0SBryan Drewery read_conf_file(const char *confpath, pkg_conf_file_t conftype) 3479950eceeSBaptiste Daroussin { 3488a7d859eSBaptiste Daroussin struct ucl_parser *p; 3498a7d859eSBaptiste Daroussin ucl_object_t *obj = NULL; 350bc5e9ac0SBryan Drewery 3518a7d859eSBaptiste Daroussin p = ucl_parser_new(0); 3528a7d859eSBaptiste Daroussin 3538a7d859eSBaptiste Daroussin if (!ucl_parser_add_file(p, confpath)) { 354bc5e9ac0SBryan Drewery if (errno != ENOENT) 3558a7d859eSBaptiste Daroussin errx(EXIT_FAILURE, "Unable to parse configuration " 3568a7d859eSBaptiste Daroussin "file %s: %s", confpath, ucl_parser_get_error(p)); 3578a7d859eSBaptiste Daroussin ucl_parser_free(p); 358bc5e9ac0SBryan Drewery /* no configuration present */ 359bc5e9ac0SBryan Drewery return (1); 360bc5e9ac0SBryan Drewery } 361bc5e9ac0SBryan Drewery 3628a7d859eSBaptiste Daroussin obj = ucl_parser_get_object(p); 3638a7d859eSBaptiste Daroussin if (obj->type != UCL_OBJECT) 364bc5e9ac0SBryan Drewery warnx("Invalid configuration format, ignoring the " 365bc5e9ac0SBryan Drewery "configuration file %s", confpath); 366bc5e9ac0SBryan Drewery else { 367bc5e9ac0SBryan Drewery if (conftype == CONFFILE_PKG) 3688a7d859eSBaptiste Daroussin config_parse(obj, conftype); 369bc5e9ac0SBryan Drewery else if (conftype == CONFFILE_REPO) 3708a7d859eSBaptiste Daroussin parse_repo_file(obj); 371bc5e9ac0SBryan Drewery } 372bc5e9ac0SBryan Drewery 373b04a7a0bSBaptiste Daroussin ucl_object_unref(obj); 3748a7d859eSBaptiste Daroussin ucl_parser_free(p); 375bc5e9ac0SBryan Drewery 376bc5e9ac0SBryan Drewery return (0); 377bc5e9ac0SBryan Drewery } 378bc5e9ac0SBryan Drewery 379eb31a574SBryan Drewery static int 380eb31a574SBryan Drewery load_repositories(const char *repodir) 381eb31a574SBryan Drewery { 382eb31a574SBryan Drewery struct dirent *ent; 383eb31a574SBryan Drewery DIR *d; 384eb31a574SBryan Drewery char *p; 385eb31a574SBryan Drewery size_t n; 386eb31a574SBryan Drewery char path[MAXPATHLEN]; 387eb31a574SBryan Drewery int ret; 388eb31a574SBryan Drewery 389eb31a574SBryan Drewery ret = 0; 390eb31a574SBryan Drewery 391eb31a574SBryan Drewery if ((d = opendir(repodir)) == NULL) 392eb31a574SBryan Drewery return (1); 393eb31a574SBryan Drewery 394eb31a574SBryan Drewery while ((ent = readdir(d))) { 395eb31a574SBryan Drewery /* Trim out 'repos'. */ 396eb31a574SBryan Drewery if ((n = strlen(ent->d_name)) <= 5) 397eb31a574SBryan Drewery continue; 398eb31a574SBryan Drewery p = &ent->d_name[n - 5]; 399eb31a574SBryan Drewery if (strcmp(p, ".conf") == 0) { 400eb31a574SBryan Drewery snprintf(path, sizeof(path), "%s%s%s", 401eb31a574SBryan Drewery repodir, 402eb31a574SBryan Drewery repodir[strlen(repodir) - 1] == '/' ? "" : "/", 403eb31a574SBryan Drewery ent->d_name); 404eb31a574SBryan Drewery if (access(path, F_OK) == 0 && 405eb31a574SBryan Drewery read_conf_file(path, CONFFILE_REPO)) { 406eb31a574SBryan Drewery ret = 1; 407eb31a574SBryan Drewery goto cleanup; 408eb31a574SBryan Drewery } 409eb31a574SBryan Drewery } 410eb31a574SBryan Drewery } 411eb31a574SBryan Drewery 412eb31a574SBryan Drewery cleanup: 413eb31a574SBryan Drewery closedir(d); 414eb31a574SBryan Drewery 415eb31a574SBryan Drewery return (ret); 416eb31a574SBryan Drewery } 417eb31a574SBryan Drewery 418bc5e9ac0SBryan Drewery int 419bc5e9ac0SBryan Drewery config_init(void) 420bc5e9ac0SBryan Drewery { 421eb31a574SBryan Drewery char *val; 4229950eceeSBaptiste Daroussin int i; 4239950eceeSBaptiste Daroussin const char *localbase; 424eb31a574SBryan Drewery char *env_list_item; 4259950eceeSBaptiste Daroussin char confpath[MAXPATHLEN]; 426eb31a574SBryan Drewery struct config_value *cv; 4279950eceeSBaptiste Daroussin char abi[BUFSIZ]; 4289950eceeSBaptiste Daroussin 4299950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 4309950eceeSBaptiste Daroussin val = getenv(c[i].key); 4319950eceeSBaptiste Daroussin if (val != NULL) { 4329950eceeSBaptiste Daroussin c[i].envset = true; 433eb31a574SBryan Drewery switch (c[i].type) { 434eb31a574SBryan Drewery case PKG_CONFIG_LIST: 435eb31a574SBryan Drewery /* Split up comma-separated items from env. */ 436eb31a574SBryan Drewery c[i].list = malloc(sizeof(*c[i].list)); 437eb31a574SBryan Drewery STAILQ_INIT(c[i].list); 438eb31a574SBryan Drewery for (env_list_item = strtok(val, ","); 439eb31a574SBryan Drewery env_list_item != NULL; 440eb31a574SBryan Drewery env_list_item = strtok(NULL, ",")) { 441eb31a574SBryan Drewery cv = 442eb31a574SBryan Drewery malloc(sizeof(struct config_value)); 443eb31a574SBryan Drewery cv->value = 444eb31a574SBryan Drewery strdup(env_list_item); 445eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[i].list, cv, 446eb31a574SBryan Drewery next); 447eb31a574SBryan Drewery } 448eb31a574SBryan Drewery break; 449eb31a574SBryan Drewery default: 450eb31a574SBryan Drewery c[i].val = val; 451eb31a574SBryan Drewery break; 452eb31a574SBryan Drewery } 4539950eceeSBaptiste Daroussin } 4549950eceeSBaptiste Daroussin } 4559950eceeSBaptiste Daroussin 456eb31a574SBryan Drewery /* Read LOCALBASE/etc/pkg.conf first. */ 4579950eceeSBaptiste Daroussin localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE; 458bc5e9ac0SBryan Drewery snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", 459bc5e9ac0SBryan Drewery localbase); 4609950eceeSBaptiste Daroussin 461bc5e9ac0SBryan Drewery if (access(confpath, F_OK) == 0 && read_conf_file(confpath, 462bc5e9ac0SBryan Drewery CONFFILE_PKG)) 4639950eceeSBaptiste Daroussin goto finalize; 4649950eceeSBaptiste Daroussin 465eb31a574SBryan Drewery /* Then read in all repos from REPOS_DIR list of directories. */ 466eb31a574SBryan Drewery if (c[REPOS_DIR].list == NULL) { 467eb31a574SBryan Drewery c[REPOS_DIR].list = malloc(sizeof(*c[REPOS_DIR].list)); 468eb31a574SBryan Drewery STAILQ_INIT(c[REPOS_DIR].list); 469eb31a574SBryan Drewery cv = malloc(sizeof(struct config_value)); 470eb31a574SBryan Drewery cv->value = strdup("/etc/pkg"); 471eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[REPOS_DIR].list, cv, next); 472eb31a574SBryan Drewery cv = malloc(sizeof(struct config_value)); 473eb31a574SBryan Drewery if (asprintf(&cv->value, "%s/etc/pkg/repos", localbase) < 0) 474eb31a574SBryan Drewery goto finalize; 475eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[REPOS_DIR].list, cv, next); 476eb31a574SBryan Drewery } 477eb31a574SBryan Drewery 478eb31a574SBryan Drewery STAILQ_FOREACH(cv, c[REPOS_DIR].list, next) 479eb31a574SBryan Drewery if (load_repositories(cv->value)) 480bc5e9ac0SBryan Drewery goto finalize; 4819950eceeSBaptiste Daroussin 4829950eceeSBaptiste Daroussin finalize: 4839950eceeSBaptiste Daroussin if (c[ABI].val == NULL && c[ABI].value == NULL) { 4849950eceeSBaptiste Daroussin if (pkg_get_myabi(abi, BUFSIZ) != 0) 4854ff9a7efSBryan Drewery errx(EXIT_FAILURE, "Failed to determine the system " 4864ff9a7efSBryan Drewery "ABI"); 4879950eceeSBaptiste Daroussin c[ABI].val = abi; 4889950eceeSBaptiste Daroussin } 4899950eceeSBaptiste Daroussin 490d5bf8a8bSBaptiste Daroussin subst_packagesite(c[ABI].value != NULL ? c[ABI].value : c[ABI].val); 4919950eceeSBaptiste Daroussin 4929950eceeSBaptiste Daroussin return (0); 4939950eceeSBaptiste Daroussin } 4949950eceeSBaptiste Daroussin 4959950eceeSBaptiste Daroussin int 4969950eceeSBaptiste Daroussin config_string(pkg_config_key k, const char **val) 4979950eceeSBaptiste Daroussin { 4989950eceeSBaptiste Daroussin if (c[k].type != PKG_CONFIG_STRING) 4999950eceeSBaptiste Daroussin return (-1); 5009950eceeSBaptiste Daroussin 5019950eceeSBaptiste Daroussin if (c[k].value != NULL) 5029950eceeSBaptiste Daroussin *val = c[k].value; 5039950eceeSBaptiste Daroussin else 5049950eceeSBaptiste Daroussin *val = c[k].val; 5059950eceeSBaptiste Daroussin 5069950eceeSBaptiste Daroussin return (0); 5079950eceeSBaptiste Daroussin } 5089950eceeSBaptiste Daroussin 5099950eceeSBaptiste Daroussin int 5109950eceeSBaptiste Daroussin config_bool(pkg_config_key k, bool *val) 5119950eceeSBaptiste Daroussin { 5129950eceeSBaptiste Daroussin const char *value; 5139950eceeSBaptiste Daroussin 5149950eceeSBaptiste Daroussin if (c[k].type != PKG_CONFIG_BOOL) 5159950eceeSBaptiste Daroussin return (-1); 5169950eceeSBaptiste Daroussin 5179950eceeSBaptiste Daroussin *val = false; 5189950eceeSBaptiste Daroussin 5199950eceeSBaptiste Daroussin if (c[k].value != NULL) 5209950eceeSBaptiste Daroussin value = c[k].value; 5219950eceeSBaptiste Daroussin else 5229950eceeSBaptiste Daroussin value = c[k].val; 5239950eceeSBaptiste Daroussin 524eb31a574SBryan Drewery if (boolstr_to_bool(value)) 5259950eceeSBaptiste Daroussin *val = true; 5269950eceeSBaptiste Daroussin 5279950eceeSBaptiste Daroussin return (0); 5289950eceeSBaptiste Daroussin } 5299950eceeSBaptiste Daroussin 5309950eceeSBaptiste Daroussin void 5319950eceeSBaptiste Daroussin config_finish(void) { 5329950eceeSBaptiste Daroussin int i; 5339950eceeSBaptiste Daroussin 5349950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) 5359950eceeSBaptiste Daroussin free(c[i].value); 5369950eceeSBaptiste Daroussin } 537