From owner-svn-src-all@FreeBSD.ORG Tue Mar 11 18:15:07 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 46EC8FB; Tue, 11 Mar 2014 18:15:07 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 31FC4B70; Tue, 11 Mar 2014 18:15:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s2BIF7rc016364; Tue, 11 Mar 2014 18:15:07 GMT (envelope-from bapt@svn.freebsd.org) Received: (from bapt@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s2BIF58q016351; Tue, 11 Mar 2014 18:15:05 GMT (envelope-from bapt@svn.freebsd.org) Message-Id: <201403111815.s2BIF58q016351@svn.freebsd.org> From: Baptiste Daroussin Date: Tue, 11 Mar 2014 18:15:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r263038 - stable/9/usr.sbin/pkg X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Mar 2014 18:15:07 -0000 Author: bapt Date: Tue Mar 11 18:15:05 2014 New Revision: 263038 URL: http://svnweb.freebsd.org/changeset/base/263038 Log: MFC: r241737,r246790,r247060,r247841,r248033,r248133,r255468,r256450,r256770 r256971,r256978,r257051,r257142,r257145,r257146,r257147,r257148,r257149 r257158,r257193,r257377,r257378,r257400,r257505,r257668,r257701,r257945 r258020,r258226,r258348,r258550,r259266,r259773,r259774,r259775,r262400 r262401,r262419 Sync pkg(7) with head: - signature checking - respecting and reading repository configurations - support pkg bootstrap -f Direct modifications: - Support old libarchive - Support old openssl API - Define non yet existing elf macros Added: stable/9/usr.sbin/pkg/config.c - copied, changed from r247841, head/usr.sbin/pkg/config.c stable/9/usr.sbin/pkg/config.h - copied, changed from r247841, head/usr.sbin/pkg/config.h stable/9/usr.sbin/pkg/pkg.7 - copied, changed from r257378, head/usr.sbin/pkg/pkg.7 Modified: stable/9/usr.sbin/pkg/Makefile stable/9/usr.sbin/pkg/dns_utils.c stable/9/usr.sbin/pkg/dns_utils.h stable/9/usr.sbin/pkg/elf_tables.h stable/9/usr.sbin/pkg/pkg.c Directory Properties: stable/9/usr.sbin/pkg/ (props changed) Modified: stable/9/usr.sbin/pkg/Makefile ============================================================================== --- stable/9/usr.sbin/pkg/Makefile Tue Mar 11 17:20:50 2014 (r263037) +++ stable/9/usr.sbin/pkg/Makefile Tue Mar 11 18:15:05 2014 (r263038) @@ -1,10 +1,14 @@ # $FreeBSD$ PROG= pkg -SRCS= pkg.c dns_utils.c +SRCS= pkg.c dns_utils.c config.c +MAN= pkg.7 -NO_MAN= yes -DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH} -LDADD= -larchive -lelf -lfetch +CFLAGS+=-I${.CURDIR}/../../contrib/libucl/include +.PATH: ${.CURDIR}/../../contrib/libucl/include +DPADD= ${LIBARCHIVE} ${LIBELF} ${LIBFETCH} ${LIBUCL} ${LIBSBUF} ${LIBSSL} \ + ${LIBCRYPTO} +LDADD= -larchive -lelf -lfetch -lucl -lsbuf -lssl -lcrypto +USEPRIVATELIB= ucl .include Copied and modified: stable/9/usr.sbin/pkg/config.c (from r247841, head/usr.sbin/pkg/config.c) ============================================================================== --- head/usr.sbin/pkg/config.c Tue Mar 5 13:31:06 2013 (r247841, copy source) +++ stable/9/usr.sbin/pkg/config.c Tue Mar 11 18:15:05 2014 (r263038) @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2013 Baptiste Daroussin + * Copyright (c) 2014 Baptiste Daroussin + * Copyright (c) 2013 Bryan Drewery * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,8 +32,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include -#include +#include +#include #include #include #include @@ -49,11 +52,17 @@ __FBSDID("$FreeBSD$"); #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ +struct config_value { + char *value; + STAILQ_ENTRY(config_value) next; +}; + struct config_entry { uint8_t type; const char *key; const char *val; char *value; + STAILQ_HEAD(, config_value) *list; bool envset; }; @@ -61,7 +70,8 @@ static struct config_entry c[] = { [PACKAGESITE] = { PKG_CONFIG_STRING, "PACKAGESITE", - "http://pkg.FreeBSD.org/${ABI}/latest", + URL_SCHEME_PREFIX "http://pkg.FreeBSD.org/${ABI}/latest", + NULL, NULL, false, }, @@ -70,6 +80,7 @@ static struct config_entry c[] = { "ABI", NULL, NULL, + NULL, false, }, [MIRROR_TYPE] = { @@ -77,6 +88,7 @@ static struct config_entry c[] = { "MIRROR_TYPE", "SRV", NULL, + NULL, false, }, [ASSUME_ALWAYS_YES] = { @@ -84,8 +96,33 @@ static struct config_entry c[] = { "ASSUME_ALWAYS_YES", "NO", NULL, + NULL, false, - } + }, + [SIGNATURE_TYPE] = { + PKG_CONFIG_STRING, + "SIGNATURE_TYPE", + NULL, + NULL, + NULL, + false, + }, + [FINGERPRINTS] = { + PKG_CONFIG_STRING, + "FINGERPRINTS", + NULL, + NULL, + NULL, + false, + }, + [REPOS_DIR] = { + PKG_CONFIG_LIST, + "REPOS_DIR", + NULL, + NULL, + NULL, + false, + }, }; static const char * @@ -257,122 +294,291 @@ subst_packagesite(const char *abi) c[PACKAGESITE].value = strdup(sbuf_data(newval)); } +static int +boolstr_to_bool(const char *str) +{ + if (str != NULL && (strcasecmp(str, "true") == 0 || + strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0 || + str[0] == '1')) + return (true); + + return (false); +} + static void -config_parse(yaml_document_t *doc, yaml_node_t *node) +config_parse(ucl_object_t *obj, pkg_conf_file_t conftype) { - yaml_node_pair_t *pair; - yaml_node_t *key, *val; struct sbuf *buf = sbuf_new_auto(); + ucl_object_t *cur, *seq; + ucl_object_iter_t it = NULL, itseq = NULL; + struct config_entry *temp_config; + struct config_value *cv; + const char *key; int i; size_t j; - pair = node->data.mapping.pairs.start; + /* Temporary config for configs that may be disabled. */ + temp_config = calloc(CONFIG_SIZE, sizeof(struct config_entry)); - 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; + while ((cur = ucl_iterate_object(obj, &it, true))) { + key = ucl_object_key(cur); + if (key == NULL) continue; - } + sbuf_clear(buf); - /* - * 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; + if (conftype == CONFFILE_PKG) { + for (j = 0; j < strlen(key); ++j) + sbuf_putc(buf, key[j]); + sbuf_finish(buf); + } else if (conftype == CONFFILE_REPO) { + if (strcasecmp(key, "url") == 0) + sbuf_cpy(buf, "PACKAGESITE"); + else if (strcasecmp(key, "mirror_type") == 0) + sbuf_cpy(buf, "MIRROR_TYPE"); + else if (strcasecmp(key, "signature_type") == 0) + sbuf_cpy(buf, "SIGNATURE_TYPE"); + else if (strcasecmp(key, "fingerprints") == 0) + sbuf_cpy(buf, "FINGERPRINTS"); + else if (strcasecmp(key, "enabled") == 0) { + if ((cur->type != UCL_BOOLEAN) || + !ucl_object_toboolean(cur)) + goto cleanup; + } else + continue; + sbuf_finish(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); for (i = 0; i < CONFIG_SIZE; i++) { if (strcmp(sbuf_data(buf), c[i].key) == 0) break; } - if (i == CONFIG_SIZE) { - ++pair; + /* Silently skip unknown keys to be future compatible. */ + if (i == CONFIG_SIZE) continue; - } /* env has priority over config file */ - if (c[i].envset) { - ++pair; + if (c[i].envset) continue; + + /* Parse sequence value ["item1", "item2"] */ + switch (c[i].type) { + case PKG_CONFIG_LIST: + if (cur->type != UCL_ARRAY) { + warnx("Skipping invalid array " + "value for %s.\n", c[i].key); + continue; + } + temp_config[i].list = + malloc(sizeof(*temp_config[i].list)); + STAILQ_INIT(temp_config[i].list); + + while ((seq = ucl_iterate_object(cur, &itseq, true))) { + if (seq->type != UCL_STRING) + continue; + cv = malloc(sizeof(struct config_value)); + cv->value = + strdup(ucl_object_tostring(seq)); + STAILQ_INSERT_TAIL(temp_config[i].list, cv, + next); + } + break; + default: + /* Normal string value. */ + temp_config[i].value = strdup(ucl_object_tostring(cur)); + break; } + } - c[i].value = strdup(val->data.scalar.value); - ++pair; + /* Repo is enabled, copy over all settings from temp_config. */ + for (i = 0; i < CONFIG_SIZE; i++) { + if (c[i].envset) + continue; + switch (c[i].type) { + case PKG_CONFIG_LIST: + c[i].list = temp_config[i].list; + break; + default: + c[i].value = temp_config[i].value; + break; + } } +cleanup: + free(temp_config); sbuf_delete(buf); } +/*- + * Parse new repo style configs in style: + * Name: + * URL: + * MIRROR_TYPE: + * etc... + */ +static void +parse_repo_file(ucl_object_t *obj) +{ + ucl_object_iter_t it = NULL; + ucl_object_t *cur; + const char *key; + + while ((cur = ucl_iterate_object(obj, &it, true))) { + key = ucl_object_key(cur); + + if (key == NULL) + continue; + + if (cur->type != UCL_OBJECT) + continue; + + config_parse(cur, CONFFILE_REPO); + } +} + + +static int +read_conf_file(const char *confpath, pkg_conf_file_t conftype) +{ + struct ucl_parser *p; + ucl_object_t *obj = NULL; + + p = ucl_parser_new(0); + + if (!ucl_parser_add_file(p, confpath)) { + if (errno != ENOENT) + errx(EXIT_FAILURE, "Unable to parse configuration " + "file %s: %s", confpath, ucl_parser_get_error(p)); + ucl_parser_free(p); + /* no configuration present */ + return (1); + } + + obj = ucl_parser_get_object(p); + if (obj->type != UCL_OBJECT) + warnx("Invalid configuration format, ignoring the " + "configuration file %s", confpath); + else { + if (conftype == CONFFILE_PKG) + config_parse(obj, conftype); + else if (conftype == CONFFILE_REPO) + parse_repo_file(obj); + } + + ucl_object_free(obj); + ucl_parser_free(p); + + return (0); +} + +static int +load_repositories(const char *repodir) +{ + struct dirent *ent; + DIR *d; + char *p; + size_t n; + char path[MAXPATHLEN]; + int ret; + + ret = 0; + + if ((d = opendir(repodir)) == NULL) + return (1); + + while ((ent = readdir(d))) { + /* Trim out 'repos'. */ + if ((n = strlen(ent->d_name)) <= 5) + continue; + p = &ent->d_name[n - 5]; + if (strcmp(p, ".conf") == 0) { + snprintf(path, sizeof(path), "%s%s%s", + repodir, + repodir[strlen(repodir) - 1] == '/' ? "" : "/", + ent->d_name); + if (access(path, F_OK) == 0 && + read_conf_file(path, CONFFILE_REPO)) { + ret = 1; + goto cleanup; + } + } + } + +cleanup: + closedir(d); + + return (ret); +} + int config_init(void) { - FILE *fp; - yaml_parser_t parser; - yaml_document_t doc; - yaml_node_t *node; - const char *val; + char *val; int i; const char *localbase; + char *env_list_item; char confpath[MAXPATHLEN]; + struct config_value *cv; 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; + switch (c[i].type) { + case PKG_CONFIG_LIST: + /* Split up comma-separated items from env. */ + c[i].list = malloc(sizeof(*c[i].list)); + STAILQ_INIT(c[i].list); + for (env_list_item = strtok(val, ","); + env_list_item != NULL; + env_list_item = strtok(NULL, ",")) { + cv = + malloc(sizeof(struct config_value)); + cv->value = + strdup(env_list_item); + STAILQ_INSERT_TAIL(c[i].list, cv, + next); + } + break; + default: + c[i].val = val; + break; + } } } + /* Read LOCALBASE/etc/pkg.conf first. */ 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 (errno != ENOENT) - err(EXIT_FAILURE, "Unable to open configuration file %s", confpath); - /* no configuration present */ + if (access(confpath, F_OK) == 0 && read_conf_file(confpath, + CONFFILE_PKG)) 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); + /* Then read in all repos from REPOS_DIR list of directories. */ + if (c[REPOS_DIR].list == NULL) { + c[REPOS_DIR].list = malloc(sizeof(*c[REPOS_DIR].list)); + STAILQ_INIT(c[REPOS_DIR].list); + cv = malloc(sizeof(struct config_value)); + cv->value = strdup("/etc/pkg"); + STAILQ_INSERT_TAIL(c[REPOS_DIR].list, cv, next); + cv = malloc(sizeof(struct config_value)); + if (asprintf(&cv->value, "%s/etc/pkg/repos", localbase) < 0) + goto finalize; + STAILQ_INSERT_TAIL(c[REPOS_DIR].list, cv, next); + } + + STAILQ_FOREACH(cv, c[REPOS_DIR].list, next) + if (load_repositories(cv->value)) + goto finalize; 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"); + errx(EXIT_FAILURE, "Failed to determine the system " + "ABI"); c[ABI].val = abi; } @@ -410,10 +616,7 @@ config_bool(pkg_config_key k, bool *val) else value = c[k].val; - if (strcasecmp(value, "true") == 0 || - strcasecmp(value, "yes") == 0 || - strcasecmp(value, "on") == 0 || - *value == '1') + if (boolstr_to_bool(value)) *val = true; return (0); Copied and modified: stable/9/usr.sbin/pkg/config.h (from r247841, head/usr.sbin/pkg/config.h) ============================================================================== --- head/usr.sbin/pkg/config.h Tue Mar 5 13:31:06 2013 (r247841, copy source) +++ stable/9/usr.sbin/pkg/config.h Tue Mar 11 18:15:05 2014 (r263038) @@ -30,20 +30,30 @@ #define _PKG_CONFIG_H #define _LOCALBASE "/usr/local" +#define URL_SCHEME_PREFIX "pkg+" typedef enum { PACKAGESITE = 0, ABI, MIRROR_TYPE, ASSUME_ALWAYS_YES, + SIGNATURE_TYPE, + FINGERPRINTS, + REPOS_DIR, CONFIG_SIZE } pkg_config_key; typedef enum { PKG_CONFIG_STRING=0, PKG_CONFIG_BOOL, + PKG_CONFIG_LIST, } pkg_config_t; +typedef enum { + CONFFILE_PKG=0, + CONFFILE_REPO, +} pkg_conf_file_t; + int config_init(void); void config_finish(void); int config_string(pkg_config_key, const char **); Modified: stable/9/usr.sbin/pkg/dns_utils.c ============================================================================== --- stable/9/usr.sbin/pkg/dns_utils.c Tue Mar 11 17:20:50 2014 (r263037) +++ stable/9/usr.sbin/pkg/dns_utils.c Tue Mar 11 18:15:05 2014 (r263038) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Baptiste Daroussin + * Copyright (c) 2012-2013 Baptiste Daroussin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,77 @@ typedef union { unsigned char buf[1024]; } dns_query; +static int +srv_priority_cmp(const void *a, const void *b) +{ + const struct dns_srvinfo *da, *db; + unsigned int r, l; + + da = *(struct dns_srvinfo * const *)a; + db = *(struct dns_srvinfo * const *)b; + + l = da->priority; + r = db->priority; + + return ((l > r) - (l < r)); +} + +static int +srv_final_cmp(const void *a, const void *b) +{ + const struct dns_srvinfo *da, *db; + unsigned int r, l, wr, wl; + int res; + + da = *(struct dns_srvinfo * const *)a; + db = *(struct dns_srvinfo * const *)b; + + l = da->priority; + r = db->priority; + + res = ((l > r) - (l < r)); + + if (res == 0) { + wl = da->finalweight; + wr = db->finalweight; + res = ((wr > wl) - (wr < wl)); + } + + return (res); +} + +static void +compute_weight(struct dns_srvinfo **d, int first, int last) +{ + int i, j, totalweight; + int *chosen; + + chosen = malloc(sizeof(int) * (last - first + 1)); + totalweight = 0; + + for (i = 0; i <= last; i++) + totalweight += d[i]->weight; + + if (totalweight == 0) + return; + + for (i = 0; i <= last; i++) { + for (;;) { + chosen[i] = random() % (d[i]->weight * 100 / totalweight); + for (j = 0; j < i; j++) { + if (chosen[i] == chosen[j]) + break; + } + if (j == i) { + d[i]->finalweight = chosen[i]; + break; + } + } + } + + free(chosen); +} + struct dns_srvinfo * dns_getsrvinfo(const char *zone) { @@ -46,7 +117,7 @@ dns_getsrvinfo(const char *zone) unsigned char *end, *p; char host[MAXHOSTNAMELEN]; dns_query q; - int len, qdcount, ancount, n, i; + int len, qdcount, ancount, n, i, f, l; unsigned int type, class, ttl, priority, weight, port; if ((len = res_query(zone, C_IN, T_SRV, q.buf, sizeof(q.buf))) == -1 || @@ -125,6 +196,21 @@ dns_getsrvinfo(const char *zone) n++; } + qsort(res, n, sizeof(res[0]), srv_priority_cmp); + + priority = f = l = 0; + for (i = 0; i < n; i++) { + if (res[i]->priority != priority) { + if (f != l) + compute_weight(res, f, l); + f = i; + priority = res[i]->priority; + } + l = i; + } + + qsort(res, n, sizeof(res[0]), srv_final_cmp); + for (i = 0; i < n - 1; i++) res[i]->next = res[i + 1]; Modified: stable/9/usr.sbin/pkg/dns_utils.h ============================================================================== --- stable/9/usr.sbin/pkg/dns_utils.h Tue Mar 11 17:20:50 2014 (r263037) +++ stable/9/usr.sbin/pkg/dns_utils.h Tue Mar 11 18:15:05 2014 (r263038) @@ -35,6 +35,7 @@ struct dns_srvinfo { unsigned int priority; unsigned int weight; unsigned int port; + unsigned int finalweight; char host[MAXHOSTNAMELEN]; struct dns_srvinfo *next; }; Modified: stable/9/usr.sbin/pkg/elf_tables.h ============================================================================== --- stable/9/usr.sbin/pkg/elf_tables.h Tue Mar 11 17:20:50 2014 (r263037) +++ stable/9/usr.sbin/pkg/elf_tables.h Tue Mar 11 18:15:05 2014 (r263038) @@ -34,7 +34,7 @@ struct _elf_corres { const char *string; }; -struct _elf_corres mach_corres[] = { +static struct _elf_corres mach_corres[] = { { EM_386, "x86" }, { EM_AMD64, "x86" }, { EM_ARM, "arm" }, @@ -46,33 +46,30 @@ struct _elf_corres mach_corres[] = { { -1, NULL }, }; -struct _elf_corres wordsize_corres[] = { +static struct _elf_corres wordsize_corres[] = { { ELFCLASS32, "32" }, { ELFCLASS64, "64" }, { -1, NULL}, }; -struct _elf_corres endian_corres[] = { +static struct _elf_corres endian_corres[] = { { ELFDATA2MSB, "eb" }, { ELFDATA2LSB, "el" }, { -1, NULL} }; -struct _elf_corres os_corres[] = { - { ELFOSABI_FREEBSD, "freebsd" }, - { -1, NULL } -}; - -#define EF_MIPS_ABI 0x0000F000 +#ifndef EF_ARM_NEW_ABI +#define EF_ARM_NEW_ABI 0x00000080UL +#endif +#ifndef EF_ARM_VFP_FLOAT +#define EF_ARM_VFP_FLOAT 0x00000400UL +#endif +#ifndef EF_MIPS_ABI +#define EF_MIPS_ABI 0x0000f000 +#endif #define E_MIPS_ABI_O32 0x00001000 #define E_MIPS_ABI_N32 0x00000020 -#define EF_ARM_NEW_ABI 0x80 -#define EF_ARM_OLD_ABI 0x100 - -#define EF_ARM_SOFT_FLOAT 0x200 -#define EF_ARM_VFP_FLOAT 0x400 - #define NT_VERSION 1 #define NT_ARCH 2 Copied and modified: stable/9/usr.sbin/pkg/pkg.7 (from r257378, head/usr.sbin/pkg/pkg.7) ============================================================================== --- head/usr.sbin/pkg/pkg.7 Wed Oct 30 10:39:14 2013 (r257378, copy source) +++ stable/9/usr.sbin/pkg/pkg.7 Tue Mar 11 18:15:05 2014 (r263038) @@ -24,22 +24,24 @@ .\" .\" $FreeBSD$ .\" -.Dd October 30, 2013 +.Dd December 12, 2013 .Dt PKG 7 .Os .Sh NAME .Nm pkg -.Nd a utility for manipulating packages. +.Nd a utility for manipulating packages .Sh SYNOPSIS .Nm .Ao Ar command Ac .Nm add +.Op Fl f .Ao Pa pkg.txz Ac .Nm .Fl N .Nm bootstrap +.Op Fl f .Sh DESCRIPTION .Nm is the package management tool. @@ -55,8 +57,7 @@ The first time invoked, will bootstrap the real .Xr pkg 8 from a remote repository. -.Pp -.Bl -tag -width "pkg add xxxxxxx" -compact +.Bl -tag -width "pkg bootstrap" .It Nm Ao Ar command Ac If .Xr pkg 8 @@ -64,7 +65,7 @@ is not installed yet, it will be fetched installed, and then have the original command forwarded to it. If already installed, the command requested will be forwarded to the real .Xr pkg 8 . -.It Nm Li add Ao Pa pkg.txz Ac +.It Nm Li add Oo Fl f Oc Ao Pa pkg.txz Ac Install .Xr pkg 8 from a local package instead of fetching from remote. @@ -73,16 +74,26 @@ If a file exists and signature checking is enabled, then the signature will be verified before installing the package. +If the +.Fl f +flag is specified, then +.Xr pkg 8 +will be installed regardless if it is already installed. .It Nm Fl N Do not bootstrap, just determine if .Xr pkg 8 is actually installed or not. Returns 0 and the number of packages installed if it is, otherwise 1. -.It Nm Li bootstrap +.It Nm Li bootstrap Op Fl f Attempt to bootstrap and do not forward anything to .Xr pkg 8 after it is installed. +If the +.Fl f +flag is specified, then +.Xr pkg 8 +will be fetched and installed regardless if it is already installed. .El .Sh CONFIGURATION Configuration varies in whether it is in a repository configuration file @@ -97,7 +108,7 @@ FreeBSD: { mirror_type: "srv", signature_type: "none", fingerprints: "/usr/share/keys/pkg", - enabled: "yes" + enabled: yes } .Ed .Bl -tag -width signature_type -compact @@ -136,12 +147,14 @@ Global configuration can be stored in .Pa /usr/local/etc/pkg.conf in the following format: .Bd -literal -offset indent -PACKAGESITE: "pkg+http://pkg.freebsd.org/${ABI}/latest", +PACKAGESITE: "pkg+http://pkg.FreeBSD.org/${ABI}/latest", MIRROR_TYPE: "srv", SIGNATURE_TYPE: "none", FINGERPRINTS: "/usr/share/keys/pkg", ASSUME_ALWAYS_YES: "yes" +REPOS_DIR: ["/etc/pkg", "/usr/local/etc/pkg/repos"] .Ed +.Pp Reference .Sx ENVIRONMENT for each variable. @@ -182,14 +195,20 @@ The URL that .Xr pkg 8 and other packages will be fetched from. +.It Ev REPOS_DIR +Comma-separated list of directories that should be searched for repository +configuration files. .El .Sh FILES Configuration is read from the files in the listed order. -The first enabled repository is the one used for bootstrapping +This path can be changed by setting +.Sy REPOS_DIR . +The last enabled repository is the one used for bootstrapping .Xr pkg 8 . .Bl -tag -width "/usr/local/etc/pkg/repos/*.conf" .It Pa /usr/local/etc/pkg.conf .It Pa /etc/pkg/FreeBSD.conf +.It Pa /usr/local/etc/pkg/repos/*.conf .El .Sh EXAMPLES Some examples are listed here. @@ -246,8 +265,8 @@ Check installed packages for checksum mi Check for missing dependencies: .Dl # pkg check -d -a .Sh SEE ALSO -.Xr pkg 8 , -.Xr ports 7 +.Xr ports 7 , +.Xr pkg 8 .Sh HISTORY The .Nm Modified: stable/9/usr.sbin/pkg/pkg.c ============================================================================== --- stable/9/usr.sbin/pkg/pkg.c Tue Mar 11 17:20:50 2014 (r263037) +++ stable/9/usr.sbin/pkg/pkg.c Tue Mar 11 18:15:05 2014 (r263038) @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2012 Baptiste Daroussin + * Copyright (c) 2012-2014 Baptiste Daroussin + * Copyright (c) 2013 Bryan Drewery * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,175 +29,56 @@ __FBSDID("$FreeBSD$"); #include -#include -#include +#include +#include +#include #include +#define _WITH_GETLINE #include #include -#include +#include #include #include #include #include -#include #include +#include #include #include #include #include #include +#include -#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(¬e, 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); +#include +#include - 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: *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***