Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Merge branch 'master' of github.com:freebsd/pkg
Vsevolod Stakhov committed 9 years ago
commit d7f6ae839008ab2da4b4e77e71a7a378a45ab686
parent 6c2aa59
113 files changed +1239 -1288
modified NEWS
@@ -1,5 +1,10 @@
+
Changes from pkg 1.10
+
- Use dep_formula in the solver
+
- Cache pw result to avoid over reloading nssswitch.conf
+
- Remove pkg2ng and support for pkg_ databases
+

Changes from pkg 1.9
-
- Fix fd leak on systems without utimensat (merged in release branch)
+
- fix pkg which -g
- Do not use openssl for sha256
- Improve the default output when fetching data
- Update libfetch to the version of FreeBSD 11
@@ -7,7 +12,7 @@ Changes from pkg 1.9
- Fix NetBSD ABI
- Add a fallback for utimensat when reporting EOPNOTSUPP
- replace libsbuf with utstring for portability
-
- Overwrite some sqlite vfs functions to allow capsicumisation of pkg
+
- Overwrite some sqlite vfs functions to allow more capsicumisation of pkg
- move more pkg audit details into the library
- allow to run pkg query without any privileges
- extend the audit periodic script to report deprecated packages
@@ -25,7 +30,8 @@ Changes from pkg 1.9
- Add progress when fetching (number of files to fetch)
- Improved messages about locked packages
- Return 1 when a user rejects the proposed plan
-
- When dealing with configuration files '@config' never overwrites non tracked files
+
- When dealing with configuration files '@config' never overwrites non tracked
+
  files
- Warn everyone about deprecation of @dirrm and @exec
- Deduplicate metadata loading code
- pkg register now understands context aware messages
modified README.md
@@ -26,7 +26,6 @@ Table of Contents:
* [pkg bootstrap](#pkgbootstrap)
* [pkg in Ports](#pkgports)
* [Building pkg using sources from Git](#pkggit)
-
* [Converting an old-style pkg database](#pkg2ng)
* [A quick usage introduction to pkg](#usageintro)
* [Getting help on the commands usage](#pkghelp)
* [Querying the local package database](#pkginfo)
@@ -321,27 +320,6 @@ get on.
	make
	sudo make install

-
<a name="pkg2ng"></a>
-
### Converting an old-style pkg database
-

-
If you're on a 9.x system or earlier and did not have a release version
-
of pkg(8) installed previously, you will need to run the pkg2ng
-
script.  This is only necessary when converting your system from the
-
old pkg_tools style packages.
-

-
In order to register your installed packages to pkg, execute the
-
commands below:
-

-
	# cd pkg/ports
-
	# sh pkg2ng
-

-
Otherwise, running any pkg(8) command that will attempt to write to
-
the local package database will automatically apply any schema
-
updates.  Be aware that these may not be backwards compatible --
-
although usually you should see no more than a warning message if you
-
try and run an older version of pkg(8) against a newer database
-
schema.
-

<a name="usageintro"></a>
## A quick usage introduction to pkg

modified TODO.md
@@ -30,16 +30,16 @@ pkg autoremove could then remove it if nothing is depending on it anymore

Difficulty: medium

-
# (explore a ) rework of the library dependencies
+
# Explore a rework of the library dependencies

Would be nice to have a better mechanism that could track the symbols of the
libraries (including versions)

-
RPM is doing that
+
RPM already does this

# Allow duplicate package handling

-
to allow multiple packages having the same name as long as they don't conflicts
+
Allow multiple packages having the same name as long as they don't conflict

* pkg.conf:

@@ -62,7 +62,7 @@ to allow multiple packages having the same name as long as they don't conflicts

# Add support for zstd format

-
zstd is very interesting compression format that it would be nice to add support to
+
zstd is very interesting compression format that it would be nice to add support for

# Add the notion of triggers

@@ -76,12 +76,12 @@ for example:
gtk-update-icon-cache should provide a trigger for everything that provides an icon

if gtk-update-icon-cache is installed on the system and packages are flagged for
-
"icons" then the gtk icon cache would be upgraded.
+
"icons" then the gtk icon cache would be updated.

-
That would remove the gtk-update-icon-cache dependence from every application
+
That would remove the gtk-update-icon-cache dependency from every application
that provides icons and make it run only once.

-
# Allow to feed a list of non available packages
+
# Teach pkg repo to keep a list of unavailable packages

When a build fail the package is not added to the repository. As such, a user who attempts to install the package is told that it does not exist, rather than it is just temporarily unavailable.

modified configure.ac
@@ -388,18 +388,18 @@ if test "$ac_cv_func_bsd_dirname" = yes ; then
	AC_DEFINE(HAVE_BSD_DIRNAME, 1, [Define 1 if you have 'dirname(const char *)' function.])
fi

-
AC_CACHE_CHECK(for BSD statfs(const char *path, struct statfs *buf),
-
               ac_cv_func_statfs,
+
AC_CACHE_CHECK(for BSD fstatfs(int, struct statfs *buf),
+
               ac_cv_func_fstatfs,
               [ac_save_CFLAGS="$CFLAGS"
		CFLAGS="$CFLAGS -Werror"
		AC_TRY_COMPILE([#include <sys/param.h>
     					#include <sys/mount.h>],
-
                               [struct statfs stfs; static int (*ac_test_statfs)(const char *path, struct statfs *buf) = statfs; ac_test_statfs("", &stfs);],
-
                               [ac_cv_func_statfs=yes],
-
                               [ac_cv_func_statfs=no])
+
                               [struct statfs stfs; static int (*ac_test_fstatfs)(int fd, struct statfs *buf) = fstatfs; ac_test_fstatfs(0, &stfs);],
+
                               [ac_cv_func_fstatfs=yes],
+
                               [ac_cv_func_fstatfs=no])
		CFLAGS="$ac_save_CFLAGS"])
-
if test "$ac_cv_func_statfs" = yes ; then
-
	AC_DEFINE(HAVE_STATFS, 1, [Define 1 if you have 'statfs(const char *path, struct statfs *buf)' function.])
+
if test "$ac_cv_func_fstatfs" = yes ; then
+
	AC_DEFINE(HAVE_FSTATFS, 1, [Define 1 if you have 'fstatfs(int fd, struct statfs *buf)' function.])
fi

AC_CHECK_FUNCS(chflags chflagsat)
@@ -517,7 +517,6 @@ AC_CONFIG_FILES(Makefile \
		scripts/periodic/411.pkg-backup
		scripts/periodic/460.pkg-checksum
		scripts/periodic/490.status-pkg-changes
-
		scripts/sbin/pkg2ng
		scripts/completion/_pkg.bash
		scripts/completion/_pkg)
AC_CONFIG_FILES(m4_expand([repos_makefiles]))
modified dev_version.m4
@@ -1 +1 @@
-
0
+
4
modified docs/Makefile.am
@@ -7,7 +7,6 @@ dist_man_MANS= pkg-add.8 \
		pkg-check.8 \
		pkg-clean.8 \
		pkg-config.8 \
-
		pkg-convert.8 \
		pkg-create.8 \
		pkg-delete.8 \
		pkg-fetch.8 \
modified docs/fix-xrefs
@@ -1,4 +1,4 @@
-
#!/usr/bin/perl
+
#!/usr/bin/env perl

use strict;
use warnings;
modified docs/pkg-add.8
@@ -120,6 +120,7 @@ See
.Xr pkg-repository 5 ,
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -127,7 +128,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-alias.8
@@ -66,7 +66,7 @@ for alias 'size'
.Xr pkg-backup 8 ,
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
-
.Xr pkg-convert 8 ,
+
.Xr pkg-config 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-annotate.8
@@ -187,13 +187,13 @@ Show all packages with the foo annotation:
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
.Xr pkg-backup 8 ,
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-audit.8
@@ -98,13 +98,13 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-autoremove 8 ,
.Xr pkg-backup 8 ,
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-autoremove.8
@@ -65,13 +65,13 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-backup 8 ,
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-backup.8
@@ -72,13 +72,13 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-check.8
@@ -143,13 +143,13 @@ pkg check -sa
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
.Xr pkg-backup 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-clean.8
@@ -78,13 +78,13 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
.Xr pkg-backup 8 ,
.Xr pkg-check 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-config.8
@@ -44,13 +44,13 @@ Getting the directories where the repositories configuration are read:
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
.Xr pkg-backup 8 ,
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
deleted docs/pkg-convert.8
@@ -1,88 +0,0 @@
-
.\"
-
.\" FreeBSD pkg - a next generation package for the installation and maintenance
-
.\" of non-core utilities.
-
.\"
-
.\" 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.
-
.\"
-
.\"
-
.\"     @(#)pkg.8
-
.\"
-
.Dd November 02, 2014
-
.Dt PKG-CONVERT 8
-
.Os
-
.Sh NAME
-
.Nm "pkg convert"
-
.Nd convert from/to pkgng database format
-
.Sh SYNOPSIS
-
.Nm
-
.Op Fl d Ar pkg_dbdir
-
.Op Fl n
-
.Pp
-
.Nm
-
.Op Cm --pkg-dbdir Ar pkg_dbdir
-
.Op Cm --dry-run
-
.Sh DESCRIPTION
-
.Nm
-
is used to convert from/to
-
.Xr pkg 8
-
local database to legacy pkg_install tools format.
-
.Sh OPTIONS
-
The following options are supported by
-
.Nm :
-
.Bl -tag -width revert
-
.It Fl d Ar pkg_dbdir , Cm --pkg-dbdir Ar pkg_dbdir
-
The location of the
-
.Xr pkg_add 1
-
dbdir.
-
Defaults to
-
.Fa /var/db/pkg .
-
.It Fl n , Cm --dry-run
-
Dry-run mode.
-
Do not actually convert anything.
-
Just show what would be done.
-
.El
-
.Sh FILES
-
See
-
.Xr pkg.conf 5 .
-
.Sh SEE ALSO
-
.Xr pkg_printf 3 ,
-
.Xr pkg_repos 3 ,
-
.Xr pkg-repository 5 ,
-
.Xr pkg.conf 5 ,
-
.Xr pkg 8 ,
-
.Xr pkg-add 8 ,
-
.Xr pkg-annotate 8 ,
-
.Xr pkg-audit 8 ,
-
.Xr pkg-autoremove 8 ,
-
.Xr pkg-backup 8 ,
-
.Xr pkg-check 8 ,
-
.Xr pkg-clean 8 ,
-
.Xr pkg-config 8 ,
-
.Xr pkg-create 8 ,
-
.Xr pkg-delete 8 ,
-
.Xr pkg-fetch 8 ,
-
.Xr pkg-info 8 ,
-
.Xr pkg-install 8 ,
-
.Xr pkg-lock 8 ,
-
.Xr pkg-query 8 ,
-
.Xr pkg-register 8 ,
-
.Xr pkg-repo 8 ,
-
.Xr pkg-rquery 8 ,
-
.Xr pkg-search 8 ,
-
.Xr pkg-set 8 ,
-
.Xr pkg-shell 8 ,
-
.Xr pkg-shlib 8 ,
-
.Xr pkg-ssh 8 ,
-
.Xr pkg-stats 8 ,
-
.Xr pkg-update 8 ,
-
.Xr pkg-updating 8 ,
-
.Xr pkg-upgrade 8 ,
-
.Xr pkg-version 8 ,
-
.Xr pkg-which 8
modified docs/pkg-create.8
@@ -498,6 +498,7 @@ Create package file for pkg:
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -505,7 +506,6 @@ Create package file for pkg:
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
.Xr pkg-info 8 ,
modified docs/pkg-delete.8
@@ -148,6 +148,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -155,7 +156,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-fetch 8 ,
.Xr pkg-info 8 ,
modified docs/pkg-fetch.8
@@ -142,13 +142,13 @@ for additional environment variables that control behaviour.
See
.Xr pkg.conf 5 .
.Sh SEE ALSO
-
.Xr fetch 3 ,
.Xr pkg_printf 3 ,
.Xr pkg_repos 3 ,
.Xr pkg-repository 5 ,
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -156,7 +156,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-info 8 ,
modified docs/pkg-info.8
@@ -182,6 +182,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -189,7 +190,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-install.8
@@ -133,7 +133,7 @@ If any installation scripts (pre-install or post-install) exist for a given
package, do not execute them.
When a package is updated, deinstallation
scripts (pre-deinstall or post-deinstall) are not run either.
-
.It Fl i , Cm --case-sensitive
+
.It Fl i , Cm --case-insensitive
Make the standard or the regular expression
.Fl ( x )
matching against
@@ -206,6 +206,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -213,7 +214,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-lock.8
@@ -150,6 +150,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -157,7 +158,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-query.8
@@ -390,6 +390,7 @@ List unmaintained packages:
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -397,7 +398,6 @@ List unmaintained packages:
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-register.8
@@ -184,6 +184,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -191,7 +192,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-repo.8
@@ -14,7 +14,7 @@
.\"
.\"     @(#)pkg.8
.\"
-
.Dd May 9, 2016
+
.Dd April 11, 2017
.Dt PKG-REPO 8
.Os
.Sh NAME
@@ -22,13 +22,13 @@
.Nd create a package repository catalogue
.Sh SYNOPSIS
.Nm
-
.Op Fl lqL
+
.Op Fl lq
.Op Fl o Ar output-dir
.Op Fl m Ar meta-file
.Ao Ar repo-path Ac Op Ao Ar rsa-key Ac | signing_command: Ao Ar the command Ac
.Pp
.Nm
-
.Op Cm --{list-files,quiet,legacy}
+
.Op Cm --{list-files,quiet}
.Op Cm --output-dir Ar output-dir
.Op Cm --meta-file Ar meta-file
.Ao Ar repo-path Ac Op Ao Ar rsa-key Ac | signing_command: Ao Ar the command Ac
@@ -185,11 +185,6 @@ The following options are supported by
.Bl -tag -width quiet
.It Fl q , Cm --quiet
Force quiet output.
-
.It Fl L , Cm --legacy
-
Create a repository compatible with pkg 1.2. Note that this is only required if
-
the repository clients will not be upgrading to pkg 1.3+. Older versions of pkg
-
can upgrade themselves even from non-legacy. repositories, provided pkg itself
-
is included in those repositories.
.It Fl m Ar meta-file , Cm --meta-file Ar meta-file
Use the specified file as repository meta file instead of the default settings.
.It Fl l , Cm --list-files
@@ -207,6 +202,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -214,7 +210,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-repository.5
@@ -269,12 +269,12 @@ in
.Pa pkg.conf .
.Pp
.Sh SEE ALSO
-
.Xr fetch 3 ,
.Xr pkg_printf 3 ,
.Xr pkg_repos 3 ,
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -282,7 +282,6 @@ in
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-rquery.8
@@ -349,6 +349,7 @@ for example usage.
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -356,7 +357,6 @@ for example usage.
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-search.8
@@ -469,6 +469,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -476,7 +477,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-set.8
@@ -148,6 +148,7 @@ for further description.
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -155,7 +156,6 @@ for further description.
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-shell.8
@@ -56,6 +56,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -63,7 +64,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-shlib.8
@@ -75,6 +75,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -82,7 +83,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-ssh.8
@@ -54,6 +54,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -61,7 +62,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-stats.8
@@ -59,6 +59,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -66,7 +67,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-update.8
@@ -104,6 +104,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -111,7 +112,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-updating.8
@@ -88,6 +88,7 @@ installed ports:
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -95,7 +96,6 @@ installed ports:
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-upgrade.8
@@ -200,6 +200,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -207,7 +208,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-version.8
@@ -299,6 +299,7 @@ The following command compares two package version strings:
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -306,7 +307,6 @@ The following command compares two package version strings:
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg-which.8
@@ -14,7 +14,7 @@
.\"
.\"     @(#)pkg.8
.\"
-
.Dd October 30, 2014
+
.Dd February 28, 2017
.Dt PKG-WHICH 8
.Os
.Sh NAME
@@ -22,11 +22,11 @@
.Nd display which package installed a specific file
.Sh SYNOPSIS
.Nm
-
.Op Fl gopq
+
.Op Fl gopqm
.Ar file
.Pp
.Nm
-
.Op Cm --{glob,origin,path-search,quiet}
+
.Op Cm --{glob,origin,path-search,quiet,show-match}
.Ar file
.Sh DESCRIPTION
.Nm
@@ -40,6 +40,8 @@ The following options are supported by
Treat
.Ao file Ac
as a glob pattern.
+
.It Fl m , Cm --show-match
+
Show files that matched the glob pattern (requires --glob)
.It Fl o , Cm --origin
Show the origin of the package instead of name-version.
.It Fl p , Cm --path-search
@@ -67,6 +69,7 @@ See
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -74,7 +77,6 @@ See
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg.8
@@ -362,15 +362,12 @@ Check for missing dependencies:
.Dl # pkg check -d -a
.\" ---------------------------------------------------------------------------
.Sh SEE ALSO
-
.Xr SBUF 9 ,
-
.Xr elf 3 ,
-
.Xr fetch 3 ,
-
.Xr libarchive 3 ,
.Xr pkg_printf 3 ,
.Xr pkg_repos 3 ,
.Xr pkg-repository 5 ,
.Xr pkg.conf 5 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -378,7 +375,6 @@ Check for missing dependencies:
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg.conf.5
@@ -573,12 +573,12 @@ from, and subsequently passes it in the environment to
which ignores it (possibly with a deprecation warning that should be
ignored), and reads the configuration files instead.
.Sh SEE ALSO
-
.Xr fetch 3 ,
.Xr pkg_printf 3 ,
.Xr pkg_repos 3 ,
.Xr pkg-repository 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -586,7 +586,6 @@ ignored), and reads the configuration files instead.
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified docs/pkg_printf.3
@@ -926,15 +926,12 @@ An invalid wide character code was encountered.
Insufficient storage space is available.
.El
.Sh SEE ALSO
-
.Xr printf 1 ,
-
.Xr printf 3 ,
-
.Xr strftime 3 ,
-
.Xr setlocale 3
.Xr pkg_repos 3 ,
.Xr pkg-repository 5 ,
.Xr pkg.conf 5 ,
.Xr pkg 8 ,
.Xr pkg-add 8 ,
+
.Xr pkg-alias 8 ,
.Xr pkg-annotate 8 ,
.Xr pkg-audit 8 ,
.Xr pkg-autoremove 8 ,
@@ -942,7 +939,6 @@ Insufficient storage space is available.
.Xr pkg-check 8 ,
.Xr pkg-clean 8 ,
.Xr pkg-config 8 ,
-
.Xr pkg-convert 8 ,
.Xr pkg-create 8 ,
.Xr pkg-delete 8 ,
.Xr pkg-fetch 8 ,
modified external/libucl/include/ucl++.h
@@ -24,6 +24,9 @@

#pragma once
#include <string>
+
#include <vector>
+
#include <map>
+
#include <set>
#include <memory>
#include <iostream>

@@ -100,6 +103,68 @@ private:
		return func;
	};

+
	static bool ucl_variable_getter(const unsigned char *data, size_t len,
+
			unsigned char ** /*replace*/, size_t * /*replace_len*/, bool *need_free, void* ud)
+
	{
+
        *need_free = false;
+

+
		auto vars = reinterpret_cast<std::set<std::string> *>(ud);
+
		if (vars && data && len != 0) {
+
			vars->emplace (data, data + len);
+
		}
+
		return false;
+
	}
+

+
	static bool ucl_variable_replacer (const unsigned char *data, size_t len,
+
			unsigned char **replace, size_t *replace_len, bool *need_free, void* ud)
+
	{
+
		*need_free = false;
+

+
		auto replacer = reinterpret_cast<variable_replacer *>(ud);
+
		if (!replacer) {
+
			return false;
+
        }
+

+
		std::string var_name (data, data + len);
+
		if (!replacer->is_variable (var_name)) {
+
			return false;
+
        }
+

+
		std::string var_value = replacer->replace (var_name);
+
		if (var_value.empty ()) {
+
			return false;
+
        }
+

+
		*replace = (unsigned char *)UCL_ALLOC (var_value.size ());
+
		memcpy (*replace, var_value.data (), var_value.size ());
+

+
		*replace_len = var_value.size ();
+
		*need_free = true;
+

+
		return true;
+
	}
+

+
	template <typename C, typename P>
+
	static Ucl parse_with_strategy_function (C config_func, P parse_func, std::string &err)
+
	{
+
		auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
+

+
		config_func (parser);
+

+
		if (!parse_func (parser)) {
+
			err.assign (ucl_parser_get_error (parser));
+
			ucl_parser_free (parser);
+

+
			return nullptr;
+
		}
+

+
		auto obj = ucl_parser_get_object (parser);
+
		ucl_parser_free (parser);
+

+
		// Obj will handle ownership
+
		return Ucl (obj);
+
	}
+

	std::unique_ptr<ucl_object_t, ucl_deleter> obj;

public:
@@ -117,9 +182,9 @@ public:

		const_iterator(const Ucl &obj) {
			it = std::shared_ptr<void>(ucl_object_iterate_new (obj.obj.get()),
-
					ucl_iter_deleter());
+
				ucl_iter_deleter());
			cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true)));
-
			if (!*cur) {
+
			if (cur->type() == UCL_NULL) {
				it.reset ();
				cur.reset ();
			}
@@ -153,7 +218,7 @@ public:
				cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true)));
			}

-
			if (!*cur) {
+
			if (cur && cur->type() == UCL_NULL) {
				it.reset ();
				cur.reset ();
			}
@@ -171,6 +236,17 @@ public:
		}
	};

+
	struct variable_replacer {
+
		virtual ~variable_replacer() {}
+

+
		virtual bool is_variable (const std::string &str) const
+
		{
+
			return !str.empty ();
+
		}
+

+
		virtual std::string replace (const std::string &var) const = 0;
+
	};
+

	// We grab ownership if get non-const ucl_object_t
	Ucl(ucl_object_t *other) {
		obj.reset (other);
@@ -211,20 +287,20 @@ public:
		obj.reset (ucl_object_fromstring_common (value.data (), value.size (),
				UCL_STRING_RAW));
	}
-
	Ucl(const char * value) {
+
	Ucl(const char *value) {
		obj.reset (ucl_object_fromstring_common (value, 0, UCL_STRING_RAW));
	}

	// Implicit constructor: anything with a to_json() function.
	template <class T, class = decltype(&T::to_ucl)>
-
	Ucl(const T & t) : Ucl(t.to_ucl()) {}
+
	Ucl(const T &t) : Ucl(t.to_ucl()) {}

	// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
	template <class M, typename std::enable_if<
		std::is_constructible<std::string, typename M::key_type>::value
		&& std::is_constructible<Ucl, typename M::mapped_type>::value,
		int>::type = 0>
-
	Ucl(const M & m) {
+
	Ucl(const M &m) {
		obj.reset (ucl_object_typed_new (UCL_OBJECT));
		auto cobj = obj.get ();

@@ -238,7 +314,7 @@ public:
	template <class V, typename std::enable_if<
		std::is_constructible<Ucl, typename V::value_type>::value,
		int>::type = 0>
-
	Ucl(const V & v) {
+
	Ucl(const V &v) {
		obj.reset (ucl_object_typed_new (UCL_ARRAY));
		auto cobj = obj.get ();

@@ -356,46 +432,138 @@ public:
		return out;
	}

-
	static Ucl parse (const std::string & in, std::string & err)
+
	static Ucl parse (const std::string &in, std::string &err)
	{
-
		auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
+
		return parse (in, std::map<std::string, std::string>(), err);
+
	}

-
		if (!ucl_parser_add_chunk (parser, (const unsigned char *)in.data (),
-
				in.size ())) {
-
			err.assign (ucl_parser_get_error (parser));
-
			ucl_parser_free (parser);
+
	static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars, std::string &err)
+
	{
+
		auto config_func = [&vars] (ucl_parser *parser) {
+
			for (const auto & item : vars) {
+
				ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ());
+
            }
+
		};
+

+
		auto parse_func = [&in] (ucl_parser *parser) {
+
			return ucl_parser_add_chunk (parser, (unsigned char *)in.data (), in.size ());
+
		};
+

+
		return parse_with_strategy_function (config_func, parse_func, err);
+
	}

+
	static Ucl parse (const std::string &in, const variable_replacer &replacer, std::string &err)
+
	{
+
		auto config_func = [&replacer] (ucl_parser *parser) {
+
			ucl_parser_set_variables_handler (parser, ucl_variable_replacer,
+
				&const_cast<variable_replacer &>(replacer));
+
		};
+

+
		auto parse_func = [&in] (ucl_parser *parser) {
+
			return ucl_parser_add_chunk (parser, (unsigned char *) in.data (), in.size ());
+
		};
+

+
		return parse_with_strategy_function (config_func, parse_func, err);
+
	}
+

+
	static Ucl parse (const char *in, std::string &err)
+
	{
+
		return parse (in, std::map<std::string, std::string>(), err);
+
	}
+

+
	static Ucl parse (const char *in, const std::map<std::string, std::string> &vars, std::string &err)
+
	{
+
		if (!in) {
+
			err = "null input";
			return nullptr;
		}
+
		return parse (std::string (in), vars, err);
+
	}

-
		auto obj = ucl_parser_get_object (parser);
+
	static Ucl parse (const char *in, const variable_replacer &replacer, std::string &err)
+
	{
+
		if (!in) {
+
			err = "null input";
+
			return nullptr;
+
		}
+
		return parse (std::string(in), replacer, err);
+
	}
+

+
	static Ucl parse_from_file (const std::string &filename, std::string &err)
+
	{
+
		return parse_from_file (filename, std::map<std::string, std::string>(), err);
+
	}
+

+
	static Ucl parse_from_file (const std::string &filename, const std::map<std::string, std::string> &vars, std::string &err)
+
	{
+
		auto config_func = [&vars] (ucl_parser *parser) {
+
			for (const auto & item : vars) {
+
				ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ());
+
            }
+
		};
+

+
		auto parse_func = [&filename] (ucl_parser *parser) {
+
			return ucl_parser_add_file (parser, filename.c_str ());
+
		};
+

+
		return parse_with_strategy_function (config_func, parse_func, err);
+
	}
+

+
	static Ucl parse_from_file (const std::string &filename, const variable_replacer &replacer, std::string &err)
+
	{
+
		auto config_func = [&replacer] (ucl_parser *parser) {
+
			ucl_parser_set_variables_handler (parser, ucl_variable_replacer,
+
				&const_cast<variable_replacer &>(replacer));
+
		};
+

+
		auto parse_func = [&filename] (ucl_parser *parser) {
+
			return ucl_parser_add_file (parser, filename.c_str ());
+
		};
+

+
		return parse_with_strategy_function (config_func, parse_func, err);
+
	}
+

+
	static std::vector<std::string> find_variable (const std::string &in)
+
	{
+
		auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
+

+
		std::set<std::string> vars;
+
		ucl_parser_set_variables_handler (parser, ucl_variable_getter, &vars);
+
		ucl_parser_add_chunk (parser, (const unsigned char *)in.data (), in.size ());
		ucl_parser_free (parser);

-
		// Obj will handle ownership
-
		return Ucl (obj);
+
		std::vector<std::string> result;
+
		std::move (vars.begin (), vars.end (), std::back_inserter (result));
+
		return result;
	}

-
	static Ucl parse (const char * in, std::string & err)
+
	static std::vector<std::string> find_variable (const char *in)
	{
-
		if (in) {
-
			return parse (std::string(in), err);
-
		} else {
-
			err = "null input";
-
			return nullptr;
+
		if (!in) {
+
			return std::vector<std::string>();
		}
+
		return find_variable (std::string (in));
	}

-
	static Ucl parse (std::istream &ifs, std::string &err)
+
	static std::vector<std::string> find_variable_from_file (const std::string &filename)
	{
-
		return Ucl::parse (std::string(std::istreambuf_iterator<char>(ifs),
-
				std::istreambuf_iterator<char>()), err);
+
		auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
+

+
		std::set<std::string> vars;
+
		ucl_parser_set_variables_handler (parser, ucl_variable_getter, &vars);
+
		ucl_parser_add_file (parser, filename.c_str ());
+
		ucl_parser_free (parser);
+

+
		std::vector<std::string> result;
+
		std::move (vars.begin (), vars.end (), std::back_inserter (result));
+
		return std::move (result);
	}

-
    Ucl& operator= (Ucl rhs)
-
    {
-
        obj.swap (rhs.obj);
-
        return *this;
-
    }
+
	Ucl& operator= (Ucl rhs)
+
	{
+
		obj.swap (rhs.obj);
+
		return *this;
+
	}

	bool operator== (const Ucl &rhs) const
	{
modified external/libucl/include/ucl.h
@@ -154,7 +154,8 @@ typedef enum ucl_parser_flags {
	UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */
	UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays instead of implicit ones */
	UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */
-
	UCL_PARSER_DISABLE_MACRO = (1 << 5) /** Treat macros as comments */
+
	UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */
+
	UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */
} ucl_parser_flags_t;

/**
@@ -205,7 +206,8 @@ enum ucl_duplicate_strategy {
enum ucl_parse_type {
	UCL_PARSE_UCL = 0, /**< Default ucl format */
	UCL_PARSE_MSGPACK, /**< Message pack input format */
-
	UCL_PARSE_CSEXP /**< Canonical S-expressions */
+
	UCL_PARSE_CSEXP, /**< Canonical S-expressions */
+
	UCL_PARSE_AUTO /**< Try to detect parse type */
};

/**
@@ -227,7 +229,7 @@ typedef struct ucl_object_s {
	const char *key;						/**< Key of an object		*/
	struct ucl_object_s *next;				/**< Array handle			*/
	struct ucl_object_s *prev;				/**< Array handle			*/
-
	uint32_t keylen;						/**< Lenght of a key		*/
+
	uint32_t keylen;						/**< Length of a key		*/
	uint32_t len;							/**< Size of an object		*/
	uint32_t ref;							/**< Reference count		*/
	uint16_t flags;							/**< Object flags			*/
@@ -831,10 +833,29 @@ UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it,
 * Get the next object from the `obj`. This fucntion iterates over arrays, objects
 * and implicit arrays
 * @param iter safe iterator
+
 * @param expand_values expand explicit arrays and objects
 * @return the next object in sequence
 */
UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter,
		bool expand_values);
+
/**
+
 * Iteration type enumerator
+
 */
+
enum ucl_iterate_type {
+
	UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */
+
	UCL_ITERATE_IMPLICIT = 1 << 1,  /**< Iterate just implicit arrays */
+
	UCL_ITERATE_BOTH = (1 << 0) | (1 << 1),   /**< Iterate both explicit and implicit arrays*/
+
};
+

+
/**
+
 * Get the next object from the `obj`. This fucntion iterates over arrays, objects
+
 * and implicit arrays if needed
+
 * @param iter safe iterator
+
 * @param
+
 * @return the next object in sequence
+
 */
+
UCL_EXTERN const ucl_object_t* ucl_object_iterate_full (ucl_object_iter_t iter,
+
		enum ucl_iterate_type type);

/**
 * Free memory associated with the safe iterator
@@ -1035,6 +1056,20 @@ UCL_EXTERN bool ucl_parser_add_file_priority (struct ucl_parser *parser,
		const char *filename, unsigned priority);

/**
+
 * Load and add data from a file
+
 * @param parser parser structure
+
 * @param filename the name of file
+
 * @param priority the desired priority of a chunk (only 4 least significant bits
+
 * are considered for this parameter)
+
 * @param strat Merge strategy to use while parsing this file
+
 * @param parse_type Parser type to use while parsing this file
+
 * @return true if chunk has been added and false in case of error
+
 */
+
UCL_EXTERN bool ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,
+
		unsigned priority, enum ucl_duplicate_strategy strat,
+
		enum ucl_parse_type parse_type);
+

+
/**
 * Load and add data from a file descriptor
 * @param parser parser structure
 * @param filename the name of file
@@ -1057,6 +1092,21 @@ UCL_EXTERN bool ucl_parser_add_fd_priority (struct ucl_parser *parser,
		int fd, unsigned priority);

/**
+
 * Load and add data from a file descriptor
+
 * @param parser parser structure
+
 * @param filename the name of file
+
 * @param err if *err is NULL it is set to parser error
+
 * @param priority the desired priority of a chunk (only 4 least significant bits
+
 * are considered for this parameter)
+
 * @param strat Merge strategy to use while parsing this file
+
 * @param parse_type Parser type to use while parsing this file
+
 * @return true if chunk has been added and false in case of error
+
 */
+
UCL_EXTERN bool ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
+
		unsigned priority, enum ucl_duplicate_strategy strat,
+
		enum ucl_parse_type parse_type);
+

+
/**
 * Provide a UCL_ARRAY of paths to search for include files. The object is
 * copied so caller must unref the object.
 * @param parser parser structure
modified external/libucl/lua/lua_ucl.c
@@ -29,7 +29,6 @@
#include "ucl_internal.h"
#include "lua_ucl.h"
#include <strings.h>
-
#include <zconf.h>

/***
 * @module ucl
@@ -187,6 +186,8 @@ ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj)
			lua_rawseti (L, -2, i);
			i ++;
		}
+

+
		ucl_object_iterate_free (it);
	}
	else {
		/* Optimize allocation by preallocation of table */
@@ -482,7 +483,7 @@ static int
lua_ucl_parser_init (lua_State *L)
{
	struct ucl_parser *parser, **pparser;
-
	int flags = 0;
+
	int flags = UCL_PARSER_NO_FILEVARS;

	if (lua_gettop (L) >= 1) {
		flags = lua_tonumber (L, 1);
@@ -524,6 +525,27 @@ lua_ucl_push_opaque (lua_State *L, ucl_object_t *obj)
	lua_setmetatable (L, -2);
}

+
static inline enum ucl_parse_type
+
lua_ucl_str_to_parse_type (const char *str)
+
{
+
	enum ucl_parse_type type = UCL_PARSE_UCL;
+

+
	if (str != NULL) {
+
		if (strcasecmp (str, "msgpack") == 0) {
+
			type = UCL_PARSE_MSGPACK;
+
		}
+
		else if (strcasecmp (str, "sexp") == 0 ||
+
				strcasecmp (str, "csexp") == 0) {
+
			type = UCL_PARSE_CSEXP;
+
		}
+
		else if (strcasecmp (str, "auto") == 0) {
+
			type = UCL_PARSE_AUTO;
+
		}
+
	}
+

+
	return type;
+
}
+

/***
 * @method parser:parse_file(name)
 * Parse UCL object from file.
@@ -579,13 +601,19 @@ lua_ucl_parser_parse_string (lua_State *L)
	struct ucl_parser *parser;
	const char *string;
	size_t llen;
+
	enum ucl_parse_type type = UCL_PARSE_UCL;
	int ret = 2;

	parser = lua_ucl_parser_get (L, 1);
	string = luaL_checklstring (L, 2, &llen);

+
	if (lua_type (L, 3) == LUA_TSTRING) {
+
		type = lua_ucl_str_to_parse_type (lua_tostring (L, 3));
+
	}
+

	if (parser != NULL && string != NULL) {
-
		if (ucl_parser_add_chunk (parser, (const unsigned char *)string, llen)) {
+
		if (ucl_parser_add_chunk_full (parser, (const unsigned char *)string,
+
				llen, 0, UCL_DUPLICATE_APPEND, type)) {
			lua_pushboolean (L, true);
			ret = 1;
		}
@@ -761,6 +789,28 @@ lua_ucl_object_unwrap (lua_State *L)
	return 1;
}

+
static inline enum ucl_emitter
+
lua_ucl_str_to_emit_type (const char *strtype)
+
{
+
	enum ucl_emitter format = UCL_EMIT_JSON_COMPACT;
+

+
	if (strcasecmp (strtype, "json") == 0) {
+
		format = UCL_EMIT_JSON;
+
	}
+
	else if (strcasecmp (strtype, "json-compact") == 0) {
+
		format = UCL_EMIT_JSON_COMPACT;
+
	}
+
	else if (strcasecmp (strtype, "yaml") == 0) {
+
		format = UCL_EMIT_YAML;
+
	}
+
	else if (strcasecmp (strtype, "config") == 0 ||
+
			strcasecmp (strtype, "ucl") == 0) {
+
		format = UCL_EMIT_CONFIG;
+
	}
+

+
	return format;
+
}
+

/***
 * @method object:tostring(type)
 * Unwraps opaque ucl object to string (json by default). Optionally you can
@@ -787,19 +837,7 @@ lua_ucl_object_tostring (lua_State *L)
			if (lua_type (L, 2) == LUA_TSTRING) {
				const char *strtype = lua_tostring (L, 2);

-
				if (strcasecmp (strtype, "json") == 0) {
-
					format = UCL_EMIT_JSON;
-
				}
-
				else if (strcasecmp (strtype, "json-compact") == 0) {
-
					format = UCL_EMIT_JSON_COMPACT;
-
				}
-
				else if (strcasecmp (strtype, "yaml") == 0) {
-
					format = UCL_EMIT_YAML;
-
				}
-
				else if (strcasecmp (strtype, "config") == 0 ||
-
						strcasecmp (strtype, "ucl") == 0) {
-
					format = UCL_EMIT_CONFIG;
-
				}
+
				format = lua_ucl_str_to_emit_type (strtype);
			}
		}

@@ -1088,6 +1126,9 @@ lua_ucl_to_format (lua_State *L)
				strcasecmp (strtype, "ucl") == 0) {
				format = UCL_EMIT_CONFIG;
			}
+
			else if (strcasecmp (strtype, "msgpack") == 0) {
+
				format = UCL_EMIT_MSGPACK;
+
			}
		}
	}

modified external/libucl/src/mum.h
@@ -73,7 +73,7 @@ typedef unsigned __int64 uint64_t;
#define _MUM_FRESH_GCC
#endif

-
#if defined(__GNUC__) && !defined(__llvm__)
+
#if defined(__GNUC__) && !defined(__llvm__) && defined(_MUM_FRESH_GCC)
#define _MUM_ATTRIBUTE_UNUSED  __attribute__((unused))
#define _MUM_OPTIMIZE(opts) __attribute__((__optimize__ (opts)))
#define _MUM_TARGET(opts) __attribute__((__target__ (opts)))
modified external/libucl/src/ucl_emitter_utils.c
@@ -102,7 +102,7 @@ ucl_elt_string_write_json (const char *str, size_t size,
	func->ucl_emitter_append_character ('"', 1, func->ud);

	while (size) {
-
		if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE)) {
+
		if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_DENIED)) {
			if (len > 0) {
				func->ucl_emitter_append_len (c, len, func->ud);
			}
@@ -128,6 +128,10 @@ ucl_elt_string_write_json (const char *str, size_t size,
			case '"':
				func->ucl_emitter_append_len ("\\\"", 2, func->ud);
				break;
+
			default:
+
				/* Emit unicode unknown character */
+
				func->ucl_emitter_append_len ("\\uFFFD", 5, func->ud);
+
				break;
			}
			len = 0;
			c = ++p;
@@ -138,9 +142,11 @@ ucl_elt_string_write_json (const char *str, size_t size,
		}
		size --;
	}
+

	if (len > 0) {
		func->ucl_emitter_append_len (c, len, func->ud);
	}
+

	func->ucl_emitter_append_character ('"', 1, func->ud);
}

modified external/libucl/src/ucl_internal.h
@@ -87,6 +87,9 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
+
#ifdef HAVE_STRINGS_H
+
#include <strings.h>
+
#endif

#include "utlist.h"
#include "utstring.h"
@@ -127,19 +130,19 @@ enum ucl_parser_state {
};

enum ucl_character_type {
-
	UCL_CHARACTER_DENIED = 0,
-
	UCL_CHARACTER_KEY = 1,
-
	UCL_CHARACTER_KEY_START = 1 << 1,
-
	UCL_CHARACTER_WHITESPACE = 1 << 2,
-
	UCL_CHARACTER_WHITESPACE_UNSAFE = 1 << 3,
-
	UCL_CHARACTER_VALUE_END = 1 << 4,
-
	UCL_CHARACTER_VALUE_STR = 1 << 5,
-
	UCL_CHARACTER_VALUE_DIGIT = 1 << 6,
-
	UCL_CHARACTER_VALUE_DIGIT_START = 1 << 7,
-
	UCL_CHARACTER_ESCAPE = 1 << 8,
-
	UCL_CHARACTER_KEY_SEP = 1 << 9,
-
	UCL_CHARACTER_JSON_UNSAFE = 1 << 10,
-
	UCL_CHARACTER_UCL_UNSAFE = 1 << 11
+
	UCL_CHARACTER_DENIED = (1 << 0),
+
	UCL_CHARACTER_KEY = (1 << 1),
+
	UCL_CHARACTER_KEY_START = (1 << 2),
+
	UCL_CHARACTER_WHITESPACE = (1 << 3),
+
	UCL_CHARACTER_WHITESPACE_UNSAFE = (1 << 4),
+
	UCL_CHARACTER_VALUE_END = (1 << 5),
+
	UCL_CHARACTER_VALUE_STR = (1 << 6),
+
	UCL_CHARACTER_VALUE_DIGIT = (1 << 7),
+
	UCL_CHARACTER_VALUE_DIGIT_START = (1 << 8),
+
	UCL_CHARACTER_ESCAPE = (1 << 9),
+
	UCL_CHARACTER_KEY_SEP = (1 << 10),
+
	UCL_CHARACTER_JSON_UNSAFE = (1 << 11),
+
	UCL_CHARACTER_UCL_UNSAFE = (1 << 12)
};

struct ucl_macro {
@@ -568,4 +571,6 @@ bool ucl_parser_process_object_element (struct ucl_parser *parser,
 */
bool ucl_parse_msgpack (struct ucl_parser *parser);

+
bool ucl_parse_csexp (struct ucl_parser *parser);
+

#endif /* UCL_INTERNAL_H_ */
modified external/libucl/src/ucl_parser.c
@@ -342,6 +342,7 @@ ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t rema
		/* Call generic handler */
		if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
				parser->var_data)) {
+
			*out_len += dstlen;
			*found = true;
			if (need_free) {
				free (dst);
@@ -458,11 +459,18 @@ ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr,
	}
	if (!found) {
		if (strict && parser->var_handler != NULL) {
-
			if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
+
			size_t var_len = 0;
+
			while (var_len < remain && p[var_len] != '}')
+
				var_len ++;
+

+
			if (parser->var_handler (p, var_len, &dst, &dstlen, &need_free,
							parser->var_data)) {
				memcpy (d, dst, dstlen);
-
				ret += dstlen;
-
				d += remain;
+
				ret += var_len;
+
				d += dstlen;
+
				if (need_free) {
+
					free (dst);
+
				}
				found = true;
			}
		}
@@ -2461,8 +2469,10 @@ ucl_parser_new (int flags)
		parser->comments = ucl_object_typed_new (UCL_OBJECT);
	}

-
	/* Initial assumption about filevars */
-
	ucl_parser_set_filevars (parser, NULL, false);
+
	if (!(flags & UCL_PARSER_NO_FILEVARS)) {
+
		/* Initial assumption about filevars */
+
		ucl_parser_set_filevars (parser, NULL, false);
+
	}

	return parser;
}
@@ -2609,6 +2619,19 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data,
			return false;
		}

+
		if (parse_type == UCL_PARSE_AUTO && len > 0) {
+
			/* We need to detect parse type by the first symbol */
+
			if ((*data & 0x80) == 0x80 && (*data >= 0xdc && *data <= 0xdf)) {
+
				parse_type = UCL_PARSE_MSGPACK;
+
			}
+
			else if (*data == '(') {
+
				parse_type = UCL_PARSE_CSEXP;
+
			}
+
			else {
+
				parse_type = UCL_PARSE_UCL;
+
			}
+
		}
+

		chunk->begin = data;
		chunk->remain = len;
		chunk->pos = chunk->begin;
@@ -2635,6 +2658,8 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data,
				return ucl_state_machine (parser);
			case UCL_PARSE_MSGPACK:
				return ucl_parse_msgpack (parser);
+
			case UCL_PARSE_CSEXP:
+
				return ucl_parse_csexp (parser);
			}
		}
		else {
modified external/libucl/src/ucl_schema.c
@@ -69,7 +69,7 @@ ucl_schema_create_error (struct ucl_schema_error *err,
 * Check whether we have a pattern specified
 */
static const ucl_object_t *
-
ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern)
+
ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern, bool recursive)
{
	const ucl_object_t *res = NULL;
#ifdef HAVE_REGEX_H
@@ -78,11 +78,16 @@ ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern)
	ucl_object_iter_t iter = NULL;

	if (regcomp (&reg, pattern, REG_EXTENDED | REG_NOSUB) == 0) {
-
		while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
-
			if (regexec (&reg, ucl_object_key (elt), 0, NULL, 0) == 0) {
-
				res = elt;
-
				break;
+
		if (recursive) {
+
			while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
+
				if (regexec (&reg, ucl_object_key (elt), 0, NULL, 0) == 0) {
+
					res = elt;
+
					break;
+
				}
			}
+
		} else {
+
			if (regexec (&reg, ucl_object_key (obj), 0, NULL, 0) == 0)
+
				res = obj;
		}
		regfree (&reg);
	}
@@ -205,12 +210,17 @@ ucl_schema_validate_object (const ucl_object_t *schema,
			}
		}
		else if (strcmp (ucl_object_key (elt), "patternProperties") == 0) {
+
			const ucl_object_t *vobj;
+
			ucl_object_iter_t viter;
			piter = NULL;
			while (ret && (prop = ucl_object_iterate (elt, &piter, true)) != NULL) {
-
				found = ucl_schema_test_pattern (obj, ucl_object_key (prop));
-
				if (found) {
-
					ret = ucl_schema_validate (prop, found, true, err, root,
-
							ext_ref);
+
				viter = NULL;
+
				while (ret && (vobj = ucl_object_iterate (obj, &viter, true)) != NULL) {
+
					found = ucl_schema_test_pattern (vobj, ucl_object_key (prop), false);
+
					if (found) {
+
						ret = ucl_schema_validate (prop, found, true, err, root,
+
								ext_ref);
+
					}
				}
			}
		}
@@ -234,7 +244,7 @@ ucl_schema_validate_object (const ucl_object_t *schema,
					piter = NULL;
					pat = ucl_object_lookup (schema, "patternProperties");
					while ((pelt = ucl_object_iterate (pat, &piter, true)) != NULL) {
-
						found = ucl_schema_test_pattern (obj, ucl_object_key (pelt));
+
						found = ucl_schema_test_pattern (obj, ucl_object_key (pelt), true);
						if (found != NULL) {
							break;
						}
modified external/libucl/src/ucl_util.c
@@ -26,11 +26,17 @@
#include "ucl_internal.h"
#include "ucl_chartable.h"
#include "kvec.h"
+
#include <limits.h>
#include <stdarg.h>
#include <stdio.h> /* for snprintf */

#ifndef _WIN32
#include <glob.h>
+
#include <sys/param.h>
+
#else
+
#ifndef NBBY
+
#define NBBY 8
+
#endif
#endif

#ifdef HAVE_LIBGEN_H
@@ -81,11 +87,6 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;
#define MAP_FAILED      ((void *) -1)
#endif

-
#ifdef _WIN32
-
#include <limits.h>
-
#define NBBY CHAR_BIT
-
#endif
-

static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset)
{
	void *map = NULL;
@@ -1795,8 +1796,9 @@ ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, bool n
}

bool
-
ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
-
		unsigned priority)
+
ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,
+
		unsigned priority, enum ucl_duplicate_strategy strat,
+
		enum ucl_parse_type parse_type)
{
	unsigned char *buf;
	size_t len;
@@ -1819,7 +1821,8 @@ ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
	}
	parser->cur_file = strdup (realbuf);
	ucl_parser_set_filevars (parser, realbuf, false);
-
	ret = ucl_parser_add_chunk_priority (parser, buf, len, priority);
+
	ret = ucl_parser_add_chunk_full (parser, buf, len, priority, strat,
+
			parse_type);

	if (len > 0) {
		ucl_munmap (buf, len);
@@ -1829,19 +1832,34 @@ ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
}

bool
+
ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
+
		unsigned priority)
+
{
+
	if (parser == NULL) {
+
		return false;
+
	}
+

+
	return ucl_parser_add_file_full(parser, filename, priority,
+
			UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);
+
}
+

+
bool
ucl_parser_add_file (struct ucl_parser *parser, const char *filename)
{
	if (parser == NULL) {
		return false;
	}

-
	return ucl_parser_add_file_priority(parser, filename,
-
			parser->default_priority);
+
	return ucl_parser_add_file_full(parser, filename,
+
			parser->default_priority, UCL_DUPLICATE_APPEND,
+
			UCL_PARSE_UCL);
}

+

bool
-
ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
-
		unsigned priority)
+
ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
+
		unsigned priority, enum ucl_duplicate_strategy strat,
+
		enum ucl_parse_type parse_type)
{
	unsigned char *buf;
	size_t len;
@@ -1867,7 +1885,8 @@ ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
	}
	parser->cur_file = NULL;
	len = st.st_size;
-
	ret = ucl_parser_add_chunk_priority (parser, buf, len, priority);
+
	ret = ucl_parser_add_chunk_full (parser, buf, len, priority, strat,
+
			parse_type);

	if (len > 0) {
		ucl_munmap (buf, len);
@@ -1877,6 +1896,18 @@ ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
}

bool
+
ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
+
		unsigned priority)
+
{
+
	if (parser == NULL) {
+
		return false;
+
	}
+

+
	return ucl_parser_add_fd_full(parser, fd, parser->default_priority,
+
			UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);
+
}
+

+
bool
ucl_parser_add_fd (struct ucl_parser *parser, int fd)
{
	if (parser == NULL) {
@@ -2473,6 +2504,10 @@ ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj)

	UCL_SAFE_ITER_CHECK (rit);

+
	if (rit->expl_it != NULL) {
+
		UCL_FREE (sizeof (*rit->expl_it), rit->expl_it);
+
	}
+

	rit->impl_it = obj;
	rit->expl_it = NULL;

@@ -2482,6 +2517,13 @@ ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj)
const ucl_object_t*
ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values)
{
+
	return ucl_object_iterate_full (it, expand_values ? UCL_ITERATE_BOTH :
+
			UCL_ITERATE_IMPLICIT);
+
}
+

+
const ucl_object_t*
+
ucl_object_iterate_full (ucl_object_iter_t it, enum ucl_iterate_type type)
+
{
	struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it);
	const ucl_object_t *ret = NULL;

@@ -2494,21 +2536,23 @@ ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values)
	if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) {
		ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true);

-
		if (ret == NULL) {
+
		if (ret == NULL && (type & UCL_ITERATE_IMPLICIT)) {
			/* Need to switch to another implicit object in chain */
			rit->impl_it = rit->impl_it->next;
			rit->expl_it = NULL;
-
			return ucl_object_iterate_safe (it, expand_values);
+

+
			return ucl_object_iterate_safe (it, type);
		}
	}
	else {
		/* Just iterate over the implicit array */
		ret = rit->impl_it;
		rit->impl_it = rit->impl_it->next;
-
		if (expand_values) {
+

+
		if (type & UCL_ITERATE_EXPLICIT) {
			/* We flatten objects if need to expand values */
			if (ret->type == UCL_OBJECT || ret->type == UCL_ARRAY) {
-
				return ucl_object_iterate_safe (it, expand_values);
+
				return ucl_object_iterate_safe (it, type);
			}
		}
	}
@@ -2523,6 +2567,10 @@ ucl_object_iterate_free (ucl_object_iter_t it)

	UCL_SAFE_ITER_CHECK (rit);

+
	if (rit->expl_it != NULL) {
+
		UCL_FREE (sizeof (*rit->expl_it), rit->expl_it);
+
	}
+

	UCL_FREE (sizeof (*rit), it);
}

modified libpkg/Makefile.am
@@ -61,7 +61,6 @@ libpkg_la_SOURCES= pkg.c \
			scripts.c \
			utils.c \
			plugins.c \
-
			pkg_old.c \
			merge3.c \
			diff.c \
			sha256.c
@@ -145,7 +144,7 @@ noinst_HEADERS= private/db_upgrades.h \
			private/utils.h \
			private/pkg_jobs.h \
			private/pkg_deps.h \
-
			private/xmalloc.h \
+
			xmalloc.h \
			sha256.h

SUBDIRS = repo .
modified libpkg/diff.c
@@ -25,7 +25,7 @@
#include <utstring.h>

#include "private/utils.h"
-
#include "private/xmalloc.h"
+
#include "xmalloc.h"

/*
** Maximum length of a line in a text file, in bytes.  (2**13 = 8192 bytes)
modified libpkg/dns_utils.c
@@ -79,7 +79,7 @@

#include <bsd_compat.h>
#include "private/utils.h"
-
#include "private/xmalloc.h"
+
#include "xmalloc.h"
#include "pkg.h"

#ifndef HAVE_LDNS
modified libpkg/fetch.c
@@ -515,15 +515,17 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,

		url += strlen(URL_SCHEME_PREFIX);
		pkg_url_scheme = true;
+
	}

+
	if (repo != NULL) {
		LL_FOREACH(repo->env, kv) {
			kvtmp = xcalloc(1, sizeof(*kvtmp));
			kvtmp->key = xstrdup(kv->key);
			if ((tmp = getenv(kv->key)) != NULL) {
				kvtmp->value = xstrdup(tmp);
-
				LL_APPEND(envtorestore, kvtmp);
+
				DL_APPEND(envtorestore, kvtmp);
			} else {
-
				LL_APPEND(envtounset, kvtmp);
+
				DL_APPEND(envtounset, kvtmp);
			}
			setenv(kv->key, kv->value, 1);
		}
@@ -601,7 +603,7 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
				utstring_printf(fetchOpts, "6");
		}

-
		if (debug_level >= 4)
+
		if (ctx.debug_level >= 4)
			utstring_printf(fetchOpts, "v");

		pkg_debug(1,"Fetch: fetching from: %s://%s%s%s%s with opts \"%s\"",
modified libpkg/packing.c
@@ -32,7 +32,6 @@
#include <fcntl.h>
#include <fts.h>
#include <string.h>
-
#include <sys/mman.h>
#include <pwd.h>
#include <grp.h>

@@ -134,7 +133,6 @@ packing_append_file_attr(struct packing *pack, const char *filepath,
    u_long fflags)
{
	int fd;
-
	char *map;
	int retcode = EPKG_OK;
	int ret;
	time_t source_time;
@@ -142,6 +140,8 @@ packing_append_file_attr(struct packing *pack, const char *filepath,
	struct archive_entry *entry, *sparse_entry;
	bool unset_timestamp;
	const char *source_date_epoch;
+
	char buf[32768];
+
	int len;

	entry = archive_entry_new();
	archive_entry_copy_sourcepath(entry, filepath);
@@ -214,49 +214,30 @@ packing_append_file_attr(struct packing *pack, const char *filepath,

	archive_write_header(pack->awrite, entry);

-
	if (archive_entry_size(entry) > 0) {
-
		if ((fd = open(filepath, O_RDONLY)) < 0) {
-
			pkg_emit_errno("open", filepath);
+
	if (archive_entry_size(entry) <= 0)
+
		goto cleanup;
+

+
	if ((fd = open(filepath, O_RDONLY)) < 0) {
+
		pkg_emit_errno("open", filepath);
+
		retcode = EPKG_FATAL;
+
		goto cleanup;
+
	}
+

+
	while ((len = read(fd, buf, sizeof(buf))) > 0) {
+
		if (archive_write_data(pack->awrite, buf, len) == -1) {
+
			pkg_emit_errno("archive_write_data", "archive write error");
			retcode = EPKG_FATAL;
-
			goto cleanup;
-
		}
-
		if (st.st_size > SSIZE_MAX) {
-
			char buf[BUFSIZ];
-
			int len;
-

-
			while ((len = read(fd, buf, sizeof(buf))) > 0)
-
				if (archive_write_data(pack->awrite, buf, len) == -1) {
-
					pkg_emit_errno("archive_write_data", "archive write error");
-
					retcode = EPKG_FATAL;
-
					break;
-
				}
-

-
			if (len == -1) {
-
				pkg_emit_errno("read", "file read error");
-
				retcode = EPKG_FATAL;
-
			}
-
			close(fd);
-
		}
-
		else {
-
			if ((map = mmap(NULL, st.st_size, PROT_READ,
-
					MAP_SHARED, fd, 0)) != MAP_FAILED) {
-
				close(fd);
-
				if (archive_write_data(pack->awrite, map, st.st_size) == -1) {
-
					pkg_emit_errno("archive_write_data", "archive write error");
-
					retcode = EPKG_FATAL;
-
				}
-
				munmap(map, st.st_size);
-
			}
-
			else {
-
				close(fd);
-
				pkg_emit_errno("open", filepath);
-
				retcode = EPKG_FATAL;
-
				goto cleanup;
-
			}
+
			break;
		}
	}

-
	cleanup:
+
	if (len == -1) {
+
		pkg_emit_errno("read", "file read error");
+
		retcode = EPKG_FATAL;
+
	}
+
	close(fd);
+

+
cleanup:
	archive_entry_free(entry);
	return (retcode);
}
modified libpkg/pkg.c
@@ -103,8 +103,8 @@ pkg_free(struct pkg *pkg)
	pkg_list_free(pkg, PKG_CATEGORIES);
	pkg_list_free(pkg, PKG_LICENSES);

-
	LL_FREE(pkg->message, pkg_message_free);
-
	LL_FREE(pkg->annotations, pkg_kv_free);
+
	DL_FREE(pkg->message, pkg_message_free);
+
	DL_FREE(pkg->annotations, pkg_kv_free);

	if (pkg->rootfd != -1)
		close(pkg->rootfd);
@@ -567,7 +567,7 @@ pkg_adduser(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	if (kh_contains(strings, pkg->users, name)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate user listing: %s, fatal (developer mode)", name);
			return (EPKG_FATAL);
		} else {
@@ -591,7 +591,7 @@ pkg_addgroup(struct pkg *pkg, const char *name)
	assert(name != NULL && name[0] != '\0');

	if (kh_contains(strings, pkg->groups, name)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate group listing: %s, fatal (developer mode)", name);
			return (EPKG_FATAL);
		} else {
@@ -631,15 +631,9 @@ pkg_adddep_chain(struct pkg_dep *chain,

	pkg_debug(3, "Pkg: add a new dependency origin: %s, name: %s", origin, name);
	if (kh_contains(pkg_deps, pkg->depshash, name)) {
-
		if (developer_mode) {
-
			pkg_emit_error("%s: duplicate dependency listing: %s, fatal (developer mode)",
-
			    pkg->name, name);
-
			return (NULL);
-
		} else {
-
			pkg_emit_error("%s-%s: duplicate dependency listing: %s, ignoring",
-
			    pkg->name, pkg->version, name);
-
			return (NULL);
-
		}
+
		pkg_emit_error("%s: duplicate dependency listing: %s",
+
		    pkg->name, name);
+
		return (NULL);
	}

	d = xcalloc(1, sizeof(*d));
@@ -709,7 +703,7 @@ pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sum,
	pkg_debug(3, "Pkg: add new file '%s'", path);

	if (check_duplicates && kh_contains(pkg_files, pkg->filehash, path)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate file listing: %s, fatal (developer mode)", path);
			return (EPKG_FATAL);
		} else {
@@ -737,7 +731,7 @@ pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sum,
		f->fflags = fflags;

	kh_safe_add(pkg_files, pkg->filehash, f, f->path);
-
	LL_APPEND(pkg->files, f);
+
	DL_APPEND(pkg->files, f);

	return (EPKG_OK);
}
@@ -752,7 +746,7 @@ pkg_addconfig_file(struct pkg *pkg, const char *path, const char *content)
	pkg_debug(3, "Pkg: add new config file '%s'", path);

	if (kh_contains(pkg_config_files, pkg->config_files, path)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate file listing: %s, fatal (developer mode)", path);
			return (EPKG_FATAL);
		} else {
@@ -779,7 +773,7 @@ pkg_addstring(kh_strings_t **list, const char *val, const char *title)
	assert(title != NULL);

	if (kh_contains(strings, *list, val)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate %s listing: %s, fatal"
			    " (developer mode)", title, val);
			return (EPKG_FATAL);
@@ -819,7 +813,7 @@ pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname,
	path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
	pkg_debug(3, "Pkg: add new directory '%s'", path);
	if (check_duplicates && kh_contains(pkg_dirs, pkg->dirhash, path)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate directory listing: %s, fatal (developer mode)", path);
			return (EPKG_FATAL);
		} else {
@@ -844,7 +838,7 @@ pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname,
		d->fflags = fflags;

	kh_safe_add(pkg_dirs, pkg->dirhash, d, d->path);
-
	LL_APPEND(pkg->dirs, d);
+
	DL_APPEND(pkg->dirs, d);

	return (EPKG_OK);
}
@@ -1007,7 +1001,7 @@ pkg_addoption(struct pkg *pkg, const char *key, const char *value)

	pkg_debug(2,"Pkg> adding options: %s = %s", key, value);
	if (kh_contains(pkg_options, pkg->optionshash, key)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate options listing: %s, fatal (developer mode)", key);
			return (EPKG_FATAL);
		} else {
@@ -1019,7 +1013,7 @@ pkg_addoption(struct pkg *pkg, const char *key, const char *value)
	o->key = xstrdup(key);
	o->value = xstrdup(value);
	kh_safe_add(pkg_options, pkg->optionshash, o, o->key);
-
	LL_APPEND(pkg->options, o);
+
	DL_APPEND(pkg->options, o);

	return (EPKG_OK);
}
@@ -1041,7 +1035,7 @@ pkg_addoption_default(struct pkg *pkg, const char *key,
	   no actual value. */

	if (kh_contains(pkg_options, pkg->optionshash, key)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate default value for option: %s, fatal (developer mode)", key);
			return (EPKG_FATAL);
		} else {
@@ -1053,7 +1047,7 @@ pkg_addoption_default(struct pkg *pkg, const char *key,
	o->key = xstrdup(key);
	o->default_value = xstrdup(default_value);
	kh_safe_add(pkg_options, pkg->optionshash, o, o->key);
-
	LL_APPEND(pkg->options, o);
+
	DL_APPEND(pkg->options, o);

	return (EPKG_OK);
}
@@ -1074,7 +1068,7 @@ pkg_addoption_description(struct pkg *pkg, const char *key,
	   value or description for an option but no actual value. */

	if (kh_contains(pkg_options, pkg->optionshash, key)) {
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_error("duplicate description for option: %s, fatal (developer mode)", key);
			return (EPKG_FATAL);
		} else {
@@ -1087,7 +1081,7 @@ pkg_addoption_description(struct pkg *pkg, const char *key,
	o->key = xstrdup(key);
	o->description = xstrdup(description);
	kh_safe_add(pkg_options, pkg->optionshash, o, o->key);
-
	LL_APPEND(pkg->options, o);
+
	DL_APPEND(pkg->options, o);

	return (EPKG_OK);
}
@@ -1154,7 +1148,7 @@ pkg_addconflict(struct pkg *pkg, const char *uniqueid)
	pkg_debug(3, "Pkg: add a new conflict origin: %s, with %s", pkg->uid, uniqueid);

	kh_safe_add(pkg_conflicts, pkg->conflictshash, c, c->uid);
-
	LL_APPEND(pkg->conflicts, c);
+
	DL_APPEND(pkg->conflicts, c);

	return (EPKG_OK);
}
@@ -1222,7 +1216,7 @@ pkg_kv_add(struct pkg_kv **list, const char *key, const char *val, const char *t

	LL_FOREACH(*list, kv) {
		if (strcmp(kv->key, key) == 0) {
-
			if (developer_mode) {
+
			if (ctx.developer_mode) {
				pkg_emit_error("duplicate %s: %s, fatal"
				    " (developer mode)", title, key);
				return (EPKG_FATAL);
@@ -1235,7 +1229,7 @@ pkg_kv_add(struct pkg_kv **list, const char *key, const char *val, const char *t
	}

	kv = pkg_kv_new(key, val);
-
	LL_APPEND(*list, kv);
+
	DL_APPEND(*list, kv);

	return (EPKG_OK);
}
@@ -1300,19 +1294,19 @@ pkg_list_free(struct pkg *pkg, pkg_list list) {
		pkg->flags &= ~PKG_LOAD_RDEPS;
		break;
	case PKG_OPTIONS:
-
		LL_FREE(pkg->options, pkg_option_free);
+
		DL_FREE(pkg->options, pkg_option_free);
		kh_destroy_pkg_options(pkg->optionshash);
		pkg->flags &= ~PKG_LOAD_OPTIONS;
		break;
	case PKG_FILES:
	case PKG_CONFIG_FILES:
-
		LL_FREE(pkg->files, pkg_file_free);
+
		DL_FREE(pkg->files, pkg_file_free);
		kh_destroy_pkg_files(pkg->filehash);
		kh_free(pkg_config_files, pkg->config_files, struct pkg_config_file, pkg_config_file_free);
		pkg->flags &= ~PKG_LOAD_FILES;
		break;
	case PKG_DIRS:
-
		LL_FREE(pkg->dirs, free);
+
		DL_FREE(pkg->dirs, free);
		kh_destroy_pkg_dirs(pkg->dirhash);
		pkg->flags &= ~PKG_LOAD_DIRS;
		break;
@@ -1333,7 +1327,7 @@ pkg_list_free(struct pkg *pkg, pkg_list list) {
		pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
		break;
	case PKG_CONFLICTS:
-
		LL_FREE(pkg->conflicts, pkg_conflict_free);
+
		DL_FREE(pkg->conflicts, pkg_conflict_free);
		kh_destroy_pkg_conflicts(pkg->conflictshash);
		pkg->flags &= ~PKG_LOAD_CONFLICTS;
		break;
@@ -1748,9 +1742,9 @@ pkg_open_root_fd(struct pkg *pkg)
	path = pkg_kv_get(&pkg->annotations, "relocated");
	if (path == NULL) {
#ifdef F_DUPFD_CLOEXEC
-
		if ((pkg->rootfd = fcntl(rootfd, F_DUPFD_CLOEXEC, 0)) == -1) {
+
		if ((pkg->rootfd = fcntl(ctx.rootfd, F_DUPFD_CLOEXEC, 0)) == -1) {
#else
-
		if ((pkg->rootfd = dup(rootfd)) == -1 || fcntl(pkg->rootfd, F_SETFD, FD_CLOEXEC) == -1) {
+
		if ((pkg->rootfd = dup(ctx.rootfd)) == -1 || fcntl(pkg->rootfd, F_SETFD, FD_CLOEXEC) == -1) {
#endif
			pkg_emit_errno("dup2", "rootfd");
			return (EPKG_FATAL);
@@ -1760,7 +1754,7 @@ pkg_open_root_fd(struct pkg *pkg)

	pkg_absolutepath(path, pkg->rootpath, sizeof(pkg->rootpath), false);

-
	if ((pkg->rootfd = openat(rootfd, pkg->rootpath + 1, O_DIRECTORY|O_CLOEXEC)) >= 0 )
+
	if ((pkg->rootfd = openat(ctx.rootfd, pkg->rootpath + 1, O_DIRECTORY|O_CLOEXEC)) >= 0 )
		return (EPKG_OK);

	pkg->rootpath[0] = '\0';
@@ -1780,7 +1774,7 @@ pkg_message_from_ucl(struct pkg *pkg, const ucl_object_t *obj)
		msg = xcalloc(1, sizeof(*msg));
		msg->str = xstrdup(ucl_object_tostring(obj));
		msg->type = PKG_MESSAGE_ALWAYS;
-
		LL_APPEND(pkg->message, msg);
+
		DL_APPEND(pkg->message, msg);
		return (EPKG_OK);
	}

@@ -1816,7 +1810,7 @@ pkg_message_from_ucl(struct pkg *pkg, const ucl_object_t *obj)
				    " message will always be printed");
		}
		if (msg->type != PKG_MESSAGE_UPGRADE) {
-
			LL_APPEND(pkg->message, msg);
+
			DL_APPEND(pkg->message, msg);
			continue;
		}

@@ -1830,7 +1824,7 @@ pkg_message_from_ucl(struct pkg *pkg, const ucl_object_t *obj)
			msg->maximum_version = xstrdup(ucl_object_tostring(elt));
		}

-
		LL_APPEND(pkg->message, msg);
+
		DL_APPEND(pkg->message, msg);
	}

	return (EPKG_OK);
@@ -1849,7 +1843,7 @@ pkg_message_from_str(struct pkg *pkg, const char *str, size_t len)
		len = strlen(str);
	}

-
	parser = ucl_parser_new(0);
+
	parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);

	if (ucl_parser_add_chunk(parser, (const unsigned char*)str, len)) {
		obj = ucl_parser_get_object(parser);
modified libpkg/pkg.h.in
@@ -118,7 +118,7 @@ typedef void * pkg_iter;
struct pkg_kv {
	char *key;
	char *value;
-
	struct pkg_kv *next;
+
	struct pkg_kv *next, *prev;
};

/**
@@ -810,7 +810,7 @@ int pkg_is_installed(struct pkgdb *db, const char *name);
 */
typedef int(pkg_password_cb)(char *, int, int, void*);
int pkg_create_repo(char *path, const char *output_dir, bool filelist,
-
	const char *metafile, bool legacy);
+
	const char *metafile);
int pkg_finish_repo(const char *output_dir, pkg_password_cb *cb, char **argv,
    int argc, bool filelist);

@@ -1484,8 +1484,6 @@ int pkg_get_myarch(char *pkgarch, size_t sz);
int pkg_get_myarch_legacy(char *pkgarch, size_t sz);

void pkgdb_cmd(int argc, char **argv);
-
int pkg_old_load_from_path(struct pkg *pkg, const char *path);
-
int pkg_from_old(struct pkg *pkg);
int pkg_sshserve(int fd);

int pkg_repos_total_count(void);
modified libpkg/pkg_add.c
@@ -183,28 +183,42 @@ attempt_to_merge(int rootfd, struct pkg_config_file *rcf, struct pkg *local,
static uid_t
get_uid_from_archive(struct archive_entry *ae)
{
-
	char buffer[128];
-
	struct passwd pwent, *result;
-

-
	if ((getpwnam_r(archive_entry_uname(ae), &pwent, buffer, sizeof(buffer),
+
	static char user_buffer[128];
+
	const char *user;
+
	static struct passwd pwent;
+
	struct passwd *result;
+

+
	user = archive_entry_uname(ae);
+
	if (pwent.pw_name != NULL && strcmp(user, pwent.pw_name) == 0)
+
		goto out;
+
	pwent.pw_name = NULL;
+
	if ((getpwnam_r(user, &pwent, user_buffer, sizeof(user_buffer),
	    &result)) < 0)
		return (0);
	if (result == NULL)
		return (0);
+
out:
	return (pwent.pw_uid);
}

static gid_t
get_gid_from_archive(struct archive_entry *ae)
{
-
	char buffer[128];
-
	struct group grent, *result;
-

-
	if ((getgrnam_r(archive_entry_gname(ae), &grent, buffer, sizeof(buffer),
+
	static char group_buffer[128];
+
	static struct group grent;
+
	struct group *result;
+
	const char *group;
+

+
	group = archive_entry_gname(ae);
+
	if (grent.gr_name != NULL && strcmp(group, grent.gr_name) == 0)
+
		goto out;
+
	grent.gr_name = NULL;
+
	if ((getgrnam_r(group, &grent, group_buffer, sizeof(group_buffer),
	    &result)) < 0)
		return (0);
	if (result == NULL)
		return (0);
+
out:
	return (grent.gr_gid);
}

@@ -492,7 +506,7 @@ create_regfile(struct pkg *pkg, struct pkg_file *f, struct archive *a,
	int fd = -1;
	bool tried_mkdir = false;
	size_t len;
-
	char buf[BUFSIZ];
+
	char buf[32768];

	pkg_hidden_tempfile(f->temppath, sizeof(f->temppath), f->path);

modified libpkg/pkg_config.c
@@ -63,13 +63,15 @@
#define INDEXFILE	"INDEX"
#endif

-
int eventpipe = -1;
-
int64_t debug_level = 0;
-
bool developer_mode = false;
-
const char *pkg_rootdir = NULL;
-
int rootfd = -1;
-
int cachedirfd = -1;
-
int pkg_dbdirfd = -1;
+
struct pkg_ctx ctx = {
+
	.eventpipe = -1,
+
	.debug_level = 0,
+
	.developer_mode = false,
+
	.pkg_rootdir = NULL,
+
	.rootfd = -1,
+
	.cachedirfd = -1,
+
	.pkg_dbdirfd = -1,
+
};

struct config_entry {
	uint8_t type;
@@ -447,13 +449,13 @@ connect_evpipe(const char *evpipe) {

	if (S_ISFIFO(st.st_mode)) {
		flag |= O_NONBLOCK;
-
		if ((eventpipe = open(evpipe, flag)) == -1)
+
		if ((ctx.eventpipe = open(evpipe, flag)) == -1)
			pkg_emit_errno("open event pipe", evpipe);
		return;
	}

	if (S_ISSOCK(st.st_mode)) {
-
		if ((eventpipe = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+
		if ((ctx.eventpipe = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
			pkg_emit_errno("Open event pipe", evpipe);
			return;
		}
@@ -462,15 +464,15 @@ connect_evpipe(const char *evpipe) {
		if (strlcpy(sock.sun_path, evpipe, sizeof(sock.sun_path)) >=
		    sizeof(sock.sun_path)) {
			pkg_emit_error("Socket path too long: %s", evpipe);
-
			close(eventpipe);
-
			eventpipe = -1;
+
			close(ctx.eventpipe);
+
			ctx.eventpipe = -1;
			return;
		}

-
		if (connect(eventpipe, (struct sockaddr *)&sock, SUN_LEN(&sock)) == -1) {
+
		if (connect(ctx.eventpipe, (struct sockaddr *)&sock, SUN_LEN(&sock)) == -1) {
			pkg_emit_errno("Connect event pipe", evpipe);
-
			close(eventpipe);
-
			eventpipe = -1;
+
			close(ctx.eventpipe);
+
			ctx.eventpipe = -1;
			return;
		}
	}
@@ -689,7 +691,7 @@ add_repo(const ucl_object_t *obj, struct pkg_repo *r, const char *rname, pkg_ini
		while ((cur = ucl_iterate_object(env, &it, true))) {
			kv = pkg_kv_new(ucl_object_key(cur),
			    ucl_object_tostring_forced(cur));
-
			LL_APPEND(r->env, kv);
+
			DL_APPEND(r->env, kv);
		}
	}
}
@@ -878,7 +880,7 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)

	k = NULL;
	o = NULL;
-
	if (rootfd == -1 && (rootfd = open("/", O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
+
	if (ctx.rootfd == -1 && (ctx.rootfd = open("/", O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
		pkg_emit_error("Impossible to open /");
		return (EPKG_FATAL);
	}
@@ -903,8 +905,8 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
		case PKG_STRING:
			tmp = NULL;
			if (c[i].def != NULL && c[i].def[0] == '/' &&
-
			    pkg_rootdir != NULL) {
-
				xasprintf(&tmp, "%s%s", pkg_rootdir, c[i].def);
+
			    ctx.pkg_rootdir != NULL) {
+
				xasprintf(&tmp, "%s%s", ctx.pkg_rootdir, c[i].def);
			}
			obj = ucl_object_fromstring_common(
			    c[i].def != NULL ? tmp != NULL ? tmp : c[i].def : "", 0, UCL_STRING_TRIM);
@@ -976,12 +978,12 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
	}

	if (path == NULL)
-
		conffd = openat(rootfd, PREFIX"/etc/pkg.conf" + 1, 0);
+
		conffd = openat(ctx.rootfd, PREFIX"/etc/pkg.conf" + 1, 0);
	else
		conffd = open(path, O_RDONLY);
	if (conffd == -1 && errno != ENOENT) {
		pkg_errno("Cannot open %s/%s",
-
		    pkg_rootdir != NULL ? pkg_rootdir : "",
+
		    ctx.pkg_rootdir != NULL ? ctx.pkg_rootdir : "",
		    path);
	}

@@ -1163,8 +1165,8 @@ pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
	if (evpipe != NULL)
		connect_evpipe(evpipe);

-
	debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL"));
-
	developer_mode = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
+
	ctx.debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL"));
+
	ctx.developer_mode = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));

	it = NULL;
	object = ucl_object_find_key(config, "PKG_ENV");
@@ -1320,12 +1322,12 @@ pkg_shutdown(void)
	ucl_object_unref(config);
	HASH_FREE(repos, pkg_repo_free);

-
	if (rootfd != -1)
-
		close(rootfd);
-
	if (cachedirfd != -1)
-
		close(rootfd);
-
	if (pkg_dbdirfd != -1)
-
		close(pkg_dbdirfd);
+
	if (ctx.rootfd != -1)
+
		close(ctx.rootfd);
+
	if (ctx.cachedirfd != -1)
+
		close(ctx.rootfd);
+
	if (ctx.pkg_dbdirfd != -1)
+
		close(ctx.pkg_dbdirfd);

	parsed = false;

@@ -1431,9 +1433,9 @@ pkg_repo_find(const char *reponame)

int64_t
pkg_set_debug_level(int64_t new_debug_level) {
-
	int64_t old_debug_level = debug_level;
+
	int64_t old_debug_level = ctx.debug_level;

-
	debug_level = new_debug_level;
+
	ctx.debug_level = new_debug_level;
	return old_debug_level;
}

@@ -1442,14 +1444,14 @@ pkg_set_rootdir(const char *rootdir) {
	if (pkg_initialized())
		return (EPKG_FATAL);

-
	if (rootfd != -1)
-
		close(rootfd);
+
	if (ctx.rootfd != -1)
+
		close(ctx.rootfd);

-
	if ((rootfd = open(rootdir, O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
+
	if ((ctx.rootfd = open(rootdir, O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
		pkg_emit_error("Impossible to open %s", rootdir);
		return (EPKG_FATAL);
	}
-
	pkg_rootdir = rootdir;
+
	ctx.pkg_rootdir = rootdir;

	return (EPKG_OK);
}
@@ -1459,16 +1461,16 @@ pkg_get_cachedirfd(void)
{
	const char *cachedir;

-
	if (cachedirfd == -1) {
+
	if (ctx.cachedirfd == -1) {
		cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));
		/*
		 * do not check the value as if we cannot open it means
		 * it has not been created yet
		 */
-
		cachedirfd = open(cachedir, O_DIRECTORY|O_CLOEXEC);
+
		ctx.cachedirfd = open(cachedir, O_DIRECTORY|O_CLOEXEC);
	}

-
	return (cachedirfd);
+
	return (ctx.cachedirfd);
}

int
@@ -1476,14 +1478,14 @@ pkg_get_dbdirfd(void)
{
	const char *dbdir;

-
	if (pkg_dbdirfd == -1) {
+
	if (ctx.pkg_dbdirfd == -1) {
		dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
		/*
		 * do not check the value as if we cannot open it means
		 * it has not been created yet
		 */
-
		pkg_dbdirfd = open(dbdir, O_DIRECTORY|O_CLOEXEC);
+
		ctx.pkg_dbdirfd = open(dbdir, O_DIRECTORY|O_CLOEXEC);
	}

-
	return (pkg_dbdirfd);
+
	return (ctx.pkg_dbdirfd);
}
modified libpkg/pkg_create.c
@@ -68,8 +68,8 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
	relocation = pkg_kv_get(&pkg->annotations, "relocated");
	if (relocation == NULL)
		relocation = "";
-
	if (pkg_rootdir != NULL)
-
		relocation = pkg_rootdir;
+
	if (ctx.pkg_rootdir != NULL)
+
		relocation = ctx.pkg_rootdir;

	/*
	 * Get / compute size / checksum if not provided in the manifest
@@ -139,7 +139,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,

		ret = packing_append_file_attr(pkg_archive, fpath, file->path,
		    file->uname, file->gname, file->perm, file->fflags);
-
		if (developer_mode && ret != EPKG_OK)
+
		if (ctx.developer_mode && ret != EPKG_OK)
			return (ret);
		counter_count();
	}
@@ -155,7 +155,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,

		ret = packing_append_file_attr(pkg_archive, fpath, dir->path,
		    dir->uname, dir->gname, dir->perm, dir->fflags);
-
		if (developer_mode && ret != EPKG_OK)
+
		if (ctx.developer_mode && ret != EPKG_OK)
			return (ret);
		counter_count();
	}
@@ -382,7 +382,7 @@ pkg_load_metadata(struct pkg *pkg, const char *mfile, const char *md_dir,
	if (!testing)
		pkg_analyse_files(NULL, pkg, rootdir);

-
	if (developer_mode)
+
	if (ctx.developer_mode)
		pkg_suggest_arch(pkg, pkg->abi, defaultarch);

cleanup:
modified libpkg/pkg_delete.c
@@ -289,8 +289,6 @@ pkg_delete_file(struct pkg *pkg, struct pkg_file *file, unsigned force)
	int fd;
#endif
#endif
-
	int ret;
-

	pkg_open_root_fd(pkg);

	path = file->path;
modified libpkg/pkg_deps.c
@@ -37,7 +37,7 @@
#include "pkg.h"
#include "private/event.h"
#include "private/pkg_deps.h"
-
#include "private/xmalloc.h"
+
#include "xmalloc.h"
#include "utlist.h"

struct pkg_dep_formula *
modified libpkg/pkg_elf.c
@@ -286,7 +286,7 @@ analyse_elf(struct pkg *pkg, const char *fpath)
		goto cleanup;
	}

-
	if (developer_mode)
+
	if (ctx.developer_mode)
		pkg->flags |= PKG_CONTAINS_ELF_OBJECTS;

	if (gelf_getehdr(e, &elfhdr) == NULL) {
@@ -477,7 +477,7 @@ pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage)
		goto cleanup;

	/* Assume no architecture dependence, for contradiction */
-
	if (developer_mode)
+
	if (ctx.developer_mode)
		pkg->flags &= ~(PKG_CONTAINS_ELF_OBJECTS |
				PKG_CONTAINS_STATIC_LIBS |
				PKG_CONTAINS_H_OR_LA);
@@ -489,7 +489,7 @@ pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage)
			strlcpy(fpath, file->path, sizeof(fpath));

		ret = analyse_elf(pkg, fpath);
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			if (ret != EPKG_OK && ret != EPKG_END) {
				failures = true;
				continue;
modified libpkg/pkg_event.c
@@ -59,7 +59,7 @@ pipeevent(struct pkg_event *ev)
	struct pkg_dep *dep = NULL;
	UT_string *msg, *buf;
	struct pkg_event_conflict *cur_conflict;
-
	if (eventpipe < 0)
+
	if (ctx.eventpipe < 0)
		return;

	utstring_new(msg);
@@ -385,7 +385,7 @@ pipeevent(struct pkg_event *ev)
	default:
		break;
	}
-
	dprintf(eventpipe, "%s\n", utstring_body(msg));
+
	dprintf(ctx.eventpipe, "%s\n", utstring_body(msg));
	utstring_free(msg);
	utstring_free(buf);
}
@@ -953,7 +953,7 @@ pkg_debug(int level, const char *fmt, ...)
	struct pkg_event ev;
	va_list ap;

-
	if (debug_level < level)
+
	if (ctx.debug_level < level)
		return;

	ev.type = PKG_EVENT_DEBUG;
modified libpkg/pkg_jobs.c
@@ -2180,7 +2180,7 @@ pkg_jobs_fetch(struct pkg_jobs *j)
	if (dlsize == 0)
		return (EPKG_OK);

-
#ifdef HAVE_STATFS
+
#ifdef HAVE_FSTATFS
	struct statfs fs;
	while (statfs(cachedir, &fs) == -1) {
		if (errno == ENOENT) {
modified libpkg/pkg_jobs_conflicts.c
@@ -171,7 +171,7 @@ pkg_conflicts_register(struct pkg *p1, struct pkg *p2, enum pkg_conflict_type ty
	if (!kh_contains(pkg_conflicts, p1->conflictshash, p2->uid)) {
		c1->uid = xstrdup(p2->uid);
		kh_safe_add(pkg_conflicts, p1->conflictshash, c1, c1->uid);
-
		LL_APPEND(p1->conflicts, c1);
+
		DL_APPEND(p1->conflicts, c1);
		pkg_debug(2, "registering conflict between %s(%s) and %s(%s)",
				p1->uid, p1->type == PKG_INSTALLED ? "l" : "r",
				p2->uid, p2->type == PKG_INSTALLED ? "l" : "r");
@@ -182,7 +182,7 @@ pkg_conflicts_register(struct pkg *p1, struct pkg *p2, enum pkg_conflict_type ty
	if (!kh_contains(pkg_conflicts, p2->conflictshash, p1->uid)) {
		c2->uid = xstrdup(p1->uid);
		kh_safe_add(pkg_conflicts, p2->conflictshash, c2, c2->uid);
-
		LL_APPEND(p2->conflicts, c2);
+
		DL_APPEND(p2->conflicts, c2);
		pkg_debug(2, "registering conflict between %s(%s) and %s(%s)",
				p2->uid, p2->type == PKG_INSTALLED ? "l" : "r",
				p1->uid, p1->type == PKG_INSTALLED ? "l" : "r");
@@ -266,7 +266,7 @@ pkg_conflicts_register_unsafe(struct pkg *p1, struct pkg *p2,
		}

		kh_safe_add(pkg_conflicts, p1->conflictshash, c1, c1->uid);
-
		LL_APPEND(p1->conflicts, c1);
+
		DL_APPEND(p1->conflicts, c1);
	}

	if (c2 == NULL) {
@@ -282,7 +282,7 @@ pkg_conflicts_register_unsafe(struct pkg *p1, struct pkg *p2,
		}

		kh_safe_add(pkg_conflicts, p2->conflictshash, c2, c2->uid);
-
		LL_APPEND(p2->conflicts, c2);
+
		DL_APPEND(p2->conflicts, c2);
	}

	pkg_debug(2, "registering conflict between %s(%s) and %s(%s) on path %s",
modified libpkg/pkg_manifest.c
@@ -3,7 +3,7 @@
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@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:
@@ -13,7 +13,7 @@
 * 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(S) ``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.
@@ -35,6 +35,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+
#include <fcntl.h>
#include <ucl.h>

#include "sha256.h"
@@ -810,7 +811,7 @@ pkg_parse_manifest(struct pkg *pkg, char *buf, size_t len, struct pkg_manifest_k

	pkg_debug(2, "%s", "Parsing manifest from buffer");

-
	p = ucl_parser_new(0);
+
	p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
	if (!ucl_parser_add_chunk(p, buf, len)) {
		pkg_emit_error("Error parsing manifest: %s",
		    ucl_parser_get_error(p));
@@ -851,7 +852,7 @@ pkg_parse_manifest_fileat(int dfd, struct pkg *pkg, const char *file,
	if ((rc = file_to_bufferat(dfd, file, &data, &sz)) != EPKG_OK)
		return (EPKG_FATAL);

-
	p = ucl_parser_new(0);
+
	p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
	if (!ucl_parser_add_string(p, data, sz)) {
		pkg_emit_error("manifest parsing error: %s", ucl_parser_get_error(p));
		ucl_parser_free(p);
@@ -871,22 +872,31 @@ pkg_parse_manifest_file(struct pkg *pkg, const char *file, struct pkg_manifest_k
{
	struct ucl_parser *p = NULL;
	ucl_object_t *obj = NULL;
-
	int rc;
+
	int rc, fd;

	assert(pkg != NULL);
	assert(file != NULL);

	pkg_debug(1, "Parsing manifest from '%s'", file);
+
	fd = open(file, O_RDONLY);
+

+
	if (fd == -1) {
+
		pkg_emit_error("Error loading manifest from %s: %s",
+
				    file, strerror(errno));
+
	}

	errno = 0;
-
	p = ucl_parser_new(0);
-
	if (!ucl_parser_add_file(p, file)) {
+
	p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
+
	if (!ucl_parser_add_fd(p, fd)) {
		pkg_emit_error("Error parsing manifest: %s",
		    ucl_parser_get_error(p));
		ucl_parser_free(p);
+
		close(fd);
		return (EPKG_FATAL);
	}

+
	close(fd);
+

	if ((obj = ucl_parser_get_object(p)) == NULL) {
		ucl_parser_free(p);
		return (EPKG_FATAL);
@@ -975,6 +985,10 @@ pkg_emit_object(struct pkg *pkg, short flags)
	ucl_object_insert_key(top, ucl_object_fromstring_common(pkg->sum, 0,
	    UCL_STRING_TRIM), "sum", 3, false);
	ucl_object_insert_key(top, ucl_object_fromint(pkg->flatsize), "flatsize", 8, false);
+
	if (pkg->dep_formula != NULL) {
+
		ucl_object_insert_key(top, ucl_object_fromstring_common(pkg->dep_formula, 0,
+
		    UCL_STRING_TRIM), "dep_formula", 11, false);
+
	}
	/*
	 * XXX: dirty hack to be compatible with pkg 1.2
	 */
deleted libpkg/pkg_old.c
@@ -1,123 +0,0 @@
-
/*-
-
 * Copyright (c) 2012-2013 Baptiste Daroussin <bapt@FreeBSD.org>
-
 * Copyright (c) 2013 Bryan Drewery <bdrewery@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
-
 *    in this position and unchanged.
-
 * 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(S) ``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(S) 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 <regex.h>
-

-
#include <pkg.h>
-
#include <private/pkg.h>
-

-
static const char * const scripts[] = {
-
	"+INSTALL",
-
	"+PRE_INSTALL",
-
	"+POST_INSTALL",
-
	"+POST_INSTALL",
-
	"+DEINSTALL",
-
	"+PRE_DEINSTALL",
-
	"+POST_DEINSTALL",
-
	"+UPGRADE",
-
	"+PRE_UPGRADE",
-
	"+POST_UPGRADE",
-
	"pkg-install",
-
	"pkg-pre-install",
-
	"pkg-post-install",
-
	"pkg-deinstall",
-
	"pkg-pre-deinstall",
-
	"pkg-post-deinstall",
-
	"pkg-upgrade",
-
	"pkg-pre-upgrade",
-
	"pkg-post-upgrade",
-
	NULL
-
};
-

-
int
-
pkg_old_load_from_path(struct pkg *pkg, const char *path)
-
{
-
	char fpath[MAXPATHLEN];
-
	regex_t preg;
-
	regmatch_t pmatch[2];
-
	int i;
-
	size_t size;
-
	char myarch[BUFSIZ];
-

-
	if (!is_dir(path))
-
		return (EPKG_FATAL);
-

-
	snprintf(fpath, sizeof(fpath), "%s/+CONTENTS", path);
-
	if (ports_parse_plist(pkg, fpath, NULL) != EPKG_OK)
-
		return (EPKG_FATAL);
-

-
	snprintf(fpath, sizeof(fpath), "%s/+COMMENT", path);
-
	if (access(fpath, F_OK) == 0)
-
		pkg_set_from_file(pkg, PKG_COMMENT, fpath, true);
-

-
	snprintf(fpath, sizeof(fpath), "%s/+DESC", path);
-
	if (access(fpath, F_OK) == 0)
-
		pkg_set_from_file(pkg, PKG_DESC, fpath, false);
-

-
	snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", path);
-
	if (access(fpath, F_OK) == 0)
-
		pkg_set_from_file(pkg, PKG_MESSAGE, fpath, false);
-

-
	snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", path);
-
	if (access(fpath, F_OK) == 0)
-
		pkg_set_from_file(pkg, PKG_MTREE, fpath, false);
-

-
	for (i = 0; scripts[i] != NULL; i++) {
-
		snprintf(fpath, sizeof(fpath), "%s/%s", path, scripts[i]);
-
		if (access(fpath, F_OK) == 0)
-
			pkg_addscript_file(pkg, fpath);
-
	}
-

-
	pkg_get_myarch(myarch, BUFSIZ);
-
	pkg->arch = xstrdup(myarch);
-
	pkg->maintainer = xstrdup("unknown");
-
	regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE);
-
	if (regexec(&preg, pkg->desc, 2, pmatch, 0) == 0) {
-
		size = pmatch[1].rm_eo - pmatch[1].rm_so;
-
		pkg->www = xstrndup(&pkg->desc[pmatch[1].rm_so], size);
-
	} else {
-
		pkg->www = xstrdup("UNKNOWN");
-
	}
-
	regfree(&preg);
-

-
	return (EPKG_OK);
-
}
-

-
int
-
pkg_from_old(struct pkg *p)
-
{
-
	struct pkg_file *f = NULL;
-

-
	p->type = PKG_INSTALLED;
-
	while (pkg_files(p, &f) == EPKG_OK) {
-
		if (f->sum == NULL)
-
			continue;
-
		f->sum = pkg_checksum_generate_file(f->path, PKG_HASH_TYPE_SHA256_HEX);
-
	}
-

-
	return (EPKG_OK);
-
}
modified libpkg/pkg_ports.c
@@ -3,7 +3,7 @@
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2012-2013 Bryan Drewery <bdrewery@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:
@@ -13,7 +13,7 @@
 * 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(S) ``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.
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+
#include <fcntl.h>
#include <unistd.h>
#include <uthash.h>

@@ -126,7 +127,7 @@ keyword_open_schema(void)
	if (keyword_schema != NULL)
		return (keyword_schema);

-
	parser = ucl_parser_new(0);
+
	parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
	if (!ucl_parser_add_chunk(parser, keyword_schema_str,
	    sizeof(keyword_schema_str) -1)) {
		pkg_emit_error("Cannot parse schema for keywords: %s",
@@ -247,7 +248,7 @@ dir(struct plist *p, char *line, struct file_attr *a)
		pkg_emit_errno("lstat", testpath);
		if (p->stage != NULL)
			ret = EPKG_FATAL;
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_developer_mode("Plist error: @dirrm %s", line);
			ret = EPKG_FATAL;
		}
@@ -320,7 +321,7 @@ meta_file(struct plist *p, char *line, struct file_attr *a, bool is_config)
		pkg_errno("Unable to access file %s", testpath);
		if (p->stage != NULL)
			ret = EPKG_FATAL;
-
		if (developer_mode) {
+
		if (ctx.developer_mode) {
			pkg_emit_developer_mode("Plist error, missing file: %s",
			    line);
			ret = EPKG_FATAL;
@@ -491,7 +492,7 @@ static int
ignore_next(struct plist *p, __unused char *line, struct file_attr *a)
{
	p->ignore_next = true;
-
	if (developer_mode)
+
	if (ctx.developer_mode)
		pkg_emit_error("Warning: @ignore is deprecated");

	return (EPKG_OK);
@@ -740,7 +741,7 @@ populate_keywords(struct plist *p)
		a = xmalloc(sizeof(struct action));
		strlcpy(k->keyword, keyacts[i].key, sizeof(k->keyword));
		a->perform = keyacts[i].action;
-
		LL_APPEND(k->actions, a);
+
		DL_APPEND(k->actions, a);
		HASH_ADD_STR(p->keywords, keyword, k);
	}
}
@@ -748,8 +749,7 @@ populate_keywords(struct plist *p)
static void
keyword_free(struct keyword *k)
{
-
	LL_FREE(k->actions, free);
-

+
	DL_FREE(k->actions, free);
	free(k);
}

@@ -924,7 +924,7 @@ apply_keyword_file(ucl_object_t *obj, struct plist *p, char *line, struct file_a
				else if (strcasecmp(ucl_object_tostring(elt), "upgrade") == 0)
					msg->type = PKG_MESSAGE_UPGRADE;
			}
-
			LL_APPEND(p->pkg->message, msg);
+
			DL_APPEND(p->pkg->message, msg);
		}
	}

@@ -944,7 +944,7 @@ external_keyword(struct plist *plist, char *keyword, char *line, struct file_att
	struct ucl_parser *parser;
	const char *keyword_dir = NULL;
	char keyfile_path[MAXPATHLEN];
-
	int ret = EPKG_UNKNOWN;
+
	int ret = EPKG_UNKNOWN, fd;
	ucl_object_t *o, *schema;
	struct ucl_schema_error err;

@@ -958,14 +958,23 @@ external_keyword(struct plist *plist, char *keyword, char *line, struct file_att
		    "%s/%s.ucl", keyword_dir, keyword);
	}

-
	parser = ucl_parser_new(0);
-
	if (!ucl_parser_add_file(parser, keyfile_path)) {
+
	fd = open(keyfile_path, O_RDONLY);
+
	if (fd == -1) {
+
		pkg_emit_error("cannot load keyword from %s: %s",
+
				keyfile_path, strerror(errno));
+
		return (EPKG_UNKNOWN);
+
	}
+

+
	parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
+
	if (!ucl_parser_add_fd(parser, fd)) {
		pkg_emit_error("cannot parse keyword: %s",
				ucl_parser_get_error(parser));
		ucl_parser_free(parser);
+
		close(fd);
		return (EPKG_UNKNOWN);
	}

+
	close(fd);
	o = ucl_parser_get_object(parser);
	ucl_parser_free(parser);

@@ -1281,10 +1290,10 @@ pkg_add_port(struct pkgdb *db, struct pkg *pkg, const char *input_path,
	struct pkg_message *msg;

	location = reloc;
-
	if (pkg_rootdir != NULL)
-
		location = pkg_rootdir;
+
	if (ctx.pkg_rootdir != NULL)
+
		location = ctx.pkg_rootdir;

-
	if (pkg_rootdir == NULL && location != NULL)
+
	if (ctx.pkg_rootdir == NULL && location != NULL)
		pkg_kv_add(&pkg->annotations, "relocated", location, "annotation");

	pkg_emit_install_begin(pkg);
modified libpkg/pkg_printf.c
@@ -1722,7 +1722,7 @@ format_architecture(UT_string *buf, const void *data, struct percent_esc *p)
{
	const struct pkg	*pkg = data;

-
	return (string_val(buf, pkg->arch, p));
+
	return (string_val(buf, pkg->abi, p));
}

/*
modified libpkg/pkg_repo.c
@@ -443,7 +443,7 @@ pkg_repo_parse_sigkeys(const char *in, int inlen, struct sig_cert **sc)
			}
			else if (len >= MAXPATHLEN) {
				pkg_emit_error("filename is incorrect for signature_fingerprints"
-
						"output: %d, wanted 5..%d bytes", type, len, MAXPATHLEN);
+
						"output: %d, wanted 5..%d bytes", type, len);
				free(s);
				return (EPKG_FATAL);
			}
@@ -513,7 +513,7 @@ pkg_repo_parse_sigkeys(const char *in, int inlen, struct sig_cert **sc)

static int
pkg_repo_archive_extract_archive(int fd, const char *file,
-
    const char *dest, struct pkg_repo *repo, int dest_fd,
+
    struct pkg_repo *repo, int dest_fd,
    struct sig_cert **signatures)
{
	struct sig_cert *sc = NULL, *s;
@@ -531,23 +531,7 @@ pkg_repo_archive_extract_archive(int fd, const char *file,

	cbdata.afd = fd;
	cbdata.fname = file;
-
	if (dest_fd != -1) {
-
		cbdata.tfd = dest_fd;
-
	}
-
	else if (dest != NULL) {
-
		cbdata.tfd = open (dest, O_WRONLY | O_CREAT | O_TRUNC,
-
				0644);
-
		if (cbdata.tfd == -1) {
-
			pkg_emit_errno("archive_read_extract", "open error");
-
			rc = EPKG_FATAL;
-
			goto cleanup;
-
		}
-
		fchown (fd, 0, 0);
-
	}
-
	else {
-
		pkg_emit_error("internal error: both fd and name are invalid");
-
		return (EPKG_FATAL);
-
	}
+
	cbdata.tfd = dest_fd;

	if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
		cbdata.need_sig = true;
@@ -592,7 +576,6 @@ pkg_repo_archive_extract_archive(int fd, const char *file,
	if (dest_fd != -1)
		(void)lseek(dest_fd, 0, SEEK_SET);

-
cleanup:
	if (rc == EPKG_OK) {
		if (signatures != NULL)
			*signatures = sc;
@@ -603,22 +586,19 @@ cleanup:
		pkg_repo_signatures_free(sc);
	}

-
	if (rc != EPKG_OK)
-
		unlink(dest);
-

	return rc;
}

static int
pkg_repo_archive_extract_check_archive(int fd, const char *file,
-
    const char *dest, struct pkg_repo *repo, int dest_fd)
+
    struct pkg_repo *repo, int dest_fd)
{
	struct sig_cert *sc = NULL, *s, *stmp;
	int ret, rc;

	ret = rc = EPKG_OK;

-
	if (pkg_repo_archive_extract_archive(fd, file, dest, repo, dest_fd, &sc)
+
	if (pkg_repo_archive_extract_archive(fd, file, repo, dest_fd, &sc)
			!= EPKG_OK)
		return (EPKG_FATAL);

@@ -627,13 +607,13 @@ pkg_repo_archive_extract_check_archive(int fd, const char *file,
			pkg_emit_error("No PUBKEY defined. Removing "
			    "repository.");
			rc = EPKG_FATAL;
-
			goto cleanup;
+
			goto out;
		}
		if (sc == NULL) {
			pkg_emit_error("No signature found in the repository.  "
					"Can not validate against %s key.", pkg_repo_key(repo));
			rc = EPKG_FATAL;
-
			goto cleanup;
+
			goto out;
		}
		/*
		 * Here are dragons:
@@ -642,18 +622,18 @@ pkg_repo_archive_extract_check_archive(int fd, const char *file,
		 *
		 * by @bdrewery
		 */
-
		ret = rsa_verify(dest, pkg_repo_key(repo), sc->sig, sc->siglen - 1,
-
				dest_fd);
+
		ret = rsa_verify(pkg_repo_key(repo), sc->sig, sc->siglen - 1,
+
		    dest_fd);
		if (ret != EPKG_OK) {
			pkg_emit_error("Invalid signature, "
					"removing repository.");
			rc = EPKG_FATAL;
-
			goto cleanup;
+
			goto out;
		}
	}
	else if (pkg_repo_signature_type(repo) == SIG_FINGERPRINT) {
		HASH_ITER(hh, sc, s, stmp) {
-
			ret = rsa_verify_cert(dest, s->cert, s->certlen, s->sig, s->siglen,
+
			ret = rsa_verify_cert(s->cert, s->certlen, s->sig, s->siglen,
				dest_fd);
			if (ret == EPKG_OK && s->trusted) {
				break;
@@ -664,24 +644,22 @@ pkg_repo_archive_extract_check_archive(int fd, const char *file,
			pkg_emit_error("No trusted certificate has been used "
			    "to sign the repository");
			rc = EPKG_FATAL;
-
			goto cleanup;
+
			goto out;
		}
	}

-
cleanup:
-
	if (rc != EPKG_OK && dest != NULL)
-
		unlink(dest);
-

+
out:
	return rc;
}

-
static int
+
int
pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, const char *filename,
-
    time_t *t, int *rc)
+
    time_t *t, int *rc, size_t *sz)
{
	int fd, dest_fd;
	const char *tmpdir;
	char tmp[MAXPATHLEN];
+
	struct stat st;

	fd = pkg_repo_fetch_remote_tmp(repo, filename,
			packing_format_to_string(repo->meta->packing_format), t, rc);
@@ -703,7 +681,7 @@ pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, const char *filename,
	}

	(void)unlink(tmp);
-
	if (pkg_repo_archive_extract_check_archive(fd, filename, NULL, repo, dest_fd)
+
	if (pkg_repo_archive_extract_check_archive(fd, filename, repo, dest_fd)
			!= EPKG_OK) {
		*rc = EPKG_FATAL;
		close(dest_fd);
@@ -713,44 +691,14 @@ pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, const char *filename,

	/* Thus removing archived file as well */
	close(fd);
-

-
	return (dest_fd);
-
}
-

-
unsigned char *
-
pkg_repo_fetch_remote_extract_mmap(struct pkg_repo *repo, const char *filename,
-
    time_t *t, int *rc, size_t *sz)
-
{
-
	int fd;
-
	struct stat st;
-
	unsigned char *map;
-

-
	fd = pkg_repo_fetch_remote_extract_fd(repo, filename, t, rc);
-
	if (fd == -1) {
-
		return (NULL);
-
	}
-

-
	if (fstat(fd, &st) == -1) {
-
		close(fd);
-
		return (MAP_FAILED);
+
	if (fstat(dest_fd, &st) == -1) {
+
		close(dest_fd);
+
		return (-1);
	}

	*sz = st.st_size;
-
	if (st.st_size > SSIZE_MAX) {
-
		pkg_emit_error("%s too large", filename);
-
		close(fd);
-
		return (MAP_FAILED);
-
	}
-

-
	map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-
	close(fd);
-
	if (map == MAP_FAILED) {
-
		pkg_emit_errno("pkg_repo_fetch_remote_mmap", "cannot mmap fetched");
-
		*rc = EPKG_FATAL;
-
		return (MAP_FAILED);
-
	}

-
	return (map);
+
	return (dest_fd);
}

struct pkg_repo_check_cbdata {
@@ -770,9 +718,8 @@ pkg_repo_meta_extract_pubkey(int fd, void *ud)
	struct iovec iov[2];
	int rc = EPKG_OK;
	int64_t res_len = 0;
-
	bool found = false;

-
	parser = ucl_parser_new(0);
+
	parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
	if (!ucl_parser_add_chunk(parser, cbdata->map, cbdata->len)) {
		pkg_emit_error("cannot parse repository meta from %s",
				ucl_parser_get_error(parser));
@@ -788,30 +735,28 @@ pkg_repo_meta_extract_pubkey(int fd, void *ud)
	if (obj == NULL) {
		pkg_emit_error("cannot find key for signature %s in meta",
				cbdata->name);
-
		rc = EPKG_FATAL;
+
		ucl_object_unref(top);
+
		return (EPKG_FATAL);
	}
-
	else {
-
		while(!found && (cur = ucl_iterate_object(obj, &iter, false)) != NULL) {
-
			elt = ucl_object_find_key(cur, "name");
-
			if (elt != NULL && elt->type == UCL_STRING) {
-
				if (strcmp(ucl_object_tostring(elt), cbdata->name) == 0) {
-
					elt = ucl_object_find_key(cur, "data");
-
					if (elt == NULL || elt->type != UCL_STRING)
-
						continue;
-

-
					/* +1 to include \0 at the end */
-
					res_len = elt->len + 1;
-
					iov[0].iov_base = (void *)ucl_object_tostring(elt);
-
					iov[0].iov_len = res_len;
-
					if (writev(fd, iov, 1) == -1) {
-
						pkg_emit_errno("pkg_repo_meta_extract_pubkey",
-
								"writev error");
-
						rc = EPKG_FATAL;
-
						break;
-
					}
-
					found = true;
-
				}
-
			}
+
	while((cur = ucl_iterate_object(obj, &iter, false)) != NULL) {
+
		elt = ucl_object_find_key(cur, "name");
+
		if (elt == NULL || elt->type != UCL_STRING)
+
			continue;
+
		if (strcmp(ucl_object_tostring(elt), cbdata->name) != 0)
+
			continue;
+
		elt = ucl_object_find_key(cur, "data");
+
		if (elt == NULL || elt->type != UCL_STRING)
+
			continue;
+

+
		/* +1 to include \0 at the end */
+
		res_len = elt->len + 1;
+
		iov[0].iov_base = (void *)ucl_object_tostring(elt);
+
		iov[0].iov_len = res_len;
+
		if (writev(fd, iov, 1) == -1) {
+
			pkg_emit_errno("pkg_repo_meta_extract_pubkey",
+
					"writev error");
+
			rc = EPKG_FATAL;
+
			break;
		}
	}

@@ -826,29 +771,27 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	char filepath[MAXPATHLEN];
	struct pkg_repo_meta *nmeta;
	struct stat st;
-
	const char *dbdir = NULL;
	unsigned char *map = NULL;
-
	int fd;
+
	int fd, dbdirfd, metafd;
	int rc = EPKG_OK, ret;
	struct sig_cert *sc = NULL, *s, *stmp;
	struct pkg_repo_check_cbdata cbdata;

-
	dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
-

+
	dbdirfd = pkg_get_dbdirfd();
	fd = pkg_repo_fetch_remote_tmp(repo, "meta", "txz", t, &rc);
	if (fd == -1)
		return (rc);

-
	snprintf(filepath, sizeof(filepath), "%s/%s.meta", dbdir, pkg_repo_name(repo));
+
	snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));

-
	/* Remove old metafile */
-
	if (unlink (filepath) == -1 && errno != ENOENT) {
+
	metafd = openat(dbdirfd, filepath, O_RDWR|O_CREAT|O_TRUNC, 0644);
+
	if (metafd == -1) {
		close(fd);
-
		return (EPKG_FATAL);
+
		return (rc);
	}

	if (pkg_repo_signature_type(repo) == SIG_PUBKEY) {
-
		if ((rc = pkg_repo_archive_extract_check_archive(fd, "meta", filepath, repo, -1)) != EPKG_OK) {
+
		if ((rc = pkg_repo_archive_extract_check_archive(fd, "meta", repo, metafd)) != EPKG_OK) {
			close (fd);
			return (rc);
		}
@@ -861,11 +804,14 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	 * a corresponding key from meta file.
	 */

-
	if ((rc = pkg_repo_archive_extract_archive(fd, "meta", filepath, repo, -1, &sc)) != EPKG_OK) {
+
	if ((rc = pkg_repo_archive_extract_archive(fd, "meta", repo,
+
	    metafd, &sc)) != EPKG_OK) {
+
		close(metafd);
+
		unlinkat(dbdirfd, filepath, 0);
		close (fd);
		return (rc);
	}
-

+
	close(metafd);
	close(fd);

	if (repo->signature_type == SIG_FINGERPRINT && repo->trusted_fp == NULL) {
@@ -874,20 +820,19 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	}

	/* Map meta file for extracting pubkeys from it */
-
	if ((fd = open(filepath, O_RDONLY)) == -1) {
+
	if ((metafd = openat(dbdirfd, filepath, O_RDONLY)) == -1) {
		pkg_emit_errno("pkg_repo_fetch_meta", "cannot open meta fetched");
		rc = EPKG_FATAL;
		goto cleanup;
	}

-
	if (fstat(fd, &st) == -1) {
+
	if (fstat(metafd, &st) == -1) {
		pkg_emit_errno("pkg_repo_fetch_meta", "cannot stat meta fetched");
		rc = EPKG_FATAL;
		goto cleanup;
	}

	map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-
	close(fd);
	if (map == MAP_FAILED) {
		pkg_emit_errno("pkg_repo_fetch_meta", "cannot mmap meta fetched");
		rc = EPKG_FATAL;
@@ -918,8 +863,8 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
		}

		HASH_ITER(hh, sc, s, stmp) {
-
			ret = rsa_verify_cert(filepath, s->cert, s->certlen, s->sig, s->siglen,
-
				-1);
+
			ret = rsa_verify_cert(s->cert, s->certlen, s->sig, s->siglen,
+
				metafd);
			if (ret == EPKG_OK && s->trusted)
				break;

@@ -934,7 +879,7 @@ pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t)
	}

load_meta:
-
	if ((rc = pkg_repo_meta_load(filepath, &nmeta)) != EPKG_OK) {
+
	if ((rc = pkg_repo_meta_load(metafd, &nmeta)) != EPKG_OK) {
		if (map != NULL)
			munmap(map, st.st_size);

@@ -954,7 +899,7 @@ cleanup:
		pkg_repo_signatures_free(sc);

	if (rc != EPKG_OK)
-
		unlink(filepath);
+
		unlinkat(dbdirfd, filepath, 0);

	return (rc);
}
@@ -1010,18 +955,27 @@ pkg_repo_load_fingerprint(const char *dir, const char *filename)
	struct ucl_parser *p = NULL;
	char path[MAXPATHLEN];
	struct fingerprint *f = NULL;
+
	int fd;

	snprintf(path, sizeof(path), "%s/%s", dir, filename);
+
	fd = open(path, O_RDONLY);
+
	if (fd == -1) {
+
		pkg_emit_error("cannot load fingerprints from %s: %s",
+
				path, strerror(errno));
+
		return (NULL);
+
	}

-
	p = ucl_parser_new(0);
+
	p = ucl_parser_new(UCL_PARSER_NO_FILEVARS);

-
	if (!ucl_parser_add_file(p, path)) {
-
		pkg_emit_error("%s", ucl_parser_get_error(p));
+
	if (!ucl_parser_add_fd(p, fd)) {
+
		pkg_emit_error("cannot parse fingerprints: %s", ucl_parser_get_error(p));
		ucl_parser_free(p);
+
		close(fd);
		return (NULL);
	}

	obj = ucl_parser_get_object(p);
+
	close(fd);

	if (obj->type == UCL_OBJECT)
		f = pkg_repo_parse_fingerprint(obj);
modified libpkg/pkg_repo_create.c
@@ -499,7 +499,7 @@ pkg_create_repo_read_pipe(int fd, struct digest_list_entry **dlist)

int
pkg_create_repo(char *path, const char *output_dir, bool filelist,
-
	const char *metafile, bool legacy)
+
	const char *metafile)
{
	FTS *fts = NULL;
	struct pkg_fts_item *fts_items = NULL, *fts_cur, *fts_start;
@@ -511,6 +511,8 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
	int cur_pipe[2], fd;
	struct pkg_repo_meta *meta = NULL;
	int retcode = EPKG_OK;
+
	ucl_object_t *meta_dump;
+
	FILE *mfile;

	char *repopath[2];
	char packagesite[MAXPATHLEN],
@@ -539,12 +541,18 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
	}

	if (metafile != NULL) {
-
		if (pkg_repo_meta_load(metafile, &meta) != EPKG_OK) {
+
		fd = open(metafile, O_RDONLY);
+
		if (fd == -1) {
			pkg_emit_error("meta loading error while trying %s", metafile);
			return (EPKG_FATAL);
		}
-
	}
-
	else {
+
		if (pkg_repo_meta_load(fd, &meta) != EPKG_OK) {
+
			pkg_emit_error("meta loading error while trying %s", metafile);
+
			close(fd);
+
			return (EPKG_FATAL);
+
		}
+
		close(fd);
+
	} else {
		meta = pkg_repo_meta_default();
	}

@@ -632,7 +640,7 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,

			if (pkg_create_repo_worker(fts_start, cur_jobs,
					packagesite, (filelist ? filesite : NULL), cur_pipe[1],
-
					(legacy ? NULL : meta)) == EPKG_FATAL) {
+
					meta) == EPKG_FATAL) {
				close(cur_pipe[0]);
				close(cur_pipe[1]);
				retcode = EPKG_FATAL;
@@ -720,25 +728,20 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
	DL_SORT(dlist, pkg_digest_sort_compare_func);

	/* Write metafile */
-
	if (!legacy) {
-
		ucl_object_t *meta_dump;
-
		FILE *mfile;
-

-
		snprintf(repodb, sizeof(repodb), "%s/%s", output_dir,
-
			"meta");
-
		if ((mfile = fopen(repodb, "w")) != NULL) {
-
			meta_dump = pkg_repo_meta_to_ucl(meta);
-
			ucl_object_emit_file(meta_dump, UCL_EMIT_CONFIG, mfile);
-
			ucl_object_unref(meta_dump);
-
			fclose(mfile);
-
		}
-
		else {
-
			pkg_emit_notice("cannot create metafile at %s", repodb);
-
		}
+
	snprintf(repodb, sizeof(repodb), "%s/%s", output_dir,
+
		"meta");
+
	if ((mfile = fopen(repodb, "w")) != NULL) {
+
		meta_dump = pkg_repo_meta_to_ucl(meta);
+
		ucl_object_emit_file(meta_dump, UCL_EMIT_CONFIG, mfile);
+
		ucl_object_unref(meta_dump);
+
		fclose(mfile);
+
	}
+
	else {
+
		pkg_emit_notice("cannot create metafile at %s", repodb);
	}
cleanup:
	HASH_ITER (hh, conflicts, curcb, tmpcb) {
-
		LL_FREE(curcb->conflicts, pkg_conflict_free);
+
		DL_FREE(curcb->conflicts, pkg_conflict_free);
		kh_destroy_pkg_conflicts(curcb->conflictshash);
		HASH_DEL(conflicts, curcb);
		free(curcb);
@@ -822,7 +825,7 @@ pkg_repo_sign(char *path, char **argv, int argc, UT_string **sig, UT_string **ce
			break;
		}
		if (buf != NULL)
-
			utstring_printf(buf, "%s", line);
+
			utstring_bincpy(buf, line, linelen);
	}

	if (pclose(fp) != 0) {
@@ -913,7 +916,7 @@ pkg_finish_repo(const char *output_dir, pkg_password_cb *password_cb,
	struct rsa_key *rsa = NULL;
	struct pkg_repo_meta *meta;
	struct stat st;
-
	int ret = EPKG_OK, nfile = 0;
+
	int ret = EPKG_OK, nfile = 0, fd;
	const int files_to_pack = 4;
	bool legacy = false;

@@ -942,13 +945,13 @@ pkg_finish_repo(const char *output_dir, pkg_password_cb *password_cb,
	/*
	 * If no meta is defined, then it is a legacy repo
	 */
-
	if (access(repo_path, R_OK) != -1) {
-
		if (pkg_repo_meta_load(repo_path, &meta) != EPKG_OK) {
+
	if ((fd = open(repo_path, O_RDONLY)) != -1) {
+
		if (pkg_repo_meta_load(fd, &meta) != EPKG_OK) {
			pkg_emit_error("meta loading error while trying %s", repo_path);
			rsa_free(rsa);
+
			close(fd);
			return (EPKG_FATAL);
-
		}
-
		else {
+
		} else {
			meta = pkg_repo_meta_default();
		}
		if (pkg_repo_pack_db(repo_meta_file, repo_path, repo_path, rsa, meta,
modified libpkg/pkg_repo_meta.c
@@ -129,7 +129,7 @@ pkg_repo_meta_open_schema_v1()
	if (repo_meta_schema_v1 != NULL)
		return (repo_meta_schema_v1);

-
	parser = ucl_parser_new(0);
+
	parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
	if (!ucl_parser_add_chunk(parser, meta_schema_str_v1,
			sizeof(meta_schema_str_v1) - 1)) {
		pkg_emit_error("cannot parse schema for repo meta: %s",
@@ -247,7 +247,7 @@ pkg_repo_meta_version(ucl_object_t *top)
}

int
-
pkg_repo_meta_load(const char *file, struct pkg_repo_meta **target)
+
pkg_repo_meta_load(const int fd, struct pkg_repo_meta **target)
{
	struct ucl_parser *parser;
	ucl_object_t *top, *schema;
@@ -256,8 +256,8 @@ pkg_repo_meta_load(const char *file, struct pkg_repo_meta **target)

	parser = ucl_parser_new(UCL_PARSER_KEY_LOWERCASE);

-
	if (!ucl_parser_add_file(parser, file)) {
-
		pkg_emit_error("cannot parse repository meta from %s: %s", file,
+
	if (!ucl_parser_add_fd(parser, fd)) {
+
		pkg_emit_error("cannot parse repository meta: %s",
				ucl_parser_get_error(parser));
		ucl_parser_free(parser);
		return (EPKG_FATAL);
@@ -268,7 +268,7 @@ pkg_repo_meta_load(const char *file, struct pkg_repo_meta **target)

	version = pkg_repo_meta_version(top);
	if (version == -1) {
-
		pkg_emit_error("repository meta %s has wrong version or wrong format", file);
+
		pkg_emit_error("repository meta has wrong version or wrong format");
		ucl_object_unref(top);
		return (EPKG_FATAL);
	}
@@ -279,14 +279,14 @@ pkg_repo_meta_load(const char *file, struct pkg_repo_meta **target)

		if (schema != NULL) {
			if (!ucl_object_validate(schema, top, &err)) {
-
				pkg_emit_error("repository meta %s cannot be validated: %s", file, err.msg);
+
				pkg_emit_error("repository meta cannot be validated: %s", err.msg);
				ucl_object_unref(top);
				return (EPKG_FATAL);
			}
		}
	}
	else {
-
		pkg_emit_error("repository meta %s has wrong version %d", file, version);
+
		pkg_emit_error("repository meta has wrong version %d", version);
		ucl_object_unref(top);
		return (EPKG_FATAL);
	}
modified libpkg/pkg_solve.c
@@ -267,7 +267,7 @@ pkg_debug_print_rule(struct pkg_solve_rule *rule)
{
	UT_string *sb;

-
	if (debug_level < 3)
+
	if (ctx.debug_level < 3)
		return;

	utstring_new(sb);
modified libpkg/pkgdb.c
@@ -58,9 +58,7 @@

#include <sqlite3.h>

-
#ifdef HAVE_SYS_STATFS_H
-
#include <sys/statfs.h>
-
#elif defined(HAVE_SYS_STATVFS_H)
+
#if defined(HAVE_SYS_STATVFS_H)
#include <sys/statvfs.h>
#endif

@@ -964,12 +962,22 @@ pkgdb_open_repos(struct pkgdb *db, const char *reponame)
	return (EPKG_OK);
}

+
static const char*
+
_dbdir_trim_path(const char*path)
+
{
+
	const char *p = strrchr(path, '/');
+

+
	if(p == NULL)
+
		return (path);
+
	return (p + 1);
+
}
+

static int
_dbdir_open(const char *path, int flags, int mode)
{
	int dfd = pkg_get_dbdirfd();

-
	return (openat(dfd, strrchr(path, '/') + 1, flags, mode));
+
	return (openat(dfd, _dbdir_trim_path(path), flags, mode));
}

static int
@@ -977,7 +985,7 @@ _dbdir_access(const char *path, int mode)
{
	int dfd = pkg_get_dbdirfd();

-
	return (faccessat(dfd, strrchr(path, '/') + 1, mode, 0));
+
	return (faccessat(dfd, _dbdir_trim_path(path), mode, 0));
}

static int
@@ -985,7 +993,15 @@ _dbdir_stat(const char * path, struct stat * sb)
{
	int dfd = pkg_get_dbdirfd();

-
	return (fstatat(dfd, strrchr(path, '/') + 1, sb, 0));
+
	return (fstatat(dfd, _dbdir_trim_path(path), sb, 0));
+
}
+

+
static int
+
_dbdir_lstat(const char * path, struct stat * sb)
+
{
+
	int dfd = pkg_get_dbdirfd();
+

+
	return (fstatat(dfd, _dbdir_trim_path(path), sb, AT_SYMLINK_NOFOLLOW));
}

static int
@@ -993,7 +1009,7 @@ _dbdir_unlink(const char *path)
{
	int dfd = pkg_get_dbdirfd();

-
	return (unlinkat(dfd, strrchr(path, '/') + 1, 0));
+
	return (unlinkat(dfd, _dbdir_trim_path(path), 0));
}

static int
@@ -1001,7 +1017,7 @@ _dbdir_mkdir(const char *path, mode_t mode)
{
	int dfd = pkg_get_dbdirfd();

-
	return (mkdirat(dfd, strrchr(path, '/') + 1, mode));
+
	return (mkdirat(dfd, _dbdir_trim_path(path), mode));
}

void
@@ -1013,6 +1029,7 @@ pkgdb_syscall_overload(void)
	vfs->xSetSystemCall(vfs, "open", (sqlite3_syscall_ptr)_dbdir_open);
	vfs->xSetSystemCall(vfs, "access", (sqlite3_syscall_ptr)_dbdir_access);
	vfs->xSetSystemCall(vfs, "stat", (sqlite3_syscall_ptr)_dbdir_stat);
+
	vfs->xSetSystemCall(vfs, "lstat", (sqlite3_syscall_ptr)_dbdir_lstat);
	vfs->xSetSystemCall(vfs, "unlink", (sqlite3_syscall_ptr)_dbdir_unlink);
	vfs->xSetSystemCall(vfs, "mkdir", (sqlite3_syscall_ptr)_dbdir_mkdir);
}
@@ -1020,7 +1037,7 @@ pkgdb_syscall_overload(void)
void
pkgdb_setup_lock(void)
{
-
	const char *dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
+
	int dbdirfd = pkg_get_dbdirfd();

	if (pkg_object_bool(pkg_config_get("NFS_WITH_PROPER_LOCKING")))
		return;
@@ -1032,14 +1049,14 @@ pkgdb_setup_lock(void)
#if defined(HAVE_SYS_STATVFS_H) && defined(ST_LOCAL)
	struct statvfs stfs;

-
	if (statvfs(dbdir, &stfs) == 0) {
+
	if (fstatvfs(dbdirfd, &stfs) == 0) {
		if ((stfs.f_flag & ST_LOCAL) != ST_LOCAL)
			sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
	}
-
#elif defined(HAVE_STATFS) && defined(MNT_LOCAL)
+
#elif defined(HAVE_FSTATFS) && defined(MNT_LOCAL)
	struct statfs stfs;

-
	if (statfs(dbdir, &stfs) == 0) {
+
	if (fstatfs(dbdirfd, &stfs) == 0) {
		if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL)
			sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
	}
modified libpkg/pkgdb_iterator.c
@@ -828,8 +828,10 @@ populate_pkg(sqlite3_stmt *stmt, struct pkg *pkg) {
						pkg_message_from_str(pkg, msg, 0);
					}
					else {
-
						pkg->message = xcalloc(1, sizeof(*pkg->message));
-
						pkg->message->str = xstrdup(msg);
+
						struct pkg_message *message;
+
						message = xcalloc(1, sizeof(*pkg->message));
+
						message->str = xstrdup(msg);
+
						DL_APPEND(pkg->message, message);
					}
				}
				else {
modified libpkg/private/pkg.h
@@ -44,7 +44,7 @@
#include <utstring.h>
#include <ucl.h>

-
#include "private/xmalloc.h"
+
#include "xmalloc.h"
#include "private/utils.h"

#define UCL_COUNT(obj) ((obj)?((obj)->len):0)
@@ -227,15 +227,18 @@
	}						\
} while (0)

+
struct pkg_ctx {
+
	int eventpipe;
+
	int64_t debug_level;
+
	bool developer_mode;
+
	const char *pkg_rootdir;
+
	int rootfd;
+
	int cachedirfd;
+
	int dbdirfd;
+
	int pkg_dbdirfd;
+
};

-

-
extern int eventpipe;
-
extern int64_t debug_level;
-
extern bool developer_mode;
-
extern const char *pkg_rootdir;
-
extern int rootfd;
-
extern int cachedirfd;
-
extern int dbdirfd;
+
extern struct pkg_ctx ctx;

struct pkg_repo_it;
struct pkg_repo;
@@ -336,7 +339,7 @@ struct pkg_message {
	char			*minimum_version;
	char			*maximum_version;
	pkg_message_t		 type;
-
	struct pkg_message	*next;
+
	struct pkg_message	*next, *prev;
};

enum pkg_conflict_type {
@@ -350,7 +353,7 @@ struct pkg_conflict {
	char *uid;
	char *digest;
	enum pkg_conflict_type type;
-
	struct pkg_conflict *next;
+
	struct pkg_conflict *next, *prev;
};

typedef enum {
@@ -379,7 +382,7 @@ struct pkg_file {
	u_long		 fflags;
	struct pkg_config_file *config;
	struct timespec	 time[2];
-
	struct pkg_file	*next;
+
	struct pkg_file	*next, *prev;
};

struct pkg_dir {
@@ -392,7 +395,7 @@ struct pkg_dir {
	gid_t		 gid;
	bool		 noattrs;
	struct timespec	 time[2];
-
	struct pkg_dir	*next;
+
	struct pkg_dir	*next, *prev;
};

struct pkg_option {
@@ -400,7 +403,7 @@ struct pkg_option {
	char	*value;
	char	*default_value;
	char	*description;
-
	struct pkg_option *next;
+
	struct pkg_option *next, *prev;
};

struct http_mirror {
@@ -595,7 +598,7 @@ struct file_attr {

struct action {
	int (*perform)(struct plist *, char *, struct file_attr *);
-
	struct action *next;
+
	struct action *next, *prev;
};

/* sql helpers */
@@ -635,12 +638,12 @@ int pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
    time_t *t, ssize_t offset, int64_t size);
int pkg_repo_fetch_package(struct pkg *pkg);
int pkg_repo_mirror_package(struct pkg *pkg, const char *destdir);
-
unsigned char *pkg_repo_fetch_remote_extract_mmap(struct pkg_repo *repo,
+
int pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo,
    const char *filename, time_t *t, int *rc, size_t *sz);
int pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t);

struct pkg_repo_meta *pkg_repo_meta_default(void);
-
int pkg_repo_meta_load(const char *file, struct pkg_repo_meta **target);
+
int pkg_repo_meta_load(const int fd, struct pkg_repo_meta **target);
void pkg_repo_meta_free(struct pkg_repo_meta *meta);
ucl_object_t * pkg_repo_meta_to_ucl(struct pkg_repo_meta *meta);
bool pkg_repo_meta_is_special_file(const char *file, struct pkg_repo_meta *meta);
modified libpkg/private/utils.h
@@ -73,9 +73,8 @@ int is_dir(const char *);
int rsa_new(struct rsa_key **, pkg_password_cb *, char *path);
void rsa_free(struct rsa_key *);
int rsa_sign(char *path, struct rsa_key *rsa, unsigned char **sigret, unsigned int *siglen);
-
int rsa_verify(const char *path, const char *key,
-
		unsigned char *sig, unsigned int sig_len, int fd);
-
int rsa_verify_cert(const char *path, unsigned char *cert,
+
int rsa_verify(const char *key, unsigned char *sig, unsigned int sig_len, int fd);
+
int rsa_verify_cert(unsigned char *cert,
    int certlen, unsigned char *sig, int sig_len, int fd);

bool check_for_hardlink(hardlinks_t *hl, struct stat *st);
deleted libpkg/private/xmalloc.h
@@ -1,58 +0,0 @@
-
#ifndef XMALLOC_H
-
#define XMALLOC_H
-

-
static inline void *xmalloc(size_t size)
-
{
-
	void *ptr = malloc(size);
-
	if (ptr == NULL)
-
		abort();
-
	return (ptr);
-
}
-

-
static inline void *xcalloc(size_t n, size_t size)
-
{
-
	void *ptr = calloc(n, size);
-
	if (ptr == NULL)
-
		abort();
-
	return (ptr);
-
}
-

-
static inline void *xrealloc(void *ptr, size_t size)
-
{
-
	ptr = realloc(ptr, size);
-
	if (ptr == NULL)
-
		abort();
-
	return (ptr);
-
}
-

-
static inline char *xstrdup(const char *str)
-
{
-
	char *s = strdup(str);
-
	if (s == NULL)
-
		abort();
-
	return (s);
-
}
-

-
static inline char *xstrndup(const char *str, size_t n)
-
{
-
	char *s = strndup(str, n);
-
	if (s == NULL)
-
		abort();
-
	return (s);
-
}
-

-
static inline int xasprintf(char **ret, const char *fmt, ...)
-
{
-
	va_list ap;
-
	int i;
-

-
	va_start(ap, fmt);
-
	i = vasprintf(ret, fmt, ap);
-
	va_end(ap);
-

-
	if (i < 0 || *ret == NULL)
-
		abort();
-

-
	return (i);
-
}
-
#endif
modified libpkg/repo/binary/init.c
@@ -26,6 +26,7 @@

#include <assert.h>
#include <errno.h>
+
#include <fcntl.h>
#include <regex.h>
#include <grp.h>
#include <stdlib.h>
@@ -297,37 +298,37 @@ int
pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode)
{
	char filepath[MAXPATHLEN];
-
	const char *dbdir = NULL;
	sqlite3 *sqlite = NULL;
-
	int flags;
+
	int flags, dbdirfd, fd;
	int64_t res;
	struct pkg_repo_it *it;
	struct pkg *pkg = NULL;

-
	dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	sqlite3_initialize();

	pkgdb_setup_lock();
	pkgdb_syscall_overload();

-
	snprintf(filepath, sizeof(filepath), "%s/%s.meta",
-
		dbdir, pkg_repo_name(repo));
+
	dbdirfd = pkg_get_dbdirfd();
+
	snprintf(filepath, sizeof(filepath), "%s.meta", pkg_repo_name(repo));

	/* Open metafile */
-
	if (access(filepath, R_OK) != -1) {
-
		if (pkg_repo_meta_load(filepath, &repo->meta) != EPKG_OK) {
+
	if ((fd = openat(dbdirfd, filepath, O_RDONLY)) != -1) {
+
		if (pkg_repo_meta_load(fd, &repo->meta) != EPKG_OK) {
			pkg_emit_error("Repository %s load error: "
					"meta cannot be loaded %s", pkg_repo_name(repo),
					strerror(errno));
+
			close(fd);
			return (EPKG_FATAL);
		}
+
		close(fd);
	}

-
	snprintf(filepath, sizeof(filepath), "%s/%s",
-
		dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo)));
+
	snprintf(filepath, sizeof(filepath), "%s",
+
		pkg_repo_binary_get_filename(pkg_repo_name(repo)));

	/* Always want read mode here */
-
	if (access(filepath, R_OK | mode) != 0) {
+
	if (faccessat(dbdirfd, filepath, R_OK | mode, 0) != 0) {
		pkg_emit_error("Repository %s load error: "
				"access repo file(%s) failed: %s", pkg_repo_name(repo),
				filepath,
@@ -411,37 +412,20 @@ int
pkg_repo_binary_create(struct pkg_repo *repo)
{
	char filepath[MAXPATHLEN];
-
	const char *dbdir = NULL;
	sqlite3 *sqlite = NULL;
-
	int retcode;
+
	int retcode, dbdirfd;

	sqlite3_initialize();
-
	dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));

-
	snprintf(filepath, sizeof(filepath), "%s/%s",
-
		dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo)));
+
	dbdirfd = pkg_get_dbdirfd();
+
	snprintf(filepath, sizeof(filepath), "%s",
+
		pkg_repo_binary_get_filename(pkg_repo_name(repo)));
	/* Should never ever happen */
-
	if (access(filepath, R_OK) == 0)
+
	if (faccessat(dbdirfd, filepath, R_OK, 0) == 0)
		return (EPKG_CONFLICT);

-
	/*
-
	 * Fall back on unix-dotfile locking strategy if on a network filesystem
-
	 */
-
#if defined(HAVE_SYS_STATVFS_H) && defined(ST_LOCAL)
-
	struct statvfs stfs;
-

-
	if (statvfs(dbdir, &stfs) == 0) {
-
		if ((stfs.f_flag & ST_LOCAL) != ST_LOCAL)
-
			sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
-
	}
-
#elif defined(HAVE_STATFS) && defined(MNT_LOCAL)
-
	struct statfs stfs;
-

-
	if (statfs(dbdir, &stfs) == 0) {
-
		if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL)
-
			sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1);
-
	}
-
#endif
+
	pkgdb_setup_lock();
+
	pkgdb_syscall_overload();

	/* Open for read/write/create */
	if (sqlite3_open(filepath, &sqlite) != SQLITE_OK)
modified libpkg/repo/binary/update.c
@@ -26,7 +26,6 @@

#include <sys/stat.h>
#include <sys/param.h>
-
#include <sys/mman.h>
#include <sys/time.h>

#include <stdio.h>
@@ -459,16 +458,19 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
	time_t *mtime, bool force)
{
	struct pkg *pkg = NULL;
-
	unsigned char *walk;
	int rc = EPKG_FATAL;
	sqlite3 *sqlite = NULL;
	int cnt = 0;
	time_t local_t;
	struct pkg_manifest_key *keys = NULL;
-
	unsigned char *map = MAP_FAILED;
	size_t len = 0;
	bool in_trans = false;
-
	char path[MAXPATHLEN];
+
	char *path = NULL;
+
	FILE *f = NULL;
+
	int fd;
+
	char *line = NULL;
+
	size_t linecap = 0;
+
	ssize_t linelen, totallen = 0;

	pkg_debug(1, "Pkgrepo, begin update of '%s'", name);

@@ -484,10 +486,12 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,

	/* Fetch packagesite */
	local_t = *mtime;
-
	map = pkg_repo_fetch_remote_extract_mmap(repo,
+
	fd = pkg_repo_fetch_remote_extract_fd(repo,
		repo->meta->manifests, &local_t, &rc, &len);
-
	if (map == NULL || map == MAP_FAILED)
+
	if (fd == -1)
		goto cleanup;
+
	f = fdopen(fd, "r");
+
	rewind(f);

	*mtime = local_t;
	/*fconflicts = repo_fetch_remote_extract_tmp(repo,
@@ -495,7 +499,7 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
			&rc, repo_conflicts_file);*/

	/* Load local repository data */
-
	snprintf(path, sizeof(path), "%s-pkgtemp", name);
+
	xasprintf(&path, "%s-pkgtemp", name);
	rename(name, path);
	pkg_register_cleanup_callback(rollback_repo, (void *)name);
	rc = pkg_repo_binary_init_update(repo, name);
@@ -522,22 +526,17 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
		goto cleanup;

	in_trans = true;
-

-
	walk = map;
-
	unsigned char *next;
-

-
	while (walk -map < len) {
+
	while ((linelen = getline(&line, &linecap, f)) > 0) {
		cnt++;
-
		next = strchr(walk, '\n');
+
		totallen += linelen;
		if ((cnt % 10 ) == 0)
-
			pkg_emit_progress_tick(next - map, len);
-
		rc = pkg_repo_binary_add_from_manifest(walk, sqlite, next - walk,
+
			pkg_emit_progress_tick(totallen, len);
+
		rc = pkg_repo_binary_add_from_manifest(line, sqlite, linelen,
		    &keys, &pkg, repo);
		if (rc != EPKG_OK) {
			pkg_emit_progress_tick(len, len);
			break;
		}
-
		walk = next + 1;
	}
	pkg_emit_progress_tick(len, len);

@@ -568,12 +567,16 @@ cleanup:
		unlink(name);
		rename(path, name);
	}
-
	unlink(path);
+
	if (path != NULL) {
+
		unlink(path);
+
		free(path);
+
	}
	pkg_unregister_cleanup_callback(rollback_repo, (void *)name);
	pkg_manifest_keys_free(keys);
	pkg_free(pkg);
-
	if (map != NULL && map != MAP_FAILED)
-
		munmap(map, len);
+
	free(line);
+
	if (f != NULL)
+
		fclose(f);

	return (rc);
}
modified libpkg/rsa.c
@@ -133,20 +133,13 @@ rsa_verify_cert_cb(int fd, void *ud)
}

int
-
rsa_verify_cert(const char *path, unsigned char *key, int keylen,
+
rsa_verify_cert(unsigned char *key, int keylen,
    unsigned char *sig, int siglen, int fd)
{
	int ret;
	bool need_close = false;
	struct rsa_verify_cbdata cbdata;

-
	if (fd == -1) {
-
		if ((fd = open(path, O_RDONLY)) == -1) {
-
			pkg_emit_errno("fopen", path);
-
			return (EPKG_FATAL);
-
		}
-
		need_close = true;
-
	}
	(void)lseek(fd, 0, SEEK_SET);

	cbdata.key = key;
@@ -201,8 +194,7 @@ rsa_verify_cb(int fd, void *ud)
}

int
-
rsa_verify(const char *path, const char *key, unsigned char *sig,
-
    unsigned int sig_len, int fd)
+
rsa_verify(const char *key, unsigned char *sig, unsigned int sig_len, int fd)
{
	int ret;
	bool need_close = false;
@@ -215,14 +207,6 @@ rsa_verify(const char *path, const char *key, unsigned char *sig,
		return (EPKG_FATAL);
	}

-
	if (fd == -1) {
-
		if ((fd = open(path, O_RDONLY)) == -1) {
-
			pkg_emit_errno("fopen", path);
-
			free(key_buf);
-
			return (EPKG_FATAL);
-
		}
-
		need_close = true;
-
	}
	(void)lseek(fd, 0, SEEK_SET);

	cbdata.key = key_buf;
modified libpkg/scripts.c
@@ -111,9 +111,9 @@ pkg_script_run(struct pkg * const pkg, pkg_script type)
		if (j == map[i].a || j == map[i].b) {
			utstring_clear(script_cmd);
			setenv("PKG_PREFIX", pkg->prefix, 1);
-
			if (pkg_rootdir == NULL)
-
				pkg_rootdir = "/";
-
			setenv("PKG_ROOTDIR", pkg_rootdir, 1);
+
			if (ctx.pkg_rootdir == NULL)
+
				ctx.pkg_rootdir = "/";
+
			setenv("PKG_ROOTDIR", ctx.pkg_rootdir, 1);
			debug = pkg_object_bool(pkg_config_get("DEBUG_SCRIPTS"));
			if (debug)
				utstring_printf(script_cmd, "set -x\n");
modified libpkg/ssh.c
@@ -59,7 +59,7 @@ pkg_sshserve(int fd)
	time_t mtime = 0;
	const char *errstr;
	int ffd;
-
	char buf[BUFSIZ];
+
	char buf[32768];
	char fpath[MAXPATHLEN];
	char rpath[MAXPATHLEN];
	const char *restricted = NULL;
modified libpkg/utils.c
@@ -51,7 +51,7 @@
#include "pkg.h"
#include "private/event.h"
#include "private/utils.h"
-
#include "private/xmalloc.h"
+
#include "xmalloc.h"

int
mkdirs(const char *_path)
added libpkg/xmalloc.h
@@ -0,0 +1,58 @@
+
#ifndef XMALLOC_H
+
#define XMALLOC_H
+

+
static inline void *xmalloc(size_t size)
+
{
+
	void *ptr = malloc(size);
+
	if (ptr == NULL)
+
		abort();
+
	return (ptr);
+
}
+

+
static inline void *xcalloc(size_t n, size_t size)
+
{
+
	void *ptr = calloc(n, size);
+
	if (ptr == NULL)
+
		abort();
+
	return (ptr);
+
}
+

+
static inline void *xrealloc(void *ptr, size_t size)
+
{
+
	ptr = realloc(ptr, size);
+
	if (ptr == NULL)
+
		abort();
+
	return (ptr);
+
}
+

+
static inline char *xstrdup(const char *str)
+
{
+
	char *s = strdup(str);
+
	if (s == NULL)
+
		abort();
+
	return (s);
+
}
+

+
static inline char *xstrndup(const char *str, size_t n)
+
{
+
	char *s = strndup(str, n);
+
	if (s == NULL)
+
		abort();
+
	return (s);
+
}
+

+
static inline int xasprintf(char **ret, const char *fmt, ...)
+
{
+
	va_list ap;
+
	int i;
+

+
	va_start(ap, fmt);
+
	i = vasprintf(ret, fmt, ap);
+
	va_end(ap);
+

+
	if (i < 0 || *ret == NULL)
+
		abort();
+

+
	return (i);
+
}
+
#endif
modified scripts/Makefile.am
@@ -4,7 +4,6 @@ pweeklydir= ${sysconfdir}/periodic/weekly
bashcompdir=		${sysconfdir}/bash_completion.d
zshcompdir=		${prefix}/share/zsh/site-functions

-
dist_sbin_SCRIPTS=	sbin/pkg2ng
dist_pdaily_SCRIPTS=	periodic/411.pkg-backup \
			periodic/490.status-pkg-changes
dist_psecurity_SCRIPTS=	periodic/410.pkg-audit \
modified scripts/completion/_pkg.bash.in
@@ -125,16 +125,6 @@ _pkgng_clean () {
    large_info=""
}

-
_pkgng_convert () {
-
    local cur prev opts lopts
-
    COMPREPLY=()
-

-
    opts=()
-
    lopts=()
-
    small_info="Convert database from/to pkgng"
-
    large_info=""
-
}
-

_pkgng_create () {
    local cur prev opts lopts
    COMPREPLY=()
modified scripts/completion/_pkg.in
@@ -104,7 +104,6 @@ _pkg() {
		'check[check for missing dependencies and database consistency]'
		'clean[clean old packages from the cache]'
		'config[display value of a configuration option]'
-
		'convert[convert database from/to pkgng]'
		'create[create software package distributions]'
		'delete[delete packages from the database and the system]'
		'fetch[fetch packages from a remote repository]'
@@ -232,12 +231,6 @@ _pkg() {
				'(-y --yes)'{-y,--yes}'[assume yes for confirmations]'
			return
			;;
-
		(convert)
-
			_arguments -s \
-
				'(-d --pkg-dbdir)'{-d,--pkg-dbdir}'[specify the location of the pkg_add(1) dbdir]: : _files -/' \
-
				'(-n --dry-run)'{-n,--dry-run}'[dry run mode]'
-
			return
-
			;;
		(create)
			_arguments -A '-*' -s \
				'(-q --quiet)'{-q,--quiet}'[force quiet output]' \
modified scripts/periodic/410.pkg-audit.in
@@ -55,8 +55,12 @@ audit_pkgs() {
	if [ $rc -ne 0 -o \
		$(( 86400 \* "${daily_status_security_pkgaudit_expiry:-2}" )) \
		-le $(( ${now} - ${then} + 600 )) ]; then
-
		# Random delay so the mirrors do not get slammed when run by periodic(8)
-
		if [ ! -t 0 ]; then
+
		# When non-interactive, sleep to reduce congestion on mirrors
+
		if [ -n "$anticongestion_sleeptime" ]; then
+
			# In FreeBSD 12.0 the anticongestion function should be
+
			# used instead of a hard-coded sleep
+
			anticongestion
+
		else
			sleep `jot -r 1 0 3600`
		fi
		${pkgcmd} ${pkgargs} audit -F $q || { rc=$?; [ $rc -lt 3 ] && rc=3; }
deleted scripts/sbin/pkg2ng.in
@@ -1,133 +0,0 @@
-
#!/bin/sh
-

-
: "${PORTSDIR:=/usr/ports}"
-
: "${PKG_DBDIR:=/var/db/pkg}"
-

-
periodic_conf='/etc/periodic.conf'
-
periodic_defaults='/etc/defaults/periodic.conf'
-

-
args=$(getopt p $*)
-

-
while getopts p arg; do
-
    case ${arg} in
-
	p)
-
	    periodic_update="yes"
-
	    ;;
-
	?)
-
	    cat <<EOF
-
$(basename $0): Usage
-
    $(basename $0) [-p]
-

-
Options:
-
    -p   Update /etc/periodic.conf to disable scripts depending on
-
         pkg_tools and modify weekly_status_pkg_enable to use pkg(8)
-

-
EOF
-
	    exit 1
-
	    ;;
-
    esac
-
done
-
shift $(( ${OPTIND} -1 ))
-

-
if [ -f ${PORTSDIR}/Mk/bsd.pkgng.mk ]; then
-
	FORCE_POST=$(make _POSTMKINCLUDED=1 UID=$(id -u) -f ${PORTSDIR}/Mk/bsd.pkgng.mk -V _FORCE_POST_PATTERNS)
-
else
-
	FORCE_POST="rmdir kldxref mkfontscale mkfontdir fc-cache fonts.dir fonts.scale gtk-update-icon-cache gio-querymodules gtk-query-immodules ldconfig load-octave-pkg update-desktop-database update-mime-database gdk-pixbuf-query-loaders catalog.ports glib-compile-schemas ccache-update-links"
-
fi
-

-
FORCE_PORT=$FORCE_POST @prefix@/sbin/pkg convert
-

-
# Delete the portupgrade pkgdb to avoid discrepencies. It will be auto
-
# recreated.
-

-
rm -f ${PKG_DBDIR}/pkgdb.db > /dev/null 2>&1
-

-
# Build the shlibs_{provided,required} tables in the pkg database
-

-
echo "Analysing shared libraries, this will take a while... "
-
@prefix@/sbin/pkg check -Ba
-

-
# Fix up /etc/periodic.conf if requested.  Pull in the current
-
# periodic settings, and update /etc/periodic.conf to disable any
-
# active periodic scripts that depend on pkg_tools(8). Make a 1-to-1
-
# correspondance between existing pkg_tools periodic jobs, and pkgng
-
# periodic jobs, and enable the equivalent set.
-
#
-
# Update the 'pkg_version' variable used by weekly_status_pkg_enable
-
# if it still references pkg_version(1)
-

-
if [ "${periodic_update}" = "yes" ]; then
-
    if [ -r $period_defaults ]; then
-
	. $periodic_defaults
-
	source_periodic_confs
-
    fi
-

-
    TMPFILE=$(mktemp -t $(basename $0)) || exit 1
-
    cleanup() {
-
	rm -f $TMPFILE
-
    }
-
    trap cleanup EXIT HUP INT KILL
-

-
    if [ -f $periodic_conf ]; then
-
	cp -p $periodic_conf $TMPFILE
-
    fi
-

-
    exec >> ${TMPFILE}
-

-
    echo
-
    echo "### Added by $(basename $0) on $(date +%Y-%m-%d)"
-

-
    # weekly_status_pkg_enable -- use 'pkg version'.  This will use
-
    # the ports tree or the ports INDEX if they exist in preference to
-
    # the pkg repository catalogue.
-

-
    if [ "$pkg_version" = 'pkg_version' ]; then
-
	echo "pkg_version='@prefix@/sbin/pkg version'"
-
    fi
-

-
    # weekly/400.status-pkg
-
    echo "weekly_status_pkgng_enable=\"$weekly_status_pkg_enable\""
-
    case "$weekly_status_pkg_enable" in
-
	[Yy][Ee][Ss])
-
	    echo "weekly_status_pkg_enable=\"NO\""
-
	    ;;
-
    esac
-

-
    # daily/411.pkg-backup <=> daily/220.backup-pkgdb
-
    echo "daily_backup_pkgng_enable=\"$daily_backup_pkgdb_enable\""
-
    case "$daily_backup_pkgdb_enable" in
-
	[Yy][Ee][Ss])
-
	    echo "daily_backup_pkgdb_enable=\"NO\"" \
-
	    ;;
-
    esac
-

-
    # daily/490.status-pkg-changes
-
    echo "daily_status_pkgng_changes_enable=\"$daily_status_pkg_changes_enable\""
-
    case "$daily_status_pkg_changes_enable" in
-
	[Yy][Ee][Ss])
-
	    echo "daily_status_pkg_changes_enable=\"NO\"" \
-
	    ;;
-
    esac
-

-
    # security/410.pkg-audit <=> security/410.portaudit
-
    echo "daily_status_security_pkgaudit_enable=\"${daily_status_security_portaudit_enable:-YES}\""
-
    case "${daily_status_security_portaudit_enable:-YES}" in
-
	[Yy][Ee][Ss])
-
	    echo "daily_status_security_portaudit_enable=\"NO\""
-
	    ;;
-
    esac
-

-
    # security/460.pkg-checksum <=> security/460.chkportsum
-
    echo "daily_status_security_pkg_checksum_enable=\"$daily_status_security_chkportsum_enable\""
-
    case "$daily_status_security_chkportsum_enable" in
-
	[Yy][Ee][Ss])
-
	    echo "daily_status_security_chkportsum_enable=\"NO\""
-
	    ;;
-
    esac
-

-
    echo "### End of additions by $(basename $0)"
-

-
    cp -p $periodic_conf ${periodic_conf}.bak
-
    cp -p $TMPFILE $periodic_conf
-
fi
-

modified src/Makefile.am
@@ -14,7 +14,6 @@ pkg_SOURCES= add.c \
			check.c \
			clean.c \
			config.c \
-
			convert.c \
			create.c \
			delete.c \
			event.c \
modified src/clean.c
@@ -340,7 +340,7 @@ exec_clean(int argc, char **argv)
	cachefd = open(cachedir, O_DIRECTORY|O_CLOEXEC);
	if (cachefd == -1) {
		warn("Impossible to open %s", cachedir);
-
		return (EX_IOERR);
+
		return (errno == ENOENT ? EX_OK : EX_IOERR);
	}

	retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
deleted src/convert.c
@@ -1,159 +0,0 @@
-
/*-
-
 * Copyright (c) 2012-2013 Baptiste Daroussin <bapt@FreeBSD.org>
-
 * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org>
-
 * Copyright (c) 2014 Matthew Seaman <matthew@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
-
 *    in this position and unchanged.
-
 * 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(S) ``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(S) 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/param.h>
-
#include <sys/stat.h>
-

-
#include <err.h>
-
#include <errno.h>
-
#include <getopt.h>
-
#include <string.h>
-
#include <sysexits.h>
-
#include <dirent.h>
-
#include <unistd.h>
-

-
#include <pkg.h>
-

-
#include <bsd_compat.h>
-

-
#include "pkgcli.h"
-

-
void
-
usage_convert(void)
-
{
-
	fprintf(stderr, "Usage: pkg convert [-d dir] [-n]\n\n");
-
	fprintf(stderr, "For more information see 'pkg help convert'.\n");
-
}
-

-
static int
-
convert_from_old(const char *pkg_add_dbdir, bool dry_run)
-
{
-
	DIR		*d;
-
	struct dirent	*dp;
-
	struct pkg	*p = NULL;
-
	char		 path[MAXPATHLEN];
-
	struct pkgdb	*db = NULL;
-
	struct stat	 sb;
-
	int		lock_type = PKGDB_LOCK_EXCLUSIVE;
-
	int		ret;
-

-
	if (dry_run)
-
		ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
-
	else
-
		ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE|
-
		    PKGDB_MODE_CREATE, PKGDB_DB_LOCAL);
-

-
	if (ret == EPKG_ENOACCESS) {
-
		warnx("Insufficient privileges to convert packages");
-
		return (EX_NOPERM);
-
	} else if (ret != EPKG_OK && ret != EPKG_ENODB) {
-
		warnx("Error accessing the package database");
-
		return (EX_SOFTWARE);
-
	}
-

-
	if ((d = opendir(pkg_add_dbdir)) == NULL)
-
		err(EX_NOINPUT, "%s", pkg_add_dbdir);
-

-
	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
-
		closedir(d);
-
		return (EX_IOERR);
-
	}
-
	if (dry_run)
-
		lock_type = PKGDB_LOCK_READONLY;
-
	if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
-
		pkgdb_close(db);
-
		warnx("Cannot get an advisory lock on a database, it is locked"
-
		    " by another process");
-
		return (EX_TEMPFAIL);
-
	}
-
	while ((dp = readdir(d)) != NULL) {
-
		if (fstatat(dirfd(d), dp->d_name, &sb, 0) == 0 &&
-
		    S_ISDIR(sb.st_mode)) {
-
			if (strcmp(dp->d_name, ".") == 0 ||
-
			    strcmp(dp->d_name, "..") == 0)
-
				continue;
-
			pkg_free(p);
-
			if (pkg_new(&p, PKG_OLD_FILE) != EPKG_OK)
-
				err(EX_OSERR, "malloc");
-
			printf("Converting %s...\n", dp->d_name);
-
			snprintf(path, sizeof(path), "%s/%s", pkg_add_dbdir, dp->d_name);
-
			if (pkg_old_load_from_path(p, path) != EPKG_OK) {
-
				fprintf(stderr, "Skipping invalid package: %s\n", path);
-
				continue;
-
			}
-
			pkg_from_old(p);
-
			if (!dry_run)
-
				pkgdb_register_ports(db, p);
-
		}
-
	}
-

-
	pkg_free(p);
-
	pkgdb_release_lock(db, lock_type);
-
	pkgdb_close(db);
-
	closedir(d);
-
	return (EX_OK);
-
}
-

-
int
-
exec_convert(__unused int argc, __unused char **argv)
-
{
-
	int		 ch;
-
	bool		 dry_run = false;
-
	const char	*pkg_add_dbdir = "/var/db/pkg";
-

-
	struct option longopts[] = {
-
		{ "pkg-dbdir",	required_argument,	NULL,	'd' },
-
		{ "dry-run",	no_argument,		NULL,	'n' },
-
		{ NULL,		0,			NULL,	0   },
-
	};
-

-
	while ((ch = getopt_long(argc, argv, "+d:n", longopts, NULL)) != -1) {
-
		switch (ch) {
-
		case 'd':
-
			pkg_add_dbdir = optarg;
-
			break;
-
		case 'n':
-
			dry_run = true;
-
			break;
-
		default:
-
			usage_convert();
-
			return (EX_USAGE);
-
		}
-
	}
-
	argc -= optind;
-
	argv += optind;
-

-
	if (argc > 1) {
-
		usage_convert();
-
		return (EX_USAGE);
-
	}
-

-
	printf("Converting packages from %s\n", pkg_add_dbdir);
-

-
	return (convert_from_old(pkg_add_dbdir, dry_run));
-
}
modified src/event.c
@@ -477,10 +477,7 @@ draw_progressbar(int64_t current, int64_t total)

			humanize_number(buf, sizeof(buf),
			    current,"B", HN_AUTOSCALE, HN_IEC_PREFIXES);
-
			if (current < 1000)
-
				printf(" %*s  ", (int)sizeof(buf) - 2, buf);
-
			else
-
				printf(" %*s", (int)sizeof(buf), buf);
+
			printf(" %*s", (int)sizeof(buf), buf);

			if (bytes_left > 0)
				format_rate_SI(buf, sizeof(buf), transferred);
@@ -536,7 +533,6 @@ event_callback(void *data, struct pkg_event *ev)
	int *debug = data, i;
	struct pkg_event_conflict *cur_conflict;
	const char *filename, *reponame;
-
	char trunc_filename[42] = { 0 };

	if (msg_buf == NULL) {
		utstring_new(msg_buf);
@@ -596,13 +592,9 @@ event_callback(void *data, struct pkg_event *ev)
			 */
			filename = ev->e_fetching.url;
		}
-
		strncpy(trunc_filename, filename, 41);
-
		if (strnlen(filename,42) > 41)
-
			trunc_filename[40] = '*';
		job_status_begin(msg_buf);
		progress_debit = true;
-
		utstring_printf(msg_buf, "%-41s", trunc_filename);
-

+
		utstring_printf(msg_buf, "Fetching %s", filename);
		break;
	case PKG_EVENT_FETCH_FINISHED:
		progress_debit = false;
modified src/main.c
@@ -94,7 +94,6 @@ static struct commands {
	{ "check", "Checks for missing dependencies and database consistency", exec_check, usage_check},
	{ "clean", "Cleans old packages from the cache", exec_clean, usage_clean},
	{ "config", "Display the value of the configuration options", exec_config, usage_config},
-
	{ "convert", "Convert database from/to pkgng", exec_convert, usage_convert},
	{ "create", "Creates software package distributions", exec_create, usage_create},
	{ "delete", "Deletes packages from the database and the system", exec_delete, usage_delete},
	{ "fetch", "Fetches packages from a remote repository", exec_fetch, usage_fetch},
modified src/pkgcli.h
@@ -184,10 +184,6 @@ void usage_version(void);
int exec_which(int, char **);
void usage_which(void);

-
/* pkg convert */
-
int exec_convert(int, char **);
-
void usage_convert(void);
-

/* pkg ssh */
int exec_ssh(int, char **);
void usage_ssh(void);
modified src/repo.c
@@ -96,18 +96,16 @@ exec_repo(int argc, char **argv)
	bool	 filelist = false;
	char	*output_dir = NULL;
	char	*meta_file = NULL;
-
	bool	legacy = false;

	struct option longopts[] = {
		{ "list-files", no_argument,		NULL,	'l' },
		{ "output-dir", required_argument,	NULL,	'o' },
		{ "quiet",	no_argument,		NULL,	'q' },
		{ "meta-file",	required_argument,	NULL,	'm' },
-
		{ "legacy",	no_argument,	NULL,	'L' },
		{ NULL,		0,			NULL,	0   },
	};

-
	while ((ch = getopt_long(argc, argv, "+lo:qm:L", longopts, NULL)) != -1) {
+
	while ((ch = getopt_long(argc, argv, "+lo:qm:", longopts, NULL)) != -1) {
		switch (ch) {
		case 'l':
			filelist = true;
@@ -121,9 +119,6 @@ exec_repo(int argc, char **argv)
		case 'm':
			meta_file = optarg;
			break;
-
		case 'L':
-
			legacy = true;
-
			break;
		default:
			usage_repo();
			return (EX_USAGE);
@@ -145,7 +140,7 @@ exec_repo(int argc, char **argv)
	if (output_dir == NULL)
		output_dir = argv[0];

-
	ret = pkg_create_repo(argv[0], output_dir, filelist, meta_file, legacy);
+
	ret = pkg_create_repo(argv[0], output_dir, filelist, meta_file);

	if (ret != EPKG_OK) {
		printf("Cannot create repository catalogue\n");
modified src/which.c
@@ -32,13 +32,14 @@

#include <err.h>
#include <getopt.h>
-
#include <pkg.h>
#include <stdio.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <kvec.h>
+
#include <fnmatch.h>

+
#include <pkg.h>
#include "pkgcli.h"

typedef kvec_t(char *) charlist;
@@ -46,7 +47,7 @@ typedef kvec_t(char *) charlist;
void
usage_which(void)
{
-
	fprintf(stderr, "Usage: pkg which [-qgop] <file>\n\n");
+
	fprintf(stderr, "Usage: pkg which [-mqgop] <file>\n\n");
	fprintf(stderr, "For more information see 'pkg help which'.\n");
}

@@ -71,6 +72,7 @@ exec_which(int argc, char **argv)
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
+
	struct pkg_file *file = NULL;
	char		 pathabs[MAXPATHLEN];
	char		*p, *path, *match, *savedpath;
	int		 ret = EPKG_OK, retcode = EX_SOFTWARE;
@@ -80,6 +82,7 @@ exec_which(int argc, char **argv)
	bool		 glob = false;
	bool		 search = false;
	bool		 search_s = false;
+
	bool		 show_match = false;
	charlist	 patterns;

	struct option longopts[] = {
@@ -87,12 +90,13 @@ exec_which(int argc, char **argv)
		{ "origin",		no_argument,	NULL,	'o' },
		{ "path-search",	no_argument,	NULL,	'p' },
		{ "quiet",		no_argument,	NULL,	'q' },
+
                { "show-match",         no_argument,    NULL,   'm' },
		{ NULL,			0,		NULL,	0   },
	};

	path = NULL;

-
	while ((ch = getopt_long(argc, argv, "+gopq", longopts, NULL)) != -1) {
+
	while ((ch = getopt_long(argc, argv, "+gopqm", longopts, NULL)) != -1) {
		switch (ch) {
		case 'g':
			glob = true;
@@ -106,6 +110,9 @@ exec_which(int argc, char **argv)
		case 'q':
			quiet = true;
			break;
+
		case 'm':
+
			show_match = true;
+
			break;
		default:
			usage_which();
			return (EX_USAGE);
@@ -195,6 +202,7 @@ exec_which(int argc, char **argv)
				retcode = EX_USAGE;
				goto cleanup;
                        }
+
			kv_push(char *, patterns, strdup(pathabs));
		}


@@ -205,16 +213,28 @@ exec_which(int argc, char **argv)
			}

			pkg = NULL;
-
			while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
+
			while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_FILES)) == EPKG_OK) {
				retcode = EX_OK;
-
				if (quiet && orig)
+
				if (quiet && orig && !show_match)
					pkg_printf("%o\n", pkg);
-
				else if (quiet && !orig)
+
				else if (quiet && !orig && !show_match)
					pkg_printf("%n-%v\n", pkg, pkg);
-
				else if (!quiet && orig)
+
				else if (!quiet && orig && !show_match)
					pkg_printf("%S was installed by package %o\n", kv_A(patterns, i), pkg);
-
				else if (!quiet && !orig)
+
				else if (!quiet && !orig && !show_match)
					pkg_printf("%S was installed by package %n-%v\n", kv_A(patterns, i), pkg, pkg);
+
				else if (glob && show_match) {
+
					if (!quiet)
+
						pkg_printf("%S was glob searched and found in package %n-%v\n", kv_A(patterns, i), pkg, pkg, pkg);
+
					while(pkg_files(pkg, &file) == EPKG_OK) {
+
						pkg_asprintf(&match, "%Fn", file);
+
						if (match == NULL)
+
							err(EX_DATAERR, "pkg_asprintf");
+
						if(!fnmatch(kv_A(patterns, i), match, 0))
+
							printf("%s\n", match);
+
						free(match);
+
					}
+
				}
			}
			if (retcode != EX_OK && !quiet)
				printf("%s was not found in the database\n", kv_A(patterns, i));
modified tests/Makefile.am
@@ -109,7 +109,8 @@ tests_scripts= \
		frontend/issue1374.sh \
		frontend/issue1425.sh \
		frontend/issue1440.sh \
-
		frontend/issue1445.sh
+
		frontend/issue1445.sh \
+
		frontend/fingerprint.sh

check_SCRIPTS=	$(tests_scripts:.sh=)
CLEANFILES+=	$(check_SCRIPTS)
modified tests/frontend/Kyuafile.in
@@ -39,3 +39,4 @@ atf_test_program{name='issue1374'}
atf_test_program{name='issue1425'}
atf_test_program{name='issue1440'}
atf_test_program{name='issue1445'}
+
atf_test_program{name='fingerprint'}
modified tests/frontend/config.sh
@@ -2,20 +2,46 @@

. $(atf_get_srcdir)/test_environment.sh
tests_init \
-
	inline_repo \
	empty_conf \
+
	inline_repo \
	nameserver
+
	#duplicate_pkgs

-
inline_repo_body() {
-
	cat > pkgconfiguration << EOF
-
repositories: {
-
	pkg1: { url = file:///tmp },
-
	pkg2: { url = file:///tmp2 },
-
}
+
# This test is half finished to show problems with `pkg register'
+
duplicate_pkgs_body() {
+
	cat << EOF > pkg.conf
+
duplicatedefault: 2
EOF
-
	atf_check -o match:'^    url             : "file:///tmp",$' \
-
		-o match:'^    url             : "file:///tmp2",$' \
-
		pkg -o REPOS_DIR=/dev/null -C pkgconfiguration -vv
+

+
	for n in 1 2; do
+
		cat << EOF > test${n}.ucl
+
name: test
+
origin: test
+
version: ${n}
+
allowduplicate: true
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /
+
desc: <<EOD
+
Yet another test
+
EOD
+
EOF
+

+
	atf_check \
+
		-e empty \
+
		-o match:"Installing test-${n}..." \
+
		-s exit:0 \
+
		pkg register -M test${n}.ucl
+
done
+

+
	atf_check \
+
		-e empty \
+
		-o match:"test-1                         a test" \
+
		-o match:"test-2                         a test" \
+
		-s exit:0 \
+
		pkg info
}

empty_conf_body() {
@@ -48,6 +74,18 @@ EOF
		pkg -C pkg.conf info test
}

+
inline_repo_body() {
+
	cat > pkgconfiguration << EOF
+
repositories: {
+
	pkg1: { url = file:///tmp },
+
	pkg2: { url = file:///tmp2 },
+
}
+
EOF
+
	atf_check -o match:'^    url             : "file:///tmp",$' \
+
		-o match:'^    url             : "file:///tmp2",$' \
+
		pkg -o REPOS_DIR=/dev/null -C pkgconfiguration -vv
+
}
+

nameserver_body()
{
	atf_skip_on Darwin Not possible to inject a namserver on OSX
modified tests/frontend/conflicts-multirepo.sh
@@ -145,13 +145,13 @@ local2: {
EOF

OUTPUT="Updating local1 repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
local1 repository update completed. 2 packages processed.
Updating local2 repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
local2 repository update completed. 2 packages processed.
All repositories are up to date.
modified tests/frontend/conflicts.sh
@@ -68,8 +68,8 @@ local: {
EOF

OUTPUT="Updating local repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
local repository update completed. 1 packages processed.
All repositories are up to date.
modified tests/frontend/create.sh
@@ -231,7 +231,7 @@ create_from_plist_with_keyword_arguments_body() {

	atf_check \
		-o empty \
-
		-e inline:"${PROGNAME}: cannot parse keyword: cannot open file ./testkeyword.ucl: No such file or directory\n${PROGNAME}: unknown keyword testkeyword: @testkeyword\n" \
+
		-e inline:"${PROGNAME}: cannot load keyword from ./testkeyword.ucl: No such file or directory\n${PROGNAME}: unknown keyword testkeyword: @testkeyword\n" \
		-s exit:70 \
		pkg -o PLIST_KEYWORDS_DIR=. create -o ${TMPDIR} -m . -p test.plist -r .

added tests/frontend/fingerprint.sh
@@ -0,0 +1,68 @@
+
#! /usr/bin/env atf-sh
+

+
. $(atf_get_srcdir)/test_environment.sh
+

+
tests_init \
+
	fingerprint
+

+
fingerprint_body() {
+
	atf_check -o ignore -e ignore \
+
		openssl genrsa -out repo.key 2048
+
	rm -rf ${TMPDIR}/keys || :
+
	mkdir -p keys/trusted
+
	mkdir -p keys/revoked
+
	chmod 0400 repo.key
+
	atf_check -o ignore -e ignore \
+
		openssl rsa -in repo.key -out repo.pub -pubout
+
	echo "function: sha256" > keys/trusted/key
+
	echo -n "fingerprint: " >> keys/trusted/key
+
	openssl dgst -sha256 -hex repo.pub | sed 's/^.* //' >> keys/trusted/key
+
	echo "" >> keys/trusted/key
+
	mkdir fakerepo
+

+
	cat >> sign.sh << EOF
+
#!/bin/sh
+
read -t 2 sum
+
[ -z "\$sum" ] && exit 1
+
echo SIGNATURE
+
echo -n \$sum | /usr/bin/openssl dgst -sign repo.key -sha256 -binary
+
echo
+
echo CERT
+
cat repo.pub
+
echo END
+
EOF
+

+
	cat >> test.ucl << EOF
+
name: test
+
origin: test
+
version: "1"
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /
+
abi = "*";
+
desc: <<EOD
+
Yet another test
+
EOD
+
EOF
+

+
	atf_check -o ignore -e ignore \
+
		pkg create -M test.ucl -o fakerepo
+
	atf_check -o ignore \
+
		pkg repo fakerepo signing_command: sh sign.sh
+

+
	cat >> repo.conf << EOF
+
local: {
+
	url: file:///${TMPDIR}/fakerepo
+
	enabled: true
+
	signature_type: FINGERPRINTS
+
	fingerprints: ${TMPDIR}/keys
+
}
+
EOF
+
	atf_check \
+
		-o ignore \
+
		-e match:".*load error: access repo file.*" \
+
		pkg -dd -o REPOS_DIR="${TMPDIR}" \
+
		-o PKG_CACHEDIR="${TMPDIR}" update
+
}
added tests/frontend/formula.sh
@@ -0,0 +1,78 @@
+
#! /usr/bin/env atf-sh
+

+
. $(atf_get_srcdir)/test_environment.sh
+

+
tests_init \
+
	formula
+

+
formula_body() {
+
	cat << EOF >> repo.conf
+
local1: {
+
	url: file://${TMPDIR},
+
	enabled: true
+
}
+
EOF
+

+
	cat << EOF > a.ucl
+
name: a
+
origin: a
+
version: "1.0"
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /usr/local
+
desc: <<EOD
+
Yet another test
+
EOD
+
EOF
+

+
	cat << EOF > b.ucl
+
name: b
+
origin: b
+
version: "1.0"
+
maintainer: test
+
categories: [test]
+
comment: a test
+
www: http://test
+
prefix: /usr/local
+
desc: <<EOD
+
Yet another test
+
EOD
+
dep_formula: 'a >= 1',
+
EOF
+
	for p in a b; do
+
		atf_check \
+
		    -o ignore \
+
		    -e empty \
+
		    -s exit:0 \
+
		    pkg create -M ./${p}.ucl
+
	done
+

+
	atf_check \
+
	    -o ignore \
+
	    -e empty \
+
	    -s exit:0 \
+
	    pkg repo .
+

+
	OUTPUT="Updating local1 repository catalogue...
+
${JAILED}meta.txz                                 :  done
+
${JAILED}packagesite.txz                          :  done
+
Processing entries:  done
+
local1 repository update completed. 2 packages processed.
+
All repositories are up to date.
+
Checking integrity... done (0 conflicting)
+
The following 2 package(s) will be affected (of 0 checked):
+

+
New packages to be INSTALLED:
+
	b: 1.0
+
	a: 1.0
+

+
Number of packages to be installed: 2
+
"
+
	atf_check \
+
	    -o inline:"${OUTPUT}" \
+
	    -e match:".*load error: access repo file.*" \
+
	    -s exit:1 \
+
	    pkg -o REPOS_DIR="${TMPDIR}" install -n b
+
}
modified tests/frontend/issue1425.sh
@@ -151,13 +151,13 @@ EOF
                pkg repo -o ${TMPDIR}/repoB ${TMPDIR}/repoB

OUTPUT_CASE1="Updating repoA repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
repoA repository update completed. 4 packages processed.
Updating repoB repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
repoB repository update completed. 4 packages processed.
All repositories are up to date.
modified tests/frontend/issue1440.sh
@@ -186,13 +186,13 @@ EOF


OUTPUT_CASE1="Updating repoA repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
repoA repository update completed. 4 packages processed.
Updating repoB repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
repoB repository update completed. 4 packages processed.
All repositories are up to date.
modified tests/frontend/php-pr.sh
@@ -239,8 +239,8 @@ php53-gd-5.3.27
"

OUTPUT="Updating local repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
local repository update completed. 4 packages processed.
All repositories are up to date.
modified tests/frontend/requires.sh
@@ -57,8 +57,8 @@ EOF
	    pkg repo .

	OUTPUT="Updating local1 repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
local1 repository update completed. 2 packages processed.
All repositories are up to date.
modified tests/frontend/rubypuppet.sh
@@ -325,8 +325,8 @@ local: {
EOF

	OUTPUT="Updating local repository catalogue...
-
${JAILED}meta.txz                                 :  done
-
${JAILED}packagesite.txz                          :  done
+
${JAILED}Fetching meta.txz:  done
+
${JAILED}Fetching packagesite.txz:  done
Processing entries:  done
local repository update completed. 5 packages processed.
All repositories are up to date.