Add support for reading configuration files from /etc/pkg.

For now only /etc/pkg/FreeBSD.conf is supported. Its style is:

Repo: {
   URL: "...",
   MIRROR_TYPE: "...",
   ...
}

The configuration will be read from /usr/local/etc/pkg.conf if exists,
otherwise /etc/pkg/FreeBSD.conf

Approved by:	bapt
MFC after: 	2 days
This commit is contained in:
Bryan Drewery 2013-10-26 03:31:05 +00:00
parent c20809e143
commit bc5e9ac08d
5 changed files with 123 additions and 32 deletions

View File

@ -225,6 +225,9 @@ distribution:
${_+_}cd ${.CURDIR}/devd; ${MAKE} install ${_+_}cd ${.CURDIR}/devd; ${MAKE} install
${_+_}cd ${.CURDIR}/gss; ${MAKE} install ${_+_}cd ${.CURDIR}/gss; ${MAKE} install
${_+_}cd ${.CURDIR}/periodic; ${MAKE} install ${_+_}cd ${.CURDIR}/periodic; ${MAKE} install
.if ${MK_PKGBOOTSTRAP} != "no"
${_+_}cd ${.CURDIR}/pkg; ${MAKE} install
.endif
${_+_}cd ${.CURDIR}/rc.d; ${MAKE} install ${_+_}cd ${.CURDIR}/rc.d; ${MAKE} install
${_+_}cd ${.CURDIR}/../gnu/usr.bin/send-pr; ${MAKE} etc-gnats-freefall ${_+_}cd ${.CURDIR}/../gnu/usr.bin/send-pr; ${MAKE} etc-gnats-freefall
${_+_}cd ${.CURDIR}/../share/termcap; ${MAKE} etc-termcap ${_+_}cd ${.CURDIR}/../share/termcap; ${MAKE} etc-termcap

6
etc/pkg/FreeBSD.conf Normal file
View File

@ -0,0 +1,6 @@
# $FreeBSD$
FreeBSD: {
url: "pkg+http://pkg.freebsd.org/${ABI}/latest",
mirror_type: "srv",
enabled: "yes"
}

10
etc/pkg/Makefile Normal file
View File

@ -0,0 +1,10 @@
# $FreeBSD$
NO_OBJ=
FILES= FreeBSD.conf
FILESDIR= /etc/pkg
FILESMODE= 644
.include <bsd.prog.mk>

View File

@ -460,7 +460,7 @@ subst_packagesite(const char *abi)
} }
static void static void
config_parse(yaml_document_t *doc, yaml_node_t *node) config_parse(yaml_document_t *doc, yaml_node_t *node, pkg_conf_file_t conftype)
{ {
yaml_node_pair_t *pair; yaml_node_pair_t *pair;
yaml_node_t *key, *val; yaml_node_t *key, *val;
@ -495,15 +495,33 @@ config_parse(yaml_document_t *doc, yaml_node_t *node)
} }
sbuf_clear(buf); sbuf_clear(buf);
for (j = 0; j < strlen(key->data.scalar.value); ++j)
sbuf_putc(buf, toupper(key->data.scalar.value[j]));
sbuf_finish(buf); if (conftype == CONFFILE_PKG) {
for (j = 0; j < strlen(key->data.scalar.value); ++j)
sbuf_putc(buf,
toupper(key->data.scalar.value[j]));
sbuf_finish(buf);
} else if (conftype == CONFFILE_REPO) {
/* The CONFFILE_REPO type is more restrictive. Only
parse known elements. */
if (strcasecmp(key->data.scalar.value, "url") == 0)
sbuf_cpy(buf, "PACKAGESITE");
else if (strcasecmp(key->data.scalar.value,
"mirror_type") == 0)
sbuf_cpy(buf, "MIRROR_TYPE");
else { /* Skip unknown entries for future use. */
++pair;
continue;
}
sbuf_finish(buf);
}
for (i = 0; i < CONFIG_SIZE; i++) { for (i = 0; i < CONFIG_SIZE; i++) {
if (strcmp(sbuf_data(buf), c[i].key) == 0) if (strcmp(sbuf_data(buf), c[i].key) == 0)
break; break;
} }
/* Silently skip unknown keys to be future compatible. */
if (i == CONFIG_SIZE) { if (i == CONFIG_SIZE) {
++pair; ++pair;
continue; continue;
@ -522,13 +540,80 @@ config_parse(yaml_document_t *doc, yaml_node_t *node)
sbuf_delete(buf); sbuf_delete(buf);
} }
int /*-
config_init(void) * Parse new repo style configs in style:
* Name:
* URL:
* MIRROR_TYPE:
* etc...
*/
static void
parse_repo_file(yaml_document_t *doc, yaml_node_t *node)
{
yaml_node_pair_t *pair;
pair = node->data.mapping.pairs.start;
while (pair < node->data.mapping.pairs.top) {
yaml_node_t *key = yaml_document_get_node(doc, pair->key);
yaml_node_t *val = yaml_document_get_node(doc, pair->value);
if (key->data.scalar.length <= 0) {
++pair;
continue;
}
if (val->type != YAML_MAPPING_NODE) {
++pair;
continue;
}
config_parse(doc, val, CONFFILE_REPO);
++pair;
}
}
static int
read_conf_file(const char *confpath, pkg_conf_file_t conftype)
{ {
FILE *fp; FILE *fp;
yaml_parser_t parser; yaml_parser_t parser;
yaml_document_t doc; yaml_document_t doc;
yaml_node_t *node; yaml_node_t *node;
if ((fp = fopen(confpath, "r")) == NULL) {
if (errno != ENOENT)
err(EXIT_FAILURE, "Unable to open configuration "
"file %s", confpath);
/* no configuration present */
return (1);
}
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, fp);
yaml_parser_load(&parser, &doc);
node = yaml_document_get_root_node(&doc);
if (node == NULL || node->type != YAML_MAPPING_NODE)
warnx("Invalid configuration format, ignoring the "
"configuration file %s", confpath);
else {
if (conftype == CONFFILE_PKG)
config_parse(&doc, node, conftype);
else if (conftype == CONFFILE_REPO)
parse_repo_file(&doc, node);
}
yaml_document_delete(&doc);
yaml_parser_delete(&parser);
return (0);
}
int
config_init(void)
{
const char *val; const char *val;
int i; int i;
const char *localbase; const char *localbase;
@ -544,35 +629,17 @@ config_init(void)
} }
localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE; localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE;
snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", localbase); snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf",
localbase);
if ((fp = fopen(confpath, "r")) == NULL) { if (access(confpath, F_OK) == 0 && read_conf_file(confpath,
if (errno != ENOENT) CONFFILE_PKG))
err(EXIT_FAILURE, "Unable to open configuration "
"file %s", confpath);
/* no configuration present */
goto finalize; goto finalize;
}
yaml_parser_initialize(&parser); snprintf(confpath, sizeof(confpath), "/etc/pkg/FreeBSD.conf");
yaml_parser_set_input_file(&parser, fp); if (access(confpath, F_OK) == 0 && read_conf_file(confpath,
yaml_parser_load(&parser, &doc); CONFFILE_REPO))
goto finalize;
node = yaml_document_get_root_node(&doc);
if (node != NULL) {
if (node->type != YAML_MAPPING_NODE)
warnx("Invalid configuration format, ignoring the "
"configuration file");
else
config_parse(&doc, node);
} else {
warnx("Invalid configuration format, ignoring the "
"configuration file");
}
yaml_document_delete(&doc);
yaml_parser_delete(&parser);
finalize: finalize:
if (c[ABI].val == NULL && c[ABI].value == NULL) { if (c[ABI].val == NULL && c[ABI].value == NULL) {

View File

@ -45,6 +45,11 @@ typedef enum {
PKG_CONFIG_BOOL, PKG_CONFIG_BOOL,
} pkg_config_t; } pkg_config_t;
typedef enum {
CONFFILE_PKG=0,
CONFFILE_REPO,
} pkg_conf_file_t;
int config_init(void); int config_init(void);
void config_finish(void); void config_finish(void);
int config_string(pkg_config_key, const char **); int config_string(pkg_config_key, const char **);