1*9950eceeSBaptiste Daroussin /*- 2*9950eceeSBaptiste Daroussin * Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org> 3*9950eceeSBaptiste Daroussin * All rights reserved. 4*9950eceeSBaptiste Daroussin * 5*9950eceeSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 6*9950eceeSBaptiste Daroussin * modification, are permitted provided that the following conditions 7*9950eceeSBaptiste Daroussin * are met: 8*9950eceeSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 9*9950eceeSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 10*9950eceeSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 11*9950eceeSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 12*9950eceeSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 13*9950eceeSBaptiste Daroussin * 14*9950eceeSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*9950eceeSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*9950eceeSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*9950eceeSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*9950eceeSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*9950eceeSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*9950eceeSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*9950eceeSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*9950eceeSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*9950eceeSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*9950eceeSBaptiste Daroussin * SUCH DAMAGE. 25*9950eceeSBaptiste Daroussin */ 26*9950eceeSBaptiste Daroussin 27*9950eceeSBaptiste Daroussin #include <sys/cdefs.h> 28*9950eceeSBaptiste Daroussin __FBSDID("$FreeBSD$"); 29*9950eceeSBaptiste Daroussin 30*9950eceeSBaptiste Daroussin #include <sys/param.h> 31*9950eceeSBaptiste Daroussin #include <sys/sbuf.h> 32*9950eceeSBaptiste Daroussin #include <sys/elf_common.h> 33*9950eceeSBaptiste Daroussin #include <sys/endian.h> 34*9950eceeSBaptiste Daroussin 35*9950eceeSBaptiste Daroussin #include <bsdyml.h> 36*9950eceeSBaptiste Daroussin #include <ctype.h> 37*9950eceeSBaptiste Daroussin #include <err.h> 38*9950eceeSBaptiste Daroussin #include <errno.h> 39*9950eceeSBaptiste Daroussin #include <fcntl.h> 40*9950eceeSBaptiste Daroussin #include <gelf.h> 41*9950eceeSBaptiste Daroussin #include <inttypes.h> 42*9950eceeSBaptiste Daroussin #include <paths.h> 43*9950eceeSBaptiste Daroussin #include <stdbool.h> 44*9950eceeSBaptiste Daroussin #include <string.h> 45*9950eceeSBaptiste Daroussin #include <unistd.h> 46*9950eceeSBaptiste Daroussin 47*9950eceeSBaptiste Daroussin #include "elf_tables.h" 48*9950eceeSBaptiste Daroussin #include "config.h" 49*9950eceeSBaptiste Daroussin 50*9950eceeSBaptiste Daroussin #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ 51*9950eceeSBaptiste Daroussin 52*9950eceeSBaptiste Daroussin struct config_entry { 53*9950eceeSBaptiste Daroussin uint8_t type; 54*9950eceeSBaptiste Daroussin const char *key; 55*9950eceeSBaptiste Daroussin const char *val; 56*9950eceeSBaptiste Daroussin char *value; 57*9950eceeSBaptiste Daroussin bool envset; 58*9950eceeSBaptiste Daroussin }; 59*9950eceeSBaptiste Daroussin 60*9950eceeSBaptiste Daroussin static struct config_entry c[] = { 61*9950eceeSBaptiste Daroussin [PACKAGESITE] = { 62*9950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 63*9950eceeSBaptiste Daroussin "PACKAGESITE", 64*9950eceeSBaptiste Daroussin "http://pkg.FreeBSD.org/${ABI}/latest", 65*9950eceeSBaptiste Daroussin NULL, 66*9950eceeSBaptiste Daroussin false, 67*9950eceeSBaptiste Daroussin }, 68*9950eceeSBaptiste Daroussin [ABI] = { 69*9950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 70*9950eceeSBaptiste Daroussin "ABI", 71*9950eceeSBaptiste Daroussin NULL, 72*9950eceeSBaptiste Daroussin NULL, 73*9950eceeSBaptiste Daroussin false, 74*9950eceeSBaptiste Daroussin }, 75*9950eceeSBaptiste Daroussin [MIRROR_TYPE] = { 76*9950eceeSBaptiste Daroussin PKG_CONFIG_STRING, 77*9950eceeSBaptiste Daroussin "MIRROR_TYPE", 78*9950eceeSBaptiste Daroussin "SRV", 79*9950eceeSBaptiste Daroussin NULL, 80*9950eceeSBaptiste Daroussin false, 81*9950eceeSBaptiste Daroussin }, 82*9950eceeSBaptiste Daroussin [ASSUME_ALWAYS_YES] = { 83*9950eceeSBaptiste Daroussin PKG_CONFIG_BOOL, 84*9950eceeSBaptiste Daroussin "ASSUME_ALWAYS_YES", 85*9950eceeSBaptiste Daroussin "NO", 86*9950eceeSBaptiste Daroussin NULL, 87*9950eceeSBaptiste Daroussin false, 88*9950eceeSBaptiste Daroussin } 89*9950eceeSBaptiste Daroussin }; 90*9950eceeSBaptiste Daroussin 91*9950eceeSBaptiste Daroussin static const char * 92*9950eceeSBaptiste Daroussin elf_corres_to_string(struct _elf_corres *m, int e) 93*9950eceeSBaptiste Daroussin { 94*9950eceeSBaptiste Daroussin int i; 95*9950eceeSBaptiste Daroussin 96*9950eceeSBaptiste Daroussin for (i = 0; m[i].string != NULL; i++) 97*9950eceeSBaptiste Daroussin if (m[i].elf_nb == e) 98*9950eceeSBaptiste Daroussin return (m[i].string); 99*9950eceeSBaptiste Daroussin 100*9950eceeSBaptiste Daroussin return ("unknown"); 101*9950eceeSBaptiste Daroussin } 102*9950eceeSBaptiste Daroussin 103*9950eceeSBaptiste Daroussin static int 104*9950eceeSBaptiste Daroussin pkg_get_myabi(char *dest, size_t sz) 105*9950eceeSBaptiste Daroussin { 106*9950eceeSBaptiste Daroussin Elf *elf; 107*9950eceeSBaptiste Daroussin Elf_Data *data; 108*9950eceeSBaptiste Daroussin Elf_Note note; 109*9950eceeSBaptiste Daroussin Elf_Scn *scn; 110*9950eceeSBaptiste Daroussin char *src, *osname; 111*9950eceeSBaptiste Daroussin const char *abi; 112*9950eceeSBaptiste Daroussin GElf_Ehdr elfhdr; 113*9950eceeSBaptiste Daroussin GElf_Shdr shdr; 114*9950eceeSBaptiste Daroussin int fd, i, ret; 115*9950eceeSBaptiste Daroussin uint32_t version; 116*9950eceeSBaptiste Daroussin 117*9950eceeSBaptiste Daroussin version = 0; 118*9950eceeSBaptiste Daroussin ret = -1; 119*9950eceeSBaptiste Daroussin scn = NULL; 120*9950eceeSBaptiste Daroussin abi = NULL; 121*9950eceeSBaptiste Daroussin 122*9950eceeSBaptiste Daroussin if (elf_version(EV_CURRENT) == EV_NONE) { 123*9950eceeSBaptiste Daroussin warnx("ELF library initialization failed: %s", 124*9950eceeSBaptiste Daroussin elf_errmsg(-1)); 125*9950eceeSBaptiste Daroussin return (-1); 126*9950eceeSBaptiste Daroussin } 127*9950eceeSBaptiste Daroussin 128*9950eceeSBaptiste Daroussin if ((fd = open(_PATH_BSHELL, O_RDONLY)) < 0) { 129*9950eceeSBaptiste Daroussin warn("open()"); 130*9950eceeSBaptiste Daroussin return (-1); 131*9950eceeSBaptiste Daroussin } 132*9950eceeSBaptiste Daroussin 133*9950eceeSBaptiste Daroussin if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { 134*9950eceeSBaptiste Daroussin ret = -1; 135*9950eceeSBaptiste Daroussin warnx("elf_begin() failed: %s.", elf_errmsg(-1)); 136*9950eceeSBaptiste Daroussin goto cleanup; 137*9950eceeSBaptiste Daroussin } 138*9950eceeSBaptiste Daroussin 139*9950eceeSBaptiste Daroussin if (gelf_getehdr(elf, &elfhdr) == NULL) { 140*9950eceeSBaptiste Daroussin ret = -1; 141*9950eceeSBaptiste Daroussin warn("getehdr() failed: %s.", elf_errmsg(-1)); 142*9950eceeSBaptiste Daroussin goto cleanup; 143*9950eceeSBaptiste Daroussin } 144*9950eceeSBaptiste Daroussin while ((scn = elf_nextscn(elf, scn)) != NULL) { 145*9950eceeSBaptiste Daroussin if (gelf_getshdr(scn, &shdr) != &shdr) { 146*9950eceeSBaptiste Daroussin ret = -1; 147*9950eceeSBaptiste Daroussin warn("getshdr() failed: %s.", elf_errmsg(-1)); 148*9950eceeSBaptiste Daroussin goto cleanup; 149*9950eceeSBaptiste Daroussin } 150*9950eceeSBaptiste Daroussin 151*9950eceeSBaptiste Daroussin if (shdr.sh_type == SHT_NOTE) 152*9950eceeSBaptiste Daroussin break; 153*9950eceeSBaptiste Daroussin } 154*9950eceeSBaptiste Daroussin 155*9950eceeSBaptiste Daroussin if (scn == NULL) { 156*9950eceeSBaptiste Daroussin ret = -1; 157*9950eceeSBaptiste Daroussin warn("failed to get the note section"); 158*9950eceeSBaptiste Daroussin goto cleanup; 159*9950eceeSBaptiste Daroussin } 160*9950eceeSBaptiste Daroussin 161*9950eceeSBaptiste Daroussin data = elf_getdata(scn, NULL); 162*9950eceeSBaptiste Daroussin src = data->d_buf; 163*9950eceeSBaptiste Daroussin for (;;) { 164*9950eceeSBaptiste Daroussin memcpy(¬e, src, sizeof(Elf_Note)); 165*9950eceeSBaptiste Daroussin src += sizeof(Elf_Note); 166*9950eceeSBaptiste Daroussin if (note.n_type == NT_VERSION) 167*9950eceeSBaptiste Daroussin break; 168*9950eceeSBaptiste Daroussin src += note.n_namesz + note.n_descsz; 169*9950eceeSBaptiste Daroussin } 170*9950eceeSBaptiste Daroussin osname = src; 171*9950eceeSBaptiste Daroussin src += roundup2(note.n_namesz, 4); 172*9950eceeSBaptiste Daroussin if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB) 173*9950eceeSBaptiste Daroussin version = be32dec(src); 174*9950eceeSBaptiste Daroussin else 175*9950eceeSBaptiste Daroussin version = le32dec(src); 176*9950eceeSBaptiste Daroussin 177*9950eceeSBaptiste Daroussin for (i = 0; osname[i] != '\0'; i++) 178*9950eceeSBaptiste Daroussin osname[i] = (char)tolower(osname[i]); 179*9950eceeSBaptiste Daroussin 180*9950eceeSBaptiste Daroussin snprintf(dest, sz, "%s:%d:%s:%s", 181*9950eceeSBaptiste Daroussin osname, version / 100000, 182*9950eceeSBaptiste Daroussin elf_corres_to_string(mach_corres, (int)elfhdr.e_machine), 183*9950eceeSBaptiste Daroussin elf_corres_to_string(wordsize_corres, 184*9950eceeSBaptiste Daroussin (int)elfhdr.e_ident[EI_CLASS])); 185*9950eceeSBaptiste Daroussin 186*9950eceeSBaptiste Daroussin ret = 0; 187*9950eceeSBaptiste Daroussin 188*9950eceeSBaptiste Daroussin switch (elfhdr.e_machine) { 189*9950eceeSBaptiste Daroussin case EM_ARM: 190*9950eceeSBaptiste Daroussin snprintf(dest + strlen(dest), sz - strlen(dest), 191*9950eceeSBaptiste Daroussin ":%s:%s:%s", elf_corres_to_string(endian_corres, 192*9950eceeSBaptiste Daroussin (int)elfhdr.e_ident[EI_DATA]), 193*9950eceeSBaptiste Daroussin (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ? 194*9950eceeSBaptiste Daroussin "eabi" : "oabi", 195*9950eceeSBaptiste Daroussin (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ? 196*9950eceeSBaptiste Daroussin "softfp" : "vfp"); 197*9950eceeSBaptiste Daroussin break; 198*9950eceeSBaptiste Daroussin case EM_MIPS: 199*9950eceeSBaptiste Daroussin /* 200*9950eceeSBaptiste Daroussin * this is taken from binutils sources: 201*9950eceeSBaptiste Daroussin * include/elf/mips.h 202*9950eceeSBaptiste Daroussin * mapping is figured out from binutils: 203*9950eceeSBaptiste Daroussin * gas/config/tc-mips.c 204*9950eceeSBaptiste Daroussin */ 205*9950eceeSBaptiste Daroussin switch (elfhdr.e_flags & EF_MIPS_ABI) { 206*9950eceeSBaptiste Daroussin case E_MIPS_ABI_O32: 207*9950eceeSBaptiste Daroussin abi = "o32"; 208*9950eceeSBaptiste Daroussin break; 209*9950eceeSBaptiste Daroussin case E_MIPS_ABI_N32: 210*9950eceeSBaptiste Daroussin abi = "n32"; 211*9950eceeSBaptiste Daroussin break; 212*9950eceeSBaptiste Daroussin default: 213*9950eceeSBaptiste Daroussin if (elfhdr.e_ident[EI_DATA] == 214*9950eceeSBaptiste Daroussin ELFCLASS32) 215*9950eceeSBaptiste Daroussin abi = "o32"; 216*9950eceeSBaptiste Daroussin else if (elfhdr.e_ident[EI_DATA] == 217*9950eceeSBaptiste Daroussin ELFCLASS64) 218*9950eceeSBaptiste Daroussin abi = "n64"; 219*9950eceeSBaptiste Daroussin break; 220*9950eceeSBaptiste Daroussin } 221*9950eceeSBaptiste Daroussin snprintf(dest + strlen(dest), sz - strlen(dest), 222*9950eceeSBaptiste Daroussin ":%s:%s", elf_corres_to_string(endian_corres, 223*9950eceeSBaptiste Daroussin (int)elfhdr.e_ident[EI_DATA]), abi); 224*9950eceeSBaptiste Daroussin break; 225*9950eceeSBaptiste Daroussin } 226*9950eceeSBaptiste Daroussin 227*9950eceeSBaptiste Daroussin cleanup: 228*9950eceeSBaptiste Daroussin if (elf != NULL) 229*9950eceeSBaptiste Daroussin elf_end(elf); 230*9950eceeSBaptiste Daroussin 231*9950eceeSBaptiste Daroussin close(fd); 232*9950eceeSBaptiste Daroussin return (ret); 233*9950eceeSBaptiste Daroussin } 234*9950eceeSBaptiste Daroussin 235*9950eceeSBaptiste Daroussin static void 236*9950eceeSBaptiste Daroussin subst_packagesite(const char *abi) 237*9950eceeSBaptiste Daroussin { 238*9950eceeSBaptiste Daroussin struct sbuf *newval; 239*9950eceeSBaptiste Daroussin const char *variable_string; 240*9950eceeSBaptiste Daroussin const char *oldval; 241*9950eceeSBaptiste Daroussin 242*9950eceeSBaptiste Daroussin if (c[PACKAGESITE].value != NULL) 243*9950eceeSBaptiste Daroussin oldval = c[PACKAGESITE].value; 244*9950eceeSBaptiste Daroussin else 245*9950eceeSBaptiste Daroussin oldval = c[PACKAGESITE].val; 246*9950eceeSBaptiste Daroussin 247*9950eceeSBaptiste Daroussin if ((variable_string = strstr(oldval, "${ABI}")) == NULL) 248*9950eceeSBaptiste Daroussin return; 249*9950eceeSBaptiste Daroussin 250*9950eceeSBaptiste Daroussin newval = sbuf_new_auto(); 251*9950eceeSBaptiste Daroussin sbuf_bcat(newval, oldval, variable_string - oldval); 252*9950eceeSBaptiste Daroussin sbuf_cat(newval, abi); 253*9950eceeSBaptiste Daroussin sbuf_cat(newval, variable_string + strlen("${ABI}")); 254*9950eceeSBaptiste Daroussin sbuf_finish(newval); 255*9950eceeSBaptiste Daroussin 256*9950eceeSBaptiste Daroussin free(c[PACKAGESITE].value); 257*9950eceeSBaptiste Daroussin c[PACKAGESITE].value = strdup(sbuf_data(newval)); 258*9950eceeSBaptiste Daroussin } 259*9950eceeSBaptiste Daroussin 260*9950eceeSBaptiste Daroussin static void 261*9950eceeSBaptiste Daroussin config_parse(yaml_document_t *doc, yaml_node_t *node) 262*9950eceeSBaptiste Daroussin { 263*9950eceeSBaptiste Daroussin yaml_node_pair_t *pair; 264*9950eceeSBaptiste Daroussin yaml_node_t *key, *val; 265*9950eceeSBaptiste Daroussin struct sbuf *buf = sbuf_new_auto(); 266*9950eceeSBaptiste Daroussin int i; 267*9950eceeSBaptiste Daroussin size_t j; 268*9950eceeSBaptiste Daroussin 269*9950eceeSBaptiste Daroussin pair = node->data.mapping.pairs.start; 270*9950eceeSBaptiste Daroussin 271*9950eceeSBaptiste Daroussin while (pair < node->data.mapping.pairs.top) { 272*9950eceeSBaptiste Daroussin key = yaml_document_get_node(doc, pair->key); 273*9950eceeSBaptiste Daroussin val = yaml_document_get_node(doc, pair->value); 274*9950eceeSBaptiste Daroussin 275*9950eceeSBaptiste Daroussin /* 276*9950eceeSBaptiste Daroussin * ignoring silently empty keys can be empty lines 277*9950eceeSBaptiste Daroussin * or user mistakes 278*9950eceeSBaptiste Daroussin */ 279*9950eceeSBaptiste Daroussin if (key->data.scalar.length <= 0) { 280*9950eceeSBaptiste Daroussin ++pair; 281*9950eceeSBaptiste Daroussin continue; 282*9950eceeSBaptiste Daroussin } 283*9950eceeSBaptiste Daroussin 284*9950eceeSBaptiste Daroussin /* 285*9950eceeSBaptiste Daroussin * silently skip on purpose to allow user to leave 286*9950eceeSBaptiste Daroussin * empty lines without complaining 287*9950eceeSBaptiste Daroussin */ 288*9950eceeSBaptiste Daroussin if (val->type == YAML_NO_NODE || 289*9950eceeSBaptiste Daroussin (val->type == YAML_SCALAR_NODE && 290*9950eceeSBaptiste Daroussin val->data.scalar.length <= 0)) { 291*9950eceeSBaptiste Daroussin ++pair; 292*9950eceeSBaptiste Daroussin continue; 293*9950eceeSBaptiste Daroussin } 294*9950eceeSBaptiste Daroussin 295*9950eceeSBaptiste Daroussin sbuf_clear(buf); 296*9950eceeSBaptiste Daroussin for (j = 0; j < strlen(key->data.scalar.value); ++j) 297*9950eceeSBaptiste Daroussin sbuf_putc(buf, toupper(key->data.scalar.value[j])); 298*9950eceeSBaptiste Daroussin 299*9950eceeSBaptiste Daroussin sbuf_finish(buf); 300*9950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 301*9950eceeSBaptiste Daroussin if (strcmp(sbuf_data(buf), c[i].key) == 0) 302*9950eceeSBaptiste Daroussin break; 303*9950eceeSBaptiste Daroussin } 304*9950eceeSBaptiste Daroussin 305*9950eceeSBaptiste Daroussin if (i == CONFIG_SIZE) { 306*9950eceeSBaptiste Daroussin ++pair; 307*9950eceeSBaptiste Daroussin continue; 308*9950eceeSBaptiste Daroussin } 309*9950eceeSBaptiste Daroussin 310*9950eceeSBaptiste Daroussin /* env has priority over config file */ 311*9950eceeSBaptiste Daroussin if (c[i].envset) { 312*9950eceeSBaptiste Daroussin ++pair; 313*9950eceeSBaptiste Daroussin continue; 314*9950eceeSBaptiste Daroussin } 315*9950eceeSBaptiste Daroussin 316*9950eceeSBaptiste Daroussin c[i].value = strdup(val->data.scalar.value); 317*9950eceeSBaptiste Daroussin ++pair; 318*9950eceeSBaptiste Daroussin } 319*9950eceeSBaptiste Daroussin 320*9950eceeSBaptiste Daroussin sbuf_delete(buf); 321*9950eceeSBaptiste Daroussin } 322*9950eceeSBaptiste Daroussin 323*9950eceeSBaptiste Daroussin int 324*9950eceeSBaptiste Daroussin config_init(void) 325*9950eceeSBaptiste Daroussin { 326*9950eceeSBaptiste Daroussin FILE *fp; 327*9950eceeSBaptiste Daroussin yaml_parser_t parser; 328*9950eceeSBaptiste Daroussin yaml_document_t doc; 329*9950eceeSBaptiste Daroussin yaml_node_t *node; 330*9950eceeSBaptiste Daroussin const char *val; 331*9950eceeSBaptiste Daroussin int i; 332*9950eceeSBaptiste Daroussin const char *localbase; 333*9950eceeSBaptiste Daroussin char confpath[MAXPATHLEN]; 334*9950eceeSBaptiste Daroussin char abi[BUFSIZ]; 335*9950eceeSBaptiste Daroussin 336*9950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) { 337*9950eceeSBaptiste Daroussin val = getenv(c[i].key); 338*9950eceeSBaptiste Daroussin if (val != NULL) { 339*9950eceeSBaptiste Daroussin c[i].val = val; 340*9950eceeSBaptiste Daroussin c[i].envset = true; 341*9950eceeSBaptiste Daroussin } 342*9950eceeSBaptiste Daroussin } 343*9950eceeSBaptiste Daroussin 344*9950eceeSBaptiste Daroussin localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE; 345*9950eceeSBaptiste Daroussin snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", localbase); 346*9950eceeSBaptiste Daroussin 347*9950eceeSBaptiste Daroussin if ((fp = fopen(confpath, "r")) == NULL) { 348*9950eceeSBaptiste Daroussin if (errno != ENOENT) 349*9950eceeSBaptiste Daroussin err(EXIT_FAILURE, "Unable to open configuration file %s", confpath); 350*9950eceeSBaptiste Daroussin /* no configuration present */ 351*9950eceeSBaptiste Daroussin goto finalize; 352*9950eceeSBaptiste Daroussin } 353*9950eceeSBaptiste Daroussin 354*9950eceeSBaptiste Daroussin yaml_parser_initialize(&parser); 355*9950eceeSBaptiste Daroussin yaml_parser_set_input_file(&parser, fp); 356*9950eceeSBaptiste Daroussin yaml_parser_load(&parser, &doc); 357*9950eceeSBaptiste Daroussin 358*9950eceeSBaptiste Daroussin node = yaml_document_get_root_node(&doc); 359*9950eceeSBaptiste Daroussin 360*9950eceeSBaptiste Daroussin if (node != NULL) { 361*9950eceeSBaptiste Daroussin if (node->type != YAML_MAPPING_NODE) 362*9950eceeSBaptiste Daroussin warnx("Invalid configuration format, ignoring the configuration file"); 363*9950eceeSBaptiste Daroussin else 364*9950eceeSBaptiste Daroussin config_parse(&doc, node); 365*9950eceeSBaptiste Daroussin } else { 366*9950eceeSBaptiste Daroussin warnx("Invalid configuration format, ignoring the configuration file"); 367*9950eceeSBaptiste Daroussin } 368*9950eceeSBaptiste Daroussin 369*9950eceeSBaptiste Daroussin yaml_document_delete(&doc); 370*9950eceeSBaptiste Daroussin yaml_parser_delete(&parser); 371*9950eceeSBaptiste Daroussin 372*9950eceeSBaptiste Daroussin finalize: 373*9950eceeSBaptiste Daroussin if (c[ABI].val == NULL && c[ABI].value == NULL) { 374*9950eceeSBaptiste Daroussin if (pkg_get_myabi(abi, BUFSIZ) != 0) 375*9950eceeSBaptiste Daroussin errx(EXIT_FAILURE, "Failed to determine the system ABI"); 376*9950eceeSBaptiste Daroussin c[ABI].val = abi; 377*9950eceeSBaptiste Daroussin } 378*9950eceeSBaptiste Daroussin 379*9950eceeSBaptiste Daroussin subst_packagesite(c[ABI].val); 380*9950eceeSBaptiste Daroussin 381*9950eceeSBaptiste Daroussin return (0); 382*9950eceeSBaptiste Daroussin } 383*9950eceeSBaptiste Daroussin 384*9950eceeSBaptiste Daroussin int 385*9950eceeSBaptiste Daroussin config_string(pkg_config_key k, const char **val) 386*9950eceeSBaptiste Daroussin { 387*9950eceeSBaptiste Daroussin if (c[k].type != PKG_CONFIG_STRING) 388*9950eceeSBaptiste Daroussin return (-1); 389*9950eceeSBaptiste Daroussin 390*9950eceeSBaptiste Daroussin if (c[k].value != NULL) 391*9950eceeSBaptiste Daroussin *val = c[k].value; 392*9950eceeSBaptiste Daroussin else 393*9950eceeSBaptiste Daroussin *val = c[k].val; 394*9950eceeSBaptiste Daroussin 395*9950eceeSBaptiste Daroussin return (0); 396*9950eceeSBaptiste Daroussin } 397*9950eceeSBaptiste Daroussin 398*9950eceeSBaptiste Daroussin int 399*9950eceeSBaptiste Daroussin config_bool(pkg_config_key k, bool *val) 400*9950eceeSBaptiste Daroussin { 401*9950eceeSBaptiste Daroussin const char *value; 402*9950eceeSBaptiste Daroussin 403*9950eceeSBaptiste Daroussin if (c[k].type != PKG_CONFIG_BOOL) 404*9950eceeSBaptiste Daroussin return (-1); 405*9950eceeSBaptiste Daroussin 406*9950eceeSBaptiste Daroussin *val = false; 407*9950eceeSBaptiste Daroussin 408*9950eceeSBaptiste Daroussin if (c[k].value != NULL) 409*9950eceeSBaptiste Daroussin value = c[k].value; 410*9950eceeSBaptiste Daroussin else 411*9950eceeSBaptiste Daroussin value = c[k].val; 412*9950eceeSBaptiste Daroussin 413*9950eceeSBaptiste Daroussin if (strcasecmp(value, "true") == 0 || 414*9950eceeSBaptiste Daroussin strcasecmp(value, "yes") == 0 || 415*9950eceeSBaptiste Daroussin strcasecmp(value, "on") == 0 || 416*9950eceeSBaptiste Daroussin *value == '1') 417*9950eceeSBaptiste Daroussin *val = true; 418*9950eceeSBaptiste Daroussin 419*9950eceeSBaptiste Daroussin return (0); 420*9950eceeSBaptiste Daroussin } 421*9950eceeSBaptiste Daroussin 422*9950eceeSBaptiste Daroussin void 423*9950eceeSBaptiste Daroussin config_finish(void) { 424*9950eceeSBaptiste Daroussin int i; 425*9950eceeSBaptiste Daroussin 426*9950eceeSBaptiste Daroussin for (i = 0; i < CONFIG_SIZE; i++) 427*9950eceeSBaptiste Daroussin free(c[i].value); 428*9950eceeSBaptiste Daroussin } 429