19950eceeSBaptiste Daroussin /*- 21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 31de7b4b8SPedro 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> 3560b9a1fcSNathan Whitehorn #include <sys/utsname.h> 36ae659caaSBaptiste Daroussin #include <sys/sbuf.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> 4356d11d4aSStefan Eßer #include <libutil.h> 441f474190SStefan Eßer #include <paths.h> 459950eceeSBaptiste Daroussin #include <stdbool.h> 469950eceeSBaptiste Daroussin #include <unistd.h> 479950eceeSBaptiste Daroussin 489950eceeSBaptiste Daroussin #include "config.h" 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 { 171ae659caaSBaptiste Daroussin char *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 183ae659caaSBaptiste Daroussin asprintf(&newval, "%.*s%s%s", 184ae659caaSBaptiste Daroussin (int)(variable_string - oldval), oldval, abi, 185ae659caaSBaptiste Daroussin variable_string + strlen("${ABI}")); 186ae659caaSBaptiste Daroussin if (newval == NULL) 187ae659caaSBaptiste Daroussin errx(EXIT_FAILURE, "asprintf"); 1889950eceeSBaptiste Daroussin 1899950eceeSBaptiste Daroussin free(c[PACKAGESITE].value); 190ae659caaSBaptiste Daroussin c[PACKAGESITE].value = 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 325*18418e19SKyle Evans parse_repo_file(ucl_object_t *obj, const char *requested_repo) 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 340*18418e19SKyle Evans if (requested_repo != NULL && strcmp(requested_repo, key) != 0) 341*18418e19SKyle Evans continue; 342*18418e19SKyle Evans 3438a7d859eSBaptiste Daroussin config_parse(cur, CONFFILE_REPO); 344bc5e9ac0SBryan Drewery } 345bc5e9ac0SBryan Drewery } 346bc5e9ac0SBryan Drewery 347bc5e9ac0SBryan Drewery 348bc5e9ac0SBryan Drewery static int 349*18418e19SKyle Evans read_conf_file(const char *confpath, const char *requested_repo, 350*18418e19SKyle Evans pkg_conf_file_t conftype) 3519950eceeSBaptiste Daroussin { 3528a7d859eSBaptiste Daroussin struct ucl_parser *p; 3538a7d859eSBaptiste Daroussin ucl_object_t *obj = NULL; 354bc5e9ac0SBryan Drewery 3558a7d859eSBaptiste Daroussin p = ucl_parser_new(0); 3568a7d859eSBaptiste Daroussin 3578a7d859eSBaptiste Daroussin if (!ucl_parser_add_file(p, confpath)) { 358bc5e9ac0SBryan Drewery if (errno != ENOENT) 3598a7d859eSBaptiste Daroussin errx(EXIT_FAILURE, "Unable to parse configuration " 3608a7d859eSBaptiste Daroussin "file %s: %s", confpath, ucl_parser_get_error(p)); 3618a7d859eSBaptiste Daroussin ucl_parser_free(p); 362bc5e9ac0SBryan Drewery /* no configuration present */ 363bc5e9ac0SBryan Drewery return (1); 364bc5e9ac0SBryan Drewery } 365bc5e9ac0SBryan Drewery 3668a7d859eSBaptiste Daroussin obj = ucl_parser_get_object(p); 3678a7d859eSBaptiste Daroussin if (obj->type != UCL_OBJECT) 368bc5e9ac0SBryan Drewery warnx("Invalid configuration format, ignoring the " 369bc5e9ac0SBryan Drewery "configuration file %s", confpath); 370bc5e9ac0SBryan Drewery else { 371bc5e9ac0SBryan Drewery if (conftype == CONFFILE_PKG) 3728a7d859eSBaptiste Daroussin config_parse(obj, conftype); 373bc5e9ac0SBryan Drewery else if (conftype == CONFFILE_REPO) 374*18418e19SKyle Evans parse_repo_file(obj, requested_repo); 375bc5e9ac0SBryan Drewery } 376bc5e9ac0SBryan Drewery 377b04a7a0bSBaptiste Daroussin ucl_object_unref(obj); 3788a7d859eSBaptiste Daroussin ucl_parser_free(p); 379bc5e9ac0SBryan Drewery 380bc5e9ac0SBryan Drewery return (0); 381bc5e9ac0SBryan Drewery } 382bc5e9ac0SBryan Drewery 383eb31a574SBryan Drewery static int 384*18418e19SKyle Evans load_repositories(const char *repodir, const char *requested_repo) 385eb31a574SBryan Drewery { 386eb31a574SBryan Drewery struct dirent *ent; 387eb31a574SBryan Drewery DIR *d; 388eb31a574SBryan Drewery char *p; 389eb31a574SBryan Drewery size_t n; 390eb31a574SBryan Drewery char path[MAXPATHLEN]; 391eb31a574SBryan Drewery int ret; 392eb31a574SBryan Drewery 393eb31a574SBryan Drewery ret = 0; 394eb31a574SBryan Drewery 395eb31a574SBryan Drewery if ((d = opendir(repodir)) == NULL) 396eb31a574SBryan Drewery return (1); 397eb31a574SBryan Drewery 398eb31a574SBryan Drewery while ((ent = readdir(d))) { 399eb31a574SBryan Drewery /* Trim out 'repos'. */ 400eb31a574SBryan Drewery if ((n = strlen(ent->d_name)) <= 5) 401eb31a574SBryan Drewery continue; 402eb31a574SBryan Drewery p = &ent->d_name[n - 5]; 403eb31a574SBryan Drewery if (strcmp(p, ".conf") == 0) { 404eb31a574SBryan Drewery snprintf(path, sizeof(path), "%s%s%s", 405eb31a574SBryan Drewery repodir, 406eb31a574SBryan Drewery repodir[strlen(repodir) - 1] == '/' ? "" : "/", 407eb31a574SBryan Drewery ent->d_name); 408*18418e19SKyle Evans if (access(path, F_OK) != 0) 409*18418e19SKyle Evans continue; 410*18418e19SKyle Evans if (read_conf_file(path, requested_repo, 411*18418e19SKyle Evans CONFFILE_REPO)) { 412eb31a574SBryan Drewery ret = 1; 413eb31a574SBryan Drewery goto cleanup; 414eb31a574SBryan Drewery } 415eb31a574SBryan Drewery } 416eb31a574SBryan Drewery } 417eb31a574SBryan Drewery 418eb31a574SBryan Drewery cleanup: 419eb31a574SBryan Drewery closedir(d); 420eb31a574SBryan Drewery 421eb31a574SBryan Drewery return (ret); 422eb31a574SBryan Drewery } 423eb31a574SBryan Drewery 424bc5e9ac0SBryan Drewery int 425*18418e19SKyle Evans config_init(const char *requested_repo) 426bc5e9ac0SBryan Drewery { 427eb31a574SBryan Drewery char *val; 4289950eceeSBaptiste Daroussin int i; 4299950eceeSBaptiste Daroussin const char *localbase; 430eb31a574SBryan Drewery char *env_list_item; 4319950eceeSBaptiste Daroussin char confpath[MAXPATHLEN]; 432eb31a574SBryan Drewery struct config_value *cv; 4339950eceeSBaptiste Daroussin char abi[BUFSIZ]; 4349950eceeSBaptiste Daroussin 4359950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 4369950eceeSBaptiste Daroussin val = getenv(c[i].key); 4379950eceeSBaptiste Daroussin if (val != NULL) { 4389950eceeSBaptiste Daroussin c[i].envset = true; 439eb31a574SBryan Drewery switch (c[i].type) { 440eb31a574SBryan Drewery case PKG_CONFIG_LIST: 441eb31a574SBryan Drewery /* Split up comma-separated items from env. */ 442eb31a574SBryan Drewery c[i].list = malloc(sizeof(*c[i].list)); 443eb31a574SBryan Drewery STAILQ_INIT(c[i].list); 444eb31a574SBryan Drewery for (env_list_item = strtok(val, ","); 445eb31a574SBryan Drewery env_list_item != NULL; 446eb31a574SBryan Drewery env_list_item = strtok(NULL, ",")) { 447eb31a574SBryan Drewery cv = 448eb31a574SBryan Drewery malloc(sizeof(struct config_value)); 449eb31a574SBryan Drewery cv->value = 450eb31a574SBryan Drewery strdup(env_list_item); 451eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[i].list, cv, 452eb31a574SBryan Drewery next); 453eb31a574SBryan Drewery } 454eb31a574SBryan Drewery break; 455eb31a574SBryan Drewery default: 456eb31a574SBryan Drewery c[i].val = val; 457eb31a574SBryan Drewery break; 458eb31a574SBryan Drewery } 4599950eceeSBaptiste Daroussin } 4609950eceeSBaptiste Daroussin } 4619950eceeSBaptiste Daroussin 462eb31a574SBryan Drewery /* Read LOCALBASE/etc/pkg.conf first. */ 46356d11d4aSStefan Eßer localbase = getlocalbase(); 46456d11d4aSStefan Eßer snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", localbase); 4659950eceeSBaptiste Daroussin 466*18418e19SKyle Evans if (access(confpath, F_OK) == 0 && read_conf_file(confpath, NULL, 467bc5e9ac0SBryan Drewery CONFFILE_PKG)) 4689950eceeSBaptiste Daroussin goto finalize; 4699950eceeSBaptiste Daroussin 470eb31a574SBryan Drewery /* Then read in all repos from REPOS_DIR list of directories. */ 471eb31a574SBryan Drewery if (c[REPOS_DIR].list == NULL) { 472eb31a574SBryan Drewery c[REPOS_DIR].list = malloc(sizeof(*c[REPOS_DIR].list)); 473eb31a574SBryan Drewery STAILQ_INIT(c[REPOS_DIR].list); 474eb31a574SBryan Drewery cv = malloc(sizeof(struct config_value)); 475eb31a574SBryan Drewery cv->value = strdup("/etc/pkg"); 476eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[REPOS_DIR].list, cv, next); 477eb31a574SBryan Drewery cv = malloc(sizeof(struct config_value)); 478eb31a574SBryan Drewery if (asprintf(&cv->value, "%s/etc/pkg/repos", localbase) < 0) 479eb31a574SBryan Drewery goto finalize; 480eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[REPOS_DIR].list, cv, next); 481eb31a574SBryan Drewery } 482eb31a574SBryan Drewery 483eb31a574SBryan Drewery STAILQ_FOREACH(cv, c[REPOS_DIR].list, next) 484*18418e19SKyle Evans if (load_repositories(cv->value, requested_repo)) 485bc5e9ac0SBryan Drewery goto finalize; 4869950eceeSBaptiste Daroussin 4879950eceeSBaptiste Daroussin finalize: 4889950eceeSBaptiste Daroussin if (c[ABI].val == NULL && c[ABI].value == NULL) { 4899950eceeSBaptiste Daroussin if (pkg_get_myabi(abi, BUFSIZ) != 0) 4904ff9a7efSBryan Drewery errx(EXIT_FAILURE, "Failed to determine the system " 4914ff9a7efSBryan Drewery "ABI"); 4929950eceeSBaptiste Daroussin c[ABI].val = abi; 4939950eceeSBaptiste Daroussin } 4949950eceeSBaptiste Daroussin 495d5bf8a8bSBaptiste Daroussin subst_packagesite(c[ABI].value != NULL ? c[ABI].value : c[ABI].val); 4969950eceeSBaptiste Daroussin 4979950eceeSBaptiste Daroussin return (0); 4989950eceeSBaptiste Daroussin } 4999950eceeSBaptiste Daroussin 5009950eceeSBaptiste Daroussin int 5019950eceeSBaptiste Daroussin config_string(pkg_config_key k, const char **val) 5029950eceeSBaptiste Daroussin { 5039950eceeSBaptiste Daroussin if (c[k].type != PKG_CONFIG_STRING) 5049950eceeSBaptiste Daroussin return (-1); 5059950eceeSBaptiste Daroussin 5069950eceeSBaptiste Daroussin if (c[k].value != NULL) 5079950eceeSBaptiste Daroussin *val = c[k].value; 5089950eceeSBaptiste Daroussin else 5099950eceeSBaptiste Daroussin *val = c[k].val; 5109950eceeSBaptiste Daroussin 5119950eceeSBaptiste Daroussin return (0); 5129950eceeSBaptiste Daroussin } 5139950eceeSBaptiste Daroussin 5149950eceeSBaptiste Daroussin int 5159950eceeSBaptiste Daroussin config_bool(pkg_config_key k, bool *val) 5169950eceeSBaptiste Daroussin { 5179950eceeSBaptiste Daroussin const char *value; 5189950eceeSBaptiste Daroussin 5199950eceeSBaptiste Daroussin if (c[k].type != PKG_CONFIG_BOOL) 5209950eceeSBaptiste Daroussin return (-1); 5219950eceeSBaptiste Daroussin 5229950eceeSBaptiste Daroussin *val = false; 5239950eceeSBaptiste Daroussin 5249950eceeSBaptiste Daroussin if (c[k].value != NULL) 5259950eceeSBaptiste Daroussin value = c[k].value; 5269950eceeSBaptiste Daroussin else 5279950eceeSBaptiste Daroussin value = c[k].val; 5289950eceeSBaptiste Daroussin 529eb31a574SBryan Drewery if (boolstr_to_bool(value)) 5309950eceeSBaptiste Daroussin *val = true; 5319950eceeSBaptiste Daroussin 5329950eceeSBaptiste Daroussin return (0); 5339950eceeSBaptiste Daroussin } 5349950eceeSBaptiste Daroussin 5359950eceeSBaptiste Daroussin void 5369950eceeSBaptiste Daroussin config_finish(void) { 5379950eceeSBaptiste Daroussin int i; 5389950eceeSBaptiste Daroussin 5399950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) 5409950eceeSBaptiste Daroussin free(c[i].value); 5419950eceeSBaptiste Daroussin } 542