1
0
forked from mirrors/pacman

Compare commits

...

64 Commits

Author SHA1 Message Date
Allan McRae
56c3b396df Restrict use of DownloadUser to during download
This removes the requirement for the DownloadUser to own DBPath/sync and
CacheDir.  Instead, files to be downloaded to are touched before switching
user, and then moved into place at the end of downloading.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 18:35:06 +10:00
Remi Gacogne
4041870a43 Fixup: Return a proper error code when failing to sandbox the downloader 2024-02-08 17:04:25 +10:00
Remi Gacogne
cd585e94db Fixup: Fix the return value from curl_download_internal_sandboxed() 2024-02-08 17:04:25 +10:00
Andrew Gregory
3c9d5f8192 pactest: test database downloads with optional signatures
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Andrew Gregory
79783695e0 pactest: Add basic sandboxed download tests
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Remi Gacogne
7953c45e16 Stop trusting the Content-Disposition HTTP header 2024-02-08 17:04:25 +10:00
Allan McRae
044c13d825 Remove random_partfile from payload struct
It is not used any more due to filling the payload structure earlier.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Allan McRae
8f4f7a2524 libalpm: fill in more payload information before passing to downloader
Filling in more of the payload fields before passing to the downloader ensures
that the these fields do not get lost during sandboxed operations. It also
fixes the use of -U with XferCommand.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Remi Gacogne
6cbdc74f31 Document DownloadUser
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Remi Gacogne
95b7c5a613 Add sandboxed download for the internal downloader
If the SandboxUser configure option is set, the internal downloader
will fork of a child process and drop to the specified user to download
the files.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Allan McRae
f7ec77fa74 Expose _alpm_reset_signals() to library
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Remi Gacogne
76b57a16f0 Add callbacks for sandboxed operations
Add log and download callbacks to use within a sandbox.  These are
designed to be passed from the sandbox to the parent through a file
descriptor and then processed into alpm callbacks to be passed to the
frontend.

Note, only callbacks used in libalpm are added. Other callbacks should
be set to NULL in the child process.
2024-02-08 17:04:25 +10:00
Remi Gacogne
29a4a22c70 Provide function for switching user in child processes
Add alpm_sandbox_child() function that will be used for switching to a
less priviledged user to run child processes.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Remi Gacogne
e421e01326 Add DownloadUser configuration option
The DownloadUser option will be used to drop privledges to the
specified user when downloading files.

The intention is for this to be extended in the future  to a more
general sandbox configuration to cover operating on package and
database files prior to verification.

Add this option to pacman configuration and the various accessors into
the libalpm backend.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-08 17:04:25 +10:00
Allan McRae
56f1eeef4b Remove obsolete Doxyfile directives
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-06 20:03:08 +10:00
David Runge
f8c2e59ec5 pacman-key: Make signature verification more robust by checking pipes
To ensure we are not dropping the return code of the `gpg` call due to
piping into `grep`, we make use of `PIPESTATUS` to check the return code
of each command separately.

Additionally, we can now distinguish between two states: The signature
does not verify (e.g. due to technical reasons) and the signature is
not trusted.

Signed-off-by: David Runge <dvzrv@archlinux.org>
2024-02-04 10:06:43 +01:00
David Runge
16a064701a makepkg: Move check for signature metadata to central location
Move the check for the `NEWSIG` metadata keyword contained in the
GnuPG based statusfile to `parse_gpg_statusfile()` so that it is also
run when creating the statusfile in `verify_file_signature()` and not
only when running `verify_git_signature()`.

Signed-off-by: David Runge <dvzrv@archlinux.org>
2024-02-04 10:06:42 +01:00
David Runge
86ec26b2d3 makepkg: Improve robustness of signature verification by limiting terms
The output of
`gpg --quiet --batch --status-fd /dev/stdout --verify <signature_file> <file> 2> /dev/null`
or
`git verify-commit --raw <commit> 2>&1`
may contain binary data, if the signature has been created with an
OpenPGP implementation, that e.g. makes use of notations.
If the notation string (see `NOTATION_DATA` in /usr/share/doc/gnupg/
DETAILS) contains a trailing binary char, this will break signature
verification, as any following entry (e.g. `VALIDSIG`) will be offset.

As we are only making use of a narrow set of terms from the statusfile
(namely `NEWSIG`, `GOODSIG`, `EXPSIG`, `EXPKEYSIG`, `REVKEYSIG`,
`BADSIG`, `ERRSIG`, `VALIDSIG`, `TRUST_UNDEFINED`, `TRUST_NEVER`,
`TRUST_MARGINAL`, `TRUST_FULLY`, `TRUST_ULTIMATE`), we are applying a
filter, so that only understood terms are written to the file.

Signed-off-by: David Runge <dvzrv@archlinux.org>
2024-02-04 10:06:42 +01:00
David Runge
3aa096a74f makepkg: Emit early error if signature verification fails
Emit an early error message if tag or commit verification with git or
detached signature verification with gpg fails.
Make `verify_file_signature()` and `verify_git_signature()` return
non-zero in this case and set errors to `1`, so that later checks
in `check_pgpsigs()`, although still run, can not lead to a positive
result.

Signed-off-by: David Runge <dvzrv@archlinux.org>
2024-02-04 10:06:40 +01:00
morganamilo
bf76b5e89f libalpm: correctly log curl_download_internal return value
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 10:23:34 +10:00
Allan McRae
ce528a2654 libalpm/discspace.c: ensure mount points provide directories
In the very unlikely situtation where getmntent() and friends return
non-null, but the mount directory is NULL, a null dereference could
occur. It is unclear what the best course of action is in this case,
so just move on to the next mount point.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 09:02:36 +10:00
Allan McRae
f996f30163 libalpm/remove.c: prevent undefined behaviour in shift_pacsave error path
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 09:02:36 +10:00
Daniel M. Capella
2ba08e622b Update maintainers list
Signed-off-by: Daniel M. Capella <polyzen@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 08:58:33 +10:00
Allan McRae
4856fb53ac Add -Wunused_result to debug build compiler flags
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 08:53:44 +10:00
Allan McRae
a6b2524762 Ensure paths fit in PATH_MAX when cleaning cache
If a path length exceeds the PATH_MAX value, then it gets truncated
when building the path of the file to delete. This could (in a very
unlikely case...) result in the wrong file being deleted.  Check the
path fittedin the buffer before removing files.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 08:44:24 +10:00
Allan McRae
2079f6866a alpm_list_reverse: restore original list on failure
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 07:56:00 +10:00
Allan McRae
845dadf183 _cache_mtree_open: remove unused variable
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 07:56:00 +10:00
Allan McRae
dfee773364 clean_filename: use strdup instead of malloc and memcpy
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 07:56:00 +10:00
Allan McRae
c64f898c48 _alpm_pkg_load_internal: remove unneeded if statement
This statement is always true due to an earlier test.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 07:56:00 +10:00
Allan McRae
16a2a79728 libalpm/signing.c: prevent underflow in length_check
The length_check function could underflow if the provided buffer index
is greater than the signature buffer length, leading to an out of
bounds read.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 07:54:12 +10:00
Allan McRae
6711d10f96 pacman/conf.c: fix leak on error in setdefaults()
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-02-04 07:49:08 +10:00
Allan McRae
36fcff6e13 pacman/util.c: fix user after free in print_packages
Signed-off-by: Allan McRae <allan@archlinux.org>
2024-01-26 18:13:11 +10:00
Allan McRae
3c28c30133 Fix typo in exporting RUSTFLAGS
Fixes #77

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-01-14 08:50:29 +10:00
Ronan Pigott
4c93e63ddf add.c: drop newline in permission and ownership log messages
These are the only log messages produced by pacman that include an
embedded newline, and it looks very incongruous in a typical pacman.log.

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-01-10 08:52:35 +10:00
Allan McRae
f69d9b4475 makepkg: only check software once
Move the checks for software and gpg signing ability to after the
fakeroot section so that it is only executed once. This also fixes
gpg (lack of) interaction under fakeroot.

Fixes #69

Signed-off-by: Allan McRae <allan@archlinux.org>
2024-01-09 22:42:45 +00:00
Andrew Gregory
42fa74e91a free handle resources before running scripts
The primary purpose of this is to allow cleanup of file descriptors
allocated by curl that were left open in the child.  I am not aware of
any issues caused by the open file descriptors, but think it better to
not leave random open fd's lying around.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2024-01-09 22:39:14 +00:00
Andrew Gregory
929bad61c0 _alpm_handle_free: free all in-memory resources
Freeing handle resources was previously split awkwardly between
_alpm_handle_free and alpm_release.  This consolidates the freeing of
all in-memory resources to _alpm_handle_free, leaving alpm_release as a
thin wrapper that provides safety checks and frees any external
resources, e.g. removing lock files.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2024-01-09 22:39:14 +00:00
Morten Linderud
00d2b1f902 strip: don't create debug packages from .a files
.a files are not valid ELF files so we can't run objcopy nor debugedit
on them.

Rename STRIPLTO to STATICLIB to be more descriptive.

Signed-off-by: Morten Linderud <morten@linderud.pw>
2023-12-17 16:04:45 +01:00
Morten Linderud
7a4fff3310 strip: split off file stripping and debug package creation
Some projects might duplicate the file in multiple locations for one
reason or another. When debug packages are enabled, `makepkg` will only
strip the first occurrence of the binary and abort early on all the
other binaries.

Signed-off-by: Morten Linderud <morten@linderud.pw>
2023-12-17 16:04:45 +01:00
morganamilo
8d38746586 libalpm: fix check_pgp_signature docs
The function did have these return values a long time ago but now only
return 0 or -1.
2023-12-04 15:34:49 +00:00
Andrew Gregory
0df44c2e20 db.c: set pm_errno for server list modifications
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-12-02 04:56:25 +00:00
Andrew Gregory
dc91476555 pacman: add cache server support
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-12-02 04:56:25 +00:00
Andrew Gregory
bad3e13eaa conf.c: remove unnecessary _add_mirror function
It does very little, is only used in one place, and can't easily be
reused for other server types due to the inclusion of an error message.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-12-02 04:56:25 +00:00
Andrew Gregory
45e94e2dae pmtest: return pkg from addpkg2db
Allows more compact syntax:

p1 = self.addpkg2db('sync', pmpkg("foo"))

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-12-02 04:56:25 +00:00
Andrew Gregory
3aa1975c1d alpm: add cache server support
Cache servers differ from regular servers in that they do not produce
warnings and are not removed from the server pool for "soft errors"
(i.e. the server was reachable, but the download failed) and they are
not used for databases.  If a host is used for both a cache server and a
regular server, it may still be removed from the server pool for soft
errors that occur when used as cache server and removal from the server
pool for soft errors will not affect future attempted use as a cache
server.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-12-02 04:56:25 +00:00
Andrew Gregory
56626816b6 dload: differentiate between hard and soft errors
Set error count to -1 to indicate a hard error to allow them to be
treated differently.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-12-02 04:56:25 +00:00
Allan McRae
0f512ae46e Do not increment on every database error to avoid overflow
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-12-02 04:55:29 +00:00
Allan McRae
d56e9ed083 Increment error count on filelist conflicts in local database
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-12-02 04:55:29 +00:00
Andrew Gregory
2d190d5a33 meson.build: add _FILE_OFFSET_BITS to pkgconfig
Meson automatically sets _FILE_OFFSET_BITS but that value was not
getting carried through to the libalpm pkgconfig file, breaking
downstream projects that relied on it.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-11-25 13:05:00 -08:00
Andrew Gregory
2e23126e2a remove unused pkgconfig template
libalpm uses meson's pkgconfig module which does not use the template
file.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2023-11-25 13:04:56 -08:00
Levente Polyak
18e49f2c97 debugflags: ensure to only append debug flags once when building
During a package build we call prepare_buildenv in multiple stages of
the process. For debug packages, one of the hooks is buildenv_debugflags
which populates the debug flags to the according variables.

The issue is that the behavior of the current implementation of
buildenv_debugflags is not idempotent, so consecutive calls will append
the same flags again. In certain cases this isn't an issue, however
for context aware build frontends like cargo any change of the build
inputs leads to a fresh build. This means that any invocation of such
a build ecosystem inside the package() function will trigger a full
rebuild, which is not desired.

To fix this issue, this commit makes buildenv_debugflags idempotent
by only appending flags once to the target variables.

Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2023-11-17 18:56:44 +01:00
Patrick Northon
0108e2c64e Omit trailing .git from url when comparing git remote urls. 2023-11-04 10:09:59 +10:00
Diego Viola
94d9c2affe doc/PKGBUILD: fix typo
Signed-off-by: Diego Viola <diego.viola@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-11-04 00:03:23 +00:00
morganamilo
6e9ab43451 Document MAKEPKG_LIBRARY in makepkg(8) 2023-11-04 00:02:17 +00:00
morganamilo
9af4033cad Rename LIBRARY to MAKEPKG_LIBRARY
Implements #59.
2023-11-04 00:02:17 +00:00
Vekhir
31ffbc94ca Delete entire $srcdir upon clean build
Currently, the file glob used to clean the $srcdir misses dotfiles.

This commit instead removes the directory entirely and recreates it.
Since the directory has to exist prior to deletion, the creation commands
are duplicated. Perhaps they could be moved to a function later on.

The directory cannot be removed while inside it, so the directory change
is moved down the line. One important insight here is that almost all functions
after it are actually independent of $pwd, allowing the optimization of just
not changing directory. They do however depend on the existence of $srcdir, so
it has to be recreated.
The only exception to this is `extract_sources` which depends on $pwd being $srcdir.

An alternative proposal wanted to extend the file matching for deletion, but it
was deemed impractical.
2023-11-04 00:01:22 +00:00
Jack Rosenthal
e9b385a636 alpm: Don't chroot() to "/"
chroot() requires CAP_SYS_CHROOT.  If the caller has put us in the
right root directory already, don't call chroot().  This allows
running pacman in a containerized environment without CAP_SYS_CHROOT.
2023-10-23 12:13:10 +00:00
morganamilo
917b67f5d1 Fix -D in package()
When entering fakeroot makepkg calls itself with it's original args
causing it to cd again and error
2023-10-20 22:40:44 +01:00
Morten Linderud
331b277eea makepkg: Implement the verify function
This patch implements a new verify function in makepkg. It allows us to
do arbitrary authentication on sources before extraction.

There are several new signing and validation methods being implemented
and it would be hard to have `makepkg` implement support for things such
as sequoia, cosign or minisign. This would allow us to distribute
generic validation functions.

Signed-off-by: Morten Linderud <morten@linderud.pw>
2023-10-02 05:12:12 +00:00
Felix Yan
30f9a2e263 Correct typos in zsh_completion.in 2023-10-02 04:34:24 +00:00
morganamilo
aff12189d8 libalpm: check filecache_find return and log errors
Some user had erros while updating their system.

:: Proceed with installation? [Y/n]
:: Retrieving packages...
checking keyring...
checking package integrity...
error: failed to commit transaction (invalid or corrupted package)
Errors occurred, no packages were upgraded.

The issue was filecache_find returning null and alpm passing that null
path to check validity. How this happened I have no idea. It may be
something to do with the user's cachedir being a network drive.

Also warn when the file exists but it is not a regular file or can not
be opened.
2023-09-30 13:28:31 +00:00
Allan McRae
332d2a1922 repo-add: clarify exit messages
Clarify if repo-add does not create a new database due to failures
or due to there being nothing to do.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-30 23:27:04 +10:00
Ivan Shapovalov
f91fa546f6 repo-add: do not recreate the database if nothing was changed
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-30 23:18:41 +10:00
morganamilo
b4f11d5496 alpm: test access of symlinks not where they point
On platforms that have AT_SYMLINK_NOFOLLOW

Fixes FS#69720
2023-09-26 03:37:49 +00:00
141 changed files with 1628 additions and 699 deletions

View File

@@ -3,4 +3,4 @@
# This script serves as a trampoline for running scripts which depend on
# libmakepkg with the libmakepkg within the build tree.
LIBRARY=@BUILDDIR@/libmakepkg exec @BASH@ -$- @REAL_PROGPATH@ "$@"
MAKEPKG_LIBRARY=@BUILDDIR@/libmakepkg exec @BASH@ -$- @REAL_PROGPATH@ "$@"

View File

@@ -169,7 +169,6 @@ HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
@@ -239,7 +238,6 @@ USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output

View File

@@ -336,6 +336,13 @@ function.
the optional functions listed below. The packaging stage is run using
fakeroot to ensure correct file permissions in the resulting package.
All other functions will be run as the user calling makepkg.
This function is run inside `$srcdir`.
*verify() Function*::
An optional `verify()` function can be specified to implement arbitrary
source authentication. The function should return a non-zero exit code when
verification fails. This function is run before sources are extracted.
This function is run inside `$startdir`.
*prepare() Function*::
An optional `prepare()` function can be specified in which operations to
@@ -343,16 +350,19 @@ function.
function is run after the source extraction and before the `build()`
function. The `prepare()` function is skipped when source extraction
is skipped.
This function is run inside `$srcdir`.
*build() Function*::
The optional `build()` function is used to compile and/or adjust the source
files in preparation to be installed by the `package()` function.
This function is run inside `$srcdir`.
*check() Function*::
An optional `check()` function can be specified in which a package's
test-suite may be run. This function is run between the `build()` and
`package()` functions. Be sure any exotic commands used are covered by the
`checkdepends` array.
This function is run inside `$srcdir`.
All of the above variables such as `$pkgname` and `$pkgver` are available for
use in the packaging functions. In addition, makepkg defines the following
@@ -362,7 +372,6 @@ variables:
This contains the directory where makepkg extracts, or copies, all source
files.
+
All of the packaging functions defined above are run starting inside `$srcdir`
*pkgdir*::
This contains the directory where makepkg bundles the installed package.

View File

@@ -18,7 +18,6 @@ Current maintainers:
* Allan McRae <allan@archlinux.org>
* Andrew Gregory <andrew.gregory.8@gmail.com>
* Eli Schwartz <eschwartz@archlinux.org>
* Morgan Adamiec <morganamilo@archlinux.org>
Past major contributors:
@@ -30,6 +29,7 @@ Past major contributors:
* Xavier Chantry <shiningxc@gmail.com>
* Nagy Gabor <ngaba@bibl.u-szeged.hu>
* Dave Reisner <dreisner@archlinux.org>
* Eli Schwartz <eschwartz@archlinux.org>
For additional contributors, use `git shortlog -s` on the pacman.git
repository.

View File

@@ -171,6 +171,9 @@ Options
*\--noprepare*::
Do not run the prepare() function in the PKGBUILD.
*\--noverify*::
Do not run the verify() function in the PKGBUILD.
*\--sign*::
Sign the resulting package with gpg, overriding the setting in
linkman:makepkg.conf[5].
@@ -230,6 +233,9 @@ before building.
Environment Variables
---------------------
**MAKEPKG_LIBRARY**="/path/to/directory"::
Use an alternative libmakepkg path instead of the {libmakepkgdir} default.
**PACMAN**::
The command that will be used to check for missing dependencies and to
install and remove packages. Pacman's '-Qq', '-Rns', '-S', '-T', and '-U'

View File

@@ -35,6 +35,7 @@ asciidoc_opts = [
'-a', 'sysconfdir=@0@'.format(SYSCONFDIR),
'-a', 'datarootdir=@0@'.format(DATAROOTDIR),
'-a', 'rootdir=@0@'.format(ROOTDIR),
'-a', 'libmakepkgdir=@0@'.format(LIBMAKEPKGDIR),
]
html_targets = []

View File

@@ -207,6 +207,10 @@ Options
positive integer. If this config option is not set then only one download
stream is used (i.e. downloads happen sequentially).
*DownloadUser =* username::
Specifies the user to switch to for downloading files. If this config
option is not set then the downloads are done as the user running pacman.
Repository Sections
-------------------
@@ -240,6 +244,12 @@ number.
general configuration options. Wildcards in the specified paths will get
expanded based on linkman:glob[7] rules.
*CacheServer =* url::
A full URL to a location where the packages, and signatures (if
available) for this repository can be found. Cache servers will be tried
before any non-cache servers, will not be removed from the server pool for
404 download errors, and will not be used for database files.
*Server =* url::
A full URL to a location where the database, packages, and signatures (if
available) for this repository can be found.

View File

@@ -262,7 +262,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
"filesystem: %o package: %o\n"), filename, lsbuf.st_mode & mask,
entrymode & mask);
alpm_logaction(handle, ALPM_CALLER_PREFIX,
"warning: directory permissions differ on %s\n"
"warning: directory permissions differ on %s, "
"filesystem: %o package: %o\n", filename, lsbuf.st_mode & mask,
entrymode & mask);
}
@@ -277,7 +277,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
"filesystem: %u:%u package: %u:%u\n"), filename,
lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
alpm_logaction(handle, ALPM_CALLER_PREFIX,
"warning: directory ownership differs on %s\n"
"warning: directory ownership differs on %s, "
"filesystem: %u:%u package: %u:%u\n", filename,
lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
}

View File

@@ -93,34 +93,16 @@ cleanup:
return NULL;
}
/* check current state and free all resources including storage locks */
int SYMEXPORT alpm_release(alpm_handle_t *myhandle)
{
int ret = 0;
alpm_db_t *db;
CHECK_HANDLE(myhandle, return -1);
/* close local database */
db = myhandle->db_local;
if(db) {
db->ops->unregister(db);
myhandle->db_local = NULL;
}
if(alpm_unregister_all_syncdbs(myhandle) == -1) {
ret = -1;
}
#ifdef HAVE_LIBCURL
curl_multi_cleanup(myhandle->curlm);
curl_global_cleanup();
FREELIST(myhandle->server_errors);
#endif
ASSERT(myhandle->trans == NULL, RET_ERR(myhandle, ALPM_ERR_TRANS_NOT_NULL, -1));
_alpm_handle_unlock(myhandle);
_alpm_handle_free(myhandle);
return ret;
return 0;
}
const char SYMEXPORT *alpm_version(void)

View File

@@ -488,7 +488,7 @@ typedef struct _alpm_siglist_t {
* Check the PGP signature for the given package file.
* @param pkg the package to check
* @param siglist a pointer to storage for signature results
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
* @return 0 if valid, -1 if an error occurred or signature is invalid
*/
int alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg, alpm_siglist_t *siglist);
@@ -496,7 +496,7 @@ int alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg, alpm_siglist_t *siglist);
* Check the PGP signature for the given database.
* @param db the database to check
* @param siglist a pointer to storage for signature results
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
* @return 0 if valid, -1 if an error occurred or signature is invalid
*/
int alpm_db_check_pgp_signature(alpm_db_t *db, alpm_siglist_t *siglist);
@@ -1343,6 +1343,34 @@ int alpm_db_add_server(alpm_db_t *db, const char *url);
*/
int alpm_db_remove_server(alpm_db_t *db, const char *url);
/** Get the list of cache servers assigned to this db.
* @param db pointer to the database to get the servers from
* @return a char* list of servers
*/
alpm_list_t *alpm_db_get_cache_servers(const alpm_db_t *db);
/** Sets the list of cache servers for the database to use.
* @param db the database to set the servers. The list will be duped and
* the original will still need to be freed by the caller.
* @param servers a char* list of servers.
*/
int alpm_db_set_cache_servers(alpm_db_t *db, alpm_list_t *servers);
/** Add a download cache server to a database.
* @param db database pointer
* @param url url of the server
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
int alpm_db_add_cache_server(alpm_db_t *db, const char *url);
/** Remove a download cache server from a database.
* @param db database pointer
* @param url url of the server
* @return 0 on success, 1 on server not present,
* -1 on error (pm_errno is set accordingly)
*/
int alpm_db_remove_cache_server(alpm_db_t *db, const char *url);
/* End of server accessors */
/** @} */
@@ -1842,6 +1870,28 @@ int alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir);
/** @} */
/** @name Accessors for use sandboxuser
*
* This controls the user that libalpm will use for sensitive operations like
* downloading files.
* @{
*/
/** Returns the user to switch to for sensitive operations.
* @return the user name
*/
const char *alpm_option_get_sandboxuser(alpm_handle_t *handle);
/** Sets the user to switch to for sensitive operations.
* @param handle the context handle
* @param sandboxuser the user to set
*/
int alpm_option_set_sandboxuser(alpm_handle_t *handle, const char *sandboxuser);
/* End of sandboxuser accessors */
/** @} */
/** @name Accessors for use syslog
*
* This controls whether libalpm will also use the syslog. Even if this option
@@ -2901,6 +2951,12 @@ const char *alpm_version(void);
* */
int alpm_capabilities(void);
/** Drop privileges by switching to a different user.
* @param sandboxuser the user to switch to
* @return 0 on success, -1 on failure
*/
int alpm_sandbox_setup_child(const char *sandboxuser);
/* End of libalpm_misc */
/** @} */

View File

@@ -417,6 +417,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
while(lp) {
if(alpm_list_append(&newlist, lp->data) == NULL) {
alpm_list_free(newlist);
list->prev = backup;
return NULL;
}
lp = lp->prev;

View File

@@ -250,7 +250,6 @@ static int _cache_changelog_close(const alpm_pkg_t UNUSED *pkg, void *fp)
*/
static struct archive *_cache_mtree_open(alpm_pkg_t *pkg)
{
int r;
struct archive *mtree;
alpm_db_t *db = alpm_pkg_get_db(pkg);
@@ -268,7 +267,7 @@ static struct archive *_cache_mtree_open(alpm_pkg_t *pkg)
_alpm_archive_read_support_filter_all(mtree);
archive_read_support_format_mtree(mtree);
if((r = _alpm_archive_read_open_file(mtree, mtfile, ALPM_BUFFER_SIZE))) {
if(_alpm_archive_read_open_file(mtree, mtfile, ALPM_BUFFER_SIZE)) {
_alpm_log(pkg->handle, ALPM_LOG_ERROR, _("error while reading file %s: %s\n"),
mtfile, archive_error_string(mtree));
_alpm_archive_read_free(mtree);

View File

@@ -683,9 +683,7 @@ pkg_invalid:
error:
_alpm_pkg_free(newpkg);
_alpm_archive_read_free(archive);
if(fd >= 0) {
close(fd);
}
close(fd);
return NULL;
}

View File

@@ -189,6 +189,18 @@ int SYMEXPORT alpm_db_update(alpm_handle_t *handle, alpm_list_t *dbs, int force)
MALLOC(payload->filepath, len,
FREE(payload); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(payload->filepath, len, "%s%s", db->treename, dbext);
STRDUP(payload->remote_name, payload->filepath,
_alpm_dload_payload_reset(payload); FREE(payload);
GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
payload->destfile_name = _alpm_get_fullpath(syncpath, payload->remote_name, "");
payload->tempfile_name = _alpm_get_fullpath(syncpath, payload->remote_name, ".part");
if(!payload->destfile_name || !payload->tempfile_name) {
_alpm_dload_payload_reset(payload);
FREE(payload);
GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup);
}
payload->handle = handle;
payload->force = dbforce;
payload->unlink_on_fail = 1;

View File

@@ -131,6 +131,26 @@ int SYMEXPORT alpm_db_unregister(alpm_db_t *db)
return 0;
}
alpm_list_t SYMEXPORT *alpm_db_get_cache_servers(const alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
return db->cache_servers;
}
int SYMEXPORT alpm_db_set_cache_servers(alpm_db_t *db, alpm_list_t *cache_servers)
{
alpm_list_t *i;
ASSERT(db != NULL, return -1);
FREELIST(db->cache_servers);
for(i = cache_servers; i; i = i->next) {
char *url = i->data;
if(alpm_db_add_cache_server(db, url) != 0) {
return -1;
}
}
return 0;
}
alpm_list_t SYMEXPORT *alpm_db_get_servers(const alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
@@ -164,6 +184,25 @@ static char *sanitize_url(const char *url)
return newurl;
}
int SYMEXPORT alpm_db_add_cache_server(alpm_db_t *db, const char *url)
{
char *newurl;
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
db->cache_servers = alpm_list_add(db->cache_servers, newurl);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding new cache server URL to database '%s': %s\n",
db->treename, newurl);
return 0;
}
int SYMEXPORT alpm_db_add_server(alpm_db_t *db, const char *url)
{
char *newurl;
@@ -174,9 +213,8 @@ int SYMEXPORT alpm_db_add_server(alpm_db_t *db, const char *url)
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
if(!newurl) {
return -1;
}
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
db->servers = alpm_list_add(db->servers, newurl);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding new server URL to database '%s': %s\n",
db->treename, newurl);
@@ -184,6 +222,32 @@ int SYMEXPORT alpm_db_add_server(alpm_db_t *db, const char *url)
return 0;
}
int SYMEXPORT alpm_db_remove_cache_server(alpm_db_t *db, const char *url)
{
char *newurl, *vdata = NULL;
int ret = 1;
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
db->cache_servers = alpm_list_remove_str(db->cache_servers, newurl, &vdata);
if(vdata) {
_alpm_log(db->handle, ALPM_LOG_DEBUG, "removed cache server URL from database '%s': %s\n",
db->treename, newurl);
free(vdata);
ret = 0;
}
free(newurl);
return ret;
}
int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
{
char *newurl, *vdata = NULL;
@@ -195,9 +259,7 @@ int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
if(!newurl) {
return -1;
}
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
db->servers = alpm_list_remove_str(db->servers, newurl, &vdata);
@@ -328,6 +390,7 @@ void _alpm_db_free(alpm_db_t *db)
/* cleanup pkgcache */
_alpm_db_free_pkgcache(db);
/* cleanup server list */
FREELIST(db->cache_servers);
FREELIST(db->servers);
FREE(db->_path);
FREE(db->treename);

View File

@@ -69,6 +69,7 @@ struct _alpm_db_t {
char *_path;
alpm_pkghash_t *pkgcache;
alpm_list_t *grpcache;
alpm_list_t *cache_servers;
alpm_list_t *servers;
const struct db_operations *ops;

View File

@@ -111,6 +111,10 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
while((mnt = getmntent(fp))) {
if(mnt->mnt_dir == NULL) {
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
STRDUP(mp->mount_dir, mnt->mnt_dir, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir_len = strlen(mp->mount_dir);
@@ -134,6 +138,10 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
while((ret = getmntent(fp, &mnt)) == 0) {
if(mnt->mnt_mountp == NULL) {
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
STRDUP(mp->mount_dir, mnt->mnt_mountp, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir_len = strlen(mp->mount_dir);
@@ -161,6 +169,10 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
for(; entries-- > 0; fsp++) {
if(fsp->f_mntonname == NULL) {
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
STRDUP(mp->mount_dir, fsp->f_mntonname, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir_len = strlen(mp->mount_dir);

View File

@@ -28,7 +28,9 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
#include <pwd.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> /* IPPROTO_TCP */
@@ -48,6 +50,145 @@
#include "log.h"
#include "util.h"
#include "handle.h"
#include "sandbox.h"
static const char *get_filename(const char *url)
{
char *filename = strrchr(url, '/');
if(filename != NULL) {
return filename + 1;
}
/* no slash found, it's a filename */
return url;
}
/* prefix to avoid possible future clash with getumask(3) */
static mode_t _getumask(void)
{
mode_t mask = umask(0);
umask(mask);
return mask;
}
static int touch_and_own_file(const char *filename, const char *user)
{
int fd;
struct passwd const *pw = NULL;
ASSERT(filename != NULL, return -1);
ASSERT(user != NULL, return -1);
ASSERT((fd = open(filename, O_CREAT | O_WRONLY, 0644)) != -1, return -1);
close(fd);
ASSERT((pw = getpwnam(user)) != NULL, return -1);
ASSERT(chown(filename, pw->pw_uid, pw->pw_gid) != -1, return -1);
return 0;
}
static int intialize_download_file(struct dload_payload *p)
{
int ret = 0;
ret = touch_and_own_file(p->tempfile_name, p->handle->sandboxuser);
if(ret == 0 && p->download_signature) {
int len = strlen(p->destfile_name) + strlen(".sig") + strlen(".part") + 1;
char * sig;
MALLOC(sig, len, FREE(sig); RET_ERR(p->handle, ALPM_ERR_MEMORY, -1));
snprintf(sig, len, "%s.sig.part", p->destfile_name);
ret = touch_and_own_file(sig, p->handle->sandboxuser);
free(sig);
}
return ret;
}
static int unlink_or_move(const char *file, const char* dest) {
struct stat st;
ASSERT(stat(file, &st) == 0, return -1);
if(st.st_size == 0) {
unlink(file);
} else {
ASSERT(chown(file, 0, 0) != -1, return -1);
if(rename(file, dest)) {
return -1;
}
}
return 0;
}
static int finalize_download_file(struct dload_payload *p)
{
int ret = 0;
ret = unlink_or_move(p->tempfile_name, p->destfile_name);
if(ret == -1) {
_alpm_log(p->handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
p->tempfile_name, p->destfile_name, strerror(errno));
return -1;
}
if(p->download_signature) {
char *sig_temp, *sig_dest;
int len = strlen(p->destfile_name) + strlen(".sig") + 1;
MALLOC(sig_dest, len, RET_ERR(p->handle, ALPM_ERR_MEMORY, -1));
snprintf(sig_dest, len, "%s.sig", p->destfile_name);
len = len + 5;
MALLOC(sig_temp, len, FREE(sig_dest); RET_ERR(p->handle, ALPM_ERR_MEMORY, -1));
snprintf(sig_temp, len, "%s.sig.part", p->destfile_name);
ret = unlink_or_move(sig_temp, sig_dest);
if(ret == -1) {
_alpm_log(p->handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
sig_temp, sig_dest, strerror(errno));
}
free(sig_dest);
free(sig_temp);
}
return ret;
}
static FILE *create_tempfile(struct dload_payload *payload, const char *localpath)
{
int fd;
FILE *fp;
char *randpath;
size_t len;
/* create a random filename, which is opened with O_EXCL */
len = strlen(localpath) + 14 + 1;
MALLOC(randpath, len, RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL));
snprintf(randpath, len, "%salpmtmp.XXXXXX", localpath);
if((fd = mkstemp(randpath)) == -1 ||
fchmod(fd, ~(_getumask()) & 0666) ||
!(fp = fdopen(fd, payload->tempfile_openmode))) {
unlink(randpath);
close(fd);
_alpm_log(payload->handle, ALPM_LOG_ERROR,
_("failed to create temporary file for download\n"));
free(randpath);
return NULL;
}
/* fp now points to our alpmtmp.XXXXXX */
free(payload->tempfile_name);
payload->tempfile_name = randpath;
free(payload->remote_name);
STRDUP(payload->remote_name, strrchr(randpath, '/') + 1,
fclose(fp); RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL));
return fp;
}
#ifdef HAVE_LIBCURL
@@ -55,16 +196,16 @@
#define HOSTNAME_SIZE 256
static int curl_add_payload(alpm_handle_t *handle, CURLM *curlm,
struct dload_payload *payload, const char *localpath);
struct dload_payload *payload);
static int curl_gethost(const char *url, char *buffer, size_t buf_len);
/* number of "soft" errors required to blacklist a server, set to 0 to disable
* server blacklisting */
const unsigned int server_error_limit = 3;
const int server_error_limit = 3;
struct server_error_count {
char server[HOSTNAME_SIZE];
unsigned int errors;
int errors;
};
static struct server_error_count *find_server_errors(alpm_handle_t *handle, const char *server)
@@ -94,22 +235,34 @@ static struct server_error_count *find_server_errors(alpm_handle_t *handle, cons
}
}
/* skip for hard errors or too many soft errors */
static int should_skip_server(alpm_handle_t *handle, const char *server)
{
struct server_error_count *h;
if(server_error_limit && (h = find_server_errors(handle, server)) ) {
return h->errors >= server_error_limit;
return h->errors < 0 || h->errors >= server_error_limit;
}
return 0;
}
static void server_increment_error(alpm_handle_t *handle, const char *server, int count)
/* only skip for hard errors */
static int should_skip_cache_server(alpm_handle_t *handle, const char *server)
{
struct server_error_count *h;
if(server_error_limit && (h = find_server_errors(handle, server)) ) {
return h->errors < 0;
}
return 0;
}
/* block normal servers after too many errors */
static void server_soft_error(alpm_handle_t *handle, const char *server)
{
struct server_error_count *h;
if(server_error_limit
&& (h = find_server_errors(handle, server))
&& !should_skip_server(handle, server) ) {
h->errors += count;
h->errors++;
if(should_skip_server(handle, server)) {
_alpm_log(handle, ALPM_LOG_WARNING,
@@ -119,37 +272,46 @@ static void server_increment_error(alpm_handle_t *handle, const char *server, in
}
}
static void server_soft_error(alpm_handle_t *handle, const char *server)
{
server_increment_error(handle, server, 1);
}
/* immediate block for both servers and cache servers */
static void server_hard_error(alpm_handle_t *handle, const char *server)
{
server_increment_error(handle, server, server_error_limit);
}
struct server_error_count *h;
if(server_error_limit && (h = find_server_errors(handle, server))) {
if(h->errors != -1) {
/* always set even if already skipped for soft errors
* to disable cache servers too */
h->errors = -1;
static const char *get_filename(const char *url)
{
char *filename = strrchr(url, '/');
if(filename != NULL) {
return filename + 1;
_alpm_log(handle, ALPM_LOG_WARNING,
_("fatal error from %s, skipping for the remainder of this transaction\n"),
h->server);
}
}
/* no slash found, it's a filename */
return url;
}
static char *get_fullpath(const char *path, const char *filename,
const char *suffix)
static const char *payload_next_server(struct dload_payload *payload)
{
char *filepath;
/* len = localpath len + filename len + suffix len + null */
size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1;
MALLOC(filepath, len, return NULL);
snprintf(filepath, len, "%s%s%s", path, filename, suffix);
return filepath;
while(payload->cache_servers
&& should_skip_cache_server(payload->handle, payload->cache_servers->data)) {
payload->cache_servers = payload->cache_servers->next;
}
if(payload->cache_servers) {
const char *server = payload->cache_servers->data;
payload->cache_servers = payload->cache_servers->next;
payload->request_errors_ok = 1;
return server;
}
while(payload->servers
&& should_skip_server(payload->handle, payload->servers->data)) {
payload->servers = payload->servers->next;
}
if(payload->servers) {
const char *server = payload->servers->data;
payload->servers = payload->servers->next;
payload->request_errors_ok = payload->errors_ok;
return server;
}
return NULL;
}
enum {
@@ -262,45 +424,12 @@ static int utimes_long(const char *path, long seconds)
return 0;
}
/* prefix to avoid possible future clash with getumask(3) */
static mode_t _getumask(void)
{
mode_t mask = umask(0);
umask(mask);
return mask;
}
static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *user)
{
size_t realsize = size * nmemb;
const char *fptr, *endptr = NULL;
const char * const cd_header = "Content-Disposition:";
const char * const fn_key = "filename=";
struct dload_payload *payload = (struct dload_payload *)user;
long respcode;
if(_alpm_raw_ncmp(cd_header, ptr, strlen(cd_header)) == 0) {
if((fptr = strstr(ptr, fn_key))) {
fptr += strlen(fn_key);
/* find the end of the field, which is either a semi-colon, or the end of
* the data. As per curl_easy_setopt(3), we cannot count on headers being
* null terminated, so we look for the closing \r\n */
endptr = fptr + strcspn(fptr, ";\r\n") - 1;
/* remove quotes */
if(*fptr == '"' && *endptr == '"') {
fptr++;
endptr--;
}
/* avoid information leakage with badly formed headers */
if(endptr > fptr) {
STRNDUP(payload->content_disp_name, fptr, endptr - fptr + 1,
RET_ERR(payload->handle, ALPM_ERR_MEMORY, realsize));
}
}
}
(void) ptr;
curl_easy_getinfo(payload->curl, CURLINFO_RESPONSE_CODE, &respcode);
if(payload->respcode != respcode) {
@@ -374,55 +503,19 @@ static void curl_set_handle_opts(CURL *curl, struct dload_payload *payload)
}
}
static FILE *create_tempfile(struct dload_payload *payload, const char *localpath)
{
int fd;
FILE *fp;
char *randpath;
size_t len;
/* create a random filename, which is opened with O_EXCL */
len = strlen(localpath) + 14 + 1;
MALLOC(randpath, len, RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL));
snprintf(randpath, len, "%salpmtmp.XXXXXX", localpath);
if((fd = mkstemp(randpath)) == -1 ||
fchmod(fd, ~(_getumask()) & 0666) ||
!(fp = fdopen(fd, payload->tempfile_openmode))) {
unlink(randpath);
close(fd);
_alpm_log(payload->handle, ALPM_LOG_ERROR,
_("failed to create temporary file for download\n"));
free(randpath);
return NULL;
}
/* fp now points to our alpmtmp.XXXXXX */
free(payload->tempfile_name);
payload->tempfile_name = randpath;
free(payload->remote_name);
STRDUP(payload->remote_name, strrchr(randpath, '/') + 1,
fclose(fp); RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL));
return fp;
}
/* Return 0 if retry was successful, -1 otherwise */
static int curl_retry_next_server(CURLM *curlm, CURL *curl, struct dload_payload *payload)
{
const char *server;
const char *server = NULL;
size_t len;
struct stat st;
alpm_handle_t *handle = payload->handle;
while(payload->servers && should_skip_server(handle, payload->servers->data)) {
payload->servers = payload->servers->next;
}
if(!payload->servers) {
if((server = payload_next_server(payload)) == NULL) {
_alpm_log(payload->handle, ALPM_LOG_DEBUG,
"%s: no more servers to retry\n", payload->remote_name);
return -1;
}
server = payload->servers->data;
payload->servers = payload->servers->next;
/* regenerate a new fileurl */
FREE(payload->fileurl);
@@ -433,7 +526,6 @@ static int curl_retry_next_server(CURLM *curlm, CURL *curl, struct dload_payload
"%s: retrying from %s\n",
payload->remote_name, payload->fileurl);
fflush(payload->localf);
if(payload->allow_resume && stat(payload->tempfile_name, &st) == 0) {
@@ -474,7 +566,7 @@ static int curl_retry_next_server(CURLM *curlm, CURL *curl, struct dload_payload
* Returns -2 if an error happened for an optional file
*/
static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CURLMsg *msg,
const char *localpath, int *active_downloads_num)
int *active_downloads_num)
{
struct dload_payload *payload = NULL;
CURL *curl = msg->easy_handle;
@@ -503,7 +595,7 @@ static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CUR
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: response code %ld\n",
payload->remote_name, payload->respcode);
if(payload->respcode >= 400) {
if(!payload->errors_ok) {
if(!payload->request_errors_ok) {
handle->pm_errno = ALPM_ERR_RETRIEVE;
/* non-translated message is same as libcurl */
snprintf(payload->error_buffer, sizeof(payload->error_buffer),
@@ -558,7 +650,7 @@ static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CUR
goto cleanup;
}
default:
if(!payload->errors_ok) {
if(!payload->request_errors_ok) {
handle->pm_errno = ALPM_ERR_LIBCURL;
_alpm_log(handle, ALPM_LOG_ERROR,
_("failed retrieving file '%s' from %s : %s\n"),
@@ -588,31 +680,6 @@ static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CUR
curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &timecond);
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
if(payload->trust_remote_name) {
if(payload->content_disp_name) {
/* content-disposition header has a better name for our file */
free(payload->destfile_name);
payload->destfile_name = get_fullpath(localpath,
get_filename(payload->content_disp_name), "");
} else {
const char *effective_filename = strrchr(effective_url, '/');
if(effective_filename && strlen(effective_filename) > 2) {
effective_filename++;
/* if destfile was never set, we wrote to a tempfile. even if destfile is
* set, we may have followed some redirects and the effective url may
* have a better suggestion as to what to name our file. in either case,
* refactor destfile to this newly derived name. */
if(!payload->destfile_name || strcmp(effective_filename,
strrchr(payload->destfile_name, '/') + 1) != 0) {
free(payload->destfile_name);
payload->destfile_name = get_fullpath(localpath, effective_filename, "");
}
}
}
}
/* Let's check if client requested downloading accompanion *.sig file */
if(!payload->signature && payload->download_signature && curlerr == CURLE_OK && payload->respcode < 400) {
struct dload_payload *sig = NULL;
@@ -644,22 +711,23 @@ static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CUR
MALLOC(sig->fileurl, len, FREE(sig); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(sig->fileurl, len, "%s.sig", url);
if(payload->trust_remote_name) {
/* In this case server might provide a new name for the main payload.
* Choose *.sig filename based on this new name.
*/
const char *final_file = get_filename(realname);
int remote_name_len = strlen(final_file) + 5;
MALLOC(sig->remote_name, remote_name_len, FREE(sig->fileurl); FREE(sig); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(sig->remote_name, remote_name_len, "%s.sig", final_file);
}
int remote_name_len = strlen(payload->remote_name) + 5;
MALLOC(sig->remote_name, remote_name_len, _alpm_dload_payload_reset(sig);
FREE(sig); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(sig->remote_name, remote_name_len, "%s.sig", payload->remote_name);
/* force the filename to be realname + ".sig" */
int destfile_name_len = strlen(realname) + 5;
MALLOC(sig->destfile_name, destfile_name_len, FREE(sig->remote_name);
FREE(sig->fileurl); FREE(sig); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
MALLOC(sig->destfile_name, destfile_name_len, _alpm_dload_payload_reset(sig);
FREE(sig); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(sig->destfile_name, destfile_name_len, "%s.sig", realname);
int tempfile_name_len = strlen(realname) + 10;
MALLOC(sig->tempfile_name, tempfile_name_len, _alpm_dload_payload_reset(sig);
FREE(sig); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(sig->tempfile_name, tempfile_name_len, "%s.sig.part", realname);
sig->signature = 1;
sig->handle = handle;
sig->force = payload->force;
@@ -668,7 +736,7 @@ static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CUR
/* set hard upper limit of 16KiB */
sig->max_size = 16 * 1024;
curl_add_payload(handle, curlm, sig, localpath);
curl_add_payload(handle, curlm, sig);
(*active_downloads_num)++;
}
@@ -707,7 +775,7 @@ cleanup:
}
if(ret == 0) {
if(payload->destfile_name) {
if(payload->destfile_name && handle->sandboxuser == NULL) {
if(rename(payload->tempfile_name, payload->destfile_name)) {
_alpm_log(handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
payload->tempfile_name, payload->destfile_name, strerror(errno));
@@ -751,7 +819,7 @@ cleanup:
* Returns -1 if am error happened while starting a new download
*/
static int curl_add_payload(alpm_handle_t *handle, CURLM *curlm,
struct dload_payload *payload, const char *localpath)
struct dload_payload *payload)
{
size_t len;
CURL *curl = NULL;
@@ -764,53 +832,24 @@ static int curl_add_payload(alpm_handle_t *handle, CURLM *curlm,
if(payload->fileurl) {
ASSERT(!payload->servers, GOTO_ERR(handle, ALPM_ERR_WRONG_ARGS, cleanup));
ASSERT(!payload->filepath, GOTO_ERR(handle, ALPM_ERR_WRONG_ARGS, cleanup));
payload->request_errors_ok = payload->errors_ok;
} else {
const char *server;
while(payload->servers && should_skip_server(handle, payload->servers->data)) {
payload->servers = payload->servers->next;
}
const char *server = payload_next_server(payload);
ASSERT(payload->servers, GOTO_ERR(handle, ALPM_ERR_SERVER_NONE, cleanup));
ASSERT(server, GOTO_ERR(handle, ALPM_ERR_SERVER_NONE, cleanup));
ASSERT(payload->filepath, GOTO_ERR(handle, ALPM_ERR_WRONG_ARGS, cleanup));
server = payload->servers->data;
payload->servers = payload->servers->next;
len = strlen(server) + strlen(payload->filepath) + 2;
MALLOC(payload->fileurl, len, GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(payload->fileurl, len, "%s/%s", server, payload->filepath);
}
payload->tempfile_openmode = "wb";
if(!payload->remote_name) {
STRDUP(payload->remote_name, get_filename(payload->fileurl),
GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
}
if(curl_gethost(payload->fileurl, hostname, sizeof(hostname)) != 0) {
_alpm_log(handle, ALPM_LOG_ERROR, _("url '%s' is invalid\n"), payload->fileurl);
GOTO_ERR(handle, ALPM_ERR_SERVER_BAD_URL, cleanup);
}
if(!payload->random_partfile && payload->remote_name && strlen(payload->remote_name) > 0) {
if(!payload->destfile_name) {
payload->destfile_name = get_fullpath(localpath, payload->remote_name, "");
}
payload->tempfile_name = get_fullpath(localpath, payload->remote_name, ".part");
if(!payload->destfile_name || !payload->tempfile_name) {
goto cleanup;
}
} else {
/* We want a random filename or the URL does not contain a filename, so download to a
* temporary location. We can not support resuming this kind of download; any partial
* transfers will be destroyed */
payload->unlink_on_fail = 1;
payload->localf = create_tempfile(payload, localpath);
if(payload->localf == NULL) {
goto cleanup;
}
}
curl_set_handle_opts(curl, payload);
if(payload->max_size == payload->initial_size && payload->max_size != 0) {
@@ -868,8 +907,7 @@ static int compare_dload_payload_sizes(const void *left_ptr, const void *right_p
* Returns 1 if no files were downloaded and all errors were non-fatal
*/
static int curl_download_internal(alpm_handle_t *handle,
alpm_list_t *payloads /* struct dload_payload */,
const char *localpath)
alpm_list_t *payloads /* struct dload_payload */)
{
int active_downloads_num = 0;
int err = 0;
@@ -887,7 +925,7 @@ static int curl_download_internal(alpm_handle_t *handle,
for(; active_downloads_num < max_streams && payloads; active_downloads_num++) {
struct dload_payload *payload = payloads->data;
if(curl_add_payload(handle, curlm, payload, localpath) == 0) {
if(curl_add_payload(handle, curlm, payload) == 0) {
payloads = payloads->next;
} else {
/* The payload failed to start. Do not start any new downloads.
@@ -918,7 +956,7 @@ static int curl_download_internal(alpm_handle_t *handle,
}
if(msg->msg == CURLMSG_DONE) {
int ret = curl_check_finished_download(handle, curlm, msg,
localpath, &active_downloads_num);
&active_downloads_num);
if(ret == -1) {
/* if current payload failed to download then stop adding new payloads but wait for the
* current ones
@@ -938,8 +976,177 @@ static int curl_download_internal(alpm_handle_t *handle,
return err ? -1 : updated ? 0 : 1;
}
/* Download the requested files by launching a process inside a sandbox.
* Returns -1 if an error happened for a required file
* Returns 0 if a payload was actually downloaded
* Returns 1 if no files were downloaded and all errors were non-fatal
*/
static int curl_download_internal_sandboxed(alpm_handle_t *handle,
alpm_list_t *payloads /* struct dload_payload */,
const char *localpath)
{
int pid, err = 0, ret = -1, callbacks_fd[2];
sigset_t oldblock;
struct sigaction sa_ign, oldint, oldquit;
_alpm_sandbox_callback_context callbacks_ctx;
sigemptyset(&sa_ign.sa_mask);
sa_ign.sa_handler = SIG_IGN;
sa_ign.sa_flags=0;
if(pipe(callbacks_fd) != 0) {
return -1;
}
sigaction(SIGINT, &sa_ign, &oldint);
sigaction(SIGQUIT, &sa_ign, &oldquit);
sigaddset(&sa_ign.sa_mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &sa_ign.sa_mask, &oldblock);
pid = fork();
if(pid == -1) {
/* fork failed, make sure errno is preserved after cleanup */
err = errno;
}
/* child */
if(pid == 0) {
close(callbacks_fd[0]);
fcntl(callbacks_fd[1], F_SETFD, FD_CLOEXEC);
callbacks_ctx.callback_pipe = callbacks_fd[1];
alpm_option_set_logcb(handle, _alpm_sandbox_cb_log, &callbacks_ctx);
alpm_option_set_dlcb(handle, _alpm_sandbox_cb_dl, &callbacks_ctx);
alpm_option_set_fetchcb(handle, NULL, NULL);
alpm_option_set_eventcb(handle, NULL, NULL);
alpm_option_set_questioncb(handle, NULL, NULL);
alpm_option_set_progresscb(handle, NULL, NULL);
/* restore default signal handling in the child */
_alpm_reset_signals();
/* cwd to the download directory */
ret = chdir(localpath);
if(ret != 0) {
handle->pm_errno = errno;
_alpm_log(handle, ALPM_LOG_ERROR, _("could not chdir to download directory %s\n"), localpath);
ret = -1;
} else {
ret = alpm_sandbox_setup_child(handle->sandboxuser);
if (ret != 0) {
_alpm_log(handle, ALPM_LOG_ERROR, _("switching to sandbox user '%s' failed!\n"), handle->sandboxuser);
_Exit(ret | 128);
}
ret = curl_download_internal(handle, payloads);
}
/* pass the result back to the parent */
if(ret == 0) {
/* a payload was actually downloaded */
_Exit(0);
}
else if(ret == 1) {
/* no files were downloaded and all errors were non-fatal */
_Exit(handle->pm_errno);
}
else {
/* an error happened for a required file */
_Exit(handle->pm_errno | 128);
}
}
/* parent */
close(callbacks_fd[1]);
if(pid != -1) {
bool had_error = false;
while(true) {
_alpm_sandbox_callback_t callback_type;
ssize_t got = read(callbacks_fd[0], &callback_type, sizeof(callback_type));
if(got < 0 || (size_t)got != sizeof(callback_type)) {
had_error = true;
break;
}
if(callback_type == ALPM_SANDBOX_CB_DOWNLOAD) {
if(!_alpm_sandbox_process_cb_download(handle, callbacks_fd[0])) {
had_error = true;
break;
}
}
else if(callback_type == ALPM_SANDBOX_CB_LOG) {
if(!_alpm_sandbox_process_cb_log(handle, callbacks_fd[0])) {
had_error = true;
break;
}
}
}
if(had_error) {
kill(pid, SIGTERM);
}
int wret;
while((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR);
if(wret > 0) {
if(!WIFEXITED(ret)) {
/* the child did not terminate normally */
ret = -1;
}
else {
ret = WEXITSTATUS(ret);
if(ret != 0) {
if(ret & 128) {
/* an error happened for a required file, or unexpected exit status */
handle->pm_errno = ret & ~128;
ret = -1;
}
else {
handle->pm_errno = ret;
ret = 1;
}
}
}
}
else {
/* waitpid failed */
err = errno;
}
}
close(callbacks_fd[0]);
sigaction(SIGINT, &oldint, NULL);
sigaction(SIGQUIT, &oldquit, NULL);
sigprocmask(SIG_SETMASK, &oldblock, NULL);
if(err) {
errno = err;
ret = -1;
}
return ret;
}
#endif
static int payload_download_fetchcb(struct dload_payload *payload,
const char *server, const char *localpath)
{
int ret;
char *fileurl;
alpm_handle_t *handle = payload->handle;
size_t len = strlen(server) + strlen(payload->filepath) + 2;
MALLOC(fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
snprintf(fileurl, len, "%s/%s", server, payload->filepath);
ret = handle->fetchcb(handle->fetchcb_ctx, fileurl, localpath, payload->force);
free(fileurl);
return ret;
}
/* Returns -1 if an error happened for a required file
* Returns 0 if a payload was actually downloaded
* Returns 1 if no files were downloaded and all errors were non-fatal
@@ -950,7 +1157,26 @@ int _alpm_download(alpm_handle_t *handle,
{
if(handle->fetchcb == NULL) {
#ifdef HAVE_LIBCURL
return curl_download_internal(handle, payloads, localpath);
if(handle->sandboxuser) {
int ret = 0;
alpm_list_t *i;
for(i = payloads; i; i = i->next) {
struct dload_payload *p = i->data;
intialize_download_file(p);
}
ret = curl_download_internal_sandboxed(handle, payloads, localpath);
for(i = payloads; i; i = i->next) {
struct dload_payload *p = i->data;
finalize_download_file(p);
}
return ret;
} else {
return curl_download_internal(handle, payloads);
}
#else
RET_ERR(handle, ALPM_ERR_EXTERNAL_DOWNLOAD, -1);
#endif
@@ -965,16 +1191,11 @@ int _alpm_download(alpm_handle_t *handle,
if(payload->fileurl) {
ret = handle->fetchcb(handle->fetchcb_ctx, payload->fileurl, localpath, payload->force);
} else {
for(s = payload->cache_servers; s && ret == -1; s = s->next) {
ret = payload_download_fetchcb(payload, s->data, localpath);
}
for(s = payload->servers; s && ret == -1; s = s->next) {
const char *server = s->data;
char *fileurl;
size_t len = strlen(server) + strlen(payload->filepath) + 2;
MALLOC(fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
snprintf(fileurl, len, "%s/%s", server, payload->filepath);
ret = handle->fetchcb(handle->fetchcb_ctx, fileurl, localpath, payload->force);
free(fileurl);
ret = payload_download_fetchcb(payload, s->data, localpath);
}
}
@@ -1034,16 +1255,34 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
CALLOC(payload, 1, sizeof(*payload), GOTO_ERR(handle, ALPM_ERR_MEMORY, err));
STRDUP(payload->fileurl, url, FREE(payload); GOTO_ERR(handle, ALPM_ERR_MEMORY, err));
STRDUP(payload->remote_name, get_filename(payload->fileurl),
GOTO_ERR(handle, ALPM_ERR_MEMORY, err));
c = strrchr(url, '/');
if(strstr(c, ".pkg")) {
if(payload->remote_name && strlen(payload->remote_name) > 0 && strstr(c, ".pkg")) {
/* we probably have a usable package filename to download to */
payload->destfile_name = _alpm_get_fullpath(cachedir, payload->remote_name, "");
payload->tempfile_name = _alpm_get_fullpath(cachedir, payload->remote_name, ".part");
payload->allow_resume = 1;
if(!payload->destfile_name || !payload->tempfile_name) {
goto err;
}
} else {
payload->random_partfile = 1;
/* The URL does not contain a filename, so download to a temporary location.
* We can not support resuming this kind of download; any partial transfers
* will be destroyed */
payload->unlink_on_fail = 1;
payload->tempfile_openmode = "wb";
payload->localf = create_tempfile(payload, cachedir);
if(payload->localf == NULL) {
goto err;
}
}
payload->handle = handle;
payload->trust_remote_name = 1;
payload->download_signature = (handle->siglevel & ALPM_SIG_PACKAGE);
payload->signature_optional = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL);
payloads = alpm_list_add(payloads, payload);
@@ -1104,7 +1343,6 @@ void _alpm_dload_payload_reset(struct dload_payload *payload)
FREE(payload->remote_name);
FREE(payload->tempfile_name);
FREE(payload->destfile_name);
FREE(payload->content_disp_name);
FREE(payload->fileurl);
FREE(payload->filepath);
*payload = (struct dload_payload){0};

View File

@@ -26,10 +26,12 @@
struct dload_payload {
alpm_handle_t *handle;
const char *tempfile_openmode;
/* name of the remote file */
char *remote_name;
/* temporary file name, to which the payload is downloaded */
char *tempfile_name;
/* name to which the downloaded file will be renamed */
char *destfile_name;
char *content_disp_name;
/* client has to provide either
* 1) fileurl - full URL to the file
* 2) pair of (servers, filepath), in this case ALPM iterates over the
@@ -37,6 +39,7 @@ struct dload_payload {
*/
char *fileurl;
char *filepath; /* download URL path */
alpm_list_t *cache_servers;
alpm_list_t *servers;
long respcode;
off_t initial_size;
@@ -44,18 +47,17 @@ struct dload_payload {
off_t prevprogress;
int force;
int allow_resume;
int random_partfile;
int errors_ok;
int unlink_on_fail;
int trust_remote_name;
int download_signature; /* specifies if an accompanion *.sig file need to be downloaded*/
int signature_optional; /* *.sig file is optional */
#ifdef HAVE_LIBCURL
CURL *curl;
char error_buffer[CURL_ERROR_SIZE];
FILE *localf; /* temp download file */
int signature; /* specifies if this payload is for a signature file */
int request_errors_ok; /* per-request errors-ok */
#endif
FILE *localf; /* temp download file */
};
void _alpm_dload_payload_reset(struct dload_payload *payload);

View File

@@ -48,12 +48,28 @@ alpm_handle_t *_alpm_handle_new(void)
return handle;
}
/* free all in-memory resources */
void _alpm_handle_free(alpm_handle_t *handle)
{
alpm_list_t *i;
alpm_db_t *db;
if(handle == NULL) {
return;
}
/* close local database */
if((db = handle->db_local)) {
db->ops->unregister(db);
}
/* unregister all sync dbs */
for(i = handle->dbs_sync; i; i = i->next) {
db = i->data;
db->ops->unregister(db);
}
alpm_list_free(handle->dbs_sync);
/* close logfile */
if(handle->logstream) {
fclose(handle->logstream);
@@ -68,6 +84,12 @@ void _alpm_handle_free(alpm_handle_t *handle)
FREELIST(handle->known_keys);
#endif
#ifdef HAVE_LIBCURL
curl_multi_cleanup(handle->curlm);
curl_global_cleanup();
FREELIST(handle->server_errors);
#endif
/* free memory */
_alpm_trans_free(handle->trans);
FREE(handle->root);
@@ -79,6 +101,7 @@ void _alpm_handle_free(alpm_handle_t *handle)
FREE(handle->lockfile);
FREELIST(handle->architectures);
FREE(handle->gpgdir);
FREE(handle->sandboxuser);
FREELIST(handle->noupgrade);
FREELIST(handle->noextract);
FREELIST(handle->ignorepkg);
@@ -270,6 +293,12 @@ const char SYMEXPORT *alpm_option_get_gpgdir(alpm_handle_t *handle)
return handle->gpgdir;
}
const char SYMEXPORT *alpm_option_get_sandboxuser(alpm_handle_t *handle)
{
CHECK_HANDLE(handle, return NULL);
return handle->sandboxuser;
}
int SYMEXPORT alpm_option_get_usesyslog(alpm_handle_t *handle)
{
CHECK_HANDLE(handle, return -1);
@@ -573,6 +602,19 @@ int SYMEXPORT alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir)
return 0;
}
int SYMEXPORT alpm_option_set_sandboxuser(alpm_handle_t *handle, const char *sandboxuser)
{
CHECK_HANDLE(handle, return -1);
if(handle->sandboxuser) {
FREE(handle->sandboxuser);
}
STRDUP(handle->sandboxuser, sandboxuser, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'sandboxuser' = %s\n", handle->sandboxuser);
return 0;
}
int SYMEXPORT alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog)
{
CHECK_HANDLE(handle, return -1);

View File

@@ -91,6 +91,7 @@ struct _alpm_handle_t {
char *logfile; /* Name of the log file */
char *lockfile; /* Name of the lock file */
char *gpgdir; /* Directory where GnuPG files are stored */
char *sandboxuser; /* User to switch to for sensitive operations */
alpm_list_t *cachedirs; /* Paths to pacman cache directories */
alpm_list_t *hookdirs; /* Paths to hook directories */
alpm_list_t *overwrite_files; /* Paths that may be overwritten */

View File

@@ -1,13 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libalpm
Description: Arch Linux package management library
URL: http://archlinux.org/pacman/
Version: @LIB_VERSION@
Requires.private: libarchive @pc_crypto@ @pc_libcurl@ @pc_gpgme@
Cflags: -I${includedir} @LFS_CFLAGS@
Libs: -L${libdir} -lalpm
Libs.private: @LIBS@ @pc_gpgme_libs@ @LIBINTL@

View File

@@ -24,6 +24,7 @@ libalpm_sources = files('''
pkghash.h pkghash.c
rawstr.c
remove.h remove.c
sandbox.h sandbox.c
signing.c signing.h
sync.h sync.c
trans.h trans.c

View File

@@ -420,7 +420,9 @@ static void shift_pacsave(alpm_handle_t *handle, const char *file)
cleanup:
free(dirname);
closedir(dir);
if(dir != NULL) {
closedir(dir);
}
}

224
lib/libalpm/sandbox.c Normal file
View File

@@ -0,0 +1,224 @@
/*
* sandbox.c
*
* Copyright (c) 2021-2022 Pacman Development Team <pacman-dev@lists.archlinux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include "alpm.h"
#include "log.h"
#include "sandbox.h"
#include "util.h"
int SYMEXPORT alpm_sandbox_setup_child(const char* sandboxuser)
{
struct passwd const *pw = NULL;
ASSERT(sandboxuser != NULL, return EINVAL);
ASSERT(getuid() == 0, return EPERM);
ASSERT((pw = getpwnam(sandboxuser)), return errno);
ASSERT(setgid(pw->pw_gid) == 0, return errno);
ASSERT(setgroups(0, NULL) == 0, return errno);
ASSERT(setuid(pw->pw_uid) == 0, return errno);
return 0;
}
static int should_retry(int errnum)
{
return errnum == EINTR;
}
static int read_from_pipe(int fd, void *buf, size_t count)
{
size_t nread = 0;
ASSERT(count > 0, return -1);
while(nread < count) {
ssize_t r = read(fd, (char *)buf + nread, count-nread);
if(r < 0) {
if(!should_retry(errno)) {
return -1;
}
continue;
}
if(r == 0) {
/* we hit EOF unexpectedly - bail */
return -1;
}
nread += r;
}
return 0;
}
static int write_to_pipe(int fd, const void *buf, size_t count)
{
size_t nwrite = 0;
ASSERT(count > 0, return -1);
while(nwrite < count) {
ssize_t r = write(fd, (char *)buf + nwrite, count-nwrite);
if(r < 0) {
if(!should_retry(errno)) {
return -1;
}
continue;
}
nwrite += r;
}
return 0;
}
void _alpm_sandbox_cb_log(void *ctx, alpm_loglevel_t level, const char *fmt, va_list args)
{
_alpm_sandbox_callback_t type = ALPM_SANDBOX_CB_LOG;
_alpm_sandbox_callback_context *context = ctx;
char *string = NULL;
int string_size = 0;
if(!context || context->callback_pipe == -1) {
return;
}
/* compute the required size, as allowed by POSIX.1-2001 and C99 */
/* first we need to copy the va_list as it will be consumed by the first call */
va_list copy;
va_copy(copy, args);
string_size = vsnprintf(NULL, 0, fmt, copy);
if(string_size <= 0) {
va_end(copy);
return;
}
MALLOC(string, string_size + 1, return);
string_size = vsnprintf(string, string_size + 1, fmt, args);
if(string_size > 0) {
write_to_pipe(context->callback_pipe, &type, sizeof(type));
write_to_pipe(context->callback_pipe, &level, sizeof(level));
write_to_pipe(context->callback_pipe, &string_size, sizeof(string_size));
write_to_pipe(context->callback_pipe, string, string_size);
}
va_end(copy);
FREE(string);
}
void _alpm_sandbox_cb_dl(void *ctx, const char *filename, alpm_download_event_type_t event, void *data)
{
_alpm_sandbox_callback_t type = ALPM_SANDBOX_CB_DOWNLOAD;
_alpm_sandbox_callback_context *context = ctx;
size_t filename_len;
if(!context || context->callback_pipe == -1) {
return;
}
ASSERT(filename != NULL, return);
ASSERT(event == ALPM_DOWNLOAD_INIT || event == ALPM_DOWNLOAD_PROGRESS || event == ALPM_DOWNLOAD_RETRY || event == ALPM_DOWNLOAD_COMPLETED, return);
filename_len = strlen(filename);
write_to_pipe(context->callback_pipe, &type, sizeof(type));
write_to_pipe(context->callback_pipe, &event, sizeof(event));
switch(event) {
case ALPM_DOWNLOAD_INIT:
write_to_pipe(context->callback_pipe, data, sizeof(alpm_download_event_init_t));
break;
case ALPM_DOWNLOAD_PROGRESS:
write_to_pipe(context->callback_pipe, data, sizeof(alpm_download_event_progress_t));
break;
case ALPM_DOWNLOAD_RETRY:
write_to_pipe(context->callback_pipe, data, sizeof(alpm_download_event_retry_t));
break;
case ALPM_DOWNLOAD_COMPLETED:
write_to_pipe(context->callback_pipe, data, sizeof(alpm_download_event_completed_t));
break;
}
write_to_pipe(context->callback_pipe, &filename_len, sizeof(filename_len));
write_to_pipe(context->callback_pipe, filename, filename_len);
}
bool _alpm_sandbox_process_cb_log(alpm_handle_t *handle, int callback_pipe) {
alpm_loglevel_t level;
char *string = NULL;
int string_size = 0;
ASSERT(read_from_pipe(callback_pipe, &level, sizeof(level)) != -1, return false);
ASSERT(read_from_pipe(callback_pipe, &string_size, sizeof(string_size)) != -1, return false);
MALLOC(string, string_size + 1, return false);
ASSERT(read_from_pipe(callback_pipe, string, string_size) != -1, FREE(string); return false);
string[string_size] = '\0';
_alpm_log(handle, level, "%s", string);
FREE(string);
return true;
}
bool _alpm_sandbox_process_cb_download(alpm_handle_t *handle, int callback_pipe) {
alpm_download_event_type_t type;
char *filename = NULL;
size_t filename_size, cb_data_size;
union {
alpm_download_event_init_t init;
alpm_download_event_progress_t progress;
alpm_download_event_retry_t retry;
alpm_download_event_completed_t completed;
} cb_data;
ASSERT(read_from_pipe(callback_pipe, &type, sizeof(type)) != -1, return false);
switch (type) {
case ALPM_DOWNLOAD_INIT:
cb_data_size = sizeof(alpm_download_event_init_t);
ASSERT(read_from_pipe(callback_pipe, &cb_data.init, cb_data_size) != -1, return false);
break;
case ALPM_DOWNLOAD_PROGRESS:
cb_data_size = sizeof(alpm_download_event_progress_t);
ASSERT(read_from_pipe(callback_pipe, &cb_data.progress, cb_data_size) != -1, return false);
break;
case ALPM_DOWNLOAD_RETRY:
cb_data_size = sizeof(alpm_download_event_retry_t);
ASSERT(read_from_pipe(callback_pipe, &cb_data.retry, cb_data_size) != -1, return false);
break;
case ALPM_DOWNLOAD_COMPLETED:
cb_data_size = sizeof(alpm_download_event_completed_t);
ASSERT(read_from_pipe(callback_pipe, &cb_data.completed, cb_data_size) != -1, return false);
break;
default:
return false;
}
ASSERT(read_from_pipe(callback_pipe, &filename_size, sizeof(filename_size)) != -1, return false);;
MALLOC(filename, filename_size + 1, return false);
ASSERT(read_from_pipe(callback_pipe, filename, filename_size) != -1, FREE(filename); return false);
filename[filename_size] = '\0';
handle->dlcb(handle->dlcb_ctx, filename, type, &cb_data);
FREE(filename);
return true;
}

51
lib/libalpm/sandbox.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* sandbox.h
*
* Copyright (c) 2021-2022 Pacman Development Team <pacman-dev@lists.archlinux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ALPM_SANDBOX_H
#define ALPM_SANDBOX_H
#include <stdbool.h>
/* The type of callbacks that can happen during a sandboxed operation */
typedef enum {
ALPM_SANDBOX_CB_LOG,
ALPM_SANDBOX_CB_DOWNLOAD
} _alpm_sandbox_callback_t;
typedef struct {
int callback_pipe;
} _alpm_sandbox_callback_context;
/* Sandbox callbacks */
__attribute__((format(printf, 3, 0)))
void _alpm_sandbox_cb_log(void *ctx, alpm_loglevel_t level, const char *fmt, va_list args);
void _alpm_sandbox_cb_dl(void *ctx, const char *filename, alpm_download_event_type_t event, void *data);
/* Functions to capture sandbox callbacks and convert them to alpm callbacks */
bool _alpm_sandbox_process_cb_log(alpm_handle_t *handle, int callback_pipe);
bool _alpm_sandbox_process_cb_download(alpm_handle_t *handle, int callback_pipe);
#endif /* ALPM_SANDBOX_H */

View File

@@ -1044,7 +1044,7 @@ int SYMEXPORT alpm_siglist_cleanup(alpm_siglist_t *siglist)
static size_t length_check(size_t length, size_t position, size_t a,
alpm_handle_t *handle, const char *identifier)
{
if( a == 0 || length - position <= a) {
if( a == 0 || position > length || length - position <= a) {
_alpm_log(handle, ALPM_LOG_ERROR,
_("%s: signature format error\n"), identifier);
return -1;

View File

@@ -767,6 +767,7 @@ static int find_dl_candidates(alpm_handle_t *handle, alpm_list_t **files)
return 0;
}
static int download_files(alpm_handle_t *handle)
{
const char *cachedir;
@@ -825,9 +826,17 @@ static int download_files(alpm_handle_t *handle)
CALLOC(payload, 1, sizeof(*payload), GOTO_ERR(handle, ALPM_ERR_MEMORY, finish));
STRDUP(payload->remote_name, pkg->filename, FREE(payload); GOTO_ERR(handle, ALPM_ERR_MEMORY, finish));
STRDUP(payload->filepath, pkg->filename,
FREE(payload->remote_name); FREE(payload);
_alpm_dload_payload_reset(payload); FREE(payload);
GOTO_ERR(handle, ALPM_ERR_MEMORY, finish));
payload->destfile_name = _alpm_get_fullpath(cachedir, payload->remote_name, "");
payload->tempfile_name = _alpm_get_fullpath(cachedir, payload->remote_name, ".part");
if(!payload->destfile_name || !payload->tempfile_name) {
_alpm_dload_payload_reset(payload);
FREE(payload);
GOTO_ERR(handle, ALPM_ERR_MEMORY, finish);
}
payload->max_size = pkg->size;
payload->cache_servers = pkg->origin_data.db->cache_servers;
payload->servers = pkg->origin_data.db->servers;
payload->handle = handle;
payload->allow_resume = 1;
@@ -995,6 +1004,13 @@ static int check_validity(alpm_handle_t *handle,
current_bytes += v.pkg->size;
v.path = _alpm_filecache_find(handle, v.pkg->filename);
if(!v.path) {
_alpm_log(handle, ALPM_LOG_ERROR,
_("%s: could not find package in cache\n"), v.pkg->name);
RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, -1);
}
v.siglevel = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg));
if(_alpm_pkg_validate_internal(handle, v.path, v.pkg,
@@ -1086,6 +1102,12 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
current_bytes += spkg->size;
filepath = _alpm_filecache_find(handle, spkg->filename);
if(!filepath) {
_alpm_log(handle, ALPM_LOG_ERROR,
_("%s: could not find package in cache\n"), spkg->name);
RET_ERR(handle, ALPM_ERR_PKG_NOT_FOUND, -1);
}
/* load the package file and replace pkgcache entry with it in the target list */
/* TODO: alpm_pkg_get_db() will not work on this target anymore */
_alpm_log(handle, ALPM_LOG_DEBUG,

View File

@@ -31,6 +31,7 @@
#include <limits.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <poll.h>
#include <signal.h>
@@ -196,6 +197,23 @@ cleanup:
return ret;
}
/** Combines a directory, filename and suffix to provide full path of a file
* @param path directory path
* @param filename file name
* @param suffix suffix
* @return file path
*/
char *_alpm_get_fullpath(const char *path, const char *filename, const char *suffix)
{
char *filepath;
/* len = localpath len + filename len + suffix len + null */
size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1;
MALLOC(filepath, len, return NULL);
snprintf(filepath, len, "%s%s%s", path, filename, suffix);
return filepath;
}
/** Trim trailing newlines from a string (if any exist).
* @param str a single line of text
* @param len size of str, if known, else 0
@@ -554,7 +572,7 @@ static int _alpm_chroot_read_from_child(alpm_handle_t *handle, int fd,
return 0;
}
static void _alpm_reset_signals(void)
void _alpm_reset_signals(void)
{
/* reset POSIX defined signals (see signal.h) */
/* there are likely more but there is no easy way
@@ -654,7 +672,9 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
}
/* use fprintf instead of _alpm_log to send output through the parent */
if(chroot(handle->root) != 0) {
/* don't chroot() to "/": this allows running with less caps when the
* caller puts us in the right root */
if(strcmp(handle->root, "/") != 0 && chroot(handle->root) != 0) {
fprintf(stderr, _("could not change the root directory (%s)\n"), strerror(errno));
exit(1);
}
@@ -672,6 +692,7 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
unsetenv("BASH_ENV");
umask(0022);
_alpm_reset_signals();
_alpm_handle_free(handle);
execv(cmd, argv);
/* execv only returns if there was an error */
fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno));
@@ -842,10 +863,17 @@ char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename)
for(i = handle->cachedirs; i; i = i->next) {
snprintf(path, PATH_MAX, "%s%s", (char *)i->data,
filename);
if(stat(path, &buf) == 0 && S_ISREG(buf.st_mode)) {
retpath = strdup(path);
_alpm_log(handle, ALPM_LOG_DEBUG, "found cached pkg: %s\n", retpath);
return retpath;
if(stat(path, &buf) == 0) {
if(S_ISREG(buf.st_mode)) {
retpath = strdup(path);
_alpm_log(handle, ALPM_LOG_DEBUG, "found cached pkg: %s\n", retpath);
return retpath;
} else {
_alpm_log(handle, ALPM_LOG_WARNING,
"cached pkg '%s' is not a regular file: mode=%i\n", path, buf.st_mode);
}
} else if(errno != ENOENT) {
_alpm_log(handle, ALPM_LOG_WARNING, "could not open '%s'\n: %s", path, strerror(errno));
}
}
/* package wasn't found in any cachedir */
@@ -1352,6 +1380,11 @@ int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int a
size_t len = 0;
int ret = 0;
int flag = 0;
#ifdef AT_SYMLINK_NOFOLLOW
flag |= AT_SYMLINK_NOFOLLOW;
#endif
if(dir) {
char *check_path;
@@ -1359,11 +1392,11 @@ int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int a
CALLOC(check_path, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
snprintf(check_path, len, "%s%s", dir, file);
ret = access(check_path, amode);
ret = faccessat(AT_FDCWD, check_path, amode, flag);
free(check_path);
} else {
dir = "";
ret = access(file, amode);
ret = faccessat(AT_FDCWD, file, amode, flag);
}
if(ret != 0) {

View File

@@ -116,6 +116,7 @@ struct archive_read_buffer {
int _alpm_makepath(const char *path);
int _alpm_makepath_mode(const char *path, mode_t mode);
int _alpm_copyfile(const char *src, const char *dest);
char *_alpm_get_fullpath(const char *path, const char *filename, const char *suffix);
size_t _alpm_strip_newline(char *str, size_t len);
int _alpm_open_archive(alpm_handle_t *handle, const char *path,
@@ -129,6 +130,7 @@ ssize_t _alpm_files_in_directory(alpm_handle_t *handle, const char *path, int fu
typedef ssize_t (*_alpm_cb_io)(void *buf, ssize_t len, void *ctx);
void _alpm_reset_signals(void);
int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
_alpm_cb_io in_cb, void *in_ctx);
int _alpm_ldconfig(alpm_handle_t *handle);

View File

@@ -233,6 +233,7 @@ if get_option('debug')
'-Wuninitialized',
'-Wunused-but-set-parameter',
'-Wunused-parameter',
'-Wunused-result',
'-Wwrite-strings',
]
add_project_arguments(cc.get_supported_arguments(extra_cflags), language : 'c')
@@ -359,7 +360,9 @@ pkgconfig.generate(
name : 'libalpm',
description : 'Arch Linux package management library',
version : libalpm_version,
url : 'http://archlinux.org/pacman/')
url : 'http://archlinux.org/pacman/',
extra_cflags: [ '-D_FILE_OFFSET_BITS=64' ],
)
pacman_bin = executable(
'pacman',

View File

@@ -553,7 +553,7 @@ _pacman_conf_directive() {
_pacman_conf_commands=(
{-l,--repo-list}'[List configured repositories]:*: :->repo_list'
{-h,--help}'[Output systax and command line options]:*: :->complete'
{-h,--help}'[Output syntax and command line options]:*: :->complete'
{-V,--version}'[Display version and exit]:*: :->complete'
)
@@ -564,7 +564,7 @@ _pacman_conf_options=(
_pacman_conf_options_common=(
'*'{-c,--config=}'[Specify an alternate configuration file]: :_files'
'*'{-R,--rootdir=}'[Specify an alternate insallation root]: :_files'
'*'{-R,--rootdir=}'[Specify an alternate installation root]: :_files'
)
_pacman_conf() {

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_AUTODEP_SH" ]] && return
LIBMAKEPKG_AUTODEP_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
declare -a autodep_functions
for lib in "$LIBRARY/autodep/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/autodep/"*.sh; do
source "$lib"
done

View File

@@ -21,7 +21,7 @@
[[ -n "$LIBMAKEPKG_AUTODEP_LIBRARY_DEPENDS_SH" ]] && return
LIBMAKEPKG_AUTODEP_LIBRARY_DEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
autodep_functions+=('library_depends')

View File

@@ -21,7 +21,7 @@
[[ -n "$LIBMAKEPKG_AUTODEP_LIBRARY_PROVIDES_SH" ]] && return
LIBMAKEPKG_AUTODEP_LIBRARY_PROVIDES_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
autodep_functions+=('library_provides')

View File

@@ -22,12 +22,12 @@
[[ -n "$LIBMAKEPKG_BUILDENV_SH" ]] && return
LIBMAKEPKG_BUILDENV_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
declare -a buildenv_functions build_options
buildenv_vars=('CPPFLAGS' 'CFLAGS' 'CXXFLAGS' 'LDFLAGS' 'MAKEFLAGS' 'CHOST')
for lib in "$LIBRARY/buildenv/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/buildenv/"*.sh; do
source "$lib"
done

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_BUILDENV_BUILDFLAGS_SH" ]] && return
LIBMAKEPKG_BUILDENV_BUILDFLAGS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
build_options+=('buildflags')

View File

@@ -23,9 +23,9 @@
[[ -n "$LIBMAKEPKG_BUILDENV_COMPILER_SH" ]] && return
LIBMAKEPKG_BUILDENV_COMPILER_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
build_options+=('ccache' 'distcc')
buildenv_functions+=('buildenv_ccache' 'buildenv_distcc')

View File

@@ -22,17 +22,18 @@
[[ -n "$LIBMAKEPKG_BUILDENV_DEBUGFLAGS_SH" ]] && return
LIBMAKEPKG_BUILDENV_DEBUGFLAGS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
buildenv_functions+=('buildenv_debugflags')
buildenv_debugflags() {
if check_option "debug" "y" && ! check_option "buildflags" "n"; then
DEBUG_CFLAGS+=" -ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
DEBUG_CXXFLAGS+=" -ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
CFLAGS+=" $DEBUG_CFLAGS"
CXXFLAGS+=" $DEBUG_CXXFLAGS"
append_once DEBUG_CFLAGS "-ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
append_once DEBUG_CXXFLAGS "-ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
append_once CFLAGS "$DEBUG_CFLAGS"
append_once CXXFLAGS "$DEBUG_CXXFLAGS"
fi
}

View File

@@ -22,17 +22,18 @@
[[ -n "$LIBMAKEPKG_BUILDENV_LTO_SH" ]] && return
LIBMAKEPKG_BUILDENV_LTO_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
build_options+=('lto')
buildenv_functions+=('buildenv_lto')
buildenv_lto() {
if check_option "lto" "y" && ! check_option "buildflags" "n"; then
CFLAGS+=" ${LTOFLAGS:--flto}"
CXXFLAGS+=" ${LTOFLAGS:--flto}"
LDFLAGS+=" ${LTOFLAGS:--flto}"
append_once CFLAGS "${LTOFLAGS:--flto}"
append_once CXXFLAGS "${LTOFLAGS:--flto}"
append_once LDFLAGS "${LTOFLAGS:--flto}"
fi
}

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_BUILDENV_MAKEFLAGS_SH" ]] && return
LIBMAKEPKG_BUILDENV_MAKEFLAGS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
build_options+=('makeflags')
buildenv_functions+=('buildenv_makeflags')

View File

@@ -21,16 +21,17 @@
[[ -n "$LIBMAKEPKG_BUILDENV_RUST_SH" ]] && return
LIBMAKEPKG_BUILDENV_RUST_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
buildenv_var+=('RUSTFLAGS' 'DEBUG_RUSTFLAGS')
buildenv_vars+=('RUSTFLAGS' 'DEBUG_RUSTFLAGS')
buildenv_functions+=('buildenv_rust')
buildenv_rust() {
if check_option "debug" "y" && ! check_option "buildflags" "n"; then
DEBUG_RUSTFLAGS+=" --remap-path-prefix=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
RUSTFLAGS+=" $DEBUG_RUSTFLAGS"
append_once DEBUG_RUSTFLAGS "--remap-path-prefix=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
append_once RUSTFLAGS "$DEBUG_RUSTFLAGS"
fi
}

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
declare -a executable_functions
for lib in "$LIBRARY/executable/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/executable/"*.sh; do
source "$lib"
done

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_CCACHE_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_CCACHE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
executable_functions+=('executable_ccache')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_CHECKSUM_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_CHECKSUM_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
executable_functions+=('executable_checksum')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_DEBUGEDIT_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_DEBUGEDIT_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
executable_functions+=('executable_debugedit')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_DISTCC_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_DISTCC_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
executable_functions+=('executable_distcc')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_FAKEROOT_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_FAKEROOT_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
executable_functions+=('executable_fakeroot')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_GPG_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_GPG_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
executable_functions+=('executable_gpg')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_GZIP_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_GZIP_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
executable_functions+=('executable_gzip')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_PACMAN_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_PACMAN_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
executable_functions+=('executable_pacman')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_STRIP_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_STRIP_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/option.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/option.sh"
executable_functions+=('executable_strip')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_SUDO_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_SUDO_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
executable_functions+=('executable_sudo')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_EXECUTABLE_VCS_SH" ]] && return
LIBMAKEPKG_EXECUTABLE_VCS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/error.sh"
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/error.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
executable_functions+=('executable_vcs')

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_INTEGRITY_SH" ]] && return
LIBMAKEPKG_INTEGRITY_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
for lib in "$LIBRARY/integrity/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/integrity/"*.sh; do
source "$lib"
done
@@ -42,4 +42,7 @@ check_source_integrity() {
check_checksums "$@"
check_pgpsigs "$@"
fi
if (( VERIFYFUNC )); then
run_verify
fi
}

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_INTEGRITY_GENERATE_CHECKSUM_SH" ]] && return
LIBMAKEPKG_INTEGRITY_GENERATE_CHECKSUM_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/schema.sh"
generate_one_checksum() {
local integ=$1 arch=$2 sources numsrc indentsz idx

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_INTEGRITY_GENERATE_SIGNATURE_SH" ]] && return
LIBMAKEPKG_INTEGRITY_GENERATE_SIGNATURE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
create_signature() {
local ret=0

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_INTEGRITY_VERIFY_CHECKSUM_SH" ]] && return
LIBMAKEPKG_INTEGRITY_CHECKSUM_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh"
source "$LIBRARY/source.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/schema.sh"
source "$MAKEPKG_LIBRARY/source.sh"
check_checksums() {
local integ a

View File

@@ -21,10 +21,16 @@
[[ -n "$LIBMAKEPKG_INTEGRITY_VERIFY_SIGNATURE_SH" ]] && return
LIBMAKEPKG_INTEGRITY_VERIFY_SIGNATURE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
# Filter the contents of a GnuPG statusfile to only contain understood terms to narrow the file's scope and circumvent
# the use of terms (e.g. NOTATION_DATA) that may contain unescaped binary data
filter_gnupg_statusfile() {
grep -E "(.*SIG| TRUST_.*)"
}
check_pgpsigs() {
(( SKIPPGPCHECK )) && return 0
@@ -35,6 +41,7 @@ check_pgpsigs() {
local netfile proto pubkey success status fingerprint trusted
local warnings=0
local errors=0
local statusfile_raw="$(mktemp)"
local statusfile=$(mktemp)
local all_sources
@@ -103,7 +110,7 @@ check_pgpsigs() {
printf '\n' >&2
done
rm -f "$statusfile"
rm -f "$statusfile" "$statusfile_raw"
if (( errors )); then
error "$(gettext "One or more PGP signatures could not be verified!")"
@@ -157,7 +164,20 @@ verify_file_signature() {
"") decompress="cat" ;;
esac
$decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile" --verify "$file" - 2> /dev/null
# verify the signature and write metadata to a status file
if ! $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile_raw" --verify "$file" - 2> /dev/null; then
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "gpg" >&2
errors=1
return 1
fi
# create a statusfile that contains only understood terms
if ! filter_gnupg_statusfile > "$statusfile" < "$statusfile_raw"; then
printf '%s\n' "$(gettext "unable to extract signature metadata.")" >&2
errors=1
return 1
fi
return 0
}
@@ -189,18 +209,33 @@ verify_git_signature() {
printf " %s git repo ... " "${dir##*/}" >&2
git -C "$dir" verify-$fragtype --raw "$fragval" > "$statusfile" 2>&1
if ! grep -qs NEWSIG "$statusfile"; then
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
# verify the signature and write metadata to a status file
if ! git -C "$dir" verify-$fragtype --raw "$fragval" > "$statusfile_raw" 2>&1; then
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "git" >&2
errors=1
return 1
fi
# create a statusfile that contains only understood terms
if ! filter_gnupg_statusfile > "$statusfile" < "$statusfile_raw"; then
printf '%s\n' "$(gettext "unable to extract signature metadata.")" >&2
errors=1
return 1
fi
return 0
}
parse_gpg_statusfile() {
local type arg1 arg6 arg10
# ensure the NEWSIG keyword is part of the metadata
if ! grep -qs NEWSIG "$statusfile"; then
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
errors=1
return 1
fi
while read -r _ type arg1 _ _ _ _ arg6 _ _ _ arg10 _; do
case "$type" in
GOODSIG)

View File

@@ -21,15 +21,15 @@
[[ -n "$LIBMAKEPKG_LINT_CONFIG_SH" ]] && return
LIBMAKEPKG_LINT_CONFIG_SH=1
LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'/usr/share/makepkg'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
declare -a lint_config_functions
for lib in "$LIBRARY/lint_config/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/lint_config/"*.sh; do
source "$lib"
done

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_CONFIG_EXT_SH" ]] && return
LIBMAKEPKG_LINT_CONFIG_EXT_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_config_functions+=('lint_ext')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_CONFIG_PATHS_SH" ]] && return
LIBMAKEPKG_LINT_CONFIG_PATHS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_config_functions+=('lint_paths')

View File

@@ -21,9 +21,9 @@
[[ -n $LIBMAKEPKG_LINT_CONFIG_SOURCE_DATE_EPOCH_SH ]] && return
LIBMAKEPKG_LINT_CONFIG_SOURCE_DATE_EPOCH_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_config_functions+=('lint_source_date_epoch')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_CONFIG_VARIABLE_SH" ]] && return
LIBMAKEPKG_LINT_CONFIG_VARIABLE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_config_functions+=('lint_config_variables')

View File

@@ -21,15 +21,15 @@
[[ -n "$LIBMAKEPKG_LINT_PACKAGE_SH" ]] && return
LIBMAKEPKG_LINT_PACKAGE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
declare -a lint_package_functions
for lib in "$LIBRARY/lint_package/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/lint_package/"*.sh; do
source "$lib"
done

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PACKAGE_BUILD_REFERENCES_SH" ]] && return
LIBMAKEPKG_LINT_PACKAGE_BUILD_REFERENCES_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_package_functions+=('warn_build_references')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PACKAGE_DOTFILES_SH" ]] && return
LIBMAKEPKG_LINT_PACKAGE_DOTFILES_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_package_functions+=('check_dotfiles')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PACKAGE_FILE_NAMES_SH" ]] && return
LIBMAKEPKG_LINT_PACKAGE_FILE_NAMES_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_package_functions+=('lint_file_names')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PACKAGE_MISSING_BACKUP_SH" ]] && return
LIBMAKEPKG_LINT_PACKAGE_MISSING_BACKUP_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_package_functions+=('warn_missing_backup')

View File

@@ -21,14 +21,14 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
declare -a lint_pkgbuild_functions
for lib in "$LIBRARY/lint_pkgbuild/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/lint_pkgbuild/"*.sh; do
source "$lib"
done

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_ARCH_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_ARCH_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_arch')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_ARCH_SPECIFIC_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_ARCH_SPECIFIC_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh"
source "$LIBRARY/util/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/schema.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
lint_pkgbuild_functions+=('lint_arch_specific')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_BACKUP_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_BACKUP_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_backup')

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_CHANGELOG_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_CHANGELOG_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/lint_pkgbuild/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/util.sh"
lint_pkgbuild_functions+=('lint_changelog')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_CHECKDEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_CHECKDEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_checkdepends')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_CONFLICTS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_CONFLICTS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_conflicts')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_DEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_DEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_depends')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_EPOCH_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_EPOCH_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_epoch')

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_FULLPKGVER_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_FULLPKGVER_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/epoch.sh"
source "$LIBRARY/lint_pkgbuild/pkgrel.sh"
source "$LIBRARY/lint_pkgbuild/pkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/epoch.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgrel.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgver.sh"
check_fullpkgver() {

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_INSTALL_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_INSTALL_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/lint_pkgbuild/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/util.sh"
lint_pkgbuild_functions+=('lint_install')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_MAKEDEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_MAKEDEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_makedepends')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_OPTDEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_OPTDEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_optdepends')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_OPTIONS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_OPTIONS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_options')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PACKAGE_FUNCTION_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PACKAGE_FUNCTION_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_package_function')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PACKAGE_FUNCTION_VARIABLE_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PACKAGE_FUNCTION_VARIABLE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh"
source "$LIBRARY/util/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/schema.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
lint_pkgbuild_functions+=('lint_package_function_variable')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PKGBASE_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PKGBASE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_pkgbase')

View File

@@ -21,10 +21,10 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PKGLIST_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PKGLIST_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/util.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
lint_pkgbuild_functions+=('lint_pkglist')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PKGNAME_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PKGNAME_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_pkgname')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PKGREL_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PKGREL_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_pkgrel')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PKGVER_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PKGVER_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_pkgver')

View File

@@ -21,12 +21,12 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_PROVIDES_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PROVIDES_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/fullpkgver.sh"
source "$MAKEPKG_LIBRARY/lint_pkgbuild/pkgname.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_provides')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_SOURCE_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_SOURCE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_source')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_UTIL_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_UTIL_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
check_files_exist() {

View File

@@ -21,11 +21,11 @@
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_VARIABLE_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_VARIABLE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/schema.sh"
lint_pkgbuild_functions+=('lint_variable')
lint_pkgbuild_functions+=('lint_array')

View File

@@ -21,9 +21,9 @@
[[ -n "$LIBMAKEPKG_REPRODUCIBLE_SH" ]] && return
LIBMAKEPKG_REPRODUCIBLE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
for lib in "$LIBRARY/reproducible/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/reproducible/"*.sh; do
source "$lib"
done

View File

@@ -22,7 +22,7 @@
LIBMAKEPKG_REPRODUCIBLE_PYTHON_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
# disable hash randomization when creating .pyc files

View File

@@ -21,14 +21,14 @@
[[ -n "$LIBMAKEPKG_SOURCE_SH" ]] && return
LIBMAKEPKG_SOURCE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/source.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/source.sh"
for lib in "$LIBRARY/source/"*.sh; do
for lib in "$MAKEPKG_LIBRARY/source/"*.sh; do
source "$lib"
done

View File

@@ -22,10 +22,10 @@
LIBMAKEPKG_SOURCE_BZR_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
download_bzr() {

View File

@@ -22,10 +22,10 @@
LIBMAKEPKG_SOURCE_FILE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
download_file() {

View File

@@ -22,10 +22,10 @@
LIBMAKEPKG_SOURCE_FOSSIL_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
download_fossil() {
# abort early if parent says not to fetch

Some files were not shown because too many files have changed in this diff Show More