1
0
forked from mirrors/pacman

Compare commits

...

44 Commits

Author SHA1 Message Date
morganamilo
ea73e66730 pacman: refactor transaction code to one path
This refactors the -S, -U and -R code to share the same implementation.

The goal here is to firstly simplify all transactoions into one code path,
then eventually allow pacman to perform multiple kinds of transactions in
one command.
2023-09-19 22:25:02 +01:00
Xiretza
05f283b5ad tests: fix order of fakechroot + fakeroot nesting
As noted in the fakechroot(1) man page, fakeroot and fakechroot
might wrap the same C library functions. Arch Linux hit this
recently with calls to stat(). It is important to start the fake
environment in proper order - fakeroot should be started inside
fakechroot.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-19 17:55:24 +10:00
Finlay Maroney
34611a6643 Avoid double slash when explicitly passing --root or --rootdir
Passing a path with a trailing slash to --root or --rootdir can lead to a
double slash at the start of paths.  e.g.

$ pacman --root / -v 2>1  | grep " //"
Log File  : //var/log/pacman.log

In MSYS2, paths starting with // will hit the network and fail.

Avoid this be explicitly stripping the trailing / from paths passed to these
flags.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-12 14:22:36 +10:00
Robin Candau
76b140c72a Replace the bzr package by breezy for the bzr protocol in makepkg.conf 2023-09-11 19:11:40 +02:00
Matthew Sexton
5f43ac85f6 specify which files are updated by --refresh option
Ref: FS#77697

Signed-off-by: Matthew Sexton <mssxtn@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-11 22:59:53 +10:00
morganamilo
0dfe5c96ae makepkg: add -D flag to change directory before building
This is similar to -C in git/make/nina. Sadly -C is already taken for
us.

This is useful for scripts where you for loop over packages, as well as
when I'm testing makepkg builds and I'm too lazy to cd.
2023-09-09 11:52:11 +10:00
InsanePrawn
36d70a93e2 pacman-key: allow overriding KEYRING_IMPORT_DIR with --populate-from
Signed-off-by: InsanePrawn <insane.prawny@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-07 00:12:41 +10:00
Allan McRae
717e5e9157 Add PRINT_FORMAT_LIST define to remove repetitive code
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Allan McRae
e7d7433b4b Rename macro for print-format handling of strings
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Jelle van der Waa
e210634982 util.c: extend --print-format with "%m"
Add md5sum as printable format string.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Jelle van der Waa
6968f77026 util.c: extend --print-format with "%G"
Add a new print attribute "%G" which prints groups.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Jelle van der Waa
06db927a1a util.c: extend --print-format with "%H"
Add a new print attribute "%H" which shows conflicts.

Signed-off-by: Jelle van der Waa <jelle@archlinux.org>
2023-09-06 17:56:55 +10:00
Jelle van der Waa
909f2e86c3 util.c: add "%O" to --print-format
Add the option to print optional depends with "%O".

Signed-off-by: Jelle van der Waa <jelle@archlinux.org>
2023-09-06 17:56:55 +10:00
Jelle van der Waa
5bd0b98b42 util.c: extend --print-format with %R and %P
Add provides "%P" and replaces "%R" as format attribute.

Signed-off-by: Jelle van der Waa <jelle@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Jelle van der Waa
c1d4a6198c Extend --print-format with %L
Add format attribute for licenses.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Allan McRae
f5af66f130 Remove unnecessary check
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Allan McRae
5473c9fd3f squash
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 17:56:55 +10:00
Allan McRae
e58d799c47 Generalise concat_alpm_depends for any list
Replace concat_alpm_depends() with concat_list() which takes an
additional parameter to handle the formatting of non-string
data types.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 14:39:00 +10:00
Matthias Kurz
366b527757 libmakepkg: make sure git cloned repo's remote is named origin
makepkg assumes that the remote git repo is named "origin" at several
places in its handling of git sources. It is possible to set the remote
repo name since git v2.30.0 (with bug fix for bare checkouts in v2.30.2).

Add "--origin=origin" to all git clone commands.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-09-06 13:51:32 +10:00
morganamilo
e83e53f3f9 makepkg: lint empty arrays
While depend arrays are already linted, many array kinds are still
not. An empty string is never a valid array value so check all
arrays for it.
2023-09-06 12:14:55 +10:00
morganamilo
2348dcab22 pacman+libalpm: print version names for conflicting packages
When ever pacman prints a conflict, it now prints pkgname-version,
instead of just pkgname.

alpm_conflict_t now carries *alpm_pkg_ts instead of just the
names of each package.

Fixes FS#12536 (point 2)
2023-09-05 01:57:01 +00:00
morganamilo
f9d8beef45 Add meson log to artifacts 2023-09-04 22:00:51 +02:00
morganamilo
85ab0307d7 Fix compile on some platforms
Controlling the type of getmntinfo's param was decided by
whether or not we had the statvfs type avaliable. But getmntinfo uses
statfs regardless of this except on netbsd where it uses statvfs.

Add a check to detect which type our version of the function uses.
2023-09-04 22:00:48 +02:00
Nicolas Rolans
ffde12cebd repo-add: fix exit on mktemp failure 2023-08-28 12:43:56 +00:00
Jouke Witteveen
37dae721d3 Replace md5sums with sha256sums in documentation
As noted in !24, md5sums are outdated.
2023-08-28 12:27:28 +00:00
Ben Westover
aa3a1bc3b5 proto: Change the default checksum from md5 to sha256
MD5 isn't a very good checksum, and the PKGBUILD page on the Arch Wiki
states that it should not be used, instead recommending sha256 or b2.
This patch changes the default from md5 to sha256 because that seems to
be the most commonly used checksum today.

Signed-off-by: Ben Westover <kwestover.kw@gmail.com>
2023-08-28 22:25:10 +10:00
Allan McRae
298755c905 pacman: do not check file md5sums
The file md5sums are removed from the .MTREE file, so pacman should
not attempt to check them.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-08-28 22:17:51 +10:00
Levente Polyak
ee933acf84 makepkg: immutable bzr by hashing the checkout content
This feature makes bzr VCS build inputs immutable by adding support for
pinning a bzr checkout by a hash of its content using the deterministic
export functionality `bzr export`.

This feature allows to preserve security implications of immutable build inputs
using a trusted cryptographic hash function of the content.

Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2023-08-28 22:15:03 +10:00
Levente Polyak
ca3c873d48 makepkg: immutable mercurial sources by hashing the checkout content
This feature makes Mercurial VCS build inputs immutable by adding
support for pinning a Mercurial checkout by a hash of its content using
the deterministic export functionality `hg archive`.

This feature aids packagers by allowing them to use simple and
convenient refnames (instead of full commit hashes) in the `PKGBUILD`
while still preserving security implications of immutable build inputs
using a trusted cryptographic hash function of the content.

Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2023-08-28 22:15:03 +10:00
Levente Polyak
2fc2ab6cf0 makepkg: immutable git sources by hashing the checkout content
This feature makes Git VCS build inputs immutable by adding support for
pinning a Git checkout by a hash of its content using the deterministic
export functionality `git archive`.

This feature aids packagers by allowing them to use simple and
convenient refnames (instead of full commit hashes) in the `PKGBUILD`
while still preserving security implications of immutable build inputs
using a trusted cryptographic hash function of the content.

Previously VCS source downloads have been skipped for `--geninteg` and
`--source` as both options did not need a checkout. This commit changes
this behavior by forcing the download of all sources as integrity checks
and generation requires to have an up to date state.

Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2023-08-28 22:15:03 +10:00
kpcyrd
843bf21e79 libmakepkg: Fix non-reproducible binaries by processing debuginfo in order 2023-08-27 13:03:40 +02:00
Allan McRae
2c45e854ab Disable brittle valgrind test in CI
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-05-22 19:32:47 +10:00
Allan McRae
a81ec016d7 Update pactest README
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-05-22 19:25:23 +10:00
Allan McRae
55da1a01b6 makepkg.conf.in: strip leading slash from LIB_DIRS
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-05-22 18:55:23 +10:00
Allan McRae
5e94752434 makepkg.conf.5: correction option name
Also fix typo "librarys"

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-05-22 18:54:01 +10:00
Allan McRae
262aa6c24e Fix comment
Signed-off-by: Allan McRae <allan@archlinux.org>
2023-02-13 12:09:11 +00:00
Allan McRae
3323662ee0 makepkg: do not recurse into LIB_DIRS when looking for library provides
We should only find library provides in the configured directories, and
not their subdirectories.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-02-13 12:09:11 +00:00
Allan McRae
6c913af95d Add the -pedantic' compiler flag back to our debug builds
This was lost in the transition from autotools to meson. No additional
warnings are given with current gcc and clang.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-02-13 22:07:32 +10:00
Allan McRae
71764b6d4c makepkg.conf: allow configuration additions via a subdirectory
Move rust related buildflags to their own configuration file to
provide an example of how other languages could be supported.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-01-17 10:26:07 +10:00
Allan McRae
e0bbfb5682 libmakepkg: ensure clearing of buildflags happens first
When 'options=('!buildflags') is used, we want to ensure our
buildflags are cleared first. Currently this happens due to luck
of alphabetical ordering, but this could change with libmakepkg
drop-ins.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-01-13 11:35:42 +10:00
Allan McRae
09e82f01ea libmakepkg: move rust buildenv handling to separate file
This serves as a demonstration for how other languages could drop
in support into libmakepkg.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-01-13 11:35:35 +10:00
Stefan Weil
d35728f924 pacman-key: Fix shell syntax
Fixes: 3f8029af92 ("pacman-key: Use ngettext for plurals")
Signed-off-by: Stefan Weil <sw@weilnetz.de>
2023-01-01 15:54:48 +01:00
Allan McRae
3f8029af92 pacman-key: Use ngettext for plurals
There are two strings that may be singular or plural in pacman-key.
Use ngettext to handle these strings correctly, and provide a fallback
function if it is not available.

Fixes FS#70556.

Signed-off-by: Allan McRae <allan@archlinux.org>
2023-01-01 13:41:52 +10:00
Allan McRae
6344aab3bd zsh: make names unique to avoid clashes
The function _keys is a bit generic and can result in clashes.  Change
other functions starting with _key_ to be _pacman_key_ as well.

Fixes FS#74507.

Signed-off-by: Allan McRae <allan@archlinux.org>
2022-12-24 00:55:30 +10:00
52 changed files with 1035 additions and 774 deletions

View File

@@ -16,6 +16,10 @@ default:
python python
fakeroot fakechroot fakeroot fakechroot
meson meson
artifacts:
when: always
paths:
- build/meson-logs/meson-log.txt
arch: arch:
extends: .arch-test extends: .arch-test
@@ -46,14 +50,14 @@ arch-clang:
- ninja -C build - ninja -C build
- fakechroot meson test -C build - fakechroot meson test -C build
arch-valgrind: #arch-valgrind:
extends: .arch-test # extends: .arch-test
script: # script:
- pacman -Syu --needed --noconfirm valgrind # - pacman -Syu --needed --noconfirm valgrind
- pacman -U --noconfirm https://geo.mirror.pkgbuild.com/core-debug/os/x86_64/glibc-debug-$(pacman -S --print-format %v glibc)-x86_64.pkg.tar.zst # - pacman -U --noconfirm https://geo.mirror.pkgbuild.com/core-debug/os/x86_64/glibc-debug-$(pacman -S --print-format %v glibc)-x86_64.pkg.tar.zst
- meson setup build # - meson setup build
- ninja -C build # - ninja -C build
- PACTEST_VALGRIND=1 fakechroot meson test -C build # - PACTEST_VALGRIND=1 fakechroot meson test -C build
arch-nettle: arch-nettle:
extends: .arch-test extends: .arch-test

View File

@@ -12,7 +12,7 @@ depends=('glibc')
makedepends=('ed') makedepends=('ed')
optdepends=('ed: for "patch -e" functionality') optdepends=('ed: for "patch -e" functionality')
source=("ftp://ftp.gnu.org/gnu/$pkgname/$pkgname-$pkgver.tar.xz"{,.sig}) source=("ftp://ftp.gnu.org/gnu/$pkgname/$pkgname-$pkgver.tar.xz"{,.sig})
md5sums=('e9ae5393426d3ad783a300a338c09b72' sha256sums=('9124ba46db0abd873d0995c2ca880e81252676bb6c03e0a37dfc5f608a9b0ceb'
'SKIP') 'SKIP')
build() { build() {

View File

@@ -464,6 +464,9 @@ Currently makepkg supports the Bazaar, Git, Subversion, Fossil and Mercurial
version control systems. For other version control systems, manual cloning of version control systems. For other version control systems, manual cloning of
upstream repositories must be done in the `prepare()` function. upstream repositories must be done in the `prepare()` function.
Some <<VCS,VCS Sources>> like Git support pinning the checkout by a checksum of
its content using deterministic export functionality like ``git archive''.
The source URL is divided into four components: The source URL is divided into four components:
*directory*:: *directory*::

View File

@@ -85,7 +85,7 @@ Example PKGBUILD
license=('PerlArtistic' 'GPL') license=('PerlArtistic' 'GPL')
depends=('perl') depends=('perl')
source=("http://search.cpan.org/CPAN/authors/id/S/SH/SHERZODR/Config-Simple-${pkgver}.tar.gz") source=("http://search.cpan.org/CPAN/authors/id/S/SH/SHERZODR/Config-Simple-${pkgver}.tar.gz")
md5sums=('f014aec54f0a1e2e880d317180fce502') sha256sums=('dd9995706f0f9384a15ccffe116c3b6e22f42ba2e58d8f24ed03c4a0e386edb4')
_distname="Config-Simple" _distname="Config-Simple"
# template start; name=perl-module; version=1.0; # template start; name=perl-module; version=1.0;

View File

@@ -146,6 +146,9 @@ Options
*-C, \--cleanbuild*:: *-C, \--cleanbuild*::
Remove the $srcdir before building the package. Remove the $srcdir before building the package.
*-D* <dir>, *\--dir* <dir> ::
Change to directory <dir> before reading the PKGBUILD or doing anything else.
*\--allsource*:: *\--allsource*::
Do not actually build the package, but build a source-only tarball that Do not actually build the package, but build a source-only tarball that
includes all sources, including those that are normally downloaded via includes all sources, including those that are normally downloaded via

View File

@@ -199,7 +199,7 @@ Options
flags specified in LTOFLAGS to CFLAGS, CXXFLAGS and LDFLAGS (or flags specified in LTOFLAGS to CFLAGS, CXXFLAGS and LDFLAGS (or
``-flto'' if LTOFLAGS is empty). ``-flto'' if LTOFLAGS is empty).
*autodep*;; *autodeps*;;
Enable the automatic addition of libraries to the depends and Enable the automatic addition of libraries to the depends and
provides arrays. Search library directories are controlled by provides arrays. Search library directories are controlled by
the LIB_DIRS variable defined below. the LIB_DIRS variable defined below.
@@ -236,7 +236,7 @@ Options
**LIB_DIRS=(**lib:usr/lib ...**)**:: **LIB_DIRS=(**lib:usr/lib ...**)**::
If `autodeps` is specified in the `OPTIONS` array, this variable will If `autodeps` is specified in the `OPTIONS` array, this variable will
instruct makepkg where to look to find librarys to add to the `provides` instruct makepkg where to look to find libraries to add to the `provides`
array. The format is "prefix:path", where provides will be added for array. The format is "prefix:path", where provides will be added for
libraries found in "path" with the specified prefix added. libraries found in "path" with the specified prefix added.

View File

@@ -237,10 +237,12 @@ Transaction Options (apply to '-S', '-R' and '-U')
Specify a printf-like format to control the output of the '\--print' Specify a printf-like format to control the output of the '\--print'
operation. The possible attributes are: "%a" for arch, "%b" for operation. The possible attributes are: "%a" for arch, "%b" for
builddate, "%d" for description, "%e" for pkgbase, "%f" for filename, builddate, "%d" for description, "%e" for pkgbase, "%f" for filename,
"%g" for base64 encoded PGP signature, "%h" for sha256sum, "%n" for "%g" for base64 encoded PGP signature, "%h" for sha256sum, "%m" for
pkgname, "%p" for packager, "%v" for pkgver, "%l" for location, "%r" md5sum, "%n" for pkgname, "%p" for packager, "%v" for pkgver, "%l" for
for repository, "%s" for size, "%C" for checkdepends, "%D" for depends location, "%r" for repository, "%s" for size, "%C" for checkdepends,
and "%M" for makedepends. "%D" for depends, "%G" for groups, "%H" for conflicts, "%L" for
licenses, "%M" for makedepends, "%O" for optional depends, "%P" for
provides and "%R" for replaces.
Implies '\--print'. Implies '\--print'.
@@ -454,11 +456,11 @@ Additional targets can also be specified manually, so that '-Su foo' will do a
system upgrade and install/upgrade the "foo" package in the same operation. system upgrade and install/upgrade the "foo" package in the same operation.
*-y, \--refresh*:: *-y, \--refresh*::
Download a fresh copy of the master package database from the server(s) Download a fresh copy of the master package databases '(repo.db)' from the
defined in linkman:pacman.conf[5]. This should typically be used each time server(s) defined in linkman:pacman.conf[5]. This should typically be used
you use '\--sysupgrade' or '-u'. Passing two '\--refresh' or '-y' flags each time you use '\--sysupgrade' or '-u'. Passing two '\--refresh' or '-y'
will force a refresh of all package databases, even if they appear to be flags will force a refresh of all package databases, even if they appear to
up-to-date. be up-to-date.
Database Options (apply to '-D')[[QO]] Database Options (apply to '-D')[[QO]]
@@ -487,8 +489,8 @@ Database Options (apply to '-D')[[QO]]
File Options (apply to '-F')[[FO]] File Options (apply to '-F')[[FO]]
---------------------------------- ----------------------------------
*-y, --refresh*:: *-y, --refresh*::
Download fresh package databases from the server. Use twice to force a Download fresh package file databases '(repo.files)' from the server.
refresh even if databases are up to date. Use twice to force a refresh even if databases are up to date.
*-l, \--list*:: *-l, \--list*::
List the files owned by the queried package. List the files owned by the queried package.

View File

@@ -0,0 +1,11 @@
#!/hint/bash
#
# @sysconfdir@/makepkg.conf.d/rust.conf
#
#########################################################################
# RUST LANGUAGE SUPPORT
#########################################################################
#
#RUSTFLAGS="-C opt-level=2"
#DEBUG_RUSTFLAGS="-C debuginfo=2"

View File

@@ -23,7 +23,7 @@ DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
#-- The package required by makepkg to download VCS sources #-- The package required by makepkg to download VCS sources
# Format: 'protocol::package' # Format: 'protocol::package'
VCSCLIENTS=('bzr::bzr' VCSCLIENTS=('bzr::breezy'
'fossil::fossil' 'fossil::fossil'
'git::git' 'git::git'
'hg::mercurial' 'hg::mercurial'
@@ -42,13 +42,11 @@ CHOST="@CHOST@"
#CXXFLAGS="-O2 -pipe" #CXXFLAGS="-O2 -pipe"
#LDFLAGS="" #LDFLAGS=""
#LTOFLAGS="-flto" #LTOFLAGS="-flto"
#RUSTFLAGS="-C opt-level=2"
#-- Make Flags: change this for DistCC/SMP systems #-- Make Flags: change this for DistCC/SMP systems
#MAKEFLAGS="-j2" #MAKEFLAGS="-j2"
#-- Debugging flags #-- Debugging flags
#DEBUG_CFLAGS="-g" #DEBUG_CFLAGS="-g"
#DEBUG_CXXFLAGS="-g" #DEBUG_CXXFLAGS="-g"
#DEBUG_RUSTFLAGS="-C debuginfo=2"
######################################################################### #########################################################################
# BUILD ENVIRONMENT # BUILD ENVIRONMENT
@@ -111,7 +109,7 @@ PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#-- Directory to store source code in for debug packages #-- Directory to store source code in for debug packages
DBGSRCDIR="/usr/src/debug" DBGSRCDIR="/usr/src/debug"
#-- Prefix and directories for library autodeps #-- Prefix and directories for library autodeps
LIB_DIRS=('lib:/usr/lib' 'lib32:/usr/lib32') LIB_DIRS=('lib:usr/lib' 'lib32:usr/lib32')
######################################################################### #########################################################################
# PACKAGE OUTPUT # PACKAGE OUTPUT

View File

@@ -600,16 +600,10 @@ typedef struct _alpm_depmissing_t {
/** A conflict that has occurred between two packages. */ /** A conflict that has occurred between two packages. */
typedef struct _alpm_conflict_t { typedef struct _alpm_conflict_t {
/** Hash of the first package name /** The first package */
* (used internally to speed up conflict checks) */ alpm_pkg_t *package1;
unsigned long package1_hash; /** The second package */
/** Hash of the second package name alpm_pkg_t *package2;
* (used internally to speed up conflict checks) */
unsigned long package2_hash;
/** Name of the first package */
char *package1;
/** Name of the second package */
char *package2;
/** The conflict */ /** The conflict */
alpm_depend_t *reason; alpm_depend_t *reason;
} alpm_conflict_t; } alpm_conflict_t;

View File

@@ -50,10 +50,8 @@ static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2,
CALLOC(conflict, 1, sizeof(alpm_conflict_t), return NULL); CALLOC(conflict, 1, sizeof(alpm_conflict_t), return NULL);
conflict->package1_hash = pkg1->name_hash; ASSERT(_alpm_pkg_dup(pkg1, &conflict->package1) == 0, goto error);
conflict->package2_hash = pkg2->name_hash; ASSERT(_alpm_pkg_dup(pkg2, &conflict->package2) == 0, goto error);
STRDUP(conflict->package1, pkg1->name, goto error);
STRDUP(conflict->package2, pkg2->name, goto error);
conflict->reason = reason; conflict->reason = reason;
return conflict; return conflict;
@@ -66,8 +64,9 @@ error:
void SYMEXPORT alpm_conflict_free(alpm_conflict_t *conflict) void SYMEXPORT alpm_conflict_free(alpm_conflict_t *conflict)
{ {
ASSERT(conflict != NULL, return); ASSERT(conflict != NULL, return);
FREE(conflict->package2); _alpm_pkg_free(conflict->package1);
FREE(conflict->package1); _alpm_pkg_free(conflict->package2);
FREE(conflict); FREE(conflict);
} }
@@ -79,10 +78,8 @@ alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict)
alpm_conflict_t *newconflict; alpm_conflict_t *newconflict;
CALLOC(newconflict, 1, sizeof(alpm_conflict_t), return NULL); CALLOC(newconflict, 1, sizeof(alpm_conflict_t), return NULL);
newconflict->package1_hash = conflict->package1_hash; ASSERT(_alpm_pkg_dup(conflict->package1, &newconflict->package1) == 0, goto error);
newconflict->package2_hash = conflict->package2_hash; ASSERT(_alpm_pkg_dup(conflict->package2, &newconflict->package2) == 0, goto error);
STRDUP(newconflict->package1, conflict->package1, goto error);
STRDUP(newconflict->package2, conflict->package2, goto error);
newconflict->reason = conflict->reason; newconflict->reason = conflict->reason;
return newconflict; return newconflict;
@@ -105,10 +102,10 @@ static int conflict_isin(alpm_conflict_t *needle, alpm_list_t *haystack)
alpm_list_t *i; alpm_list_t *i;
for(i = haystack; i; i = i->next) { for(i = haystack; i; i = i->next) {
alpm_conflict_t *conflict = i->data; alpm_conflict_t *conflict = i->data;
if(needle->package1_hash == conflict->package1_hash if(needle->package1->name_hash == conflict->package1->name_hash
&& needle->package2_hash == conflict->package2_hash && needle->package2->name_hash == conflict->package2->name_hash
&& strcmp(needle->package1, conflict->package1) == 0 && strcmp(needle->package1->name, conflict->package1->name) == 0
&& strcmp(needle->package2, conflict->package2) == 0) { && strcmp(needle->package2->name, conflict->package2->name) == 0) {
return 1; return 1;
} }
} }

View File

@@ -517,21 +517,23 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
for(i = deps; i; i = i->next) { for(i = deps; i; i = i->next) {
alpm_conflict_t *conflict = i->data; alpm_conflict_t *conflict = i->data;
const char *name1 = conflict->package1->name;
const char *name2 = conflict->package2->name;
alpm_pkg_t *rsync, *sync, *sync1, *sync2; alpm_pkg_t *rsync, *sync, *sync1, *sync2;
/* have we already removed one of the conflicting targets? */ /* have we already removed one of the conflicting targets? */
sync1 = alpm_pkg_find(trans->add, conflict->package1); sync1 = alpm_pkg_find(trans->add, name1);
sync2 = alpm_pkg_find(trans->add, conflict->package2); sync2 = alpm_pkg_find(trans->add, name2);
if(!sync1 || !sync2) { if(!sync1 || !sync2) {
continue; continue;
} }
_alpm_log(handle, ALPM_LOG_DEBUG, "conflicting packages in the sync list: '%s' <-> '%s'\n", _alpm_log(handle, ALPM_LOG_DEBUG, "conflicting packages in the sync list: '%s' <-> '%s'\n",
conflict->package1, conflict->package2); name1, name2);
/* if sync1 provides sync2, we remove sync2 from the targets, and vice versa */ /* if sync1 provides sync2, we remove sync2 from the targets, and vice versa */
alpm_depend_t *dep1 = alpm_dep_from_string(conflict->package1); alpm_depend_t *dep1 = alpm_dep_from_string(name1);
alpm_depend_t *dep2 = alpm_dep_from_string(conflict->package2); alpm_depend_t *dep2 = alpm_dep_from_string(name2);
if(_alpm_depcmp(sync1, dep2)) { if(_alpm_depcmp(sync1, dep2)) {
rsync = sync2; rsync = sync2;
sync = sync1; sync = sync1;
@@ -559,8 +561,8 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
/* Prints warning */ /* Prints warning */
_alpm_log(handle, ALPM_LOG_WARNING, _alpm_log(handle, ALPM_LOG_WARNING,
_("removing '%s' from target list because it conflicts with '%s'\n"), _("removing '%s-%s' from target list because it conflicts with '%s-%s'\n"),
rsync->name, sync->name); rsync->name, rsync->version, sync->name, sync->version);
trans->add = alpm_list_remove(trans->add, rsync, _alpm_pkg_cmp, NULL); trans->add = alpm_list_remove(trans->add, rsync, _alpm_pkg_cmp, NULL);
/* rsync is not a transaction target anymore */ /* rsync is not a transaction target anymore */
trans->unresolvable = alpm_list_add(trans->unresolvable, rsync); trans->unresolvable = alpm_list_add(trans->unresolvable, rsync);
@@ -581,16 +583,18 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
.conflict = i->data .conflict = i->data
}; };
alpm_conflict_t *conflict = i->data; alpm_conflict_t *conflict = i->data;
const char *name1 = conflict->package1->name;
const char *name2 = conflict->package2->name;
int found = 0; int found = 0;
/* if conflict->package2 (the local package) is not elected for removal, /* if name2 (the local package) is not elected for removal,
we ask the user */ we ask the user */
if(alpm_pkg_find(trans->remove, conflict->package2)) { if(alpm_pkg_find(trans->remove, name2)) {
found = 1; found = 1;
} }
for(j = trans->add; j && !found; j = j->next) { for(j = trans->add; j && !found; j = j->next) {
alpm_pkg_t *spkg = j->data; alpm_pkg_t *spkg = j->data;
if(alpm_pkg_find(spkg->removes, conflict->package2)) { if(alpm_pkg_find(spkg->removes, name2)) {
found = 1; found = 1;
} }
} }
@@ -598,15 +602,15 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
continue; continue;
} }
_alpm_log(handle, ALPM_LOG_DEBUG, "package '%s' conflicts with '%s'\n", _alpm_log(handle, ALPM_LOG_DEBUG, "package '%s-%s' conflicts with '%s-%s'\n",
conflict->package1, conflict->package2); name1, conflict->package1->version, name2,conflict->package2->version);
QUESTION(handle, &question); QUESTION(handle, &question);
if(question.remove) { if(question.remove) {
/* append to the removes list */ /* append to the removes list */
alpm_pkg_t *sync = alpm_pkg_find(trans->add, conflict->package1); alpm_pkg_t *sync = alpm_pkg_find(trans->add, name1);
alpm_pkg_t *local = _alpm_db_get_pkgfromcache(handle->db_local, conflict->package2); alpm_pkg_t *local = _alpm_db_get_pkgfromcache(handle->db_local, name2);
_alpm_log(handle, ALPM_LOG_DEBUG, "electing '%s' for removal\n", conflict->package2); _alpm_log(handle, ALPM_LOG_DEBUG, "electing '%s' for removal\n", name2);
sync->removes = alpm_list_add(sync->removes, local); sync->removes = alpm_list_add(sync->removes, local);
} else { /* abort */ } else { /* abort */
_alpm_log(handle, ALPM_LOG_ERROR, _("unresolvable package conflicts detected\n")); _alpm_log(handle, ALPM_LOG_ERROR, _("unresolvable package conflicts detected\n"));

View File

@@ -182,7 +182,22 @@ foreach type : [
endif endif
endforeach endforeach
if conf.has('HAVE_STRUCT_STATVFS_F_FLAG')
if conf.has('HAVE_GETMNTINFO')
if cc.compiles('''
#include <sys/types.h>
#include <sys/statvfs.h>
void func() {
struct statvfs *buf;
getmntinfo(&buf, 0);
}
''')
conf.set('FSSTATSTYPE', 'struct statvfs')
else
conf.set('FSSTATSTYPE', 'struct statfs')
endif
elif conf.has('HAVE_STRUCT_STATVFS_F_FLAG')
conf.set('FSSTATSTYPE', 'struct statvfs') conf.set('FSSTATSTYPE', 'struct statvfs')
elif conf.has('HAVE_STRUCT_STATFS_F_FLAGS') elif conf.has('HAVE_STRUCT_STATFS_F_FLAGS')
conf.set('FSSTATSTYPE', 'struct statfs') conf.set('FSSTATSTYPE', 'struct statfs')
@@ -190,6 +205,7 @@ endif
if get_option('debug') if get_option('debug')
extra_cflags = [ extra_cflags = [
'-pedantic',
'-Wcast-align', '-Wcast-align',
'-Wclobbered', '-Wclobbered',
'-Wempty-body', '-Wempty-body',
@@ -401,6 +417,12 @@ configure_file(
configuration : substs, configuration : substs,
install_dir : SYSCONFDIR) install_dir : SYSCONFDIR)
configure_file(
input : 'etc/makepkg.conf.d/rust.conf.in',
output : 'rust.conf',
configuration : substs,
install_dir : join_paths(SYSCONFDIR, 'makepkg.conf.d/'))
configure_file( configure_file(
input : 'etc/pacman.conf.in', input : 'etc/pacman.conf.in',
output : 'pacman.conf', output : 'pacman.conf',

View File

@@ -28,7 +28,7 @@ changelog=
source=("$pkgbase-$pkgver.tar.gz" source=("$pkgbase-$pkgver.tar.gz"
"$pkgname-$pkgver.patch") "$pkgname-$pkgver.patch")
noextract=() noextract=()
md5sums=() sha256sums=()
validpgpkeys=() validpgpkeys=()
prepare() { prepare() {

View File

@@ -25,7 +25,7 @@ options=()
install= install=
source=('FOLDER::VCS+URL#FRAGMENT') source=('FOLDER::VCS+URL#FRAGMENT')
noextract=() noextract=()
md5sums=('SKIP') sha256sums=('SKIP')
# Please refer to the 'USING VCS SOURCES' section of the PKGBUILD man page for # Please refer to the 'USING VCS SOURCES' section of the PKGBUILD man page for
# a description of each element in the source array. # a description of each element in the source array.

View File

@@ -27,7 +27,7 @@ changelog=
source=("$pkgname-$pkgver.tar.gz" source=("$pkgname-$pkgver.tar.gz"
"$pkgname-$pkgver.patch") "$pkgname-$pkgver.patch")
noextract=() noextract=()
md5sums=() sha256sums=()
validpgpkeys=() validpgpkeys=()
prepare() { prepare() {

View File

@@ -586,38 +586,38 @@ _pacman_conf() {
esac esac
} }
_key_shortopts=( _pacman_key_shortopts=(
'-h[show help]' '-h[show help]'
'-a[Add the specified keys (empty for stdin)]: :_files' '-a[Add the specified keys (empty for stdin)]: :_files'
'-d[Remove the Specified keyids]:*: :_keys' '-d[Remove the Specified keyids]:*: :_pacman_key_list'
'-e[Export the specified or all keyids]:*: :_keys' '-e[Export the specified or all keyids]:*: :_pacman_key_list'
'-f[List fingerprint for specified or all keyids]:*: :_keys' '-f[List fingerprint for specified or all keyids]:*: :_pacman_key_list'
'-l[List the specified or all keys]:*: :_keys' '-l[List the specified or all keys]:*: :_pacman_key_list'
'-r[Fetch the specified keyids]:*: :_keys' '-r[Fetch the specified keyids]:*: :_pacman_key_list'
'-u[Update the trustdb of pacman]' '-u[Update the trustdb of pacman]'
'-v[Verify the file specified by the signature]: :_files -g "*.sig"' '-v[Verify the file specified by the signature]: :_files -g "*.sig"'
'-V[Show program version]' '-V[Show program version]'
) )
_key_longopts=( _pacman_key_longopts=(
'--help[show help]' '--help[show help]'
'--add[Add the specified keys (empty for stdin)]: :_files' '--add[Add the specified keys (empty for stdin)]: :_files'
'--delete[Remove the Specified keyids]:*: :_keys' '--delete[Remove the Specified keyids]:*: :_pacman_key_list'
'--export[Export the specified or all keyids]:*: :_keys' '--export[Export the specified or all keyids]:*: :_pacman_key_list'
'--finger[List fingerprint for specified or all keyids]:*: :_keys' '--finger[List fingerprint for specified or all keyids]:*: :_pacman_key_list'
'--list-keys[List the specified or all keys]:*: :_keys' '--list-keys[List the specified or all keys]:*: :_pacman_key_list'
'--recv-keys[Fetch the specified keyids]:*: :_keys' '--recv-keys[Fetch the specified keyids]:*: :_pacman_key_list'
'--updatedb[Update the trustdb of pacman]' '--updatedb[Update the trustdb of pacman]'
'--verify[Verify the file specified by the signature]: :_files -g "*.sig"' '--verify[Verify the file specified by the signature]: :_files -g "*.sig"'
'--version[Show program version]' '--version[Show program version]'
'--edit-key[Present a menu for key management task on keyids]:*: :_keys' '--edit-key[Present a menu for key management task on keyids]:*: :_pacman_key_list'
'--import[Imports pubring.gpg from dir(s)]: :_files -g "*.gpg"' '--import[Imports pubring.gpg from dir(s)]: :_files -g "*.gpg"'
'--import-tb[Imports ownertrust values from trustdb.gpg in dir(s)]: :_files -g "*.gpg"' '--import-tb[Imports ownertrust values from trustdb.gpg in dir(s)]: :_files -g "*.gpg"'
'--init[Ensure the keyring is properly initialized]' '--init[Ensure the keyring is properly initialized]'
'--list-sigs[List keys and their signatures]:*: :_keys' '--list-sigs[List keys and their signatures]:*: :_pacman_key_list'
'--lsign-key[Locally sign the specified keyid]:*: :_keys' '--lsign-key[Locally sign the specified keyid]:*: :_pacman_key_list'
'--populate[Reload the default keys from the (given) keyrings in '@keyringdir@']: :_path_files -W @keyringdir@' '--populate[Reload the default keys from the (given) keyrings in '@keyringdir@']: :_path_files -W @keyringdir@'
'--refresh-keys[Update specified or all keys from a keyserver]:*: :_keys' '--refresh-keys[Update specified or all keys from a keyserver]:*: :_pacman_key_list'
) )
_pacman_key_options=( _pacman_key_options=(
@@ -631,13 +631,13 @@ _pacman_key() {
--*) --*)
_arguments -s : \ _arguments -s : \
"$_pacman_key_options[@]" \ "$_pacman_key_options[@]" \
"$_key_longopts[@]" "$_pacman_key_longopts[@]"
;; ;;
-*) -*)
_arguments -s : \ _arguments -s : \
"$_pacman_key_options[@]" \ "$_pacman_key_options[@]" \
"$_key_shortopts[@]" \ "$_pacman_key_shortopts[@]" \
"$_key_longopts[@]" "$_pacman_key_longopts[@]"
;; ;;
*) *)
i=$# i=$#
@@ -648,13 +648,13 @@ _pacman_key() {
--*) --*)
_arguments -s : \ _arguments -s : \
"$_pacman_key_options[@]" \ "$_pacman_key_options[@]" \
"$_key_longopts[@]" "$_pacman_key_longopts[@]"
;; ;;
-*) -*)
_arguments -s : \ _arguments -s : \
"$_pacman_key_options[@]" \ "$_pacman_key_options[@]" \
"$_key_shortopts[@]" \ "$_pacman_key_shortopts[@]" \
"$_key_longopts[@]" "$_pacman_key_longopts[@]"
;; ;;
*) *)
return 1 return 1
@@ -664,7 +664,7 @@ _pacman_key() {
esac esac
} }
_keys() { _pacman_key_list() {
local keylist keys local keylist keys
keylist=$(pacman-key --list-keys 2>/dev/null | awk ' keylist=$(pacman-key --list-keys 2>/dev/null | awk '
$1 == "pub" { $1 == "pub" {
@@ -733,7 +733,7 @@ _makepkg_longopts=(
'--check[Run check() function in the PKGBUILD]' '--check[Run check() function in the PKGBUILD]'
'--config[Use an alternate config file instead of '@sysconfdir@/makepkg.conf']: :_files' '--config[Use an alternate config file instead of '@sysconfdir@/makepkg.conf']: :_files'
'--holdver[Do not update VCS sources]' '--holdver[Do not update VCS sources]'
'--key[Specify key to use for gpg signing instead of the default]: :_keys' '--key[Specify key to use for gpg signing instead of the default]: :_pacman_key_list'
'--noarchive[Do not create package archive]' '--noarchive[Do not create package archive]'
'--nocheck[Do not run the check() function in the PKGBUILD]' '--nocheck[Do not run the check() function in the PKGBUILD]'
'--noprepare[Do not run the prepare() function in the PKGBUILD]' '--noprepare[Do not run the prepare() function in the PKGBUILD]'

View File

@@ -35,7 +35,7 @@ library_provides() {
continue; continue;
fi fi
mapfile -t filenames < <(find "$pkgdir/$dir" -type f | LC_ALL=C sort) mapfile -t filenames < <(find "$pkgdir/$dir" -maxdepth 1 -type f | LC_ALL=C sort)
for fn in "${filenames[@]}"; do for fn in "${filenames[@]}"; do
# check we have a shared library # check we have a shared library
@@ -44,7 +44,7 @@ library_provides() {
local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p') local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
if [[ -z "$sofile" ]]; then if [[ -z "$sofile" ]]; then
# the library is not versioned # the library has no soname
continue continue
fi fi

View File

@@ -25,18 +25,22 @@ LIBMAKEPKG_BUILDENV_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'} LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
declare -a buildenv_functions build_options declare -a buildenv_functions build_options
buildenv_vars=('CPPFLAGS' 'CFLAGS' 'CXXFLAGS' 'LDFLAGS' 'MAKEFLAGS' 'CHOST')
for lib in "$LIBRARY/buildenv/"*.sh; do for lib in "$LIBRARY/buildenv/"*.sh; do
source "$lib" source "$lib"
done done
readonly -a buildenv_functions build_options readonly -a buildenv_functions buildenv_vars build_options
prepare_buildenv() { prepare_buildenv() {
# ensure this function runs first
buildenv_buildflags
for func in ${buildenv_functions[@]}; do for func in ${buildenv_functions[@]}; do
$func $func
done done
# ensure all necessary build variables are exported # ensure all necessary build variables are exported
export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS RUSTFLAGS MAKEFLAGS CHOST export ${buildenv_vars[@]}
} }

View File

@@ -26,10 +26,9 @@ LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh" source "$LIBRARY/util/option.sh"
build_options+=('buildflags') build_options+=('buildflags')
buildenv_functions+=('buildenv_buildflags')
buildenv_buildflags() { buildenv_buildflags() {
if check_option "buildflags" "n"; then if check_option "buildflags" "n"; then
unset CPPFLAGS CFLAGS DEBUG_CFLAGS CXXFLAGS DEBUG_CXXFLAGS LDFLAGS LTOFLAGS RUSTFLAGS DEBUG_RUSTFLAGS unset ${buildenv_vars[@]}
fi fi
} }

View File

@@ -32,9 +32,7 @@ buildenv_debugflags() {
if check_option "debug" "y" && ! check_option "buildflags" "n"; then if check_option "debug" "y" && ! check_option "buildflags" "n"; then
DEBUG_CFLAGS+=" -ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}" DEBUG_CFLAGS+=" -ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
DEBUG_CXXFLAGS+=" -ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}" DEBUG_CXXFLAGS+=" -ffile-prefix-map=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
DEBUG_RUSTFLAGS+=" --remap-path-prefix=$srcdir=${DBGSRCDIR:-/usr/src/debug}/${pkgbase}"
CFLAGS+=" $DEBUG_CFLAGS" CFLAGS+=" $DEBUG_CFLAGS"
CXXFLAGS+=" $DEBUG_CXXFLAGS" CXXFLAGS+=" $DEBUG_CXXFLAGS"
RUSTFLAGS+=" $DEBUG_RUSTFLAGS"
fi fi
} }

View File

@@ -6,6 +6,7 @@ sources = [
'debugflags.sh.in', 'debugflags.sh.in',
'lto.sh.in', 'lto.sh.in',
'makeflags.sh.in', 'makeflags.sh.in',
'rust.sh.in',
] ]
foreach src : sources foreach src : sources

View File

@@ -0,0 +1,36 @@
#!/usr/bin/bash
#
# rust.sh - Specify flags for building a package with rust
#
# Copyright (c) 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/>.
#
[[ -n "$LIBMAKEPKG_BUILDENV_RUST_SH" ]] && return
LIBMAKEPKG_BUILDENV_RUST_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/option.sh"
buildenv_var+=('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"
fi
}

View File

@@ -54,7 +54,17 @@ generate_one_checksum() {
case $proto in case $proto in
bzr|git|hg|svn) bzr|git|hg|svn)
if declare -f "calc_checksum_$proto" > /dev/null; then
if ! sum=$("calc_checksum_$proto" "$netfile" "$integ"); then
local name
name=$(get_filename "$netfile")
error "$(gettext "Failure while calculating %s %s checksum")" "${name}" "${proto}"
plainerr "$(gettext "Aborting...")"
exit 1
fi
else
sum="SKIP" sum="SKIP"
fi
;; ;;
*) *)
if [[ ${netfile%%::*} != *.@(sig?(n)|asc) ]]; then if [[ ${netfile%%::*} != *.@(sig?(n)|asc) ]]; then

View File

@@ -26,6 +26,7 @@ LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh" source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh" source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh" source "$LIBRARY/util/schema.sh"
source "$LIBRARY/source.sh"
check_checksums() { check_checksums() {
local integ a local integ a
@@ -68,9 +69,9 @@ check_checksums() {
} }
verify_integrity_one() { verify_integrity_one() {
local source_name=$1 integ=$2 expectedsum=$3 local source_name=$1 integ=$2 expectedsum=$3 file proto realsum
local file="$(get_filename "$source_name")" file="$(get_filename "$source_name")"
printf ' %s ... ' "$file" >&2 printf ' %s ... ' "$file" >&2
if [[ $expectedsum = 'SKIP' ]]; then if [[ $expectedsum = 'SKIP' ]]; then
@@ -78,20 +79,18 @@ verify_integrity_one() {
return return
fi fi
if ! file="$(get_filepath "$file")"; then proto="$(get_protocol "$source_name")"
printf '%s\n' "$(gettext "NOT FOUND")" >&2 if declare -f "calc_checksum_${proto}" > /dev/null; then
return 1 realsum=$("calc_checksum_${proto}" "$source_name" "$integ") || return 1
else
realsum=$(calc_checksum_file "$source_name" "$integ") || return 1
fi fi
local realsum="$("${integ}sum" "$file")" if [[ ${expectedsum,,} != "$realsum" ]]; then
realsum="${realsum%% *}"
if [[ ${expectedsum,,} = "$realsum" ]]; then
printf '%s\n' "$(gettext "Passed")" >&2
else
printf '%s\n' "$(gettext "FAILED")" >&2 printf '%s\n' "$(gettext "FAILED")" >&2
return 1 return 1
fi fi
printf '%s\n' "$(gettext "Passed")" >&2
return 0 return 0
} }

View File

@@ -32,10 +32,10 @@ lint_config_variables() {
local array=(DLAGENTS VCSCLIENTS BUILDENV OPTIONS INTEGRITY_CHECK MAN_DIRS local array=(DLAGENTS VCSCLIENTS BUILDENV OPTIONS INTEGRITY_CHECK MAN_DIRS
DOC_DIRS PURGE_TARGETS COMPRESSGZ COMPRESSBZ2 COMPRESSXZ DOC_DIRS PURGE_TARGETS COMPRESSGZ COMPRESSBZ2 COMPRESSXZ
COMPRESSLRZ COMPRESSLZO COMPRESSZ) COMPRESSLRZ COMPRESSLZO COMPRESSZ)
local string=(CARCH CHOST CPPFLAGS CFLAGS CXXFLAGS RUSTFLAGS LDFLAGS LTOFLAGS local string=(CARCH CHOST CPPFLAGS CFLAGS CXXFLAGS LDFLAGS LTOFLAGS DEBUG_CFLAGS
DEBUG_CFLAGS DEBUG_CXXFLAGS DEBUG_RUSTFLAGS DISTCC_HOSTS BUILDDIR DEBUG_CXXFLAGS DISTCC_HOSTS BUILDDIR STRIP_BINARIES STRIP_SHARED
STRIP_BINARIES STRIP_SHARED STRIP_STATIC PKGDEST SRCDEST SRCPKGDEST STRIP_STATIC PKGDEST SRCDEST SRCPKGDEST LOGDEST PACKAGER GPGKEY
LOGDEST PACKAGER GPGKEY PKGEXT SRCEXT) PKGEXT SRCEXT)
local i keys ret=0 local i keys ret=0

View File

@@ -28,7 +28,7 @@ source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/util/schema.sh" source "$LIBRARY/util/schema.sh"
lint_pkgbuild_functions+=('lint_variable') lint_pkgbuild_functions+=('lint_variable')
lint_pkgbuild_functions+=('lint_array')
lint_variable() { lint_variable() {
local i a pkg out bad ret=0 local i a pkg out bad ret=0
@@ -95,3 +95,21 @@ lint_variable() {
return $ret return $ret
} }
lint_array() {
local i var ret=0
for i in ${pkgbuild_schema_arrays[@]}; do
local l=()
get_pkgbuild_all_split_attributes $i l
for var in "${l[@]}"; do
if [[ -z $var ]]; then
error "$(gettext "%s does not allow empty values.")" "$i"
ret=1
fi
done
done
return $ret
}

View File

@@ -109,3 +109,29 @@ extract_bzr() {
popd &>/dev/null popd &>/dev/null
} }
calc_checksum_bzr() {
local netfile=$1 integ=$2 ret=0 shellopts dir url fragment fragval sum
# this function requires pipefail - save current status to restore later
shellopts=$(shopt -p -o pipefail)
shopt -s -o pipefail
dir=$(get_filepath "$netfile")
url=$(get_url "$netfile")
fragment=$(get_uri_fragment "$url")
case ${fragment%%=*} in
revision)
fragval=${fragment##*=}
sum=$(bzr export --directory "$dir" --format tar --revision "$fragval" - | "${integ}sum" 2>&1) || ret=1
sum="${sum%% *}"
;;
*)
sum="SKIP"
esac
eval "$shellopts"
printf '%s' "$sum"
return $ret
}

View File

@@ -151,3 +151,18 @@ extract_file() {
chown -R 0:0 "$srcdir" chown -R 0:0 "$srcdir"
fi fi
} }
calc_checksum_file() {
local netfile=$1 integ=$2 ret=0 file sum
if ! file="$(get_filepath "$netfile")"; then
printf '%s\n' "$(gettext "NOT FOUND")" >&2
return 1
fi
sum="$("${integ}sum" "$file")" || ret=1
sum="${sum%% *}"
printf '%s' "$sum"
return $ret
}

View File

@@ -48,7 +48,7 @@ download_git() {
if [[ ! -d "$dir" ]] || dir_is_empty "$dir" ; then if [[ ! -d "$dir" ]] || dir_is_empty "$dir" ; then
msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "git" msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "git"
if ! git clone ${GITFLAGS:---mirror} "$url" "$dir"; then if ! git clone --origin=origin ${GITFLAGS:---mirror} "$url" "$dir"; then
error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "git" error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "git"
plainerr "$(gettext "Aborting...")" plainerr "$(gettext "Aborting...")"
exit 1 exit 1
@@ -91,7 +91,7 @@ extract_git() {
exit 1 exit 1
fi fi
cd_safe "$srcdir" cd_safe "$srcdir"
elif ! git clone -s "$dir" "${dir##*/}"; then elif ! git clone --origin=origin -s "$dir" "${dir##*/}"; then
error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git" error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "git"
plainerr "$(gettext "Aborting...")" plainerr "$(gettext "Aborting...")"
exit 1 exit 1
@@ -134,3 +134,30 @@ extract_git() {
popd &>/dev/null popd &>/dev/null
} }
calc_checksum_git() {
local netfile=$1 integ=$2 ret=0 shellopts dir url fragment sum
# this function requires pipefail - save current status to restore later
shellopts=$(shopt -p -o pipefail)
shopt -s -o pipefail
dir=$(get_filepath "$netfile")
url=$(get_url "$netfile")
fragment=$(get_uri_fragment "$url")
case ${fragment%%=*} in
tag|commit)
fragval=${fragment##*=}
sum=$(git -c core.abbrev=no -C "$dir" archive --format tar "$fragval" | "${integ}sum" 2>&1) || ret=1
sum="${sum%% *}"
;;
*)
sum="SKIP"
;;
esac
eval "$shellopts"
printf '%s' "$sum"
return $ret
}

View File

@@ -111,3 +111,30 @@ extract_hg() {
popd &>/dev/null popd &>/dev/null
} }
calc_checksum_hg() {
local netfile=$1 integ=$2 ret=0 shellopts dir url fragment fragval sum
# this function requires pipefail - save current status to restore later
shellopts=$(shopt -p -o pipefail)
shopt -s -o pipefail
dir=$(get_filepath "$netfile")
url=$(get_url "$netfile")
fragment=$(get_uri_fragment "$url")
case ${fragment%%=*} in
tag|revision)
fragval=${fragment##*=}
sum=$(hg --repository "$dir" archive --type tar --rev "$fragval" - | "${integ}sum" 2>&1) || ret=1
sum="${sum%% *}"
;;
*)
sum="SKIP"
;;
esac
eval "$shellopts"
printf '%s' "$sum"
return $ret
}

View File

@@ -152,7 +152,7 @@ tidy_strip() {
fi fi
local binary strip_flags local binary strip_flags
find . -type f -perm -u+w -print0 2>/dev/null | while IFS= read -rd '' binary ; do find . -type f -perm -u+w -print0 2>/dev/null | LC_ALL=C sort -z | while IFS= read -rd '' binary ; do
local STRIPLTO=0 local STRIPLTO=0
case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in
*Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries *Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries

View File

@@ -37,6 +37,11 @@ source_makepkg_config() {
# Source the config file; fail if it is not found # Source the config file; fail if it is not found
if [[ -r $MAKEPKG_CONF ]]; then if [[ -r $MAKEPKG_CONF ]]; then
source_safe "$MAKEPKG_CONF" source_safe "$MAKEPKG_CONF"
if [[ -d "$MAKEPKG_CONF.d" ]]; then
for c in "$MAKEPKG_CONF.d"/*.conf; do
source_safe $c
done
fi
else else
error "$(gettext "%s not found.")" "$MAKEPKG_CONF" error "$(gettext "%s not found.")" "$MAKEPKG_CONF"
plainerr "$(gettext "Aborting...")" plainerr "$(gettext "Aborting...")"

View File

@@ -43,7 +43,6 @@ unset GREP_OPTIONS
declare -r makepkg_version='@PACKAGE_VERSION@' declare -r makepkg_version='@PACKAGE_VERSION@'
declare -r confdir='@sysconfdir@' declare -r confdir='@sysconfdir@'
declare -r BUILDSCRIPT='@BUILDSCRIPT@' declare -r BUILDSCRIPT='@BUILDSCRIPT@'
declare -r startdir="$(pwd -P)"
LIBRARY=${LIBRARY:-'@libmakepkgdir@'} LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
@@ -51,6 +50,7 @@ LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
ASDEPS=0 ASDEPS=0
BUILDFUNC=0 BUILDFUNC=0
BUILDPKG=1 BUILDPKG=1
CHDIR=''
CHECKFUNC=0 CHECKFUNC=0
CLEANBUILD=0 CLEANBUILD=0
CLEANUP=0 CLEANUP=0
@@ -939,8 +939,8 @@ fi
ARGLIST=("$@") ARGLIST=("$@")
# Parse Command Line Options. # Parse Command Line Options.
OPT_SHORT="AcCdefFghiLmop:rRsSV" OPT_SHORT="AcCdD:efFghiLmop:rRsSV"
OPT_LONG=('allsource' 'check' 'clean' 'cleanbuild' 'config:' 'force' 'geninteg' OPT_LONG=('allsource' 'check' 'clean' 'cleanbuild' 'config:' 'dir:' 'force' 'geninteg'
'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'noarchive' 'nobuild' 'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'noarchive' 'nobuild'
'nocolor' 'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'packagelist' 'nocolor' 'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'packagelist'
'printsrcinfo' 'repackage' 'rmdeps' 'sign' 'skipchecksums' 'skipinteg' 'printsrcinfo' 'repackage' 'rmdeps' 'sign' 'skipchecksums' 'skipinteg'
@@ -971,6 +971,7 @@ while true; do
--check) RUN_CHECK='y' ;; --check) RUN_CHECK='y' ;;
--config) shift; MAKEPKG_CONF=$1 ;; --config) shift; MAKEPKG_CONF=$1 ;;
-d|--nodeps) NODEPS=1 ;; -d|--nodeps) NODEPS=1 ;;
-D|--dir) shift; CHDIR=$1 ;;
-e|--noextract) NOEXTRACT=1 ;; -e|--noextract) NOEXTRACT=1 ;;
-f|--force) FORCE=1 ;; -f|--force) FORCE=1 ;;
-F) INFAKEROOT=1 ;; -F) INFAKEROOT=1 ;;
@@ -1017,6 +1018,12 @@ while [[ $1 ]]; do
shift shift
done done
if [[ -n $CHDIR ]]; then
cd_safe "$CHDIR"
fi
declare -r startdir="$(pwd -P)"
# setup signal traps # setup signal traps
trap 'clean_up' 0 trap 'clean_up' 0
for signal in TERM HUP QUIT; do for signal in TERM HUP QUIT; do
@@ -1158,7 +1165,7 @@ if (( GENINTEG )); then
mkdir -p "$srcdir" mkdir -p "$srcdir"
chmod a-s "$srcdir" chmod a-s "$srcdir"
cd_safe "$srcdir" cd_safe "$srcdir"
download_sources novcs allarch >&2 download_sources allarch >&2
generate_checksums generate_checksums
exit $E_OK exit $E_OK
fi fi
@@ -1262,7 +1269,7 @@ if (( SOURCEONLY )); then
download_sources allarch download_sources allarch
elif ( (( ! SKIPCHECKSUMS )) || \ elif ( (( ! SKIPCHECKSUMS )) || \
( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then
download_sources allarch novcs download_sources allarch
fi fi
check_source_integrity all check_source_integrity all
cd_safe "$startdir" cd_safe "$startdir"

View File

@@ -84,6 +84,8 @@ usage() {
'%s')")\n" "@sysconfdir@/pacman.conf" '%s')")\n" "@sysconfdir@/pacman.conf"
printf -- "$(gettext " --gpgdir <dir> Set an alternate directory for GnuPG (instead\n\ printf -- "$(gettext " --gpgdir <dir> Set an alternate directory for GnuPG (instead\n\
of '%s')")\n" "@sysconfdir@/pacman.d/gnupg" of '%s')")\n" "@sysconfdir@/pacman.d/gnupg"
printf -- "$(gettext " --populate-from <dir> Set an alternate directory for --populate (instead\n\
of '%s')")\n" "@keyringdir@"
printf -- "$(gettext " --keyserver <server-url> Specify a keyserver to use if necessary")\n" printf -- "$(gettext " --keyserver <server-url> Specify a keyserver to use if necessary")\n"
echo echo
printf -- "$(gettext " -h, --help Show this help message and exit")\n" printf -- "$(gettext " -h, --help Show this help message and exit")\n"
@@ -283,7 +285,6 @@ check_keyring() {
} }
populate_keyring() { populate_keyring() {
local KEYRING_IMPORT_DIR='@keyringdir@'
local keyring KEYRINGIDS=("$@") local keyring KEYRINGIDS=("$@")
local ret=0 local ret=0
@@ -378,7 +379,7 @@ populate_keyring() {
key_count=$((key_count+1)) key_count=$((key_count+1))
done done
if (( key_count )); then if (( key_count )); then
msg2 "$(gettext "Disabled %s keys.")" "${key_count}" msg2 "$(ngettext "Disabled %s key." "Disabled %s keys." "${key_count}")" "${key_count}"
fi fi
fi fi
} }
@@ -506,7 +507,7 @@ lsign_keys() {
exit 1 exit 1
fi fi
if (( key_count )); then if (( key_count )); then
msg2 "$(gettext "Locally signed %s keys.")" "${key_count}" msg2 "$(ngettext "Locally signed %s key." "Locally signed %s keys." "${key_count}")" "${key_count}"
fi fi
} }
@@ -612,10 +613,20 @@ if ! type gettext &>/dev/null; then
} }
fi fi
if ! type ngettext &>/dev/null; then
ngettext() {
if (( $3 == 1 )); then
echo "$1"
else
echo "$2"
fi
}
fi
OPT_SHORT="adefhlruvV" OPT_SHORT="adefhlruvV"
OPT_LONG=('add' 'config:' 'delete' 'edit-key' 'export' 'finger' 'gpgdir:' OPT_LONG=('add' 'config:' 'delete' 'edit-key' 'export' 'finger' 'gpgdir:'
'help' 'import' 'import-trustdb' 'init' 'keyserver:' 'list-keys' 'list-sigs' 'help' 'import' 'import-trustdb' 'init' 'keyserver:' 'list-keys' 'list-sigs'
'lsign-key' 'nocolor' 'populate' 'recv-keys' 'refresh-keys' 'updatedb' 'lsign-key' 'nocolor' 'populate' 'populate-from:' 'recv-keys' 'refresh-keys' 'updatedb'
'verbose' 'verify' 'version') 'verbose' 'verify' 'version')
if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
exit 1 # E_INVALID_OPTION exit 1 # E_INVALID_OPTION
@@ -637,6 +648,7 @@ while (( $# )); do
-e|--export) EXPORT=1 ;; -e|--export) EXPORT=1 ;;
-f|--finger) FINGER=1 ;; -f|--finger) FINGER=1 ;;
--gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;; --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;;
--populate-from) shift; KEYRING_IMPORT_DIR=$1 ;;
--import) IMPORT=1 UPDATEDB=1 ;; --import) IMPORT=1 UPDATEDB=1 ;;
--import-trustdb) IMPORT_TRUSTDB=1 UPDATEDB=1 ;; --import-trustdb) IMPORT_TRUSTDB=1 UPDATEDB=1 ;;
--init) INIT=1 ;; --init) INIT=1 ;;
@@ -683,6 +695,8 @@ if [[ ! -r "${CONFIG}" ]]; then
exit 1 exit 1
fi fi
KEYRING_IMPORT_DIR=${KEYRING_IMPORT_DIR:-"@keyringdir@"}
# if PACMAN_KEYRING_DIR isn't assigned, try to get it from the config # if PACMAN_KEYRING_DIR isn't assigned, try to get it from the config
# file, falling back on a hard default # file, falling back on a hard default
PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-$(pacman-conf --config="$CONFIG" gpgdir)} PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-$(pacman-conf --config="$CONFIG" gpgdir)}

View File

@@ -584,9 +584,9 @@ if [[ $cmd != "repo-add" && $cmd != "repo-remove" ]]; then
exit 1 exit 1
fi fi
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/repo-tools.XXXXXXXXXX") || (\ tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/repo-tools.XXXXXXXXXX") || {
error "$(gettext "Cannot create temp directory for database building.")"; \ error "$(gettext "Cannot create temp directory for database building.")";
exit 1) exit 1; }
for repo in "db" "files"; do for repo in "db" "files"; do
mkdir "$tmpdir/$repo" mkdir "$tmpdir/$repo"

View File

@@ -423,6 +423,8 @@ void cb_event(void *ctx, alpm_event_t *event)
void cb_question(void *ctx, alpm_question_t *question) void cb_question(void *ctx, alpm_question_t *question)
{ {
(void)ctx; (void)ctx;
const colstr_t *colstr = &config->colstr;
if(config->print) { if(config->print) {
switch(question->type) { switch(question->type) {
case ALPM_QUESTION_INSTALL_IGNOREPKG: case ALPM_QUESTION_INSTALL_IGNOREPKG:
@@ -460,18 +462,30 @@ void cb_question(void *ctx, alpm_question_t *question)
{ {
alpm_question_conflict_t *q = &question->conflict; alpm_question_conflict_t *q = &question->conflict;
/* print conflict only if it contains new information */ /* print conflict only if it contains new information */
if(strcmp(q->conflict->package1, q->conflict->reason->name) == 0 if(strcmp(alpm_pkg_get_name(q->conflict->package1), q->conflict->reason->name) == 0
|| strcmp(q->conflict->package2, q->conflict->reason->name) == 0) { || strcmp(alpm_pkg_get_name(q->conflict->package2), q->conflict->reason->name) == 0) {
q->remove = noyes(_("%s and %s are in conflict. Remove %s?"), q->remove = noyes(_("%s-%s%s%s and %s-%s%s%s are in conflict. Remove %s?"),
q->conflict->package1, alpm_pkg_get_name(q->conflict->package1),
q->conflict->package2, colstr->faint,
q->conflict->package2); alpm_pkg_get_version(q->conflict->package1),
colstr->nocolor,
alpm_pkg_get_name(q->conflict->package2),
colstr->faint,
alpm_pkg_get_version(q->conflict->package2),
colstr->nocolor,
alpm_pkg_get_name(q->conflict->package2));
} else { } else {
q->remove = noyes(_("%s and %s are in conflict (%s). Remove %s?"), q->remove = noyes(_("%s-%s%s%s and %s-%s%s%s are in conflict (%s). Remove %s?"),
q->conflict->package1, alpm_pkg_get_name(q->conflict->package1),
q->conflict->package2, colstr->faint,
alpm_pkg_get_version(q->conflict->package1),
colstr->nocolor,
alpm_pkg_get_name(q->conflict->package2),
colstr->faint,
alpm_pkg_get_version(q->conflict->package2),
colstr->nocolor,
q->conflict->reason->name, q->conflict->reason->name,
q->conflict->package2); alpm_pkg_get_name(q->conflict->package2));
} }
} }
break; break;

View File

@@ -217,22 +217,6 @@ static int check_file_cksum(const char *pkgname, const char *filepath,
} }
#endif #endif
static int check_file_md5sum(const char *pkgname, const char *filepath,
struct archive_entry *entry, int backup)
{
int errors = 0;
#if ARCHIVE_VERSION_NUMBER >= 3005000
char *cksum_calc = alpm_compute_md5sum(filepath);
char *cksum_mtree = hex_representation(archive_entry_digest(entry,
ARCHIVE_ENTRY_DIGEST_MD5), 16);
errors = check_file_cksum(pkgname, filepath, backup, "MD5", cksum_calc,
cksum_mtree);
free(cksum_mtree);
free(cksum_calc);
#endif
return (errors != 0 ? 1 : 0);
}
static int check_file_sha256sum(const char *pkgname, const char *filepath, static int check_file_sha256sum(const char *pkgname, const char *filepath,
struct archive_entry *entry, int backup) struct archive_entry *entry, int backup)
{ {
@@ -428,7 +412,6 @@ int check_pkg_full(alpm_pkg_t *pkg)
if(type == AE_IFREG) { if(type == AE_IFREG) {
file_errors += check_file_size(pkgname, filepath, &st, entry, backup); file_errors += check_file_size(pkgname, filepath, &st, entry, backup);
file_errors += check_file_md5sum(pkgname, filepath, entry, backup);
file_errors += check_file_sha256sum(pkgname, filepath, entry, backup); file_errors += check_file_sha256sum(pkgname, filepath, entry, backup);
} }

View File

@@ -105,7 +105,7 @@ config_t *config_new(void)
return NULL; return NULL;
} }
/* defaults which may get overridden later */ /* defaults which may get overridden later */
newconfig->op = PM_OP_MAIN; newconfig->op = PM_OP_NONE;
newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING; newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING;
newconfig->configfile = strdup(CONFFILE); newconfig->configfile = strdup(CONFFILE);
if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) { if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) {
@@ -131,6 +131,13 @@ config_t *config_new(void)
return newconfig; return newconfig;
} }
void targets_free(targets_t *targets) {
FREELIST(targets->targets);
FREELIST(targets->sync);
FREELIST(targets->upgrade);
FREELIST(targets->remove);
}
int config_free(config_t *oldconfig) int config_free(config_t *oldconfig)
{ {
if(oldconfig == NULL) { if(oldconfig == NULL) {
@@ -1136,15 +1143,22 @@ int setdefaults(config_t *c)
#define SETDEFAULT(opt, val) if(!opt) { opt = val; if(!opt) { return -1; } } #define SETDEFAULT(opt, val) if(!opt) { opt = val; if(!opt) { return -1; } }
if(c->rootdir) { if(c->rootdir) {
char* rootdir = strdup(c->rootdir);
int rootdir_len = strlen(rootdir);
/* This removes trailing slashes from the root directory */
if(rootdir[rootdir_len-1] == '/'){
rootdir[rootdir_len-1] = '\0';
}
char path[PATH_MAX]; char path[PATH_MAX];
if(!c->dbpath) { if(!c->dbpath) {
snprintf(path, PATH_MAX, "%s/%s", c->rootdir, &DBPATH[1]); snprintf(path, PATH_MAX, "%s/%s", rootdir, &DBPATH[1]);
SETDEFAULT(c->dbpath, strdup(path)); SETDEFAULT(c->dbpath, strdup(path));
} }
if(!c->logfile) { if(!c->logfile) {
snprintf(path, PATH_MAX, "%s/%s", c->rootdir, &LOGFILE[1]); snprintf(path, PATH_MAX, "%s/%s", rootdir, &LOGFILE[1]);
SETDEFAULT(c->logfile, strdup(path)); SETDEFAULT(c->logfile, strdup(path));
} }
free(rootdir);
} else { } else {
SETDEFAULT(c->rootdir, strdup(ROOTDIR)); SETDEFAULT(c->rootdir, strdup(ROOTDIR));
SETDEFAULT(c->dbpath, strdup(DBPATH)); SETDEFAULT(c->dbpath, strdup(DBPATH));

View File

@@ -43,6 +43,14 @@ typedef struct __config_repo_t {
int siglevel_mask; int siglevel_mask;
} config_repo_t; } config_repo_t;
typedef struct __targets_t {
alpm_list_t *targets;
alpm_list_t *sync;
alpm_list_t *upgrade;
alpm_list_t *remove;
} targets_t;
typedef struct __config_t { typedef struct __config_t {
unsigned short op; unsigned short op;
unsigned short quiet; unsigned short quiet;
@@ -142,14 +150,15 @@ typedef struct __config_t {
/* Operations */ /* Operations */
enum { enum {
PM_OP_MAIN = 1, PM_OP_NONE = 0,
PM_OP_REMOVE, PM_OP_INVALID = (1 << 0),
PM_OP_UPGRADE, PM_OP_REMOVE = (1 << 1),
PM_OP_QUERY, PM_OP_UPGRADE = (1 << 2),
PM_OP_SYNC, PM_OP_QUERY = (1 << 3),
PM_OP_DEPTEST, PM_OP_SYNC = (1 << 4),
PM_OP_DATABASE, PM_OP_DEPTEST = (1 << 5),
PM_OP_FILES PM_OP_DATABASE = (1 << 6),
PM_OP_FILES = (1 << 7)
}; };
/* Long Operations */ /* Long Operations */
@@ -235,6 +244,9 @@ enum {
/* global config variable */ /* global config variable */
extern config_t *config; extern config_t *config;
void targets_free(targets_t *targets);
void enable_colors(int colors); void enable_colors(int colors);
config_t *config_new(void); config_t *config_new(void);
int config_free(config_t *oldconfig); int config_free(config_t *oldconfig);

View File

@@ -157,7 +157,7 @@ static int check_db_local_package_conflicts(alpm_list_t *pkglist)
for(i = data; i; i = i->next) { for(i = data; i; i = i->next) {
alpm_conflict_t *conflict = i->data; alpm_conflict_t *conflict = i->data;
pm_printf(ALPM_LOG_ERROR, "'%s' conflicts with '%s'\n", pm_printf(ALPM_LOG_ERROR, "'%s' conflicts with '%s'\n",
conflict->package1, conflict->package2); alpm_pkg_get_name(conflict->package1), alpm_pkg_get_name(conflict->package2));
ret++; ret++;
} }
alpm_list_free_inner(data, (alpm_list_fn_free)alpm_conflict_free); alpm_list_free_inner(data, (alpm_list_fn_free)alpm_conflict_free);

View File

@@ -10,6 +10,7 @@ pacman_sources = files('''
remove.c remove.c
sighandler.h sighandler.c sighandler.h sighandler.c
sync.c sync.c
trans.c
callback.h callback.c callback.h callback.c
upgrade.c upgrade.c
util.h util.c util.h util.c

View File

@@ -104,7 +104,7 @@ static void usage(int op, const char * const myname)
char const *const str_opr = _("operation"); char const *const str_opr = _("operation");
/* please limit your strings to 80 characters in width */ /* please limit your strings to 80 characters in width */
if(op == PM_OP_MAIN) { if(op == PM_OP_NONE) {
printf("%s: %s <%s> [...]\n", str_usg, myname, str_opr); printf("%s: %s <%s> [...]\n", str_usg, myname, str_opr);
printf(_("operations:\n")); printf(_("operations:\n"));
printf(" %s {-h --help}\n", myname); printf(" %s {-h --help}\n", myname);
@@ -338,25 +338,25 @@ static int parsearg_op(int opt, int dryrun)
/* operations */ /* operations */
case 'D': case 'D':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DATABASE); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_DATABASE); break;
case 'F': case 'F':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_FILES); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_FILES); break;
case 'Q': case 'Q':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_QUERY); break;
case 'R': case 'R':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_REMOVE); break;
case 'S': case 'S':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_SYNC); break;
case 'T': case 'T':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DEPTEST); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_DEPTEST); break;
case 'U': case 'U':
if(dryrun) break; if(dryrun) break;
config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_UPGRADE); break; config->op = (config->op != PM_OP_NONE ? PM_OP_INVALID : PM_OP_UPGRADE); break;
case 'V': case 'V':
if(dryrun) break; if(dryrun) break;
config->version = 1; break; config->version = 1; break;
@@ -962,7 +962,7 @@ static int parseargs(int argc, char *argv[])
parsearg_op(opt, 0); parsearg_op(opt, 0);
} }
if(config->op == 0) { if(config->op == PM_OP_INVALID) {
pm_printf(ALPM_LOG_ERROR, _("only one operation may be used at a time\n")); pm_printf(ALPM_LOG_ERROR, _("only one operation may be used at a time\n"));
return 1; return 1;
} }
@@ -1088,6 +1088,7 @@ int main(int argc, char *argv[])
{ {
int ret = 0; int ret = 0;
uid_t myuid = getuid(); uid_t myuid = getuid();
targets_t targets = {0};
console_cursor_hide(); console_cursor_hide();
install_segv_handler(); install_segv_handler();
@@ -1246,24 +1247,27 @@ int main(int argc, char *argv[])
case PM_OP_DATABASE: case PM_OP_DATABASE:
ret = pacman_database(pm_targets); ret = pacman_database(pm_targets);
break; break;
case PM_OP_REMOVE:
ret = pacman_remove(pm_targets);
break;
case PM_OP_UPGRADE:
ret = pacman_upgrade(pm_targets);
break;
case PM_OP_QUERY: case PM_OP_QUERY:
ret = pacman_query(pm_targets); ret = pacman_query(pm_targets);
break; break;
case PM_OP_SYNC:
ret = pacman_sync(pm_targets);
break;
case PM_OP_DEPTEST: case PM_OP_DEPTEST:
ret = pacman_deptest(pm_targets); ret = pacman_deptest(pm_targets);
break; break;
case PM_OP_FILES: case PM_OP_FILES:
ret = pacman_files(pm_targets); ret = pacman_files(pm_targets);
break; break;
case PM_OP_SYNC:
targets.sync = pm_targets;
ret = do_transaction(&targets);
break;
case PM_OP_UPGRADE:
targets.upgrade = pm_targets;
ret = do_transaction(&targets);
break;
case PM_OP_REMOVE:
targets.remove = pm_targets;
ret = do_transaction(&targets);
break;
default: default:
pm_printf(ALPM_LOG_ERROR, _("no operation specified (use -h for help)\n")); pm_printf(ALPM_LOG_ERROR, _("no operation specified (use -h for help)\n"));
ret = EXIT_FAILURE; ret = EXIT_FAILURE;

View File

@@ -22,6 +22,8 @@
#include <alpm_list.h> #include <alpm_list.h>
#include "conf.h"
#define PACMAN_CALLER_PREFIX "PACMAN" #define PACMAN_CALLER_PREFIX "PACMAN"
/* database.c */ /* database.c */
@@ -32,12 +34,14 @@ int pacman_deptest(alpm_list_t *targets);
int pacman_files(alpm_list_t *files); int pacman_files(alpm_list_t *files);
/* query.c */ /* query.c */
int pacman_query(alpm_list_t *targets); int pacman_query(alpm_list_t *targets);
/* remove.c */
int pacman_remove(alpm_list_t *targets);
/* sync.c */ /* sync.c */
int pacman_sync(alpm_list_t *targets); int pacman_sync(alpm_list_t *targets);
int sync_prepare_execute(void); /* remove.c */
int load_remove(alpm_list_t *targets);
/* upgrade.c */ /* upgrade.c */
int pacman_upgrade(alpm_list_t *targets); int load_upgrade(alpm_list_t *targets);
/* trans.c */
int do_transaction(targets_t *targets);
#endif /* PM_PACMAN_H */ #endif /* PM_PACMAN_H */

View File

@@ -18,7 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <fnmatch.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@@ -30,11 +29,6 @@
#include "util.h" #include "util.h"
#include "conf.h" #include "conf.h"
static int fnmatch_cmp(const void *pattern, const void *string)
{
return fnmatch(pattern, string, 0);
}
static int remove_target(const char *target) static int remove_target(const char *target)
{ {
alpm_pkg_t *pkg; alpm_pkg_t *pkg;
@@ -69,28 +63,16 @@ static int remove_target(const char *target)
return 0; return 0;
} }
/** int load_remove(alpm_list_t *targets)
* @brief Remove a specified list of packages.
*
* @param targets a list of packages (as strings) to remove from the system
*
* @return 0 on success, 1 on failure
*/
int pacman_remove(alpm_list_t *targets)
{ {
int retval = 0; int retval = 0;
alpm_list_t *i, *data = NULL; alpm_list_t *i;
if(targets == NULL) { if(targets == NULL) {
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
return 1; return 1;
} }
/* Step 0: create a new transaction */
if(trans_init(config->flags, 0) == -1) {
return 1;
}
/* Step 1: add targets to the created transaction */ /* Step 1: add targets to the created transaction */
for(i = targets; i; i = alpm_list_next(i)) { for(i = targets; i; i = alpm_list_next(i)) {
char *target = i->data; char *target = i->data;
@@ -102,81 +84,6 @@ int pacman_remove(alpm_list_t *targets)
} }
} }
if(retval == 1) {
goto cleanup;
}
/* Step 2: prepare the transaction based on its type, targets and flags */
if(alpm_trans_prepare(config->handle, &data) == -1) {
alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
alpm_depmissing_t *miss = i->data;
char *depstring = alpm_dep_compute_string(miss->depend);
colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
miss->causingpkg, depstring, miss->target);
free(depstring);
alpm_depmissing_free(miss);
}
break;
default:
break;
}
alpm_list_free(data);
retval = 1;
goto cleanup;
}
/* Search for holdpkg in target list */
int holdpkg = 0;
for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
alpm_pkg_t *pkg = i->data;
if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
alpm_pkg_get_name(pkg));
holdpkg = 1;
}
}
if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
retval = 1;
goto cleanup;
}
/* Step 3: actually perform the removal */
alpm_list_t *pkglist = alpm_trans_get_remove(config->handle);
if(pkglist == NULL) {
printf(_(" there is nothing to do\n"));
goto cleanup; /* we are done */
}
if(config->print) {
print_packages(pkglist);
goto cleanup;
}
/* print targets and ask user confirmation */
display_targets();
printf("\n");
if(yesno(_("Do you want to remove these packages?")) == 0) {
retval = 1;
goto cleanup;
}
if(alpm_trans_commit(config->handle, &data) == -1) {
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
alpm_strerror(alpm_errno(config->handle)));
retval = 1;
}
FREELIST(data);
/* Step 4: release transaction resources */
cleanup:
if(trans_release() == -1) {
retval = 1;
}
return retval; return retval;
} }

View File

@@ -35,7 +35,6 @@
#include "pacman.h" #include "pacman.h"
#include "util.h" #include "util.h"
#include "package.h" #include "package.h"
#include "callback.h"
#include "conf.h" #include "conf.h"
static int unlink_verbose(const char *pathname, int ignore_missing) static int unlink_verbose(const char *pathname, int ignore_missing)
@@ -510,376 +509,6 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
return ret; return ret;
} }
static alpm_db_t *get_db(const char *dbname)
{
alpm_list_t *i;
for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
alpm_db_t *db = i->data;
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
return db;
}
}
return NULL;
}
static int process_pkg(alpm_pkg_t *pkg)
{
int ret = alpm_add_pkg(config->handle, pkg);
if(ret == -1) {
alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerror(err));
return 1;
}
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
return 0;
}
static int group_exists(alpm_list_t *dbs, const char *name)
{
alpm_list_t *i;
for(i = dbs; i; i = i->next) {
alpm_db_t *db = i->data;
if(alpm_db_get_group(db, name)) {
return 1;
}
}
return 0;
}
static int process_group(alpm_list_t *dbs, const char *group, int error)
{
int ret = 0;
alpm_list_t *i;
alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
int count = alpm_list_count(pkgs);
if(!count) {
if(group_exists(dbs, group)) {
return 0;
}
pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
return 1;
}
if(error) {
/* we already know another target errored. there is no reason to prompt the
* user here; we already validated the group name so just move on since we
* won't actually be installing anything anyway. */
goto cleanup;
}
if(config->print == 0) {
char *array = malloc(count);
int n = 0;
const colstr_t *colstr = &config->colstr;
colon_printf(_n("There is %d member in group %s%s%s:\n",
"There are %d members in group %s%s%s:\n", count),
count, colstr->groups, group, colstr->title);
select_display(pkgs);
if(!array) {
ret = 1;
goto cleanup;
}
if(multiselect_question(array, count)) {
ret = 1;
free(array);
goto cleanup;
}
for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
alpm_pkg_t *pkg = i->data;
if(array[n++] == 0) {
continue;
}
if(process_pkg(pkg) == 1) {
ret = 1;
free(array);
goto cleanup;
}
}
free(array);
} else {
for(i = pkgs; i; i = alpm_list_next(i)) {
alpm_pkg_t *pkg = i->data;
if(process_pkg(pkg) == 1) {
ret = 1;
goto cleanup;
}
}
}
cleanup:
alpm_list_free(pkgs);
return ret;
}
static int process_targname(alpm_list_t *dblist, const char *targname,
int error)
{
alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
/* skip ignored packages when user says no */
if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
return 0;
}
if(pkg) {
return process_pkg(pkg);
}
/* fallback on group */
return process_group(dblist, targname, error);
}
static int process_target(const char *target, int error)
{
/* process targets */
char *targstring = strdup(target);
char *targname = strchr(targstring, '/');
int ret = 0;
alpm_list_t *dblist;
if(targname && targname != targstring) {
alpm_db_t *db;
const char *dbname;
int usage;
*targname = '\0';
targname++;
dbname = targstring;
db = get_db(dbname);
if(!db) {
pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
dbname);
ret = 1;
goto cleanup;
}
/* explicitly mark this repo as valid for installs since
* a repo name was given with the target */
alpm_db_get_usage(db, &usage);
alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
dblist = alpm_list_add(NULL, db);
ret = process_targname(dblist, targname, error);
alpm_list_free(dblist);
/* restore old usage so we don't possibly disturb later
* targets */
alpm_db_set_usage(db, usage);
} else {
targname = targstring;
dblist = alpm_get_syncdbs(config->handle);
ret = process_targname(dblist, targname, error);
}
cleanup:
free(targstring);
if(ret && access(target, R_OK) == 0) {
pm_printf(ALPM_LOG_WARNING,
_("'%s' is a file, did you mean %s instead of %s?\n"),
target, "-U/--upgrade", "-S/--sync");
}
return ret;
}
static int sync_trans(alpm_list_t *targets)
{
int retval = 0;
alpm_list_t *i;
/* Step 1: create a new transaction... */
if(trans_init(config->flags, 1) == -1) {
return 1;
}
/* process targets */
for(i = targets; i; i = alpm_list_next(i)) {
const char *targ = i->data;
if(process_target(targ, retval) == 1) {
retval = 1;
}
}
if(retval) {
trans_release();
return retval;
}
if(config->op_s_upgrade) {
if(!config->print) {
colon_printf(_("Starting full system upgrade...\n"));
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
"starting full system upgrade\n");
}
if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
trans_release();
return 1;
}
}
return sync_prepare_execute();
}
static void print_broken_dep(alpm_depmissing_t *miss)
{
char *depstring = alpm_dep_compute_string(miss->depend);
alpm_list_t *trans_add = alpm_trans_get_add(config->handle);
alpm_pkg_t *pkg;
if(miss->causingpkg == NULL) {
/* package being installed/upgraded has unresolved dependency */
colon_printf(_("unable to satisfy dependency '%s' required by %s\n"),
depstring, miss->target);
} else if((pkg = alpm_pkg_find(trans_add, miss->causingpkg))) {
/* upgrading a package breaks a local dependency */
colon_printf(_("installing %s (%s) breaks dependency '%s' required by %s\n"),
miss->causingpkg, alpm_pkg_get_version(pkg), depstring, miss->target);
} else {
/* removing a package breaks a local dependency */
colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
miss->causingpkg, depstring, miss->target);
}
free(depstring);
}
int sync_prepare_execute(void)
{
alpm_list_t *i, *packages, *data = NULL;
int retval = 0;
/* Step 2: "compute" the transaction based on targets and flags */
if(alpm_trans_prepare(config->handle, &data) == -1) {
alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_PKG_INVALID_ARCH:
for(i = data; i; i = alpm_list_next(i)) {
char *pkg = i->data;
colon_printf(_("package %s does not have a valid architecture\n"), pkg);
free(pkg);
}
break;
case ALPM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
print_broken_dep(i->data);
alpm_depmissing_free(i->data);
}
break;
case ALPM_ERR_CONFLICTING_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
alpm_conflict_t *conflict = i->data;
/* only print reason if it contains new information */
if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
colon_printf(_("%s and %s are in conflict\n"),
conflict->package1, conflict->package2);
} else {
char *reason = alpm_dep_compute_string(conflict->reason);
colon_printf(_("%s and %s are in conflict (%s)\n"),
conflict->package1, conflict->package2, reason);
free(reason);
}
alpm_conflict_free(conflict);
}
break;
default:
break;
}
retval = 1;
goto cleanup;
}
packages = alpm_trans_get_add(config->handle);
if(packages == NULL) {
/* nothing to do: just exit without complaining */
if(!config->print) {
printf(_(" there is nothing to do\n"));
}
goto cleanup;
}
/* Step 3: actually perform the operation */
if(config->print) {
print_packages(packages);
goto cleanup;
}
display_targets();
printf("\n");
int confirm;
if(config->op_s_downloadonly) {
confirm = yesno(_("Proceed with download?"));
} else {
confirm = yesno(_("Proceed with installation?"));
}
if(!confirm) {
retval = 1;
goto cleanup;
}
multibar_move_completed_up(true);
if(alpm_trans_commit(config->handle, &data) == -1) {
alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_FILE_CONFLICTS:
for(i = data; i; i = alpm_list_next(i)) {
alpm_fileconflict_t *conflict = i->data;
switch(conflict->type) {
case ALPM_FILECONFLICT_TARGET:
fprintf(stderr, _("%s exists in both '%s' and '%s'\n"),
conflict->file, conflict->target, conflict->ctarget);
break;
case ALPM_FILECONFLICT_FILESYSTEM:
if(conflict->ctarget[0]) {
fprintf(stderr, _("%s: %s exists in filesystem (owned by %s)\n"),
conflict->target, conflict->file, conflict->ctarget);
} else {
fprintf(stderr, _("%s: %s exists in filesystem\n"),
conflict->target, conflict->file);
}
break;
}
alpm_fileconflict_free(conflict);
}
break;
case ALPM_ERR_PKG_INVALID:
case ALPM_ERR_PKG_INVALID_CHECKSUM:
case ALPM_ERR_PKG_INVALID_SIG:
for(i = data; i; i = alpm_list_next(i)) {
char *filename = i->data;
fprintf(stderr, _("%s is invalid or corrupted\n"), filename);
free(filename);
}
break;
default:
break;
}
/* TODO: stderr? */
printf(_("Errors occurred, no packages were upgraded.\n"));
retval = 1;
goto cleanup;
}
/* Step 4: release transaction resources */
cleanup:
alpm_list_free(data);
if(trans_release() == -1) {
retval = 1;
}
return retval;
}
int pacman_sync(alpm_list_t *targets) int pacman_sync(alpm_list_t *targets)
{ {
alpm_list_t *sync_dbs = NULL; alpm_list_t *sync_dbs = NULL;
@@ -902,26 +531,8 @@ int pacman_sync(alpm_list_t *targets)
return ret; return ret;
} }
if(check_syncdbs(1, 0)) {
return 1;
}
sync_dbs = alpm_get_syncdbs(config->handle); sync_dbs = alpm_get_syncdbs(config->handle);
if(config->op_s_sync) {
/* grab a fresh package list */
colon_printf(_("Synchronizing package databases...\n"));
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
"synchronizing package lists\n");
if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
return 1;
}
}
if(check_syncdbs(1, 1)) {
return 1;
}
/* search for a package */ /* search for a package */
if(config->op_s_search) { if(config->op_s_search) {
return sync_search(sync_dbs, targets); return sync_search(sync_dbs, targets);
@@ -943,17 +554,9 @@ int pacman_sync(alpm_list_t *targets)
} }
if(targets == NULL) { if(targets == NULL) {
if(config->op_s_upgrade) {
/* proceed */
} else if(config->op_s_sync) {
return 0;
} else {
/* don't proceed here unless we have an operation that doesn't require a
* target list */
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
return 1; return 1;
} }
}
return sync_trans(targets); return 0;
} }

499
src/pacman/trans.c Normal file
View File

@@ -0,0 +1,499 @@
/*
* trans.c
*
* Copyright (c) 2006-2021 Pacman Development Team <pacman-dev(a)archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet(a)zeroflux.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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fnmatch.h>
#include <alpm.h>
#include <alpm_list.h>
/* pacman */
#include "pacman.h"
#include "callback.h"
#include "conf.h"
#include "util.h"
static int fnmatch_cmp(const void *pattern, const void *string)
{
return fnmatch(pattern, string, 0);
}
static void print_broken_dep(alpm_depmissing_t *miss)
{
char *depstring = alpm_dep_compute_string(miss->depend);
alpm_list_t *trans_add = alpm_trans_get_add(config->handle);
alpm_pkg_t *pkg;
if(miss->causingpkg == NULL) {
/* package being installed/upgraded has unresolved dependency */
colon_printf(_("unable to satisfy dependency '%s' required by %s\n"),
depstring, miss->target);
} else if((pkg = alpm_pkg_find(trans_add, miss->causingpkg))) {
/* upgrading a package breaks a local dependency */
colon_printf(_("installing %s (%s) breaks dependency '%s' required by %s\n"),
miss->causingpkg, alpm_pkg_get_version(pkg), depstring, miss->target);
} else {
/* removing a package breaks a local dependency */
colon_printf(_("removing %s breaks dependency '%s' required by %s\n"),
miss->causingpkg, depstring, miss->target);
}
free(depstring);
}
static void handle_trans_prepare_error(alpm_list_t *data)
{
alpm_errno_t err = alpm_errno(config->handle);
alpm_list_t *i;
pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_PKG_INVALID_ARCH:
for(i = data; i; i = alpm_list_next(i)) {
char *pkg = i->data;
colon_printf(_("package %s does not have a valid architecture\n"), pkg);
free(pkg);
}
break;
case ALPM_ERR_UNSATISFIED_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
print_broken_dep(i->data);
alpm_depmissing_free(i->data);
}
break;
case ALPM_ERR_CONFLICTING_DEPS:
for(i = data; i; i = alpm_list_next(i)) {
alpm_conflict_t *conflict = i->data;
/* only print reason if it contains new information */
if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
colon_printf(_("%s-%s and %s-%s are in conflict\n"),
alpm_pkg_get_name(conflict->package1),
alpm_pkg_get_version(conflict->package1),
alpm_pkg_get_name(conflict->package2),
alpm_pkg_get_version(conflict->package2));
} else {
char *reason = alpm_dep_compute_string(conflict->reason);
colon_printf(_("%s-%s and %s-%s are in conflict (%s)\n"),
alpm_pkg_get_name(conflict->package1),
alpm_pkg_get_version(conflict->package1),
alpm_pkg_get_name(conflict->package2),
alpm_pkg_get_version(conflict->package2),
reason);
free(reason);
}
alpm_conflict_free(conflict);
}
break;
default:
break;
}
}
static void handle_trans_commit_error(alpm_list_t *data) {
alpm_errno_t err = alpm_errno(config->handle);
alpm_list_t *i;
pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
alpm_strerror(err));
switch(err) {
case ALPM_ERR_FILE_CONFLICTS:
for(i = data; i; i = alpm_list_next(i)) {
alpm_fileconflict_t *conflict = i->data;
switch(conflict->type) {
case ALPM_FILECONFLICT_TARGET:
fprintf(stderr, _("%s exists in both '%s' and '%s'\n"),
conflict->file, conflict->target, conflict->ctarget);
break;
case ALPM_FILECONFLICT_FILESYSTEM:
if(conflict->ctarget[0]) {
fprintf(stderr, _("%s: %s exists in filesystem (owned by %s)\n"),
conflict->target, conflict->file, conflict->ctarget);
} else {
fprintf(stderr, _("%s: %s exists in filesystem\n"),
conflict->target, conflict->file);
}
break;
}
alpm_fileconflict_free(conflict);
}
break;
case ALPM_ERR_PKG_INVALID:
case ALPM_ERR_PKG_INVALID_CHECKSUM:
case ALPM_ERR_PKG_INVALID_SIG:
for(i = data; i; i = alpm_list_next(i)) {
char *filename = i->data;
fprintf(stderr, _("%s is invalid or corrupted\n"), filename);
free(filename);
}
break;
default:
break;
}
/* TODO: stderr? */
printf(_("Errors occurred, no packages were upgraded.\n"));
}
static int trans_prepare_execute(void)
{
alpm_list_t *i, *packages, *remove_packages, *data = NULL;
int retval = 0;
/* Step 2: "compute" the transaction based on targets and flags */
if(alpm_trans_prepare(config->handle, &data) == -1) {
handle_trans_prepare_error(data);
retval = 1;
goto cleanup;
}
packages = alpm_trans_get_add(config->handle);
remove_packages = alpm_trans_get_remove(config->handle);
if(packages == NULL && remove_packages == NULL) {
/* nothing to do: just exit without complaining */
if(!config->print) {
printf(_(" there is nothing to do\n"));
}
goto cleanup;
}
/* Search for holdpkg in target list */
int holdpkg = 0;
for(i = remove_packages; i; i = alpm_list_next(i)) {
alpm_pkg_t *pkg = i->data;
if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
alpm_pkg_get_name(pkg));
holdpkg = 1;
}
}
if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
retval = 1;
goto cleanup;
}
/* Step 3: actually perform the operation */
if(config->print) {
print_packages(packages);
print_packages(remove_packages);
goto cleanup;
}
display_targets();
printf("\n");
int confirm;
if(config->op_s_downloadonly) {
confirm = yesno(_("Proceed with download?"));
} else {
confirm = yesno(_("Proceed with installation?"));
}
if(!confirm) {
retval = 1;
goto cleanup;
}
multibar_move_completed_up(true);
if(alpm_trans_commit(config->handle, &data) == -1) {
handle_trans_commit_error(data);
retval = 1;
goto cleanup;
}
/* Step 4: release transaction resources */
cleanup:
alpm_list_free(data);
if(trans_release() == -1) {
retval = 1;
}
return retval;
}
static int group_exists(alpm_list_t *dbs, const char *name)
{
alpm_list_t *i;
for(i = dbs; i; i = i->next) {
alpm_db_t *db = i->data;
if(alpm_db_get_group(db, name)) {
return 1;
}
}
return 0;
}
static alpm_db_t *get_db(const char *dbname)
{
alpm_list_t *i;
for(i = alpm_get_syncdbs(config->handle); i; i = i->next) {
alpm_db_t *db = i->data;
if(strcmp(alpm_db_get_name(db), dbname) == 0) {
return db;
}
}
return NULL;
}
static int process_pkg(alpm_pkg_t *pkg)
{
int ret = alpm_add_pkg(config->handle, pkg);
if(ret == -1) {
alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerror(err));
return 1;
}
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
return 0;
}
static int process_group(alpm_list_t *dbs, const char *group, int error)
{
int ret = 0;
alpm_list_t *i;
alpm_list_t *pkgs = alpm_find_group_pkgs(dbs, group);
int count = alpm_list_count(pkgs);
if(!count) {
if(group_exists(dbs, group)) {
return 0;
}
pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), group);
return 1;
}
if(error) {
/* we already know another target errored. there is no reason to prompt the
* user here; we already validated the group name so just move on since we
* won't actually be installing anything anyway. */
goto cleanup;
}
if(config->print == 0) {
char *array = malloc(count);
int n = 0;
const colstr_t *colstr = &config->colstr;
colon_printf(_n("There is %d member in group %s%s%s:\n",
"There are %d members in group %s%s%s:\n", count),
count, colstr->groups, group, colstr->title);
select_display(pkgs);
if(!array) {
ret = 1;
goto cleanup;
}
if(multiselect_question(array, count)) {
ret = 1;
free(array);
goto cleanup;
}
for(i = pkgs, n = 0; i; i = alpm_list_next(i)) {
alpm_pkg_t *pkg = i->data;
if(array[n++] == 0) {
continue;
}
if(process_pkg(pkg) == 1) {
ret = 1;
free(array);
goto cleanup;
}
}
free(array);
} else {
for(i = pkgs; i; i = alpm_list_next(i)) {
alpm_pkg_t *pkg = i->data;
if(process_pkg(pkg) == 1) {
ret = 1;
goto cleanup;
}
}
}
cleanup:
alpm_list_free(pkgs);
return ret;
}
static int process_targname(alpm_list_t *dblist, const char *targname,
int error)
{
alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, targname);
/* skip ignored packages when user says no */
if(alpm_errno(config->handle) == ALPM_ERR_PKG_IGNORED) {
pm_printf(ALPM_LOG_WARNING, _("skipping target: %s\n"), targname);
return 0;
}
if(pkg) {
return process_pkg(pkg);
}
/* fallback on group */
return process_group(dblist, targname, error);
}
static int process_target(const char *target, int error)
{
/* process targets */
char *targstring = strdup(target);
char *targname = strchr(targstring, '/');
int ret = 0;
alpm_list_t *dblist;
if(targname && targname != targstring) {
alpm_db_t *db;
const char *dbname;
int usage;
*targname = '\0';
targname++;
dbname = targstring;
db = get_db(dbname);
if(!db) {
pm_printf(ALPM_LOG_ERROR, _("database not found: %s\n"),
dbname);
ret = 1;
goto cleanup;
}
/* explicitly mark this repo as valid for installs since
* a repo name was given with the target */
alpm_db_get_usage(db, &usage);
alpm_db_set_usage(db, usage|ALPM_DB_USAGE_INSTALL);
dblist = alpm_list_add(NULL, db);
ret = process_targname(dblist, targname, error);
alpm_list_free(dblist);
/* restore old usage so we don't possibly disturb later
* targets */
alpm_db_set_usage(db, usage);
} else {
targname = targstring;
dblist = alpm_get_syncdbs(config->handle);
ret = process_targname(dblist, targname, error);
}
cleanup:
free(targstring);
if(ret && access(target, R_OK) == 0) {
pm_printf(ALPM_LOG_WARNING,
_("'%s' is a file, did you mean %s instead of %s?\n"),
target, "-U/--upgrade", "-S/--sync");
}
return ret;
}
static int load_sync(alpm_list_t *targets)
{
int retval = 0;
alpm_list_t *i;
if(targets == NULL && !config->op_s_upgrade && !config->op_s_sync) {
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
return 1;
}
/* process targets */
for(i = targets; i; i = alpm_list_next(i)) {
const char *targ = i->data;
if(process_target(targ, retval) == 1) {
retval = 1;
}
}
return retval;
}
int do_transaction(targets_t *targets) {
int need_repos = (config->op & PM_OP_SYNC);
alpm_list_t *sync_dbs;
if(targets->targets != NULL) {
pm_printf(ALPM_LOG_ERROR, _("targets must come after operation\n"));
return 1;
}
if(check_syncdbs(need_repos, 0)) {
return 1;
}
sync_dbs = alpm_get_syncdbs(config->handle);
if(config->op_s_sync) {
/* grab a fresh package list */
colon_printf(_("Synchronizing package databases...\n"));
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
"synchronizing package lists\n");
if(!sync_syncdbs(config->op_s_sync, sync_dbs)) {
return 1;
}
}
if(check_syncdbs(need_repos, 1)) {
return 1;
}
if(config->op_s_clean || config->op_s_search || config->op_s_info
|| config->op_q_list || config->group) {
return pacman_sync(targets->sync);
}
/* Step 1: create a new transaction... */
if(trans_init(config->flags, 1) == -1) {
return 1;
}
if(config->op & PM_OP_SYNC && load_sync(targets->sync)) {
goto cleanup;
}
if(config->op & PM_OP_REMOVE && load_remove(targets->remove)) {
goto cleanup;
}
if(config->op & PM_OP_UPGRADE && load_upgrade(targets->upgrade)) {
goto cleanup;
}
if(config->op_s_upgrade) {
if(!config->print) {
colon_printf(_("Starting full system upgrade...\n"));
alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
"starting full system upgrade\n");
}
if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
trans_release();
return 1;
}
}
return trans_prepare_execute();
cleanup:
trans_release();
return 1;
}

View File

@@ -65,7 +65,7 @@ static int load_packages(alpm_list_t *targets, int siglevel)
* *
* @return 0 on success, 1 on failure * @return 0 on success, 1 on failure
*/ */
int pacman_upgrade(alpm_list_t *targets) int load_upgrade(alpm_list_t *targets)
{ {
int retval = 0; int retval = 0;
alpm_list_t *remote_targets = NULL, *fetched_files = NULL; alpm_list_t *remote_targets = NULL, *fetched_files = NULL;
@@ -88,15 +88,6 @@ int pacman_upgrade(alpm_list_t *targets)
if(remote_targets) { if(remote_targets) {
retval = alpm_fetch_pkgurl(config->handle, remote_targets, &fetched_files); retval = alpm_fetch_pkgurl(config->handle, remote_targets, &fetched_files);
if(retval) {
goto fail_free;
}
}
/* Step 1: create a new transaction */
if(trans_init(config->flags, 1) == -1) {
retval = 1;
goto fail_free;
} }
if(!config->print) { if(!config->print) {
@@ -105,23 +96,10 @@ int pacman_upgrade(alpm_list_t *targets)
retval |= load_packages(local_targets, alpm_option_get_local_file_siglevel(config->handle)); retval |= load_packages(local_targets, alpm_option_get_local_file_siglevel(config->handle));
retval |= load_packages(fetched_files, alpm_option_get_remote_file_siglevel(config->handle)); retval |= load_packages(fetched_files, alpm_option_get_remote_file_siglevel(config->handle));
if(retval) {
goto fail_release;
}
alpm_list_free(remote_targets);
alpm_list_free(local_targets);
FREELIST(fetched_files);
/* now that targets are resolved, we can hand it all off to the sync code */
return sync_prepare_execute();
fail_release:
trans_release();
fail_free:
alpm_list_free(remote_targets); alpm_list_free(remote_targets);
alpm_list_free(local_targets); alpm_list_free(local_targets);
FREELIST(fetched_files); FREELIST(fetched_files);
return retval; return retval;
} }

View File

@@ -61,13 +61,24 @@ enum {
CELL_FREE = (1 << 3) CELL_FREE = (1 << 3)
}; };
#define VAL_FROM_FORMAT_STR(temp, format, func) \ #define PRINT_FORMAT_STRING(temp, format, func) \
if(strstr(temp, format)) { \ if(strstr(temp, format)) { \
string = strreplace(temp, format, func(pkg)); \ string = strreplace(temp, format, func(pkg)); \
free(temp); \ free(temp); \
temp = string; \ temp = string; \
} \ } \
#define PRINT_FORMAT_LIST(temp, format, func, extract) \
if(strstr(temp, format)) { \
alpm_list_t *lst = func(pkg); \
char *cl = concat_list(lst, (formatfn)extract); \
string = strreplace(temp, format, cl); \
free(cl); \
free(temp); \
temp = string; \
} \
int trans_init(int flags, int check_valid) int trans_init(int flags, int check_valid)
{ {
int ret; int ret;
@@ -405,26 +416,37 @@ char *strreplace(const char *str, const char *needle, const char *replace)
return newstr; return newstr;
} }
static char *concat_alpm_depends(alpm_list_t *lst) typedef char *(*formatfn)(void*);
static char *concat_list(alpm_list_t *lst, formatfn fn)
{ {
char *depends = NULL; char *output = NULL, *tmp = NULL;
char *tmp = NULL;
for(alpm_list_t *i = lst; i; i = alpm_list_next(i)) { for(alpm_list_t *i = lst; i; i = alpm_list_next(i)) {
alpm_depend_t *dep = i->data; char *str = fn ? fn(i->data) : i->data;
char *depstring = alpm_dep_compute_string(dep);
if(str == NULL) {
continue;
}
if(tmp) { if(tmp) {
asprintf(&depends, "%s %s", tmp, depstring); asprintf(&output, "%s %s", tmp, str);
free(tmp); free(tmp);
} else { } else {
asprintf(&depends, "%s", depstring); asprintf(&output, "%s", str);
} }
tmp = depends; tmp = output;
free(depstring);
if(fn) {
free(str);
} }
if(!depends) {
asprintf(&depends, "%s", "");
} }
return depends;
if(!output) {
asprintf(&output, "%s", "");
}
return output;
} }
static size_t string_length(const char *s) static size_t string_length(const char *s)
@@ -1197,21 +1219,23 @@ void print_packages(const alpm_list_t *packages)
} }
} }
/* %d : description */ /* %d : description */
VAL_FROM_FORMAT_STR(temp, "%d", alpm_pkg_get_desc) PRINT_FORMAT_STRING(temp, "%d", alpm_pkg_get_desc)
/* %e : pkgbase */ /* %e : pkgbase */
VAL_FROM_FORMAT_STR(temp, "%e", alpm_pkg_get_base) PRINT_FORMAT_STRING(temp, "%e", alpm_pkg_get_base)
/* %f : filename */ /* %f : filename */
VAL_FROM_FORMAT_STR(temp, "%f", alpm_pkg_get_filename) PRINT_FORMAT_STRING(temp, "%f", alpm_pkg_get_filename)
/* %g : base64 encoded PGP signature */ /* %g : base64 encoded PGP signature */
VAL_FROM_FORMAT_STR(temp, "%g", alpm_pkg_get_base64_sig) PRINT_FORMAT_STRING(temp, "%g", alpm_pkg_get_base64_sig)
/* %h : sha25sum */ /* %h : sha25sum */
VAL_FROM_FORMAT_STR(temp, "%h", alpm_pkg_get_sha256sum) PRINT_FORMAT_STRING(temp, "%h", alpm_pkg_get_sha256sum)
/* %n : pkgname */ /* %n : pkgname */
VAL_FROM_FORMAT_STR(temp, "%n", alpm_pkg_get_name) PRINT_FORMAT_STRING(temp, "%n", alpm_pkg_get_name)
/* %p : packager */ /* %p : packager */
VAL_FROM_FORMAT_STR(temp, "%p", alpm_pkg_get_packager) PRINT_FORMAT_STRING(temp, "%p", alpm_pkg_get_packager)
/* %v : pkgver */ /* %v : pkgver */
VAL_FROM_FORMAT_STR(temp, "%v", alpm_pkg_get_version) PRINT_FORMAT_STRING(temp, "%v", alpm_pkg_get_version)
/* %m : md5sum */
PRINT_FORMAT_STRING(temp, "%m", alpm_pkg_get_md5sum)
/* %l : location */ /* %l : location */
if(strstr(temp, "%l")) { if(strstr(temp, "%l")) {
char *pkgloc = pkg_get_location(pkg); char *pkgloc = pkg_get_location(pkg);
@@ -1240,34 +1264,26 @@ void print_packages(const alpm_list_t *packages)
free(temp); free(temp);
} }
/* %u : url */ /* %u : url */
VAL_FROM_FORMAT_STR(temp, "%u", alpm_pkg_get_url) PRINT_FORMAT_STRING(temp, "%u", alpm_pkg_get_url)
/* %C : checkdepends */ /* %C : checkdepends */
if(strstr(temp, "%C")) { PRINT_FORMAT_LIST(temp, "%C", alpm_pkg_get_checkdepends, alpm_dep_compute_string)
alpm_list_t *lst = alpm_pkg_get_checkdepends(pkg);
char *depends = concat_alpm_depends(lst);
string = strreplace(temp, "%C", lst ? depends : "");
free(depends);
free(temp);
temp = string;
}
/* %D : depends */ /* %D : depends */
if(strstr(temp, "%D")) { PRINT_FORMAT_LIST(temp, "%D", alpm_pkg_get_depends, alpm_dep_compute_string)
alpm_list_t *lst = alpm_pkg_get_depends(pkg); /* %G : groups */
char *depends = concat_alpm_depends(lst); PRINT_FORMAT_LIST(temp, "%G", alpm_pkg_get_groups, NULL)
string = strreplace(temp, "%D", depends); /* %H : conflicts */
free(depends); PRINT_FORMAT_LIST(temp, "%H", alpm_pkg_get_conflicts, alpm_dep_compute_string)
free(temp);
temp = string;
}
/* %M : makedepends */ /* %M : makedepends */
if(strstr(temp, "%M")) { PRINT_FORMAT_LIST(temp, "%M", alpm_pkg_get_makedepends, alpm_dep_compute_string)
alpm_list_t *lst = alpm_pkg_get_makedepends(pkg); /* %O : optdepends */
char *depends = concat_alpm_depends(lst); PRINT_FORMAT_LIST(temp, "%O", alpm_pkg_get_optdepends, alpm_dep_compute_string)
string = strreplace(temp, "%M", depends); /* %P : provides */
free(depends); PRINT_FORMAT_LIST(temp, "%P", alpm_pkg_get_provides, alpm_dep_compute_string)
free(temp); /* %R : replaces */
temp = string; PRINT_FORMAT_LIST(temp, "%R", alpm_pkg_get_replaces, alpm_dep_compute_string)
} /* %L : license */
PRINT_FORMAT_LIST(temp, "%L", alpm_pkg_get_licenses, NULL)
printf("%s\n", string); printf("%s\n", string);
free(string); free(string);
} }

View File

@@ -65,7 +65,7 @@ Use the "help" option to get the full list of parameters:
When run with the `--valgrind' option, an additional rule will be added to all When run with the `--valgrind' option, an additional rule will be added to all
tests to check for memory leaks. To use `--valgrind' when running the full tests to check for memory leaks. To use `--valgrind' when running the full
test suite, run: test suite, run:
make PY_LOG_FLAGS=--valgrind check PACTEST_VALGRIND=1 ninja test
The following pieces of software are required to run the pactest suite: The following pieces of software are required to run the pactest suite:

View File

@@ -240,18 +240,20 @@ class pmtest(object):
cmd = [] cmd = []
if os.geteuid() != 0: if os.geteuid() != 0:
fakeroot = util.which("fakeroot") # fakechroot must be called before fakeroot due to potential
if not fakeroot: # potential interactions when wrapping the same C functions
tap.diag("WARNING: fakeroot not found!")
else:
cmd.append("fakeroot")
fakechroot = util.which("fakechroot") fakechroot = util.which("fakechroot")
if not fakechroot: if not fakechroot:
tap.diag("WARNING: fakechroot not found!") tap.diag("WARNING: fakechroot not found!")
else: else:
cmd.append("fakechroot") cmd.append("fakechroot")
fakeroot = util.which("fakeroot")
if not fakeroot:
tap.diag("WARNING: fakeroot not found!")
else:
cmd.append("fakeroot")
if pacman["gdb"]: if pacman["gdb"]:
cmd.extend(["libtool", "execute", "gdb", "--args"]) cmd.extend(["libtool", "execute", "gdb", "--args"])
if pacman["valgrind"]: if pacman["valgrind"]:

View File

@@ -10,7 +10,7 @@ lp3 = pmpkg("pkg3")
lp3.depends = [ "pkg1" ] lp3.depends = [ "pkg1" ]
self.addpkg2db("local", lp3) self.addpkg2db("local", lp3)
self.args = "-Ru pkg1 pkg2" self.args = "-R --unneeded pkg1 pkg2"
self.addrule("PACMAN_RETCODE=0") self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg1")