19950eceeSBaptiste Daroussin /*- 20ad5dbacSBaptiste Daroussin * Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> 3f12db248SBryan Drewery * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org> 49950eceeSBaptiste Daroussin * All rights reserved. 59950eceeSBaptiste Daroussin * 69950eceeSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 79950eceeSBaptiste Daroussin * modification, are permitted provided that the following conditions 89950eceeSBaptiste Daroussin * are met: 99950eceeSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 109950eceeSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 119950eceeSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 129950eceeSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 139950eceeSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 149950eceeSBaptiste Daroussin * 159950eceeSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 169950eceeSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 179950eceeSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 189950eceeSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 199950eceeSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 209950eceeSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 219950eceeSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 229950eceeSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 239950eceeSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 249950eceeSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 259950eceeSBaptiste Daroussin * SUCH DAMAGE. 269950eceeSBaptiste Daroussin */ 279950eceeSBaptiste Daroussin 289950eceeSBaptiste Daroussin #include <sys/cdefs.h> 299950eceeSBaptiste Daroussin __FBSDID("$FreeBSD$"); 309950eceeSBaptiste Daroussin 319950eceeSBaptiste Daroussin #include <sys/param.h> 32a351c93dSBaptiste Daroussin #include <sys/queue.h> 339950eceeSBaptiste Daroussin #include <sys/sbuf.h> 34eb31a574SBryan Drewery #include <sys/types.h> 3560b9a1fcSNathan Whitehorn #include <sys/utsname.h> 3660b9a1fcSNathan Whitehorn #include <sys/sysctl.h> 379950eceeSBaptiste Daroussin 3840274a2dSBaptiste Daroussin #include <assert.h> 39eb31a574SBryan Drewery #include <dirent.h> 408a7d859eSBaptiste Daroussin #include <ucl.h> 419950eceeSBaptiste Daroussin #include <ctype.h> 429950eceeSBaptiste Daroussin #include <err.h> 439950eceeSBaptiste Daroussin #include <errno.h> 449950eceeSBaptiste Daroussin #include <fcntl.h> 459950eceeSBaptiste Daroussin #include <inttypes.h> 469950eceeSBaptiste Daroussin #include <paths.h> 479950eceeSBaptiste Daroussin #include <stdbool.h> 489950eceeSBaptiste Daroussin #include <string.h> 499950eceeSBaptiste Daroussin #include <unistd.h> 509950eceeSBaptiste Daroussin 519950eceeSBaptiste Daroussin #include "config.h" 529950eceeSBaptiste Daroussin 539950eceeSBaptiste Daroussin #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ 549950eceeSBaptiste Daroussin 55eb31a574SBryan Drewery struct config_value { 56eb31a574SBryan Drewery char *value; 57eb31a574SBryan Drewery STAILQ_ENTRY(config_value) next; 58eb31a574SBryan Drewery }; 59eb31a574SBryan Drewery 609950eceeSBaptiste Daroussin struct config_entry { 619950eceeSBaptiste Daroussin uint8_t type; 629950eceeSBaptiste Daroussin const char *key; 639950eceeSBaptiste Daroussin const char *val; 649950eceeSBaptiste Daroussin char *value; 65eb31a574SBryan Drewery STAILQ_HEAD(, config_value) *list; 669950eceeSBaptiste Daroussin bool envset; 6797c3a766SBryan Drewery bool main_only; /* Only set in pkg.conf. */ 689950eceeSBaptiste Daroussin }; 699950eceeSBaptiste Daroussin 709950eceeSBaptiste Daroussin static struct config_entry c[] = { 719950eceeSBaptiste Daroussin [PACKAGESITE] = { 729950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 739950eceeSBaptiste Daroussin "PACKAGESITE", 7462940ea9SBryan Drewery URL_SCHEME_PREFIX "http://pkg.FreeBSD.org/${ABI}/latest", 759950eceeSBaptiste Daroussin NULL, 76eb31a574SBryan Drewery NULL, 779950eceeSBaptiste Daroussin false, 7897c3a766SBryan Drewery false, 799950eceeSBaptiste Daroussin }, 809950eceeSBaptiste Daroussin [ABI] = { 819950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 829950eceeSBaptiste Daroussin "ABI", 839950eceeSBaptiste Daroussin NULL, 849950eceeSBaptiste Daroussin NULL, 85eb31a574SBryan Drewery NULL, 869950eceeSBaptiste Daroussin false, 8797c3a766SBryan Drewery true, 889950eceeSBaptiste Daroussin }, 899950eceeSBaptiste Daroussin [MIRROR_TYPE] = { 909950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 919950eceeSBaptiste Daroussin "MIRROR_TYPE", 929950eceeSBaptiste Daroussin "SRV", 939950eceeSBaptiste Daroussin NULL, 94eb31a574SBryan Drewery NULL, 959950eceeSBaptiste Daroussin false, 9697c3a766SBryan Drewery false, 979950eceeSBaptiste Daroussin }, 989950eceeSBaptiste Daroussin [ASSUME_ALWAYS_YES] = { 999950eceeSBaptiste Daroussin PKG_CONFIG_BOOL, 1009950eceeSBaptiste Daroussin "ASSUME_ALWAYS_YES", 1019950eceeSBaptiste Daroussin "NO", 1029950eceeSBaptiste Daroussin NULL, 103eb31a574SBryan Drewery NULL, 1049950eceeSBaptiste Daroussin false, 10597c3a766SBryan Drewery true, 106f12db248SBryan Drewery }, 107f12db248SBryan Drewery [SIGNATURE_TYPE] = { 108f12db248SBryan Drewery PKG_CONFIG_STRING, 109f12db248SBryan Drewery "SIGNATURE_TYPE", 110f12db248SBryan Drewery NULL, 111f12db248SBryan Drewery NULL, 112eb31a574SBryan Drewery NULL, 113f12db248SBryan Drewery false, 11497c3a766SBryan Drewery false, 115f12db248SBryan Drewery }, 116f12db248SBryan Drewery [FINGERPRINTS] = { 117f12db248SBryan Drewery PKG_CONFIG_STRING, 118f12db248SBryan Drewery "FINGERPRINTS", 119f12db248SBryan Drewery NULL, 120f12db248SBryan Drewery NULL, 121eb31a574SBryan Drewery NULL, 122eb31a574SBryan Drewery false, 12397c3a766SBryan Drewery false, 124eb31a574SBryan Drewery }, 125eb31a574SBryan Drewery [REPOS_DIR] = { 126eb31a574SBryan Drewery PKG_CONFIG_LIST, 127eb31a574SBryan Drewery "REPOS_DIR", 128eb31a574SBryan Drewery NULL, 129eb31a574SBryan Drewery NULL, 130eb31a574SBryan Drewery NULL, 131f12db248SBryan Drewery false, 13297c3a766SBryan Drewery true, 133f12db248SBryan Drewery }, 134*61acb458SBaptiste Daroussin [PUBKEY] = { 135*61acb458SBaptiste Daroussin PKG_CONFIG_STRING, 136*61acb458SBaptiste Daroussin "PUBKEY", 137*61acb458SBaptiste Daroussin NULL, 138*61acb458SBaptiste Daroussin NULL, 139*61acb458SBaptiste Daroussin NULL, 140*61acb458SBaptiste Daroussin false, 141*61acb458SBaptiste Daroussin false 142*61acb458SBaptiste Daroussin } 1439950eceeSBaptiste Daroussin }; 1449950eceeSBaptiste Daroussin 1459950eceeSBaptiste Daroussin static int 1469950eceeSBaptiste Daroussin pkg_get_myabi(char *dest, size_t sz) 1479950eceeSBaptiste Daroussin { 14860b9a1fcSNathan Whitehorn struct utsname uts; 14960b9a1fcSNathan Whitehorn char machine_arch[255]; 15060b9a1fcSNathan Whitehorn size_t len; 15160b9a1fcSNathan Whitehorn int error; 1529950eceeSBaptiste Daroussin 15360b9a1fcSNathan Whitehorn error = uname(&uts); 15460b9a1fcSNathan Whitehorn if (error) 15560b9a1fcSNathan Whitehorn return (errno); 1569950eceeSBaptiste Daroussin 15760b9a1fcSNathan Whitehorn len = sizeof(machine_arch); 15860b9a1fcSNathan Whitehorn error = sysctlbyname("hw.machine_arch", machine_arch, &len, NULL, 0); 15960b9a1fcSNathan Whitehorn if (error) 16060b9a1fcSNathan Whitehorn return (errno); 16160b9a1fcSNathan Whitehorn machine_arch[len] = '\0'; 1629950eceeSBaptiste Daroussin 16340274a2dSBaptiste Daroussin /* 16460b9a1fcSNathan Whitehorn * Use __FreeBSD_version rather than kernel version (uts.release) for 16560b9a1fcSNathan Whitehorn * use in jails. This is equivalent to the value of uname -U. 16640274a2dSBaptiste Daroussin */ 16760b9a1fcSNathan Whitehorn snprintf(dest, sz, "%s:%d:%s", uts.sysname, __FreeBSD_version/100000, 16860b9a1fcSNathan Whitehorn machine_arch); 16940274a2dSBaptiste Daroussin 17060b9a1fcSNathan Whitehorn return (error); 1719950eceeSBaptiste Daroussin } 1729950eceeSBaptiste Daroussin 1739950eceeSBaptiste Daroussin static void 1749950eceeSBaptiste Daroussin subst_packagesite(const char *abi) 1759950eceeSBaptiste Daroussin { 1769950eceeSBaptiste Daroussin struct sbuf *newval; 1779950eceeSBaptiste Daroussin const char *variable_string; 1789950eceeSBaptiste Daroussin const char *oldval; 1799950eceeSBaptiste Daroussin 1809950eceeSBaptiste Daroussin if (c[PACKAGESITE].value != NULL) 1819950eceeSBaptiste Daroussin oldval = c[PACKAGESITE].value; 1829950eceeSBaptiste Daroussin else 1839950eceeSBaptiste Daroussin oldval = c[PACKAGESITE].val; 1849950eceeSBaptiste Daroussin 1859950eceeSBaptiste Daroussin if ((variable_string = strstr(oldval, "${ABI}")) == NULL) 1869950eceeSBaptiste Daroussin return; 1879950eceeSBaptiste Daroussin 1889950eceeSBaptiste Daroussin newval = sbuf_new_auto(); 1899950eceeSBaptiste Daroussin sbuf_bcat(newval, oldval, variable_string - oldval); 1909950eceeSBaptiste Daroussin sbuf_cat(newval, abi); 1919950eceeSBaptiste Daroussin sbuf_cat(newval, variable_string + strlen("${ABI}")); 1929950eceeSBaptiste Daroussin sbuf_finish(newval); 1939950eceeSBaptiste Daroussin 1949950eceeSBaptiste Daroussin free(c[PACKAGESITE].value); 1959950eceeSBaptiste Daroussin c[PACKAGESITE].value = strdup(sbuf_data(newval)); 1969950eceeSBaptiste Daroussin } 1979950eceeSBaptiste Daroussin 198eb31a574SBryan Drewery static int 199eb31a574SBryan Drewery boolstr_to_bool(const char *str) 200eb31a574SBryan Drewery { 201eb31a574SBryan Drewery if (str != NULL && (strcasecmp(str, "true") == 0 || 202eb31a574SBryan Drewery strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0 || 203eb31a574SBryan Drewery str[0] == '1')) 204eb31a574SBryan Drewery return (true); 205eb31a574SBryan Drewery 206eb31a574SBryan Drewery return (false); 207eb31a574SBryan Drewery } 208eb31a574SBryan Drewery 2099950eceeSBaptiste Daroussin static void 210b04a7a0bSBaptiste Daroussin config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype) 2119950eceeSBaptiste Daroussin { 2129950eceeSBaptiste Daroussin struct sbuf *buf = sbuf_new_auto(); 213b04a7a0bSBaptiste Daroussin const ucl_object_t *cur, *seq; 2148a7d859eSBaptiste Daroussin ucl_object_iter_t it = NULL, itseq = NULL; 215eb31a574SBryan Drewery struct config_entry *temp_config; 216eb31a574SBryan Drewery struct config_value *cv; 2178a7d859eSBaptiste Daroussin const char *key; 2189950eceeSBaptiste Daroussin int i; 2199950eceeSBaptiste Daroussin size_t j; 2209950eceeSBaptiste Daroussin 221eb31a574SBryan Drewery /* Temporary config for configs that may be disabled. */ 222eb31a574SBryan Drewery temp_config = calloc(CONFIG_SIZE, sizeof(struct config_entry)); 223eb31a574SBryan Drewery 2248a7d859eSBaptiste Daroussin while ((cur = ucl_iterate_object(obj, &it, true))) { 2258a7d859eSBaptiste Daroussin key = ucl_object_key(cur); 2268a7d859eSBaptiste Daroussin if (key == NULL) 2279950eceeSBaptiste Daroussin continue; 2289950eceeSBaptiste Daroussin sbuf_clear(buf); 2299950eceeSBaptiste Daroussin 230bc5e9ac0SBryan Drewery if (conftype == CONFFILE_PKG) { 2318a7d859eSBaptiste Daroussin for (j = 0; j < strlen(key); ++j) 2328a7d859eSBaptiste Daroussin sbuf_putc(buf, key[j]); 2339950eceeSBaptiste Daroussin sbuf_finish(buf); 234bc5e9ac0SBryan Drewery } else if (conftype == CONFFILE_REPO) { 2358a7d859eSBaptiste Daroussin if (strcasecmp(key, "url") == 0) 236bc5e9ac0SBryan Drewery sbuf_cpy(buf, "PACKAGESITE"); 2378a7d859eSBaptiste Daroussin else if (strcasecmp(key, "mirror_type") == 0) 238bc5e9ac0SBryan Drewery sbuf_cpy(buf, "MIRROR_TYPE"); 2398a7d859eSBaptiste Daroussin else if (strcasecmp(key, "signature_type") == 0) 240f12db248SBryan Drewery sbuf_cpy(buf, "SIGNATURE_TYPE"); 2418a7d859eSBaptiste Daroussin else if (strcasecmp(key, "fingerprints") == 0) 242f12db248SBryan Drewery sbuf_cpy(buf, "FINGERPRINTS"); 243*61acb458SBaptiste Daroussin else if (strcasecmp(key, "pubkey") == 0) 244*61acb458SBaptiste Daroussin sbuf_cpy(buf, "PUBKEY"); 2458a7d859eSBaptiste Daroussin else if (strcasecmp(key, "enabled") == 0) { 2468a7d859eSBaptiste Daroussin if ((cur->type != UCL_BOOLEAN) || 2478a7d859eSBaptiste Daroussin !ucl_object_toboolean(cur)) 248eb31a574SBryan Drewery goto cleanup; 2498a7d859eSBaptiste Daroussin } else 250bc5e9ac0SBryan Drewery continue; 251bc5e9ac0SBryan Drewery sbuf_finish(buf); 252bc5e9ac0SBryan Drewery } 253bc5e9ac0SBryan Drewery 2549950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 2559950eceeSBaptiste Daroussin if (strcmp(sbuf_data(buf), c[i].key) == 0) 2569950eceeSBaptiste Daroussin break; 2579950eceeSBaptiste Daroussin } 2589950eceeSBaptiste Daroussin 259bc5e9ac0SBryan Drewery /* Silently skip unknown keys to be future compatible. */ 2608a7d859eSBaptiste Daroussin if (i == CONFIG_SIZE) 2619950eceeSBaptiste Daroussin continue; 2629950eceeSBaptiste Daroussin 2639950eceeSBaptiste Daroussin /* env has priority over config file */ 2648a7d859eSBaptiste Daroussin if (c[i].envset) 2659950eceeSBaptiste Daroussin continue; 2669950eceeSBaptiste Daroussin 267eb31a574SBryan Drewery /* Parse sequence value ["item1", "item2"] */ 268eb31a574SBryan Drewery switch (c[i].type) { 269eb31a574SBryan Drewery case PKG_CONFIG_LIST: 2708a7d859eSBaptiste Daroussin if (cur->type != UCL_ARRAY) { 2718a7d859eSBaptiste Daroussin warnx("Skipping invalid array " 272eb31a574SBryan Drewery "value for %s.\n", c[i].key); 273eb31a574SBryan Drewery continue; 274eb31a574SBryan Drewery } 275eb31a574SBryan Drewery temp_config[i].list = 276eb31a574SBryan Drewery malloc(sizeof(*temp_config[i].list)); 277eb31a574SBryan Drewery STAILQ_INIT(temp_config[i].list); 278eb31a574SBryan Drewery 2798a7d859eSBaptiste Daroussin while ((seq = ucl_iterate_object(cur, &itseq, true))) { 2808a7d859eSBaptiste Daroussin if (seq->type != UCL_STRING) 281eb31a574SBryan Drewery continue; 282eb31a574SBryan Drewery cv = malloc(sizeof(struct config_value)); 283eb31a574SBryan Drewery cv->value = 2848a7d859eSBaptiste Daroussin strdup(ucl_object_tostring(seq)); 285eb31a574SBryan Drewery STAILQ_INSERT_TAIL(temp_config[i].list, cv, 286eb31a574SBryan Drewery next); 287eb31a574SBryan Drewery } 288eb31a574SBryan Drewery break; 289197372c2SBryan Drewery case PKG_CONFIG_BOOL: 290197372c2SBryan Drewery temp_config[i].value = 291197372c2SBryan Drewery strdup(ucl_object_toboolean(cur) ? "yes" : "no"); 292197372c2SBryan Drewery break; 293eb31a574SBryan Drewery default: 294eb31a574SBryan Drewery /* Normal string value. */ 2958a7d859eSBaptiste Daroussin temp_config[i].value = strdup(ucl_object_tostring(cur)); 296eb31a574SBryan Drewery break; 297eb31a574SBryan Drewery } 2989950eceeSBaptiste Daroussin } 2999950eceeSBaptiste Daroussin 300eb31a574SBryan Drewery /* Repo is enabled, copy over all settings from temp_config. */ 301eb31a574SBryan Drewery for (i = 0; i < CONFIG_SIZE; i++) { 302eb31a574SBryan Drewery if (c[i].envset) 303eb31a574SBryan Drewery continue; 30497c3a766SBryan Drewery /* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */ 30597c3a766SBryan Drewery if (conftype != CONFFILE_PKG && c[i].main_only == true) 30697c3a766SBryan Drewery continue; 307eb31a574SBryan Drewery switch (c[i].type) { 308eb31a574SBryan Drewery case PKG_CONFIG_LIST: 309eb31a574SBryan Drewery c[i].list = temp_config[i].list; 310eb31a574SBryan Drewery break; 311eb31a574SBryan Drewery default: 312eb31a574SBryan Drewery c[i].value = temp_config[i].value; 313eb31a574SBryan Drewery break; 314eb31a574SBryan Drewery } 315eb31a574SBryan Drewery } 316eb31a574SBryan Drewery 317eb31a574SBryan Drewery cleanup: 318eb31a574SBryan Drewery free(temp_config); 3199950eceeSBaptiste Daroussin sbuf_delete(buf); 3209950eceeSBaptiste Daroussin } 3219950eceeSBaptiste Daroussin 322bc5e9ac0SBryan Drewery /*- 323bc5e9ac0SBryan Drewery * Parse new repo style configs in style: 324bc5e9ac0SBryan Drewery * Name: 325bc5e9ac0SBryan Drewery * URL: 326bc5e9ac0SBryan Drewery * MIRROR_TYPE: 327bc5e9ac0SBryan Drewery * etc... 328bc5e9ac0SBryan Drewery */ 329bc5e9ac0SBryan Drewery static void 3308a7d859eSBaptiste Daroussin parse_repo_file(ucl_object_t *obj) 331bc5e9ac0SBryan Drewery { 3328a7d859eSBaptiste Daroussin ucl_object_iter_t it = NULL; 333b04a7a0bSBaptiste Daroussin const ucl_object_t *cur; 3348a7d859eSBaptiste Daroussin const char *key; 335bc5e9ac0SBryan Drewery 3368a7d859eSBaptiste Daroussin while ((cur = ucl_iterate_object(obj, &it, true))) { 3378a7d859eSBaptiste Daroussin key = ucl_object_key(cur); 338bc5e9ac0SBryan Drewery 3398a7d859eSBaptiste Daroussin if (key == NULL) 340bc5e9ac0SBryan Drewery continue; 341bc5e9ac0SBryan Drewery 3428a7d859eSBaptiste Daroussin if (cur->type != UCL_OBJECT) 343bc5e9ac0SBryan Drewery continue; 344bc5e9ac0SBryan Drewery 3458a7d859eSBaptiste Daroussin config_parse(cur, CONFFILE_REPO); 346bc5e9ac0SBryan Drewery } 347bc5e9ac0SBryan Drewery } 348bc5e9ac0SBryan Drewery 349bc5e9ac0SBryan Drewery 350bc5e9ac0SBryan Drewery static int 351bc5e9ac0SBryan Drewery read_conf_file(const char *confpath, pkg_conf_file_t conftype) 3529950eceeSBaptiste Daroussin { 3538a7d859eSBaptiste Daroussin struct ucl_parser *p; 3548a7d859eSBaptiste Daroussin ucl_object_t *obj = NULL; 355bc5e9ac0SBryan Drewery 3568a7d859eSBaptiste Daroussin p = ucl_parser_new(0); 3578a7d859eSBaptiste Daroussin 3588a7d859eSBaptiste Daroussin if (!ucl_parser_add_file(p, confpath)) { 359bc5e9ac0SBryan Drewery if (errno != ENOENT) 3608a7d859eSBaptiste Daroussin errx(EXIT_FAILURE, "Unable to parse configuration " 3618a7d859eSBaptiste Daroussin "file %s: %s", confpath, ucl_parser_get_error(p)); 3628a7d859eSBaptiste Daroussin ucl_parser_free(p); 363bc5e9ac0SBryan Drewery /* no configuration present */ 364bc5e9ac0SBryan Drewery return (1); 365bc5e9ac0SBryan Drewery } 366bc5e9ac0SBryan Drewery 3678a7d859eSBaptiste Daroussin obj = ucl_parser_get_object(p); 3688a7d859eSBaptiste Daroussin if (obj->type != UCL_OBJECT) 369bc5e9ac0SBryan Drewery warnx("Invalid configuration format, ignoring the " 370bc5e9ac0SBryan Drewery "configuration file %s", confpath); 371bc5e9ac0SBryan Drewery else { 372bc5e9ac0SBryan Drewery if (conftype == CONFFILE_PKG) 3738a7d859eSBaptiste Daroussin config_parse(obj, conftype); 374bc5e9ac0SBryan Drewery else if (conftype == CONFFILE_REPO) 3758a7d859eSBaptiste Daroussin parse_repo_file(obj); 376bc5e9ac0SBryan Drewery } 377bc5e9ac0SBryan Drewery 378b04a7a0bSBaptiste Daroussin ucl_object_unref(obj); 3798a7d859eSBaptiste Daroussin ucl_parser_free(p); 380bc5e9ac0SBryan Drewery 381bc5e9ac0SBryan Drewery return (0); 382bc5e9ac0SBryan Drewery } 383bc5e9ac0SBryan Drewery 384eb31a574SBryan Drewery static int 385eb31a574SBryan Drewery load_repositories(const char *repodir) 386eb31a574SBryan Drewery { 387eb31a574SBryan Drewery struct dirent *ent; 388eb31a574SBryan Drewery DIR *d; 389eb31a574SBryan Drewery char *p; 390eb31a574SBryan Drewery size_t n; 391eb31a574SBryan Drewery char path[MAXPATHLEN]; 392eb31a574SBryan Drewery int ret; 393eb31a574SBryan Drewery 394eb31a574SBryan Drewery ret = 0; 395eb31a574SBryan Drewery 396eb31a574SBryan Drewery if ((d = opendir(repodir)) == NULL) 397eb31a574SBryan Drewery return (1); 398eb31a574SBryan Drewery 399eb31a574SBryan Drewery while ((ent = readdir(d))) { 400eb31a574SBryan Drewery /* Trim out 'repos'. */ 401eb31a574SBryan Drewery if ((n = strlen(ent->d_name)) <= 5) 402eb31a574SBryan Drewery continue; 403eb31a574SBryan Drewery p = &ent->d_name[n - 5]; 404eb31a574SBryan Drewery if (strcmp(p, ".conf") == 0) { 405eb31a574SBryan Drewery snprintf(path, sizeof(path), "%s%s%s", 406eb31a574SBryan Drewery repodir, 407eb31a574SBryan Drewery repodir[strlen(repodir) - 1] == '/' ? "" : "/", 408eb31a574SBryan Drewery ent->d_name); 409eb31a574SBryan Drewery if (access(path, F_OK) == 0 && 410eb31a574SBryan Drewery read_conf_file(path, CONFFILE_REPO)) { 411eb31a574SBryan Drewery ret = 1; 412eb31a574SBryan Drewery goto cleanup; 413eb31a574SBryan Drewery } 414eb31a574SBryan Drewery } 415eb31a574SBryan Drewery } 416eb31a574SBryan Drewery 417eb31a574SBryan Drewery cleanup: 418eb31a574SBryan Drewery closedir(d); 419eb31a574SBryan Drewery 420eb31a574SBryan Drewery return (ret); 421eb31a574SBryan Drewery } 422eb31a574SBryan Drewery 423bc5e9ac0SBryan Drewery int 424bc5e9ac0SBryan Drewery config_init(void) 425bc5e9ac0SBryan Drewery { 426eb31a574SBryan Drewery char *val; 4279950eceeSBaptiste Daroussin int i; 4289950eceeSBaptiste Daroussin const char *localbase; 429eb31a574SBryan Drewery char *env_list_item; 4309950eceeSBaptiste Daroussin char confpath[MAXPATHLEN]; 431eb31a574SBryan Drewery struct config_value *cv; 4329950eceeSBaptiste Daroussin char abi[BUFSIZ]; 4339950eceeSBaptiste Daroussin 4349950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 4359950eceeSBaptiste Daroussin val = getenv(c[i].key); 4369950eceeSBaptiste Daroussin if (val != NULL) { 4379950eceeSBaptiste Daroussin c[i].envset = true; 438eb31a574SBryan Drewery switch (c[i].type) { 439eb31a574SBryan Drewery case PKG_CONFIG_LIST: 440eb31a574SBryan Drewery /* Split up comma-separated items from env. */ 441eb31a574SBryan Drewery c[i].list = malloc(sizeof(*c[i].list)); 442eb31a574SBryan Drewery STAILQ_INIT(c[i].list); 443eb31a574SBryan Drewery for (env_list_item = strtok(val, ","); 444eb31a574SBryan Drewery env_list_item != NULL; 445eb31a574SBryan Drewery env_list_item = strtok(NULL, ",")) { 446eb31a574SBryan Drewery cv = 447eb31a574SBryan Drewery malloc(sizeof(struct config_value)); 448eb31a574SBryan Drewery cv->value = 449eb31a574SBryan Drewery strdup(env_list_item); 450eb31a574SBryan Drewery STAILQ_INSERT_TAIL(c[i].list, cv, 451eb31a574SBryan Drewery next); 452eb31a574SBryan Drewery } 453eb31a574SBryan Drewery break; 454eb31a574SBryan Drewery default: 455eb31a574SBryan Drewery c[i].val = val; 456eb31a574SBryan Drewery break; 457eb31a574SBryan Drewery } 4589950eceeSBaptiste Daroussin } 4599950eceeSBaptiste Daroussin } 4609950eceeSBaptiste Daroussin 461eb31a574SBryan Drewery /* Read LOCALBASE/etc/pkg.conf first. */ 4629950eceeSBaptiste Daroussin localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE; 463bc5e9ac0SBryan Drewery snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", 464bc5e9ac0SBryan Drewery localbase); 4659950eceeSBaptiste Daroussin 466bc5e9ac0SBryan Drewery if (access(confpath, F_OK) == 0 && read_conf_file(confpath, 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) 484eb31a574SBryan Drewery if (load_repositories(cv->value)) 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