summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
committersjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
commit97d8b9495668afa398ab17c8c5f7e223b5fd2e89 (patch)
tree54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /usr.sbin/pkg
parent5ee3bfdb338e7c80af29a67f4425c4be24c7b866 (diff)
parent086d73aef6d0ab7d21daa2076fdc8d25961f9b05 (diff)
downloadFreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.zip
FreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.tar.gz
sync from head
Diffstat (limited to 'usr.sbin/pkg')
-rw-r--r--usr.sbin/pkg/Makefile6
-rw-r--r--usr.sbin/pkg/config.c428
-rw-r--r--usr.sbin/pkg/config.h52
-rw-r--r--usr.sbin/pkg/pkg.c192
4 files changed, 505 insertions, 173 deletions
diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile
index c2ca0a3..d244bd2 100644
--- a/usr.sbin/pkg/Makefile
+++ b/usr.sbin/pkg/Makefile
@@ -1,10 +1,10 @@
# $FreeBSD$
PROG= pkg
-SRCS= pkg.c dns_utils.c
+SRCS= pkg.c dns_utils.c config.c
NO_MAN= yes
-DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH}
-LDADD= -larchive -lelf -lfetch
+DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH} ${LIBBSDYML} ${LIBSBUF}
+LDADD= -larchive -lelf -lfetch -lbsdyml -lsbuf
.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg/config.c b/usr.sbin/pkg/config.c
new file mode 100644
index 0000000..5924d57
--- /dev/null
+++ b/usr.sbin/pkg/config.c
@@ -0,0 +1,428 @@
+/*-
+ * Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/sbuf.h>
+#include <sys/elf_common.h>
+#include <sys/endian.h>
+
+#include <bsdyml.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "elf_tables.h"
+#include "config.h"
+
+#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+
+struct config_entry {
+ uint8_t type;
+ const char *key;
+ const char *val;
+ char *value;
+ bool envset;
+};
+
+static struct config_entry c[] = {
+ [PACKAGESITE] = {
+ PKG_CONFIG_STRING,
+ "PACKAGESITE",
+ "http://pkg.FreeBSD.org/${ABI}/latest",
+ NULL,
+ false,
+ },
+ [ABI] = {
+ PKG_CONFIG_STRING,
+ "ABI",
+ NULL,
+ NULL,
+ false,
+ },
+ [MIRROR_TYPE] = {
+ PKG_CONFIG_STRING,
+ "MIRROR_TYPE",
+ "SRV",
+ NULL,
+ false,
+ },
+ [ASSUME_ALWAYS_YES] = {
+ PKG_CONFIG_BOOL,
+ "ASSUME_ALWAYS_YES",
+ "NO",
+ NULL,
+ false,
+ }
+};
+
+static const char *
+elf_corres_to_string(struct _elf_corres *m, int e)
+{
+ int i;
+
+ for (i = 0; m[i].string != NULL; i++)
+ if (m[i].elf_nb == e)
+ return (m[i].string);
+
+ return ("unknown");
+}
+
+static int
+pkg_get_myabi(char *dest, size_t sz)
+{
+ Elf *elf;
+ Elf_Data *data;
+ Elf_Note note;
+ Elf_Scn *scn;
+ char *src, *osname;
+ const char *abi;
+ GElf_Ehdr elfhdr;
+ GElf_Shdr shdr;
+ int fd, i, ret;
+ uint32_t version;
+
+ version = 0;
+ ret = -1;
+ scn = NULL;
+ abi = NULL;
+
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ warnx("ELF library initialization failed: %s",
+ elf_errmsg(-1));
+ return (-1);
+ }
+
+ if ((fd = open(_PATH_BSHELL, O_RDONLY)) < 0) {
+ warn("open()");
+ return (-1);
+ }
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ ret = -1;
+ warnx("elf_begin() failed: %s.", elf_errmsg(-1));
+ goto cleanup;
+ }
+
+ if (gelf_getehdr(elf, &elfhdr) == NULL) {
+ ret = -1;
+ warn("getehdr() failed: %s.", elf_errmsg(-1));
+ goto cleanup;
+ }
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ if (gelf_getshdr(scn, &shdr) != &shdr) {
+ ret = -1;
+ warn("getshdr() failed: %s.", elf_errmsg(-1));
+ goto cleanup;
+ }
+
+ if (shdr.sh_type == SHT_NOTE)
+ break;
+ }
+
+ if (scn == NULL) {
+ ret = -1;
+ warn("failed to get the note section");
+ goto cleanup;
+ }
+
+ data = elf_getdata(scn, NULL);
+ src = data->d_buf;
+ for (;;) {
+ memcpy(&note, src, sizeof(Elf_Note));
+ src += sizeof(Elf_Note);
+ if (note.n_type == NT_VERSION)
+ break;
+ src += note.n_namesz + note.n_descsz;
+ }
+ osname = src;
+ src += roundup2(note.n_namesz, 4);
+ if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB)
+ version = be32dec(src);
+ else
+ version = le32dec(src);
+
+ for (i = 0; osname[i] != '\0'; i++)
+ osname[i] = (char)tolower(osname[i]);
+
+ snprintf(dest, sz, "%s:%d:%s:%s",
+ osname, version / 100000,
+ elf_corres_to_string(mach_corres, (int)elfhdr.e_machine),
+ elf_corres_to_string(wordsize_corres,
+ (int)elfhdr.e_ident[EI_CLASS]));
+
+ ret = 0;
+
+ switch (elfhdr.e_machine) {
+ case EM_ARM:
+ snprintf(dest + strlen(dest), sz - strlen(dest),
+ ":%s:%s:%s", elf_corres_to_string(endian_corres,
+ (int)elfhdr.e_ident[EI_DATA]),
+ (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
+ "eabi" : "oabi",
+ (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
+ "softfp" : "vfp");
+ break;
+ case EM_MIPS:
+ /*
+ * this is taken from binutils sources:
+ * include/elf/mips.h
+ * mapping is figured out from binutils:
+ * gas/config/tc-mips.c
+ */
+ switch (elfhdr.e_flags & EF_MIPS_ABI) {
+ case E_MIPS_ABI_O32:
+ abi = "o32";
+ break;
+ case E_MIPS_ABI_N32:
+ abi = "n32";
+ break;
+ default:
+ if (elfhdr.e_ident[EI_DATA] ==
+ ELFCLASS32)
+ abi = "o32";
+ else if (elfhdr.e_ident[EI_DATA] ==
+ ELFCLASS64)
+ abi = "n64";
+ break;
+ }
+ snprintf(dest + strlen(dest), sz - strlen(dest),
+ ":%s:%s", elf_corres_to_string(endian_corres,
+ (int)elfhdr.e_ident[EI_DATA]), abi);
+ break;
+ }
+
+cleanup:
+ if (elf != NULL)
+ elf_end(elf);
+
+ close(fd);
+ return (ret);
+}
+
+static void
+subst_packagesite(const char *abi)
+{
+ struct sbuf *newval;
+ const char *variable_string;
+ const char *oldval;
+
+ if (c[PACKAGESITE].value != NULL)
+ oldval = c[PACKAGESITE].value;
+ else
+ oldval = c[PACKAGESITE].val;
+
+ if ((variable_string = strstr(oldval, "${ABI}")) == NULL)
+ return;
+
+ newval = sbuf_new_auto();
+ sbuf_bcat(newval, oldval, variable_string - oldval);
+ sbuf_cat(newval, abi);
+ sbuf_cat(newval, variable_string + strlen("${ABI}"));
+ sbuf_finish(newval);
+
+ free(c[PACKAGESITE].value);
+ c[PACKAGESITE].value = strdup(sbuf_data(newval));
+}
+
+static void
+config_parse(yaml_document_t *doc, yaml_node_t *node)
+{
+ yaml_node_pair_t *pair;
+ yaml_node_t *key, *val;
+ struct sbuf *buf = sbuf_new_auto();
+ int i;
+ size_t j;
+
+ pair = node->data.mapping.pairs.start;
+
+ while (pair < node->data.mapping.pairs.top) {
+ key = yaml_document_get_node(doc, pair->key);
+ val = yaml_document_get_node(doc, pair->value);
+
+ /*
+ * ignoring silently empty keys can be empty lines
+ * or user mistakes
+ */
+ if (key->data.scalar.length <= 0) {
+ ++pair;
+ continue;
+ }
+
+ /*
+ * silently skip on purpose to allow user to leave
+ * empty lines without complaining
+ */
+ if (val->type == YAML_NO_NODE ||
+ (val->type == YAML_SCALAR_NODE &&
+ val->data.scalar.length <= 0)) {
+ ++pair;
+ continue;
+ }
+
+ 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);
+ for (i = 0; i < CONFIG_SIZE; i++) {
+ if (strcmp(sbuf_data(buf), c[i].key) == 0)
+ break;
+ }
+
+ if (i == CONFIG_SIZE) {
+ ++pair;
+ continue;
+ }
+
+ /* env has priority over config file */
+ if (c[i].envset) {
+ ++pair;
+ continue;
+ }
+
+ c[i].value = strdup(val->data.scalar.value);
+ ++pair;
+ }
+
+ sbuf_delete(buf);
+}
+
+int
+config_init(void)
+{
+ FILE *fp;
+ yaml_parser_t parser;
+ yaml_document_t doc;
+ yaml_node_t *node;
+ const char *val;
+ int i;
+ const char *localbase;
+ char confpath[MAXPATHLEN];
+ char abi[BUFSIZ];
+
+ for (i = 0; i < CONFIG_SIZE; i++) {
+ val = getenv(c[i].key);
+ if (val != NULL) {
+ c[i].val = val;
+ c[i].envset = true;
+ }
+ }
+
+ localbase = getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE;
+ snprintf(confpath, sizeof(confpath), "%s/etc/pkg.conf", localbase);
+
+ if ((fp = fopen(confpath, "r")) == NULL) {
+ if (errno != ENOENT)
+ err(EXIT_FAILURE, "Unable to open configuration file %s", confpath);
+ /* no configuration present */
+ goto finalize;
+ }
+
+ 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) {
+ 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:
+ if (c[ABI].val == NULL && c[ABI].value == NULL) {
+ if (pkg_get_myabi(abi, BUFSIZ) != 0)
+ errx(EXIT_FAILURE, "Failed to determine the system ABI");
+ c[ABI].val = abi;
+ }
+
+ subst_packagesite(c[ABI].value != NULL ? c[ABI].value : c[ABI].val);
+
+ return (0);
+}
+
+int
+config_string(pkg_config_key k, const char **val)
+{
+ if (c[k].type != PKG_CONFIG_STRING)
+ return (-1);
+
+ if (c[k].value != NULL)
+ *val = c[k].value;
+ else
+ *val = c[k].val;
+
+ return (0);
+}
+
+int
+config_bool(pkg_config_key k, bool *val)
+{
+ const char *value;
+
+ if (c[k].type != PKG_CONFIG_BOOL)
+ return (-1);
+
+ *val = false;
+
+ if (c[k].value != NULL)
+ value = c[k].value;
+ else
+ value = c[k].val;
+
+ if (strcasecmp(value, "true") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "on") == 0 ||
+ *value == '1')
+ *val = true;
+
+ return (0);
+}
+
+void
+config_finish(void) {
+ int i;
+
+ for (i = 0; i < CONFIG_SIZE; i++)
+ free(c[i].value);
+}
diff --git a/usr.sbin/pkg/config.h b/usr.sbin/pkg/config.h
new file mode 100644
index 0000000..e592f6d
--- /dev/null
+++ b/usr.sbin/pkg/config.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2013 Baptiste Daroussin <bapt@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PKG_CONFIG_H
+#define _PKG_CONFIG_H
+
+#define _LOCALBASE "/usr/local"
+
+typedef enum {
+ PACKAGESITE = 0,
+ ABI,
+ MIRROR_TYPE,
+ ASSUME_ALWAYS_YES,
+ CONFIG_SIZE
+} pkg_config_key;
+
+typedef enum {
+ PKG_CONFIG_STRING=0,
+ PKG_CONFIG_BOOL,
+} pkg_config_t;
+
+int config_init(void);
+void config_finish(void);
+int config_string(pkg_config_key, const char **);
+int config_bool(pkg_config_key, bool *);
+
+#endif
diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c
index 1b3146b..0aef3da 100644
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (c) 2012-2013 Baptiste Daroussin <bapt@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,175 +28,23 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/elf_common.h>
-#include <sys/endian.h>
#include <sys/wait.h>
#include <archive.h>
#include <archive_entry.h>
-#include <ctype.h>
#include <err.h>
#include <errno.h>
-#include <fcntl.h>
#include <fetch.h>
-#include <gelf.h>
#include <paths.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
-#include "elf_tables.h"
#include "dns_utils.h"
-
-#define _LOCALBASE "/usr/local"
-#define _PKGS_URL "http://pkg.FreeBSD.org"
-
-static const char *
-elf_corres_to_string(struct _elf_corres *m, int e)
-{
- int i;
-
- for (i = 0; m[i].string != NULL; i++)
- if (m[i].elf_nb == e)
- return (m[i].string);
-
- return ("unknown");
-}
-
-static int
-pkg_get_myabi(char *dest, size_t sz)
-{
- Elf *elf;
- Elf_Data *data;
- Elf_Note note;
- Elf_Scn *scn;
- char *src, *osname;
- const char *abi;
- GElf_Ehdr elfhdr;
- GElf_Shdr shdr;
- int fd, i, ret;
- uint32_t version;
-
- version = 0;
- ret = -1;
- scn = NULL;
- abi = NULL;
-
- if (elf_version(EV_CURRENT) == EV_NONE) {
- warnx("ELF library initialization failed: %s",
- elf_errmsg(-1));
- return (-1);
- }
-
- if ((fd = open("/bin/sh", O_RDONLY)) < 0) {
- warn("open()");
- return (-1);
- }
-
- if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- ret = -1;
- warnx("elf_begin() failed: %s.", elf_errmsg(-1));
- goto cleanup;
- }
-
- if (gelf_getehdr(elf, &elfhdr) == NULL) {
- ret = -1;
- warn("getehdr() failed: %s.", elf_errmsg(-1));
- goto cleanup;
- }
-
- while ((scn = elf_nextscn(elf, scn)) != NULL) {
- if (gelf_getshdr(scn, &shdr) != &shdr) {
- ret = -1;
- warn("getshdr() failed: %s.", elf_errmsg(-1));
- goto cleanup;
- }
-
- if (shdr.sh_type == SHT_NOTE)
- break;
- }
-
- if (scn == NULL) {
- ret = -1;
- warn("failed to get the note section");
- goto cleanup;
- }
-
- data = elf_getdata(scn, NULL);
- src = data->d_buf;
- for (;;) {
- memcpy(&note, src, sizeof(Elf_Note));
- src += sizeof(Elf_Note);
- if (note.n_type == NT_VERSION)
- break;
- src += note.n_namesz + note.n_descsz;
- }
- osname = src;
- src += note.n_namesz;
- if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB)
- version = be32dec(src);
- else
- version = le32dec(src);
-
- for (i = 0; osname[i] != '\0'; i++)
- osname[i] = (char)tolower(osname[i]);
-
- snprintf(dest, sz, "%s:%d:%s:%s",
- osname, version / 100000,
- elf_corres_to_string(mach_corres, (int)elfhdr.e_machine),
- elf_corres_to_string(wordsize_corres,
- (int)elfhdr.e_ident[EI_CLASS]));
-
- ret = 0;
-
- switch (elfhdr.e_machine) {
- case EM_ARM:
- snprintf(dest + strlen(dest), sz - strlen(dest),
- ":%s:%s:%s", elf_corres_to_string(endian_corres,
- (int)elfhdr.e_ident[EI_DATA]),
- (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
- "eabi" : "oabi",
- (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
- "softfp" : "vfp");
- break;
- case EM_MIPS:
- /*
- * this is taken from binutils sources:
- * include/elf/mips.h
- * mapping is figured out from binutils:
- * gas/config/tc-mips.c
- */
- switch (elfhdr.e_flags & EF_MIPS_ABI) {
- case E_MIPS_ABI_O32:
- abi = "o32";
- break;
- case E_MIPS_ABI_N32:
- abi = "n32";
- break;
- default:
- if (elfhdr.e_ident[EI_DATA] ==
- ELFCLASS32)
- abi = "o32";
- else if (elfhdr.e_ident[EI_DATA] ==
- ELFCLASS64)
- abi = "n64";
- break;
- }
- snprintf(dest + strlen(dest), sz - strlen(dest),
- ":%s:%s", elf_corres_to_string(endian_corres,
- (int)elfhdr.e_ident[EI_DATA]), abi);
- break;
- }
-
-cleanup:
- if (elf != NULL)
- elf_end(elf);
-
- close(fd);
- return (ret);
-}
+#include "config.h"
static int
extract_pkg_static(int fd, char *p, int sz)
@@ -212,7 +60,7 @@ extract_pkg_static(int fd, char *p, int sz)
warn("archive_read_new");
return (ret);
}
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_tar(a);
if (lseek(fd, 0, 0) == -1) {
@@ -247,7 +95,7 @@ extract_pkg_static(int fd, char *p, int sz)
warnx("fail to extract pkg-static");
cleanup:
- archive_read_finish(a);
+ archive_read_free(a);
return (ret);
}
@@ -291,8 +139,8 @@ bootstrap_pkg(void)
char zone[MAXHOSTNAMELEN + 13];
char url[MAXPATHLEN];
char conf[MAXPATHLEN];
- char abi[BUFSIZ];
char tmppkg[MAXPATHLEN];
+ const char *packagesite, *mirror_type;
char buf[10240];
char pkgstatic[MAXPATHLEN];
int fd, retry, ret, max_retry;
@@ -311,17 +159,15 @@ bootstrap_pkg(void)
printf("Bootstrapping pkg please wait\n");
- if (pkg_get_myabi(abi, MAXPATHLEN) != 0) {
- warnx("failed to determine the system ABI");
+ if (config_string(PACKAGESITE, &packagesite) != 0) {
+ warnx("No PACKAGESITE defined");
return (-1);
}
-
- if (getenv("PACKAGESITE") != NULL)
- snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", getenv("PACKAGESITE"));
- else
- snprintf(url, MAXPATHLEN, "%s/%s/latest/Latest/pkg.txz",
- getenv("PACKAGEROOT") ? getenv("PACKAGEROOT") : _PKGS_URL,
- getenv("ABI") ? getenv("ABI") : abi);
+ if (config_string(MIRROR_TYPE, &mirror_type) != 0) {
+ warnx("No MIRROR_TYPE defined");
+ return (-1);
+ }
+ snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz", packagesite);
snprintf(tmppkg, MAXPATHLEN, "%s/pkg.txz.XXXXXX",
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP);
@@ -336,10 +182,10 @@ bootstrap_pkg(void)
u = fetchParseURL(url);
while (remote == NULL) {
if (retry == max_retry) {
- if (strcmp(u->scheme, "file") != 0) {
+ if (strcmp(u->scheme, "file") != 0 &&
+ strcasecmp(mirror_type, "srv") == 0) {
snprintf(zone, sizeof(zone),
"_%s._tcp.%s", u->scheme, u->host);
- printf("%s\n", zone);
mirrors = dns_getsrvinfo(zone);
current = mirrors;
}
@@ -411,6 +257,8 @@ bootstrap_pkg(void)
fetchfail:
warnx("Error fetching %s: %s", url, fetchLastErrString);
+ fprintf(stderr, "A pre-built version of pkg could not be found for your system.\n");
+ fprintf(stderr, "Consider changing PACKAGESITE or installing it from ports: 'ports-mgmt/pkg'.\n");
cleanup:
if (remote != NULL)
@@ -447,6 +295,7 @@ int
main(__unused int argc, char *argv[])
{
char pkgpath[MAXPATHLEN];
+ bool yes = false;
snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg",
getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);
@@ -465,7 +314,9 @@ main(__unused int argc, char *argv[])
* not tty. Check the environment to see if user has answer
* tucked in there already.
*/
- if (getenv("ASSUME_ALWAYS_YES") == NULL) {
+ config_init();
+ config_bool(ASSUME_ALWAYS_YES, &yes);
+ if (!yes) {
printf("%s", confirmation_message);
if (!isatty(fileno(stdin)))
exit(EXIT_FAILURE);
@@ -475,6 +326,7 @@ main(__unused int argc, char *argv[])
}
if (bootstrap_pkg() != 0)
exit(EXIT_FAILURE);
+ config_finish();
}
execv(pkgpath, argv);
OpenPOWER on IntegriCloud