Compare commits

..

53 commits

Author SHA1 Message Date
Andrew Gregory
0c633c27ea Release v5.0.2
Signed-off-by: Andrew Gregory <andrew@archlinux.org>
2017-06-03 22:20:58 -04:00
Andrew Gregory
fdf53393bc update NEWS for v5.0.2
Signed-off-by: Andrew Gregory <andrew@archlinux.org>
2017-06-03 22:20:58 -04:00
Allan McRae
34d8beaef8 Pull translation changes for 5.0.2
Signed-off-by: Allan McRae <allan@archlinux.org>
2017-05-31 23:47:00 +10:00
Allan McRae
d39271ab56 Prepare translations for 5.0.2 release
Pull translation updates from transifex and regenerate po files.

Signed-off-by: Allan McRae <allan@archlinux.org>
2017-05-22 11:03:33 +10:00
Andrew Gregory
831cc8d9cd extract db files with dbonly
Some database files (install, mtree, and changelog) are extracted
directly from the package, but DBONLY was skipping extraction
altogether, causing those files to be missing after the transaction.

Fixes #52052

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 2c4511bdbe)
2017-05-08 23:27:45 -04:00
Christian Hesse
e708b606ae add generated scripts to gitignore
These files are generated at build time. Ignore in git.

Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit fc756c3c70)
2017-05-08 23:27:45 -04:00
Christian Hesse
cd8debfbfb libalpm/signing: support EDDSA from gpgme 1.7.0
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit c3b954e7b9)
2017-05-08 23:27:45 -04:00
Andrew Gregory
0fd8455c66 unlink_file: strip trailing slashes
If the user replaces a directory with a symlink, libalpm would get
confused because the trailing slash causes system calls to resolve the
symlink.  This leads to errors and a misleading message during upgrades.
Even though libalpm does not support this, it should not be giving
misleading errors.

Also adds an overflow check.

Fixes FS#51377

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
(cherry picked from commit 16b91f798f)
2017-05-08 23:27:44 -04:00
Armin K
908769b540 libalpm: Use archive_read_extract2
archive_read_extract() forces resolution of uid/gid to names
when extracting the tarball. This can lead to wrong file
ownership when using pacman with -r option and when uid/gid
differ in the host and in the chroot.

archive_read_extract2() uses uid's and gid's only. See also:

https://lists.archlinux.org/pipermail/pacman-dev/2017-March/021912.html

Signed-off-by: Armin K <krejzi@email.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 86f5c74694)
2017-05-08 23:27:44 -04:00
Dave Reisner
33dbe13a6b makepkg.conf: add -g to default curl options
This disables globbing, which should never be used in source URL
specifications as it would lead to mismatches in the checksum mapping
and un-checked sources.

(cherry picked from commit e7fc560866)
2017-05-08 23:27:44 -04:00
Alad Wenter
7bb1c73cfa libmakepkg: generate all scripts
In order for the scripts to be used in testsuites, it is easiest to generate
all of them so they are found in the build directory (which may be different
to the source directory).

Signed-off-by: Alad Wenter <alad@archlinux.info>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit aca153bfa6)
2017-05-08 23:27:44 -04:00
Martin Kühne
c2aed8aaff Use f_bavail for diskspace calculations
This should make pacman's behavior consistent with GNU coreutils df,
as well as follow advice from affected filesystems' devs as well as
`man statvfs`.

This fixes FS#37402

Signed-off-by: Martin Kühne <mysatyre@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 8c55c0096c)
2017-05-08 23:27:44 -04:00
Allan McRae
80a0016de4 Ensure makepkg-wrapper is built after makepkg
makepkg-wrapper did not get rebuilt if makepkg was regenerated due to library
changes.  Ensure makepkg-wrapper is always generated and linked any time
makepkg changes.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit ad27aa30fb)
2017-05-08 23:27:44 -04:00
Allan McRae
722be61ca8 Move bash/zsh completion out of contrib
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 2e76c184aa)
2017-05-08 23:27:44 -04:00
Levente Polyak
5de2ad13fd fix --printsrcinfo unify arch and non-arch specific variables
This fixes the issue with --printsrcinfo that all arch specific variants
of a variable get merged into their non arch specific variant.

The .SRCINFO file ends up having $depends containing $depends_x86_64
and omitting the latter.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 3190b87b65)
2017-05-08 23:27:43 -04:00
Ivy Foster
c889403cf7 Do not #define _RESERVED_IDENTIFIERS
Signed-off-by: Ivy Foster <ivy.foster@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 0d2ba870c9)
2017-05-08 23:27:43 -04:00
Alastair Hughes
537f8c881c Add missing newline in paclog-pkglist help output
Add missing newline in paclog-pkglist help output

Signed-off-by: Alastair Hughes <hobbitalastair@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 45b6a3074a)
2017-05-08 23:27:43 -04:00
Rikard Falkeborn
f6ccb46dc9 Change type of count in be_sync
Making it size_t matches the return value of alpm_list_count() and
avoids the implicit cast to int.

Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 6a5156eedc)
2017-05-08 23:27:43 -04:00
Rikard Falkeborn
7cc5012549 Return boolean from db_populate
Since the number of packages is not used anywhere, just return a
boolean to avoid the implicit cast from size_t to int in be_local.c.
Use 0 as success to be consistent with db_validate.

Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 85171807c1)
2017-05-08 23:27:43 -04:00
Rikard Falkeborn
22cadea56a Fix gcc strict-overflow error
Recent gcc (tested with 6.2.1) produces the following error when
compiling with both --enable-warningflags and --enable-debug.
In particular, it seems it is the combination of GCC_STACK_PROTECT_LIB
and -Wstrict-overflow=5 produces the error.

    be_local.c:609:4: error: assuming signed overflow does not occur
                             when simplifying conditional
                             [-Werror=strict-overflow]
    if(count > 0) {

Fix this by changing the type of count from int to size_t, which is
fine since count is never negative.

Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 34f3f1e7a6)
2017-05-08 23:27:43 -04:00
Fabio Castell
eca2e0f5ed repo-add: fix error in directories with a space in their name
Fixes FS#50285

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 07d1e0441b)
2017-05-08 23:27:43 -04:00
Ivy Foster
1f3793e71a lib/libalpm/be_sync.c: Close memory leaks when mallocing while out of memory
Signed-off-by: Ivy Foster <ivy.foster@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 900a22b90c)
2017-05-08 23:27:42 -04:00
Eli Schwartz
9e3aeb30d3 bash-completion: fix leaking "files" array into shell environment
Signed-off-by: Eli Schwartz <eschwartz93@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 38e229e4db)
2017-05-08 23:27:42 -04:00
Allan McRae
5a7204ee18 Fix memory leak in remove_notify_needed_optdepends
Also add pactest which captures this leak when run under valgrind.

Reported-by: Sergey Petrenko
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit fac4831a09)
2017-05-08 23:27:42 -04:00
Allan McRae
d6b6896a13 Fix typo in pacman-db-upgrade usage message
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit d560a9aecd)
2017-05-08 23:27:42 -04:00
Alastair Hughes
31af485d7e Remove AC_FUNC_MALLOC check.
We weren't supplying the rpl_malloc function needed if this failed, and
didn't check for realloc, so just remove.

Signed-off-by: Alastair Hughes <hobbitalastair@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 1dbfef7b1c)
2017-05-08 23:27:42 -04:00
Lukas Fleischer
4024bf0490 pacman.8: fix typo in the documentation of --asexplicit
Add a space between the option and its argument. Also, do not enclose
the argument in asterisk characters.

Fixes a typo introduced in aa4c61f (Document database checking options,
2014-12-28).

Reported-by: Luca Weiss <luca.emanuel.weiss@gmail.com>
Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 1e2b398406)
2017-05-08 23:27:42 -04:00
Giulio Fidente
6d5c70cf93 Merge Giolio Fidente into "Pacman Development Team" contribution
As discussed on mailing list:
https://lists.archlinux.org/pipermail/pacman-dev/2016-July/021239.html

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 69aee3e391)
2017-05-08 23:27:42 -04:00
Jack O'Connor
e20a502c40 libmakepkg: look for architecture-specific hashes in get_integlist
`makepkg -g` looks for existing checksums in the PKGBUILD file, so that
it can generate new sums of the same type. Previously it only checked
variables of the form "sha256sums", and not "sha256sums_x86_64". That
meant it would always fall back to MD5 for packages with only
architecture-specific sources. This change makes it look at
architecture-specific checksums too to determine the type.

Signed-off-by: Jack O'Connor <oconnor663@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 56de155296)

[andrew@archlinux.org: patch adapted to makepkg.sh.in]
2017-05-08 23:27:41 -04:00
Olivier Brunel
2e7162fe87 configure.ac: Fix handling --with-libcurl
It was reported being --with-libcurl in the help (and the check for libcurl
being installed used $with_libcurl accordingly), but the option handling was set
using $with_curl and, therefore, expected option --with-curl.

In the end, --with-libcurl wasn't recognized, and --with-curl had no effect.

Signed-off-by: Olivier Brunel <jjk@jjacky.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 56ae960376)
2017-05-08 23:27:41 -04:00
Andrew Gregory
cebb20762d hook.c: replace fstatat with stat
macOS < 10.10 do not provide fstatat.  We were constructing the full
path to the hook file for all other operations anyway, so there was no
real benefit to using fstatat.

Fixes FS#49771

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit be1ffedaf6)
2017-05-08 23:27:41 -04:00
Andrew Gregory
e770b5728b hook.c: replace readdir_r with readdir
glibc 2.24 deprecates readdir_r.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit c981f5ad76)
2017-05-08 23:27:41 -04:00
Tobias Stoeckmann
21fe34c3a1 Handle all POSIX compliant systems in mbscasecmp.
The width of wchar_t is allowed to be of the same width as long,
according to standards. The return type of mbscasecmp is int though.

On amd64 with a 32 bit int, this means that mbscasecmp can return
zero (indicating that strings are equal) even though the input
strings differ.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit af83a58574)
2017-05-08 23:27:41 -04:00
Tobias Stoeckmann
3218360114 Reject files larger than 16384 bytes in read_sigfile.
If signature files are larger than SIZE_MAX, not enough memory could
be allocated for this file. The script repo-add rejects files which
are larger than 16384 bytes, therefore handle these as errors here,
too.

While at it, I also rearranged the code to avoid a quite harmless
TOCTOU race condition between stat() and fopen().

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 5fcd60e264)
2017-05-08 23:27:41 -04:00
Tobias Stoeckmann
8abb0cbf0e Release resources on error paths.
Some resources (memory or file descriptors) are not released on all
error paths.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 681509fd44)
2017-05-08 23:27:41 -04:00
Tobias Stoeckmann
e03c539288 Always use proper error code in alpm_initialize.
In out of memory conditions, an undefined error value is written
into *err, because myerr is never explicitly set in these cases.

I have also converted a calloc into a MALLOC call, because the memory
will be properly filled by the snprintf call right after it.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 80d97fcf75)
2017-05-08 23:27:40 -04:00
Andrew Gregory
f31792adb5 recursedeps: include cyclic dependencies
Cyclic dependencies (A depends on B, B depends on A) were not selected
because neither package could be removed individually, so
can_remove_package would always return false for both.  By preselecting
all dependencies then filtering back out any dependencies still required
by any packages that will not be uninstalled, groups of unneeded cyclic
dependencies can be found.

Fixes FS#41031

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 6ac2ee21b3)
2017-05-08 23:27:40 -04:00
Christian Hesse
f84d0a8282 pacman.8: add link to alpm-hooks(5) in see also
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 839417e8c6)
2017-05-08 23:27:40 -04:00
Christian Hesse
689c413b96 libalpm.3: add link to alpm-hooks(5) in see also
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit f018317f48)
2017-05-08 23:27:40 -04:00
Alastair Hughes
b9bf727e33 makepkg: ignore the architecture for --printsrcinfo
Signed-off-by: Alastair Hughes <hobbitalastair@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 87082e3f44)
2017-05-08 23:27:40 -04:00
Allan McRae
2f1797783e Avoid logical OR duplication warning from gcc-6
The value EAGAIN is allowed by POSIX to be the same as EWOULDBLOCK, but this is
not guaranteed. Thus on some systems (e.g. glibc Linux), we get a warning that
the logical OR is being performed on two expressions of the same type. We can
not get rid of this test in case any system defines these as unique values.

Suggested-by: Dave Reisner
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 3729ef7a9a)
2017-05-08 23:27:40 -04:00
Ashley Whetter
a9bec8bed8 pacsort help clearly states that files contain inputs to be sorted
Fixes FS#44121

Signed-off-by: Ashley Whetter <ashley@awhetter.co.uk>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 6c96ad36e0)
2017-05-08 23:27:40 -04:00
Allan McRae
a5c23f0643 Prevent wrapping of enum items
GCC-6 points out that the value we use for the sentinal in enums is actually
too large for the integer type. Reduce the bitshift by one to fix this.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 5b9bc6024c)
2017-04-27 22:25:19 -04:00
Eric Engestrom
fcf4da76e0 fix spelling mistakes
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 2694d17ad9)
2017-04-27 22:25:08 -04:00
Andrew Gregory
d6ea5bd26d use multi-byte character matching for user input
Fixes FS#47992

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 02731189f1)
2017-04-27 22:21:54 -04:00
Allan McRae
cd7acd7529 repo-add: do not alter the database if only verifying signature
Fixes FS#48085.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit f363cf7857)
2017-04-27 22:21:33 -04:00
Allan McRae
9bddaac93c Use versions specified in optdepends
Checking install status and if a package is optionally required on removal
now considers the version of the optdepend.

Fixes FS#44957.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 3da06c3519)
2017-04-27 22:18:39 -04:00
Allan McRae
5211118a06 Consider provides when warning about optdepnd removal
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 59112e186b)
2017-04-27 22:12:42 -04:00
Allan McRae
c6e46c9ebb Consider provides when labelling optdepends status as pending install
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 76a7d2293c)
2017-04-27 22:12:28 -04:00
Leonid Isaev
c2f9758018 Use a more generic regexp when parsing output of gpg(1) in signature verification.
The current way of extracting key trust from output of gpg --verify is not very
robust against changes in the format of said output. As a result, pacman-key
can return an error even if the signature is actuall good.

This change relaxes the regexp when parsing output of gpg.

Signed-off-by: Leonid Isaev <leonid.isaev@jila.colorado.edu>
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 892a1076c0)
2016-05-18 15:46:59 +10:00
Allan McRae
5469161dad PKGBUILD.5: document that the pkgver() function runs after prepare()
Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 5901038610)
2016-05-05 13:57:32 +10:00
Allan McRae
07ccbc2691 Do not add root prefix twice when checking database files
When checking .INSTALL and .CHANGELOG files in the mtree file, we need to find
the path they are stored in the local database. This was appending the root
prefix twice as alpm_option_get_dbpath already returns the absolute path to
the database.

While fixing that issue I added checks that the paths for the database files
were not longer than PATH_MAX.

Fixes FS#48563.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit 2ee1706a72)
2016-05-05 13:56:27 +10:00
Allan McRae
a66cba1b08 libmakepkg: ensure emptydir find command acts on individual directories
Using "-exec command {} +" systax exits on any error.  Such errors occur when
running rmdir on a non-empty directory.  Switch to "{} ;" syntax instead which
avoids exiting before the find command is completed.

Fixes FS#48515.

Note, we can not use "-empty" in the find command because it is not supported
by Busybox find, and the "--ignore-fail-on-non-empty" flag for rmdir is not
available on BSD rmdir variants.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit baf1ff64e6)
2016-05-05 13:56:06 +10:00
551 changed files with 118512 additions and 105699 deletions

View file

@ -1,24 +0,0 @@
# EditorConfig configuration for pacman
# https://editorconfig.org
# Top-most EditorConfig file
root = true
# Unix-style newlines without trailing whitespaces, but with a newline
# ending every file, utf-8 charset, set indent to tabs
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = tab
[{NEWS,HACKING}]
indent_style = space
[meson.build]
indent_style = space
indent_size = 2
[*.py]
indent_style = space

21
.gitignore vendored
View file

@ -1,3 +1,24 @@
*~
*.o
ABOUT-NLS
aclocal.m4
autom4te.cache
config.h
config.h.in
config.log
config.status
config.status.lineno
configure
configure.lineno
cov-int
cscope.in.out
cscope.out
cscope.po.out
intl
libtool
Makefile
Makefile.in
pacman-*.tar.gz
root
stamp-h1
tags

View file

@ -1,132 +0,0 @@
variables:
MAKEFLAGS: "-j10"
VERBOSE: 1
default:
after_script:
- build-aux/print-failed-test-output build/meson-logs/testlog.json
.arch-test:
image: archlinux:base-devel
before_script:
- >
pacman -Syu --needed --noconfirm
git
gpgme libarchive curl
python
fakeroot fakechroot
meson
artifacts:
when: always
paths:
- build/meson-logs/meson-log.txt
arch:
extends: .arch-test
script:
- meson setup build
- ninja -C build
- fakechroot meson test -C build
arch-debug:
extends: .arch-test
script:
- meson setup --buildtype=debug --werror build
- ninja -C build
- fakechroot meson test -C build
arch-docs:
extends: .arch-test
script:
- pacman -Syu --needed --noconfirm asciidoc
- meson setup -Ddoc=enabled build
- ninja -C build
arch-clang:
extends: .arch-test
script:
- pacman -Syu --needed --noconfirm clang
- CC=clang meson setup build
- ninja -C build
- fakechroot meson test -C build
#arch-valgrind:
# extends: .arch-test
# script:
# - 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
# - meson setup build
# - ninja -C build
# - PACTEST_VALGRIND=1 fakechroot meson test -C build
arch-nettle:
extends: .arch-test
script:
- meson setup -Dcrypto=nettle --buildtype=debug build
- ninja -C build
- fakechroot meson test -C build
arch-no-gpg:
extends: .arch-test
script:
- meson setup -Dgpgme=disabled --buildtype=debug build
- ninja -C build
- fakechroot meson test -C build
arch-no-curl:
extends: .arch-test
script:
- meson setup -Dcurl=disabled --buildtype=debug build
- ninja -C build
- fakechroot meson test -C build
arch-no-nls:
extends: .arch-test
script:
- meson setup -Di18n=false --buildtype=debug build
- ninja -C build
- fakechroot meson test -C build
debian:
image: debian:bookworm
before_script:
- apt update
- >
apt -y install --no-install-recommends
git pkg-config meson gcc libtool
libgpgme-dev libarchive-dev libcurl4-openssl-dev libssl-dev curl
gettext python3 python3-setuptools dash gawk ca-certificates
fakeroot fakechroot
script:
- meson setup --buildtype=debug build
- ninja -C build
- fakechroot meson test -C build
fedora:
image: fedora
before_script:
- >
dnf -y install
git findutils patch sed
meson gcc libtool bsdtar
gpgme-devel libarchive-devel libcurl-devel openssl-devel gettext-devel
asciidoc python3 dash gawk
fakeroot fakechroot
perl-Module-Load-Conditional
script:
- meson setup --buildtype=debug build
- ninja -C build
- fakechroot meson test -C build
pages:
extends: .arch-test
script:
- pacman -Syu --needed --noconfirm asciidoc
- meson setup -Ddoc=enabled build
- ninja -C build html
artifacts:
paths:
- build/doc
publish: build/doc
rules:
- if: $CI_COMMIT_BRANCH == "release/6.1.x"

View file

@ -12,7 +12,7 @@ Daenyth Blank <Daenyth+arch@gmail.com> <Daenyth+git@gmail.com>
Dave Reisner <dreisner@archlinux.org> <d@falconindy.com>
甘露(Gan Lu) <rhythm.gan@gmail.com>
Giovanni Scafora <giovanni@archlinux.org> <linuxmania@gmail.com>
Jan Alexander Steffens (heftig) <heftig@archlinux.org> <jan.steffens@gmail.com>
Jan Steffens <jan.steffens@gmail.com>
Jaroslaw Swierczynski <swiergot@gmail.com> <swiergot@juvepoland.com>
Jonathan Conder <j@skurvy.no-ip.org> <jonno.conder@gmail.com>
Juan Pablo González Tognarelli <lord_jotape@yahoo.com.ar>
@ -20,7 +20,6 @@ Juan Pablo González Tognarelli <lord_jotape@yahoo.com.ar> <jotapesan@gmail.com>
Manuel Tortosa <manutortosa@chakra-project.org> <manutortosa@gmail.com>
Marc - A. Dahlhaus <mad@wol.de>
Matthias Gorissen <matthias@archlinux.de> <siquame@web.de>
morganamilo <morganamilo@archlinux.org> <morganamilo@gmail.com>
Laszlo Papp <djszapi@archlinux.us> <djszapi2@gmail.com>
Nagy Gabor <ngaba@bibl.u-szeged.hu> <ngaba@petra.hos.u-szeged.hu>
Nagy Gabor <ngaba@bibl.u-szeged.hu> <ngaba at bibl.u-szeged.hu>

View file

@ -1,17 +1,17 @@
[main]
host = https://www.transifex.com
[o:toofishes:p:archlinux-pacman:r:libalpm-pot]
[archlinux-pacman.libalpm-pot]
file_filter = lib/libalpm/po/<lang>.po
source_file = lib/libalpm/po/libalpm.pot
source_lang = en
[o:toofishes:p:archlinux-pacman:r:pacman-pot]
[archlinux-pacman.pacman-pot]
file_filter = src/pacman/po/<lang>.po
source_file = src/pacman/po/pacman.pot
source_lang = en
[o:toofishes:p:archlinux-pacman:r:pacman-scripts-pot]
[archlinux-pacman.pacman-scripts-pot]
file_filter = scripts/po/<lang>.po
source_file = scripts/po/pacman-scripts.pot
source_lang = en

26
HACKING
View file

@ -11,8 +11,13 @@ Coding Style
1. All code should be indented with tabs. (Ignore the use of only spaces in
this file.) A tab size of two spaces is used when calculating line widths,
which should be a maximum of 80 characters. An EditorConfig file is used
to set this project-wide default.
which should be a maximum of 80 characters. By default, source files
contain the following Vim modeline:
+
[source,C]
-------------------------------------------
/* vim: set noet: */
-------------------------------------------
2. When opening new blocks such as 'while', 'if', or 'for', leave the opening
brace on the same line as the beginning of the codeblock. The closing brace
@ -176,3 +181,20 @@ For pacman:
-------------------------------------------
Never directly include config.h. This will always be added via Makefiles.
GDB and Valgrind Usage
~~~~~~~~~~~~~~~~~~~~~~
When using GDB or valgrind on pacman, you will want to run it on the actual
binary rather than the shell script wrapper produced by libtool. The actual
binary lives at `src/pacman/.libs/lt-pacman`, and will exist after running
`./src/pacman/pacman` at least once.
For example, to run valgrind:
./src/pacman/pacman
valgrind --leak-check=full -- src/pacman/.libs/lt-pacman -Syu
/////
vim:set syntax=asciidoc noet spell spelllang=en_us:
/////

370
INSTALL Normal file
View file

@ -0,0 +1,370 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

73
Makefile.am Normal file
View file

@ -0,0 +1,73 @@
SUBDIRS = lib/libalpm src/util src/pacman scripts etc test/pacman test/util test/scripts
if WANT_DOC
SUBDIRS += doc
endif
DIST_SUBDIRS = $(SUBDIRS) contrib src/common
ACLOCAL_AMFLAGS = -I m4 --install
AM_MAKEFLAGS = --no-print-directory
# Make sure we test and build manpages when doing distcheck
DISTCHECK_CONFIGURE_FLAGS = --enable-doc --disable-git-version
# Some files automatically included, so they aren't specified below:
# AUTHORS, COPYING, NEWS, README
EXTRA_DIST = HACKING test/tap.sh
# Sample makepkg prototype files
pkgdatadir = ${datadir}/${PACKAGE}
dist_pkgdata_DATA = \
proto/PKGBUILD.proto \
proto/PKGBUILD-split.proto \
proto/PKGBUILD-vcs.proto \
proto/proto.install
$(top_srcdir)/test/pacman/tests/TESTS: $(wildcard test/pacman/tests/*.py)
@printf "TESTS += %s\n" $^ | LC_ALL=C sort -u > "$@"
TESTS = test/scripts/parseopts_test.sh \
test/scripts/human_to_size_test.sh \
test/scripts/makepkg-template_test.sh \
test/scripts/pacman-db-upgrade-v9.py \
test/util/pacsorttest.sh \
test/util/vercmptest.sh
include $(top_srcdir)/test/pacman/tests/TESTS
TEST_SUITE_LOG = test/test-suite.log
TEST_EXTENSIONS = .py
AM_TESTS_ENVIRONMENT = \
PMTEST_UTIL_DIR=$(top_builddir)/src/util/; export PMTEST_UTIL_DIR; \
PMTEST_SCRIPT_DIR=$(top_builddir)/scripts/; export PMTEST_SCRIPT_DIR; \
PMTEST_SCRIPTLIB_DIR=$(top_srcdir)/scripts/library/; export PMTEST_SCRIPTLIB_DIR;
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
$(top_srcdir)/build-aux/tap-driver.sh
PY_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
$(top_srcdir)/build-aux/tap-driver.sh
PY_LOG_COMPILER = $(PYTHON) $(top_srcdir)/test/pacman/pactest.py
AM_PY_LOG_FLAGS = \
--scriptlet-shell $(SCRIPTLET_SHELL) \
--ldconfig $(LDCONFIG) \
--bindir $(top_builddir)/src/pacman \
--bindir $(top_builddir)/scripts
# create the pacman DB, cache, makepkg-template and system hook directories upon install
install-data-local:
for dir in "$(DESTDIR)$(localstatedir)/lib/pacman" "$(DESTDIR)$(localstatedir)/cache/pacman/pkg" \
"$(DESTDIR)$(datarootdir)/makepkg-template" "$(DESTDIR)$(datarootdir)/libalpm/hooks"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
update-po:
$(MAKE) -C lib/libalpm/po update-po
$(MAKE) -C scripts/po update-po
$(MAKE) -C src/pacman/po update-po
update-copyright:
for file in $(shell sh -c 'git grep -l "Copyright .* Pacman Development" | grep -v "\.po"'); do \
sed -i -e "/Copyright (/s/-$(OLD)/-$(NEW)/" -e "/Copyright (/s/ $(OLD)/ $(OLD)-$(NEW)/" "$$file"; \
done
.PHONY: update-po update-copyright
# vim:set noet:

468
NEWS
View file

@ -1,443 +1,5 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
7.0.0 - Add DownloadUser configuration option used to drop-privileges
when downloading files.
- Download files to a temporary directory owned by DownloadUser
- On Linux systems, ensure the download process does not write
outside the download directory
- Add DisableSandbox option and --disable-sandbox flag to
disable the download write restrictions on Linux systems
- Ensure database and signature are downloaded from the same
location. Fixes the use of XferCommand.
- Use snprintf instead of sprintf
- Fix issue preventing use of _FORITIFY_SOURCE=3 when compiling
- Fix read-after-free issue when parsing config files
- Fix searching for files in an non-NULL by empty filelist
- Prevent buffer overflow with long scriptlet shell path
- repo-add:
- Fix issue with missing argument in parsepots for -k/--key
- Handle lack of newline at the end of .PKGINFO
- create empty databases when requested
- makepkg:
- Remove GITFLAGS support - this required multiple breaking
changes to git source handling in order to fully support.
- Prevent MAKEFLAGS and CHOST from being disabled with
options=(!buildenv)
- Fix unstable git checksumming, and dependence on user
config
- Make "not a clone of" source errors visible with a new
return code
- Document makepkg.conf.d dropin configuration
- Drop sudo permissions after use
- Prevent PKGBUILDs overriding BUILDENV
- only copy source files once when creating a debug package
- pacman-key:
- Fix permissions check for non-root operations
6.1.0 - Add cache server support
- Improvements to --sysroot option - NOTE: targets to -U are no
longer interpreted relative to sysroot
- Add more format specifiers for --print operations
- Add extended data field for arbitrary package data
- Do not run hooks with --dbonly
- Provide more details when encountering file conflicts or
corrupt packages
- Improved WKD support (FS#73703, FS#73534)
- Improved handling of malformed download headers (FS#73704)
- Use openssl interfaces for calculating sha256 and md5 sums
- Fix multi download bar chomps
- makepkg:
- Replace libdepends and libprovides with autodeps
- Support configuration via makepkg.conf.d drop-ins
- Add GITFLAGS environment variable to customize checkouts
- Add -D option to change directory before building
- Implement verify() function for custom source verificaton
- Add checksum support for git/mercurial/bzr sources
- Improved stripping and debug package support
- Configurable LTO support
- Add source signing PGP keys to package if available
- Store "pkgtype" in xdata
- Remove md5sum from mtree files
- Document MAKEPKG_LIBRARY
- repo-add:
- Do not include package signature details in the repo. Add
the --include-sigs to revert to old behaviour.
- Do not add md5sum to the repo database
6.0.1 - Prevent download error pages ending up in package files
(FS#71083)
- Give -U downloads a random .part file name if needed
(FS#71464)
- Fix downloading signatures with redirecting URLs (FS#71148)
- Fix double free when importing PGP keys (FS#71107)
- Ensure signature files are named after original file
following redirects (FS#71274)
- Order downloads by size - largest to smallest (FS#70172)
- Fix reproducibility of man pages (FS#71154)
- makepkg:
- Fix stripping debug symbols with binutils 2.37 (FS#71722)
- Export PYTHONHASHSEED for reproducible python packages
- pacman-key:
- Quieten trust db checks.
6.0.0 - internal downloader can retrieve files in parallel (FS#20056)
- an additional progress bar is added to track total download
progress. This replaces the previous TotalDownload option.
- fix download rates becoming negative
- skip mirror servers with too many errors (FS#29293)
- package signatures are always retrieved even if signature is
embedded in repo database or package is in cache (FS#33992)
- detached package signatures found in CacheDir can be used to
verify packages if signature is not in the database. Also
verify packages checksums from repo db when using detached
signatures.
- add support for multiple 'Architecture' values
- -Qkk now validates file checksums in addition to date/size
- colored upgrade summary now dulls version numbers for contrast
- libalpm frontends can now supply context to callbacks (FS#12721)
- support xattr when extracting packages
- allow setting --noprogressbar in pacman.conf
- fix output alignment for CJK translated text (FS#59229)
- fix reading targets from stdin when using --sysroot (FS#68630)
- fix deleting signatures for existing databases with -Sc
- check for and forbid duplicate download filenames (FS#67850)
- -Fx now reports error for invalid regex
- remove support for the autotools build system
- meson: properly compile internal symbols as hidden
- meson: make -uninstalled.pc correct
- fix build errors on systems like FreeBSD
- makepkg:
- add link time optimization support to makepkg
- add support for sources using the fossil VCS
- allow specifying alternative authentication commands when
running pacman as root (FS#32621)
- support zstd decompression for sources
- strip: fix removing file attributes such as xattr
- switch to CRC as default integrity checksum
- record $startdir for reproducible builds
- record name of build orchestration tool for reproducible builds
- fix signing of source packages
- add optional argument support to parseopts
- reduce dependency on file for detecting ELF files
- remove dependency on GNU sed
- avoid trailing whitespace in --printsrcinfo output
- libprovides: don't provide both versioned and unversioned
sonames
- don't double-layer distcc on ccache
- fix detection of source file names for debug packages with
gcc 11
- strip: silence warnings emitted by readelf while detecting
source filenames
- fix use of spaces in source file renaming (FS#70254)
- pacman-key:
- --refresh-keys queries WKD before keyserver
- be less noisy when populating the keyring (FS#64142)
- warn about time taken for master key generation
- repo-add:
- support the same compression methods as makepkg
- zsh completion: add pacman-conf support
- various documentation updates
- after a decade and a half of promising libalpm.3 documentation
"once we get around to doing good Doxygen documentation", it
has happened!
5.2.2 - fix pacman test suite under python 3.8
- only prompt to import new keys once in a transaction
- fix handling of fully downloaded .part files
- increase maximum database size (FS#65197)
- fix segfault in alpm_option_set_assumeinstalled
- change config parsing warnings to errors to match actual
behavior
- fix key extraction for signatures with two-octet sub-packet
headers
- fix documentation typos (FS#67000)
- change master signing key to RSA4096
- improve error message when building without autoconf-archive
- pacman-conf:
- allow querying ILoveCandy individually
- fix querying NoExtract individually
- makepkg:
- fix seccmp-related error while stripping binaries (FS#65100)
- fix extraction of file:// sources (FS#64648)
- allow $pkgname in install and changelog file names (FS#64932)
- sort libprovides for reproducibility
- strip: don't re-add the same debug source multiple times
- error on empty refspecs in git sources
- correctly handle missing download clients
- fix splitting multi-line error messages across stdout and
stderr
- handle GPGKEY with spaces (FS#66949)
- do not accept public-only keys for signing
- repo-add:
- handle GPGKEY with spaces (FS#66949)
- do not accept public-only keys for signing
5.2.1 - fix segfault on importing PGP keys for -U operations
- fix distribution of meson files
- fix inode command for darwin/bsd
- distribute all documentation files
- update bash/zsh completion for -F changes, remove --force
- makepkg:
- fix calculation of package sizes in presence of hardlinks
- do not warn about PACKAGER format if not set
- only run --clean when a package is built
- repo-add:
- fix compression of databases with zstd (FS#64213)
5.2.0 - completely remove delta support (CVE-2019-18183)
- add support to pacman and pacman-key for downloading PGP
signing keys using the WKD protocol (FS#63171)
- completely remove the --force option
- renovate and simplify the UI for -F (FS#47949)
- hooks: rename type File to Path, for accuracy
- add the meson build system as an alternative to autotools, and
distribute it in autotools dist tarballs
- switch from system() to exec() when using alternative download
agents for XferCommand; this prevents a potential source of
shell injection (CVE-2019-18182)
- ignore .hook suffix when sorting libalpm hooks
- update the minimum requirement of bash to 4.4
- scripts: pass on options such as set -x to child processes
- show group and installed status during -Fs
- user-visible log when validity check fails due to access
- port pactest to python3
- process --needed before group selection when resolving the
dependencies to prompt for (FS#22870)
- don't error when a group exists but all packages are ignored
- bash completion now completes when it should, and doesn't
complete when it shouldn't (FS#59965)
- improve error message when gpg support is missing (FS#60880)
- don't emit confusing errors when a package is simultaneously
replaced and upgraded (FS#50875, FS#55534)
- better warning message when skipping duplicate targets
(FS#49377)
- libalpm: parse {check, make}depends when reading database
(FS#60347)
- add [ignored] to -Qu output for packages in repos that are not
Usage = Upgrade (FS#59854)
- prevent 301 redirect loop from hanging libalpm
- use standard, consistent units in the download progress
(FS#59201)
- fix segfault when Usage is specified without a value
- include timezones in pacman.log
- bash-completion: use POSIX character classes for portability
- correctly report a download failure for 404s
- fix handling of signals during SIGSEGV
- fix buffer overread in pacman/callback
- fix crash when downloading files with a Content-Disposition
that has no directory component
- pacman-conf, testpkg are now properly localized
- when -F returns zero results, set a failing exit code
- improve wording for the error message when a package cannot be
removed due to dependencies
- fix segfaults and other incorrect behavior when using -Qip if
pacman was compiled without GPGME support
- makepkg:
- implement extendable source/signature verification routines
within libmakepkg (FS#49076)
- if pacman is in use, wait until it is available before
continuing (FS#28840)
- add support for lzip, lz4 and zst compressed packages
(FS#56676, FS#59081)
- add new checksum algorithm, b2sum
- various improvements to PKGBUILD linting
- when signing packages, report package filename on failure
- fix pkgver() function not aborting on errors
- remove checksum algorithm whirlpoolsum as it has not worked
for a long time
- reject PKGBUILDs with both split and non-split package
functions
- send status messages to stderr rather than stdout (FS#17173)
- ensure debug buildflags are unset when they are supposed to be
- buildenv and executable detection, definitions for the
PKGBUILD schema, and makepkg.conf loading are now part of
libmakepkg
- fix broken check for the fakeroot binary
- improve the error message for invalid dependency versioning
- add routine for linting $SOURCE_DATE_EPOCH
- fix the error code when no PKGBUILD exists
- use --unneeded when removing build deps to allow runtime-only
deps to work well with makepkg -sir (FS#32723)
- compute package sizes correctly across different filesystems
- use shared clones for git sources to save space when building
- fix reporting of invalid archive extensions
- correctly handle hg sources with updates on a non-default
branch
- install pkg-config file for libmakepkg's library directory
- propagate error codes when package failed to sign correctly
- be compatible with file 5.37's application/gzip MIME type
- forbid non-ASCII pkgname and pkgver (FS#49342)
- fix exiting on failure without ensuring dependencies are
prompted for removal (FS#63000)
- quiet superfluous warnings for missing debug source files for
artificial symbols
- add routine for linting $PACKAGER to check that it has a
valid name and email address, and document the desired format
in makepkg.conf(5)
- add rust support for *FLAGS and debug-prefix-map
- correctly handle a system file command with seccomp enabled
(FS#58626)
- try to more thoroughly clean up logpipe during unusual exit
states such as CTRL-C
- when installing packages with -sir, be more robust against
conflicting makedepends by always uninstalling them first
- fix exit code when removing deps fails
- reproducible builds: suppress filesystem-specific archive
metadata from built packages as they are not needed
- pacman-key:
- just accept one file to verify, and enforce detached sigs
(FS#52022)
- after recent GnuPG updates, ensure the Web of Trust is still
used
- clean keys during import to reduce size consumed by unusable
signatures
- repo-add:
- add support for zst compressed databases
- print the name of the database when extracting
- do not infinitely loop on malformed arguments with embedded
globs
- add option to prevent downgrading (FS#17752)
- various documentation updates
5.1.3 - Sanitize file name received from Content-Disposition header
during -U (CVE-2019-9686)
5.1.2 - pacman-conf: add missing DisableDownloadTimeout support
- Include version when checking optdepend install status
during -Qi (FS#60106)
- Improve error message for unresolvable urls (FS#48285)
- Do not raise SIGINT when a downloaded file exceeds the expected
size
- Fix previous download interruption status carrying over to new
downloads
- Reset known signal handlers before running install scripts or
hooks (FS#56756)
- Properly handle signal interrupts while running install scripts
or hooks (FS#60396)
- Allow explicitly disabling signature checks when compiled
without signature support (FS#60880)
- makepkg: fix linting error on environment variables (FS#60681)
5.1.1 - Allow full path including root prefix to be passed to
--overwrite
- Revert deprecation of --root
- Document comment syntax restrictions in pacman.conf
- makepkg:
- handle pre-existing directories when checking for write
permissions
- reduce restrictions on pkgver in depends listings (FS#58776)
- permit versioned optdepends
- remove unintended chmod of $BUILDDIR (FS#58790)
- fix issue when $startdir was not an absolute path (FS#58865)
- fix syntax error when $pkgname is empty
- fix --nocolor being passed to pacman (FS#58820)
- fix issues with trap handling
- fix several issues with debug packages (signing, printing of
package names, clearing of global package options, source
file inclusion)
- fix --help text for --packagelist
- pacman-conf: Fix detection of Usage option
5.1.0 - Add new --overwrite option and deprecate --force. This accepts a
glob pattern with far more control than the widely abused force
option which mostly just causes issues (FS#31549)
- Add new --sysroot option and deprecate --root. This uses the
guest configuration instead of the host configuration, which is
what most people erroneously thought --root would do
- introduce a 'disable-download-timeout' option
- remove contrib - this is now maintained in a separate project
- report the owner of an existing file, if any, when erroring out
on a file conflict
- resolve cyclic dependencies when calculating unneeded dependency
trees (FS#41031)
- report the needed command to download missing databases for the
-F and -S actions
- don't error if -Qo cannot find the file it is querying on disk
(FS#55856)
- support new-style OpenPGP format packets lengths
- support EDDSA from gpgme 1.7.0
- fix continuously trying to open invalid databases and reporting
excessively excessive redundant error messages excessively
- fix the download callback erroneously reporting itself too many
times with --noprogressbar, or reporting inaccurate times for
small files (FS#56408, FS#56468)
- fix erroneous negative speed in download progressbar (FS#43434)
- parse stdin as newline-separated instead of whitespace-separated
(FS#52992)
- when printing urls in the package cache, print the file url
instead (FS#15868)
- add color to group selection dialogs and -{F,Q}o
- the -Q option now respects provides (FS#20650)
- remove notification of system upgrade when only printing URLs
- print replacements when using -Sup (FS#35812)
- fix -Qk and -r checking for the root prefix twice (FS#48563)
- Do not recognize # as a comment unless it is at the beginning of
a line. This allows using it as a value in ini files (FS#48702)
- ignore comments when examining INSTALL files (FS#51916)
- match multi-byte user input properly (FS#47992)
- abort transactions if even one database fails to sync (FS#47599)
- do not resolve uid/gid to names when extracting files with -r
- --dbonly now properly extracts metadata files (FS#52052)
- remove support for internal checksumming implementations, and
require at least one of openssl or nettle to exist
- consider provides to satisfy optdepends when warning for removal
or logging new optdepends during a transaction, as was already
the case for -Qi
- -Dk now reports if it is successful (FS#50087)
- consider version for optdepends (FS#44957)
- remove vim modelines in favor of EditorConfig
- implement pacman-conf, a new tool to safely parse pacman.conf,
and use it in internal scripts
- bash completion now completes -Qn
- various small documentation updates
- makepkg:
- Reproducible build support. makepkg now respects environment
SOURCE_DATE_EPOCH when creating package metadata, and unifies
source file timestamps to match
- add more info to .BUILDINFO to aid in reproducing the build
environment of a package
- it is now possible to check the signature of VCS sources
(currently only git is supported)
- use informative exit codes when exiting with errors (FS#54204)
- lint_pkgbuild has vastly improved linting of pkgname and
variables that can contain pkgname/pkgver (FS#57833)
- implement linting for makepkg.conf
- fix using libmakepkg in external scripts without extglob
- fix handling of configurable directories e.g. PKGDEST to align
with their documented behavior, and consistently check that
they can be used (FS#43537)
- parseopts, srcinfo, and integrity are now part of libmakepkg
- consistently use coreutils for checksumming instead of openssl
(which may be replaced by nettle in pacman)
- lint build_references now prints affected filenames (FS#31558)
- lint_package can now abort on fatal packaging errors
- lint_package now checks for filenames with newline characters
- lint_package now checks for root-level /.dotfiles
- debug packages are now per pkgbase, not per pkgname
- debug packages now contain source files to allow the debugger
to step through code
- remove optipng and upx support - these can now be plugged into
libmakepkg
- fix emptydirs support with newer findutils (FS#48515)
- ignore architecture for --printsrcinfo
- makepkg --printsrcinfo now correctly lists depends_$CARCH
instead of merging this into depends
- fix bug in is_array that broke packages with arch-dependent
sources only (FS#48340)
- move package signing outside of fakeroot which is incompatible
with recent gnupg versions (FS#49946)
- makepkg --clean now cleans up logfiles (FS#51039)
- when using $PKGDEST, do not symlink build artifacts into
current directory
- --packagelist now lists the built filenames, rather than all
possible basenames without extensions
- fix --geninteg not properly ignoring renamed signature files
- use localized date strings
- ensure sane umask is set both before and after installing deps
- adapt to file(1) changes in order to continue to strip PIE
executables
- repo-add:
- don't recreate the database when only verifying signature
(FS#48085)
- fix error when repo directory path contains spaces (FS#50285)
- pacman-key:
- reject armored signatures
- don't set a default keyserver, deferring to gpg's sane default
- disable scdaemon as we don't use it and it breaks --lsign when
a smartcard is plugged into the machine
- vercmp:
- remove duplicate, undocumented --usage option
- fail when the wrong number of arguments are used (FS#49093)
5.0.2 - fix database file checks with -Qkk and non-standard root
(FS#48563)
- improve optdepend detection for status messages (FS#44957)
@ -461,7 +23,7 @@ VERSION DESCRIPTION
- fix triggering of Install hooks (FS#47996)
- fix handling of stdin scripts called by pacman
- hook activity is logged
- documentation updates for alpm-hooks (FS#48080)
- documentataion updates for alpm-hooks (FS#48080)
- makepkg:
- increase robustness of variable array checks
- makepkg -g does not perform current architecture checks
@ -553,9 +115,9 @@ VERSION DESCRIPTION
- Fix removal of static libraries when the shared library
uses the absolute path in symbolic links (FS#43395)
- Improve Bazaar cloning (FS#43448)
- Fix issues with architecture dependent checksum
- Fix issues with architecture dependant checksum
verification (FS#43192)
- Fix .SRCINFO file with architecture dependent fields
- Fix .SRCINFO file with architecture dependant fields
(FS#43247)
- Fix compatibility with older bash versions
- Allow git checkouts to be downloaded into directory ending
@ -618,8 +180,8 @@ VERSION DESCRIPTION
- remove --asroot and enforce fakeroot usage
- all PKGBUILDs require a package() function
- PKGBUILDs can no longer be read from stdin
- enable make-style environment variable overrides
- Read CARCH environment variable (FS#35030)
- enable make style environmental overrides
- Read CARCH environmental variable (FS#35030)
- makedepends and checkdepends are installed together (FS#31557)
- added support for sha224 checksums (FS#36776)
- remove warning when license is not specified in PKGBUILD
@ -645,11 +207,11 @@ VERSION DESCRIPTION
- checkupdates: rename CHECKUPDATE_DB to CHECKUPDATES_DB
- pacdiff: add a "Quit" option, and many other improvements
- pacsysclean is removed
4.1.2 - validate %FILEPATH% when parsing repos to prevent arbitrary
4.1.2 - validate %FILEPATH% when parsing repos to prevent arbitary
file overwrites from malicious databases
- makepkg:
- restrict package name from starting with a dot
- fix Bazaar source revision support (FS#35281)
- fix BZR source revision support (FS#35281)
- Use LOGDEST for log pipe
- fix distcc disabling (FS#35741)
- correct stat usage on BSD/Darwin (FS#35469)
@ -665,7 +227,7 @@ VERSION DESCRIPTION
FS#34716, FS#35097)
- makepkg:
- improve SVN VCS PKGBUILD handling (FS#34675, FS#34636)
- allow "lp:" URLs for Bazaar sources (FS#34650)
- allow "lp:" URLs for BZR sources (FS#34650)
- prevent pkgver() capturing stderr (FS#34974)
- fix attempt to remove package twice on failure (FS#34672)
- contrib:
@ -716,7 +278,7 @@ VERSION DESCRIPTION
- pkgrel must be in decimal format
- PKGBUILDs without package() functions are deprecated
- support specifying CPPFLAGS in makepkg.conf
- support PACKAGER environment variable
- support PACKAGER environmental variable
- allow source renaming to work on signature files
- configurable compression options (FS#27430)
- allow multiple packages to be build when using
@ -730,7 +292,7 @@ VERSION DESCRIPTION
- add LOGDEST configuration option
- install makedepends with --repackage
- repo-add:
- honor TMPDIR environment variable
- honor TMPDIR environmental variable
- add makedepends/checkdepends information to database
- pacman-key:
- fix importing keys with quotes in file name (FS#28445)
@ -1110,7 +672,7 @@ VERSION DESCRIPTION
- repo-add: use openssl instead of md5sum
- simplify doc building process for ease of development
- ensure correct handling of syscall interruptions
- re-add missing newline on -Qi/-Si output (FS#11331)
- readd missing newline on -Qi/-Si output (FS#11331)
- fix TotalDownload regression (FS#11339)
- makepkg:
- replace getopt with an internal function
@ -1338,7 +900,7 @@ VERSION DESCRIPTION
- add source package creation option
- rankmirrors- allow reading from stdin (FS#8043)
- and many other updates: 198 bugs/FRs closed since 3.0.0 release
- switch to Git for source code management
- switch to GIT for source code management
3.0.6 - config files updated to reflect current -> core change
- fix symlink overwriting issue (FS#7484)
- fix config parsing with tr_TR locale (FS#7235)
@ -1490,7 +1052,7 @@ VERSION DESCRIPTION
- Cleanup db_loadpkgs(), add list_add_sorted()
- Fixed a memory leak in db_find_conflicts()
2.8.3 - Fixed a little makepkg bug with bash 3.0
- Fixed resolvedeps to always prefer literals over providers
- Fixed resolvedeps to always prefer literals over provisios
- Added --config option to specify an alternate config file
- Added "Include" directive to include repositories from
config files (inspired by Michael Baehr's patch)
@ -1556,7 +1118,7 @@ VERSION DESCRIPTION
external download utility like wget
- added a license field to package meta-data
- add url support to -A and -U operations (download packages)
- -Ss now searches through provides fields
- -Ss now searches thru provides fields
- added --dbonly option to -R
2.7.6 - added --print-uris option
- fixed an http download bug (FS#667)
@ -1714,3 +1276,5 @@ VERSION DESCRIPTION
backed up, then it will be copied to "file.save"
- Changed db_find_conflicts() to ignore directories
1.0 - Initial Release
vim: set et spell spelllang=en_us:

286
README
View file

@ -6,7 +6,7 @@ Package Management) library. This document, while not exhaustive, also
indicates some limitations (on purpose, or sometimes due to its poor design) of
the library at the present time.
There is one special file, "alpm.h", which is the public interface that
There is one special file,"alpm.h", which is the public interface that
should be distributed and installed on systems with the library. Only
structures, data and functions declared within this file are made available to
the frontend. Lots of structures are of an opaque type and their fields are
@ -52,11 +52,13 @@ library is initialized.
* logcb: The callback function for "log" operations.
* dlcb: The callback function for download progress of each package.
* fetchcb: Callback for custom download function.
* totaldlcb: The callback function for overall download progress.
* eventcb: Callback for transaction messages.
* questioncb: Callback for selecting amongst choices.
* progresscb: Callback to handle display of transaction progress.
* gpgdir: Directory where GnuPG files are stored.
* arch: Allowed package architecture.
* deltaratio: Download deltas if possible; a ratio value.
* checkspace: Check disk space before installing.
* default_siglevel: Default signature verification level.
* local_file_siglevel: Signature verification level for local file upgrades.
@ -194,8 +196,8 @@ remove.c and sync.c).
The frontend is using a configuration file, usually "/etc/pacman.conf". Some
of these options are only useful for the frontend only (mainly the ones used to
control the output like verbosepkglist, or the behavior with cleanmethod).
The rest is used to configure the library.
control the output like totaldownload, or the behavior with cleanmethod and
syncfirst). The rest is used to configure the library.
[UPGRADE/REMOVE/SYNC]
@ -239,7 +241,7 @@ API CHANGES BETWEEN 3.1 AND 3.2
- alpm_checkdbconflicts()
- alpm_sync_newversion()
- alpm_deptest()
- error codes:
- error codes :
PM_ERR_DLT_INVALID, PM_ERR_LIBARCHIVE, PM_ERR_LIBDOWNLOAD and
PM_ERR_EXTERNAL_DOWNLOAD
- flags:
@ -352,7 +354,7 @@ API CHANGES BETWEEN 3.4 AND 3.5
- alpm_db_get_pkg() for normal targets
- alpm_find_dbs_satisfier() for versioned provisions
- alpm_find_grp_pkgs() for groups
- alpm_deptest() is replaced by the more flexible alpm_find_satisfier()
- alpm_deptest() is replaced by the more flexibile alpm_find_satisfier()
- size_t used for alpm_list_t sizes
- return type for alpm_list_count()
- parameter type in alpm_list_msort() and alpm_list_nth()
@ -362,11 +364,11 @@ API CHANGES BETWEEN 3.4 AND 3.5
- alpm_find_grp_pkgs()
- alpm_trans_get_flags()
- error codes:
PM_ERR_DISK_SPACE, PM_ERR_WRITE
- flags:
PM_TRANS_FLAG_NODEPVERSION, PM_TRANS_EVT_DISKSPACE_START,
PM_TRANS_EVT_DISKSPACE_DONE, PM_TRANS_CONV_SELECT_PROVIDER,
PM_TRANS_PROGRESS_DISKSPACE_START, PM_TRANS_PROGRESS_INTEGRITY_START
PM_ERR_DISK_SPACE, PM_ERR_WRITE
- flags
PM_TRANS_FLAG_NODEPVERSION, PM_TRANS_EVT_DISKSPACE_START,
PM_TRANS_EVT_DISKSPACE_DONE, PM_TRANS_CONV_SELECT_PROVIDER,
PM_TRANS_PROGRESS_DISKSPACE_START, PM_TRANS_PROGRESS_INTEGRITY_START
API CHANGES BETWEEN 3.5 AND 4.0
@ -419,7 +421,7 @@ API CHANGES BETWEEN 3.5 AND 4.0
- alpm_release
- alpm_remove_pkg
- alpm_sync_sysupgrade
- several structs are no longer opaque:
- several structs are no longer opaque
- alpm_conflict_t
- alpm_delta_t
- alpm_depend_t
@ -431,33 +433,19 @@ API CHANGES BETWEEN 3.5 AND 4.0
[ADDED]
- option functions:
- alpm_{get,set}_eventcb()
- alpm_option_{get,set}_convcb()
- alpm_option_{get,set}_progresscb()
alpm_{get,set}_eventcb(), alpm_option_{get,set}_convcb(),
alpm_option_{get,set}_progresscb()
- package signing functions:
- alpm_option_get_default_siglevel()
- alpm_option_set_default_siglevel()
- alpm_option_get_gpgdir()
- alpm_option_set_gpgdir()
- alpm_db_get_siglevel()
- alpm_siglist_cleanup()
- alpm_db_check_pgp_signature()
- alpm_pkg_check_pgp_signature()
- alpm_pkg_get_origin()
- alpm_pkg_get_sha256sum()
- alpm_pkg_get_base64_sig()
alpm_option_get_default_siglevel(), alpm_option_set_default_siglevel(),
alpm_option_get_gpgdir(), alpm_option_set_gpgdir(), alpm_db_get_siglevel(),
alpm_siglist_cleanup(), alpm_db_check_pgp_signature(), alpm_pkg_check_pgp_signature(),
alpm_pkg_get_origin(), alpm_pkg_get_sha256sum(), alpm_pkg_get_base64_sig()
- list functions:
- alpm_list_to_array()
- alpm_list_previous()
alpm_list_to_array(), alpm_list_previous()
- structs:
- alpm_backup_t
- alpm_file_t
- alpm_filelist_t
alpm_backup_t, alpm_file_t, alpm_filelist_t
- enums:
- alpm_siglevel_t
- alpm_sigstatus_t
- alpm_sigvalidity_t
- alpm_pkgfrom_t
alpm_siglevel_t, alpm_sigstatus_t, alpm_sigvalidity_t, alpm_pkgfrom_t
- error codes:
ALPM_ERR_DB_INVALID, ALPM_ERR_DB_INVALID_SIG, ALPM_ERR_GPGME,
ALPM_ERR_PKG_INVALID_CHECKSUM, ALPM_ERR_PKG_INVALID_SIG, ALPM_ERR_SIG_INVALID,
@ -484,10 +472,10 @@ API CHANGES BETWEEN 4.0 AND 4.1
- alpm_db_unregister_all -> alpm_unregister_all_syncdbs
- alpm_db_readgroup -> alpm_db_get_group
- alpm_db_set_pkgreason -> alpm_pkg_set_reason (handle parameter removed)
- alpm_time_t typedef used for all times:
- alpm_time_t typedef used for all times
- members of alpm_pgpkey_t
- return types of alpm_pkg_get_builddate and alpm_pkg_get_installdate
- delta options now use required ratio rather than on/off:
- delta options now use required ratio rather than on/off
- alpm_option_get_usedelta -> alpm_option_get_deltaratio
- alpm_option_set_usedelta -> alpm_option_set_deltaratio
@ -504,21 +492,21 @@ API CHANGES BETWEEN 4.0 AND 4.1
- alpm_db_usage_t
- alpm_db_set_usage()
- alpm_db_get_usage()
- wrapper functions for reading mtree files:
- wrapper functions for reading mtree files
- alpm_pkg_mtree_open()
- alpm_pkg_mtree_next()
- alpm_pkg_mtree_close()
- utility functions:
- utility functions
- alpm_pkg_find()
- alpm_pkg_compute_optionalfor()
- alpm_filelist_contains()
- types:
- types
- alpm_time_t
- alpm_errno_t
- flags:
ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING,
ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START,
ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START
- flags
ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING,
ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START,
ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START
API CHANGES BETWEEN 4.1 AND 4.2
@ -527,49 +515,49 @@ API CHANGES BETWEEN 4.1 AND 4.2
[CHANGED]
- alpm_filelist_t - removed member resolved_path
- alpm_filelist_contains - now returns alpm_file_t
- event callback:
- alpm_event_t renamed to alpm_event_type_t
- alpm_event_t union added
- alpm_event_cb now takes only an alpm_event_t parameter
- alpm_event_any_t, alpm_package_operation_t, alpm_event_package_operation_t,
alpm_event_optdep_removal_t, alpm_event_delta_patch_t, alpm_event_scriptlet_info_t,
alpm_event_database_missing_t, alpm_event_pkgdownload_t, alpm_event_pacnew_created_t,
alpm_event_pacsave_created_t, alpm_event_pacorig_created_t added
- ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START
- ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE
- question callback:
- alpm_question_t renamed to alpm_question_type_t
- alpm_question_t union added
- alpm_cb_question now takes only an alpm_question_t parameter
- alpm_question_any_t, alpm_question_install_ignorepkg_t, alpm_question_replace_t
alpm_question_conflict_t, alpm_question_corrupted_t, alpm_question_remove_pkgs_t,
alpm_question_select_provider_t, alpm_question_import_key_t added
- event callback
- alpm_event_t renamed to alpm_event_type_t
- alpm_event_t union added
- alpm_event_cb now takes only an alpm_event_t parameter
- alpm_event_any_t, alpm_package_operation_t, alpm_event_package_operation_t,
alpm_event_optdep_removal_t, alpm_event_delta_patch_t, alpm_event_scriptlet_info_t,
alpm_event_database_missing_t, alpm_event_pkgdownload_t, alpm_event_pacnew_created_t,
alpm_event_pacsave_created_t, alpm_event_pacorig_created_t added
- ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START
- ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE
- question callback
- alpm_question_t renamed to alpm_question_type_t
- alpm_question_t union added
- alpm_cb_question now takes only an alpm_question_t parameter
- alpm_question_any_t, alpm_question_install_ignorepkg_t, alpm_question_replace_t
alpm_question_conflict_t, alpm_question_corrupted_t, alpm_question_remove_pkgs_t,
alpm_question_select_provider_t, alpm_question_import_key_t added
[ADDED]
- memory management:
- memory management
- alpm_fileconflict_free()
- alpm_depmissing_free()
- alpm_conflict_free()
- alpm_dep_free()
- database usage:
- database usage
- alpm_db_usage_t
- alpm_db_set_usage()
- alpm_db_get_usage()
- assume installed:
- assume installed
- alpm_option_get_assumeinstalled()
- alpm_option_add_assumeinstalled()
- alpm_option_set_assumeinstalled()
- alpm_option_remove_assumeinstalled()
- using noupgrade/noextract:
- using noupgrade/noextract
- alpm_option_match_noupgrade()
- alpm_option_match_noextract()
- utility functions:
- utility functions
- alpm_dep_from_string()
- alpm_pkg_should_ignore()
- alpm_decode_signature()
- alpm_extract_keyid()
- flags:
ALPM_EVENT_RETRIEVE_DONE, ALPM_EVENT_RETRIEVE_FAILED, ALPM_EVENT_PKGDOWNLOAD_START,
- flags
- ALPM_EVENT_RETRIEVE_DONE, ALPM_EVENT_RETRIEVE_FAILED, ALPM_EVENT_PKGDOWNLOAD_START,
ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED, ALPM_EVENT_OPTDEP_REMOVAL,
ALPM_EVENT_PACNEW_CREATED, ALPM_EVENT_PACSVAE_CREATED, ALPM_EVENT_PACORIG_CREATED
@ -579,13 +567,13 @@ API CHANGES BETWEEN 4.2 AND 5.0
[REMOVED]
- alpm_siglevel_t - removed members ALPM_SIG_PACKAGE_SET, ALPM_SIG_PACKAGE_TRUST_SET
- removed .pacorig generation:
- removed .pacorig generation
- ALPM_EVENT_PACORIG_CREATED
- alpm_event_pacorig_created_t
- alpm_event_t.pacorig_created
[ADDED]
- hook support:
- hook support
- alpm_option_get_hookdirs()
- alpm_option_set_hookdirs()
- alpm_option_add_hookdir()
@ -595,164 +583,12 @@ API CHANGES BETWEEN 4.2 AND 5.0
- ALPM_EVENT_HOOK_START, ALPM_EVENT_HOOK_DONE
- ALPM_EVENT_HOOK_RUN_START, ALPM_EVENT_HOOK_RUN_DONE
- ALPM_ERR_TRANS_HOOK_FAILED
- different database extension support:
- different database extension support
- alpm_option_get_dbext()
- alpm_option_set_dbext()
- pkgbase accessor:
- pkgbase accessor
- alpm_pkg_get_base()
- transaction events:
- transaction events
- ALPM_EVENT_TRANSACTION_START, ALPM_EVENT_TRANSACTION_DONE
- database unlocking:
- database unlocking
- alpm_unlock()
API CHANGES BETWEEN 5.0 AND 5.1
===============================
[CHANGED]
- alpm_errno_t - added member ALPM_ERR_OK
- alpm_siglevel_t - value of ALPM_SIG_USE_DEFAULT changed
- functions using bitfields return/pass an int instead of an enum:
- alpm_option_get_default_siglevel()
- alpm_option_set_default_siglevel()
- alpm_option_get_remote_file_siglevel()
- alpm_option_set_remote_file_siglevel()
- alpm_register_syncdb()
- alpm_db_get_siglevel()
- alpm_db_set_usage()
- alpm_db_get_usage()
- alpm_pkg_load()
- alpm_pkg_get_validation()
- alpm_trans_get_flags()
- alpm_trans_init()
- alpm_option_get_local_file_siglevel()
- alpm_option_set_local_file_siglevel()
[ADDED]
- overwrite support:
- alpm_option_get_overwrite_files()
- alpm_option_set_overwrite_files()
- alpm_option_add_overwrite_file()
- alpm_option_remove_overwrite_file()
- download timeout control:
- alpm_option_set_disable_dl_timeout()
- access make/checkdepends info:
- alpm_pkg_get_checkdepends()
- alpm_pkg_get_makedepends()
- check pacman capabilities:
- alpm_capabilities()
- duplicate and add to list:
- alpm_list_append_strdup()
API CHANGES BETWEEN 5.1 AND 5.2
===============================
[REMOVED]
- package delta support:
- alpm_delta_t
- alpm_event_delta_patch_t
- alpm_event_t union - removed alpm_event_delta_patch_t
- ALPM_EVENT_DELTA_INTEGRITY_START, ALPM_EVENT_DELTA_INTEGRITY_DONE,
ALPM_EVENT_DELTA_PATCHES_START, ALPM_EVENT_DELTA_PATCHES_DONE,
ALPM_EVENT_DELTA_PATCH_START, ALPM_EVENT_DELTA_PATCH_DONE,
ALPM_EVENT_DELTA_PATCH_FAILED
- ALPM_ERR_DLT_INVALID, ALPM_ERR_DLT_PATCHFAILED
- alpm_option_get_deltaratio()
- alpm_option_set_deltaratio()
- alpm_pkg_get_deltas()
- alpm_pkg_unused_deltas()
- alpm_transflag_t - removed member ALPM_TRANS_FLAG_FORCE
[CHANGED]
- alpm_errno_t - added member ALPM_ERR_MISSING_CAPABILITY_SIGNATURES
- alpm_sync_newversion() replaced with alpm_sync_get_new_version() which
does not filter on any ALPM_DB_USAGE_*.
API CHANGES BETWEEN 5.2 AND 6.0
===============================
[REMOVED]
- ALPM_EVENT_PKGDOWNLOAD_START, ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED
- ALPM_ERR_PKG_REPO_NOT_FOUND
- old TotalDownload implementation:
- alpm_cb_totaldl
- alpm_option_get_totaldlcb()
- alpm_option_set_totaldlcb()
[CHANGED]
- alpm_db_update() now accepts a list of databases rather than a single database.
- alpm_fetch_pkgurl() accepts a list of packages to download.
- alpm_db_search() now has an additional parameter and returns success status
- ALPM_EVENT_RETRIEVE_* -> ALPM_EVENT_DB_RETRIEVE_* and ALPM_EVENT_PKG_RETRIEVE_*
- alpm_cb_download pass event and data
- multi architecture support:
- alpm_option_get_arch() -> alpm_option_get_architectures()
- alpm_option_set_arch() -> alpm_option_set_architectures()
- alpm_db_get_servers() copies parameter data
[ADDED]
- parallel download support:
- alpm_option_set_parallel_downloads()
- alpm_option_get_parallel_downloads()
- file download events:
- alpm_download_event_type_t
- alpm_download_event_init_t
- alpm_download_event_progress_t
- alpm_download_event_completed_t
- download misc:
- ALPM_DOWNLOAD_RETRY
- alpm_download_event_retry_t
- alpm_event_pkg_retrieve_t
- multiarchitecture support:
- alpm_option_add_architecture()
- alpm_option_remove_architecture()
- misc:
- alpm_pkg_get_sig()
- callbacks add front-end provided context
API CHANGES BETWEEN 6.0 AND 6.1
===============================
[REMOVED]
- alpm_trans_t
[CHANGED]
- alpm_conflict_t - full package added as member, removing package name and name
hash members
- alpm_question_import_key_t - holds key uid and fingerprint rather than alpm_pgpkey_t
- alpm_pkgreason_t - added ALPM_PKG_REASON_UNKNOWN
- alpm_transflag_t - added ALPM_TRANS_FLAG_NOHOOKS
[ADDED]
- extensible package data type:
- alpm_pkg_xdata_t
- alpm_pkg_get_xdata()
- accessor functions:
- alpm_db_get_handle()
- alpm_pkg_get_handle()
- cache server support:
- alpm_db_get_cache_servers()
- alpm_db_set_cache_servers()
- alpm_db_add_cache_server()
API CHANGES BETWEEN 6.1 AND 7.0
===============================
[ADDED]
- sandbox functions:
- alpm_option_get_sandboxuser()
- alpm_option_set_sandboxuser()
- alpm_option_set_disable_sandbox()
- alpm_sandbox_setup_child()
API CHANGES BETWEEN 7.0 AND 7.1
===============================
[CHANGED]
- error codes:
PM_ERR_TRANS_COMMITING renamed to PM_ERR_TRANS_COMMITTING

34
RELEASE
View file

@ -1,34 +0,0 @@
The following checklist should be used for making a pacman release.
- Ensure "ninja dist" succeeds
- Call a freeze to development.
- Send translation updates to Transifex at least two weeks before a major
release (see below). At this stage, strings can only be changed for a
major issue.
- Update NEWS and README files
- Pull translation updates from Transifex
- Update version in meson.build as described in file
- Update doc/index.asciidoc
- Create a signed git tag (git tag -s vX.Y.Z -m "commit message")
- Create and sign release tarballs (generate with "ninja dist")
- Create release on gitlab project page
- Upload release tarball and signature to gitlab ("glab release upload ...")
- Create branch release/?.?.x (with ?.? replaced by major version number)
- Update .gitlab-ci.yml to point the website pages run at release branch
Transifex updates are handled using the transifex client. The basic process is:
- Pull updates from transifex ("tx pull -f --minimum-perc 75")
- Update po files ("./build-aux/update-po")
- Fix all translation errors found (e.g. using "mint-check-translations")
- Add any new locales to the relevant LINGUAS file
- Optional: Make any manual changes needed (e.g. fixing spacing in a string)
and update po files again
- Push updated po files to transifex ("tx push -s -t --skip")
Point releases:
- all bugs fixes slated for the release branch must first land on master
(unless no longer relevant)
- following the initial post-release period when the release and master
branches may be kept in sync, commits are backported to the release branch
using "git cherry-pick -x"
- translation updates should be pulled onto the release branch only

View file

@ -3,7 +3,7 @@ currently. Our translations are currently maintained in Transifex; please read
doc/translation-help.txt for more details.
Below is a list of past translators before we switched to Transifex; more can
be found by looking in the Git history.
be found by looking in the GIT history.
If your language is not already in the various po/ subdirectories and you wish
it was, set up a team in Transifex for your language and we will be happy to

6
autogen.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/sh -x
autoreconf -i
patch -d build-aux -Np0 -i ltmain-asneeded.patch
exit 0

View file

@ -1,11 +0,0 @@
#!/usr/bin/python3
import sys
for path in sys.argv[1:]:
print('# -----------------------------------')
print('# ' + path + ':')
print('# -----------------------------------')
with open(path, 'r') as f:
for line in f:
print('# ' + line, end='')

View file

@ -1,29 +0,0 @@
#!@BASH@
input=$1
output=$2
mode=$3
sed \
-e "s|@rootdir[@]|@ROOTDIR@|g" \
-e "s|@localedir[@]|@LOCALEDIR@|g" \
-e "s|@sysconfdir[@]|@sysconfdir@|g" \
-e "s|@localstatedir[@]|@localstatedir@|g" \
-e "s|@libmakepkgdir[@]|@LIBMAKEPKGDIR@|g" \
-e "s|@pkgdatadir[@]|@PKGDATADIR@|g" \
-e "s|@keyringdir[@]|@KEYRINGDIR@|g" \
-e "s|@prefix[@]|@PREFIX@|g" \
-e "1s|#!/bin/bash|#!@BASH@|g" \
-e "s|@PACKAGE_VERSION[@]|@PACKAGE_VERSION@|g" \
-e "s|@PACKAGE_NAME[@]|@PACKAGE_NAME@|g" \
-e "s|@BUILDSCRIPT[@]|@BUILDSCRIPT@|g" \
-e "s|@TEMPLATE_DIR[@]|@TEMPLATE_DIR@|g" \
-e "s|@DEBUGSUFFIX[@]|@DEBUGSUFFIX@|g" \
-e "s|@INODECMD[@]|@INODECMD@|g" \
-e "s|@FILECMD[@]|@FILECMD@|g" \
-e "s|@BSDTAR_NO_READ_SPARSE[@]|@BSDTAR_NO_READ_SPARSE@|g" \
"$input" >"$output"
if [[ $mode ]]; then
chmod "$mode" "$output"
fi

View file

@ -0,0 +1,33 @@
--- ltmain.sh.orig 2013-06-26 14:31:53.472627840 +1000
+++ ltmain.sh 2013-06-26 14:30:56.137038936 +1000
@@ -5800,6 +5800,14 @@
arg=$func_stripname_result
;;
+ -Wl,*--as-needed*)
+ deplibs="$deplibs $wl--as-needed"
+ ;;
+
+ -Wl,*--no-as-needed*)
+ deplibs="$deplibs $wl--no-as-needed"
+ ;;
+
-Wl,*)
func_stripname '-Wl,' '' "$arg"
args=$func_stripname_result
@@ -6160,6 +6168,15 @@
lib=
found=no
case $deplib in
+ -Wl,--as-needed|-Wl,--no-as-needed)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ fi
+ continue
+ ;;
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
|-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
if test "$linkmode,$pass" = "prog,link"; then

View file

@ -1,10 +0,0 @@
#!/bin/sh
set -eu
# this is needed mostly because $DESTDIR is provided as a variable,
# and we need to create the target directory...
mkdir -vp "$(dirname "${DESTDIR:-}$2")"
rm -f "${DESTDIR:-}$2"
ln -vs "$1" "${DESTDIR:-}$2"

View file

@ -1,17 +0,0 @@
#!/usr/bin/python
import json
import sys
def print_result(result):
print('==================================================================')
print(result['name'])
print(' '.join(result['command']))
print('==================================================================')
print(result['stdout'])
with open(sys.argv[1], 'r') as f:
for line in f:
result = json.loads(line)
if result['result'] == 'FAIL':
print_result(result)

View file

@ -1,6 +0,0 @@
#!/bin/bash
# This script serves as a trampoline for running scripts which depend on
# libmakepkg with the libmakepkg within the build tree.
MAKEPKG_LIBRARY=@BUILDDIR@/libmakepkg exec @BASH@ -$- @REAL_PROGPATH@ "$@"

652
build-aux/tap-driver.sh Executable file
View file

@ -0,0 +1,652 @@
#! /bin/sh
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
# 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, 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/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
scriptversion=2011-12-27.17; # UTC
# Make unconditional expansion of undefined variables an error. This
# helps a lot in preventing typo-related bugs.
set -u
me=tap-driver.sh
fatal ()
{
echo "$me: fatal: $*" >&2
exit 1
}
usage_error ()
{
echo "$me: $*" >&2
print_usage >&2
exit 2
}
print_usage ()
{
cat <<END
Usage:
tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}]
[--enable-hard-errors={yes|no}] [--ignore-exit]
[--diagnostic-string=STRING] [--merge|--no-merge]
[--comments|--no-comments] [--] TEST-COMMAND
The \`--test-name', \`--log-file' and \`--trs-file' options are mandatory.
END
}
# TODO: better error handling in option parsing (in particular, ensure
# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting.
log_file= # Where to save the result and output of the test script.
trs_file= # Where to save the metadata of the test run.
expect_failure=0
color_tests=0
merge=0
ignore_exit=0
comments=0
diag_string='#'
while test $# -gt 0; do
case $1 in
--help) print_usage; exit $?;;
--version) echo "$me $scriptversion"; exit $?;;
--test-name) test_name=$2; shift;;
--log-file) log_file=$2; shift;;
--trs-file) trs_file=$2; shift;;
--color-tests) color_tests=$2; shift;;
--expect-failure) expect_failure=$2; shift;;
--enable-hard-errors) shift;; # No-op.
--merge) merge=1;;
--no-merge) merge=0;;
--ignore-exit) ignore_exit=1;;
--comments) comments=1;;
--no-comments) comments=0;;
--diagnostic-string) diag_string=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
esac
shift
done
test $# -gt 0 || usage_error "missing test command"
case $expect_failure in
yes) expect_failure=1;;
*) expect_failure=0;;
esac
if test $color_tests = yes; then
init_colors='
color_map["red"]="" # Red.
color_map["grn"]="" # Green.
color_map["lgn"]="" # Light green.
color_map["blu"]="" # Blue.
color_map["mgn"]="" # Magenta.
color_map["std"]="" # No color.
color_for_result["ERROR"] = "mgn"
color_for_result["PASS"] = "grn"
color_for_result["XPASS"] = "red"
color_for_result["FAIL"] = "red"
color_for_result["XFAIL"] = "lgn"
color_for_result["SKIP"] = "blu"'
else
init_colors=''
fi
# :; is there to work around a bug in bash 3.2 (and earlier) which
# does not always set '$?' properly on redirection failure.
# See the Autoconf manual for more details.
:;{
(
# Ignore common signals (in this subshell only!), to avoid potential
# problems with Korn shells. Some Korn shells are known to propagate
# to themselves signals that have killed a child process they were
# waiting for; this is done at least for SIGINT (and usually only for
# it, in truth). Without the `trap' below, such a behaviour could
# cause a premature exit in the current subshell, e.g., in case the
# test command it runs gets terminated by a SIGINT. Thus, the awk
# script we are piping into would never seen the exit status it
# expects on its last input line (which is displayed below by the
# last `echo $?' statement), and would thus die reporting an internal
# error.
# For more information, see the Autoconf manual and the threads:
# <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
# <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
trap : 1 3 2 13 15
if test $merge -gt 0; then
exec 2>&1
else
exec 2>&3
fi
"$@"
echo $?
) | LC_ALL=C ${AM_TAP_AWK-awk} \
-v me="$me" \
-v test_script_name="$test_name" \
-v log_file="$log_file" \
-v trs_file="$trs_file" \
-v expect_failure="$expect_failure" \
-v merge="$merge" \
-v ignore_exit="$ignore_exit" \
-v comments="$comments" \
-v diag_string="$diag_string" \
'
# FIXME: the usages of "cat >&3" below could be optimized when using
# FIXME: GNU awk, and/on on systems that supports /dev/fd/.
# Implementation note: in what follows, `result_obj` will be an
# associative array that (partly) simulates a TAP result object
# from the `TAP::Parser` perl module.
## ----------- ##
## FUNCTIONS ##
## ----------- ##
function fatal(msg)
{
print me ": " msg | "cat >&2"
exit 1
}
function abort(where)
{
fatal("internal error " where)
}
# Convert a boolean to a "yes"/"no" string.
function yn(bool)
{
return bool ? "yes" : "no";
}
function add_test_result(result)
{
if (!test_results_index)
test_results_index = 0
test_results_list[test_results_index] = result
test_results_index += 1
test_results_seen[result] = 1;
}
# Whether the test script should be re-run by "make recheck".
function must_recheck()
{
for (k in test_results_seen)
if (k != "XFAIL" && k != "PASS" && k != "SKIP")
return 1
return 0
}
# Whether the content of the log file associated to this test should
# be copied into the "global" test-suite.log.
function copy_in_global_log()
{
for (k in test_results_seen)
if (k != "PASS")
return 1
return 0
}
# FIXME: this can certainly be improved ...
function get_global_test_result()
{
if ("ERROR" in test_results_seen)
return "ERROR"
if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
return "FAIL"
all_skipped = 1
for (k in test_results_seen)
if (k != "SKIP")
all_skipped = 0
if (all_skipped)
return "SKIP"
return "PASS";
}
function stringify_result_obj(result_obj)
{
if (result_obj["is_unplanned"] || result_obj["number"] != testno)
return "ERROR"
if (plan_seen == LATE_PLAN)
return "ERROR"
if (result_obj["directive"] == "TODO")
return result_obj["is_ok"] ? "XPASS" : "XFAIL"
if (result_obj["directive"] == "SKIP")
return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
if (length(result_obj["directive"]))
abort("in function stringify_result_obj()")
return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
}
function decorate_result(result)
{
color_name = color_for_result[result]
if (color_name)
return color_map[color_name] "" result "" color_map["std"]
# If we are not using colorized output, or if we do not know how
# to colorize the given result, we should return it unchanged.
return result
}
function report(result, details)
{
if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
{
msg = ": " test_script_name
add_test_result(result)
}
else if (result == "#")
{
msg = " " test_script_name ":"
}
else
{
abort("in function report()")
}
if (length(details))
msg = msg " " details
# Output on console might be colorized.
print decorate_result(result) msg
# Log the result in the log file too, to help debugging (this is
# especially true when said result is a TAP error or "Bail out!").
print result msg | "cat >&3";
}
function testsuite_error(error_message)
{
report("ERROR", "- " error_message)
}
function handle_tap_result()
{
details = result_obj["number"];
if (length(result_obj["description"]))
details = details " " result_obj["description"]
if (plan_seen == LATE_PLAN)
{
details = details " # AFTER LATE PLAN";
}
else if (result_obj["is_unplanned"])
{
details = details " # UNPLANNED";
}
else if (result_obj["number"] != testno)
{
details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
details, testno);
}
else if (result_obj["directive"])
{
details = details " # " result_obj["directive"];
if (length(result_obj["explanation"]))
details = details " " result_obj["explanation"]
}
report(stringify_result_obj(result_obj), details)
}
# `skip_reason` should be empty whenever planned > 0.
function handle_tap_plan(planned, skip_reason)
{
planned += 0 # Avoid getting confused if, say, `planned` is "00"
if (length(skip_reason) && planned > 0)
abort("in function handle_tap_plan()")
if (plan_seen)
{
# Error, only one plan per stream is acceptable.
testsuite_error("multiple test plans")
return;
}
planned_tests = planned
# The TAP plan can come before or after *all* the TAP results; we speak
# respectively of an "early" or a "late" plan. If we see the plan line
# after at least one TAP result has been seen, assume we have a late
# plan; in this case, any further test result seen after the plan will
# be flagged as an error.
plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
# If testno > 0, we have an error ("too many tests run") that will be
# automatically dealt with later, so do not worry about it here. If
# $plan_seen is true, we have an error due to a repeated plan, and that
# has already been dealt with above. Otherwise, we have a valid "plan
# with SKIP" specification, and should report it as a particular kind
# of SKIP result.
if (planned == 0 && testno == 0)
{
if (length(skip_reason))
skip_reason = "- " skip_reason;
report("SKIP", skip_reason);
}
}
function extract_tap_comment(line)
{
if (index(line, diag_string) == 1)
{
# Strip leading `diag_string` from `line`.
line = substr(line, length(diag_string) + 1)
# And strip any leading and trailing whitespace left.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
# Return what is left (if any).
return line;
}
return "";
}
# When this function is called, we know that line is a TAP result line,
# so that it matches the (perl) RE "^(not )?ok\b".
function setup_result_obj(line)
{
# Get the result, and remove it from the line.
result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
sub("^(not )?ok[ \t]*", "", line)
# If the result has an explicit number, get it and strip it; otherwise,
# automatically assing the next progresive number to it.
if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
{
match(line, "^[0-9]+")
# The final `+ 0` is to normalize numbers with leading zeros.
result_obj["number"] = substr(line, 1, RLENGTH) + 0
line = substr(line, RLENGTH + 1)
}
else
{
result_obj["number"] = testno
}
if (plan_seen == LATE_PLAN)
# No further test results are acceptable after a "late" TAP plan
# has been seen.
result_obj["is_unplanned"] = 1
else if (plan_seen && testno > planned_tests)
result_obj["is_unplanned"] = 1
else
result_obj["is_unplanned"] = 0
# Strip trailing and leading whitespace.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
# This will have to be corrected if we have a "TODO"/"SKIP" directive.
result_obj["description"] = line
result_obj["directive"] = ""
result_obj["explanation"] = ""
if (index(line, "#") == 0)
return # No possible directive, nothing more to do.
# Directives are case-insensitive.
rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
# See whether we have the directive, and if yes, where.
pos = match(line, rx "$")
if (!pos)
pos = match(line, rx "[^a-zA-Z0-9_]")
# If there was no TAP directive, we have nothing more to do.
if (!pos)
return
# Let`s now see if the TAP directive has been escaped. For example:
# escaped: ok \# SKIP
# not escaped: ok \\# SKIP
# escaped: ok \\\\\# SKIP
# not escaped: ok \ # SKIP
if (substr(line, pos, 1) == "#")
{
bslash_count = 0
for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
bslash_count += 1
if (bslash_count % 2)
return # Directive was escaped.
}
# Strip the directive and its explanation (if any) from the test
# description.
result_obj["description"] = substr(line, 1, pos - 1)
# Now remove the test description from the line, that has been dealt
# with already.
line = substr(line, pos)
# Strip the directive, and save its value (normalized to upper case).
sub("^[ \t]*#[ \t]*", "", line)
result_obj["directive"] = toupper(substr(line, 1, 4))
line = substr(line, 5)
# Now get the explanation for the directive (if any), with leading
# and trailing whitespace removed.
sub("^[ \t]*", "", line)
sub("[ \t]*$", "", line)
result_obj["explanation"] = line
}
function get_test_exit_message(status)
{
if (status == 0)
return ""
if (status !~ /^[1-9][0-9]*$/)
abort("getting exit status")
if (status < 127)
exit_details = ""
else if (status == 127)
exit_details = " (command not found?)"
else if (status >= 128 && status <= 255)
exit_details = sprintf(" (terminated by signal %d?)", status - 128)
else if (status > 256 && status <= 384)
# We used to report an "abnormal termination" here, but some Korn
# shells, when a child process die due to signal number n, can leave
# in $? an exit status of 256+n instead of the more standard 128+n.
# Apparently, both behaviours are allowed by POSIX (2008), so be
# prepared to handle them both. See also Austing Group report ID
# 0000051 <http://www.austingroupbugs.net/view.php?id=51>
exit_details = sprintf(" (terminated by signal %d?)", status - 256)
else
# Never seen in practice.
exit_details = " (abnormal termination)"
return sprintf("exited with status %d%s", status, exit_details)
}
function write_test_results()
{
print ":global-test-result: " get_global_test_result() > trs_file
print ":recheck: " yn(must_recheck()) > trs_file
print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
for (i = 0; i < test_results_index; i += 1)
print ":test-result: " test_results_list[i] > trs_file
close(trs_file);
}
BEGIN {
## ------- ##
## SETUP ##
## ------- ##
'"$init_colors"'
# Properly initialized once the TAP plan is seen.
planned_tests = 0
COOKED_PASS = expect_failure ? "XPASS": "PASS";
COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
# Enumeration-like constants to remember which kind of plan (if any)
# has been seen. It is important that NO_PLAN evaluates "false" as
# a boolean.
NO_PLAN = 0
EARLY_PLAN = 1
LATE_PLAN = 2
testno = 0 # Number of test results seen so far.
bailed_out = 0 # Whether a "Bail out!" directive has been seen.
# Whether the TAP plan has been seen or not, and if yes, which kind
# it is ("early" is seen before any test result, "late" otherwise).
plan_seen = NO_PLAN
## --------- ##
## PARSING ##
## --------- ##
is_first_read = 1
while (1)
{
# Involutions required so that we are able to read the exit status
# from the last input line.
st = getline
if (st < 0) # I/O error.
fatal("I/O error while reading from input stream")
else if (st == 0) # End-of-input
{
if (is_first_read)
abort("in input loop: only one input line")
break
}
if (is_first_read)
{
is_first_read = 0
nextline = $0
continue
}
else
{
curline = nextline
nextline = $0
$0 = curline
}
# Copy any input line verbatim into the log file.
print | "cat >&3"
# Parsing of TAP input should stop after a "Bail out!" directive.
if (bailed_out)
continue
# TAP test result.
if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
{
testno += 1
setup_result_obj($0)
handle_tap_result()
}
# TAP plan (normal or "SKIP" without explanation).
else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
{
# The next two lines will put the number of planned tests in $0.
sub("^1\\.\\.", "")
sub("[^0-9]*$", "")
handle_tap_plan($0, "")
continue
}
# TAP "SKIP" plan, with an explanation.
else if ($0 ~ /^1\.\.0+[ \t]*#/)
{
# The next lines will put the skip explanation in $0, stripping
# any leading and trailing whitespace. This is a little more
# tricky in truth, since we want to also strip a potential leading
# "SKIP" string from the message.
sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
sub("[ \t]*$", "");
handle_tap_plan(0, $0)
}
# "Bail out!" magic.
# Older versions of prove and TAP::Harness (e.g., 3.17) did not
# recognize a "Bail out!" directive when preceded by leading
# whitespace, but more modern versions (e.g., 3.23) do. So we
# emulate the latter, "more modern" behaviour.
else if ($0 ~ /^[ \t]*Bail out!/)
{
bailed_out = 1
# Get the bailout message (if any), with leading and trailing
# whitespace stripped. The message remains stored in `$0`.
sub("^[ \t]*Bail out![ \t]*", "");
sub("[ \t]*$", "");
# Format the error message for the
bailout_message = "Bail out!"
if (length($0))
bailout_message = bailout_message " " $0
testsuite_error(bailout_message)
}
# Maybe we have too look for dianogtic comments too.
else if (comments != 0)
{
comment = extract_tap_comment($0);
if (length(comment))
report("#", comment);
}
}
## -------- ##
## FINISH ##
## -------- ##
# A "Bail out!" directive should cause us to ignore any following TAP
# error, as well as a non-zero exit status from the TAP producer.
if (!bailed_out)
{
if (!plan_seen)
{
testsuite_error("missing test plan")
}
else if (planned_tests != testno)
{
bad_amount = testno > planned_tests ? "many" : "few"
testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
bad_amount, planned_tests, testno))
}
if (!ignore_exit)
{
# Fetch exit status from the last line.
exit_message = get_test_exit_message(nextline)
if (exit_message)
testsuite_error(exit_message)
}
}
write_test_results()
exit 0
} # End of "BEGIN" block.
'
# TODO: document that we consume the file descriptor 3 :-(
} 3>"$log_file"
test $? -eq 0 || fatal "I/O or internal error"
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View file

@ -1,8 +0,0 @@
#! /bin/sh
OLD=$1
NEW=$2
for file in $(git grep -l "Copyright .* Pacman Development" | grep -v "\.po"); do \
sed -i -e "/Copyright (/s/-${OLD}/-${NEW}/" -e "/Copyright (/s/ ${OLD}/ ${OLD}-${NEW}/" "$file"
done

View file

@ -1,39 +0,0 @@
#!/bin/bash
find_build_directory() {
local build_dirs=(*/build.ninja)
if [[ ! -e ${build_dirs[0]} ]]; then
echo "error: No build directory found. Have you run 'meson build' yet?" >&2
return 1
elif (( ${#build_dirs[*]} > 1 )); then
echo "error: Multiple build directories found. Unable to proceed." >&2
return 1
fi
printf '%s\n' "${build_dirs[0]%/*}"
}
filter_targets_by_name() {
if command -v jq &>/dev/null; then
jq --arg re "$1" -r 'map(.name)[] | select(match($re))'
else
json_pp | awk -v filter="$1" -F'[:"]' \
'$2 == "name" && $(NF - 1) ~ filter { print $(NF - 1) }'
fi
}
# Make things simple and require that we're in the build root rather than
# trying to chase down the location of this script and the relative build dir.
if [[ ! -d .git ]]; then
echo "This script must be run from the root of the repository" >&2
exit 1
fi
build_dir=$(find_build_directory) || exit 1
mapfile -t targets < \
<(meson introspect "$build_dir" --targets | filter_targets_by_name "-update-po$")
ninja -C "$build_dir" "${targets[@]}"

575
configure.ac Normal file
View file

@ -0,0 +1,575 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
# Minimum version of autoconf required
AC_PREREQ(2.62)
# UPDATING VERSION NUMBERS FOR RELEASES
#
# libalpm:
# current
# The most recent interface number that this library implements.
# revision
# The implementation number of the current interface.
# age
# The difference between the newest and oldest interfaces that this library
# implements. In other words, the library implements all the interface
# numbers in the range from number current - age to current.
#
# 1. Start with version information of `0:0:0' for each libtool library.
# 2. Update the version information only immediately before a public release of
# your software. More frequent updates are unnecessary, and only guarantee
# that the current interface number gets larger faster.
# 3. If the library source code has changed at all since the last update, then
# increment revision (`c:r:a' becomes `c:r+1:a').
# 4. If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0.
# 5. If any interfaces have been added since the last public release, then
# increment age.
# 6. If any interfaces have been removed since the last public release, then
# set age to 0.
#
# pacman:
# Extreme huge major changes:
# pacman_version_major += 1
# pacman_version_minor = 0
# pacman_version_micro = 0
#
# Real releases:
# pacman_version_minor += 1
# pacman_version_micro = 0
#
# Bugfix releases:
# pacman_version_micro += 1
m4_define([lib_current], [10])
m4_define([lib_revision], [2])
m4_define([lib_age], [0])
m4_define([pacman_version_major], [5])
m4_define([pacman_version_minor], [0])
m4_define([pacman_version_micro], [2])
m4_define([pacman_version],
[pacman_version_major.pacman_version_minor.pacman_version_micro])
# Autoconf initialization
AC_INIT([pacman], [pacman_version], [pacman-dev@archlinux.org])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_REQUIRE_AUX_FILE([tap-driver.sh])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.11 foreign])
AM_SILENT_RULES([yes])
LT_INIT
LIB_VERSION=`expr lib_current - lib_age`.lib_age.lib_revision
LIB_VERSION_INFO="lib_current:lib_revision:lib_age"
# Respect empty CFLAGS during compiler tests
if test "x$CFLAGS" = "x"; then
CFLAGS=""
fi
# Set subsitution values for version stuff in Makefiles and anywhere else,
# and put LIB_VERSION in config.h
AC_SUBST(LIB_VERSION)
AC_SUBST(LIB_VERSION_INFO)
AC_DEFINE_UNQUOTED([LIB_VERSION], ["$LIB_VERSION"], [libalpm version number])
# Help line for root directory
AC_ARG_WITH(root-dir,
AS_HELP_STRING([--with-root-dir=path], [set the location of the root operating directory]),
[ROOTDIR=$withval], [ROOTDIR=/])
# Help line for package extension
AC_ARG_WITH(pkg-ext,
AS_HELP_STRING([--with-pkg-ext=ext], [set the file extension used by packages]),
[PKGEXT=$withval], [PKGEXT=.pkg.tar.gz])
# Help line for source package directory
AC_ARG_WITH(src-ext,
AS_HELP_STRING([--with-src-ext=ext], [set the file extension used by source packages]),
[SRCEXT=$withval], [SRCEXT=.src.tar.gz])
# Help line for buildscript filename
AC_ARG_WITH(buildscript,
AS_HELP_STRING([--with-buildscript=name], [set the build script name used by makepkg]),
[BUILDSCRIPT=$withval], [BUILDSCRIPT=PKGBUILD])
# Help line for buildscript filename
AC_ARG_WITH(makepkg-template-dir,
AS_HELP_STRING([--with-makepkg-template-dir=name], [set the template dir used by makepkg-template]),
[TEMPLATE_DIR=$withval], [TEMPLATE_DIR=/usr/share/makepkg-template])
# Help line for debug package suffix
AC_ARG_WITH(debug-suffix,
AS_HELP_STRING([--with-debug-suffix=name], [set the suffix for split debugging symbol packages used by makepkg]),
[DEBUGSUFFIX=$withval], [DEBUGSUFFIX=debug])
# Help line for changing shell used to run install scriptlets
AC_ARG_WITH(scriptlet-shell,
AS_HELP_STRING([--with-scriptlet-shell=shell],
[set the full path to the shell used to run install scriptlets]),
[SCRIPTLET_SHELL=$withval], [SCRIPTLET_SHELL=/bin/sh])
# Help line for ldconfig path
AC_ARG_WITH(ldconfig,
AS_HELP_STRING([--with-ldconfig=path],
[set the full path to ldconfig]),
[LDCONFIG=$withval], [LDCONFIG=/sbin/ldconfig])
# Help line for using OpenSSL
AC_ARG_WITH(openssl,
AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations instead of internal routines]),
[], [with_openssl=check])
# Help line for using gpgme
AC_ARG_WITH(gpgme,
AS_HELP_STRING([--with-gpgme], [use GPGME for PGP signature verification]),
[], [with_gpgme=check])
# Help line for using libcurl
AC_ARG_WITH(libcurl,
AS_HELP_STRING([--with-libcurl], [use libcurl for the internal downloader]),
[], [with_libcurl=check])
# Help line for documentation
AC_ARG_ENABLE(doc,
AS_HELP_STRING([--disable-doc], [prevent make from looking at doc/ dir]),
[wantdoc=$enableval], [wantdoc=yes])
# Help line for doxygen
AC_ARG_ENABLE(doxygen,
AS_HELP_STRING([--enable-doxygen], [build your own API docs via Doxygen]),
[wantdoxygen=$enableval], [wantdoxygen=no])
# Help line for debug
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug], [enable debugging support]),
[debug=$enableval], [debug=no])
# Help line for compiler warning flags
AC_ARG_ENABLE(warningflags,
AS_HELP_STRING([--enable-warningflags], [enable extra compiler warning flags]),
[warningflags=$enableval], [warningflags=no])
# Help line for using git version in pacman version string
AC_ARG_ENABLE(git-version,
AS_HELP_STRING([--enable-git-version],
[enable use of git version in version string if available]),
[wantgitver=$enableval], [wantgitver=no])
# Enable large file support if available (must be enabled before
# testing compilation against gpgme).
AC_SYS_LARGEFILE
# Record large file flags in pkgconfig file
if test "$enable_largefile" != no; then
if test "$ac_cv_sys_file_offset_bits" != 'no'; then
LFS_CFLAGS="-D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
fi
fi
AC_SUBST(LFS_CFLAGS)
# Checks for programs.
AC_PROG_AWK
AC_PROG_CC_C99
AC_PROG_INSTALL
AC_CHECK_PROGS([PYTHON], [python2.7 python2 python], [false])
AC_PATH_PROGS([BASH_SHELL], [bash bash4], [false])
# check for perl 5.10.1 (needed by makepkg-template)
AC_PATH_PROG([PERL],[perl])
AC_DEFUN([AX_PROG_PERL_VERSION],
[AC_CACHE_CHECK([for Perl version $1 or later], [ax_cv_prog_perl_version],
[AS_IF(["$PERL" -e 'require v$1;' >/dev/null 2>&1],
[ax_cv_prog_perl_version=yes],
[ax_cv_prog_perl_version=no])])
AS_IF([test x"$ax_cv_prog_perl_version" = xyes], [$2], [$3])])
AX_PROG_PERL_VERSION([5.10.1], [], [AC_MSG_ERROR([perl is too old])])
AS_IF([test "x$BASH_SHELL" = "xfalse"],
AC_MSG_WARN([*** bash >= 4.1.0 is required for pacman scripts]),
[bash_version_major=`$BASH_SHELL -c 'echo "${BASH_VERSINFO[[0]]}"'`
bash_version_minor=`$BASH_SHELL -c 'echo "${BASH_VERSINFO[[1]]}"'`
ok=yes
if test "$bash_version_major" -lt 4; then
ok=no
fi
if test "$bash_version_major" -eq 4 && test "$bash_version_minor" -lt 1; then
ok=no
fi
if test "$ok" = "no"; then
AC_MSG_ERROR([*** bash >= 4.1.0 is required for pacman scripts])
fi
unset bash_version_major bash_version_minor ok])
# find installed gettext
AM_GNU_GETTEXT([external], [need-ngettext])
AM_GNU_GETTEXT_VERSION(0.13.1)
AC_CHECK_LIB([m], [fabs], ,
AC_MSG_ERROR([libm is needed to compile pacman!]))
# Check for libarchive
PKG_CHECK_MODULES(LIBARCHIVE, [libarchive >= 2.8.0], ,
AC_MSG_ERROR([*** libarchive >= 2.8.0 is needed to compile pacman!]))
# Check for OpenSSL
have_openssl=no
if test "x$with_openssl" != "xno"; then
PKG_CHECK_MODULES(LIBSSL, [libcrypto],
[AC_DEFINE(HAVE_LIBSSL, 1, [Define if libcrypto is available]) have_openssl=yes], have_openssl=no)
if test "x$have_openssl" = xno -a "x$with_openssl" = xyes; then
AC_MSG_ERROR([*** openssl support requested but libraries not found])
fi
fi
AM_CONDITIONAL(HAVE_LIBSSL, [test "$have_openssl" = "yes"])
# Check for libcurl
have_libcurl=no
if test "x$with_libcurl" != "xno"; then
PKG_CHECK_MODULES(LIBCURL, [libcurl >= 7.19.4],
[AC_DEFINE(HAVE_LIBCURL, 1, [Define if libcurl is available]) have_libcurl=yes], have_libcurl=no)
if test "x$have_libcurl" = xno -a "x$with_libcurl" = xyes; then
AC_MSG_ERROR([*** libcurl >= 7.19.4 is required for internal downloader support])
fi
fi
AM_CONDITIONAL(HAVE_LIBCURL, [test "$have_libcurl" = "yes"])
# Check for gpgme
AC_MSG_CHECKING(whether to link with libgpgme)
AS_IF([test "x$with_gpgme" != "xno"],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
have_gpgme=no
AS_IF([test "x$with_gpgme" != "xno"],
[AM_PATH_GPGME([1.3.0],
[LIBS_save="$LIBS"
CPPFLAGS_save="$CPPFLAGS"
CFLAGS_save="$CFLAGS"
LIBS="$LIBS $GPGME_LIBS"
CPPFLAGS="$CPPFLAGS $GPGME_CPPFLAGS"
CFLAGS="$CFLAGS $GPGME_CFLAGS"
AC_MSG_CHECKING([for sane gpgme])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <gpgme.h>]],
[[return gpgme_check_version("1.3.0");]])],
[AC_MSG_RESULT([yes])
have_gpgme=yes
AC_DEFINE([HAVE_LIBGPGME], [1], [Define if gpgme should be used to provide GPG signature support.])],
[AC_MSG_RESULT([no])
have_gpgme=no
unset GPGME_LIBS
unset GPGME_CFLAGS]
AS_IF([test "x$with_gpgme" = "xyes"],
[AC_MSG_FAILURE([*** gpgme >= 1.3.0 is needed for GPG signature support])])
)
LIBS="$LIBS_save"
CPPFLAGS="$CPPFLAGS_save"
CFLAGS="$CFLAGS_save"
unset CPPFLAGS_save
unset CFLAGS_save],)])
AS_IF([test "x$have_gpgme" = xno -a "x$with_gpgme" = xyes],
[AC_MSG_FAILURE([--with-gpgme was given, but gpgme was not found])])
AM_CONDITIONAL([HAVE_LIBGPGME], [test "x$have_gpgme" = "xyes"])
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h float.h glob.h langinfo.h libintl.h limits.h \
locale.h mntent.h netinet/in.h netinet/tcp.h \
stddef.h string.h sys/ioctl.h \
sys/mnttab.h sys/mount.h \
sys/param.h sys/statvfs.h sys/time.h sys/types.h \
sys/ucred.h syslog.h termios.h wchar.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_TYPE_INT64_T
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_STRUCT_TM
AC_TYPE_UID_T
AC_STRUCT_DIRENT_D_TYPE
PATH_MAX_DEFINED
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_GETMNTENT
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_MKTIME
AC_FUNC_STRCOLL
AC_CHECK_FUNCS([dup2 getcwd getmntinfo gettimeofday memmove memset \
mkdir realpath regcomp rmdir setenv setlocale strcasecmp \
strchr strcspn strdup strerror strndup strnlen strrchr \
strsep strstr strtol swprintf tcflush wcwidth uname])
AC_CHECK_MEMBERS([struct stat.st_blksize],,,[[#include <sys/stat.h>]])
# For the diskspace code
FS_STATS_TYPE
AC_CHECK_MEMBERS([struct statvfs.f_flag],,,[[#include <sys/statvfs.h>]])
AC_CHECK_MEMBERS([struct statfs.f_flags],,,[[#include <sys/param.h>
#include <sys/mount.h>]])
# Check if we can use symbol visibility support in GCC
GCC_VISIBILITY_CC
# Host-dependant definitions
INODECMD="stat -c '%i %n'"
OWNERCMD="stat -c '%u:%g'"
MODECMD="stat -c '%a'"
SIZECMD="stat -c %s"
SEDINPLACE="sed --follow-symlinks -i"
DUFLAGS="-sk --apparent-size"
STRIP_BINARIES="--strip-all"
STRIP_SHARED="--strip-unneeded"
STRIP_STATIC="--strip-debug"
case "${host_os}" in
*bsd*)
INODECMD="stat -f '%i %N'"
OWNERCMD="stat -f '%u:%g'"
MODECMD="stat -f '%Lp'"
SIZECMD="stat -f %z"
SEDINPLACE="sed -i \"\""
DUFLAGS="-sk"
;;
darwin*)
host_os_darwin=yes
INODECMD="/usr/bin/stat -f '%i %N'"
OWNERCMD="/usr/bin/stat -f '%u:%g'"
MODECMD="/usr/bin/stat -f '%Lp'"
SIZECMD="/usr/bin/stat -f %z"
SEDINPLACE="/usr/bin/sed -i ''"
DUFLAGS="-sk"
STRIP_BINARIES=""
STRIP_SHARED="-S"
STRIP_STATIC="-S"
;;
esac
AM_CONDITIONAL([DARWIN], test "x$host_os_darwin" = "xyes")
AC_PATH_PROGS([DUPATH], [du], [du], [/usr/bin$PATH_SEPARATOR/bin] )
AC_SUBST(INODECMD)
AC_SUBST(OWNERCMD)
AC_SUBST(MODECMD)
AC_SUBST(SIZECMD)
AC_SUBST(SEDINPLACE)
AC_SUBST(DUFLAGS)
AC_SUBST(STRIP_BINARIES)
AC_SUBST(STRIP_SHARED)
AC_SUBST(STRIP_STATIC)
# Variables plugged into makepkg.conf
CARCH="${host%%-*}"
CHOST="${host}"
AC_SUBST(CARCH)
AC_SUBST(CHOST)
# Check for documentation support and status
AC_CHECK_PROGS([ASCIIDOC], [asciidoc])
AC_MSG_CHECKING([for building documentation])
if test "x$wantdoc" = "xyes" ; then
if test $ASCIIDOC ; then
AC_MSG_RESULT([yes, enabled by configure])
else
asciidoc="(warning : asciidoc not installed)"
AC_MSG_RESULT([yes $asciidoc])
fi
wantdoc=yes
else
AC_MSG_RESULT([no, disabled by configure])
wantdoc=no
fi
AM_CONDITIONAL(WANT_DOC, test "x$wantdoc" = "xyes")
# Check for doxygen support and status
AC_CHECK_PROGS([DOXYGEN], [doxygen])
AC_MSG_CHECKING([for doxygen])
if test "x$wantdoxygen" = "xyes" ; then
if test $DOXYGEN ; then
AC_MSG_RESULT([yes])
usedoxygen=yes
else
AC_MSG_RESULT([no, doxygen missing])
usedoxygen=no
fi
else
AC_MSG_RESULT([no, disabled by configure])
usedoxygen=no
fi
AM_CONDITIONAL(USE_DOXYGEN, test "x$usedoxygen" = "xyes")
# Enable or disable debug code
AC_MSG_CHECKING(for debug mode request)
if test "x$debug" = "xyes" ; then
AC_MSG_RESULT(yes)
AC_DEFINE([PACMAN_DEBUG], , [Enable debug code])
# Check for -fstack-protector availability
GCC_STACK_PROTECT_LIB
GCC_STACK_PROTECT_CC
GCC_FORTIFY_SOURCE_CC
WARNING_CFLAGS="-g -Wall -Werror"
else
AC_MSG_RESULT(no)
WARNING_CFLAGS="-Wall"
fi
# Enable or disable compiler warning flags
AC_MSG_CHECKING(for excessive compiler warning flags)
if test "x$warningflags" = "xyes" ; then
AC_MSG_RESULT(yes)
CFLAGS_ADD([-Wcast-align], [WARNING_CFLAGS])
CFLAGS_ADD([-Wclobbered], [WARNING_CFLAGS])
CFLAGS_ADD([-Wempty-body], [WARNING_CFLAGS])
CFLAGS_ADD([-Wfloat-equal], [WARNING_CFLAGS])
CFLAGS_ADD([-Wformat-nonliteral], [WARNING_CFLAGS])
CFLAGS_ADD([-Wformat-security], [WARNING_CFLAGS])
CFLAGS_ADD([-Wignored-qualifiers], [WARNING_CFLAGS])
CFLAGS_ADD([-Winit-self], [WARNING_CFLAGS])
CFLAGS_ADD([-Wlogical-op], [WARNING_CFLAGS])
CFLAGS_ADD([-Wmissing-declarations], [WARNING_CFLAGS])
CFLAGS_ADD([-Wmissing-field-initializers], [WARNING_CFLAGS])
CFLAGS_ADD([-Wmissing-parameter-type], [WARNING_CFLAGS])
CFLAGS_ADD([-Wmissing-prototypes], [WARNING_CFLAGS])
CFLAGS_ADD([-Wold-style-declaration], [WARNING_CFLAGS])
CFLAGS_ADD([-Woverride-init], [WARNING_CFLAGS])
CFLAGS_ADD([-Wpointer-arith], [WARNING_CFLAGS])
CFLAGS_ADD([-Wredundant-decls], [WARNING_CFLAGS])
CFLAGS_ADD([-Wshadow], [WARNING_CFLAGS])
CFLAGS_ADD([-Wsign-compare], [WARNING_CFLAGS])
CFLAGS_ADD([-Wstrict-aliasing], [WARNING_CFLAGS])
CFLAGS_ADD([-Wstrict-overflow=5], [WARNING_CFLAGS])
CFLAGS_ADD([-Wstrict-prototypes], [WARNING_CFLAGS])
CFLAGS_ADD([-Wtype-limits], [WARNING_CFLAGS])
CFLAGS_ADD([-Wuninitialized], [WARNING_CFLAGS])
CFLAGS_ADD([-Wunused-but-set-parameter], [WARNING_CFLAGS])
CFLAGS_ADD([-Wunused-parameter], [WARNING_CFLAGS])
CFLAGS_ADD([-Wwrite-strings], [WARNING_CFLAGS])
else
AC_MSG_RESULT(no)
fi
# Enable or disable use of git version in pacman version string
AC_MSG_CHECKING(whether to use git version if available)
if test "x$wantgitver" = "xyes" ; then
AC_CHECK_PROGS([GIT], [git])
AC_CHECK_FILE([.git/], hasgitdir=yes)
usegitver=$ac_cv_file__git_
if test $GIT -a "x$hasgitdir" = "xyes"; then
AC_DEFINE([USE_GIT_VERSION], , [Use GIT version in version string])
fi
else
AC_MSG_RESULT([no, disabled by configure])
usegitver=no
fi
AM_CONDITIONAL(USE_GIT_VERSION, test "x$usegitver" = "xyes")
# Set root directory
AC_SUBST(ROOTDIR)
AC_DEFINE_UNQUOTED([ROOTDIR], "$ROOTDIR", [The location of the root operating directory])
# Set package file extension
AC_SUBST(PKGEXT)
AC_DEFINE_UNQUOTED([PKGEXT], "$PKGEXT", [The file extension used by pacman packages])
# Set source package file extension
AC_SUBST(SRCEXT)
AC_DEFINE_UNQUOTED([SRCEXT], "$SRCEXT", [The file extension used by pacman source packages])
# Set makepkg build script name
AC_SUBST(BUILDSCRIPT)
AC_DEFINE_UNQUOTED([BUILDSCRIPT], "$BUILDSCRIPT", [The build script name used by makepkg])
# Set makepkg-template template directory
AC_SUBST(TEMPLATE_DIR)
AC_DEFINE_UNQUOTED([TEMPLATE_DIR], "$TEMPLATE_DIR", [The template directory used by makepkg-teplate])
# Set makepkg split debugging symbol package suffix
AC_SUBST(DEBUGSUFFIX)
AC_DEFINE_UNQUOTED([DEBUGSUFFIX], "$DEBUGSUFFIX", [The suffix for debugging symbol packages used by makepkg])
# Set shell used by install scriptlets
AC_SUBST(SCRIPTLET_SHELL)
AC_DEFINE_UNQUOTED([SCRIPTLET_SHELL], "$SCRIPTLET_SHELL", [The full path of the shell used to run install scriptlets])
# Set ldconfig path
AC_SUBST(LDCONFIG)
AC_DEFINE_UNQUOTED([LDCONFIG], "$LDCONFIG", [The full path to ldconfig])
# Configuration files
AC_CONFIG_FILES([
lib/libalpm/Makefile
lib/libalpm/po/Makefile.in
lib/libalpm/libalpm.pc
src/common/Makefile
src/pacman/Makefile
src/pacman/po/Makefile.in
src/util/Makefile
scripts/Makefile
scripts/po/Makefile.in
doc/Makefile
etc/Makefile
test/pacman/Makefile
test/pacman/tests/Makefile
test/scripts/Makefile
test/util/Makefile
contrib/Makefile
Makefile
])
AC_OUTPUT
echo "
${PACKAGE_NAME}:
Build information:
source code location : ${srcdir}
prefix : ${prefix}
sysconfdir : $(eval echo ${sysconfdir})
conf file : $(eval echo ${sysconfdir})/pacman.conf
localstatedir : $(eval echo ${localstatedir})
database dir : $(eval echo ${localstatedir})/lib/pacman/
cache dir : $(eval echo ${localstatedir})/cache/pacman/pkg/
compiler : ${CC}
preprocessor flags : ${CPPFLAGS}
compiler flags : ${WARNING_CFLAGS} ${CFLAGS}
library flags : ${LIBS} ${LIBSSL_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS}
linker flags : ${LDFLAGS}
Architecture : ${CARCH}
Host Type : ${CHOST}
File inode command : ${INODECMD}
File owner command : ${OWNERCMD}
File mode command : ${MODECMD}
Filesize command : ${SIZECMD}
In-place sed command : ${SEDINPLACE}
libalpm version : ${LIB_VERSION}
libalpm version info : ${LIB_VERSION_INFO}
pacman version : ${PACKAGE_VERSION}
using git version : ${usegitver}
Directory and file information:
root working directory : ${ROOTDIR}
package extension : ${PKGEXT}
source pkg extension : ${SRCEXT}
build script name : ${BUILDSCRIPT}
template directory : ${TEMPLATE_DIR}
Compilation options:
Use libcurl : ${have_libcurl}
Use GPGME : ${have_gpgme}
Use OpenSSL : ${have_openssl}
Run make in doc/ dir : ${wantdoc} ${asciidoc}
Doxygen support : ${usedoxygen}
debug support : ${debug}
extra warning flags : ${warningflags}
use git version : ${wantgitver}
"
# vim:set noet:

12
contrib/.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
bacman
bash_completion
checkupdates
paccache
pacdiff
paclist
paclog-pkglist
pacscripts
pacsearch
rankmirrors
updpkgsums
zsh_completion

89
contrib/Makefile.am Normal file
View file

@ -0,0 +1,89 @@
# enforce that all scripts have a --help and --version option
AUTOMAKE_OPTIONS = std-options
bin_SCRIPTS = \
$(OURSCRIPTS)
BASHSCRIPTS = \
bacman \
checkupdates \
paccache \
pacdiff \
paclist \
paclog-pkglist \
pacscripts \
rankmirrors \
updpkgsums
OTHERSCRIPTS = \
pacsearch
OURSCRIPTS = \
$(BASHSCRIPTS) \
$(OTHERSCRIPTS)
EXTRA_DIST = \
PKGBUILD.vim \
bacman.sh.in \
checkupdates.sh.in \
paccache.sh.in \
paclog-pkglist.sh.in \
pacdiff.sh.in \
paclist.sh.in \
pacscripts.sh.in \
pacsearch.in \
rankmirrors.sh.in \
updpkgsums.sh.in \
vimprojects \
README
# Files that should be removed, but which Automake does not know.
MOSTLYCLEANFILES = $(OURSCRIPTS) *.tmp
if USE_GIT_VERSION
GIT_VERSION := $(shell sh -c 'git describe --abbrev=4 --dirty | sed s/^v//')
REAL_PACKAGE_VERSION = $(GIT_VERSION)
else
REAL_PACKAGE_VERSION = $(PACKAGE_VERSION)
endif
edit = sed \
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@PACKAGE_VERSION[@]|$(REAL_PACKAGE_VERSION)|g' \
-e 's|@SIZECMD[@]|$(SIZECMD)|g' \
-e 's|@SCRIPTNAME[@]|$@|g' \
-e '1s|!/bin/bash|!$(BASH_SHELL)|g'
$(OTHERSCRIPTS): Makefile
$(AM_V_at)$(RM) $@ $@.tmp
$(AM_V_GEN)$(edit) $(srcdir)/$@.in >$@.tmp
$(AM_V_at)chmod +x,a-w $@.tmp
$(AM_V_at)mv $@.tmp $@
$(BASHSCRIPTS): Makefile
$(AM_V_at)$(RM) $@
$(AM_V_GEN)test -f $(srcdir)/$@.sh.in && m4 -P -I $(srcdir) $(srcdir)/$@.sh.in | $(edit) >$@
$(AM_V_at)chmod +x,a-w $@
@$(BASH_SHELL) -O extglob -n $@
$(OURFILES): Makefile
$(AM_V_at)$(RM) $@ $@.tmp
$(AM_V_GEN)$(edit) $(srcdir)/$@.in >$@.tmp
$(AM_V_at)chmod a-w $@.tmp
$(AM_V_at)mv $@.tmp $@
all-am: $(OURSCRIPTS)
bacman: $(srcdir)/bacman.sh.in
checkupdates: $(srcdir)/checkupdates.sh.in
paccache: $(srcdir)/paccache.sh.in $(top_srcdir)/scripts/library/parseopts.sh $(top_srcdir)/scripts/library/size_to_human.sh
pacdiff: $(srcdir)/pacdiff.sh.in
paclist: $(srcdir)/paclist.sh.in
paclog-pkglist: $(srcdir)/paclog-pkglist.sh.in
pacscripts: $(srcdir)/pacscripts.sh.in
pacsearch: $(srcdir)/pacsearch.in
rankmirrors: $(srcdir)/rankmirrors.sh.in
updpkgsums: $(srcdir)/updpkgsums.sh.in
# vim:set noet:

320
contrib/PKGBUILD.vim Normal file
View file

@ -0,0 +1,320 @@
" Vim syntax file
" Language: PKGBUILD
" Maintainer: Alessio 'mOLOk' Bolognino <themolok at gmail.com>
" Last Change: 2007/05/08
" Version Info: PKGBUILD-0.2 (colorphobic)
" For version 5.x: Clear all syntax items
" For version 6.x: Quit when a syntax file was already loaded
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
let b:main_syntax = "sh"
let b:is_bash = 1
runtime! syntax/sh.vim
" case on
syn case match
" pkgname
" FIXME if '=' is in pkgname/pkgver, it highlights whole string, not just '='
syn keyword pb_k_pkgname pkgname contained
syn match pbValidPkgname /\([[:alnum:]]\|+\|-\|_\){,32}/ contained contains=pbIllegalPkgname
syn match pbIllegalPkgname /[[:upper:]]\|[^[:alnum:]-+_=]\|=.*=\|=['"]\?.\{33,\}['"]\?/ contained
syn match pbPkgnameGroup /^pkgname=.*/ contains=pbIllegalPkgname,pb_k_pkgname,shDoubleQuote,shSingleQuote
" pkgbase
" FIXME if '=' is in pkgbase/pkgname/pkgver, it highlights whole string, not just '='
syn keyword pb_k_pkgbase pkgbase contained
syn match pbValidPkgbase /\([[:alnum:]]\|+\|-\|_\){,32}/ contained contains=pbIllegalPkgbase
syn match pbIllegalPkgbase /[[:upper:]]\|[^[:alnum:]-+_=]\|=.*=\|=['"]\?.\{33,\}['"]\?/ contained
syn match pbPkgbaseGroup /^pkgbase=.*/ contains=pbIllegalPkgbase,pb_k_pkgbase,shDoubleQuote,shSingleQuote
" pkgver
syn keyword pb_k_pkgver pkgver contained
syn match pbValidPkgver /\([[:alnum:]]\|\.\|+\|_\)/ contained contains=pbIllegalPkgver
syn match pbIllegalPkgver /[^[:alnum:]+=\.\_]\|=.*=/ contained
syn match pbPkgverGroup /^pkgver=.*/ contains=pbIllegalPkgver,pbValidPkgver,pb_k_pkgver,shDoubleQuote,shSingleQuote
" pkgrel
syn keyword pb_k_pkgrel pkgrel contained
syn match pbValidPkgrel /[[:digit:]]*/ contained contains=pbIllegalPkgrel
syn match pbIllegalPkgrel /[^[:digit:]=]\|=.*=/ contained
syn match pbPkgrelGroup /^pkgrel=.*/ contains=pbIllegalPkgrel,pbValidPkgrel,pb_k_pkgrel,shDoubleQuote,shSingleQuote
" pkgdesc
syn keyword pb_k_desc pkgdesc contained
" 90 chars: 80 for description, 8 for pkgdesc and 2 for ''
syn match pbIllegalPkgdesc /.\{90,}\|=['"]\?.*['" ]\+[iI][sS] [aA]/ contained contains=pbPkgdescSign
syn match pbValidPkgdesc /[^='"]\.\{,80}/ contained contains=pbIllegalPkgdesc
syn match pbPkgdescGroup /^pkgdesc=.*/ contains=pbIllegalPkgdesc,pb_k_desc,pbValidPkgdesc,shDoubleQuote,shSingleQuote
syn match pbPkgdescSign /[='"]/ contained
" epoch
syn keyword pb_k_epoch epoch contained
syn match pbValidEpoch /[[:digit:]]*/ contained contains=pbIllegalEpoch
syn match pbIllegalEpoch /[^[:digit:]=]\|=.*=/ contained
syn match pbEpochGroup /^epoch=.*/ contains=pbIllegalEpoch,pbValidEpoch,pb_k_epoch,shDoubleQuote,shSingleQuote
" url
syn keyword pb_k_url url contained
syn match pbValidUrl /['"]*\(https\|http\|ftp\)\:\/.*\.\+.*/ contained
syn match pbIllegalUrl /[^=]/ contained contains=pbValidUrl
syn match pbUrlGroup /^url=.*/ contains=pbValidUrl,pb_k_url,pbIllegalUrl,shDoubleQuote,shSingleQuote
" license
syn keyword pb_k_license license contained
" echo $(pacman -Ql licenses | grep '/usr/share/licenses/common/' | cut -d'/' -f6 | sort -u)
syn keyword pbLicense AGPL AGPL3 Apache APACHE Artistic2.0 CCPL CDDL CPL EPL FDL FDL1.2 FDL1.3 GPL GPL2 GPL3 LGPL LGPL2.1 LGPL3 LPPL MPL PerlArtistic PHP PSF RUBY W3C ZPL contained
" special cases from https://wiki.archlinux.org/index.php/Arch_Packaging_Standards
syn keyword pbLicenseSpecial BSD MIT ZLIB Python contained
syn match pbLicenseCustom /custom\(:[[:alnum:]]*\)*/ contained
syn match pbIllegalLicense /[^='"() ]/ contained contains=pbLicenseCustom,pbLicenseSpecial,pbLicense
syn region pbLicenseGroup start=/^license=(/ end=/)/ contains=pb_k_license,pbLicenseCustom,pbLicenseSpecial,pbLicense,pbIllegalLicense
" backup
syn keyword pb_k_backup backup contained
syn match pbValidBackup /\.\?[[:alpha:]]*\/[[:alnum:]\{\}+._$-]*]*/ contained
syn region pbBackupGroup start=/^backup=(/ end=/)/ contains=pb_k_backup,pbValidBackup,shDoubleQuote,shSingleQuote
" arch
syn keyword pb_k_arch arch contained
syn keyword pbArch i686 x86_64 ppc any contained
syn match pbIllegalArch /[^='"() ]/ contained contains=pbArch
syn region pbArchGroup start=/^arch=(/ end=/)/ contains=pb_k_arch,pbArch,pbIllegalArch
" groups
syn keyword pb_k_groups groups contained
syn match pbValidGroups /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbGroupsGroup start=/^groups=(/ end=/)/ contains=pb_k_groups,pbValidGroups,shDoubleQuote,shSingleQuote
" depends
syn keyword pb_k_depends depends contained
syn match pbValidDepends /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbDependsGroup start=/^depends=(/ end=/)/ contains=pb_k_depends,pbValidDepends,shDoubleQuote,shSingleQuote
" makedepends
syn keyword pb_k_makedepends makedepends contained
syn match pbValidMakedepends /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbMakedependsGroup start=/^makedepends=(/ end=/)/ contains=pb_k_makedepends,pbValidMakedepends,shDoubleQuote,shSingleQuote
" optdepends
syn keyword pb_k_optdepends optdepends contained
syn match pbValidOptdepends /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbOptdependsGroup start=/^optdepends=(/ end=/)/ contains=pb_k_optdepends,pbValidOptdepends,shDoubleQuote,shSingleQuote
" checkdepends
syn keyword pb_k_ckdepends checkdepends contained
syn match pbValidCkdepends /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbCkdependsGroup start=/^checkdepends=(/ end=/)/ contains=pb_k_ckdepends,pbValidCkdepends,shDoubleQuote,shSingleQuote
" conflicts
syn keyword pb_k_conflicts conflicts contained
syn match pbValidConflicts /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbConflictsGroup start=/^conflicts=(/ end=/)/ contains=pb_k_conflicts,pbValidConflicts,shDoubleQuote,shSingleQuote
" provides
syn keyword pb_k_provides provides contained
syn match pbValidProvides /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbProvidesGroup start=/^provides=(/ end=/)/ contains=pb_k_provides,pbValidProvides,shDoubleQuote,shSingleQuote
" replaces
syn keyword pb_k_replaces replaces contained
syn match pbValidReplaces /\([[:alnum:]]\|+\|-\|_\)*/ contained
syn region pbReplacesGroup start=/^replaces=(/ end=/)/ contains=pb_k_replaces,pbValidReplaces,shDoubleQuote,shSingleQuote
" install
" XXX remove install from bashStatement, fix strange bug
syn clear bashStatement
syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch
syn keyword pb_k_install install contained
syn match pbValidInstall /\([[:alnum:]]\|\$\|+\|-\|_\)*\.install/ contained
syn match pbIllegalInstall /[^=]/ contained contains=pbValidInstall
syn match pbInstallGroup /^install=.*/ contains=pb_k_install,pbValidInstall,pbIllegalInstall,shDeref,shDoubleQuote,shSingleQuote
" changelog
syn keyword pb_k_changelog changelog contained
syn match pbValidChangelog /\([[:alnum:]]\|\$\|+\|-\|_\)*/ contained
syn match pbIllegalChangelog /[^=]/ contained contains=pbValidChangelog
syn match pbChangelogGroup /^changelog=.*/ contains=pb_k_changelog,pbValidChangelog,pbIllegalChangelog,shDeref,shDoubleQuote,shSingleQuote
" source:
" XXX remove source from shStatement, fix strange bug
syn clear shStatement
syn keyword shStatement xxx wait getopts return autoload whence printf true popd nohup enable r trap readonly fc fg kill ulimit umask disown stop pushd read history logout times local exit test pwd time eval integer suspend dirs shopt hash false newgrp bg print jobs continue functions exec help cd break unalias chdir type shift builtin let bind
syn keyword pb_k_source source contained
syn match pbIllegalSource /\(http\|ftp\|https\).*\.\+\(dl\|download.\?\)\.\(sourceforge\|sf\).net/
syn region pbSourceGroup start=/^source=(/ end=/)/ contains=pb_k_source,pbIllegalSource,shNumber,shDoubleQuote,shSingleQuote,pbDerefEmulation
syn match pbDerefEmulation /\$[{]\?[[:alnum:]_]*[}]\?/ contained
hi def link pbDerefEmulation PreProc
" md5sums
syn keyword pb_k_md5sums md5sums contained
syn match pbIllegalMd5sums /[^='"()\/ ]/ contained contains=pbValidMd5sums
syn match pbValidMd5sums /\x\{32\}/ contained
syn region pbMd5sumsGroup start=/^md5sums/ end=/)/ contains=pb_k_md5sums,pbMd5Quotes,pbMd5Hash,pbIllegalMd5sums keepend
syn match pbMd5Quotes /'.*'\|".*"/ contained contains=pbMd5Hash,pbIllegalMd5sums
syn match pbMd5Hash /\x\+/ contained contains=pbValidMd5sums
hi def link pbMd5Quotes Keyword
hi def link pbMd5Hash Error
hi def link pbValidMd5sums Number
" sha1sums
syn keyword pb_k_sha1sums sha1sums contained
syn match pbIllegalSha1sums /[^='"()\/ ]/ contained contains=pbValidSha1sums
syn match pbValidSha1sums /\x\{40\}/ contained
syn region pbSha1sumsGroup start=/^sha1sums/ end=/)/ contains=pb_k_sha1sums,pbSha1Quotes,pbSha1Hash,pbIllegalSha1sums keepend
syn match pbSha1Quotes /'.*'\|".*"/ contained contains=pbSha1Hash,pbIllegalSha1sums
syn match pbSha1Hash /\x\+/ contained contains=pbValidSha1sums
hi def link pbSha1Quotes Keyword
hi def link pbSha1Hash Error
hi def link pbValidSha1sums Number
" sha256sums
syn keyword pb_k_sha256sums sha256sums contained
syn match pbIllegalSha256sums /[^='"()\/ ]/ contained contains=pbValidSha256sums
syn match pbValidSha256sums /\x\{64\}/ contained
syn region pbSha256sumsGroup start=/^sha256sums/ end=/)/ contains=pb_k_sha256sums,pbSha256Quotes,pbSha256Hash,pbIllegalSha256sums keepend
syn match pbSha256Quotes /'.*'\|".*"/ contained contains=pbSha256Hash,pbIllegalSha256sums
syn match pbSha256Hash /\x\+/ contained contains=pbValidSha256sums
hi def link pbSha256Quotes Keyword
hi def link pbSha256Hash Error
hi def link pbValidSha256sums Number
" sha384sums
syn keyword pb_k_sha384sums sha384sums contained
syn match pbIllegalSha384sums /[^='"()\/ ]/ contained contains=pbValidSha384sums
syn match pbValidSha384sums /\x\{96\}/ contained
syn region pbSha384sumsGroup start=/^sha384sums/ end=/)/ contains=pb_k_sha384sums,pbSha384Quotes,pbSha384Hash,pbIllegalSha384sums keepend
syn match pbSha384Quotes /'.*'\|".*"/ contained contains=pbSha384Hash,pbIllegalSha384sums
syn match pbSha384Hash /\x\+/ contained contains=pbValidSha384sums
hi def link pbSha384Quotes Keyword
hi def link pbSha384Hash Error
hi def link pbValidSha384sums Number
" sha512sums
syn keyword pb_k_sha512sums sha512sums contained
syn match pbIllegalSha512sums /[^='"()\/ ]/ contained contains=pbValidSha512sums
syn match pbValidSha512sums /\x\{128\}/ contained
syn region pbSha512sumsGroup start=/^sha512sums/ end=/)/ contains=pb_k_sha512sums,pbSha512Quotes,pbSha512Hash,pbIllegalSha512sums keepend
syn match pbSha512Quotes /'.*'\|".*"/ contained contains=pbSha512Hash,pbIllegalSha512sums
syn match pbSha512Hash /\x\+/ contained contains=pbValidSha512sums
hi def link pbSha512Quotes Keyword
hi def link pbSha512Hash Error
hi def link pbValidSha512sums Number
" options
syn keyword pb_k_options options contained
syn match pbOptions /\(no\)\?\(strip\|docs\|libtool\|emptydirs\|zipman\|purge\|upx\|optipng\|distcc\|color\|ccache\|check\|sign\|makeflags\|buildflags\)/ contained
syn match pbOptionsNeg /\!/ contained
syn match pbOptionsDeprec /no/ contained
syn region pbOptionsGroup start=/^options=(/ end=/)/ contains=pb_k_options,pbOptions,pbOptionsNeg,pbOptionsDeprec,pbIllegalOption
syn match pbIllegalOption /[^!"'()= ]/ contained contains=pbOptionsDeprec,pbOptions
" noextract
syn match pbNoextract /[[:alnum:]+._${}-]\+/ contained
syn keyword pb_k_noextract noextract contained
syn region pbNoextractGroup start=/^noextract=(/ end=/)/ contains=pb_k_noextract,pbNoextract,shDoubleQuote,shSingleQuote
" comments
syn keyword pb_k_maintainer Maintainer Contributor contained
syn match pbMaintainerGroup /Maintainer.*/ contains=pbMaintainer contained
syn match pbDate /[0-9]\{4}\/[0-9]\{2}\/[0-9]\{2}/ contained
syn cluster pbCommentGroup contains=pbTodo,pb_k_maintainer,pbMaintainerGroup,pbDate
syn keyword pbTodo contained COMBAK FIXME TODO XXX
syn match pbComment "^#.*$" contains=@pbCommentGroup
syn match pbComment "[^0-9]#.*$" contains=@pbCommentGroup
" quotes are handled by sh.vim
hi def link pbComment Comment
hi def link pbTodo Todo
hi def link pbIllegalPkgname Error
hi def link pb_k_pkgname pbKeywords
hi def link pbIllegalPkgbase Error
hi def link pb_k_pkgbase pbKeywords
hi def link pbIllegalPkgver Error
hi def link pb_k_pkgver pbKeywords
hi def link pbIllegalPkgrel Error
hi def link pb_k_pkgrel pbKeywords
hi def link pbIllegalPkgdesc Error
hi def link pb_k_desc pbKeywords
hi def link pbIllegalEpoch Error
hi def link pb_k_epoch pbKeywords
hi def link pbIllegalUrl Error
hi def link pb_k_url pbKeywords
hi def link pb_k_license pbKeywords
hi def link pbIllegalLicense Error
hi def link pb_k_backup pbKeywords
hi def link pb_k_arch pbKeywords
hi def link pbIllegalArch Error
hi def link pb_k_groups pbKeywords
hi def link pb_k_makedepends pbKeywords
hi def link pb_k_optdepends pbKeywords
hi def link pb_k_ckdepends pbKeywords
hi def link pb_k_depends pbKeywords
hi def link pb_k_replaces pbKeywords
hi def link pb_k_conflicts pbKeywords
hi def link pb_k_provides pbKeywords
hi def link pbIllegalInstall Error
hi def link pb_k_install pbKeywords
hi def link pbIllegalChangelog Error
hi def link pb_k_changelog pbKeywords
hi def link pb_k_source pbKeywords
hi def link pbIllegalSource Error
hi def link pb_k_md5sums pbKeywords
hi def link pbIllegalMd5sums Error
hi def link pb_k_sha1sums pbKeywords
hi def link pbIllegalSha1sums Error
hi def link pb_k_sha256sums pbKeywords
hi def link pbIllegalSha256sums Error
hi def link pb_k_sha384sums pbKeywords
hi def link pbIllegalSha384sums Error
hi def link pb_k_sha512sums pbKeywords
hi def link pbIllegalSha512sums Error
hi def link pb_k_options pbKeywords
hi def link pbOptionsDeprec Todo
hi def link pbIllegalOption Error
hi def link pb_k_noextract pbKeywords
hi def link pbNoextract Normal
hi def link pb_k_maintainer pbKeywords
hi def link pbKeywords Keyword
hi def link pbDate Special
"syntax include @SHELL syntax/sh.vim
"syntax region BUILD start=/^build()/ end=/^}/ contains=@SHELL
"let b:current_syntax = "PKGBUILD"
" vim: ft=vim

41
contrib/README Normal file
View file

@ -0,0 +1,41 @@
Here is a brief description of the files included in this directory:
PKGBUILD.vim - a vim/gvim syntax file for PKGBUILDs. Colors known variable
names, highlights common errors such as invalid characters in pkgname or
pkgver, etc.
bacman - regenerate a pacman package based on installed files and the pacman
database entries. Useful for reuse, or possible config file extension.
bash_completion - a bash completion script for pacman, install in
/etc/bash_completion.d/ for use (but rename to something descriptive!).
checkupdates - print a list of pending updates without touching the system
sync databases (for safety on rolling release distributions).
paccache - a flexible package cache cleaning utility that allows greater
control over which packages are removed.
pacdiff - a simple pacnew/pacsave updater for /etc/.
paclist - list all packages installed from a given repository. Useful for
seeing which packages you may have installed from the testing repository,
for instance.
paclog-pkglist - lists currently installs packages based pacman's log.
pacscripts - tries to print out the {pre,post}_{install,remove,upgrade}
scripts of a given package.
pacsearch - a colorized search combining both -Ss and -Qs output. Installed
packages are easily identified with a *** and local-only packages are also
listed.
rankmirrors - ranks pacman mirrors by their connection and opening speed.
updpkgsums - performs an in place update of the checksums in a PKGBUILD.
vimprojects - a project file for the vim project plugin.
zsh_completion - a zsh completion script, install (with a rename) to
/usr/share/zsh/site-functions/.

358
contrib/bacman.sh.in Normal file
View file

@ -0,0 +1,358 @@
#!/bin/bash
#
# bacman: recreate a package from a running system
# This script rebuilds an already installed package using metadata
# stored into the pacman database and system files
#
# Copyright (c) 2008 locci <carlocci_at_gmail_dot_com>
# Copyright (c) 2008-2016 Pacman Development Team <pacman-dev@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/>.
#
shopt -s extglob
shopt -s nullglob
declare -r myname='bacman'
declare -r myver='@PACKAGE_VERSION@'
USE_COLOR='y'
INCLUDE_PACNEW='n'
# Required for fakeroot because options are shifted off the array.
ARGS=("$@")
m4_include(../scripts/library/output_format.sh)
#
# User Friendliness
#
usage() {
echo "${myname} (pacman) v${myver}"
echo
echo "Recreate a package using pacman's database and system files"
echo
echo "Usage: ${myname} [--nocolor] [--pacnew] <installed package name>"
echo
echo "Example: ${myname} linux-headers"
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2008 locci <carlocci_at_gmail_dot_com>'
echo 'Copyright (C) 2008-2016 Pacman Development Team <pacman-dev@archlinux.org>'
}
while [[ ! -z $1 ]]; do
if [[ $1 == "--nocolor" ]]; then
USE_COLOR='n'
shift
elif [[ $1 == "--pacnew" ]]; then
INCLUDE_PACNEW='y'
shift
else
break
fi
done
m4_include(../scripts/library/term_colors.sh)
if (( $# != 1 )); then
usage
exit 1
fi
if [[ $1 = -@(h|-help) ]]; then
usage
exit 0
elif [[ $1 = -@(V|-version) ]]; then
version
exit 0
fi
#
# Fakeroot support
#
if (( EUID )); then
if [[ -f /usr/bin/fakeroot ]]; then
msg "Entering fakeroot environment"
export INFAKEROOT="1"
/usr/bin/fakeroot -u -- "$0" "${ARGS[@]}"
exit $?
else
warning "installing fakeroot or running $myname as root is required to"
plain " preserve the ownership permissions of files in some packages\n"
fi
fi
#
# Setting environmental variables
#
if [[ ! -r @sysconfdir@/pacman.conf ]]; then
error "unable to read @sysconfdir@/pacman.conf"
exit 1
fi
eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
pac_db="${DBPath:-@localstatedir@/lib/pacman/}/local"
if [[ ! -r @sysconfdir@/makepkg.conf ]]; then
error "unable to read @sysconfdir@/makepkg.conf"
exit 1
fi
source "@sysconfdir@/makepkg.conf"
if [[ -r ~/.makepkg.conf ]]; then
source ~/.makepkg.conf
fi
pkg_dest="${PKGDEST:-$PWD}"
pkg_pkger=${PACKAGER:-'Unknown Packager'}
pkg_name="$1"
pkg_dir=("$pac_db/$pkg_name"-+([^-])-+([^-]))
pkg_namver=("${pkg_dir[@]##*/}")
#
# Checks everything is in place
#
if [[ ! -d $pac_db ]]; then
error "pacman database directory ${pac_db} not found"
exit 1
fi
if (( ${#pkg_dir[@]} != 1 )); then
error "%d entries for package %s found in pacman database" \
${#pkg_dir[@]} "${pkg_name}"
msg2 "%s" "${pkg_dir[@]}"
exit 1
fi
if [[ ! -d $pkg_dir ]]; then
error "package %s is found in pacman database," "${pkg_name}"
plain " but '%s' is not a directory" "${pkg_dir}"
exit 1
fi
#
# Begin
#
msg "Package: ${pkg_namver}"
work_dir=$(mktemp -d "${TMPDIR:-/tmp}/bacman.XXXXXXXXXX")
cd "$work_dir" || exit 1
#
# File copying
#
msg2 "Copying package files..."
while read i; do
if [[ -z $i ]]; then
continue
fi
if [[ $i == %+([A-Z])% ]]; then
current=$i
continue
fi
case "$current" in
%FILES%)
local_file="/$i"
package_file="$work_dir/$i"
if [[ ! -e $local_file ]]; then
warning "package file $local_file is missing"
continue
fi
;;
%BACKUP%)
# Get the MD5 checksum.
original_md5="${i##*$'\t'}"
# Strip the md5sum after the tab.
i="${i%$'\t'*}"
local_file="/$i.pacnew"
package_file="$work_dir/$i"
# Include unmodified .pacnew files.
local_md5="$(md5sum "$local_file" | cut -d' ' -f1)"
if [[ $INCLUDE_PACNEW == 'n' ]] \
|| [[ ! -e $local_file ]] \
|| [[ $local_md5 != $original_md5 ]]; then
# Warn about modified files.
local_md5="$(md5sum "/$i" | cut -d' ' -f1)"
if [[ $local_md5 != $original_md5 ]]; then
warning "package file /$i has been modified"
fi
# Let the normal file be included in the %FILES% list.
continue
fi
;;
*)
continue
;;
esac
ret=0
bsdtar -cnf - -s'/.pacnew$//' "$local_file" 2> /dev/null | bsdtar -xpf - 2> /dev/null
# Workaround to bsdtar not reporting a missing file as an error
if ! [[ -e $package_file || -L $package_file ]]; then
error "unable to add $local_file to the package"
plain " If your user does not have permission to read this file, then"
plain " you will need to run $myname as root."
rm -rf "$work_dir"
exit 1
fi
done < "$pkg_dir"/files
ret=$?
if (( ret )); then
rm -rf "$work_dir"
exit 1
fi
pkg_size=$(du -sk | awk '{print $1 * 1024}')
#
# .PKGINFO stuff
# TODO adopt makepkg's write_pkginfo() into this or scripts/library
#
msg2 "Generating .PKGINFO metadata..."
echo "# Generated by $myname $myver" > .PKGINFO
if [[ $INFAKEROOT == "1" ]]; then
echo "# Using $(fakeroot -v)" >> .PKGINFO
fi
echo "# $(LC_ALL=C date)" >> .PKGINFO
echo "#" >> .PKGINFO
while read i; do
if [[ -z $i ]]; then
continue;
fi
if [[ $i == %+([A-Z])% ]]; then
current=$i
continue
fi
case "$current" in
# desc
%NAME%)
echo "pkgname = $i" >> .PKGINFO
;;
%VERSION%)
echo "pkgver = $i" >> .PKGINFO
;;
%DESC%)
echo "pkgdesc = $i" >> .PKGINFO
;;
%URL%)
echo "url = $i" >> .PKGINFO
;;
%LICENSE%)
echo "license = $i" >> .PKGINFO
;;
%ARCH%)
echo "arch = $i" >> .PKGINFO
pkg_arch="$i"
;;
%BUILDDATE%)
echo "builddate = $(date -u "+%s")" >> .PKGINFO
;;
%PACKAGER%)
echo "packager = $pkg_pkger" >> .PKGINFO
;;
%SIZE%)
echo "size = $pkg_size" >> .PKGINFO
;;
%GROUPS%)
echo "group = $i" >> .PKGINFO
;;
%REPLACES%)
echo "replaces = $i" >> .PKGINFO
;;
%DEPENDS%)
echo "depend = $i" >> .PKGINFO
;;
%OPTDEPENDS%)
echo "optdepend = $i" >> .PKGINFO
;;
%CONFLICTS%)
echo "conflict = $i" >> .PKGINFO
;;
%PROVIDES%)
echo "provides = $i" >> .PKGINFO
;;
# files
%BACKUP%)
# Strip the md5sum after the tab
echo "backup = ${i%%$'\t'*}" >> .PKGINFO
;;
esac
done < <(cat "$pkg_dir"/{desc,files})
comp_files=".PKGINFO"
if [[ -f $pkg_dir/install ]]; then
cp "$pkg_dir/install" "$work_dir/.INSTALL"
comp_files+=" .INSTALL"
fi
if [[ -f $pkg_dir/changelog ]]; then
cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG"
comp_files+=" .CHANGELOG"
fi
#
# Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL
#
chown root:root "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null
chmod 644 "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null
#
# Generate the package
#
msg2 "Generating the package..."
pkg_file="$pkg_dest/$pkg_namver-$pkg_arch${PKGEXT}"
ret=0
# TODO: Maybe this can be set globally for robustness
shopt -s -o pipefail
bsdtar -cf - $comp_files * |
case "$PKGEXT" in
*tar.gz) gzip -c -f -n ;;
*tar.bz2) bzip2 -c -f ;;
*tar.xz) xz -c -z - ;;
*tar.Z) compress -c -f ;;
*tar) cat ;;
*) warning "'%s' is not a valid archive extension." \
"$PKGEXT"; cat ;;
esac > "${pkg_file}"; ret=$?
if (( ret )); then
error "Unable to write package to $pkg_dest"
plain " Maybe the disk is full or you do not have write access"
rm -rf "$work_dir"
exit 1
fi
rm -rf "$work_dir"
msg "Done."
exit 0
# vim: set noet:

View file

@ -0,0 +1,59 @@
#!/bin/bash
#
# checkupdates: Safely print a list of pending updates.
#
# Copyright (c) 2013 Kyle Keen <keenerd@gmail.com>
#
# 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/>.
#
declare -r myname='checkupdates'
declare -r myver='@PACKAGE_VERSION@'
m4_include(../scripts/library/output_format.sh)
m4_include(../scripts/library/term_colors.sh)
if (( $# > 0 )); then
echo "${myname} (pacman) v${myver}"
echo
echo "Safely print a list of pending updates"
echo
echo "Usage: ${myname}"
echo
echo 'Note: Export the "CHECKUPDATES_DB" variable to change the path of the temporary database.'
exit 0
fi
if ! type -P fakeroot >/dev/null; then
error 'Cannot find the fakeroot binary.'
exit 1
fi
if [[ -z $CHECKUPDATES_DB ]]; then
CHECKUPDATES_DB="${TMPDIR:-/tmp}/checkup-db-${USER}/"
fi
trap 'rm -f $CHECKUPDATES_DB/db.lck' INT TERM EXIT
DBPath="${DBPath:-@localstatedir@/lib/pacman/}"
eval $(awk -F' *= *' '$1 ~ /DBPath/ { print $1 "=" $2 }' @sysconfdir@/pacman.conf)
mkdir -p "$CHECKUPDATES_DB"
ln -s "${DBPath}/local" "$CHECKUPDATES_DB" &> /dev/null
fakeroot -- pacman -Sy --dbpath "$CHECKUPDATES_DB" --logfile /dev/null &> /dev/null
pacman -Qu --dbpath "$CHECKUPDATES_DB" 2> /dev/null | grep -v '\[.*\]'
exit 0
# vim: set noet:

366
contrib/paccache.sh.in Normal file
View file

@ -0,0 +1,366 @@
#!/bin/bash
#
# pacache - flexible pacman cache cleaning
#
# Copyright (C) 2011 Dave Reisner <dreisner@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/>.
shopt -s extglob
declare -r myname='paccache'
declare -r myver='@PACKAGE_VERSION@'
declare -a cachedirs=() candidates=() cmdopts=() whitelist=() blacklist=()
declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0 verbose=0
declare delim=$'\n' keep=3 movedir= scanarch=
QUIET=0
USE_COLOR='y'
m4_include(../scripts/library/output_format.sh)
m4_include(../scripts/library/parseopts.sh)
die() {
error "$@"
exit 1
}
get_cachedir_from_config() {
local key value
while IFS=$'= \t' read -r key value _; do
if [[ $key = CacheDir ]]; then
echo "$value"
return 0
fi
done <"$1"
return 1
}
# reads a list of files on stdin and prints out deletion candidates
pkgfilter() {
# there's whitelist and blacklist parameters passed to this
# script after the block of awk.
awk -v keep="$1" -v scanarch="$2" '
function basename(str) {
sub(".*/", "", str);
return str;
}
function parse_filename(filename, parts, count, i, pkgname, arch) {
count = split(basename(filename), parts, "-")
i = 1
pkgname = parts[i++]
while (i <= count - 3) {
pkgname = pkgname "-" parts[i++]
}
arch = substr(parts[count], 1, index(parts[count], ".") - 1)
# filter on whitelist or blacklist
if (wlen && !whitelist[pkgname]) return
if (blen && blacklist[pkgname]) return
if ("" == packages[pkgname,arch]) {
packages[pkgname,arch] = filename
} else {
packages[pkgname,arch] = packages[pkgname,arch] SUBSEP filename
}
}
BEGIN {
# create whitelist
wlen = ARGV[1]; delete ARGV[1]
for (i = 2; i < 2 + wlen; i++) {
whitelist[ARGV[i]] = 1
delete ARGV[i]
}
# create blacklist
blen = ARGV[i]; delete ARGV[i]
while (i++ < ARGC) {
blacklist[ARGV[i]] = 1
delete ARGV[i]
}
# read package filenames
while (getline < "/dev/stdin") {
parse_filename($0)
}
for (pkglist in packages) {
# idx[1,2] = idx[pkgname,arch]
split(pkglist, idx, SUBSEP)
# enforce architecture match if specified
if (!scanarch || scanarch == idx[2]) {
count = split(packages[idx[1], idx[2]], pkgs, SUBSEP)
for(i = 1; i <= count - keep; i++) {
print pkgs[i]
}
}
}
}' "${@:3}"
}
m4_include(../scripts/library/size_to_human.sh)
runcmd() {
if (( needsroot && EUID != 0 )); then
msg "Privilege escalation required"
if sudo -v &>/dev/null && sudo -l &>/dev/null; then
sudo "$@"
else
die 'Unable to escalate privileges using sudo'
fi
else
"$@"
fi
}
summarize() {
(( QUIET )) && return
local -i filecount=$1; shift
local seenarch= seen= arch= name=
local -r pkg_re='(.+)-[^-]+-[0-9]+-([^.]+)\.pkg.*'
if (( delete )); then
printf -v output 'finished: %d packages removed' "$filecount"
elif (( move )); then
printf -v output "finished: %d packages moved to '%s'" "$filecount" "$movedir"
elif (( dryrun )); then
if (( verbose )); then
msg "Candidate packages:"
while read -r pkg; do
if (( verbose >= 3 )); then
[[ $pkg =~ $pkg_re ]] && name=${BASH_REMATCH[1]} arch=${BASH_REMATCH[2]}
if [[ -z $seen || $seenarch != "$arch" || $seen != "$name" ]]; then
seen=$name seenarch=$arch
printf '%s (%s):\n' "${name##*/}" "$arch"
fi
printf ' %s\n' "${pkg##*/}"
elif (( verbose >= 2 )); then
printf "%s$delim" "$pkg"
else
printf "%s$delim" "${pkg##*/}"
fi
done < <(printf '%s\n' "$@" | pacsort --files)
fi
printf -v output 'finished dry run: %d candidates' "$filecount"
fi
echo
msg "$output (disk space saved: %s)" "$(size_to_human "$totalsaved")"
}
usage() {
cat <<EOF
${myname} (pacman) v${myver}
A flexible pacman cache cleaning utility.
Usage: ${myname} <operation> [options] [targets...]
Operations:
-d, --dryrun perform a dry run, only finding candidate packages.
-m, --move <dir> move candidate packages to "dir".
-r, --remove remove candidate packages.
Options:
-a, --arch <arch> scan for "arch" (default: all architectures).
-c, --cachedir <dir> scan "dir" for packages. can be used more than once.
(default: read from @sysconfdir@/pacman.conf).
-f, --force apply force to mv(1) and rm(1) operations.
-h, --help display this help message and exit.
-i, --ignore <pkgs> ignore "pkgs", comma-separated. Alternatively, specify
"-" to read package names from stdin, newline-
delimited.
-k, --keep <num> keep "num" of each package in the cache (default: 3).
--nocolor remove color from output.
-q, --quiet minimize output
-u, --uninstalled target uninstalled packages.
-v, --verbose increase verbosity. specify up to 3 times.
-z, --null use null delimiters for candidate names (only with -v
and -vv).
EOF
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2011 Dave Reisner <dreisner@archlinux.org>'
}
OPT_SHORT=':a:c:dfhi:k:m:qrsuVvz'
OPT_LONG=('arch:' 'cachedir:' 'dryrun' 'force' 'help' 'ignore:' 'keep:' 'move'
'nocolor' 'quiet' 'remove' 'uninstalled' 'version' 'verbose' 'null')
if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
exit 1
fi
set -- "${OPTRET[@]}"
unset OPT_SHORT OPT_LONG OPTRET
while :; do
case $1 in
-a|--arch)
scanarch=$2
shift ;;
-c|--cachedir)
cachedirs+=("$2")
shift ;;
-d|--dryrun)
dryrun=1 ;;
-f|--force)
cmdopts=(-f) ;;
-h|--help)
usage
exit 0 ;;
-i|--ignore)
if [[ $2 = '-' ]]; then
[[ ! -t 0 ]] && IFS=$'\n' read -r -d '' -a ign
else
IFS=',' read -r -a ign <<< "$2"
fi
blacklist+=("${ign[@]}")
unset i ign
shift ;;
-k|--keep)
keep=$2
if [[ -z $keep || -n ${keep//[0-9]/} ]]; then
die 'argument to option -k must be a non-negative integer'
else
keep=$(( 10#$keep ))
fi
shift ;;
-m|--move)
move=1 movedir=$2
shift ;;
--nocolor)
USE_COLOR='n' ;;
-q|--quiet)
QUIET=1 ;;
-r|--remove)
delete=1 ;;
-u|--uninstalled)
IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq)
# pacman -Qq may exit with an error, thus making ign an empty array
(( ${#ign[@]} )) || die 'failed to retrieve the list of installed packages'
blacklist+=("${ign[@]}")
unset ign ;;
-V|--version)
version
exit 0 ;;
-v|--verbose)
(( ++verbose )) ;;
-z|--null)
delim='\0' ;;
--)
shift
break 2 ;;
esac
shift
done
m4_include(../scripts/library/term_colors.sh)
# setting default cachedir
if [[ -z $cachedirs ]]; then
if cachedir=$(get_cachedir_from_config "@sysconfdir@/pacman.conf"); then
cachedirs=("$cachedir")
else
cachedirs=("${cachedirs[@]:-@localstatedir@/cache/pacman/pkg}")
fi
fi
# remaining args are a whitelist
whitelist=("$@")
# sanity checks
case $(( dryrun+delete+move )) in
0) die "no operation specified (use -h for help)" ;;
[^1]) die "only one operation may be used at a time" ;;
esac
[[ $movedir && ! -d $movedir ]] &&
die "destination directory '%s' does not exist or is not a directory" "$movedir"
if (( move || delete )); then
# make it an absolute path since we're about to chdir
[[ $movedir && ${movedir:0:1} != '/' ]] && movedir=$PWD/$movedir
[[ $movedir && ! -w $movedir ]] && needsroot=1
fi
for cachedir in "${cachedirs[@]}"; do
[[ -d $cachedir ]] ||
die "cachedir '%s' does not exist or is not a directory" "$cachedir"
if (( move || delete )); then
[[ ! -w $cachedir ]] && needsroot=1
fi
# unlikely that this will fail, but better make sure
pushd "$cachedir" &>/dev/null || die "failed to chdir to '%s'" "$cachedir"
# note that these results are returned in an arbitrary order from awk, but
# they'll be resorted (in summarize) iff we have a verbosity level set.
IFS=$'\n' read -r -d '' -a cand < \
<(printf '%s\n' "$PWD"/*.pkg.tar?(.+([^.])) | pacsort --files |
pkgfilter "$keep" "$scanarch" \
"${#whitelist[*]}" "${whitelist[@]}" \
"${#blacklist[*]}" "${blacklist[@]}")
candidates+=("${cand[@]}")
unset cand
popd &>/dev/null
done
if (( ! ${#candidates[*]} )); then
msg 'no candidate packages found for pruning'
exit 0
fi
# grab this prior to signature scavenging
pkgcount=${#candidates[*]}
# copy the list, merging in any found sigs
for cand in "${candidates[@]}"; do
candtemp+=("$cand")
[[ -f $cand.sig ]] && candtemp+=("$cand.sig")
done
candidates=("${candtemp[@]}")
unset candtemp
# do this before we destroy anything
totalsaved=$(@SIZECMD@ "${candidates[@]}" | awk '{ sum += $1 } END { print sum }')
# crush. kill. destroy.
(( verbose )) && cmdopts+=(-v)
if (( delete )); then
printf '%s\0' "${candidates[@]}" | runcmd xargs -0 rm "${cmdopts[@]}"
elif (( move )); then
printf '%s\0' "${candidates[@]}" | runcmd xargs -0 mv "${cmdopts[@]}" -t "$movedir"
fi
summarize "$pkgcount" "${candidates[@]}"
# vim: set noet:

194
contrib/pacdiff.sh.in Normal file
View file

@ -0,0 +1,194 @@
#!/bin/bash
# pacdiff : a simple pacnew/pacsave updater
#
# Copyright (c) 2007 Aaron Griffin <aaronmgriffin@gmail.com>
# Copyright (c) 2013-2016 Pacman Development Team <pacman-dev@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/>.
#
shopt -s extglob
declare -r myname='pacdiff'
declare -r myver='@PACKAGE_VERSION@'
diffprog=${DIFFPROG:-'vim -d'}
diffsearchpath=${DIFFSEARCHPATH:-/etc}
USE_COLOR='y'
declare -a oldsaves
declare -i USE_FIND=0 USE_LOCATE=0 USE_PACDB=0 OUTPUTONLY=0
m4_include(../scripts/library/output_format.sh)
usage() {
cat <<EOF
${myname} (pacman) v${myver}
A simple program to merge or remove pacnew/pacsave files.
Usage: $myname [-l | -f | -p] [--nocolor]
Search Options: select one (default: --pacmandb)
-l/--locate scan using locate
-f/--find scan using find
-p/--pacmandb scan active config files from pacman database
General Options:
-o/--output print files instead of merging them
--nocolor remove colors from output
Environment Variables:
DIFFPROG override the merge program: (default: 'vim -d')
DIFFSEARCHPATH override the search path. (only when using find)
(default: /etc)
Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" $myname
Example: $myname --output --locate
EOF
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2007 Aaron Griffin <aaronmgriffin@gmail.com>'
echo 'Copyright (C) 2013-2016 Pacman Development Team <pacman-dev@archlinux.org>'
}
print_existing() {
[[ -f "$1" ]] && printf '%s\0' "$1"
}
print_existing_pacsave(){
for f in "${1}"?(.+([0-9])); do
[[ -f $f ]] && printf '%s\0' "$f"
done
}
cmd() {
if (( USE_LOCATE )); then
locate -0 -e -b \*.pacnew \*.pacorig \*.pacsave '*.pacsave.[0-9]*'
elif (( USE_FIND )); then
find $diffsearchpath \( -name \*.pacnew -o -name \*.pacorig -o -name \*.pacsave -o -name '*.pacsave.[0-9]*' \) -print0
elif (( USE_PACDB )); then
awk '/^%BACKUP%$/ {
while (getline) {
if (/^$/) { nextfile }
print $1
}
}' "${pac_db}"/*/files | while read -r bkup; do
print_existing "/$bkup.pacnew"
print_existing "/$bkup.pacorig"
print_existing_pacsave "/$bkup.pacsave"
done
fi
}
while [[ -n "$1" ]]; do
case "$1" in
-l|--locate)
USE_LOCATE=1;;
-f|--find)
USE_FIND=1;;
-p|--pacmandb)
USE_PACDB=1;;
-o|--output)
OUTPUTONLY=1;;
--nocolor)
USE_COLOR='n';;
-V|--version)
version; exit 0;;
-h|--help)
usage; exit 0;;
*)
usage; exit 1;;
esac
shift
done
m4_include(../scripts/library/term_colors.sh)
if ! type -p ${diffprog%% *} >/dev/null && (( ! OUTPUTONLY )); then
error "Cannot find the $diffprog binary required for viewing differences."
exit 1
fi
case $(( USE_FIND + USE_LOCATE + USE_PACDB )) in
0) USE_PACDB=1;; # set the default search option
[^1]) error "Only one search option may be used at a time"
usage; exit 1;;
esac
if (( USE_PACDB )); then
if [[ ! -r @sysconfdir@/pacman.conf ]]; then
error "unable to read @sysconfdir@/pacman.conf"
usage; exit 1
fi
eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
pac_db="${DBPath:-@localstatedir@/lib/pacman/}local"
if [[ ! -d "${pac_db}" ]]; then
error "unable to read pacman database %s". "${pac_db}"
usage; exit 1
fi
fi
# see http://mywiki.wooledge.org/BashFAQ/020
while IFS= read -u 3 -r -d '' pacfile; do
file="${pacfile%.pac*}"
file_type="pac${pacfile##*.pac}"
if (( OUTPUTONLY )); then
echo "$pacfile"
continue
fi
# add matches for pacsave.N to oldsaves array, do not prompt
if [[ $file_type = pacsave.+([0-9]) ]]; then
oldsaves+=("$pacfile")
continue
fi
msg "%s file found for %s" "$file_type" "$file"
if [ ! -f "$file" ]; then
warning "$file does not exist"
rm -iv "$pacfile"
continue
fi
if cmp -s "$pacfile" "$file"; then
msg2 "Files are identical, removing..."
rm -v "$pacfile"
else
ask "(V)iew, (S)kip, (R)emove %s, (O)verwrite with %s, (Q)uit: [v/s/r/o/q] " "$file_type" "$file_type"
while read c; do
case $c in
q|Q) exit 0;;
r|R) rm -v "$pacfile"; break ;;
o|O) mv -v "$pacfile" "$file"; break ;;
v|V)
$diffprog "$pacfile" "$file"
ask "(V)iew, (S)kip, (R)emove %s, (O)verwrite with %s, (Q)uit: [v/s/r/o/q] " "$file_type" "$file_type";
continue ;;
s|S) break ;;
*) ask "Invalid answer. Try again: [v/s/r/o/q] "; continue ;;
esac
done
fi
done 3< <(cmd)
(( ${#oldsaves[@]} )) && warning "Ignoring %s" "${oldsaves[@]}"
exit 0
# vim: set noet:

68
contrib/paclist.sh.in Normal file
View file

@ -0,0 +1,68 @@
#!/bin/bash
# paclist - List all packages installed from a given repo
#
# Copyright (C) 2008 Dan McGee <dpmcgee@gmail.com>
# Copyright (C) 2011 Dave Reisner <dreisner@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/>.
declare -r myname='paclist'
declare -r myver='@PACKAGE_VERSION@'
export TEXTDOMAIN='pacman'
export TEXTDOMAINDIR='/usr/share/locale'
# determine whether we have gettext; make it a no-op if we do not
if ! type gettext &>/dev/null; then
gettext() {
echo "$@"
}
fi
usage() {
printf "%s (pacman) v%s\n" "${myname}" "${myver}"
echo
printf "List all packages installed from a given repository\n" "${myname}"
echo
printf "Usage: %s <repository>\n" "${myname}"
echo
printf "Example: %s testing\n" "${myname}"
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2008 Dan McGee <dpmcgee@gmail.com>'
echo 'Copyright (C) 2011 Dave Reisner <dreisner@archlinux.org>'
}
if [[ -z $1 ]]; then
usage
exit 1
fi
if [[ $1 = -@(h|-help) ]]; then
usage
exit 0
elif [[ $1 = -@(V|-version) ]]; then
version
exit 0
fi
printf -v installed '[%s]' "$(gettext installed)"
pacman -Sl $1 | awk -v i="$installed" '$NF == i { print $2,$3 }'
# exit with pacman's return value, not awk's
exit ${PIPESTATUS[0]}
# vim: set noet:

View file

@ -0,0 +1,99 @@
#!/bin/bash
#
# paclog-pkglist - Parse a log file into a list of currently installed packages
#
# Copyright (C) 2011 Dave Reisner <dave@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/>.
declare -r myname='paclog-pkglist'
declare -r myver='@PACKAGE_VERSION@'
export TEXTDOMAIN='pacman'
export TEXTDOMAINDIR='/usr/share/locale'
declare logfile=${1:-@localstatedir@/log/pacman.log}
usage() {
printf "%s (pacman) v%s\n" "${myname}" "${myver}"
echo
echo "Parse a log file into a list of currently installed packages"
echo
printf "Usage: %s [path to pacman log]\n" "${myname}"
echo
printf "Example: %s @localstatedir@/log/pacman.log\n" "${myname}"
echo
echo 'Defaults to: @localstatedir@/log/pacman.log'
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2011 Dave Reisner <dave@archlinux.org>'
}
if [[ $1 ]]; then
if [[ $1 = -@(h|-help) ]]; then
usage
exit 0
elif [[ $1 = -@(V|-version) ]]; then
version
exit 0
elif [[ ! -e $logfile ]]; then
printf $"target not found: %s\n" "$1"
exit 1
fi
fi
<"$logfile" awk '
{
if ($3 ~ /^\[.*\]$/) {
# new style with caller name
action = $4
pkgname = $5
pkgver = $6
upgver = $8
nfields = NF
} else {
action = $3
pkgname = $4
pkgver = $5
upgver = $7
nfields = (NF + 1) # compensate for missing caller field
}
}
nfields == 6 && action == "installed" {
gsub(/[()]/, "", pkgver)
pkg[pkgname] = pkgver
next
}
nfields == 8 && (action == "upgraded" || action == "downgraded") {
sub(/\)/, "", upgver)
pkg[pkgname] = upgver
next
}
nfields == 6 && action == "removed" {
pkg[pkgname] = -1
}
END {
for (i in pkg) {
if (pkg[i] != -1) {
printf "%s %s\n",i,pkg[i]
}
}
}' | sort
# vim: set noet:

140
contrib/pacscripts.sh.in Normal file
View file

@ -0,0 +1,140 @@
#!/bin/bash
#
# pacscripts : tries to print out the {pre,post}_{install,remove,upgrade}
# scripts of a given package
#
# Copyright (c) 2009 Xavier Chantry <shiningxc@gmail.com>
# Copyright (c) 2009-2016 Pacman Development Team <pacman-dev@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/>.
#
# bash options
set -o nounset
set -o errexit
declare -r myname='pacscripts'
declare -r myver='@PACKAGE_VERSION@'
conf="@sysconfdir@/pacman.conf"
if [ ! -r "$conf" ]; then
echo "ERROR: unable to read $conf"
exit 1
fi
eval $(awk '/DBPath/ {print $1$2$3}' "$conf")
eval $(awk '/CacheDir/ {print $1$2$3}' "$conf")
pac_db="${DBPath:-@localstatedir@/lib/pacman}/local"
pac_cache="${CacheDir:-@localstatedir@/cache/pacman/pkg}"
error() {
local mesg=$1; shift
printf "==> $(gettext "ERROR:") ${mesg}\n" "$@" >&2
}
usage() {
echo "${myname} (pacman) v${myver}"
echo
echo "Prints the {pre,post}_{install,remove,upgrade} scripts of a given package."
echo
echo "Usage: ${myname} <pkgname|pkgfile>"
echo
echo " Options:"
echo " -h, --help Print this help message"
echo " -v, --version Print program name and version"
echo
echo "Example: ${myname} gconf-editor"
echo "Example: ${myname} gconf-editor-3.0.1-3-x86_64.pkg.tar.xz"
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (c) 2009 Giulio "giulivo" Fidente <giulivo.navigante@gmail.com>'
echo 'Copyright (c) 2009 Xavier Chantry <shiningxc@gmail.com>'
}
spacman() {
if [ $EUID -eq 0 ]; then
pacman "$@"
else
if ! type -p sudo; then
error "Cannot find the sudo binary!"
error "${myname} requires root privileges. Either install \"sudo\" or run as root."
exit 1
else
sudo pacman "$@"
fi
fi
}
print_db() {
pkg=$(pacman -Q "$1")
pkg=${pkg/ /-}
if [ -f $pac_db/$pkg*/install ]; then
cat $pac_db/$pkg*/install
echo
return 0
else
error "Package $1 does not include any .INSTALL script"
return 1
fi
}
print_pkg() {
if ! bsdtar -xqOf "$1" .INSTALL 2>/dev/null; then
error "Package $1 does not include any .INSTALL script"
return 1
fi
echo
}
print_scriptlet() {
if [ -f "$1" ]; then
if bsdtar tf "$1" .PKGINFO &>/dev/null; then
print_pkg "$1"
return
fi
fi
if pacman -Q "$1" &>/dev/null; then
print_db "$1"
return
fi
if ! pacman -Si $1 &>/dev/null; then
error "Package $1 not found"
return 1
fi
url=$(pacman -Sddp $1)
filename=$(basename $url)
if [ ! -f "$pac_cache/$filename" ]; then
if ! spacman -Sddw --noconfirm $1 >&2; then
error "Failed to download $1"
return 1
fi
echo >&2
fi
print_pkg "$pac_cache/$filename"
return
}
if [ $# -ne 1 ] ; then
usage
exit 1
fi
case "$1" in
--help|-h) usage; exit 0 ;;
--version|-V) version; exit 0 ;;
*) print_scriptlet $1 ;;
esac

125
contrib/pacsearch.in Normal file
View file

@ -0,0 +1,125 @@
#!/usr/bin/perl
# pacsearch - Perform a pacman search using both the local and the sync databases
#
# Copyright (C) 2008-2014 Dan McGee <dan@archlinux.org>
#
# Based off original shell script version:
# Copyright (C) 2006-2007 Dan McGee <dan@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/>.
use strict;
use warnings;
use Term::ANSIColor;
my $myname = 'pacsearch';
my $myver = '@PACKAGE_VERSION@';
sub usage {
print "$myname (pacman) v$myver\n\n";
print "Perform a pacman search using both the local and the sync databases.\n\n";
print "Usage: $myname [-n] <pattern>\n\n";
print "Options:\n";
print " -n, --nocolor: turn off coloring\n\n";
print "Example: $myname ^gnome\n";
}
sub version {
printf "%s %s\n", $myname, $myver;
print "Copyright (C) 2008-2014 Dan McGee <dan\@archlinux.org>\n\n";
print "Based off original shell script version:\n";
print "Copyright (C) 2006-2007 Dan McGee <dan\@archlinux.org>\n";
}
if ($#ARGV lt 0 || $ARGV[0] eq "--help" || $ARGV[0] eq "-h") {
usage;
if ($#ARGV lt 0) {
exit 1;
}
exit 0;
}
if ($ARGV[0] eq "--version" || $ARGV[0] eq "-V") {
version;
exit 0;
}
# define formatting variables
my($BLUE, $CYAN, $GREEN, $MAGENTA, $RED, $YELLOW, $BOLD, $RESET);
if ($ARGV[0] eq "--nocolor" || $ARGV[0] eq "-n") {
shift;
$BLUE = "";
$CYAN = "";
$GREEN = "";
$MAGENTA = "";
$RED = "";
$YELLOW = "";
$BOLD = "";
$RESET = "";
} else {
$BLUE = color('blue');
$CYAN = color('cyan');
$GREEN = color('green');
$MAGENTA = color('magenta');
$RED = color('red');
$YELLOW = color('yellow');
$BOLD = color('bold');
$RESET = color('reset');
}
# localization
my $LC_INSTALLED = `gettext pacman installed`;
# Print a "repo/pkgname pkgver (groups) [installed]" line.
# We stick to pacman colors.
sub print_pkg {
my @v = @_;
print "$RESET$BOLD";
if ( "$v[0]" eq "local" ) {
print "$RED";
} else {
print "$MAGENTA";
}
print "$v[0]/$RESET$BOLD$v[1] $GREEN$v[2]$BLUE$v[3]$CYAN$v[4]$RESET\n";
print "$v[5]";
}
sub list_pkg {
my $db = shift;
open (my $out, '-|', 'pacman', $db, '--', @ARGV) or exit 1;
my @pkglist = ();
while ( readline($out) ) {
# We grab the following fields: repo, name, ver, group, installed, and
# desc. We grab leading space for 'group' and 'installed' so that we do
# not need to test if non-empty when printing.
my @pkgfields = /^(.*?)\/(.*?) (.*?)( \(.*?\))?( \[.*\])?$/s;
my $desc = readline($out);
# since 'group' and 'installed' are optional, we should fill it in if
# necessary
$pkgfields[3] = "" if not defined $pkgfields[3];
$pkgfields[4] = "" if not defined $pkgfields[4];
$pkgfields[5] = $desc;
push (@pkglist, \@pkgfields);
}
close ($out);
return @pkglist;
}
my @sync = list_pkg('-Ss', @ARGV);
my %allpkgs = map {$_->[1] . $_->[2] => 1} @sync;
my @query = grep { not $allpkgs{$_->[1] . $_->[2]}} list_pkg('-Qs', @ARGV);
$_->[4] = " [$LC_INSTALLED]" foreach @query;
print_pkg (@{$_}) foreach (@sync, @query);
#vim: set noet:

234
contrib/rankmirrors.sh.in Normal file
View file

@ -0,0 +1,234 @@
#!/bin/bash
#
# rankmirrors - read a list of mirrors from a file and rank them by speed
# @configure_input@
#
# Copyright (c) 2009 Matthew Bruenig <matthewbruenig@gmail.com>
#
# 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 3 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/>.
# traps interrupt key to spit out pre-interrupt info
trap finaloutput INT
declare -r myname='rankmirrors'
declare -r myver='@PACKAGE_VERSION@'
usage() {
echo "${myname} (pacman) v${myver}"
echo
echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror"
echo "files are located in @sysconfdir@/pacman.d/. It can also rank one mirror if the URL is"
echo "provided."
echo
echo "Usage: ${myname} [options] MIRRORFILE | URL"
echo
echo "Options:"
echo " --version show program's version number and exit"
echo " -h, --help show this help message and exit"
echo " -n NUM number of servers to output, 0 for all"
echo " -t, --times only output mirrors and their response times"
echo " -u, --url test a specific URL"
echo " -v, --verbose be verbose in ouptut"
echo " -r, --repo specify a repository name instead of guessing"
exit 0
}
version() {
echo "${myname} (pacman) ${myver}"
echo "Copyright (c) 2009 Matthew Bruenig <matthewbruenig@gmail.com>."
echo
echo "This is free software; see the source for copying conditions."
echo "There is NO WARRANTY, to the extent permitted by law."
exit 0
}
err() {
echo "$1" >&2
exit 1
}
# gettime fetchurl (e.g gettime http://foo.com/core/os/i686/core.db.tar.gz)
# returns the fetching time, or timeout, or unreachable
gettime() {
IFS=' ' output=( $(curl -s -m 10 -w "%{time_total} %{http_code}" "$1" -o/dev/null) )
(( $? == 28 )) && echo timeout && return
(( ${output[1]} >= 400 || ! ${output[1]} )) && echo unreachable && return
echo "${output[0]}"
}
# getfetchurl serverurl (e.g. getturl http://foo.com/core/os/i686)
# if $repo is in the line, then assumes core
# if $arch is in the line, then assumes $(uname -m)
# returns a fetchurl (e.g. http://foo.com/core/os/i686/core.db.tar.gz)
ARCH="$(uname -m)"
getfetchurl() {
local strippedurl="${1%/}"
local replacedurl="${strippedurl//'$arch'/$ARCH}"
if [[ ! $TARGETREPO ]]; then
replacedurl="${replacedurl//'$repo'/core}"
local tmp="${replacedurl%/*}"
tmp="${tmp%/*}"
local reponame="${tmp##*/}"
else
replacedurl="${replacedurl//'$repo'/$TARGETREPO}"
local reponame="$TARGETREPO"
fi
if [[ -z $reponame || $reponame = $replacedurl ]]; then
echo "fail"
else
local fetchurl="${replacedurl}/$reponame.db"
echo "$fetchurl"
fi
}
# This exists to remove the need for a separate interrupt function
finaloutput() {
IFS=$'\n' read -r -d '' -a sortedarray < \
<(printf '%s\n' "${timesarray[@]}" | LC_COLLATE=C sort)
# Final output for mirrorfile
numiterator="0"
if [[ $TIMESONLY ]]; then
echo
echo " Servers sorted by time (seconds):"
for line in "${sortedarray[@]}"; do
echo "${line#* } : ${line% *}"
((numiterator++))
(( NUM && numiterator >= NUM )) && break
done
else
for line in "${sortedarray[@]}"; do
echo "Server = ${line#* }"
((numiterator++))
(( NUM && numiterator >= NUM )) && break
done
fi
exit 0
}
# Argument parsing
[[ $1 ]] || usage
while [[ $1 ]]; do
if [[ ${1:0:2} = -- ]]; then
case "${1:2}" in
help) usage ;;
version) version ;;
times) TIMESONLY=1 ; shift ;;
verbose) VERBOSE=1 ; shift ;;
url)
CHECKURL=1;
[[ $2 ]] || err "Must specify URL.";
URL="$2";
shift 2;;
repo)
[[ $2 ]] || err "Must specify repository name.";
TARGETREPO="$2";
shift 2;;
*) err "'$1' is an invalid argument."
esac
elif [[ ${1:0:1} = - ]]; then
if [[ ! ${1:1:1} ]]; then
[[ -t 0 ]] && err "Stdin is empty."
IFS=$'\n' linearray=( $(</dev/stdin) )
STDIN=1
shift
else
snum=1
for ((i=1 ; i<${#1}; i++)); do
case ${1:$i:1} in
h) usage ;;
t) TIMESONLY=1 ;;
v) VERBOSE=1 ;;
u)
CHECKURL=1;
[[ $2 ]] || err "Must specify URL.";
URL="$2";
snum=2;;
r)
[[ $2 ]] || err "Must specify repository name.";
TARGETREPO="$2";
snum=2;;
n)
[[ $2 ]] || err "Must specify number.";
NUM="$2";
snum=2;;
*) err "'$1' is an invalid argument." ;;
esac
done
shift $snum
fi
elif [[ -f $1 ]]; then
FILE="1"
IFS=$'\n' linearray=( $(<$1) )
[[ $linearray ]] || err "File is empty."
shift
else
err "'$1' does not exist."
fi
done
# Some sanity checks
[[ $NUM ]] || NUM=0
[[ $FILE && $CHECKURL ]] && err "Cannot specify a URL and mirrorfile."
[[ $FILE || $CHECKURL || $STDIN ]] || err "Must specify URL, mirrorfile, or stdin."
# Single URL handling
if [[ $CHECKURL ]]; then
url="$(getfetchurl "$URL")"
[[ $url = fail ]] && err "URL '$URL' is malformed."
[[ $VERBOSE ]] && echo "Testing $url..."
time=$(gettime "$url")
echo "$URL : $time"
exit 0
fi
# Get URL results from mirrorfile, fill up the array, and so on
if [[ $TIMESONLY ]]; then
echo "Querying servers. This may take some time..."
elif [[ $FILE ]]; then
echo "# Server list generated by rankmirrors on $(date +%Y-%m-%d)"
fi
timesarray=()
for line in "${linearray[@]}"; do
if [[ $line =~ ^[[:space:]]*# ]]; then
[[ $TIMESONLY ]] || echo $line
elif [[ $line =~ ^[[:space:]]*Server ]]; then
# Getting values and times and such
server="${line#*= }"
server="${server%%#*}"
url="$(getfetchurl "$server")"
[[ $url = fail ]] && err "URL '$URL' is malformed."
time=$(gettime "$url")
timesarray+=("$time $server")
# Output
if [[ $VERBOSE && $TIMESONLY ]]; then
echo "$server ... $time"
elif [[ $VERBOSE ]]; then
echo "# $server ... $time"
elif [[ $TIMESONLY ]]; then
echo -n " *"
fi
fi
done
finaloutput
# vim: set noet:

106
contrib/updpkgsums.sh.in Normal file
View file

@ -0,0 +1,106 @@
#!/bin/bash
#
# updpkgsums - update source checksums in-place in PKGBUILDs
#
# Copyright (C) 2012-2013 Dave Reisner <dreisner@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/>.
shopt -s extglob
declare -r myname='updpkgsums'
declare -r myver='@PACKAGE_VERSION@'
usage() {
printf "%s (pacman) v%s\n" "${myname}" "${myver}"
echo
printf "%s will perform an in place update of the checksums in the\n" "${myname}"
echo "path specified by [build file], defaulting to PKGBUILD in the current"
echo "working directory."
echo
printf "Usage: %s [build file]\n" "${myname}"
echo
echo " -h, --help display this help message and exit"
echo " -V, --version display version information and exit"
}
version() {
printf "%s %s\n" "$myname" "$myver"
echo 'Copyright (C) 2012-2013 Dave Reisner <dreisner@archlinux.org>'
}
die() {
printf "==> ERROR: $1\n" "${@:2}" >&2
exit 1
}
case $1 in
-h|--help) usage; exit ;;
-V|--version) version; exit ;;
esac
buildfile=${1:-PKGBUILD}
if [[ ! -f $buildfile ]]; then
die "%s not found or is not a file" "$buildfile"
fi
# Resolve any symlinks to avoid replacing the symlink with a file. But, we
# have to do this portably -- readlink's flags are inconsistent across OSes.
while [[ -L $buildfile ]]; do
buildfile=$(readlink "$buildfile")
if [[ $buildfile = */* ]]; then
cd "${buildfile%/*}"
buildfile=${buildfile##*/}
fi
done
# cd into the directory with the build file. This avoids creating random src/
# directories scattered about the filesystem, and avoids cases where we might
# not be able to write in the $PWD.
if [[ $buildfile = */* ]]; then
cd "${buildfile%/*}"
buildfile=${buildfile##*/}
fi
# Check $PWD/ for permission to unlink the $buildfile and write a new one
if [[ ! -w . ]]; then
die "No write permission in '%s'" "$PWD"
fi
# Generate the new sums
export BUILDDIR=$(mktemp -d "${TMPDIR:-/tmp}/updpkgsums.XXXXXX")
newbuildfile=$(mktemp "${TMPDIR:-/tmp}/updpkgsums.XXXXXX")
trap "rm -rf '$BUILDDIR' '$newbuildfile'" EXIT
newsums=$(makepkg -g -p "$buildfile") || die 'Failed to generate new checksums'
awk -v newsums="$newsums" '
/^[[:blank:]]*(md|sha)[[:digit:]]+sums(_[^=]+)?=/,/\)[[:blank:]]*(#.*)?$/ {
if (!w) {
print newsums
w++
}
next
}
1
END { if (!w) print newsums }
' "$buildfile" > "$newbuildfile" || die 'Failed to write new PKGBUILD'
# Rewrite the original buildfile. Use cat instead of mv/cp to preserve
# permissions implicitly.
if ! cat -- "$newbuildfile" >"$buildfile"; then
die "Failed to update %s. The file has not been modified." "$buildfile"
fi
# vim: set noet:

25
contrib/vimprojects Normal file
View file

@ -0,0 +1,25 @@
This is a project file
for the vim-project plugin.
Save it as ~/.vimprojects
$ pacman -S vim-project
change the pacman path below
$ vim
:Project
Press \r in the project view
on a project name to generate
the list of files
pacman=~/devel/pacman/ CD=. filter="*.ac *.am" flags=S {
libalpm=lib/libalpm/ filter="*.c *.h *.am" {
}
pacman=src/pacman/ filter="*.c *.h *.am" {
}
scripts=scripts/ filter="*.sh.in *.py.in *.am" {
}
utils=src/util filter="*.c *.h *.am" {
}
contrib=contrib CD=. {
}
}

16
doc/.gitignore vendored
View file

@ -1,4 +1,17 @@
*.[1-8]
alpm-hooks.5
PKGBUILD.5
libalpm.3
makepkg.8
makepkg-template.1
makepkg.conf.5
pacman.8
pacman-key.8
pacman.conf.5
pactree.8
pkgdelta.8
repo-add.8
repo-remove.8
vercmp.8
asciidoc-manpage.css
asciidoc.css
asciidoc.js
@ -6,4 +19,3 @@ asciidoc.js
*.xml
man3
website.tar.gz
Doxyfile

View file

@ -1,79 +0,0 @@
BUILDINFO(5)
============
Name
----
BUILDINFO - Makepkg package build information file
Synopsis
--------
This manual page describes the format of a BUILDINFO file found in the root of
a package created by makepkg. The file contains a description of the package's
build environment. The information is formatted in key-value pairs separated by
a '=', one value per line. Arrays are represented as multiple key-value pairs
having the same key.
Description
-----------
This is a description of the contents of version '2' of the
BUILDINFO file format.
*format*::
Denotes the file format version, represented by a plain positive integer.
*pkgname*::
The name of the package.
*pkgbase*::
The base name of a package, usually the same as the pkgname except for
split packages.
*pkgver*::
The version of the package including pkgrel and epoch.
*pkgarch*::
The architecture of the package.
*pkgbuild_sha256sum*::
The sha256sum in hex format of the PKGBUILD used to build the package.
*packager*::
The details of the packager that built the package.
*builddate*::
The build date of the package in epoch.
*builddir*::
The directory where the package was built.
*startdir*::
The directory from which makepkg was executed.
*buildtool*::
The name of the tool ecosystem used to set up the build environment. Used
for defining a spec for reproducible builds, e.g. the source of the
linkman:makepkg.conf[5] used.
*buildtoolver*::
The full version of the 'buildtool', for example:
"$pkgver-$pkgrel-$pkgarch".
*buildenv (array)*::
The build environment specified in makepkg.conf.
*options (array)*::
The options set specified when building the package.
*installed (array)*::
The installed packages at build time including the version information of
the package. Formatted as "$pkgname-$pkgver-$pkgrel-$pkgarch".
See Also
--------
linkman:makepkg[8], linkman:pacman[8], linkman:makepkg.conf[5]
include::footer.asciidoc[]

View file

@ -1,4 +1,4 @@
# Doxyfile 1.9.3
# Doxyfile 1.8.2
#---------------------------------------------------------------------------
# Project related configuration options
@ -8,9 +8,8 @@ PROJECT_NAME = libalpm
PROJECT_NUMBER =
PROJECT_BRIEF = "Arch Linux Package Manager Library"
PROJECT_LOGO =
OUTPUT_DIRECTORY = @OUTPUT_DIRECTORY@
OUTPUT_DIRECTORY = ./
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
@ -32,47 +31,41 @@ STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
JAVADOC_BANNER = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = YES
TYPEDEF_HIDES_STRUCT = YES
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PRIV_VIRTUAL = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
RESOLVE_UNNAMED_PARAMS = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
@ -80,10 +73,7 @@ HIDE_IN_BODY_DOCS = YES
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_HEADERFILE = YES
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
@ -105,30 +95,26 @@ FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @INPUT_DIRECTORY@/../lib/libalpm/alpm.h \
@INPUT_DIRECTORY@/../lib/libalpm/alpm_list.h
INPUT = ../lib/libalpm/
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS = _alpm_* \
__alpm_*
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
@ -137,9 +123,8 @@ INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
@ -147,16 +132,16 @@ STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = NO
HTML_OUTPUT = html
@ -169,12 +154,11 @@ HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_DYNAMIC_MENUS = YES
HTML_TIMESTAMP = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_FEEDURL =
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
@ -197,50 +181,36 @@ GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
OBFUSCATE_EMAILS = YES
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
FORMULA_MACROFILE =
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = NO
SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO
SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = letter
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
@ -249,31 +219,26 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# Configuration options related to the man page output
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = YES
MAN_OUTPUT = .
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
@ -289,6 +254,7 @@ SEARCH_INCLUDES = YES
INCLUDE_PATH = ../..
INCLUDE_FILE_PATTERNS = *.h
PREDEFINED = HAVE_CONFIG_H= \
SYMHIDDEN= \
SYMEXPORT= \
HAVE_LIBARCHIVE \
HAVE_LIBCURL \
@ -296,28 +262,29 @@ PREDEFINED = HAVE_CONFIG_H= \
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
DIA_PATH =
CLASS_DIAGRAMS = NO
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
DOT_UML_DETAILS = NO
DOT_WRAP_THRESHOLD = 17
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
@ -325,18 +292,14 @@ CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DIR_GRAPH_MAX_DEPTH = 1
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 3
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

182
doc/Makefile.am Normal file
View file

@ -0,0 +1,182 @@
# We have to do some funny stuff here with the manpages. In order to ensure
# a dist tarball doesn't get put out there without manpages, we keep those
# files listed in EXTRA_DIST no matter what. However, we only add them to
# man_MANS if --enable-asciidoc and/or --enable-doxygen are used.
ASCIIDOC_MANS = \
alpm-hooks.5 \
pacman.8 \
makepkg.8 \
makepkg-template.1 \
repo-add.8 \
vercmp.8 \
pkgdelta.8 \
pacman-key.8 \
pactree.8 \
PKGBUILD.5 \
makepkg.conf.5 \
pacman.conf.5 \
libalpm.3
DOXYGEN_MANS = $(wildcard man3/*.3)
HTML_MANPAGES = \
alpm-hooks.5.html \
pacman.8.html \
makepkg.8.html \
makepkg-template.1.html \
repo-add.8.html \
vercmp.8.html \
pkgdelta.8.html \
pacman-key.8.html \
pactree.8.html \
PKGBUILD.5.html \
makepkg.conf.5.html \
pacman.conf.5.html \
libalpm.3.html
HTML_OTHER = \
index.html \
submitting-patches.html \
translation-help.html \
HACKING.html
HTML_DOCS = \
$(HTML_MANPAGES) \
$(HTML_OTHER)
EXTRA_DIST = \
asciidoc.conf \
asciidoc-override.css \
alpm-hooks.5.txt \
pacman.8.txt \
makepkg.8.txt \
makepkg-template.1.txt \
repo-add.8.txt \
vercmp.8.txt \
pkgdelta.8.txt \
pacman-key.8.txt \
pactree.8.txt \
PKGBUILD.5.txt \
PKGBUILD-example.txt \
makepkg.conf.5.txt \
pacman.conf.5.txt \
libalpm.3.txt \
footer.txt \
index.txt \
submitting-patches.txt \
translation-help.txt \
Doxyfile \
$(ASCIIDOC_MANS) \
$(DOXYGEN_MANS)
# Files that should be removed, but which Automake does not know.
MOSTLYCLEANFILES = *.xml $(ASCIIDOC_MANS) $(HTML_DOCS) repo-remove.8 website.tar.gz
# Ensure manpages are fresh when building a dist tarball
dist-hook:
$(MAKE) $(AM_MAKEFLAGS) clean
$(MAKE) $(AM_MAKEFLAGS) all
if USE_GIT_VERSION
GIT_VERSION := $(shell sh -c 'git describe --abbrev=4 --dirty | sed s/^v//')
REAL_PACKAGE_VERSION = $(GIT_VERSION)
else
REAL_PACKAGE_VERSION = $(PACKAGE_VERSION)
endif
man_MANS =
dist_man_MANS = $(ASCIIDOC_MANS)
if USE_DOXYGEN
man_MANS += $(DOXYGEN_MANS)
all-local: doxygen.in
doxygen.in:
$(DOXYGEN) $(srcdir)/Doxyfile
endif
html: $(HTML_DOCS)
website: website.tar.gz
.PHONY: html website
website.tar.gz: html
$(AM_V_GEN)bsdtar czf $@ $(HTML_DOCS) \
asciidoc-override.css \
-C /etc/asciidoc/stylesheets/ \
asciidoc.css \
-C /etc/asciidoc/javascripts/ \
asciidoc.js \
-C /etc/asciidoc/ \
images
pkgdatadir = ${datadir}/${PACKAGE}
ASCIIDOC_OPTS = \
-f $(srcdir)/asciidoc.conf \
-a pacman_version="$(REAL_PACKAGE_VERSION)" \
-a pacman_date="`date +%Y-%m-%d`" \
-a pkgdatadir=$(pkgdatadir) \
-a localstatedir=$(localstatedir) \
-a sysconfdir=$(sysconfdir) \
-a datarootdir=$(datarootdir)
A2X_OPTS = \
--no-xmllint \
-d manpage \
-f manpage \
--xsltproc-opts='-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0'
# These rules are due to the includes and files of the asciidoc text
$(ASCIIDOC_MANS): asciidoc.conf footer.txt Makefile.am
$(AM_V_GEN)a2x $(A2X_OPTS) --asciidoc-opts="$(ASCIIDOC_OPTS) --out-file=./$@.xml" $(srcdir)/$@.txt
%.html: %.txt
$(AM_V_GEN)asciidoc $(ASCIIDOC_OPTS) -o - $*.txt | \
sed -e 's/\r$$//' > $@
HACKING.html: ../HACKING
$(AM_V_GEN)asciidoc $(ASCIIDOC_OPTS) -o - ../HACKING | \
sed -e 's/\r$$//' > $@
# Customizations for certain HTML docs
$(HTML_MANPAGES): asciidoc.conf footer.txt Makefile.am
$(HTML_OTHER): asciidoc.conf Makefile.am
%.html: ASCIIDOC_OPTS += -a linkcss -a toc -a icons -a max-width=960px -a stylesheet=asciidoc-override.css
%.8.html: ASCIIDOC_OPTS += -d manpage
%.5.html: ASCIIDOC_OPTS += -d manpage
%.3.html: ASCIIDOC_OPTS += -d manpage
# Dependency rules
alpm-hooks.5 alpm-hooks.5.html: alpm-hooks.5.txt
pacman.8 pacman.8.html: pacman.8.txt
makepkg.8 makepkg.8.html: makepkg.8.txt
makepkg-template.1 makepkg-template.1.html: makepkg-template.1.txt
repo-add.8 repo-add.8.html: repo-add.8.txt
vercmp.8 vercmp.8.html: vercmp.8.txt
pkgdelta.8 pkgdelta.8.html: pkgdelta.8.txt
pacman-key.8 pacman-key.8.html: pacman-key.8.txt
pactree.8 pactree.8.html: pactree.8.txt
PKGBUILD.5 PKGBUILD.5.html: PKGBUILD.5.txt PKGBUILD-example.txt
makepkg.conf.5 makepkg.conf.5.html: makepkg.conf.5.txt
pacman.conf.5 pacman.conf.5.html: pacman.conf.5.txt
libalpm.3 libalpm.3.html: libalpm.3.txt
# this one is just a symlink
repo-remove.8: repo-add.8
$(RM) repo-remove.8
$(LN_S) repo-add.8 repo-remove.8
install-data-hook:
cd $(DESTDIR)$(mandir)/man8 && \
$(RM) repo-remove.8 && \
( $(LN_S) repo-add.8 repo-remove.8 || \
ln repo-add.8 repo-remove.8 || \
cp repo-add.8 repo-remove.8 )
uninstall-hook:
$(RM) $(DESTDIR)$(mandir)/man8/repo-remove.8
# vim:set noet:

View file

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

View file

@ -1,9 +1,12 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
PKGBUILD(5)
===========
Name
----
PKGBUILD - Package build description file
PKGBUILD - Arch Linux package build description file
Synopsis
@ -18,9 +21,9 @@ PKGBUILD is written, the actual package is built using makepkg and installed
with pacman.
NOTE: An example PKGBUILD, useful for reference, is located in '{pkgdatadir}'
along with other example files such as an install script. You can copy the
provided PKGBUILD.proto file to a new package build directory and make
customizations to suit your needs.
along with other example files such as a ChangeLog and an install
script. You can copy the provided PKGBUILD.proto file to a new package build
directory and make customizations to suit your needs.
Options and Directives
@ -45,8 +48,7 @@ similar to `$_basekernver`.
*pkgver*::
The version of the software as released from the author (e.g., '2.7.1').
The variable is not allowed to contain colons, forward slashes, hyphens
or whitespace.
The variable is not allowed to contain colons or hyphens.
+
The `pkgver` variable can be automatically updated by providing a `pkgver()`
function in the PKGBUILD that outputs the new package version.
@ -56,13 +58,11 @@ new `pkgver`. This is most useful when used with sources from version control
systems (see below).
*pkgrel*::
This is the release number specific to the distribution. This
This is the release number specific to the Arch Linux release. This
allows package maintainers to make updates to the package's configure
flags, for example. This is typically set to '1' for each new upstream
software release and incremented for intermediate PKGBUILD updates. The
variable is a positive integer, with an optional subrelease level
specified by adding another positive integer separated by a period
(i.e. in the form x.y).
variable is not allowed to contain hyphens.
*epoch*::
Used to force the package to be seen as newer than any previous versions
@ -84,7 +84,14 @@ systems (see below).
*license (array)*::
This field specifies the license(s) that apply to the package.
If multiple licenses are applicable, list all of them:
Commonly used licenses can be found in '/usr/share/licenses/common'. If you
see the package's license there, simply reference it in the license
field (e.g., `license=('GPL')`). If the package provides a license not
available in '/usr/share/licenses/common', then you should include it
in the package itself and set `license=('custom')` or
`license=('custom:LicenseName')`. The license should be placed in
'$pkgdir/usr/share/licenses/$pkgname/' when building the package. If
multiple licenses are applicable, list all of them:
`license=('GPL' 'FDL')`.
*install*::
@ -111,7 +118,7 @@ systems (see below).
+
Additional architecture-specific sources can be added by appending an
underscore and the architecture name e.g., 'source_x86_64=()'. There must be a
corresponding integrity array with checksums, e.g. 'cksums_x86_64=()'.
corresponding integrity array with checksums, e.g. 'md5sums_x86_64=()'.
+
It is also possible to change the name of the downloaded file, which is helpful
with weird URLs and for handling multiple source files with the same
@ -139,19 +146,17 @@ contain whitespace characters.
listed here will not be extracted with the rest of the source files. This
is useful for packages that use compressed data directly.
*cksums (array)*::
This array contains CRC checksums for every source file specified in the
*md5sums (array)*::
This array contains an MD5 hash for every source file specified in the
source array (in the same order). makepkg will use this to verify source
file integrity during subsequent builds. If 'SKIP' is put in the array
in place of a normal hash, the integrity check for that source file will
be skipped. To easily generate cksums, run ``makepkg -g >> PKGBUILD''.
If desired, move the cksums line to an appropriate location. Note that
checksums generated by "makepkg -g" should be verified using checksum
values provided by the software developer.
be skipped. To easily generate md5sums, run ``makepkg -g >> PKGBUILD''.
If desired, move the md5sums line to an appropriate location.
*md5sums, sha1sums, sha224sums, sha256sums, sha384sums, sha512sums, b2sums (arrays)*::
*sha1sums, sha256sums, sha384sums, sha512sums (arrays)*::
Alternative integrity checks that makepkg supports; these all behave
similar to the cksums option described above. To enable use and generation
similar to the md5sums option described above. To enable use and generation
of these checksums, be sure to set up the `INTEGRITY_CHECK` option in
linkman:makepkg.conf[5].
@ -163,8 +168,7 @@ contain whitespace characters.
*arch (array)*::
Defines on which architectures the given package is available (e.g.,
`arch=('i686' 'x86_64')`). Packages that contain no architecture specific
files should use `arch=('any')`. Valid characters for members of this array
are alphanumerics and ```_`''.
files should use `arch=('any')`.
*backup (array)*::
An array of file names, without preceding slashes, that
@ -180,6 +184,11 @@ contain whitespace characters.
than or equal to), `<=` (less than or equal to), `=` (equal to), `>`
(greater than), or `<` (less than).
+
If the dependency name appears to be a library (ends with .so), makepkg will
try to find a binary that depends on the library in the built package and
append the version needed by the binary. Appending the version yourself
disables automatic detection.
+
Additional architecture-specific depends can be added by appending an
underscore and the architecture name e.g., 'depends_x86_64=()'.
@ -204,9 +213,8 @@ underscore and the architecture name e.g., 'checkdepends_x86_64=()'.
An array of packages (and accompanying reasons) that are not essential for
base functionality, but may be necessary to make full use of the contents
of this package. optdepends are currently for informational purposes only
and are not utilized by pacman during dependency resolution. Packages in
this list follow the same format as depends, with an optional description
appended. The format for specifying optdepends descriptions is:
and are not utilized by pacman during dependency resolution. The format
for specifying optdepends is:
optdepends=('python: for library bindings')
+
@ -233,6 +241,10 @@ example, dcron can provide 'cron=2.0' to satisfy the 'cron>=2.0' dependency of
other packages. Provisions involving the `>` and `<` operators are invalid as
only specific versions of a package may be provided.
+
If the provision name appears to be a library (ends with .so), makepkg will
try to find the library in the built package and append the correct
version. Appending the version yourself disables automatic detection.
+
Additional architecture-specific provides can be added by appending an
underscore and the architecture name e.g., 'provides_x86_64=()'.
@ -281,24 +293,30 @@ underscore and the architecture name e.g., 'replaces_x86_64=()'.
*zipman*;;
Compress man and info pages with gzip.
*upx*;;
Compress binary executable files using UPX.
*optipng*;;
Optimize PNG images with optipng.
*ccache*;;
Allow the use of ccache during `build()`. More useful in its negative
Allow the use of ccache during build. More useful in its negative
form `!ccache` with select packages that have problems building
with ccache.
*distcc*;;
Allow the use of distcc during `build()`. More useful in its negative
Allow the use of distcc during build. More useful in its negative
form `!distcc` with select packages that have problems building
with distcc.
*buildflags*;;
Allow the use of user-specific buildflags (CPPFLAGS, CFLAGS, CXXFLAGS,
LDFLAGS) during `build()` as specified in linkman:makepkg.conf[5]. More
LDFLAGS) during build as specified in linkman:makepkg.conf[5]. More
useful in its negative form `!buildflags` with select packages that
have problems building with custom buildflags.
*makeflags*;;
Allow the use of user-specific makeflags during `build()` as specified
Allow the use of user-specific makeflags during build as specified
in linkman:makepkg.conf[5]. More useful in its negative form
`!makeflags` with select packages that have problems building with
custom makeflags such as `-j2` (or higher).
@ -309,19 +327,6 @@ underscore and the architecture name e.g., 'replaces_x86_64=()'.
When used in combination with the `strip' option, a separate package
containing the debug symbols is created.
*lto*;;
Enable building packages using link time optimization. Adds '-flto'
to both CFLAGS and CXXFLAGS.
*xdata (array)*::
This array allows you to add additional metadata to the package.
This data is neither used by pacman nor by makepkg;
It has purely informational purpose, or may be interpreted by third-party tools.
+
All entries in that array must have the form 'key=value', where
'key' is an arbitrary non-empty string and 'value' must not contain an equal sign.
Furthermore, the key ``pkgtype'' is reserved for the makepkg program.
Packaging Functions
-------------------
@ -331,27 +336,12 @@ PKGBUILD must contain a `package()` function which installs all the package's
files into the packaging directory, with optional `prepare()`, `build()`, and
`check()` functions being used to create those files from source.
This is directly sourced and executed by makepkg, so anything that Bash or the
system has available is available for use here. Be sure any exotic commands
used are covered by the `makedepends` array.
If you create any variables of your own in any of these functions, it is
recommended to use the Bash `local` keyword to scope the variable to inside the
function.
*package() Function*::
The `package()` function is used to install files into the directory that
will become the root directory of the built package and is run after all
the optional functions listed below. The packaging stage is run using
fakeroot to ensure correct file permissions in the resulting package.
All other functions will be run as the user calling makepkg.
This function is run inside `$srcdir`.
*verify() Function*::
An optional `verify()` function can be specified to implement arbitrary
source authentication. The function should return a non-zero exit code when
verification fails. This function is run before sources are extracted.
This function is run inside `$startdir`.
*prepare() Function*::
An optional `prepare()` function can be specified in which operations to
@ -359,19 +349,23 @@ function.
function is run after the source extraction and before the `build()`
function. The `prepare()` function is skipped when source extraction
is skipped.
This function is run inside `$srcdir`.
*build() Function*::
The optional `build()` function is used to compile and/or adjust the source
files in preparation to be installed by the `package()` function.
This function is run inside `$srcdir`.
The optional `build()` function is use to compile and/or adjust the source
files in preparation to be installed by the `package()` function. This is
directly sourced and executed by makepkg, so anything that Bash or the
system has available is available for use here. Be sure any exotic
commands used are covered by the `makedepends` array.
+
If you create any variables of your own in the `build()` function, it is
recommended to use the Bash `local` keyword to scope the variable to inside
the `build()` function.
*check() Function*::
An optional `check()` function can be specified in which a package's
test-suite may be run. This function is run between the `build()` and
`package()` functions. Be sure any exotic commands used are covered by the
`checkdepends` array.
This function is run inside `$srcdir`.
All of the above variables such as `$pkgname` and `$pkgver` are available for
use in the packaging functions. In addition, makepkg defines the following
@ -381,6 +375,7 @@ variables:
This contains the directory where makepkg extracts, or copies, all source
files.
+
All of the packaging functions defined above are run starting inside `$srcdir`
*pkgdir*::
This contains the directory where makepkg bundles the installed package.
@ -474,18 +469,13 @@ reference with all of the available functions defined.
Using VCS Sources[[VCS]]
------------------------
Building a developmental version of a package using sources from a version
control system (VCS) is enabled by specifying the source in the form:
control system (VCS) is enabled by specifying the source in the form
`source=('directory::url#fragment')`. Currently makepkg supports the Bazaar, Git,
Subversion, and Mercurial version control systems. For other version control
systems, manual cloning of upstream repositories must be done in the `prepare()`
function.
source=('directory::url#fragment?query')
Currently makepkg supports the Bazaar, Git, Subversion, Fossil and Mercurial
version control systems. For other version control systems, manual cloning of
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 three components:
*directory*::
(optional) Specifies an alternate directory name for makepkg to download
@ -501,16 +491,13 @@ The source URL is divided into four components:
*fragment*::
(optional) Allows specifying a revision number or branch for makepkg to checkout
from the VCS. A fragment has the form `type=value`, for example to checkout a
given revision the source line would be `source=(url#revision=123)`. The
available types depends on the VCS being used:
from the VCS. For example, to checkout a given revision, the source line would
have the format `source=(url#revision=123)`. The available fragments depends on
the VCS being used:
*bzr*;;
revision (see `'bzr help revisionspec'` for details)
*fossil*;;
branch, commit, tag
*git*;;
branch, commit, tag
@ -520,16 +507,12 @@ The source URL is divided into four components:
*svn*;;
revision
*query*::
(optional) Allows specifying whether a VCS checkout should be checked for
PGP-signed revisions. The source line should have the format
`source=(url#fragment?signed)` or `source=(url?signed#fragment)`. Currently
only supported by Git.
Example
-------
The following is an example PKGBUILD for the 'patch' package. For more
examples, look through the build files of your distribution's packages.
examples, look through the build files of your distribution's packages. For
those using Arch Linux, consult the Arch Build System (ABS) tree.
[source,sh]
-------------------------------
@ -541,4 +524,4 @@ See Also
--------
linkman:makepkg[8], linkman:pacman[8], linkman:makepkg.conf[5]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
alpm-hooks(5)
=============
@ -12,7 +15,7 @@ SYNOPSIS
--------
[Trigger] (Required, Repeatable)
Operation = Install|Upgrade|Remove (Required, Repeatable)
Type = Path|Package (Required)
Type = File|Package (Required)
Target = <Path|PkgName> (Required, Repeatable)
[Action] (Required)
@ -30,13 +33,9 @@ DESCRIPTION
libalpm provides the ability to specify hooks to run before or after
transactions based on the packages and/or files being modified. Hooks consist
of a single '[Action]' section describing the action to be run and one or more
'[Trigger]' section describing which transactions it should be run for.
Hooks are read from files located in the system hook directory
+{datarootdir}/libalpm/hooks+, and additional custom directories specified in
linkman:pacman.conf[5] (the default is +{sysconfdir}/pacman.d/hooks+). The
'[Trigger]' section describing which transactions it should be run for. Hook
file names are required to have the suffix ".hook". Hooks are run in
alphabetical order of their file name, where the ordering ignores the suffix.
alphabetical order of their file name.
TRIGGERS
--------
@ -49,20 +48,19 @@ defined the hook will run if the transaction matches *any* of the triggers.
Select the type of operation to match targets against. May be specified
multiple times. Installations are considered an upgrade if the package or
file is already present on the system regardless of whether the new package
version is actually greater than the currently installed version. For Path
version is actually greater than the currently installed version. For File
triggers, this is true even if the file changes ownership from one package
to another. Required.
*Type =* Path|Package::
*Type =* File|Package::
Select whether targets are matched against transaction packages or files.
See CAVEATS for special notes regarding Path triggers. 'File' is a deprecated
alias for 'Path' and will be removed in a future release. Required.
See CAVEATS for special notes regarding File triggers. Required.
*Target =* <path|package>::
The path or package name to match against the active transaction.
Paths refer to the files in the package archive; the installation root
The file path or package name to match against the active transaction.
File paths refer to the files in the package archive; the installation root
should *not* be included in the path. Shell-style glob patterns are
allowed. It is possible to invert matches by prepending a target with an
allowed. It is possible to invert matches by prepending a file with an
exclamation mark. May be specified multiple times. Required.
ACTIONS
@ -120,7 +118,7 @@ Exec = /usr/bin/sync
CAVEATS
-------
There are situations when path triggers may act in unexpected ways. Hooks are
There are situations when file triggers may act in unexpected ways. Hooks are
triggered using the file list of the installed, upgraded, or removed package.
When installing or upgrading a file that is extracted with a '.pacnew'
extension, the original file name is used in triggering the hook. When
@ -130,4 +128,4 @@ or not they were actually present on the file system before package removal.
PostTransaction hooks will *not* run if the transaction fails to complete for
any reason.
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,5 +1,5 @@
## linkman: macro
# Inspired by/borrowed from the Git source tree at Documentation/asciidoc.conf
# Inspired by/borrowed from the GIT source tree at Documentation/asciidoc.conf
#
# Usage: linkman:command[manpage-section]
#
@ -50,7 +50,7 @@ ifdef::backend-docbook[]
template::[header-declarations]
<refentry>
<refentryinfo>
<date>{localdate}</date>
<date>{pacman_date}</date>
</refentryinfo>
<refmeta>
<refentrytitle>{mantitle}</refentrytitle>

View file

@ -1,15 +1,16 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
See the pacman website at https://archlinux.org/pacman/[] for current
See the pacman website at https://www.archlinux.org/pacman/[] for current
information on pacman and its related tools.
Bugs
----
Bugs? You must be kidding; there are no bugs in this software. But if we
happen to be wrong, please report them to the issue tracker at
link:https://gitlab.archlinux.org/pacman/pacman/-/issues[] with specific
information such as your command-line, the nature of the bug, and even
the package database if it helps.
happen to be wrong, send us an email with as much detail as possible to
mailto:pacman-dev@archlinux.org[].
Authors
@ -19,18 +20,16 @@ Current maintainers:
* Allan McRae <allan@archlinux.org>
* Andrew Gregory <andrew.gregory.8@gmail.com>
* Morgan Adamiec <morganamilo@archlinux.org>
* Dan McGee <dan@archlinux.org>
* Dave Reisner <dreisner@archlinux.org>
Past major contributors:
* Judd Vinet <jvinet@zeroflux.org>
* Aurelien Foret <aurelien@archlinux.org>
* Aaron Griffin <aaron@archlinux.org>
* Dan McGee <dan@archlinux.org>
* Xavier Chantry <shiningxc@gmail.com>
* Nagy Gabor <ngaba@bibl.u-szeged.hu>
* Dave Reisner <dreisner@archlinux.org>
* Eli Schwartz <eschwartz@archlinux.org>
For additional contributors, use `git shortlog -s` on the pacman.git
repository.

View file

@ -34,8 +34,6 @@ makepkg/repo-add/pacman toolchain via GnuPG and GPGME.
Version 5.0 added support for pre/post-transaction hooks and sync database file
list operations.
Version 6.0 added support for parallel downloads.
Documentation
-------------
@ -45,27 +43,25 @@ There are several man pages available for the programs, utilities, and
configuration files dealing with pacman.
* linkman:alpm-hooks[5]
* linkman:BUILDINFO[5]
* linkman:PKGBUILD[5]
* linkman:libalpm[3]
* linkman:makepkg[8]
* linkman:makepkg-template[1]
* linkman:makepkg.conf[5]
* linkman:pacman[8]
* linkman:pacman-key[8]
* linkman:pacman-conf[8]
* linkman:pacman.conf[5]
* linkman:pkgdelta[8]
* linkman:repo-add[8]
* linkman:vercmp[8]
Changelog
~~~~~~~~~
For a good idea of what is going on in pacman development, take a look at the
link:https://gitlab.archlinux.org/pacman/pacman[Git summary page] for the
link:https://projects.archlinux.org/pacman.git/[Git summary page] for the
project.
See the most recent
link:https://gitlab.archlinux.org/pacman/pacman/-/blob/master/NEWS[NEWS]
link:https://projects.archlinux.org/pacman.git/tree/NEWS[NEWS]
file for a not-as-frequently-updated list of changes. However, this should
contain the biggest changes in a format more concise than the commit log.
@ -79,18 +75,7 @@ Releases
[frame="topbot",grid="none",options="header,autowidth"]
!======
!Version !Date
!7.0.0 !2024-07-14
!6.1.0 !2024-03-04
!6.0.1 !2021-09-04
!6.0.0 !2021-05-20
!6.0.0alpha1 !2020-12-04
!5.2.1 !2019-11-01
!5.2.0 !2019-10-21
!5.1.3 !2019-03-01
!5.1.2 !2018-12-25
!5.1.1 !2018-07-27
!5.1.0 !2018-05-28
!5.0.2 !2017-06-03
!5.0.2 !2016-06-03
!5.0.1 !2016-02-23
!5.0.0 !2016-01-30
!4.2.1 !2015-02-20
@ -113,11 +98,6 @@ Releases
!3.4.3 !2011-01-22
!3.4.2 !2010-12-29
!3.4.1 !2010-09-03
!======
|
[frame="topbot",grid="none",options="header,autowidth"]
!======
!Version !Date
!3.4.0 !2010-06-16
!3.3.3 !2009-11-10
!3.3.2 !2009-10-05
@ -127,6 +107,11 @@ Releases
!3.2.1 !2008-08-26
!3.2.0 !2008-07-30
!3.1.4 !2008-04-01
!======
|
[frame="topbot",grid="none",options="header,autowidth"]
!======
!Version !Date
!3.1.3 !2008-03-06
!3.1.2 !2008-02-20
!3.1.1 !2008-01-20
@ -152,16 +137,16 @@ Releases
!2.9 !2004-09-18
!2.8.4 !2004-08-23
!2.8.3 !2004-08-04
!======
|
[frame="topbot",grid="none",options="header,autowidth"]
!======
!Version !Date
!2.8.2 !2004-07-22
!2.8.1 !2004-07-17
!2.8 !2004-07-03
!2.7.9 !2004-04-30
!2.7.8 !2004-04-29
!======
|
[frame="topbot",grid="none",options="header,autowidth"]
!======
!Version !Date
!2.7.7 !2004-04-15
!2.7.6 !2004-04-04
!2.7.5 !2004-03-02
@ -195,18 +180,16 @@ Releases
|======
Source code for releases since moving to gitlab is available at
link:https://gitlab.archlinux.org/pacman/pacman/-/releases[].
Source code for historical releases is available at
Source code for all releases is available at
link:https://sources.archlinux.org/other/pacman/[]. To install, download the newest
available source tarball, unpack it in a directory, and run the three magic
commands:
$ meson build
$ ninja -C build
# ninja -C build install
$ ./configure
$ make
# make install
You may wish to read the options presented by `meson` in order to
You may wish to read the options presented by `./configure --help` in order to
set appropriate paths and build options that are correct for your system.
Development
@ -215,8 +198,8 @@ Development
Mailing List
~~~~~~~~~~~~
There is a mailing list devoted to pacman development, hosted by Arch Linux.
link:https://lists.archlinux.org/listinfo/pacman-dev/[Subscribe] or
link:https://lists.archlinux.org/pipermail/pacman-dev/[view the archives].
link:https://mailman.archlinux.org/mailman/listinfo/pacman-dev/[Subscribe] or
link:https://mailman.archlinux.org/pipermail/pacman-dev/[view the archives].
Source Code
~~~~~~~~~~~
@ -227,11 +210,12 @@ these trees).
The current development tree can be fetched with the following command:
git clone https://gitlab.archlinux.org/pacman/pacman.git
git clone git://projects.archlinux.org/pacman.git pacman
which will fetch the full development history into a directory named pacman.
You can browse the source as well using
link:https://gitlab.archlinux.org/pacman/pacman/[gitlab].
link:https://projects.archlinux.org/pacman.git/[cgit]. HTTP/HTTPS URLs are also
available for cloning purposes; these URLs are listed at the above page.
If you are interested in hacking on pacman, it is highly recommended you join
the mailing list mentioned above, as well as take a quick glance at our
@ -243,16 +227,40 @@ you speak a foreign language, you can help by either creating or updating a
translation file for your native language. Instructions can be found in
link:translation-help.html[translation-help].
Other Utilities
~~~~~~~~~~~~~~~
Although the package manager itself is quite simple, many scripts have been
developed that help automate building and installing packages. These are used
extensively in link:https://www.archlinux.org/[Arch Linux]. Most of these utilities
are available in the Arch Linux projects
link:https://projects.archlinux.org/[code browser].
Utilities available:
* link:https://projects.archlinux.org/abs.git/[abs] - ABS (Arch Build System), scripts to download & use the Arch Linux PKGBUILD tree
* link:https://projects.archlinux.org/dbscripts.git/[dbscripts] - scripts used by Arch Linux to manage the main package repositories
* link:https://projects.archlinux.org/devtools.git/[devtools] - tools to assist in packaging and dependency checking
* link:https://projects.archlinux.org/namcap.git/[namcap] - a package analysis utility written in python
* link:https://projects.archlinux.org/srcpac.git/[srcpac] - a bash build-from-source pacman wrapper
Bugs
----
If you find bugs (which is quite likely), please report them to the issue
tracker at link:https://gitlab.archlinux.org/pacman/pacman/-/issues[] with
specific information such as your command-line, the nature of the bug, and even
the package database if it helps.
If you find bugs (which is quite likely), please email them to the pacman-dev
mailing last at mailto:pacman-dev@archlinux.org[] with specific information
such as your command-line, the nature of the bug, and even the package database
if it helps.
You can also post a bug to the Arch Linux bug tracker
link:https://bugs.archlinux.org/index.php?project=3[Flyspray]. Be sure to file
bugs under the Pacman project.
Copyright
---------
pacman is Copyright (C) 2006-2025 Pacman Development Team
<pacman-dev@lists.archlinux.org> and Copyright (C) 2002-2006 Judd Vinet
pacman is Copyright (C) 2006-2016 Pacman Development Team
<pacman-dev@archlinux.org> and Copyright (C) 2002-2006 Judd Vinet
<jvinet@zeroflux.org> and is licensed through the GNU General Public License,
version 2 or later.
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

40
doc/libalpm.3.txt Normal file
View file

@ -0,0 +1,40 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
libalpm(3)
==========
Name
----
libalpm - Arch Linux Package Management (ALPM) library
Synopsis
--------
For ease of access, the libalpm manual has been split up into several sections.
*TODO:* Yes, this man page needs a lot of work. Once we get around to doing
good Doxygen documentation, it will improve. We promise.
*alpm_databases*:: Database Functions
*alpm_interface*:: Interface Functions
*alpm_list*:: List Functions
*alpm_log*:: Logging Functions
*alpm_misc*:: Miscellaneous Functions
*alpm_packages*:: Package Functions
*alpm_sync*:: Sync Functions
*alpm_trans*:: Transaction Functions
Configuration
-------------
See linkman:pacman.conf[5] for more details on configuring libalpm using the
'pacman.conf' file.
See Also
--------
linkman:alpm-hooks[5], linkman:makepkg[8], linkman:pacman[8],
linkman:pacman.conf[5]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
makepkg-template(1)
===================
@ -85,7 +88,7 @@ Example PKGBUILD
license=('PerlArtistic' 'GPL')
depends=('perl')
source=("http://search.cpan.org/CPAN/authors/id/S/SH/SHERZODR/Config-Simple-${pkgver}.tar.gz")
sha256sums=('dd9995706f0f9384a15ccffe116c3b6e22f42ba2e58d8f24ed03c4a0e386edb4')
md5sums=('f014aec54f0a1e2e880d317180fce502')
_distname="Config-Simple"
# template start; name=perl-module; version=1.0;
@ -115,4 +118,4 @@ See Also
--------
linkman:makepkg[8], linkman:PKGBUILD[5]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
makepkg(8)
==========
@ -75,7 +78,7 @@ Options
For each source file in the source array of PKGBUILD, download the file
if required and generate integrity checks. The integrity checks generated
are determined by the checks present in the PKGBUILD, falling back to the
value of the INTEGRITY_CHECK array in makepkg.conf(5) if these are absent.
value of the INTEGRITY_CHECK array in makepkg.conf(5) if these are absent
This output can be redirected into your PKGBUILD for source validation
using "`makepkg -g >> PKGBUILD`".
@ -144,12 +147,8 @@ Options
Display version information.
*-C, \--cleanbuild*::
Clean build artifacts from previous runs of makepkg in the current
directory by removing $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*::
Do not actually build the package, but build a source-only tarball that
includes all sources, including those that are normally downloaded via
@ -172,9 +171,6 @@ Options
*\--noprepare*::
Do not run the prepare() function in the PKGBUILD.
*\--noverify*::
Do not run the verify() function in the PKGBUILD.
*\--sign*::
Sign the resulting package with gpg, overriding the setting in
linkman:makepkg.conf[5].
@ -204,13 +200,12 @@ Options
useful if you are redirecting makepkg output to file.
*\--packagelist*::
List the package filenames that would be produced without building. Listed
package filenames include PKGDEST and PKGEXT.
List the packages that would be produced without building. Listed
package names do not include PKGEXT.
*\--printsrcinfo*::
Generate and print the SRCINFO file to stdout.
Additional Features
-------------------
makepkg supports building development versions of packages without having to
@ -219,24 +214,8 @@ separate utility 'versionpkg'. See linkman:PKGBUILD[5] for details on how to
set up a development PKGBUILD.
Reproducibility
---------------
makepkg is designed to be compatible with
link:https://reproducible-builds.org/docs/[Reproducible Builds]. If the
**SOURCE_DATE_EPOCH** environment variable is set, it will be exported to
subprocesses, and source and package file modification times and package
metadata will be unified based on the timestamp specified.
If the **SOURCE_DATE_EPOCH** environment variable is not set, makepkg will use
its own start date for internal use, but will not unify source file timestamps
before building.
Environment Variables
---------------------
**MAKEPKG_LIBRARY**="/path/to/directory"::
Use an alternative libmakepkg path instead of the {libmakepkgdir} default.
**PACMAN**::
The command that will be used to check for missing dependencies and to
install and remove packages. Pacman's '-Qq', '-Rns', '-S', '-T', and '-U'
@ -247,11 +226,6 @@ Environment Variables
Use an alternate config file instead of the +{sysconfdir}/makepkg.conf+
default.
**MAKEPKG_GIT_CONFIG=**"/path/to/file"::
Use an alternate config file for Git instead of the
+{sysconfdir}/makepkg.d/gitconfig+ default. makepkg always prevents Git
from loading any other config files.
**PKGDEST=**"/path/to/directory"::
Directory where the resulting packages will be stored. Overrides the
corresponding value defined in linkman:makepkg.conf[5].
@ -289,23 +263,7 @@ Environment Variables
**GPGKEY=**"keyid"::
Specify a key to use when signing packages, overriding the GPGKEY setting
in linkman:makepkg.conf[5].
**SOURCE_DATE_EPOCH=**"<date>"::
Used for link:https://reproducible-builds.org/docs/[Reproducible Builds].
**BUILDTOOL=**"<name>"::
The name of a tool ecosystem used to set up the build environment. Used for
defining a spec for reproducible builds, e.g. the linkman:makepkg.conf[5]
used.
**BUILDTOOLVER=**"<version>"::
The version of the '$BUILDTOOL' used.
**MAKEPKG_LINT_PKGBUILD=**0::
Setting to 0 disables PKGBUILD linting within makepkg. Useful on systems
with slow bash subshell operations, or on PKGBUILDs with extreme amounts of
package splitting.
in linkman:makepkg.conf[5]
Configuration
@ -314,69 +272,8 @@ See linkman:makepkg.conf[5] for more details on configuring makepkg using the
'makepkg.conf' file.
Errors
------
On exit, makepkg will return one of the following error codes.
0::
Normal exit condition.
1::
Unknown cause of failure.
2::
Error in configuration file.
3::
User specified an invalid option.
4::
Error in user-supplied function in PKGBUILD.
5::
Failed to create a viable package.
6::
A source or auxiliary file specified in the PKGBUILD is
missing.
7::
The PKGDIR is missing.
8::
Failed to install dependencies.
9::
Failed to remove dependencies.
10::
User attempted to run makepkg as root.
11::
User lacks permissions to build or install to a given
location.
12::
Error parsing PKGBUILD.
13::
A package has already been built.
14::
The package failed to install.
15::
Programs necessary to run makepkg are missing.
16::
Specified GPG key does not exist or failed to sign package.
17::
The local repository is not a clone of the source repository
specified in PKGBUILD.
See Also
--------
linkman:makepkg.conf[5], linkman:PKGBUILD[5], linkman:pacman[8]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
makepkg.conf(5)
===============
@ -23,9 +26,6 @@ NOTE: This does not guarantee that all package Makefiles will use your exported
variables. Some of them are non-standard.
The system-wide configuration file is found in {sysconfdir}/makepkg.conf.
Specific additions (e.g. build flags for additional languages) can be placed
in {sysconfdir}/makepkg.conf.d/*.conf.
Individual options can be overridden (or added to) on a per-user basis in
$XDG_CONFIG_HOME/pacman/makepkg.conf or ~/.makepkg.conf, with the former
taking priority.
@ -62,11 +62,6 @@ Options
A string such as ``i686-pc-linux-gnu''; do not touch this unless you know what
you are doing. This can be commented out by most users if desired.
**NPROC=**""::
Sets the number of processors to use for parallel jobs in makepkg.
Note: this does not affect parallelization of tasks during ``build()`` and
related functions.
**CPPFLAGS=**"cppflags"::
Flags used for the C preprocessor; see CFLAGS for more information.
@ -85,11 +80,6 @@ Options
usage resembling ``-Wl,--hash-style=gnu''. Read ld(1) for more details on
available linker flags.
**LTOFLAGS=**"ltoflags"::
Additional compiler and linker flags appended to `CFLAGS`, `CXXFLAGS`
and `LDFLAGS` when building with link time optimization. If empty,
``-flto'' is used.
**MAKEFLAGS=**"makeflags"::
This is often used to set the number of jobs used; for example, `-j2`.
Other flags that make accepts can also be passed.
@ -102,7 +92,7 @@ Options
**DEBUG_CXXFLAGS=**"debug_cxxflags"::
Debug flags used for the C++ compiler; see DEBUG_CFLAGS for more info.
**BUILDENV=(**!distcc !color !ccache check !sign**)**::
**BUILDENV=(**!distcc color !ccache check !sign**)**::
This array contains options that affect the build environment; the defaults
are shown here. All options should always be left in the array; to enable
or disable an option, simply remove or add an ``!'' at the front of the
@ -130,7 +120,7 @@ Options
*sign*;;
Generate a PGP signature file using GnuPG. This will execute 'gpg
\--detach-sign' on the built package to generate a detached
\--detach-sign \--use-agent' on the built package to generate a detached
signature file, using the GPG agent, if it is available. The signature
file will be the entire file name of the package with a ``.sig''
extension.
@ -151,7 +141,7 @@ Options
Specify a key to use for GPG signing instead of the default key in the
keyring. Can be overridden with makepkg's '\--key' option.
**OPTIONS=(**!strip docs libtool staticlibs emptydirs ...**)**::
**OPTIONS=(**strip docs libtool staticlibs emptydirs zipman purge !upx !optipng**)**::
This array contains options that affect default packaging. They are
equivalent to options that can be placed in the PKGBUILD; the defaults are
shown here. All options should always be left in the array; to enable or
@ -188,33 +178,31 @@ Options
Remove files specified by the `PURGE_TARGETS` variable from the
package.
*upx*;;
Compress binary executable files using UPX. Additional options
can be passed to UPX by specifying the `UPXFLAGS` array variable.
*optipng*;;
Optimize PNG images with optipng. Additional options can be passed
to optipng by specifying the `OPTIPNGFLAGS` array variable.
*debug*;;
Add the user-specified debug flags as specified in DEBUG_CFLAGS and
DEBUG_CXXFLAGS to their counterpart buildflags. Creates a separate
package containing the debug symbols when used with `strip'.
*lto*;;
Enable building packages using link time optimization. Adds the
flags specified in LTOFLAGS to CFLAGS, CXXFLAGS and LDFLAGS (or
``-flto'' if LTOFLAGS is empty).
*autodeps*;;
Enable the automatic addition of libraries to the depends and
provides arrays. Search library directories are controlled by
the LIB_DIRS variable defined below.
**INTEGRITY_CHECK=(**check1 ...**)**::
File integrity checks to use. Multiple checks may be specified; this
affects both generation and checking. The current valid options are:
`ck`, `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`, and `b2`.
`md5`, `sha1`, `sha256`, `sha384`, and `sha512`.
**STRIP_BINARIES=**"--strip-all"::
Options to be used when stripping binaries. See linkman:strip[1]
for details.
**STRIP_SHARED=**"--strip-unneeded"::
Options to be used when stripping shared libraries or PIE executables.
See linkman:strip[1] for details.
Options to be used when stripping shared libraries. See linkman:strip[1]
for details.
**STRIP_STATIC=**"--strip-debug"::
Options to be used when stripping static libraries. See linkman:strip[1]
@ -233,23 +221,11 @@ Options
that are located in opt/, you may need to add the directory to this
array. *NOTE:* Do not add the leading slash to the directory name.
**LIB_DIRS=(**lib:usr/lib ...**)**::
If `autodeps` is specified in the `OPTIONS` array, this variable will
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
libraries found in "path" with the specified prefix added.
**PURGE_TARGETS=(**usr/{,share}/info/dir .podlist *.pod...**)**::
If `purge` is specified in the `OPTIONS` array, this variable will
instruct makepkg which files to remove from the package. This is
useful for index files that are added by multiple packages.
**DBGSRCDIR=**"/usr/src/debug"::
If `strip` and `debug` are specified in the `OPTIONS` array, this variable
will instruct makepkg where to place source files for installed binaries.
The binaries will be modified to link this directory for the debugger
search path.
**PKGDEST=**"/path/to/directory"::
If this value is not set, packages will, by default, be placed in the
current directory (location of the linkman:PKGBUILD[5]). Many people
@ -273,40 +249,26 @@ Options
**PACKAGER=**"John Doe <john@example.com>"::
This value is used when querying a package to see who was the builder.
The given format is required for PGP key lookup through WKD.
It is recommended to change this to your name and email address.
**COMPRESSGZ=**"(gzip -c -f -n)"::
**COMPRESSBZ2=**"(bzip2 -c -f)"::
**COMPRESSXZ=**"(xz -c -z -)"::
**COMPRESSZST=**"(zstd -c -z -)"::
**COMPRESSLZO**"(lzop -q)"::
**COMPRESSLRZ=**"(lrzip -q)"::
**COMPRESSLZ4=**"(lz4 -q)"::
**COMPRESSZ=**"(compress -c -f)"::
**COMPRESSLZ=**"(lzip -c -f)"::
Sets the command and options used when compressing compiled or source
packages in the named format.
**PKGEXT=**"{pkgext}", **SRCEXT=**"{srcext}"::
**PKGEXT=**".pkg.tar.gz", **SRCEXT=**".src.tar.gz"::
Sets the compression used when making compiled or source packages.
Valid suffixes are `.pkg` or `.src` (for PKGEXT and SRCEXT respectively)
followed by one of `.tar.gz`, `.tar.bz2`, `.tar.xz`, `.tar.zst`, `.tar.lzo`,
`.tar.lrz`, `.tar.lz4`, `.tar.lz` and `.tar.Z`, or simply `.tar` to
disable compression entirely.
**PACMAN_AUTH=()**::
Specify a command prefix for running pacman as root. If unset, makepkg will
check for the presence of sudo(8) and su(1) in turn, and try the first one
it finds.
+
If present, `%c` will be replaced with the shell-quoted form of the command
to run. Otherwise, the command to run is appended to the auth command.
Valid suffixes are `.tar`, `.tar.gz`, `.tar.bz2`, `.tar.xz`,
`.tar.lzo`, `.tar.lrz`, and `.tar.Z`.
Do not touch these unless you know what you are doing.
See Also
--------
linkman:makepkg[8], linkman:pacman[8], linkman:PKGBUILD[5]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,157 +0,0 @@
manpages = [
{ 'name': 'alpm-hooks.5' },
{ 'name': 'pacman.8' },
{ 'name': 'makepkg.8' },
{ 'name': 'makepkg-template.1' },
{ 'name': 'repo-add.8' },
{ 'name': 'vercmp.8' },
{ 'name': 'testpkg.8' },
{ 'name': 'pacman-key.8' },
{ 'name': 'pacman-db-upgrade.8' },
{ 'name': 'PKGBUILD.5', 'extra_depends' : [ 'PKGBUILD-example.txt' ] },
{ 'name': 'makepkg.conf.5' },
{ 'name': 'pacman.conf.5' },
{ 'name': 'BUILDINFO.5' },
{ 'name': 'pacman-conf.8' },
]
sitepages = [
{ 'name': 'submitting-patches' },
{ 'name': 'translation-help' },
{ 'name': 'HACKING', 'source': '../HACKING' },
{ 'name': 'index' },
]
asciidoc_conf = join_paths(meson.current_source_dir(), 'asciidoc.conf')
asciidoc_opts = [
'-f', asciidoc_conf,
'-a', 'pacman_version="@0@"'.format(PACKAGE_VERSION),
'-a', 'srcext=@0@'.format(get_option('src-ext')),
'-a', 'pkgext=@0@'.format(get_option('pkg-ext')),
'-a', 'pkgdatadir=@0@'.format(PKGDATADIR),
'-a', 'keyringdir=@0@'.format(KEYRINGDIR),
'-a', 'localstatedir=@0@'.format(LOCALSTATEDIR),
'-a', 'sysconfdir=@0@'.format(SYSCONFDIR),
'-a', 'datarootdir=@0@'.format(DATAROOTDIR),
'-a', 'rootdir=@0@'.format(ROOTDIR),
'-a', 'libmakepkgdir=@0@'.format(LIBMAKEPKGDIR),
]
html_targets = []
html_files = []
foreach page : manpages
manpage = page['name']
htmlpage = '@0@.html'.format(manpage)
input = '@0@.asciidoc'.format(manpage)
section = page['name'].split('.')[-1]
mandirn = join_paths(MANDIR, 'man' + section)
custom_target(
manpage,
command : [
A2X,
'--no-xmllint',
'-d', 'manpage',
'-f', 'manpage',
'--xsltproc-opts', '-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0',
'-D', '@OUTDIR@',
'--asciidoc-opts', ' '.join(asciidoc_opts),
'@INPUT@',
],
input : input,
output : [manpage],
depend_files : [
asciidoc_conf,
] + page.get('extra_depends', []),
install : true,
install_dir : mandirn,
)
endforeach
foreach page: manpages + sitepages
manpage = page['name']
htmlpage = '@0@.html'.format(manpage)
input = page.get('source', '@0@.asciidoc'.format(manpage))
html = custom_target(
htmlpage,
command : [
ASCIIDOC,
] + asciidoc_opts + [
'-a', 'linkcss',
'-a', 'toc',
'-a', 'icons',
'-a', 'max-width=960px',
'-a', 'stylesheet=asciidoc-override.css',
'-o', '@OUTPUT@',
'@INPUT@',
],
input : input,
output : [htmlpage],
depend_files : [
asciidoc_conf,
'asciidoc-override.css',
] + page.get('extra_depends', []),
build_by_default : false,
install : false,
)
html_targets += [html]
html_files += [htmlpage]
endforeach
run_target('html',
command : ['/bin/true'],
depends : html_targets)
custom_target(
'website.tar.gz',
command : [
'bsdtar', 'czf', '@OUTPUT@',
'-C', meson.current_build_dir(),
] + html_files + [
'-C', meson.current_source_dir(),
'asciidoc-override.css',
'-C', '/etc/asciidoc/stylesheets/',
'asciidoc.css',
'-C', '/etc/asciidoc/javascripts/',
'asciidoc.js',
'-C', '/etc/asciidoc/',
'images',
],
output : ['website.tar.gz'],
build_by_default : false,
depends : html_targets,
)
meson.add_install_script(MESON_MAKE_SYMLINK,
'repo-add.8',
join_paths(MANDIR, 'man8/repo-remove.8'))
meson.add_install_script(MESON_MAKE_SYMLINK,
'alpm-hooks.5',
join_paths(MANDIR, 'man5/pacman-hooks.5'))
doxygen = find_program('doxygen', required : get_option('doxygen'))
if doxygen.found() and not get_option('doxygen').disabled()
doxyconf = configuration_data()
doxyconf.set('INPUT_DIRECTORY', meson.current_source_dir())
doxyconf.set('OUTPUT_DIRECTORY', meson.current_build_dir())
doxyfile = configure_file(
input : 'Doxyfile.in',
output : 'Doxyfile',
configuration : doxyconf,
install : false)
custom_target(
'doxygen',
input : doxyfile,
output : ['man3'],
command : [doxygen, doxyfile],
build_by_default : true,
install : true,
install_dir : MANDIR)
endif

View file

@ -1,67 +0,0 @@
pacman-conf(8)
==============
Name
----
pacman-conf - query pacman's configuration file
Synopsis
--------
'pacman-conf' [options] [<directive> ...]
'pacman-conf' (--repo-list|--help|--version)
Description
-----------
'pacman-conf' is a utility for parsing the 'pacman' configuration file
and returning script-friendly output. It is designed to properly handle
non-trivial configuration features such as variable interpolation and
the use of the Include directive, and guarantees that it will return the
same configuration values which 'pacman' itself would use.
'pacman-conf' will output the fully-resolved contents of the
configuration file by default, or, if provided with the name of a
configuration directive, output the contents of the given directive alone.
Options
-------
*-c, \--config* <path>::
Specify an alternate configuration file.
*-R, \--rootdir* <path>::
Specify an alternate installation root (default is `/`).
*-r, \--repo* <repository>::
Query options for a specific repository.
*-v, \--verbose*::
Always shown directive names.
*-l, \--repo-list*::
List configured repositories.
*-h, \--help*::
Output syntax and command line options.
*-V, \--version*::
Display version and exit.
Examples
--------
pacman-conf -r core Usage::
Show the value of the Usage configuration option for core repository.
pacman-conf HoldPkg::
Show the value of the HoldPkg configuration option.
See Also
--------
linkman:pacman.conf[5]
include::footer.asciidoc[]

View file

@ -1,36 +0,0 @@
pacman-db-upgrade(8)
====================
Name
----
pacman-db-upgrade - upgrade the local pacman database to a newer format
Synopsis
--------
'pacman-db-upgrade' [options]
Description
-----------
'pacman-db-upgrade' is a script that upgrades the local database used
by linkman:pacman[8] to a newer format.
Options
--------------
*-h, \--help*::
Show the built-in help message and exit.
*-V, \--version*::
Show version information and exit.
*-d, \--dbpath* <path>::
Set an alternate database location.
*-r, \--root* <path>::
Set an alternate installation root.
*\--config* <path>::
Set an alternate configuration file.
*\--nocolor*::
Remove color from output.
See Also
--------
linkman:pacman[8]
include::footer.asciidoc[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pacman-key(8)
=============
@ -86,7 +89,7 @@ Operations
*\--populate*::
Reload the default keys from the (optionally provided) keyrings in
+{keyringdir}+. For more information, see
+{pkgdatadir}/keyrings+. For more information, see
<<PK,Providing a Keyring for Import>> below.
*-u, \--updatedb*::
@ -97,13 +100,7 @@ Operations
Displays the program version.
*-v, \--verify*::
Assume that the first argument is a signature and verify it. If a second
argument is provided, it is the file to be verified.
+
With only one argument given, assume that the signature is a detached
signature, and look for a matching data file to verify by stripping the file
extension. If no matching data file is found, fall back on GnuPG semantics and
attempt to verify a file with an embedded signature.
Verify the file(s) specified by the signature(s).
Options
@ -129,7 +126,7 @@ A distribution or other repository provided may want to provide a set of
PGP keys used in the signing of its packages and repository databases that can
be readily imported into the pacman keyring. This is achieved by providing a
PGP keyring file `foo.gpg` that contains the keys for the foo keyring in the
directory +{keyringdir}+.
directory +{pkgdatadir}/keyrings+.
Optionally, the file `foo-trusted` can be provided containing a list of trusted
key IDs for that keyring. This is a file in a format compatible with 'gpg
@ -148,4 +145,4 @@ See Also
--------
linkman:pacman[8], linkman:pacman.conf[5]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pacman(8)
=========
@ -124,35 +127,33 @@ greater than `1:3.6-1`.
Options
-------
*-b, \--dbpath* <path>::
Specify an alternative database location (the default is
Specify an alternative database location (a typical default is
+{localstatedir}/lib/pacman+). This should not be used unless you know what
you are doing.
*NOTE*: If specified, this is an absolute path, and the root path is
not automatically prepended.
*-r, \--root* <path>::
Specify an alternative installation root (default is +{rootdir}+). This should
Specify an alternative installation root (default is `/`). This should
not be used as a way to install software into `/usr/local` instead of
`/usr`.
`/usr`. This option is used if you want to install a package on a
temporarily mounted partition that is "owned" by another system.
*NOTE*: If database path or log file are not specified on either the
command line or in linkman:pacman.conf[5], their default location will
be inside this root path.
*NOTE*: This option is not suitable for performing operations on a mounted
guest system. See '\--sysroot' instead.
*-v, \--verbose*::
Output paths such as the Root, Conf File, DB Path, Cache Dirs, etc.
Output paths such as as the Root, Conf File, DB Path, Cache Dirs, etc.
*\--arch* <arch>::
Specify an alternate architecture.
*\--cachedir* <dir>::
Specify an alternative package cache location (the default is
Specify an alternative package cache location (a typical default is
+{localstatedir}/cache/pacman/pkg+). Multiple cache directories can be
specified, and they are tried in the order they are passed to pacman.
*NOTE*: This is an absolute path, and the root path is not automatically
prepended. If DownloadUser is set in linkman:pacman.conf[5], then the
specified user must have permission to access the cache directory.
prepended.
*\--color* <when>::
Specify when to enable coloring. Valid options are 'always', 'never', or
@ -167,15 +168,15 @@ Options
to be used.
*\--gpgdir* <dir>::
Specify a directory of files used by GnuPG to verify package signatures
(the default is +{sysconfdir}/pacman.d/gnupg+). This directory should contain
Specify a directory of files used by GnuPG to verify package signatures (a
typical default is +{sysconfdir}/pacman.d/gnupg+). This directory should contain
two files: `pubring.gpg` and `trustdb.gpg`. `pubring.gpg` holds the public keys
of all packagers. `trustdb.gpg` contains a so-called trust database, which
specifies that the keys are authentic and trusted. *NOTE*: This is an absolute
path, and the root path is not automatically prepended.
*\--hookdir* <dir>::
Specify a alternative directory containing hook files (the default is
Specify a alternative directory containing hook files (a typical default is
+{sysconfdir}/pacman.d/hooks+). Multiple hook directories can be specified
with hooks in later directories taking precedence over hooks in earlier
directories. *NOTE*: This is an absolute path, and the root path is not
@ -192,19 +193,6 @@ Options
*\--confirm*::
Cancels the effects of a previous '\--noconfirm'.
*\--disable-download-timeout*::
Disable defaults for low speed limit and timeout on downloads. Use this
if you have issues downloading files with proxy and/or security gateway.
*\--sysroot* <dir>:: Specify an alternative system root. This path will be
prepended to all other configuration directories and any repository servers
beginning with `file://`. Any paths or URLs passed as targets will not be
modified. This allows mounted guest systems to be properly operated on.
*\--disable-sandbox*::
Disable the default sandbox applied to the process downloading files on Linux
systems. Useful if experiencing landlock related failures while downloading
files when running a Linux kernel that does not support this feature.
Transaction Options (apply to '-S', '-R' and '-U')
--------------------------------------------------
@ -216,7 +204,7 @@ Transaction Options (apply to '-S', '-R' and '-U')
*\--assume-installed* <package=version>::
Add a virtual package "package" with version "version" to the transaction
to satisfy dependencies. This allows disabling the specific dependency checks
to satisfy dependencies. This allows to disable specific dependency checks
without affecting all dependency checks. To disable all dependency
checking, see the '\--nodeps' option.
@ -239,21 +227,19 @@ Transaction Options (apply to '-S', '-R' and '-U')
*\--print-format* <format>::
Specify a printf-like format to control the output of the '\--print'
operation. The possible attributes are: "%a" for arch, "%b" for
builddate, "%d" for description, "%e" for pkgbase, "%f" for filename,
"%g" for base64 encoded PGP signature, "%h" for sha256sum, "%m" for
md5sum, "%n" for pkgname, "%p" for packager, "%v" for pkgver, "%l" for
location, "%r" for repository, "%s" for size, "%C" for checkdepends,
"%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'.
operation. The possible attributes are: "%n" for pkgname, "%v" for pkgver,
"%l" for location, "%r" for repository, and "%s" for size. Implies '\--print'.
Upgrade Options (apply to '-S' and '-U')[[UO]]
----------------------------------------------
*-w, \--downloadonly*::
Retrieve all packages from the server, but do not install/upgrade anything.
--------------------------------------------
*\--force*::
Bypass file conflict checks and overwrite conflicting files. If the
package that is about to be installed contains files that are already
installed, this option will cause all those files to be overwritten.
Using '\--force' will not allow overwriting a directory with a file or
installing packages with conflicting files and directories.
This option should be used with care, ideally not at all.
*\--asdeps*::
Install packages non-explicitly; in other words, fake their install reason
@ -280,21 +266,9 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
*\--needed*::
Do not reinstall the targets that are already up-to-date.
*\--overwrite* <glob>::
Bypass file conflict checks and overwrite conflicting files. If the
package that is about to be installed contains files that are already
installed and match 'glob', this option will cause all those files to be
overwritten. Using '\--overwrite' will not allow overwriting a directory
with a file or installing packages with conflicting files and directories.
Multiple patterns can be specified by separating them with a comma. May be
specified multiple times. Patterns can be negated, such that files
matching them will not be overwritten, by prefixing them with an
exclamation mark. Subsequent matches will override previous ones. A leading
literal exclamation mark or backslash needs to be escaped.
Query Options (apply to '-Q')[[QO]]
-----------------------------------
Query Options[[QO]]
-------------------
*-c, \--changelog*::
View the ChangeLog of a package if it exists.
@ -319,7 +293,7 @@ Query Options (apply to '-Q')[[QO]]
'\--info' or '-i' flags will also display the list of backup files and
their modification states.
*-k, \--check*::
*-k \--check*::
Check that all files owned by the given package(s) are present on the
system. If packages are not specified or filter flags are not provided,
check all installed packages. Specifying this option twice will perform
@ -364,10 +338,10 @@ Query Options (apply to '-Q')[[QO]]
with descriptions matching ALL of those terms are returned.
*-t, \--unrequired*::
Restrict or filter output to print only packages neither required nor
optionally required by any currently installed package. Specify this
option twice to include packages which are optionally, but not directly,
required by another package.
Restrict or filter output to packages not required or optionally required by
any currently installed package. Specify this option twice to only filter
packages that are direct dependencies (i.e. do not filter optional
dependencies).
*-u, \--upgrades*::
Restrict or filter output to packages that are out-of-date on the local
@ -376,8 +350,8 @@ Query Options (apply to '-Q')[[QO]]
database is refreshed using '-Sy'.
Remove Options (apply to '-R')[[RO]]
------------------------------------
Remove Options[[RO]]
--------------------
*-c, \--cascade*::
Remove all target packages, as well as all packages that depend on one
or more target packages. This operation is recursive and must be used
@ -401,8 +375,8 @@ Remove Options (apply to '-R')[[RO]]
to avoid breaking any dependencies.
Sync Options (apply to '-S')[[SO]]
----------------------------------
Sync Options[[SO]]
------------------
*-c, \--clean*::
Remove packages that are no longer installed from the cache as well as
currently unused sync databases to free up disk space. When pacman
@ -459,27 +433,30 @@ can be useful when the user switches from a testing repository to a stable one.
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.
*-w, \--downloadonly*::
Retrieve all packages from the server, but do not install/upgrade anything.
*-y, \--refresh*::
Download a fresh copy of the master package databases '(repo.db)' from the
server(s) defined in linkman:pacman.conf[5]. This should typically be used
each time you use '\--sysupgrade' or '-u'. Passing two '\--refresh' or '-y'
flags will force a refresh of all package databases, even if they appear to
be up-to-date.
Download a fresh copy of the master package database from the server(s)
defined in linkman:pacman.conf[5]. This should typically be used each time
you use '\--sysupgrade' or '-u'. Passing two '\--refresh' or '-y' flags
will force a refresh of all package databases, even if they appear to be
up-to-date.
Database Options (apply to '-D')[[QO]]
--------------------------------------
Database Options[[QO]]
----------------------
*\--asdeps* <package>::
Mark a package as non-explicitly installed; in other words, set their install
reason to be installed as a dependency.
*\--asexplicit* <package>::
Mark a package as explicitly installed; in other words, set their install
reason to be explicitly installed. This is useful if you want to keep a
reason to be explicitly installed. This is useful it you want to keep a
package installed even when it was initially installed as a dependency
of another package.
*-k, \--check*::
*-k \--check*::
Check the local package database is internally consistent. This will
check all required files are present and that installed packages have
the required dependencies, do not conflict and that multiple packages
@ -487,20 +464,24 @@ Database Options (apply to '-D')[[QO]]
a check on the sync databases to ensure all specified dependencies
are available.
*-q, \--quiet*::
Suppress messages on successful completion of database operations.
File Options[[FO]]
------------------
File Options (apply to '-F')[[FO]]
----------------------------------
*-y, --refresh*::
Download fresh package file databases '(repo.files)' from the server.
Use twice to force a refresh even if databases are up to date.
Download fresh package databases from the server. Use twice to force a
refresh even if databases are up to date.
*-l, \--list*::
List the files owned by the queried package.
*-s, \--search*::
Search package file names for matching strings.
*-x, --regex*::
Interpret each query as a regular expression.
Treat arguments to '--search' as regular expressions.
*-o, \--owns*::
Search for packages that own a particular file.
*-q, \--quiet*::
Show less information for certain file operations. This is useful when
@ -508,9 +489,9 @@ File Options (apply to '-F')[[FO]]
'--machinereadable' instead.
*--machinereadable*::
Print each match in a machine readable output format. The format is
'repository\0pkgname\0pkgver\0path\n' with '\0' being the NULL character
and '\n' a linefeed.
Use a machine readable output format for '--list', '--search' and
'--owns'. The format is 'repository\0pkgname\0pkgver\0path\n' with '\0'
being the NULL character and '\n' a linefeed.
Handling Config Files[[HCF]]
----------------------------
@ -519,7 +500,7 @@ designated to be backed up. During an upgrade, three MD5 hashes are used for
each backup file to determine the required action: one for the original file
installed, one for the new file that is about to be installed, and one for the
actual file existing on the file system. After comparing these three hashes, the
following scenarios can result:
follow scenarios can result:
original=X, current=X, new=X::
All three files are the same, so overwrites are not an issue. Install the
@ -580,4 +561,4 @@ See Also
linkman:alpm-hooks[5], linkman:libalpm[3], linkman:makepkg[8],
linkman:pacman.conf[5]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pacman.conf(5)
==============
@ -19,9 +22,6 @@ Each section defines a package repository that pacman can use when searching
for packages in '\--sync' mode. The exception to this is the options section,
which defines global options.
Comments are only supported by beginning a line with the hash (#) symbol.
Comments cannot begin in the middle of a line.
Example
-------
@ -48,7 +48,7 @@ work.
Options
-------
*RootDir =* /path/to/root/dir::
*RootDir =* path/to/root::
Set the default root directory for pacman to install to. This option is
used if you want to install a package on a temporary mounted partition
which is "owned" by another system, or for a chroot install.
@ -56,32 +56,32 @@ Options
command line or in linkman:pacman.conf[5], their default location will
be inside this root path.
*DBPath =* /path/to/db/dir::
Overrides the default location of the toplevel database directory. The
default is +{localstatedir}/lib/pacman/+. Most users will not need to set
*DBPath =* path/to/db/dir::
Overrides the default location of the toplevel database directory. A
typical default is +{localstatedir}/lib/pacman/+. Most users will not need to set
this option. *NOTE*: if specified, this is an absolute path and the root
path is not automatically prepended.
*CacheDir =* /path/to/cache/dir::
Overrides the default location of the package cache directory. The
*CacheDir =* path/to/cache/dir::
Overrides the default location of the package cache directory. A typical
default is +{localstatedir}/cache/pacman/pkg/+. Multiple cache directories can be
specified, and they are tried in the order they are listed in the config
file. If a file is not found in any cache directory, it will be downloaded
to the first cache directory with write access. *NOTE*: this is an absolute
path, the root path is not automatically prepended.
*HookDir =* /path/to/hook/dir::
*HookDir =* path/to/hook/dir::
Add directories to search for alpm hooks in addition to the system hook
directory (+{datarootdir}/libalpm/hooks/+). The default is
directory (+{datarootdir}/libalpm/hooks/+). A typical default is
+{sysconfdir}/pacman.d/hooks+. Multiple directories can be specified with
hooks in later directories taking precedence over hooks in earlier
directories. *NOTE*: this is an absolute path, the root path is not
automatically prepended. For more information on the alpm hooks, see
linkman:alpm-hooks[5].
*GPGDir =* /path/to/gpg/dir::
*GPGDir =* path/to/gpg/dir::
Overrides the default location of the directory containing configuration
files for GnuPG. The default is +{sysconfdir}/pacman.d/gnupg/+.
files for GnuPG. A typical default is +{sysconfdir}/pacman.d/gnupg/+.
This directory should contain two files: `pubring.gpg` and `trustdb.gpg`.
`pubring.gpg` holds the public keys of all packagers. `trustdb.gpg`
contains a so-called trust database, which specifies that the keys are
@ -89,8 +89,8 @@ Options
*NOTE*: this is an absolute path, the root path is not automatically
prepended.
*LogFile =* /path/to/log/file::
Overrides the default location of the pacman log file. The default
*LogFile =* /path/to/file::
Overrides the default location of the pacman log file. A typical default
is +{localstatedir}/log/pacman.log+. This is an absolute path and the root directory
is not prepended.
@ -108,20 +108,20 @@ Options
group when performing a '\--sysupgrade'. Shell-style glob patterns are
allowed.
*Include =* /path/to/config/file::
*Include =* path::
Include another configuration file. This file can include repositories or
general configuration options. Wildcards in the specified paths will get
expanded based on linkman:glob[7] rules.
*Architecture =* auto &| i686 &| x86_64 | ...::
If set, pacman will only allow installation of packages with the given
architectures (e.g. 'i686', 'x86_64', etc). The special value 'auto' will
*Architecture =* auto | i686 | x86_64 | ...::
If set, pacman will only allow installation of packages of the given
architecture (e.g. 'i686', 'x86_64', etc). The special value 'auto' will
use the system architecture, provided via ``uname -m''. If unset, no
architecture checks are made. *NOTE*: Packages with the special
architecture 'any' can always be installed, as they are meant to be
architecture independent.
*XferCommand =* /path/to/command %u [%o]::
*XferCommand =* /path/to/command %u::
If set, an external program will be used to download all remote files.
All instances of `%u` will be replaced with the download URL. If present,
instances of `%o` will be replaced with the local filename, plus a
@ -176,7 +176,7 @@ Options
operation on a local file. Uses the value from SigLevel as the default.
*RemoteFileSigLevel =* ...::
Set the signature verification level for installing packages using the "-U"
Set the signature verification level for installing packages using the "-U"
operation on a remote file URL. Uses the value from SigLevel as the default.
*UseSyslog*::
@ -186,9 +186,20 @@ Options
*Color*::
Automatically enable colors only when pacman's output is on a tty.
*NoProgressBar*::
Disables progress bars. This is useful for terminals which do
not support escape characters.
*UseDelta* [= ratio]::
Download delta files instead of complete packages if possible. Requires
the `xdelta3` program to be installed. If a ratio is specified (e.g.,
`0.5`), then it is used as a cutoff for determining whether to use deltas.
Allowed values are between `0.0` and `2.0`; sensible values are between
`0.2` and `0.9`. Using a value above `1.0` is not recommended. The
default is `0.7` if left unspecified.
*TotalDownload*::
When downloading, display the amount downloaded, download rate, ETA,
and completed percentage of the entire download list rather
than the percent of each individual download target. The progress
bar is still based solely on the current file download.
This option won't work if XferCommand is used.
*CheckSpace*::
Performs an approximate check for adequate available disk space before
@ -198,23 +209,6 @@ Options
Displays name, version and size of target packages formatted
as a table for upgrade, sync and remove operations.
*DisableDownloadTimeout*::
Disable defaults for low speed limit and timeout on downloads. Use this
if you have issues downloading files with proxy and/or security gateway.
*ParallelDownloads =* ...::
Specifies number of concurrent download streams. The value needs to be a
positive integer. If this config option is not set then only one download
stream is used (i.e. downloads happen sequentially).
*DownloadUser =* username::
Specifies the user to switch to for downloading files. If this config
option is not set then the downloads are done as the user running pacman.
*DisableSandbox*::
Disable the default sandbox applied to the process downloading files on Linux
systems. Useful if experiencing landlock related failures while downloading
files when running a Linux kernel that does not support this feature.
Repository Sections
-------------------
@ -235,7 +229,7 @@ contain a file that lists the servers for that repository.
# use this server first
Server = ftp://ftp.archlinux.org/$repo/os/$arch
# next use servers as defined in the mirrorlist below
Include = /etc/pacman.d/mirrorlist
Include = {sysconfdir}/pacman.d/mirrorlist
--------
The order of repositories in the configuration files matters; repositories
@ -248,12 +242,6 @@ number.
general configuration options. Wildcards in the specified paths will get
expanded based on linkman:glob[7] rules.
*CacheServer =* url::
A full URL to a location where the packages, and signatures (if
available) for this repository can be found. Cache servers will be tried
before any non-cache servers, will not be removed from the server pool for
404 download errors, and will not be used for database files.
*Server =* url::
A full URL to a location where the database, packages, and signatures (if
available) for this repository can be found.
@ -261,8 +249,8 @@ number.
During parsing, pacman will define the `$repo` variable to the name of the
current section. This is often utilized in files specified using the 'Include'
directive so all repositories can use the same mirrorfile. pacman also defines
the `$arch` variable to the first (or only) value of the `Architecture` option,
so the same mirrorfile can even be used for different architectures.
the `$arch` variable to the value of `Architecture`, so the same mirrorfile can
even be used for different architectures.
*SigLevel =* ...::
Set the signature verification level for this repository. For more
@ -379,4 +367,4 @@ See Also
--------
linkman:pacman[8], linkman:libalpm[3]
include::footer.asciidoc[]
include::footer.txt[]

69
doc/pactree.8.txt Normal file
View file

@ -0,0 +1,69 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pactree(8)
=========
Name
----
pactree - package dependency tree viewer
Synopsis
--------
'pactree' [options] package
Description
-----------
Pactree produces a dependency tree for a package.
By default, a tree-like output is generated, but with the '\--graph' option, a Graphviz
description is generated.
Options
-------
*-a, \--ascii*::
Use ASCII characters for tree formatting. By default, pactree will use Unicode
line drawing characters if it is able to detect that the locale supports them.
*-b, \--dbpath*::
Specify an alternative database location.
*-c, \--color*::
Colorize output.
*-d, \--depth <num>*::
Limits the number of levels of dependency to show. A zero means
show the named package only, one shows the packages that are directly
required.
*-g, \--graph*::
Generate a Graphviz description. If this option is given, the '\--color' and
'\--linear' options are ignored.
*-h, \--help*::
Output syntax and command-line options.
*-l, \--linear*::
Prints package names at the start of each line, one per line.
*-r, \--reverse*::
Show packages that depend on the named package.
*-s, \--sync*::
Read package data from sync databases instead of local database.
*-u, \--unique*::
List dependent packages once. Implies '\--linear'.
*\--config <file>*::
Specify an alternate pacman configuration file.
See Also
--------
linkman:pacman[8], linkman:pacman.conf[5], linkman:makepkg[8]
include::footer.txt[]

56
doc/pkgdelta.8.txt Normal file
View file

@ -0,0 +1,56 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pkgdelta(8)
=========
Name
----
pkgdelta - package delta generation utility
Synopsis
--------
'pkgdelta' [options] <package1> <package2>
Description
-----------
'pkgdelta' is used to create package delta files between two versions of the
same package. These files are essentially binary patches. linkman:pacman[8] can
download deltas instead of full package upgrades, and use them with the
previous versions of packages (in the package cache) to synthesize the upgraded
version of the packages. This likely reduces download sizes for upgrades
significantly.
'pkgdelta' requires linkman:xdelta3[1] to do its job.
Options
-------
*--max-delta-size <ratio>*::
Only create delta files if the delta is smaller than ratio * package_size.
Possible values: 0.0 to 2.0.
Recommended values: 0.2 to 0.9.
Default value: 0.7
*--min-pkg-size <size>*::
Minimal size of the package file in bytes to be considered for delta creation.
Default value: 1048576 bytes = 1 MiB. This may be any absolute size in bytes or
a human-readable value such as `4MiB` or `3.5MB`.
*-q, \--quiet*::
Be quiet. Do not output anything but warnings and errors.
Examples
--------
$ pkgdelta libreoffice-3.3.2-1-x86_64.pkg.tar.xz libreoffice-3.3.2-2-x86_64.pkg.tar.xz
See Also
--------
linkman:pacman[8], linkman:xdelta3[1]
include::footer.txt[]

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
repo-add(8)
==========
@ -8,31 +11,32 @@ repo-add - package database maintenance utility
Synopsis
--------
'repo-add' [options] <path-to-db> <package> [<package> ...]
'repo-add' [options] <path-to-db> <package|delta> [<package|delta> ...]
'repo-remove' [options] <path-to-db> <packagename> [<packagename> ...]
'repo-remove' [options] <path-to-db> <packagename|delta> [<packagename|delta> ...]
Description
-----------
'repo-add' and 'repo-remove' are two scripts to help build a package database for
packages built with linkman:makepkg[8] and installed with linkman:pacman[8].
They also handle package deltas produced by linkman:pkgdelta[8].
'repo-add' will update a package database by reading a built package file.
Multiple packages to add can be specified on the command line.
'repo-add' will update a package database by reading a built package or package
delta file. Multiple packages and/or deltas to add can be specified on the
command line.
If a matching ``.sig'' file is found alongside a package file, the signature
will automatically be embedded into the database.
'repo-remove' will update a package database by removing the package name
specified on the command line. Multiple packages to remove can be specified
on the command line.
'repo-remove' will update a package database by removing the package name or
delta specified on the command line. Multiple packages and/or delta to remove
can be specified on the command line.
A package database is a tar file, optionally compressed. Valid extensions are
``.db'' followed by an archive extension of ``.tar'', ``.tar.bz2'',
``.tar.gz'', ``.tar.lrz'', ``.tar.lz'', ``.tar.lz4'', ``.tar.lzo'',
``.tar.xz'', ``.tar.zst'' or ``.tar.Z''. The file does not need to exist, but
all parent directories must exist.
``.db'' followed by an archive extension of ``.tar'', ``.tar.gz'', ``.tar.bz2'',
``.tar.xz'', or ``.tar.Z''. The file does not need to exist, but all parent
directories must exist.
Common Options
@ -43,13 +47,13 @@ Common Options
*-s, \--sign*::
Generate a PGP signature file using GnuPG. This will execute `gpg
--detach-sign` on the generated database to generate a detached
--detach-sign --use-agent` on the generated database to generate a detached
signature file, using the GPG agent if it is available. The signature file
will be the entire filename of the database with a ``.sig'' extension.
*-k, \--key* <key>::
Specify a key to use when signing packages. Can also be specified using
the GPGKEY environment variable. If not specified in either location, the
the GPGKEY environmental variable. If not specified in either location, the
default key from the keyring will be used.
*-v, \--verify*::
@ -60,23 +64,21 @@ Common Options
*\--nocolor*::
Remove color from 'repo-add' and 'repo-remove' output.
*-R, \--remove*::
Remove old package files from the disk when updating or removing their
entry in the database.
*-w, \--wait-for-lock*::
Wait for the lock file to be acquired. If unset, command will fail with
exit code 2 if acquiring the lock fails. If set, it will retry to acquire
lock until success.
repo-add Options
----------------
*-d, \--delta*::
Automatically generate and add a delta file between the old entry and the
new one, if the old package file is found next to the new one.
*-n, \--new*::
Only add packages that are not already in the database. Warnings will be
printed upon detection of existing packages, but they will not be re-added.
*\--include-sigs*::
Include package PGP signatures in the repository database (if available)
*-R, \--remove*::
Remove old package files from the disk when updating their entry in the
database.
Example
-------
@ -90,6 +92,6 @@ db.tar* extension), there is currently no additional benefit for the larger down
See Also
--------
linkman:makepkg[8], linkman:pacman[8]
linkman:makepkg[8], linkman:pacman[8], linkman:pkgdelta[8]
include::footer.asciidoc[]
include::footer.txt[]

View file

@ -11,31 +11,16 @@ NOTE: Some of this is paraphrased from the kernel documentation's
Getting the most recent source
------------------------------
Patches need to be submitted in Git format and are best if they are against the
Patches need to be submitted in GIT format and are best if they are against the
latest version of the code. There are several helpful tutorials for getting
started with Git if you have not worked with it before.
started with GIT if you have not worked with it before.
* https://www.kernel.org/pub/software/scm/git/docs/gittutorial.html
* https://wiki.archlinux.org/index.php/Super_Quick_Git_Guide
The pacman code can be fetched using the following command:
git clone https://gitlab.archlinux.org/pacman/pacman.git
Before making large changes
---------------------------
--
* Discuss your idea
There is nothing worse that spending time making a change only for it to be
rejected immediately. Ensure ideas are discussed beforehand to avoid
disappointment. Appropriate locations for discussion are the issue tracker
on gitlab, or the pacman-dev mailing list. Transient discussion channels
such as IRC are not appropriate.
--
git clone git://projects.archlinux.org/pacman.git
Creating your patch
@ -54,22 +39,40 @@ address if you're afraid of spam.
* Describe your patch.
It helps if you describe the overview and goals of the patch in the git commit
It helps if you describe the overview and goals of the patch in the git commit
log. This allows others to see what you intended so as to compare it to what
was actually done, and allows better feedback.
* Use `git format-patch` to create patches.
Your commit message will be shown above the patch by default when you will use
`git format-patch`, including the signoff line. Sets of multiple patches that
need extra explanation beyond the commit messages may include additional notes
in a cover letter. Individual patches may include additional notes between the
"---" following the commit message and the beginning of the diff.
--
Submitting your patch
---------------------
--
* Submit patches with a gitlab merge request
* Send the patch to the pacman-dev mailing list
The pacman gitlab instance is the primary queue for review and acceptance.
Here you will get feedback, and let the reviewers know the details of your
patch.
The mailing list is the primary queue for review and acceptance. Here you
will get feedback, and let the reviewers know the details of your patch.
* No MIME, no links, no compression, no attachments. Just plain text.
Patches should be contained in the actual body of the email. There are many
reasons for this. First, it makes them easier to read with any mail reader,
it allows easier review "at a glance", and most importantly, it allows people
to comment on exact lines of the patch in reply emails.
`git send-email` allows you to send Git-formatted patches in plain text easily
and is the preferred method for submission to the mailing list. Mail clients,
including Gmail's web interface, have a tendency to break patches by wrapping
lines and/or adjusting whitespace and should be avoided.
--
@ -92,6 +95,11 @@ When you do get feedback, it usually merits a response, whether this be a
resubmission of the patch with corrections or a follow-up email asking for
clarifications. When neither of these occurs, don't expect your patch to get
further review. The all-volunteer staff don't have time to fix up patches that
aren't their own.
aren't their own. When resubmitting patches, update the subject line to reflect
the version number ('[PATCHv2]'), and send it as a reply to the original thread.
--
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

View file

@ -1,20 +0,0 @@
testpkg(8)
==========
Name
----
testpkg - test a pacman package for validity
Synopsis
--------
'testpkg' <package file>
Description
-----------
'testpkg' is a script used to make sure that a pacman package is valid.
See Also
--------
linkman:pacman[8]
include::footer.asciidoc[]

View file

@ -4,10 +4,10 @@ Pacman - Translating
This document is here to guide you in helping translate pacman messages,
libalpm messages, and the manual pages for the entire pacman package.
We are currently using https://app.transifex.com/[Transifex] as the translation
We are currently using http://www.transifex.com/[Transifex] as the translation
platform for pacman and libalpm. You will need to sign up for an account there
and then register with a translation team on the
https://explore.transifex.com/toofishes/archlinux-pacman/[pacman project page].
http://www.transifex.com/projects/p/archlinux-pacman/[pacman project page].
NOTE: This may be old information due to our switch to Transifex, but the
gettext website is a very useful guide to read before embarking on translation
@ -31,7 +31,7 @@ either be hand-edited, or modified with a tool such as poedit, gtranslator or
kbabel. Using a translation tool tends to make the job easier.
Please read up on Transifex usage using the
https://help.transifex.com/[Transifex Help] if you are not familiar.
http://docs.transifex.com/[Transifex Help] if you are not familiar.
Transifex provides a command-line client to help with translations. Here is
an example set of commands if you have a source code checkout and are not
@ -55,20 +55,20 @@ Pre-release Updates
~~~~~~~~~~~~~~~~~~~
A week or two before each release, the codebase will go into a string freeze
and an email will be sent to the mailto:pacman-dev@lists.archlinux.org[pacman-dev]
mailing list asking for translations. An announcement in Transifex is also made,
which reaches everyone that is member of the translation team.
and an email will be sent to the mailto:pacman-dev@archlinux.org[pacman-dev]
mailing list asking for translations. This email will have a prefix of
*[translation]* for anyone looking to set up an email filter.
At this time, the latest `.po` language files will be made available at the
Transifex project page. Each language will have three files available (libalpm,
pacman and pacman-scripts). Translators interested in helping are encouraged to use the
Transifex project page. Each language will have two files available (back-end
and front-end). Translators interested in helping are encouraged to use the
features of Transifex to let others know they are currently translating their
language.
Once a translator has completed the translation offline (*OR* realizes they do not have
Once a translator has completed the translation (*OR* realizes they do not have
time to finish), please upload your progress back to the Transifex site.
NOTE: Please upload your translations as soon as possible - this will give other
NOTE: Please upload your translations as soon as possible- this will give other
speakers of your language time to review your translations and update them as
necessary.
@ -78,27 +78,23 @@ Incremental Updates
If you have more advanced needs you will have to get a copy of the pacman
repository.
git clone https://gitlab.archlinux.org/pacman/pacman.git
git clone git://projects.archlinux.org/pacman.git pacman
Next, you will need to configure the build environment. From the base directory,
run:
Next, you will need to run `./autogen.sh` and `./configure` in the base
directory to generate the correct Makefiles. At this point, all necessary
make targets will be generated and we can begin updating the translation
files.
meson setup . build
We need to first update the main message catalog file. Navigate into either the
`lib/libalpm/po` or `po` directory depending on which translation you wish to
work on first, and execute the following command. If you are working in the
`po/` tree, replace 'libalpm.pot' with 'pacman.pot':
If any required dependencies are missing, please install. After that,
update the template translation (.pot) files to the latest state of
the source code by running:
meson compile -C build pacman-scripts-pot pacman-pot libalpm-pot
We need to first update the main message catalog file. Navigate into either
the `lib/libalpm/po`, `scripts/po` or `src/pacman/po` directory depending
on which translation you wish to work on first, and execute the following
command to update your specific language's translation file
(replace `lang_code` with your language code e.g. 'pt_BR', and `pot_file`
with `libalpm.pot`, `pacman.pot` or `pacman-scripts.pot`):
make libalpm.pot-update
msgmerge --update --previous <lang_code>.po <pot_filename>.pot
Next, update your specific language's translation file:
make <po file>-update
At this point, you can do the translation. To submit your changes, either email
the new `.po` file to the mailing-list with *[translation]* in the subject, or
@ -107,7 +103,7 @@ submit a Git-formatted patch (please do not include any `.pot` file changes).
As a shortcut, all translation files (including `.pot` files) can be updated
with the following command:
./build-aux/update-po
make update-po
Adding a New Language
~~~~~~~~~~~~~~~~~~~~~
@ -116,10 +112,10 @@ Making a new language is not too hard, but be sure to follow all the steps.
You will have to do the following steps in both the `lib/libalpm/po/` and `po/`
directories, substituting where appropriate. First, edit the `LINGUAS` file and
add your new language code at the bottom. Next, run the following command,
substituting `libalpm.pot` or `pacman.pot` for potfile depending on which
substituting 'libalpm.pot' or 'pacman.pot' for potfile depending on which
directory you are currently working in:
msginit -l <lang_code> -o <lang_code>.po -i <potfile>
msginit -l <lang code> -o <lang code>.po -i <potfile>
You can then also add your language code to the end of the `LINGUAS` file
located in each po directory.
@ -141,13 +137,11 @@ following two translations are equivalent:
msgstr ""
"This is a test translation"
If you want to test the translation (copy the .po file you want to test,
you may ignore the rest), replacing `<lang_code>` accordingly:
If you want to test the translation (for example, the front-end one):
meson compile -C build pacman-scripts-gmo pacman-gmo libalpm-gmo
cp ./build/lib/libalpm/po/<lang_code>/LC_MESSAGES/libalpm.mo /usr/share/locale/<lang_code>/LC_MESSAGES/libalpm.mo
cp ./build/scripts/po/<lang_code>/LC_MESSAGES/pacman-scripts.mo /usr/share/locale/<lang_code>/LC_MESSAGES/pacman-scripts.mo
cp ./build/src/pacman/po/<lang_code>/LC_MESSAGES/pacman.mo /usr/share/locale/<lang_code>/LC_MESSAGES/pacman.mo
rm *.gmo stamp-po
make
cp <lang code>.gmo /usr/share/locale/<lang code>/LC_MESSAGES/pacman.mo
Translating Manpages
@ -156,4 +150,8 @@ There are currently no efforts underway to include translated manual pages in
the pacman codebase. However, this is not to say translations are unwelcome. If
someone has experience with i18n man pages and how to best include them with our
source, please contact the pacman-dev mailing list at
mailto:pacman-dev@lists.archlinux.org[].
mailto:pacman-dev@archlinux.org[].
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

View file

@ -1,3 +1,6 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
vercmp(8)
=========
@ -8,7 +11,7 @@ vercmp - version comparison utility
Synopsis
--------
'vercmp' [-h] [--help] <version1> <version2>
'vercmp' <version1> <version2>
Description
@ -41,9 +44,8 @@ mainly for supporting versioned dependencies that do not include the 'pkgrel'.
Options
-------
*-h, \--help*::
Display summary of the available return codes. Must be the first option
specified.
Display syntax for the given operation. If no operation was supplied,
then the general syntax is shown.
Examples
@ -65,8 +67,13 @@ Examples
-1
Configuration
-------------
There is none.
See Also
--------
linkman:pacman[8], linkman:makepkg[8], linkman:libalpm[3]
include::footer.asciidoc[]
include::footer.txt[]

29
etc/Makefile.am Normal file
View file

@ -0,0 +1,29 @@
dist_sysconf_DATA = makepkg.conf pacman.conf
EXTRA_DIST = makepkg.conf.in pacman.conf.in
# Files that should be removed, but which Automake does not know.
MOSTLYCLEANFILES = $(dist_sysconf_DATA)
SED_PROCESS = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
$(SED) \
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@prefix[@]|$(prefix)|g' \
-e 's|@PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
-e 's|@PACKAGE_NAME[@]|$(PACKAGE_NAME)|g' \
-e 's|@PKGEXT[@]|$(PKGEXT)|g' \
-e 's|@SRCEXT[@]|$(SRCEXT)|g' \
-e 's|@STRIP_BINARIES[@]|$(STRIP_BINARIES)|g' \
-e 's|@STRIP_SHARED[@]|$(STRIP_SHARED)|g' \
-e 's|@STRIP_STATIC[@]|$(STRIP_STATIC)|g' \
-e 's|@CARCH[@]|$(CARCH)|g' \
-e 's|@CHOST[@]|$(CHOST)|g' \
-e 's|@ARCHSWITCH[@]|$(ARCHSWITCH)|g' \
-e 's|@ROOTDIR[@]|$(ROOTDIR)|g' \
< $< > $@
%.conf: %.conf.in Makefile
$(SED_PROCESS)
# vim:set noet:

View file

@ -1,18 +0,0 @@
#!/hint/bash
#
# @sysconfdir@/makepkg.conf.d/fortran.conf
#
#########################################################################
# FORTRAN LANGUAGE SUPPORT
#########################################################################
# Flags used for the Fortran compiler, similar in spirit to CFLAGS. Read
# linkman:gfortran[1] for more details on the available flags.
#FFLAGS="-O2 -pipe"
#FCFLAGS="$FFLAGS"
# Additional compiler flags appended to `FFLAGS` and `FCFLAGS` for use in debugging. Usually
# this would include: ``-g''. Read linkman:gfortran[1] for more details on the wide
# variety of compiler flags available.
#DEBUG_FFLAGS="-g"

View file

@ -1,17 +0,0 @@
#!/hint/bash
#
# @sysconfdir@/makepkg.conf.d/rust.conf
#
#########################################################################
# RUST LANGUAGE SUPPORT
#########################################################################
# Flags used for the Rust compiler, similar in spirit to CFLAGS. Read
# linkman:rustc[1] for more details on the available flags.
#RUSTFLAGS="-C opt-level=3"
# Additional compiler flags appended to `RUSTFLAGS` for use in debugging.
# Usually this would include: ``-C debuginfo=2''. Read linkman:rustc[1] for
# more details on the available flags.
#DEBUG_RUSTFLAGS="-C debuginfo=2"

View file

@ -1,4 +1,3 @@
#!/hint/bash
#
# @sysconfdir@/makepkg.conf
#
@ -9,10 +8,9 @@
#
#-- The download utilities that makepkg should use to acquire sources
# Format: 'protocol::agent'
DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
'ftp::/usr/bin/curl -qgfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
'http::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
'https::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
DLAGENTS=('ftp::/usr/bin/curl -gqfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
'http::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
'https::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
'rsync::/usr/bin/rsync --no-motd -z %u %o'
'scp::/usr/bin/scp -C %u %o')
@ -23,8 +21,7 @@ DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
#-- The package required by makepkg to download VCS sources
# Format: 'protocol::package'
VCSCLIENTS=('bzr::breezy'
'fossil::fossil'
VCSCLIENTS=('bzr::bzr'
'git::git'
'hg::mercurial'
'svn::subversion')
@ -36,14 +33,11 @@ VCSCLIENTS=('bzr::breezy'
CARCH="@CARCH@"
CHOST="@CHOST@"
#NPROC=2
#-- Compiler and Linker Flags
#CPPFLAGS=""
#CFLAGS="-O2 -pipe"
#CXXFLAGS="-O2 -pipe"
#LDFLAGS=""
#LTOFLAGS="-flto"
#-- Make Flags: change this for DistCC/SMP systems
#MAKEFLAGS="-j2"
#-- Debugging flags
@ -54,7 +48,7 @@ CHOST="@CHOST@"
# BUILD ENVIRONMENT
#########################################################################
#
# Makepkg defaults: BUILDENV=(!distcc !color !ccache check !sign)
# Defaults: BUILDENV=(!distcc color !ccache check !sign)
# A negated environment option will do the opposite of the comments below.
#
#-- distcc: Use the Distributed C/C++/ObjC compiler
@ -77,8 +71,7 @@ BUILDENV=(!distcc color !ccache check !sign)
# These are default values for the options=() settings
#########################################################################
#
# Makepkg defaults:
# OPTIONS=(!strip docs libtool staticlibs emptydirs !zipman !purge !debug !lto !autodeps)
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !optipng !debug)
# A negated option will do the opposite of the comments below.
#
#-- strip: Strip symbols from binaries/libraries
@ -88,14 +81,14 @@ BUILDENV=(!distcc color !ccache check !sign)
#-- emptydirs: Leave empty directories in packages
#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip
#-- purge: Remove files specified by PURGE_TARGETS
#-- upx: Compress binary executable files using UPX
#-- optipng: Optimize PNG images with optipng
#-- debug: Add debugging flags as specified in DEBUG_* variables
#-- lto: Add compile flags for building with link time optimization
#-- autodeps: Automatically add depends/provides
#
OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !debug !lto !autodeps)
OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !optipng !debug)
#-- File integrity checks to use. Valid: ck, md5, sha1, sha224, sha256, sha384, sha512, b2
INTEGRITY_CHECK=(ck)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5)
#-- Options to be used when stripping binaries. See `man strip' for details.
STRIP_BINARIES="@STRIP_BINARIES@"
#-- Options to be used when stripping shared libraries. See `man strip' for details.
@ -108,10 +101,6 @@ MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info})
DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc})
#-- Files to be removed from all packages (if purge is specified)
PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#-- Directory to store source code in for debug packages
DBGSRCDIR="/usr/src/debug"
#-- Prefix and directories for library autodeps
LIB_DIRS=('lib:usr/lib' 'lib32:usr/lib32')
#########################################################################
# PACKAGE OUTPUT
@ -139,23 +128,18 @@ LIB_DIRS=('lib:usr/lib' 'lib32:usr/lib32')
COMPRESSGZ=(gzip -c -f -n)
COMPRESSBZ2=(bzip2 -c -f)
COMPRESSXZ=(xz -c -z -)
COMPRESSZST=(zstd -c -z -q -)
COMPRESSLRZ=(lrzip -q)
COMPRESSLZO=(lzop -q)
COMPRESSZ=(compress -c -f)
COMPRESSLZ4=(lz4 -q)
COMPRESSLZ=(lzip -c -f)
#########################################################################
# EXTENSION DEFAULTS
#########################################################################
#
# WARNING: Do NOT modify these variables unless you know what you are
# doing.
#
PKGEXT='@PKGEXT@'
SRCEXT='@SRCEXT@'
#########################################################################
# OTHER
#########################################################################
#
#-- Command used to run pacman as root, instead of trying sudo and su
PACMAN_AUTH=()
# vim: set ft=sh ts=2 sw=2 et:

View file

@ -16,9 +16,10 @@
#GPGDir = @sysconfdir@/pacman.d/gnupg/
#HookDir = @sysconfdir@/pacman.d/hooks/
HoldPkg = pacman glibc
#XferCommand = /usr/bin/curl -L -C - -f -o %o %u
#XferCommand = /usr/bin/curl -C - -f %u > %o
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#CleanMethod = KeepInstalled
#UseDelta = 0.7
Architecture = auto
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
@ -31,12 +32,9 @@ Architecture = auto
# Misc options
#UseSyslog
#Color
#NoProgressBar
#TotalDownload
CheckSpace
#VerbosePkgLists
ParallelDownloads = 5
#DownloadUser = alpm
#DisableSandbox
# PGP signature checking
#SigLevel = Optional
@ -76,4 +74,4 @@ ParallelDownloads = 5
# tips on creating your own repositories.
#[custom]
#SigLevel = Optional TrustAll
#Server = file:///home/packages
#Server = file:///home/custompkgs

83
lib/libalpm/Makefile.am Normal file
View file

@ -0,0 +1,83 @@
AUTOMAKE_OPTIONS = gnu
SUBDIRS = po
lib_LTLIBRARIES = libalpm.la
include_HEADERS = alpm_list.h alpm.h
AM_CPPFLAGS = \
-imacros $(top_builddir)/config.h \
-DSYSHOOKDIR=\"@datarootdir@/libalpm/hooks/\" \
-DLOCALEDIR=\"@localedir@\"
AM_CFLAGS = -pedantic -D_GNU_SOURCE $(WARNING_CFLAGS)
if ENABLE_VISIBILITY_CC
if DARWIN
AM_CFLAGS += -fvisibility=hidden
else
AM_CFLAGS += -fvisibility=internal
endif
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libalpm.pc
libalpm_la_SOURCES = \
add.h add.c \
alpm.h alpm.c \
alpm_list.h alpm_list.c \
backup.h backup.c \
base64.h base64.c \
be_local.c \
be_package.c \
be_sync.c \
conflict.h conflict.c \
db.h db.c \
delta.h delta.c \
deps.h deps.c \
diskspace.h diskspace.c \
dload.h dload.c \
error.c \
filelist.h filelist.c \
graph.h graph.c \
group.h group.c \
handle.h handle.c \
hook.h hook.c \
ini.h ini.c \
libarchive-compat.h \
log.h log.c \
package.h package.c \
pkghash.h pkghash.c \
rawstr.c \
remove.h remove.c \
signing.c signing.h \
sync.h sync.c \
trans.h trans.c \
util.h util.c \
util-common.h util-common.c \
version.c
if !HAVE_LIBSSL
libalpm_la_SOURCES += \
md5.h md5.c \
sha2.h sha2.c
endif
libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO)
libalpm_la_CFLAGS = \
$(AM_CFLAGS) \
$(GPGME_CFLAGS) \
$(LIBARCHIVE_CFLAGS) \
$(LIBCURL_CFLAGS) \
$(LIBSSL_CFLAGS)
libalpm_la_LIBADD = \
$(LTLIBINTL) \
$(GPGME_LIBS) \
$(LIBARCHIVE_LIBS) \
$(LIBCURL_LIBS) \
$(LIBSSL_LIBS)
# vim:set noet:

View file

@ -1,7 +1,7 @@
/*
* add.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -47,12 +47,12 @@
#include "remove.h"
#include "handle.h"
/** Add a package to the transaction. */
int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
{
const char *pkgname, *pkgver;
alpm_trans_t *trans;
alpm_pkg_t *local;
alpm_pkg_t *dup;
/* Sanity checks */
CHECK_HANDLE(handle, return -1);
@ -70,16 +70,12 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
_alpm_log(handle, ALPM_LOG_DEBUG, "adding package '%s'\n", pkgname);
if((dup = alpm_pkg_find(trans->add, pkgname))) {
if(dup == pkg) {
_alpm_log(handle, ALPM_LOG_DEBUG, "skipping duplicate target: %s\n", pkgname);
return 0;
}
/* error for separate packages with the same name */
if(alpm_pkg_find(trans->add, pkgname)) {
RET_ERR(handle, ALPM_ERR_TRANS_DUP_TARGET, -1);
}
if((local = _alpm_db_get_pkgfromcache(handle->db_local, pkgname))) {
local = _alpm_db_get_pkgfromcache(handle->db_local, pkgname);
if(local) {
const char *localpkgname = local->name;
const char *localpkgver = local->version;
int cmp = _alpm_pkg_compare_versions(pkg, local);
@ -119,7 +115,6 @@ static int perform_extraction(alpm_handle_t *handle, struct archive *archive,
ARCHIVE_EXTRACT_PERM |
ARCHIVE_EXTRACT_TIME |
ARCHIVE_EXTRACT_UNLINK |
ARCHIVE_EXTRACT_XATTR |
ARCHIVE_EXTRACT_SECURE_SYMLINKS;
archive_entry_set_pathname(entry, filename);
@ -262,7 +257,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
"filesystem: %o package: %o\n"), filename, lsbuf.st_mode & mask,
entrymode & mask);
alpm_logaction(handle, ALPM_CALLER_PREFIX,
"warning: directory permissions differ on %s, "
"warning: directory permissions differ on %s\n"
"filesystem: %o package: %o\n", filename, lsbuf.st_mode & mask,
entrymode & mask);
}
@ -277,7 +272,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
"filesystem: %u:%u package: %u:%u\n"), filename,
lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
alpm_logaction(handle, ALPM_CALLER_PREFIX,
"warning: directory ownership differs on %s, "
"warning: directory ownership differs on %s\n"
"filesystem: %u:%u package: %u:%u\n", filename,
lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
}
@ -415,7 +410,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
size_t pkg_current, size_t pkg_count)
{
int ret = 0, errors = 0;
int i, ret = 0, errors = 0;
int is_upgrade = 0;
alpm_pkg_t *oldpkg = NULL;
alpm_db_t *db = handle->db_local;
@ -432,7 +427,7 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
ASSERT(trans != NULL, return -1);
/* see if this is an upgrade. if so, remove the old package first */
if(_alpm_db_get_pkgfromcache(db, newpkg->name) && (oldpkg = newpkg->oldpkg)) {
if((oldpkg = newpkg->oldpkg)) {
int cmp = _alpm_pkg_compare_versions(newpkg, oldpkg);
if(cmp < 0) {
log_msg = "downgrading";
@ -484,7 +479,8 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
/* set up fake remove transaction */
if(_alpm_remove_single_package(handle, oldpkg, newpkg, 0, 0) == -1) {
handle->pm_errno = ALPM_ERR_TRANS_ABORT;
return -1;
ret = -1;
goto cleanup;
}
}
@ -495,13 +491,15 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
"error: could not create database entry %s-%s\n",
newpkg->name, newpkg->version);
handle->pm_errno = ALPM_ERR_DB_WRITE;
return -1;
ret = -1;
goto cleanup;
}
fd = _alpm_open_archive(db->handle, pkgfile, &buf,
&archive, ALPM_ERR_PKG_OPEN);
if(fd < 0) {
return -1;
ret = -1;
goto cleanup;
}
/* save the cwd so we can restore it later */
@ -519,7 +517,8 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
close(cwdfd);
}
close(fd);
return -1;
ret = -1;
goto cleanup;
}
if(trans->flags & ALPM_TRANS_FLAG_DBONLY) {
@ -538,7 +537,7 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
/* call PROGRESS once with 0 percent, as we sort-of skip that here */
PROGRESS(handle, progress, newpkg->name, 0, pkg_count, pkg_current);
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
int percent;
if(newpkg->size != 0) {
@ -603,7 +602,8 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
"error: could not update database entry %s-%s\n",
newpkg->name, newpkg->version);
handle->pm_errno = ALPM_ERR_DB_WRITE;
return -1;
ret = -1;
goto cleanup;
}
if(_alpm_db_add_pkgincache(db, newpkg) == -1) {
@ -649,6 +649,7 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
event.type = ALPM_EVENT_PACKAGE_OPERATION_DONE;
EVENT(handle, &event);
cleanup:
return ret;
}
@ -693,3 +694,5 @@ int _alpm_upgrade_packages(alpm_handle_t *handle)
return ret;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* add.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -27,3 +27,5 @@
int _alpm_upgrade_packages(alpm_handle_t *handle);
#endif /* ALPM_ADD_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* alpm.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
@ -25,9 +25,6 @@
#include <curl/curl.h>
#endif
#include <errno.h>
#include <pwd.h>
/* libalpm */
#include "alpm.h"
#include "alpm_list.h"
@ -35,14 +32,26 @@
#include "log.h"
#include "util.h"
/** \addtogroup alpm_interface Interface Functions
* @brief Functions to initialize and release libalpm
* @{
*/
/** Initializes the library.
* Creates handle, connects to database and creates lockfile.
* This must be called before any other functions are called.
* @param root the root path for all filesystem operations
* @param dbpath the absolute path to the libalpm database
* @param err an optional variable to hold any error return codes
* @return a context handle on success, NULL on error, err will be set if provided
*/
alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
alpm_errno_t *err)
{
alpm_errno_t myerr;
const char *lf = "db.lck";
char *hookdir;
size_t hookdirlen, lockfilelen;
struct passwd const *pw = NULL;
size_t lockfilelen;
alpm_handle_t *myhandle = _alpm_handle_new();
if(myhandle == NULL) {
@ -55,12 +64,11 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
goto cleanup;
}
/* to concatenate myhandle->root (ends with a slash) with SYSHOOKDIR (starts
/* to contatenate myhandle->root (ends with a slash) with SYSHOOKDIR (starts
* with a slash) correctly, we skip SYSHOOKDIR[0]; the regular +1 therefore
* disappears from the allocation */
hookdirlen = strlen(myhandle->root) + strlen(SYSHOOKDIR);
MALLOC(hookdir, hookdirlen, goto nomem);
snprintf(hookdir, hookdirlen, "%s%s", myhandle->root, &SYSHOOKDIR[1]);
MALLOC(hookdir, strlen(myhandle->root) + strlen(SYSHOOKDIR), goto nomem);
sprintf(hookdir, "%s%s", myhandle->root, SYSHOOKDIR + 1);
myhandle->hookdirs = alpm_list_add(NULL, hookdir);
/* set default database extension */
@ -75,17 +83,6 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
goto cleanup;
}
#ifdef HAVE_LIBCURL
curl_global_init(CURL_GLOBAL_ALL);
myhandle->curlm = curl_multi_init();
#endif
myhandle->parallel_downloads = 1;
/* set default sandboxuser */
ASSERT((pw = getpwuid(0)) != NULL, myerr = errno; goto cleanup);
STRDUP(myhandle->sandboxuser, pw->pw_name, goto nomem);
#ifdef ENABLE_NLS
bindtextdomain("libalpm", LOCALEDIR);
#endif
@ -102,24 +99,60 @@ cleanup:
return NULL;
}
/* check current state and free all resources including storage locks */
/** Release the library.
* Disconnects from the database, removes handle and lockfile
* This should be the last alpm call you make.
* After this returns, handle should be considered invalid and cannot be reused
* in any way.
* @param myhandle the context handle
* @return 0 on success, -1 on error
*/
int SYMEXPORT alpm_release(alpm_handle_t *myhandle)
{
int ret = 0;
alpm_db_t *db;
CHECK_HANDLE(myhandle, return -1);
ASSERT(myhandle->trans == NULL, RET_ERR(myhandle, ALPM_ERR_TRANS_NOT_NULL, -1));
/* close local database */
db = myhandle->db_local;
if(db) {
db->ops->unregister(db);
myhandle->db_local = NULL;
}
if(alpm_unregister_all_syncdbs(myhandle) == -1) {
ret = -1;
}
_alpm_handle_unlock(myhandle);
_alpm_handle_free(myhandle);
return 0;
#ifdef HAVE_LIBCURL
curl_global_cleanup();
#endif
return ret;
}
/** @} */
/** @defgroup alpm_misc Miscellaneous Functions
* @brief Various libalpm functions
*/
/** Get the version of library.
* @return the library version, e.g. "6.0.4"
* */
const char SYMEXPORT *alpm_version(void)
{
return LIB_VERSION;
}
int SYMEXPORT alpm_capabilities(void)
/** Get the capabilities of the library.
* @return a bitmask of the capabilities
* */
enum alpm_caps SYMEXPORT alpm_capabilities(void)
{
return 0
#ifdef ENABLE_NLS
@ -133,3 +166,5 @@ int SYMEXPORT alpm_capabilities(void)
#endif
| 0;
}
/* vim: set noet: */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*
* alpm_list.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -30,9 +30,25 @@
/* check exported library symbols with: nm -C -D <lib> */
#define SYMEXPORT __attribute__((visibility("default")))
#define SYMHIDDEN __attribute__((visibility("internal")))
/**
* @addtogroup alpm_list List Functions
* @brief Functions to manipulate alpm_list_t lists.
*
* These functions are designed to create, destroy, and modify lists of
* type alpm_list_t. This is an internal list type used by libalpm that is
* publicly exposed for use by frontends if desired.
*
* @{ */
/* Allocation */
/**
* @brief Free a list, but not the contained data.
*
* @param list the list to free
*/
void SYMEXPORT alpm_list_free(alpm_list_t *list)
{
alpm_list_t *it = list;
@ -44,6 +60,12 @@ void SYMEXPORT alpm_list_free(alpm_list_t *list)
}
}
/**
* @brief Free the internal data of a list structure.
*
* @param list the list to free
* @param fn a free function for the internal data
*/
void SYMEXPORT alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn)
{
alpm_list_t *it = list;
@ -61,12 +83,28 @@ void SYMEXPORT alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn)
/* Mutators */
/**
* @brief Add a new item to the end of the list.
*
* @param list the list to add to
* @param data the new item to be added to the list
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
{
alpm_list_append(&list, data);
return list;
}
/**
* @brief Add a new item to the end of the list.
*
* @param list the list to add to
* @param data the new item to be added to the list
*
* @return the newly added item
*/
alpm_list_t SYMEXPORT *alpm_list_append(alpm_list_t **list, void *data)
{
alpm_list_t *ptr;
@ -93,18 +131,15 @@ alpm_list_t SYMEXPORT *alpm_list_append(alpm_list_t **list, void *data)
return ptr;
}
alpm_list_t SYMEXPORT *alpm_list_append_strdup(alpm_list_t **list, const char *data)
{
alpm_list_t *ret;
char *dup;
if((dup = strdup(data)) && (ret = alpm_list_append(list, dup))) {
return ret;
} else {
free(dup);
return NULL;
}
}
/**
* @brief Add items to a list in sorted order.
*
* @param list the list to add to
* @param data the new item to be added to the list
* @param fn the comparison function to use to determine order
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn)
{
if(!fn || !list) {
@ -147,6 +182,17 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_
}
}
/**
* @brief Join two lists.
* The two lists must be independent. Do not free the original lists after
* calling this function, as this is not a copy operation. The list pointers
* passed in should be considered invalid after calling this function.
*
* @param first the first list
* @param second the second list
*
* @return the resultant joined list
*/
alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
{
alpm_list_t *tmp;
@ -169,6 +215,15 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
return first;
}
/**
* @brief Merge the two sorted sublists into one sorted list.
*
* @param left the first list
* @param right the second list
* @param fn comparison function for determining merge order
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right,
alpm_list_fn_cmp fn)
{
@ -230,6 +285,15 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right,
return newlist;
}
/**
* @brief Sort a list of size `n` using mergesort algorithm.
*
* @param list the list to sort
* @param n the size of the list
* @param fn the comparison function for determining order
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n,
alpm_list_fn_cmp fn)
{
@ -255,6 +319,15 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n,
return list;
}
/**
* @brief Remove an item from the list.
* item is not freed; this is the responsibility of the caller.
*
* @param haystack the list to remove the item from
* @param item the item to remove from the list
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,
alpm_list_t *item)
{
@ -292,6 +365,17 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,
return haystack;
}
/**
* @brief Remove an item from the list.
*
* @param haystack the list to remove the item from
* @param needle the data member of the item we're removing
* @param fn the comparison function for searching
* @param data output parameter containing data of the removed item
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
const void *needle, alpm_list_fn_cmp fn, void **data)
{
@ -326,6 +410,15 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
return haystack;
}
/**
* @brief Remove a string from a list.
*
* @param haystack the list to remove the item from
* @param needle the data member of the item we're removing
* @param data output parameter containing data of the removed item
*
* @return the resultant list
*/
alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack,
const char *needle, char **data)
{
@ -333,50 +426,74 @@ alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack,
(alpm_list_fn_cmp)strcmp, (void **)data);
}
/**
* @brief Create a new list without any duplicates.
*
* This does NOT copy data members.
*
* @param list the list to copy
*
* @return a new list containing non-duplicate items
*/
alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list)
{
const alpm_list_t *lp = list;
alpm_list_t *newlist = NULL;
while(lp) {
if(!alpm_list_find_ptr(newlist, lp->data)) {
if(alpm_list_append(&newlist, lp->data) == NULL) {
alpm_list_free(newlist);
return NULL;
}
newlist = alpm_list_add(newlist, lp->data);
}
lp = lp->next;
}
return newlist;
}
/**
* @brief Copy a string list, including data.
*
* @param list the list to copy
*
* @return a copy of the original list
*/
alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list)
{
const alpm_list_t *lp = list;
alpm_list_t *newlist = NULL;
while(lp) {
if(alpm_list_append_strdup(&newlist, lp->data) == NULL) {
FREELIST(newlist);
return NULL;
}
newlist = alpm_list_add(newlist, strdup(lp->data));
lp = lp->next;
}
return newlist;
}
/**
* @brief Copy a list, without copying data.
*
* @param list the list to copy
*
* @return a copy of the original list
*/
alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list)
{
const alpm_list_t *lp = list;
alpm_list_t *newlist = NULL;
while(lp) {
if(alpm_list_append(&newlist, lp->data) == NULL) {
alpm_list_free(newlist);
return NULL;
}
newlist = alpm_list_add(newlist, lp->data);
lp = lp->next;
}
return newlist;
}
/**
* @brief Copy a list and copy the data.
* Note that the data elements to be copied should not contain pointers
* and should also be of constant size.
*
* @param list the list to copy
* @param size the size of each data element
*
* @return a copy of the original list, data copied as well
*/
alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
size_t size)
{
@ -386,20 +503,20 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
void *newdata = malloc(size);
if(newdata) {
memcpy(newdata, lp->data, size);
if(alpm_list_append(&newlist, newdata) == NULL) {
free(newdata);
FREELIST(newlist);
return NULL;
}
newlist = alpm_list_add(newlist, newdata);
lp = lp->next;
} else {
FREELIST(newlist);
return NULL;
}
}
return newlist;
}
/**
* @brief Create a new list in reverse order.
*
* @param list the list to copy
*
* @return a new list in reverse order
*/
alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
{
const alpm_list_t *lp;
@ -415,11 +532,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
list->prev = NULL;
while(lp) {
if(alpm_list_append(&newlist, lp->data) == NULL) {
alpm_list_free(newlist);
list->prev = backup;
return NULL;
}
newlist = alpm_list_add(newlist, lp->data);
lp = lp->prev;
}
list->prev = backup; /* restore tail pointer */
@ -428,6 +541,14 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
/* Accessors */
/**
* @brief Return nth element from list (starting from 0).
*
* @param list the list
* @param n the index of the item to find (n < alpm_list_count(list) IS needed)
*
* @return an alpm_list_t node for index `n`
*/
alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n)
{
const alpm_list_t *i = list;
@ -437,6 +558,13 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n)
return (alpm_list_t *)i;
}
/**
* @brief Get the next element of a list.
*
* @param node the list node
*
* @return the next element, or NULL when no more elements exist
*/
inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
{
if(node) {
@ -446,6 +574,13 @@ inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
}
}
/**
* @brief Get the previous element of a list.
*
* @param list the list head
*
* @return the previous element, or NULL when no previous element exist
*/
inline alpm_list_t SYMEXPORT *alpm_list_previous(const alpm_list_t *list)
{
if(list && list->prev->next) {
@ -455,6 +590,13 @@ inline alpm_list_t SYMEXPORT *alpm_list_previous(const alpm_list_t *list)
}
}
/**
* @brief Get the last item in the list.
*
* @param list the list
*
* @return the last element in the list
*/
alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)
{
if(list) {
@ -466,6 +608,13 @@ alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)
/* Misc */
/**
* @brief Get the number of items in a list.
*
* @param list the list
*
* @return the number of list items
*/
size_t SYMEXPORT alpm_list_count(const alpm_list_t *list)
{
size_t i = 0;
@ -477,6 +626,15 @@ size_t SYMEXPORT alpm_list_count(const alpm_list_t *list)
return i;
}
/**
* @brief Find an item in a list.
*
* @param needle the item to search
* @param haystack the list
* @param fn the comparison function for searching (!= NULL)
*
* @return `needle` if found, NULL otherwise
*/
void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle,
alpm_list_fn_cmp fn)
{
@ -496,12 +654,30 @@ static int ptr_cmp(const void *p, const void *q)
return (p != q);
}
/**
* @brief Find an item in a list.
*
* Search for the item whose data matches that of the `needle`.
*
* @param needle the data to search for (== comparison)
* @param haystack the list
*
* @return `needle` if found, NULL otherwise
*/
void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack,
const void *needle)
{
return alpm_list_find(haystack, needle, ptr_cmp);
}
/**
* @brief Find a string in a list.
*
* @param needle the string to search for
* @param haystack the list
*
* @return `needle` if found, NULL otherwise
*/
char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack,
const char *needle)
{
@ -509,63 +685,20 @@ char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack,
(alpm_list_fn_cmp)strcmp);
}
int SYMEXPORT alpm_list_cmp_unsorted(const alpm_list_t *left,
const alpm_list_t *right, alpm_list_fn_cmp fn)
{
const alpm_list_t *l = left;
const alpm_list_t *r = right;
int *matched;
/* short circuiting length comparison */
while(l && r) {
l = l->next;
r = r->next;
}
if(l || r) {
return 0;
}
/* faster comparison for if the lists happen to be in the same order */
while(left && fn(left->data, right->data) == 0) {
left = left->next;
right = right->next;
}
if(!left) {
return 1;
}
matched = calloc(alpm_list_count(right), sizeof(int));
if(matched == NULL) {
return -1;
}
for(l = left; l; l = l->next) {
int found = 0;
int n = 0;
for(r = right; r; r = r->next, n++) {
/* make sure we don't match the same value twice */
if(matched[n]) {
continue;
}
if(fn(l->data, r->data) == 0) {
found = 1;
matched[n] = 1;
break;
}
}
if(!found) {
free(matched);
return 0;
}
}
free(matched);
return 1;
}
/**
* @brief Find the differences between list `left` and list `right`
*
* The two lists must be sorted. Items only in list `left` are added to the
* `onlyleft` list. Items only in list `right` are added to the `onlyright`
* list.
*
* @param left the first list
* @param right the second list
* @param fn the comparison function
* @param onlyleft pointer to the first result list
* @param onlyright pointer to the second result list
*
*/
void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left,
const alpm_list_t *right, alpm_list_fn_cmp fn,
alpm_list_t **onlyleft, alpm_list_t **onlyright)
@ -610,6 +743,15 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left,
}
/**
* @brief Find the items in list `lhs` that are not present in list `rhs`.
*
* @param lhs the first list
* @param rhs the second list
* @param fn the comparison function
*
* @return a list containing all items in `lhs` not present in `rhs`
*/
alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs,
const alpm_list_t *rhs, alpm_list_fn_cmp fn)
{
@ -628,6 +770,17 @@ alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs,
return ret;
}
/**
* @brief Copy a list and data into a standard C array of fixed length.
* Note that the data elements are shallow copied so any contained pointers
* will point to the original data.
*
* @param list the list to copy
* @param n the size of the list
* @param size the size of each data element
*
* @return an array version of the original list, data copied as well
*/
void SYMEXPORT *alpm_list_to_array(const alpm_list_t *list, size_t n,
size_t size)
{
@ -648,3 +801,7 @@ void SYMEXPORT *alpm_list_to_array(const alpm_list_t *list, size_t n,
}
return array;
}
/** @} */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* alpm_list.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -17,8 +17,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ALPM_LIST_H
#define ALPM_LIST_H
@ -33,363 +31,65 @@ extern "C" {
#endif
/**
* @ingroup libalpm
* @addtogroup libalpm_list libalpm_list(3)
* @brief Functions to manipulate alpm_list_t lists.
*
* These functions are designed to create, destroy, and modify lists of
* type alpm_list_t. This is an internal list type used by libalpm that is
* publicly exposed for use by frontends if desired.
* @brief Linked list type used by libalpm.
*
* It is exposed so front ends can use it to prevent the need to reimplement
* lists of their own; however, it is not required that the front end uses
* it.
* @{
*/
/** A doubly linked list */
typedef struct _alpm_list_t {
typedef struct __alpm_list_t {
/** data held by the list node */
void *data;
/** pointer to the previous node */
struct _alpm_list_t *prev;
struct __alpm_list_t *prev;
/** pointer to the next node */
struct _alpm_list_t *next;
struct __alpm_list_t *next;
} alpm_list_t;
/** Frees a list and its contents */
#define FREELIST(p) do { alpm_list_free_inner(p, free); alpm_list_free(p); p = NULL; } while(0)
/** item deallocation callback.
* @param item the item to free
*/
typedef void (*alpm_list_fn_free)(void * item);
/** item comparison callback */
typedef int (*alpm_list_fn_cmp)(const void *, const void *);
typedef void (*alpm_list_fn_free)(void *); /* item deallocation callback */
typedef int (*alpm_list_fn_cmp)(const void *, const void *); /* item comparison callback */
/* allocation */
/** Free a list, but not the contained data.
*
* @param list the list to free
*/
void alpm_list_free(alpm_list_t *list);
/** Free the internal data of a list structure but not the list itself.
*
* @param list the list to free
* @param fn a free function for the internal data
*/
void alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn);
/* item mutators */
/** Add a new item to the end of the list.
*
* @param list the list to add to
* @param data the new item to be added to the list
*
* @return the resultant list
*/
alpm_list_t *alpm_list_add(alpm_list_t *list, void *data);
/**
* @brief Add a new item to the end of the list.
*
* @param list the list to add to
* @param data the new item to be added to the list
*
* @return the newly added item
*/
alpm_list_t *alpm_list_append(alpm_list_t **list, void *data);
/**
* @brief Duplicate and append a string to a list.
*
* @param list the list to append to
* @param data the string to duplicate and append
*
* @return the newly added item
*/
alpm_list_t *alpm_list_append_strdup(alpm_list_t **list, const char *data);
/**
* @brief Add items to a list in sorted order.
*
* @param list the list to add to
* @param data the new item to be added to the list
* @param fn the comparison function to use to determine order
*
* @return the resultant list
*/
alpm_list_t *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn);
/**
* @brief Join two lists.
* The two lists must be independent. Do not free the original lists after
* calling this function, as this is not a copy operation. The list pointers
* passed in should be considered invalid after calling this function.
*
* @param first the first list
* @param second the second list
*
* @return the resultant joined list
*/
alpm_list_t *alpm_list_join(alpm_list_t *first, alpm_list_t *second);
/**
* @brief Merge the two sorted sublists into one sorted list.
*
* @param left the first list
* @param right the second list
* @param fn comparison function for determining merge order
*
* @return the resultant list
*/
alpm_list_t *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn);
/**
* @brief Sort a list of size `n` using mergesort algorithm.
*
* @param list the list to sort
* @param n the size of the list
* @param fn the comparison function for determining order
*
* @return the resultant list
*/
alpm_list_t *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn);
/**
* @brief Remove an item from the list.
* item is not freed; this is the responsibility of the caller.
*
* @param haystack the list to remove the item from
* @param item the item to remove from the list
*
* @return the resultant list
*/
alpm_list_t *alpm_list_remove_item(alpm_list_t *haystack, alpm_list_t *item);
/**
* @brief Remove an item from the list.
*
* @param haystack the list to remove the item from
* @param needle the data member of the item we're removing
* @param fn the comparison function for searching
* @param data output parameter containing data of the removed item
*
* @return the resultant list
*/
alpm_list_t *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn, void **data);
/**
* @brief Remove a string from a list.
*
* @param haystack the list to remove the item from
* @param needle the data member of the item we're removing
* @param data output parameter containing data of the removed item
*
* @return the resultant list
*/
alpm_list_t *alpm_list_remove_str(alpm_list_t *haystack, const char *needle, char **data);
/**
* @brief Create a new list without any duplicates.
*
* This does NOT copy data members.
*
* @param list the list to copy
*
* @return a new list containing non-duplicate items
*/
alpm_list_t *alpm_list_remove_dupes(const alpm_list_t *list);
/**
* @brief Copy a string list, including data.
*
* @param list the list to copy
*
* @return a copy of the original list
*/
alpm_list_t *alpm_list_strdup(const alpm_list_t *list);
/**
* @brief Copy a list, without copying data.
*
* @param list the list to copy
*
* @return a copy of the original list
*/
alpm_list_t *alpm_list_copy(const alpm_list_t *list);
/**
* @brief Copy a list and copy the data.
* Note that the data elements to be copied should not contain pointers
* and should also be of constant size.
*
* @param list the list to copy
* @param size the size of each data element
*
* @return a copy of the original list, data copied as well
*/
alpm_list_t *alpm_list_copy_data(const alpm_list_t *list, size_t size);
/**
* @brief Create a new list in reverse order.
*
* @param list the list to copy
*
* @return a new list in reverse order
*/
alpm_list_t *alpm_list_reverse(alpm_list_t *list);
/* item accessors */
/**
* @brief Return nth element from list (starting from 0).
*
* @param list the list
* @param n the index of the item to find (n < alpm_list_count(list) IS needed)
*
* @return an alpm_list_t node for index `n`
*/
alpm_list_t *alpm_list_nth(const alpm_list_t *list, size_t n);
/**
* @brief Get the next element of a list.
*
* @param list the list node
*
* @return the next element, or NULL when no more elements exist
*/
alpm_list_t *alpm_list_next(const alpm_list_t *list);
/**
* @brief Get the previous element of a list.
*
* @param list the list head
*
* @return the previous element, or NULL when no previous element exist
*/
alpm_list_t *alpm_list_previous(const alpm_list_t *list);
/**
* @brief Get the last item in the list.
*
* @param list the list
*
* @return the last element in the list
*/
alpm_list_t *alpm_list_last(const alpm_list_t *list);
/* misc */
/**
* @brief Get the number of items in a list.
*
* @param list the list
*
* @return the number of list items
*/
size_t alpm_list_count(const alpm_list_t *list);
/**
* @brief Find an item in a list.
*
* @param needle the item to search
* @param haystack the list
* @param fn the comparison function for searching (!= NULL)
*
* @return `needle` if found, NULL otherwise
*/
void *alpm_list_find(const alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn);
/**
* @brief Find an item in a list.
*
* Search for the item whose data matches that of the `needle`.
*
* @param needle the data to search for (== comparison)
* @param haystack the list
*
* @return `needle` if found, NULL otherwise
*/
void *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle);
/**
* @brief Find a string in a list.
*
* @param needle the string to search for
* @param haystack the list
*
* @return `needle` if found, NULL otherwise
*/
char *alpm_list_find_str(const alpm_list_t *haystack, const char *needle);
/**
* @brief Check if two lists contain the same data, ignoring order.
*
* Lists are considered equal if they both contain the same data regardless
* of order.
*
* @param left the first list
* @param right the second list
* @param fn the comparison function
*
* @return 1 if the lists are equal, 0 if not equal, -1 on error.
*/
int alpm_list_cmp_unsorted(const alpm_list_t *left,
const alpm_list_t *right, alpm_list_fn_cmp fn);
/**
* @brief Find the differences between list `left` and list `right`
*
* The two lists must be sorted. Items only in list `left` are added to the
* `onlyleft` list. Items only in list `right` are added to the `onlyright`
* list.
*
* @param left the first list
* @param right the second list
* @param fn the comparison function
* @param onlyleft pointer to the first result list
* @param onlyright pointer to the second result list
*
*/
alpm_list_t *alpm_list_diff(const alpm_list_t *lhs, const alpm_list_t *rhs, alpm_list_fn_cmp fn);
void alpm_list_diff_sorted(const alpm_list_t *left, const alpm_list_t *right,
alpm_list_fn_cmp fn, alpm_list_t **onlyleft, alpm_list_t **onlyright);
/**
* @brief Find the items in list `lhs` that are not present in list `rhs`.
*
* @param lhs the first list
* @param rhs the second list
* @param fn the comparison function
*
* @return a list containing all items in `lhs` not present in `rhs`
*/
alpm_list_t *alpm_list_diff(const alpm_list_t *lhs, const alpm_list_t *rhs, alpm_list_fn_cmp fn);
/**
* @brief Copy a list and data into a standard C array of fixed length.
* Note that the data elements are shallow copied so any contained pointers
* will point to the original data.
*
* @param list the list to copy
* @param n the size of the list
* @param size the size of each data element
*
* @return an array version of the original list, data copied as well
*/
void *alpm_list_to_array(const alpm_list_t *list, size_t n, size_t size);
/* End of alpm_list */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ALPM_LIST_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* backup.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2005 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
@ -98,3 +98,5 @@ error:
free(newbackup);
return NULL;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* backup.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -29,3 +29,5 @@ void _alpm_backup_free(alpm_backup_t *backup);
alpm_backup_t *_alpm_backup_dup(const alpm_backup_t *backup);
#endif /* ALPM_BACKUP_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* be_local.c : backend for the local database
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -47,9 +47,9 @@
/* local database format version */
size_t ALPM_LOCAL_DB_VERSION = 9;
static int local_db_read(alpm_pkg_t *info, int inforeq);
static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq);
#define LAZY_LOAD(info) \
#define LAZY_LOAD(info, errret) \
do { \
if(!(pkg->infolevel & info)) { \
local_db_read(pkg, info); \
@ -65,142 +65,124 @@ static int local_db_read(alpm_pkg_t *info, int inforeq);
static const char *_cache_get_base(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->base;
}
static const char *_cache_get_desc(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->desc;
}
static const char *_cache_get_url(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->url;
}
static alpm_time_t _cache_get_builddate(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, 0);
return pkg->builddate;
}
static alpm_time_t _cache_get_installdate(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, 0);
return pkg->installdate;
}
static const char *_cache_get_packager(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->packager;
}
static const char *_cache_get_arch(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->arch;
}
static off_t _cache_get_isize(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, -1);
return pkg->isize;
}
static alpm_pkgreason_t _cache_get_reason(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, -1);
return pkg->reason;
}
static int _cache_get_validation(alpm_pkg_t *pkg)
static alpm_pkgvalidation_t _cache_get_validation(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, -1);
return pkg->validation;
}
static alpm_list_t *_cache_get_licenses(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->licenses;
}
static alpm_list_t *_cache_get_groups(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->groups;
}
static int _cache_has_scriptlet(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_SCRIPTLET);
LAZY_LOAD(INFRQ_SCRIPTLET, NULL);
return pkg->scriptlet;
}
static alpm_list_t *_cache_get_depends(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->depends;
}
static alpm_list_t *_cache_get_optdepends(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->optdepends;
}
static alpm_list_t *_cache_get_makedepends(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
return pkg->makedepends;
}
static alpm_list_t *_cache_get_checkdepends(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
return pkg->checkdepends;
}
static alpm_list_t *_cache_get_conflicts(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->conflicts;
}
static alpm_list_t *_cache_get_provides(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->provides;
}
static alpm_list_t *_cache_get_replaces(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
LAZY_LOAD(INFRQ_DESC, NULL);
return pkg->replaces;
}
static alpm_filelist_t *_cache_get_files(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_FILES);
LAZY_LOAD(INFRQ_FILES, NULL);
return &(pkg->files);
}
static alpm_list_t *_cache_get_backup(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_FILES);
LAZY_LOAD(INFRQ_FILES, NULL);
return pkg->backup;
}
static alpm_list_t *_cache_get_xdata(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
return pkg->xdata;
}
/**
* Open a package changelog for reading. Similar to fopen in functionality,
* except that the returned 'file stream' is from the database.
@ -250,6 +232,7 @@ static int _cache_changelog_close(const alpm_pkg_t UNUSED *pkg, void *fp)
*/
static struct archive *_cache_mtree_open(alpm_pkg_t *pkg)
{
int r;
struct archive *mtree;
alpm_db_t *db = alpm_pkg_get_db(pkg);
@ -261,17 +244,19 @@ static struct archive *_cache_mtree_open(alpm_pkg_t *pkg)
}
if((mtree = archive_read_new()) == NULL) {
GOTO_ERR(pkg->handle, ALPM_ERR_LIBARCHIVE, error);
pkg->handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
_alpm_archive_read_support_filter_all(mtree);
archive_read_support_format_mtree(mtree);
if(_alpm_archive_read_open_file(mtree, mtfile, ALPM_BUFFER_SIZE)) {
if((r = _alpm_archive_read_open_file(mtree, mtfile, ALPM_BUFFER_SIZE))) {
_alpm_log(pkg->handle, ALPM_LOG_ERROR, _("error while reading file %s: %s\n"),
mtfile, archive_error_string(mtree));
pkg->handle->pm_errno = ALPM_ERR_LIBARCHIVE;
_alpm_archive_read_free(mtree);
GOTO_ERR(pkg->handle, ALPM_ERR_LIBARCHIVE, error);
goto error;
}
free(mtfile);
@ -287,26 +272,12 @@ error:
* @param pkg the package that the mtree file is being read from
* @param archive the archive structure reading from the mtree file
* @param entry an archive_entry to store the entry header information
* @return 0 on success, 1 if end of archive is reached, -1 otherwise.
* @return 0 if end of archive is reached, non-zero otherwise.
*/
static int _cache_mtree_next(const alpm_pkg_t UNUSED *pkg,
struct archive *mtree, struct archive_entry **entry)
{
int ret;
ret = archive_read_next_header(mtree, entry);
switch(ret) {
case ARCHIVE_OK:
return 0;
break;
case ARCHIVE_EOF:
return 1;
break;
default:
break;
}
return -1;
return archive_read_next_header(mtree, entry);
}
/**
@ -331,40 +302,37 @@ static int _cache_force_load(alpm_pkg_t *pkg)
* lazy accessor methods that handle any backend loading and caching
* logic.
*/
static const struct pkg_operations local_pkg_ops = {
.get_base = _cache_get_base,
.get_desc = _cache_get_desc,
.get_url = _cache_get_url,
.get_builddate = _cache_get_builddate,
static struct pkg_operations local_pkg_ops = {
.get_base = _cache_get_base,
.get_desc = _cache_get_desc,
.get_url = _cache_get_url,
.get_builddate = _cache_get_builddate,
.get_installdate = _cache_get_installdate,
.get_packager = _cache_get_packager,
.get_arch = _cache_get_arch,
.get_isize = _cache_get_isize,
.get_reason = _cache_get_reason,
.get_validation = _cache_get_validation,
.has_scriptlet = _cache_has_scriptlet,
.get_licenses = _cache_get_licenses,
.get_groups = _cache_get_groups,
.get_depends = _cache_get_depends,
.get_optdepends = _cache_get_optdepends,
.get_makedepends = _cache_get_makedepends,
.get_checkdepends = _cache_get_checkdepends,
.get_conflicts = _cache_get_conflicts,
.get_provides = _cache_get_provides,
.get_replaces = _cache_get_replaces,
.get_files = _cache_get_files,
.get_backup = _cache_get_backup,
.get_xdata = _cache_get_xdata,
.get_packager = _cache_get_packager,
.get_arch = _cache_get_arch,
.get_isize = _cache_get_isize,
.get_reason = _cache_get_reason,
.get_validation = _cache_get_validation,
.has_scriptlet = _cache_has_scriptlet,
.get_licenses = _cache_get_licenses,
.get_groups = _cache_get_groups,
.get_depends = _cache_get_depends,
.get_optdepends = _cache_get_optdepends,
.get_conflicts = _cache_get_conflicts,
.get_provides = _cache_get_provides,
.get_replaces = _cache_get_replaces,
.get_files = _cache_get_files,
.get_backup = _cache_get_backup,
.changelog_open = _cache_changelog_open,
.changelog_read = _cache_changelog_read,
.changelog_open = _cache_changelog_open,
.changelog_read = _cache_changelog_read,
.changelog_close = _cache_changelog_close,
.mtree_open = _cache_mtree_open,
.mtree_next = _cache_mtree_next,
.mtree_close = _cache_mtree_close,
.mtree_open = _cache_mtree_open,
.mtree_next = _cache_mtree_next,
.mtree_close = _cache_mtree_close,
.force_load = _cache_force_load,
.force_load = _cache_force_load,
};
static int checkdbdir(alpm_db_t *db)
@ -630,17 +598,10 @@ static int local_db_populate(alpm_db_t *db)
continue;
}
/* treat local metadata errors as warning-only,
* they are already installed and otherwise they can't be operated on */
_alpm_pkg_check_meta(pkg);
/* add to the collection */
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename);
if(_alpm_pkghash_add(&db->pkgcache, pkg) == NULL) {
_alpm_pkg_free(pkg);
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
}
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);
count++;
}
@ -654,17 +615,6 @@ static int local_db_populate(alpm_db_t *db)
return 0;
}
static alpm_pkgreason_t _read_pkgreason(alpm_handle_t *handle, const char *pkgname, const char *line) {
if(strcmp(line, "0") == 0) {
return ALPM_PKG_REASON_EXPLICIT;
} else if(strcmp(line, "1") == 0) {
return ALPM_PKG_REASON_DEPEND;
} else {
_alpm_log(handle, ALPM_LOG_ERROR, _("unknown install reason for package %s: %s\n"), pkgname, line);
return ALPM_PKG_REASON_UNKNOWN;
}
}
/* Note: the return value must be freed by the caller */
char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
const char *filename)
@ -677,7 +627,7 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3;
len += filename ? strlen(filename) : 0;
MALLOC(pkgpath, len, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
snprintf(pkgpath, len, "%s%s-%s/%s", dbpath, info->name, info->version,
sprintf(pkgpath, "%s%s-%s/%s", dbpath, info->name, info->version,
filename ? filename : "");
return pkgpath;
}
@ -710,10 +660,10 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
f = alpm_list_add(f, alpm_dep_from_string(line)); \
} while(1) /* note the while(1) and not (0) */
static int local_db_read(alpm_pkg_t *info, int inforeq)
static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
{
FILE *fp = NULL;
char line[1024] = {0};
char line[1024];
alpm_db_t *db = info->origin_data.db;
/* bitmask logic here:
@ -736,6 +686,9 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
"loading package data for %s : level=0x%x\n",
info->name, inforeq);
/* clear out 'line', to be certain - and to make valgrind happy */
memset(line, 0, sizeof(line));
/* DESC */
if(inforeq & INFRQ_DESC && !(info->infolevel & INFRQ_DESC)) {
char *path = _alpm_local_db_pkgpath(db, info, "desc");
@ -787,7 +740,7 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
READ_AND_STORE(info->packager);
} else if(strcmp(line, "%REASON%") == 0) {
READ_NEXT();
info->reason = _read_pkgreason(db->handle, info->name, line);
info->reason = (alpm_pkgreason_t)atoi(line);
} else if(strcmp(line, "%VALIDATION%") == 0) {
alpm_list_t *i, *v = NULL;
READ_AND_STORE_ALL(v);
@ -817,31 +770,10 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
READ_AND_SPLITDEP(info->depends);
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
READ_AND_SPLITDEP(info->optdepends);
} else if(strcmp(line, "%MAKEDEPENDS%") == 0) {
READ_AND_SPLITDEP(info->makedepends);
} else if(strcmp(line, "%CHECKDEPENDS%") == 0) {
READ_AND_SPLITDEP(info->checkdepends);
} else if(strcmp(line, "%CONFLICTS%") == 0) {
READ_AND_SPLITDEP(info->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
READ_AND_SPLITDEP(info->provides);
} else if(strcmp(line, "%XDATA%") == 0) {
alpm_list_t *i, *lines = NULL;
READ_AND_STORE_ALL(lines);
for(i = lines; i; i = i->next) {
alpm_pkg_xdata_t *pd = _alpm_pkg_parse_xdata(i->data);
if(pd == NULL || !alpm_list_append(&info->xdata, pd)) {
_alpm_pkg_xdata_free(pd);
FREELIST(lines);
goto error;
}
}
FREELIST(lines);
} else {
_alpm_log(db->handle, ALPM_LOG_WARNING, _("%s: unknown key '%s' in local database\n"), info->name, line);
alpm_list_t *lines = NULL;
READ_AND_STORE_ALL(lines);
FREELIST(lines);
}
}
fclose(fp);
@ -879,13 +811,20 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
}
/* attempt to hand back any memory we don't need */
if(files_count > 0) {
REALLOC(files, sizeof(alpm_file_t) * files_count, (void)0);
alpm_file_t *newfiles;
newfiles = realloc(files, sizeof(alpm_file_t) * files_count);
if(newfiles != NULL) {
files = newfiles;
}
/* make sure the list is sorted */
qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp);
} else {
FREE(files);
}
info->files.count = files_count;
info->files.files = files;
_alpm_filelist_sort(&info->files);
continue;
nomem:
while(files_count > 0) {
@ -971,7 +910,7 @@ static void write_deps(FILE *fp, const char *header, alpm_list_t *deplist)
fputc('\n', fp);
}
int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq)
int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
{
FILE *fp = NULL;
mode_t oldmask;
@ -1078,15 +1017,6 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq)
write_deps(fp, "%CONFLICTS%", info->conflicts);
write_deps(fp, "%PROVIDES%", info->provides);
if(info->xdata) {
fputs("%XDATA%\n", fp);
for(lp = info->xdata; lp; lp = lp->next) {
alpm_pkg_xdata_t *pd = lp->data;
fprintf(fp, "%s=%s\n", pd->name, pd->value);
}
fputc('\n', fp);
}
fclose(fp);
fp = NULL;
}
@ -1164,7 +1094,7 @@ int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info)
/* file path is too long to remove, hmm. */
ret = -1;
} else {
snprintf(name, PATH_MAX, "%s/%s", pkgpath, dp->d_name);
sprintf(name, "%s/%s", pkgpath, dp->d_name);
if(unlink(name)) {
ret = -1;
}
@ -1205,7 +1135,7 @@ int SYMEXPORT alpm_pkg_set_reason(alpm_pkg_t *pkg, alpm_pkgreason_t reason)
return 0;
}
static const struct db_operations local_db_ops = {
struct db_operations local_db_ops = {
.validate = local_db_validate,
.populate = local_db_populate,
.unregister = _alpm_db_unregister,
@ -1235,3 +1165,5 @@ alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle)
handle->db_local = db;
return db;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* be_package.c : backend for packages
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -134,10 +134,11 @@ static int _package_changelog_close(const alpm_pkg_t UNUSED *pkg, void *fp)
}
/** Package file operations struct accessor. We implement this as a method
* because we want to reuse the majority of the default_pkg_ops struct and
* add only a few operations of our own on top.
* rather than a static struct as in be_files because we want to reuse the
* majority of the default_pkg_ops struct and add only a few operations of
* our own on top.
*/
static const struct pkg_operations *get_file_pkg_ops(void)
static struct pkg_operations *get_file_pkg_ops(void)
{
static struct pkg_operations file_pkg_ops;
static int file_pkg_ops_initialized = 0;
@ -163,8 +164,9 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
char *ptr = NULL;
char *key = NULL;
int ret, linenum = 0;
struct archive_read_buffer buf = {0};
struct archive_read_buffer buf;
memset(&buf, 0, sizeof(buf));
/* 512K for a line length seems reasonable */
buf.max_line_size = 512 * 1024;
@ -200,15 +202,11 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
} else if(strcmp(key, "pkgdesc") == 0) {
STRDUP(newpkg->desc, ptr, return -1);
} else if(strcmp(key, "group") == 0) {
char *tmp = NULL;
STRDUP(tmp, ptr, return -1);
newpkg->groups = alpm_list_add(newpkg->groups, tmp);
newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr));
} else if(strcmp(key, "url") == 0) {
STRDUP(newpkg->url, ptr, return -1);
} else if(strcmp(key, "license") == 0) {
char *tmp = NULL;
STRDUP(tmp, ptr, return -1);
newpkg->licenses = alpm_list_add(newpkg->licenses, tmp);
newpkg->licenses = alpm_list_add(newpkg->licenses, strdup(ptr));
} else if(strcmp(key, "builddate") == 0) {
newpkg->builddate = _alpm_parsedate(ptr);
} else if(strcmp(key, "packager") == 0) {
@ -225,11 +223,9 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
alpm_depend_t *optdep = alpm_dep_from_string(ptr);
newpkg->optdepends = alpm_list_add(newpkg->optdepends, optdep);
} else if(strcmp(key, "makedepend") == 0) {
alpm_depend_t *makedep = alpm_dep_from_string(ptr);
newpkg->makedepends = alpm_list_add(newpkg->makedepends, makedep);
/* not used atm */
} else if(strcmp(key, "checkdepend") == 0) {
alpm_depend_t *checkdep = alpm_dep_from_string(ptr);
newpkg->checkdepends = alpm_list_add(newpkg->checkdepends, checkdep);
/* not used atm */
} else if(strcmp(key, "conflict") == 0) {
alpm_depend_t *conflict = alpm_dep_from_string(ptr);
newpkg->conflicts = alpm_list_add(newpkg->conflicts, conflict);
@ -244,17 +240,13 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
CALLOC(backup, 1, sizeof(alpm_backup_t), return -1);
STRDUP(backup->name, ptr, FREE(backup); return -1);
newpkg->backup = alpm_list_add(newpkg->backup, backup);
} else if(strcmp(key, "xdata") == 0) {
alpm_pkg_xdata_t *pd = _alpm_pkg_parse_xdata(ptr);
if(pd == NULL || !alpm_list_append(&newpkg->xdata, pd)) {
_alpm_pkg_xdata_free(pd);
return -1;
}
} else if(strcmp(key, "force") == 0) {
/* deprecated, skip it */
} else if(strcmp(key, "makepkgopt") == 0) {
/* not used atm */
} else {
const char *pkgname = newpkg->name ? newpkg->name : "error";
_alpm_log(handle, ALPM_LOG_WARNING, _("%s: unknown key '%s' in package description\n"), pkgname, key);
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: unknown key '%s' in description file line %d\n",
pkgname, key, linenum);
newpkg->name ? newpkg->name : "error", key, linenum);
}
}
}
@ -278,11 +270,11 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
* @return 0 if package is fully valid, -1 and pm_errno otherwise
*/
int _alpm_pkg_validate_internal(alpm_handle_t *handle,
const char *pkgfile, alpm_pkg_t *syncpkg, int level,
alpm_siglist_t **sigdata, int *validation)
const char *pkgfile, alpm_pkg_t *syncpkg, alpm_siglevel_t level,
alpm_siglist_t **sigdata, alpm_pkgvalidation_t *validation)
{
int has_sig;
handle->pm_errno = ALPM_ERR_OK;
handle->pm_errno = 0;
if(pkgfile == NULL || strlen(pkgfile) == 0) {
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
@ -314,7 +306,7 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle,
}
}
if(syncpkg && (!has_sig || !syncpkg->base64_sig)) {
if(syncpkg && !has_sig) {
if(syncpkg->md5sum && !syncpkg->sha256sum) {
_alpm_log(handle, ALPM_LOG_DEBUG, "md5sum: %s\n", syncpkg->md5sum);
_alpm_log(handle, ALPM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile);
@ -454,15 +446,18 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
char *mtree_data = NULL;
struct archive *mtree;
struct archive_entry *mtree_entry = NULL;
alpm_filelist_t filelist = {0};
alpm_filelist_t filelist;
_alpm_log(handle, ALPM_LOG_DEBUG,
"found mtree for package %s, getting file list\n", pkg->filename);
memset(&filelist, 0, sizeof(alpm_filelist_t));
/* create a new archive to parse the mtree and load it from archive into memory */
/* TODO: split this into a function */
if((mtree = archive_read_new()) == NULL) {
GOTO_ERR(handle, ALPM_ERR_LIBARCHIVE, error);
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
_alpm_archive_read_support_filter_all(mtree);
@ -481,7 +476,8 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
if(size < 0) {
_alpm_log(handle, ALPM_LOG_DEBUG, _("error while reading package %s: %s\n"),
pkg->filename, archive_error_string(archive));
GOTO_ERR(handle, ALPM_ERR_LIBARCHIVE, error);
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
if(size == 0) {
break;
@ -494,7 +490,8 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
_alpm_log(handle, ALPM_LOG_DEBUG,
_("error while reading mtree of package %s: %s\n"),
pkg->filename, archive_error_string(mtree));
GOTO_ERR(handle, ALPM_ERR_LIBARCHIVE, error);
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
while((ret = archive_read_next_header(mtree, &mtree_entry)) == ARCHIVE_OK) {
@ -517,7 +514,8 @@ static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, str
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occurred */
_alpm_log(handle, ALPM_LOG_DEBUG, _("error while reading mtree of package %s: %s\n"),
pkg->filename, archive_error_string(mtree));
GOTO_ERR(handle, ALPM_ERR_LIBARCHIVE, error);
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
/* throw away any files we loaded directly from the archive */
@ -582,9 +580,11 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
newpkg = _alpm_pkg_new();
if(newpkg == NULL) {
GOTO_ERR(handle, ALPM_ERR_MEMORY, error);
handle->pm_errno = ALPM_ERR_MEMORY;
goto error;
}
STRDUP(newpkg->filename, pkgfile, GOTO_ERR(handle, ALPM_ERR_MEMORY, error));
STRDUP(newpkg->filename, pkgfile,
handle->pm_errno = ALPM_ERR_MEMORY; goto error);
newpkg->size = st.st_size;
_alpm_log(handle, ALPM_LOG_DEBUG, "starting package load for %s\n", pkgfile);
@ -634,7 +634,8 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
if(archive_read_data_skip(archive)) {
_alpm_log(handle, ALPM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
GOTO_ERR(handle, ALPM_ERR_LIBARCHIVE, error);
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
/* if we are not doing a full read, see if we have all we need */
@ -646,7 +647,8 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occurred */
_alpm_log(handle, ALPM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
GOTO_ERR(handle, ALPM_ERR_LIBARCHIVE, error);
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
if(!config) {
@ -654,9 +656,12 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
goto pkg_invalid;
}
_alpm_archive_read_free(archive);
close(fd);
/* internal fields for package struct */
newpkg->origin = ALPM_PKG_FROM_FILE;
STRDUP(newpkg->origin_data.file, pkgfile, goto error);
newpkg->origin_data.file = strdup(pkgfile);
newpkg->ops = get_file_pkg_ops();
newpkg->handle = handle;
newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_SCRIPTLET;
@ -665,22 +670,18 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
if(full) {
if(newpkg->files.files) {
/* attempt to hand back any memory we don't need */
REALLOC(newpkg->files.files, sizeof(alpm_file_t) * newpkg->files.count, (void)0);
newpkg->files.files = realloc(newpkg->files.files,
sizeof(alpm_file_t) * newpkg->files.count);
/* "checking for conflicts" requires a sorted list, ensure that here */
_alpm_log(handle, ALPM_LOG_DEBUG,
"sorting package filelist for %s\n", pkgfile);
_alpm_filelist_sort(&newpkg->files);
qsort(newpkg->files.files, newpkg->files.count,
sizeof(alpm_file_t), _alpm_files_cmp);
}
newpkg->infolevel |= INFRQ_FILES;
}
if(_alpm_pkg_check_meta(newpkg) != 0) {
goto pkg_invalid;
}
_alpm_archive_read_free(archive);
close(fd);
return newpkg;
pkg_invalid:
@ -688,7 +689,9 @@ pkg_invalid:
error:
_alpm_pkg_free(newpkg);
_alpm_archive_read_free(archive);
close(fd);
if(fd >= 0) {
close(fd);
}
return NULL;
}
@ -723,11 +726,10 @@ static int read_sigfile(const char *sigpath, unsigned char **sig)
}
int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full,
int level, alpm_pkg_t **pkg)
alpm_siglevel_t level, alpm_pkg_t **pkg)
{
int validation = 0;
alpm_pkgvalidation_t validation = 0;
char *sigpath;
alpm_pkg_t *pkg_temp;
CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
@ -752,11 +754,9 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
for(k = keys; k; k = k->next) {
char *key = k->data;
if(_alpm_key_in_keychain(handle, key) == 0) {
pkg_temp = _alpm_pkg_load_internal(handle, filename, full);
if(_alpm_key_import(handle, NULL, key) == -1) {
if(_alpm_key_import(handle, key) == -1) {
fail = 1;
}
_alpm_pkg_free(pkg_temp);
}
}
FREELIST(keys);
@ -787,3 +787,5 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
return 0;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* be_sync.c : backend for sync databases
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -37,6 +37,7 @@
#include "alpm_list.h"
#include "package.h"
#include "handle.h"
#include "delta.h"
#include "deps.h"
#include "dload.h"
#include "filelist.h"
@ -48,7 +49,7 @@ static char *get_sync_dir(alpm_handle_t *handle)
struct stat buf;
MALLOC(syncpath, len, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
snprintf(syncpath, len, "%s%s", handle->dbpath, "sync/");
sprintf(syncpath, "%s%s", handle->dbpath, "sync/");
if(stat(syncpath, &buf) != 0) {
_alpm_log(handle, ALPM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
@ -70,7 +71,7 @@ static char *get_sync_dir(alpm_handle_t *handle)
static int sync_db_validate(alpm_db_t *db)
{
int siglevel;
alpm_siglevel_t level;
const char *dbpath;
if(db->status & DB_STATUS_VALID || db->status & DB_STATUS_MISSING) {
@ -103,20 +104,20 @@ static int sync_db_validate(alpm_db_t *db)
/* this takes into account the default verification level if UNKNOWN
* was assigned to this db */
siglevel = alpm_db_get_siglevel(db);
level = alpm_db_get_siglevel(db);
if(siglevel & ALPM_SIG_DATABASE) {
if(level & ALPM_SIG_DATABASE) {
int retry, ret;
do {
retry = 0;
alpm_siglist_t *siglist;
ret = _alpm_check_pgp_helper(db->handle, dbpath, NULL,
siglevel & ALPM_SIG_DATABASE_OPTIONAL, siglevel & ALPM_SIG_DATABASE_MARGINAL_OK,
siglevel & ALPM_SIG_DATABASE_UNKNOWN_OK, &siglist);
level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK,
level & ALPM_SIG_DATABASE_UNKNOWN_OK, &siglist);
if(ret) {
retry = _alpm_process_siglist(db->handle, db->treename, siglist,
siglevel & ALPM_SIG_DATABASE_OPTIONAL, siglevel & ALPM_SIG_DATABASE_MARGINAL_OK,
siglevel & ALPM_SIG_DATABASE_UNKNOWN_OK);
level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK,
level & ALPM_SIG_DATABASE_UNKNOWN_OK);
}
alpm_siglist_cleanup(siglist);
free(siglist);
@ -136,105 +137,178 @@ valid:
return 0;
}
int SYMEXPORT alpm_db_update(alpm_handle_t *handle, alpm_list_t *dbs, int force) {
/** Update a package database
*
* An update of the package database \a db will be attempted. Unless
* \a force is true, the update will only be performed if the remote
* database was modified since the last update.
*
* This operation requires a database lock, and will return an applicable error
* if the lock could not be obtained.
*
* Example:
* @code
* alpm_list_t *syncs = alpm_get_syncdbs();
* for(i = syncs; i; i = alpm_list_next(i)) {
* alpm_db_t *db = alpm_list_getdata(i);
* result = alpm_db_update(0, db);
*
* if(result < 0) {
* printf("Unable to update database: %s\n", alpm_strerrorlast());
* } else if(result == 1) {
* printf("Database already up to date\n");
* } else {
* printf("Database updated\n");
* }
* }
* @endcode
*
* @ingroup alpm_databases
* @note After a successful update, the \link alpm_db_get_pkgcache()
* package cache \endlink will be invalidated
* @param force if true, then forces the update, otherwise update only in case
* the database isn't up to date
* @param db pointer to the package database to update
* @return 0 on success, -1 on error (pm_errno is set accordingly), 1 if up to
* to date
*/
int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
{
char *syncpath;
char *temporary_syncpath;
const char *dbext = handle->dbext;
const char *dbext;
alpm_list_t *i;
int updated = 0;
int ret = -1;
mode_t oldmask;
alpm_list_t *payloads = NULL;
alpm_event_t event;
alpm_handle_t *handle;
alpm_siglevel_t level;
/* Sanity checks */
CHECK_HANDLE(handle, return -1);
ASSERT(dbs != NULL, return -1);
handle->pm_errno = ALPM_ERR_OK;
ASSERT(db != NULL, return -1);
handle = db->handle;
handle->pm_errno = 0;
ASSERT(db != handle->db_local, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
ASSERT(db->servers != NULL, RET_ERR(handle, ALPM_ERR_SERVER_NONE, -1));
if(!(db->usage & ALPM_DB_USAGE_SYNC)) {
return 0;
}
syncpath = get_sync_dir(handle);
ASSERT(syncpath != NULL, return -1);
temporary_syncpath = _alpm_temporary_download_dir_setup(syncpath, handle->sandboxuser);
ASSERT(temporary_syncpath != NULL, FREE(syncpath); return -1);
if(!syncpath) {
return -1;
}
/* force update of invalid databases to fix potential mismatched database/signature */
if(db->status & DB_STATUS_INVALID) {
force = 1;
}
/* make sure we have a sane umask */
oldmask = umask(0022);
level = alpm_db_get_siglevel(db);
/* attempt to grab a lock */
if(_alpm_handle_lock(handle)) {
GOTO_ERR(handle, ALPM_ERR_HANDLE_LOCK, cleanup);
free(syncpath);
umask(oldmask);
RET_ERR(handle, ALPM_ERR_HANDLE_LOCK, -1);
}
for(i = dbs; i; i = i->next) {
alpm_db_t *db = i->data;
int dbforce = force;
struct dload_payload *payload = NULL;
dbext = db->handle->dbext;
for(i = db->servers; i; i = i->next) {
const char *server = i->data, *final_db_url = NULL;
struct dload_payload payload;
size_t len;
int siglevel;
int sig_ret = 0;
if(!(db->usage & ALPM_DB_USAGE_SYNC)) {
continue;
}
memset(&payload, 0, sizeof(struct dload_payload));
ASSERT(db != handle->db_local, GOTO_ERR(handle, ALPM_ERR_WRONG_ARGS, cleanup));
ASSERT(db->servers != NULL, GOTO_ERR(handle, ALPM_ERR_SERVER_NONE, cleanup));
/* set hard upper limit of 25MiB */
payload.max_size = 25 * 1024 * 1024;
/* force update of invalid databases to fix potential mismatched database/signature */
if(db->status & DB_STATUS_INVALID) {
dbforce = 1;
}
siglevel = alpm_db_get_siglevel(db);
CALLOC(payload, 1, sizeof(*payload), GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
payload->servers = db->servers;
/* print server + filename into a buffer */
len = strlen(db->treename) + strlen(dbext) + 1;
MALLOC(payload->filepath, len,
FREE(payload); GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
snprintf(payload->filepath, len, "%s%s", db->treename, dbext);
len = strlen(server) + strlen(db->treename) + strlen(dbext) + 2;
MALLOC(payload.fileurl, len,
{
free(syncpath);
umask(oldmask);
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
}
);
snprintf(payload.fileurl, len, "%s/%s%s", server, db->treename, dbext);
payload.handle = handle;
payload.force = force;
payload.unlink_on_fail = 1;
STRDUP(payload->remote_name, payload->filepath,
_alpm_dload_payload_reset(payload); FREE(payload);
GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup));
payload->destfile_name = _alpm_get_fullpath(temporary_syncpath, payload->remote_name, "");
payload->tempfile_name = _alpm_get_fullpath(temporary_syncpath, payload->remote_name, ".part");
if(!payload->destfile_name || !payload->tempfile_name) {
_alpm_dload_payload_reset(payload);
FREE(payload);
GOTO_ERR(handle, ALPM_ERR_MEMORY, cleanup);
ret = _alpm_download(&payload, syncpath, NULL, &final_db_url);
_alpm_dload_payload_reset(&payload);
updated = (updated || ret == 0);
if(ret != -1 && updated && (level & ALPM_SIG_DATABASE)) {
/* an existing sig file is no good at this point */
char *sigpath = _alpm_sigpath(handle, _alpm_db_path(db));
if(!sigpath) {
ret = -1;
break;
}
unlink(sigpath);
free(sigpath);
/* check if the final URL from internal downloader looks reasonable */
if(final_db_url != NULL) {
if(strlen(final_db_url) < 3
|| strcmp(final_db_url + strlen(final_db_url) - strlen(dbext),
dbext) != 0) {
final_db_url = NULL;
}
}
/* if we downloaded a DB, we want the .sig from the same server */
if(final_db_url != NULL) {
/* print final_db_url into a buffer (leave space for .sig) */
len = strlen(final_db_url) + 5;
} else {
/* print server + filename into a buffer (leave space for separator and .sig) */
len = strlen(server) + strlen(db->treename) + strlen(dbext) + 6;
}
MALLOC(payload.fileurl, len,
{
free(syncpath);
umask(oldmask);
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
}
);
if(final_db_url != NULL) {
snprintf(payload.fileurl, len, "%s.sig", final_db_url);
} else {
snprintf(payload.fileurl, len, "%s/%s%s.sig", server, db->treename, dbext);
}
payload.handle = handle;
payload.force = 1;
payload.errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL);
/* set hard upper limit of 16KiB */
payload.max_size = 16 * 1024;
sig_ret = _alpm_download(&payload, syncpath, NULL, NULL);
/* errors_ok suppresses error messages, but not the return code */
sig_ret = payload.errors_ok ? 0 : sig_ret;
_alpm_dload_payload_reset(&payload);
}
payload->handle = handle;
payload->force = dbforce;
payload->unlink_on_fail = 1;
payload->download_signature = (siglevel & ALPM_SIG_DATABASE);
payload->signature_optional = (siglevel & ALPM_SIG_DATABASE_OPTIONAL);
/* set hard upper limit of 128 MiB */
payload->max_size = 128 * 1024 * 1024;
payloads = alpm_list_add(payloads, payload);
}
if(payloads == NULL) {
ret = 0;
goto cleanup;
}
event.type = ALPM_EVENT_DB_RETRIEVE_START;
EVENT(handle, &event);
ret = _alpm_download(handle, payloads, syncpath, temporary_syncpath);
if(ret < 0) {
event.type = ALPM_EVENT_DB_RETRIEVE_FAILED;
EVENT(handle, &event);
goto cleanup;
}
event.type = ALPM_EVENT_DB_RETRIEVE_DONE;
EVENT(handle, &event);
for(i = dbs; i; i = i->next) {
alpm_db_t *db = i->data;
if(!(db->usage & ALPM_DB_USAGE_SYNC)) {
continue;
if(ret != -1 && sig_ret != -1) {
break;
}
}
if(updated) {
/* Cache needs to be rebuilt */
_alpm_db_free_pkgcache(db);
@ -245,31 +319,22 @@ int SYMEXPORT alpm_db_update(alpm_handle_t *handle, alpm_list_t *dbs, int force)
db->status &= ~DB_STATUS_MISSING;
/* if the download failed skip validation to preserve the download error */
if(sync_db_validate(db) != 0) {
_alpm_log(handle, ALPM_LOG_DEBUG, "failed to validate db: %s\n",
db->treename);
if(ret != -1 && sync_db_validate(db) != 0) {
/* pm_errno should be set */
ret = -1;
}
}
cleanup:
_alpm_handle_unlock(handle);
if(ret == -1) {
/* pm_errno was set by the download code */
_alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync dbs: %s\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n",
alpm_strerror(handle->pm_errno));
} else {
handle->pm_errno = ALPM_ERR_OK;
handle->pm_errno = 0;
}
if(payloads) {
alpm_list_free_inner(payloads, (alpm_list_fn_free)_alpm_dload_payload_reset);
FREELIST(payloads);
}
FREE(temporary_syncpath);
FREE(syncpath);
_alpm_handle_unlock(handle);
free(syncpath);
umask(oldmask);
return ret;
}
@ -278,7 +343,7 @@ cleanup:
static int sync_db_read(alpm_db_t *db, struct archive *archive,
struct archive_entry *entry, alpm_pkg_t **likely_pkg);
static int _sync_get_validation(alpm_pkg_t *pkg)
static alpm_pkgvalidation_t _sync_get_validation(alpm_pkg_t *pkg)
{
if(pkg->validation) {
return pkg->validation;
@ -301,22 +366,6 @@ static int _sync_get_validation(alpm_pkg_t *pkg)
return pkg->validation;
}
/** Package sync operations struct accessor. We implement this as a method
* because we want to reuse the majority of the default_pkg_ops struct and
* add only a few operations of our own on top.
*/
static const struct pkg_operations *get_sync_pkg_ops(void)
{
static struct pkg_operations sync_pkg_ops;
static int sync_pkg_ops_initialized = 0;
if(!sync_pkg_ops_initialized) {
sync_pkg_ops = default_pkg_ops;
sync_pkg_ops.get_validation = _sync_get_validation;
sync_pkg_ops_initialized = 1;
}
return &sync_pkg_ops;
}
static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
const char **entry_filename, alpm_pkg_t *likely_pkg)
{
@ -357,21 +406,14 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
pkg->origin = ALPM_PKG_FROM_SYNCDB;
pkg->origin_data.db = db;
pkg->ops = get_sync_pkg_ops();
pkg->ops = &default_pkg_ops;
pkg->ops->get_validation = _sync_get_validation;
pkg->handle = db->handle;
if(_alpm_pkg_check_meta(pkg) != 0) {
_alpm_pkg_free(pkg);
RET_ERR(db->handle, ALPM_ERR_PKG_INVALID, NULL);
}
/* add to the collection */
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename);
if(_alpm_pkghash_add(&db->pkgcache, pkg) == NULL) {
_alpm_pkg_free(pkg);
RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL);
}
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);
} else {
free(pkgname);
free(pkgver);
@ -382,8 +424,9 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
/* This function doesn't work as well as one might think, as size of database
* entries varies considerably. Adding signatures nearly doubles the size of a
* single entry. These current values are heavily influenced by Arch Linux;
* databases with a single signature per package. */
* single entry; deltas also can make for large variations in size. These
* current values are heavily influenced by Arch Linux; databases with no
* deltas and a single signature per package. */
static size_t estimate_package_count(struct stat *st, struct archive *archive)
{
int per_package;
@ -422,7 +465,6 @@ static int sync_db_populate(alpm_db_t *db)
size_t est_count, count;
int fd;
int ret = 0;
int archive_ret;
struct stat buf;
struct archive *archive;
struct archive_entry *entry;
@ -443,8 +485,6 @@ static int sync_db_populate(alpm_db_t *db)
fd = _alpm_open_archive(db->handle, dbpath, &buf,
&archive, ALPM_ERR_DB_OPEN);
if(fd < 0) {
db->status &= ~DB_STATUS_VALID;
db->status |= DB_STATUS_INVALID;
return -1;
}
est_count = estimate_package_count(&buf, archive);
@ -457,37 +497,25 @@ static int sync_db_populate(alpm_db_t *db)
db->pkgcache = _alpm_pkghash_create(est_count);
if(db->pkgcache == NULL) {
db->handle->pm_errno = ALPM_ERR_MEMORY;
ret = -1;
GOTO_ERR(db->handle, ALPM_ERR_MEMORY, cleanup);
goto cleanup;
}
while((archive_ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
mode_t mode = archive_entry_mode(entry);
if(!S_ISDIR(mode)) {
/* we have desc or depends - parse it */
if(S_ISDIR(mode)) {
continue;
} else {
/* we have desc, depends or deltas - parse it */
if(sync_db_read(db, archive, entry, &pkg) != 0) {
_alpm_log(db->handle, ALPM_LOG_ERROR,
_("could not parse package description file '%s' from db '%s'\n"),
archive_entry_pathname(entry), db->treename);
ret = -1;
continue;
}
}
}
/* the db file was successfully read, but contained errors */
if(ret == -1) {
db->status &= ~DB_STATUS_VALID;
db->status |= DB_STATUS_INVALID;
_alpm_db_free_pkgcache(db);
GOTO_ERR(db->handle, ALPM_ERR_DB_INVALID, cleanup);
}
/* reading the db file failed */
if(archive_ret != ARCHIVE_EOF) {
_alpm_log(db->handle, ALPM_LOG_ERROR, _("could not read db '%s' (%s)\n"),
db->treename, archive_error_string(archive));
_alpm_db_free_pkgcache(db);
ret = -1;
GOTO_ERR(db->handle, ALPM_ERR_LIBARCHIVE, cleanup);
}
count = alpm_list_count(db->pkgcache->list);
if(count > 0) {
@ -563,7 +591,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
{
const char *entryname, *filename;
alpm_pkg_t *pkg;
struct archive_read_buffer buf = {0};
struct archive_read_buffer buf;
entryname = archive_entry_pathname(entry);
if(entryname == NULL) {
@ -575,6 +603,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "loading package data from archive entry %s\n",
entryname);
memset(&buf, 0, sizeof(buf));
/* 512K for a line length seems reasonable */
buf.max_line_size = 512 * 1024;
@ -582,7 +611,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
if(pkg == NULL) {
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"entry %s could not be loaded into %s sync database\n",
"entry %s could not be loaded into %s sync database",
entryname, db->treename);
return -1;
}
@ -591,12 +620,13 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
/* A file exists outside of a subdirectory. This isn't a read error, so return
* success and try to continue on. */
_alpm_log(db->handle, ALPM_LOG_WARNING, _("unknown database file: %s\n"),
entryname);
filename);
return 0;
}
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|| strcmp(filename, "files") == 0) {
|| strcmp(filename, "files") == 0
|| (strcmp(filename, "deltas") == 0 && db->handle->deltaratio > 0.0) ) {
int ret;
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
char *line = buf.line;
@ -658,13 +688,29 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
READ_AND_SPLITDEP(pkg->optdepends);
} else if(strcmp(line, "%MAKEDEPENDS%") == 0) {
READ_AND_SPLITDEP(pkg->makedepends);
/* currently unused */
while(1) {
READ_NEXT();
if(strlen(line) == 0) break;
}
} else if(strcmp(line, "%CHECKDEPENDS%") == 0) {
READ_AND_SPLITDEP(pkg->checkdepends);
/* currently unused */
while(1) {
READ_NEXT();
if(strlen(line) == 0) break;
}
} else if(strcmp(line, "%CONFLICTS%") == 0) {
READ_AND_SPLITDEP(pkg->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
READ_AND_SPLITDEP(pkg->provides);
} else if(strcmp(line, "%DELTAS%") == 0) {
/* Different than the rest because of the _alpm_delta_parse call. */
while(1) {
READ_NEXT();
if(strlen(line) == 0) break;
pkg->deltas = alpm_list_add(pkg->deltas,
_alpm_delta_parse(db->handle, line));
}
} else if(strcmp(line, "%FILES%") == 0) {
/* TODO: this could lazy load if there is future demand */
size_t files_count = 0, files_size = 0;
@ -688,36 +734,22 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
}
/* attempt to hand back any memory we don't need */
if(files_count > 0) {
REALLOC(files, sizeof(alpm_file_t) * files_count, (void)0);
files = realloc(files, sizeof(alpm_file_t) * files_count);
/* make sure the list is sorted */
qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp);
} else {
FREE(files);
}
pkg->files.count = files_count;
pkg->files.files = files;
_alpm_filelist_sort(&pkg->files);
} else if(strcmp(line, "%DATA%") == 0) {
alpm_list_t *i, *lines = NULL;
READ_AND_STORE_ALL(lines);
for(i = lines; i; i = i->next) {
alpm_pkg_xdata_t *pd = _alpm_pkg_parse_xdata(i->data);
if(pd == NULL || !alpm_list_append(&pkg->xdata, pd)) {
_alpm_pkg_xdata_free(pd);
FREELIST(lines);
goto error;
}
}
FREELIST(lines);
} else {
_alpm_log(db->handle, ALPM_LOG_WARNING, _("%s: unknown key '%s' in sync database\n"), pkg->name, line);
alpm_list_t *lines = NULL;
READ_AND_STORE_ALL(lines);
FREELIST(lines);
}
}
if(ret != ARCHIVE_EOF) {
goto error;
}
*likely_pkg = pkg;
} else if(strcmp(filename, "deltas") == 0) {
/* skip reading delta files if UseDelta is unset */
} else {
/* unknown database file */
_alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename);
@ -737,15 +769,15 @@ struct db_operations sync_db_ops = {
};
alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
int level)
alpm_siglevel_t level)
{
alpm_db_t *db;
_alpm_log(handle, ALPM_LOG_DEBUG, "registering sync database '%s'\n", treename);
#ifndef HAVE_LIBGPGME
if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
RET_ERR(handle, ALPM_ERR_MISSING_CAPABILITY_SIGNATURES, NULL);
if(level != ALPM_SIG_USE_DEFAULT) {
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL);
}
#endif
@ -762,3 +794,5 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
return db;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* conflict.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
@ -50,8 +50,10 @@ static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2,
CALLOC(conflict, 1, sizeof(alpm_conflict_t), return NULL);
ASSERT(_alpm_pkg_dup(pkg1, &conflict->package1) == 0, goto error);
ASSERT(_alpm_pkg_dup(pkg2, &conflict->package2) == 0, goto error);
conflict->package1_hash = pkg1->name_hash;
conflict->package2_hash = pkg2->name_hash;
STRDUP(conflict->package1, pkg1->name, goto error);
STRDUP(conflict->package2, pkg2->name, goto error);
conflict->reason = reason;
return conflict;
@ -61,12 +63,14 @@ error:
return NULL;
}
/**
* @brief Free a conflict and its members.
*/
void SYMEXPORT alpm_conflict_free(alpm_conflict_t *conflict)
{
ASSERT(conflict != NULL, return);
_alpm_pkg_free(conflict->package1);
_alpm_pkg_free(conflict->package2);
FREE(conflict->package2);
FREE(conflict->package1);
FREE(conflict);
}
@ -78,8 +82,10 @@ alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict)
alpm_conflict_t *newconflict;
CALLOC(newconflict, 1, sizeof(alpm_conflict_t), return NULL);
ASSERT(_alpm_pkg_dup(conflict->package1, &newconflict->package1) == 0, goto error);
ASSERT(_alpm_pkg_dup(conflict->package2, &newconflict->package2) == 0, goto error);
newconflict->package1_hash = conflict->package1_hash;
newconflict->package2_hash = conflict->package2_hash;
STRDUP(newconflict->package1, conflict->package1, goto error);
STRDUP(newconflict->package2, conflict->package2, goto error);
newconflict->reason = conflict->reason;
return newconflict;
@ -102,10 +108,10 @@ static int conflict_isin(alpm_conflict_t *needle, alpm_list_t *haystack)
alpm_list_t *i;
for(i = haystack; i; i = i->next) {
alpm_conflict_t *conflict = i->data;
if(needle->package1->name_hash == conflict->package1->name_hash
&& needle->package2->name_hash == conflict->package2->name_hash
&& strcmp(needle->package1->name, conflict->package1->name) == 0
&& strcmp(needle->package2->name, conflict->package2->name) == 0) {
if(needle->package1_hash == conflict->package1_hash
&& needle->package2_hash == conflict->package2_hash
&& strcmp(needle->package1, conflict->package1) == 0
&& strcmp(needle->package2, conflict->package2) == 0) {
return 1;
}
}
@ -237,6 +243,14 @@ alpm_list_t *_alpm_outerconflicts(alpm_db_t *db, alpm_list_t *packages)
return baddeps;
}
/**
* @brief Check the package conflicts in a database
*
* @param handle the context handle
* @param pkglist the list of packages to check
*
* @return an alpm_list_t of alpm_conflict_t
*/
alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_handle_t *handle,
alpm_list_t *pkglist)
{
@ -264,15 +278,12 @@ static alpm_list_t *add_fileconflict(alpm_handle_t *handle,
STRDUP(conflict->target, pkg1->name, goto error);
STRDUP(conflict->file, filestr, goto error);
if(!pkg2) {
conflict->type = ALPM_FILECONFLICT_FILESYSTEM;
STRDUP(conflict->ctarget, "", goto error);
} else if(pkg2->origin == ALPM_PKG_FROM_LOCALDB) {
conflict->type = ALPM_FILECONFLICT_FILESYSTEM;
STRDUP(conflict->ctarget, pkg2->name, goto error);
} else {
if(pkg2) {
conflict->type = ALPM_FILECONFLICT_TARGET;
STRDUP(conflict->ctarget, pkg2->name, goto error);
} else {
conflict->type = ALPM_FILECONFLICT_FILESYSTEM;
STRDUP(conflict->ctarget, "", goto error);
}
conflicts = alpm_list_add(conflicts, conflict);
@ -286,6 +297,9 @@ error:
RET_ERR(handle, ALPM_ERR_MEMORY, conflicts);
}
/**
* @brief Frees a conflict and its members.
*/
void SYMEXPORT alpm_fileconflict_free(alpm_fileconflict_t *conflict)
{
ASSERT(conflict != NULL, return);
@ -371,23 +385,6 @@ static alpm_list_t *alpm_db_find_file_owners(alpm_db_t* db, const char *path)
return owners;
}
static alpm_pkg_t *_alpm_find_file_owner(alpm_handle_t *handle, const char *path)
{
alpm_list_t *i;
for(i = alpm_db_get_pkgcache(handle->db_local); i; i = i->next) {
if(alpm_filelist_contains(alpm_pkg_get_files(i->data), path)) {
return i->data;
}
}
return NULL;
}
static int _alpm_can_overwrite_file(alpm_handle_t *handle, const char *path, const char *rootedpath)
{
return _alpm_fnmatch_patterns(handle->overwrite_files, path) == 0
|| _alpm_fnmatch_patterns(handle->overwrite_files, rootedpath) == 0;
}
/**
* @brief Find file conflicts that may occur during the transaction.
*
@ -422,7 +419,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
for(current = 0, i = upgrade; i; i = i->next, current++) {
alpm_pkg_t *p1 = i->data;
alpm_list_t *j;
alpm_list_t *newfiles = NULL;
alpm_list_t *tmpfiles = NULL;
alpm_pkg_t *dbpkg;
int percent = (current * 100) / numtargs;
@ -451,8 +448,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
/* can skip file-file conflicts when forced *
* checking presence in p2_files detects dir-file or file-dir
* conflicts as the path from p1 is returned */
if(_alpm_can_overwrite_file(handle, filename, path)
&& alpm_filelist_contains(p2_files, filename)) {
if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) &&
alpm_filelist_contains(p2_files, filename)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"%s exists in both '%s' and '%s'\n", filename,
p1->name, p2->name);
@ -486,18 +483,18 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
* be freed. */
if(dbpkg) {
/* older ver of package currently installed */
newfiles = _alpm_filelist_difference(alpm_pkg_get_files(p1),
tmpfiles = _alpm_filelist_difference(alpm_pkg_get_files(p1),
alpm_pkg_get_files(dbpkg));
} else {
/* no version of package currently installed */
alpm_filelist_t *fl = alpm_pkg_get_files(p1);
size_t filenum;
for(filenum = 0; filenum < fl->count; filenum++) {
newfiles = alpm_list_add(newfiles, fl->files[filenum].name);
tmpfiles = alpm_list_add(tmpfiles, fl->files[filenum].name);
}
}
for(j = newfiles; j; j = j->next) {
for(j = tmpfiles; j; j = j->next) {
const char *filestr = j->data;
const char *relative_path;
alpm_list_t *k;
@ -506,7 +503,6 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
struct stat lsbuf;
char path[PATH_MAX];
size_t pathlen;
int pfile_isdir;
pathlen = snprintf(path, PATH_MAX, "%s%s", handle->root, filestr);
relative_path = path + rootlen;
@ -518,8 +514,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
_alpm_log(handle, ALPM_LOG_DEBUG, "checking possible conflict: %s\n", path);
pfile_isdir = path[pathlen - 1] == '/';
if(pfile_isdir) {
if(path[pathlen - 1] == '/') {
if(S_ISDIR(lsbuf.st_mode)) {
_alpm_log(handle, ALPM_LOG_DEBUG, "file is a directory, not a conflict\n");
continue;
@ -556,18 +551,6 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
_alpm_log(handle, ALPM_LOG_DEBUG,
"local file will be removed, not a conflict\n");
resolved_conflict = 1;
if(pfile_isdir) {
/* go ahead and skip any files inside filestr as they will
* necessarily be resolved by replacing the file with a dir
* NOTE: afterward, j will point to the last file inside filestr */
size_t fslen = strlen(filestr);
for( ; j->next; j = j->next) {
const char *filestr2 = j->next->data;
if(strncmp(filestr, filestr2, fslen) != 0) {
break;
}
}
}
}
}
@ -612,9 +595,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
/* check if all files of the dir belong to the installed pkg */
if(!resolved_conflict && S_ISDIR(lsbuf.st_mode)) {
alpm_list_t *owners;
size_t dir_len = strlen(relative_path) + 2;
char *dir = malloc(dir_len);
snprintf(dir, dir_len, "%s/", relative_path);
char *dir = malloc(strlen(relative_path) + 2);
sprintf(dir, "%s/", relative_path);
owners = alpm_db_find_file_owners(handle->db_local, dir);
if(owners) {
@ -658,29 +640,30 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
}
/* skip file-file conflicts when being forced */
if(!S_ISDIR(lsbuf.st_mode)
&& _alpm_can_overwrite_file(handle, filestr, path)) {
if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) &&
!S_ISDIR(lsbuf.st_mode)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"conflict with file on filesystem being forced\n");
resolved_conflict = 1;
}
if(!resolved_conflict) {
conflicts = add_fileconflict(handle, conflicts, path, p1,
_alpm_find_file_owner(handle, relative_path));
conflicts = add_fileconflict(handle, conflicts, path, p1, NULL);
if(handle->pm_errno == ALPM_ERR_MEMORY) {
alpm_list_free_inner(conflicts,
(alpm_list_fn_free) alpm_conflict_free);
alpm_list_free(conflicts);
alpm_list_free(newfiles);
alpm_list_free(tmpfiles);
return NULL;
}
}
}
alpm_list_free(newfiles);
alpm_list_free(tmpfiles);
}
PROGRESS(handle, ALPM_PROGRESS_CONFLICTS_START, "", 100,
numtargs, current);
return conflicts;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* conflict.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -31,3 +31,5 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
alpm_list_t *upgrade, alpm_list_t *remove);
#endif /* ALPM_CONFLICT_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* db.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
@ -37,8 +37,14 @@
#include "package.h"
#include "group.h"
/** \addtogroup alpm_databases Database Functions
* @brief Functions to query and manipulate the database of libalpm
* @{
*/
/** Register a sync database of packages. */
alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle,
const char *treename, int siglevel)
const char *treename, alpm_siglevel_t level)
{
alpm_list_t *i;
@ -61,7 +67,7 @@ alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle,
}
}
return _alpm_db_register_sync(handle, treename, siglevel);
return _alpm_db_register_sync(handle, treename, level);
}
/* Helper function for alpm_db_unregister{_all} */
@ -75,6 +81,7 @@ void _alpm_db_unregister(alpm_db_t *db)
_alpm_db_free(db);
}
/** Unregister all package databases. */
int SYMEXPORT alpm_unregister_all_syncdbs(alpm_handle_t *handle)
{
alpm_list_t *i;
@ -95,6 +102,7 @@ int SYMEXPORT alpm_unregister_all_syncdbs(alpm_handle_t *handle)
return 0;
}
/** Unregister a package database. */
int SYMEXPORT alpm_db_unregister(alpm_db_t *db)
{
int found = 0;
@ -104,7 +112,7 @@ int SYMEXPORT alpm_db_unregister(alpm_db_t *db)
ASSERT(db != NULL, return -1);
/* Do not unregister a database if a transaction is on-going */
handle = db->handle;
handle->pm_errno = ALPM_ERR_OK;
handle->pm_errno = 0;
ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, -1));
if(db == handle->db_local) {
@ -131,43 +139,19 @@ int SYMEXPORT alpm_db_unregister(alpm_db_t *db)
return 0;
}
alpm_list_t SYMEXPORT *alpm_db_get_cache_servers(const alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
return db->cache_servers;
}
int SYMEXPORT alpm_db_set_cache_servers(alpm_db_t *db, alpm_list_t *cache_servers)
{
alpm_list_t *i;
ASSERT(db != NULL, return -1);
FREELIST(db->cache_servers);
for(i = cache_servers; i; i = i->next) {
char *url = i->data;
if(alpm_db_add_cache_server(db, url) != 0) {
return -1;
}
}
return 0;
}
/** Get the serverlist of a database. */
alpm_list_t SYMEXPORT *alpm_db_get_servers(const alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
return db->servers;
}
/** Set the serverlist of a database. */
int SYMEXPORT alpm_db_set_servers(alpm_db_t *db, alpm_list_t *servers)
{
alpm_list_t *i;
ASSERT(db != NULL, return -1);
FREELIST(db->servers);
for(i = servers; i; i = i->next) {
char *url = i->data;
if(alpm_db_add_server(db, url) != 0) {
return -1;
}
}
db->servers = servers;
return 0;
}
@ -184,37 +168,24 @@ static char *sanitize_url(const char *url)
return newurl;
}
int SYMEXPORT alpm_db_add_cache_server(alpm_db_t *db, const char *url)
{
char *newurl;
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
db->cache_servers = alpm_list_add(db->cache_servers, newurl);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding new cache server URL to database '%s': %s\n",
db->treename, newurl);
return 0;
}
/** Add a download server to a database.
* @param db database pointer
* @param url url of the server
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
int SYMEXPORT alpm_db_add_server(alpm_db_t *db, const char *url)
{
char *newurl;
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
db->handle->pm_errno = 0;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
if(!newurl) {
return -1;
}
db->servers = alpm_list_add(db->servers, newurl);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding new server URL to database '%s': %s\n",
db->treename, newurl);
@ -222,32 +193,12 @@ int SYMEXPORT alpm_db_add_server(alpm_db_t *db, const char *url)
return 0;
}
int SYMEXPORT alpm_db_remove_cache_server(alpm_db_t *db, const char *url)
{
char *newurl, *vdata = NULL;
int ret = 1;
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
db->cache_servers = alpm_list_remove_str(db->cache_servers, newurl, &vdata);
if(vdata) {
_alpm_log(db->handle, ALPM_LOG_DEBUG, "removed cache server URL from database '%s': %s\n",
db->treename, newurl);
free(vdata);
ret = 0;
}
free(newurl);
return ret;
}
/** Remove a download server from a database.
* @param db database pointer
* @param url url of the server
* @return 0 on success, 1 on server not present,
* -1 on error (pm_errno is set accordingly)
*/
int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
{
char *newurl, *vdata = NULL;
@ -255,11 +206,13 @@ int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
db->handle->pm_errno = 0;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
ASSERT(newurl != NULL, RET_ERR(db->handle, ALPM_ERR_MEMORY, -1));
if(!newurl) {
return -1;
}
db->servers = alpm_list_remove_str(db->servers, newurl, &vdata);
@ -274,19 +227,15 @@ int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
return ret;
}
alpm_handle_t SYMEXPORT *alpm_db_get_handle(alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
return db->handle;
}
/** Get the name of a package database. */
const char SYMEXPORT *alpm_db_get_name(const alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
return db->treename;
}
int SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db)
/** Get the signature verification level for a database. */
alpm_siglevel_t SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db)
{
ASSERT(db != NULL, return -1);
if(db->siglevel & ALPM_SIG_USE_DEFAULT) {
@ -296,18 +245,20 @@ int SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db)
}
}
/** Check the validity of a database. */
int SYMEXPORT alpm_db_get_valid(alpm_db_t *db)
{
ASSERT(db != NULL, return -1);
db->handle->pm_errno = ALPM_ERR_OK;
db->handle->pm_errno = 0;
return db->ops->validate(db);
}
/** Get a package entry from a package database. */
alpm_pkg_t SYMEXPORT *alpm_db_get_pkg(alpm_db_t *db, const char *name)
{
alpm_pkg_t *pkg;
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = ALPM_ERR_OK;
db->handle->pm_errno = 0;
ASSERT(name != NULL && strlen(name) != 0,
RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, NULL));
@ -318,13 +269,15 @@ alpm_pkg_t SYMEXPORT *alpm_db_get_pkg(alpm_db_t *db, const char *name)
return pkg;
}
/** Get the package cache of a package database. */
alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = ALPM_ERR_OK;
db->handle->pm_errno = 0;
return _alpm_db_get_pkgcache(db);
}
/** Get a group entry from a package database. */
alpm_group_t SYMEXPORT *alpm_db_get_group(alpm_db_t *db, const char *name)
{
ASSERT(db != NULL, return NULL);
@ -335,32 +288,34 @@ alpm_group_t SYMEXPORT *alpm_db_get_group(alpm_db_t *db, const char *name)
return _alpm_db_get_groupfromcache(db, name);
}
/** Get the group cache of a package database. */
alpm_list_t SYMEXPORT *alpm_db_get_groupcache(alpm_db_t *db)
{
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = ALPM_ERR_OK;
db->handle->pm_errno = 0;
return _alpm_db_get_groupcache(db);
}
int SYMEXPORT alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
alpm_list_t **ret)
/** Searches a database. */
alpm_list_t SYMEXPORT *alpm_db_search(alpm_db_t *db, const alpm_list_t *needles)
{
ASSERT(db != NULL && ret != NULL && *ret == NULL,
RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
db->handle->pm_errno = ALPM_ERR_OK;
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = 0;
return _alpm_db_search(db, needles, ret);
return _alpm_db_search(db, needles);
}
int SYMEXPORT alpm_db_set_usage(alpm_db_t *db, int usage)
/** Sets the usage bitmask for a repo */
int SYMEXPORT alpm_db_set_usage(alpm_db_t *db, alpm_db_usage_t usage)
{
ASSERT(db != NULL, return -1);
db->usage = usage;
return 0;
}
int SYMEXPORT alpm_db_get_usage(alpm_db_t *db, int *usage)
/** Gets the usage bitmask for a repo */
int SYMEXPORT alpm_db_get_usage(alpm_db_t *db, alpm_db_usage_t *usage)
{
ASSERT(db != NULL, return -1);
ASSERT(usage != NULL, return -1);
@ -368,6 +323,9 @@ int SYMEXPORT alpm_db_get_usage(alpm_db_t *db, int *usage)
return 0;
}
/** @} */
alpm_db_t *_alpm_db_new(const char *treename, int is_local)
{
alpm_db_t *db;
@ -390,7 +348,6 @@ void _alpm_db_free(alpm_db_t *db)
/* cleanup pkgcache */
_alpm_db_free_pkgcache(db);
/* cleanup server list */
FREELIST(db->cache_servers);
FREELIST(db->servers);
FREE(db->_path);
FREE(db->treename);
@ -417,14 +374,14 @@ const char *_alpm_db_path(alpm_db_t *db)
if(db->status & DB_STATUS_LOCAL) {
pathsize = strlen(dbpath) + strlen(db->treename) + 2;
CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
snprintf(db->_path, pathsize, "%s%s/", dbpath, db->treename);
sprintf(db->_path, "%s%s/", dbpath, db->treename);
} else {
const char *dbext = db->handle->dbext;
pathsize = strlen(dbpath) + 5 + strlen(db->treename) + strlen(dbext) + 1;
CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
/* all sync DBs now reside in the sync/ subdir of the dbpath */
snprintf(db->_path, pathsize, "%ssync/%s%s", dbpath, db->treename, dbext);
sprintf(db->_path, "%ssync/%s%s", dbpath, db->treename, dbext);
}
_alpm_log(db->handle, ALPM_LOG_DEBUG, "database path for tree %s set to %s\n",
db->treename, db->_path);
@ -439,13 +396,13 @@ int _alpm_db_cmp(const void *d1, const void *d2)
return strcmp(db1->treename, db2->treename);
}
int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
alpm_list_t **ret)
alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles)
{
const alpm_list_t *i, *j, *k;
alpm_list_t *ret = NULL;
if(!(db->usage & ALPM_DB_USAGE_SEARCH)) {
return 0;
return NULL;
}
/* copy the pkgcache- we will free the list var after each needle */
@ -458,15 +415,12 @@ int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
if(i->data == NULL) {
continue;
}
*ret = NULL;
ret = NULL;
targ = i->data;
_alpm_log(db->handle, ALPM_LOG_DEBUG, "searching for target '%s'\n", targ);
if(regcomp(&reg, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) {
db->handle->pm_errno = ALPM_ERR_INVALID_REGEX;
alpm_list_free(list);
alpm_list_free(*ret);
return -1;
RET_ERR(db->handle, ALPM_ERR_INVALID_REGEX, NULL);
}
for(j = list; j; j = j->next) {
@ -509,18 +463,18 @@ int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"search target '%s' matched '%s' on package '%s'\n",
targ, matched, name);
*ret = alpm_list_add(*ret, pkg);
ret = alpm_list_add(ret, pkg);
}
}
/* Free the existing search list, and use the returned list for the
* next needle. This allows for AND-based package searching. */
alpm_list_free(list);
list = *ret;
list = ret;
regfree(&reg);
}
return 0;
return ret;
}
/* Returns a new package cache from db.
@ -563,17 +517,18 @@ static void free_groupcache(alpm_db_t *db)
void _alpm_db_free_pkgcache(alpm_db_t *db)
{
if(db == NULL || db->pkgcache == NULL) {
if(db == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
return;
}
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"freeing package cache for repository '%s'\n", db->treename);
alpm_list_free_inner(db->pkgcache->list,
(alpm_list_fn_free)_alpm_pkg_free);
_alpm_pkghash_free(db->pkgcache);
db->pkgcache = NULL;
if(db->pkgcache) {
alpm_list_free_inner(db->pkgcache->list,
(alpm_list_fn_free)_alpm_pkg_free);
_alpm_pkghash_free(db->pkgcache);
}
db->status &= ~DB_STATUS_PKGCACHE;
free_groupcache(db);
@ -634,10 +589,7 @@ int _alpm_db_add_pkgincache(alpm_db_t *db, alpm_pkg_t *pkg)
? ALPM_PKG_FROM_LOCALDB
: ALPM_PKG_FROM_SYNCDB;
newpkg->origin_data.db = db;
if(_alpm_pkghash_add_sorted(&db->pkgcache, newpkg) == NULL) {
_alpm_pkg_free(newpkg);
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
}
db->pkgcache = _alpm_pkghash_add_sorted(db->pkgcache, newpkg);
free_groupcache(db);
@ -771,3 +723,5 @@ alpm_group_t *_alpm_db_get_groupfromcache(alpm_db_t *db, const char *target)
return NULL;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* db.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
@ -62,24 +62,19 @@ struct db_operations {
};
/* Database */
struct _alpm_db_t {
struct __alpm_db_t {
alpm_handle_t *handle;
char *treename;
/* do not access directly, use _alpm_db_path(db) for lazy access */
char *_path;
alpm_pkghash_t *pkgcache;
alpm_list_t *grpcache;
alpm_list_t *cache_servers;
alpm_list_t *servers;
const struct db_operations *ops;
/* bitfields for validity, local, loaded caches, etc. */
/* From _alpm_dbstatus_t */
int status;
/* alpm_siglevel_t */
int siglevel;
/* alpm_db_usage_t */
int usage;
struct db_operations *ops;
/* flags determining validity, local, loaded caches, etc. */
enum _alpm_dbstatus_t status;
alpm_siglevel_t siglevel;
alpm_db_usage_t usage;
};
@ -88,16 +83,15 @@ alpm_db_t *_alpm_db_new(const char *treename, int is_local);
void _alpm_db_free(alpm_db_t *db);
const char *_alpm_db_path(alpm_db_t *db);
int _alpm_db_cmp(const void *d1, const void *d2);
int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles,
alpm_list_t **ret);
alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles);
alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle);
alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
int level);
alpm_siglevel_t level);
void _alpm_db_unregister(alpm_db_t *db);
/* be_*.c, backend specific calls */
int _alpm_local_db_prepare(alpm_db_t *db, alpm_pkg_t *info);
int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq);
int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq);
int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info);
char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info, const char *filename);
@ -114,3 +108,5 @@ alpm_list_t *_alpm_db_get_groupcache(alpm_db_t *db);
alpm_group_t *_alpm_db_get_groupfromcache(alpm_db_t *db, const char *target);
#endif /* ALPM_DB_H */
/* vim: set noet: */

364
lib/libalpm/delta.c Normal file
View file

@ -0,0 +1,364 @@
/*
* delta.c
*
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2007-2006 by Judd Vinet <jvinet@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 <string.h>
#include <stdint.h> /* intmax_t */
#include <limits.h>
#include <sys/types.h>
#include <regex.h>
/* libalpm */
#include "delta.h"
#include "alpm_list.h"
#include "util.h"
#include "log.h"
#include "graph.h"
static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)
{
alpm_list_t *i, *j;
alpm_list_t *vertices = NULL;
/* create the vertices */
for(i = deltas; i; i = i->next) {
alpm_graph_t *v = _alpm_graph_new();
if(!v) {
alpm_list_free(vertices);
return NULL;
}
alpm_delta_t *vdelta = i->data;
vdelta->download_size = vdelta->delta_size;
v->weight = LONG_MAX;
v->data = vdelta;
vertices = alpm_list_add(vertices, v);
}
/* compute the edges */
for(i = vertices; i; i = i->next) {
alpm_graph_t *v_i = i->data;
alpm_delta_t *d_i = v_i->data;
/* loop a second time so we make all possible comparisons */
for(j = vertices; j; j = j->next) {
alpm_graph_t *v_j = j->data;
alpm_delta_t *d_j = v_j->data;
/* We want to create a delta tree like the following:
* 1_to_2
* |
* 1_to_3 2_to_3
* \ /
* 3_to_4
* If J 'from' is equal to I 'to', then J is a child of I.
* */
if((!reverse && strcmp(d_j->from, d_i->to) == 0) ||
(reverse && strcmp(d_j->to, d_i->from) == 0)) {
v_i->children = alpm_list_add(v_i->children, v_j);
}
}
v_i->childptr = v_i->children;
}
return vertices;
}
static void graph_init_size(alpm_handle_t *handle, alpm_list_t *vertices)
{
alpm_list_t *i;
for(i = vertices; i; i = i->next) {
char *fpath, *md5sum;
alpm_graph_t *v = i->data;
alpm_delta_t *vdelta = v->data;
/* determine whether the delta file already exists */
fpath = _alpm_filecache_find(handle, vdelta->delta);
if(fpath) {
md5sum = alpm_compute_md5sum(fpath);
if(md5sum && strcmp(md5sum, vdelta->delta_md5) == 0) {
vdelta->download_size = 0;
}
FREE(md5sum);
FREE(fpath);
} else {
char *fnamepart;
CALLOC(fnamepart, strlen(vdelta->delta) + 6, sizeof(char), return);
sprintf(fnamepart, "%s.part", vdelta->delta);
fpath = _alpm_filecache_find(handle, fnamepart);
if(fpath) {
struct stat st;
if(stat(fpath, &st) == 0) {
vdelta->download_size = vdelta->delta_size - st.st_size;
vdelta->download_size = vdelta->download_size < 0 ? 0 : vdelta->download_size;
}
FREE(fpath);
}
FREE(fnamepart);
}
/* determine whether a base 'from' file exists */
fpath = _alpm_filecache_find(handle, vdelta->from);
if(fpath) {
v->weight = vdelta->download_size;
}
FREE(fpath);
}
}
static void dijkstra(alpm_list_t *vertices)
{
alpm_list_t *i;
alpm_graph_t *v;
while(1) {
v = NULL;
/* find the smallest vertice not visited yet */
for(i = vertices; i; i = i->next) {
alpm_graph_t *v_i = i->data;
if(v_i->state == -1) {
continue;
}
if(v == NULL || v_i->weight < v->weight) {
v = v_i;
}
}
if(v == NULL || v->weight == LONG_MAX) {
break;
}
v->state = -1;
v->childptr = v->children;
while(v->childptr) {
alpm_graph_t *v_c = v->childptr->data;
alpm_delta_t *d_c = v_c->data;
if(v_c->weight > v->weight + d_c->download_size) {
v_c->weight = v->weight + d_c->download_size;
v_c->parent = v;
}
v->childptr = (v->childptr)->next;
}
}
}
static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t **path)
{
alpm_list_t *i;
alpm_graph_t *v = NULL;
off_t bestsize = 0;
alpm_list_t *rpath = NULL;
for(i = vertices; i; i = i->next) {
alpm_graph_t *v_i = i->data;
alpm_delta_t *d_i = v_i->data;
if(strcmp(d_i->to, to) == 0) {
if(v == NULL || v_i->weight < v->weight) {
v = v_i;
bestsize = v->weight;
}
}
}
while(v != NULL) {
alpm_delta_t *vdelta = v->data;
rpath = alpm_list_add(rpath, vdelta);
v = v->parent;
}
*path = alpm_list_reverse(rpath);
alpm_list_free(rpath);
return bestsize;
}
/** Calculates the shortest path from one version to another.
* The shortest path is defined as the path with the smallest combined
* size, not the length of the path.
* @param handle the context handle
* @param deltas the list of alpm_delta_t * objects that a file has
* @param to the file to start the search at
* @param path the pointer to a list location where alpm_delta_t * objects that
* have the smallest size are placed. NULL is set if there is no path
* possible with the files available.
* @return the size of the path stored, or LONG_MAX if path is unfindable
*/
off_t _alpm_shortest_delta_path(alpm_handle_t *handle, alpm_list_t *deltas,
const char *to, alpm_list_t **path)
{
alpm_list_t *bestpath = NULL;
alpm_list_t *vertices;
off_t bestsize = LONG_MAX;
if(deltas == NULL) {
*path = NULL;
return bestsize;
}
_alpm_log(handle, ALPM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to);
vertices = graph_init(deltas, 0);
graph_init_size(handle, vertices);
dijkstra(vertices);
bestsize = shortest_path(vertices, to, &bestpath);
_alpm_log(handle, ALPM_LOG_DEBUG, "delta shortest-path search complete : '%jd'\n", (intmax_t)bestsize);
alpm_list_free_inner(vertices, _alpm_graph_free);
alpm_list_free(vertices);
*path = bestpath;
return bestsize;
}
static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota)
{
alpm_list_t *unused = NULL;
alpm_list_t *vertices;
alpm_list_t *i;
vertices = graph_init(deltas, 1);
for(i = vertices; i; i = i->next) {
alpm_graph_t *v = i->data;
alpm_delta_t *vdelta = v->data;
if(strcmp(vdelta->to, to) == 0)
{
v->weight = vdelta->download_size;
}
}
dijkstra(vertices);
for(i = vertices; i; i = i->next) {
alpm_graph_t *v = i->data;
alpm_delta_t *vdelta = v->data;
if(v->weight > quota) {
unused = alpm_list_add(unused, vdelta->delta);
}
}
alpm_list_free_inner(vertices, _alpm_graph_free);
alpm_list_free(vertices);
return unused;
}
/** \addtogroup alpm_deltas Delta Functions
* @brief Functions to manipulate libalpm deltas
* @{
*/
alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
return find_unused(pkg->deltas, pkg->filename,
pkg->size * pkg->handle->deltaratio);
}
/** @} */
#define NUM_MATCHES 6
/** Parses the string representation of a alpm_delta_t object.
* This function assumes that the string is in the correct format.
* This format is as follows:
* $deltafile $deltamd5 $deltasize $oldfile $newfile
* @param handle the context handle
* @param line the string to parse
* @return A pointer to the new alpm_delta_t object
*/
alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line)
{
alpm_delta_t *delta;
size_t len;
regmatch_t pmatch[NUM_MATCHES];
char filesize[32];
/* this is so we only have to compile the pattern once */
if(!handle->delta_regex_compiled) {
/* $deltafile $deltamd5 $deltasize $oldfile $newfile*/
regcomp(&handle->delta_regex,
"^([^[:space:]]+) ([[:xdigit:]]{32}) ([[:digit:]]+)"
" ([^[:space:]]+) ([^[:space:]]+)$",
REG_EXTENDED | REG_NEWLINE);
handle->delta_regex_compiled = 1;
}
if(regexec(&handle->delta_regex, line, NUM_MATCHES, pmatch, 0) != 0) {
/* delta line is invalid, return NULL */
return NULL;
}
CALLOC(delta, 1, sizeof(alpm_delta_t), return NULL);
/* start at index 1 -- match 0 is the entire match */
len = pmatch[1].rm_eo - pmatch[1].rm_so;
STRNDUP(delta->delta, &line[pmatch[1].rm_so], len, goto error);
len = pmatch[2].rm_eo - pmatch[2].rm_so;
STRNDUP(delta->delta_md5, &line[pmatch[2].rm_so], len, goto error);
len = pmatch[3].rm_eo - pmatch[3].rm_so;
if(len < sizeof(filesize)) {
strncpy(filesize, &line[pmatch[3].rm_so], len);
filesize[len] = '\0';
delta->delta_size = _alpm_strtoofft(filesize);
}
len = pmatch[4].rm_eo - pmatch[4].rm_so;
STRNDUP(delta->from, &line[pmatch[4].rm_so], len, goto error);
len = pmatch[5].rm_eo - pmatch[5].rm_so;
STRNDUP(delta->to, &line[pmatch[5].rm_so], len, goto error);
return delta;
error:
_alpm_delta_free(delta);
return NULL;
}
#undef NUM_MATCHES
void _alpm_delta_free(alpm_delta_t *delta)
{
ASSERT(delta != NULL, return);
FREE(delta->delta);
FREE(delta->delta_md5);
FREE(delta->from);
FREE(delta->to);
FREE(delta);
}
alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta)
{
alpm_delta_t *newdelta;
CALLOC(newdelta, 1, sizeof(alpm_delta_t), return NULL);
STRDUP(newdelta->delta, delta->delta, goto error);
STRDUP(newdelta->delta_md5, delta->delta_md5, goto error);
STRDUP(newdelta->from, delta->from, goto error);
STRDUP(newdelta->to, delta->to, goto error);
newdelta->delta_size = delta->delta_size;
newdelta->download_size = delta->download_size;
return newdelta;
error:
_alpm_delta_free(newdelta);
return NULL;
}
/* vim: set noet: */

View file

@ -1,7 +1,8 @@
/*
* sandbox_fs.h
* delta.h
*
* Copyright (c) 2021-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2007-2006 by Judd Vinet <jvinet@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
@ -16,12 +17,19 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ALPM_SANDBOX_FS_H
#define ALPM_SANDBOX_FS_H
#ifndef ALPM_DELTA_H
#define ALPM_DELTA_H
#include <sys/types.h> /* off_t */
#include <stdbool.h>
#include "alpm.h"
bool _alpm_sandbox_fs_restrict_writes_to(alpm_handle_t *handle, const char *path);
alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line);
void _alpm_delta_free(alpm_delta_t *delta);
alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta);
off_t _alpm_shortest_delta_path(alpm_handle_t *handle, alpm_list_t *deltas,
const char *to, alpm_list_t **path);
#endif /* ALPM_SANDBOX_FS_H */
#endif /* ALPM_DELTA_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* deps.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
@ -152,48 +152,12 @@ static alpm_list_t *dep_graph_init(alpm_handle_t *handle,
j = next;
}
vertex_i->iterator = vertex_i->children;
vertex_i->childptr = vertex_i->children;
}
alpm_list_free(localpkgs);
return vertices;
}
static void _alpm_warn_dep_cycle(alpm_handle_t *handle, alpm_list_t *targets,
alpm_graph_t *ancestor, alpm_graph_t *vertex, int reverse)
{
/* vertex depends on and is required by ancestor */
if(!alpm_list_find_ptr(targets, vertex->data)) {
/* child is not part of the transaction, not a problem */
return;
}
/* find the nearest ancestor that's part of the transaction */
while(ancestor) {
if(alpm_list_find_ptr(targets, ancestor->data)) {
break;
}
ancestor = ancestor->parent;
}
if(!ancestor || ancestor == vertex) {
/* no transaction package in our ancestry or the package has
* a circular dependency with itself, not a problem */
} else {
alpm_pkg_t *ancestorpkg = ancestor->data;
alpm_pkg_t *childpkg = vertex->data;
_alpm_log(handle, ALPM_LOG_DEBUG, _("dependency cycle detected:\n"));
if(reverse) {
_alpm_log(handle, ALPM_LOG_DEBUG,
_("%s will be removed after its %s dependency\n"),
ancestorpkg->name, childpkg->name);
} else {
_alpm_log(handle, ALPM_LOG_DEBUG,
_("%s will be installed before its %s dependency\n"),
ancestorpkg->name, childpkg->name);
}
}
}
/* Re-order a list of target packages with respect to their dependencies.
*
* Example (reverse == 0):
@ -215,7 +179,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
{
alpm_list_t *newtargs = NULL;
alpm_list_t *vertices = NULL;
alpm_list_t *i;
alpm_list_t *vptr;
alpm_graph_t *vertex;
if(targets == NULL) {
@ -226,35 +190,67 @@ alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
vertices = dep_graph_init(handle, targets, ignore);
i = vertices;
vptr = vertices;
vertex = vertices->data;
while(i) {
while(vptr) {
/* mark that we touched the vertex */
vertex->state = ALPM_GRAPH_STATE_PROCESSING;
int switched_to_child = 0;
while(vertex->iterator && !switched_to_child) {
alpm_graph_t *nextchild = vertex->iterator->data;
vertex->iterator = vertex->iterator->next;
if(nextchild->state == ALPM_GRAPH_STATE_UNPROCESSED) {
switched_to_child = 1;
vertex->state = -1;
int found = 0;
while(vertex->childptr && !found) {
alpm_graph_t *nextchild = vertex->childptr->data;
vertex->childptr = vertex->childptr->next;
if(nextchild->state == 0) {
found = 1;
nextchild->parent = vertex;
vertex = nextchild;
} else if(nextchild->state == ALPM_GRAPH_STATE_PROCESSING) {
_alpm_warn_dep_cycle(handle, targets, vertex, nextchild, reverse);
} else if(nextchild->state == -1) {
/* child is an ancestor of vertex */
alpm_graph_t *transvertex = vertex;
if(!alpm_list_find_ptr(targets, nextchild->data)) {
/* child is not part of the transaction, not a problem */
continue;
}
/* find the nearest parent that's part of the transaction */
while(transvertex) {
if(alpm_list_find_ptr(targets, transvertex->data)) {
break;
}
transvertex = transvertex->parent;
}
if(!transvertex || transvertex == nextchild) {
/* no transaction package in our ancestry or the package has
* a circular dependency with itself, not a problem */
} else {
alpm_pkg_t *transpkg = transvertex->data;
alpm_pkg_t *childpkg = nextchild->data;
_alpm_log(handle, ALPM_LOG_WARNING, _("dependency cycle detected:\n"));
if(reverse) {
_alpm_log(handle, ALPM_LOG_WARNING,
_("%s will be removed after its %s dependency\n"),
transpkg->name, childpkg->name);
} else {
_alpm_log(handle, ALPM_LOG_WARNING,
_("%s will be installed before its %s dependency\n"),
transpkg->name, childpkg->name);
}
}
}
}
if(!switched_to_child) {
if(!found) {
if(alpm_list_find_ptr(targets, vertex->data)) {
newtargs = alpm_list_add(newtargs, vertex->data);
}
/* mark that we've left this vertex */
vertex->state = ALPM_GRAPH_STATE_PROCESSED;
vertex->state = 1;
vertex = vertex->parent;
if(!vertex) {
/* top level vertex reached, move to the next unprocessed vertex */
for(i = i->next; i; i = i->next) {
vertex = i->data;
if(vertex->state == ALPM_GRAPH_STATE_UNPROCESSED) {
for( vptr = vptr->next; vptr; vptr = vptr->next) {
vertex = vptr->data;
if(vertex->state == 0) {
break;
}
}
@ -286,6 +282,12 @@ static int no_dep_version(alpm_handle_t *handle)
return (handle->trans->flags & ALPM_TRANS_FLAG_NODEPVERSION);
}
/** Find a package satisfying a specified dependency.
* The dependency can include versions with depmod operators.
* @param pkgs an alpm_list_t* of alpm_pkg_t where the satisfier will be searched
* @param depstring package or provision name, versioned or not
* @return a alpm_pkg_t* satisfying depstring
*/
alpm_pkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)
{
alpm_depend_t *dep = alpm_dep_from_string(depstring);
@ -297,6 +299,15 @@ alpm_pkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstri
return pkg;
}
/** Checks dependencies and returns missing ones in a list.
* Dependencies can include versions with depmod operators.
* @param handle the context handle
* @param pkglist the list of local packages
* @param remove an alpm_list_t* of packages to be removed
* @param upgrade an alpm_list_t* of packages to be upgraded (remove-then-upgrade)
* @param reversedeps handles the backward dependencies
* @return an alpm_list_t* of alpm_depmissing_t pointers.
*/
alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
alpm_list_t *pkglist, alpm_list_t *rem, alpm_list_t *upgrade,
int reversedeps)
@ -556,7 +567,7 @@ static void _alpm_select_depends(alpm_list_t **from, alpm_list_t **to,
for(i = *from; i; i = next) {
alpm_pkg_t *deppkg = i->data;
next = i->next;
if((explicit || alpm_pkg_get_reason(deppkg) == ALPM_PKG_REASON_DEPEND)
if((explicit || alpm_pkg_get_reason(deppkg) != ALPM_PKG_REASON_EXPLICIT)
&& _alpm_pkg_depends_on(pkg, deppkg)) {
*to = alpm_list_add(*to, deppkg);
*from = alpm_list_remove_item(*from, i);
@ -628,9 +639,10 @@ int _alpm_recursedeps(alpm_db_t *db, alpm_list_t **targs, int include_explicit)
* @param dep is the dependency to search for
* @param dbs are the databases to search
* @param excluding are the packages to exclude from the search
* @param prompt if true, ask an alpm_question_install_ignorepkg_t to decide
* if ignored packages should be installed; if false, skip ignored
* packages.
* @param prompt if true, will cause an unresolvable dependency to issue an
* interactive prompt asking whether the package should be removed from
* the transaction or the transaction aborted; if false, simply returns
* an error code without prompting
* @return the resolved package
**/
static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
@ -682,8 +694,9 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
}
for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
alpm_pkg_t *pkg = j->data;
if((pkg->name_hash != dep->name_hash || strcmp(pkg->name, dep->name) != 0)
&& _alpm_depcmp_provides(dep, alpm_pkg_get_provides(pkg))
/* with hash != hash, we can even skip the strcmp() as we know they can't
* possibly be the same string */
if(pkg->name_hash != dep->name_hash && _alpm_depcmp(pkg, dep)
&& !alpm_pkg_find(excluding, pkg->name)) {
if(alpm_pkg_should_ignore(handle, pkg)) {
alpm_question_install_ignorepkg_t question = {
@ -704,19 +717,20 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
}
_alpm_log(handle, ALPM_LOG_DEBUG, "provider found (%s provides %s)\n",
pkg->name, dep->name);
/* provide is already installed so return early instead of prompting later */
if(_alpm_db_get_pkgfromcache(handle->db_local, pkg->name)) {
alpm_list_free(providers);
return pkg;
}
providers = alpm_list_add(providers, pkg);
/* keep looking for other providers in the all dbs */
}
}
}
/* first check if one provider is already installed locally */
for(i = providers; i; i = i->next) {
alpm_pkg_t *pkg = i->data;
if(_alpm_db_get_pkgfromcache(handle->db_local, pkg->name)) {
alpm_list_free(providers);
return pkg;
}
}
count = alpm_list_count(providers);
if(count >= 1) {
alpm_question_select_provider_t question = {
@ -748,6 +762,15 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
return NULL;
}
/** Find a package satisfying a specified dependency.
* First look for a literal, going through each db one by one. Then look for
* providers. The first satisfier found is returned.
* The dependency can include versions with depmod operators.
* @param handle the context handle
* @param dbs an alpm_list_t* of alpm_db_t where the satisfier will be searched
* @param depstring package or provision name, versioned or not
* @return a alpm_pkg_t* satisfying depstring
*/
alpm_pkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_handle_t *handle,
alpm_list_t *dbs, const char *depstring)
{
@ -862,6 +885,11 @@ int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
return ret;
}
/** Reverse of splitdep; make a dep string from a alpm_depend_t struct.
* The string must be freed!
* @param dep the depend to turn into a string
* @return a string-formatted dependency with operator if necessary
*/
char SYMEXPORT *alpm_dep_compute_string(const alpm_depend_t *dep)
{
const char *name, *opr, *ver, *desc_delim, *desc;
@ -924,3 +952,4 @@ char SYMEXPORT *alpm_dep_compute_string(const alpm_depend_t *dep)
return str;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* deps.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
@ -39,3 +39,5 @@ int _alpm_depcmp_provides(alpm_depend_t *dep, alpm_list_t *provisions);
int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep);
#endif /* ALPM_DEPS_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* diskspace.c
*
* Copyright (c) 2010-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@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
@ -111,10 +111,6 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
while((mnt = getmntent(fp))) {
if(mnt->mnt_dir == NULL) {
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
STRDUP(mp->mount_dir, mnt->mnt_dir, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir_len = strlen(mp->mount_dir);
@ -138,10 +134,6 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
while((ret = getmntent(fp, &mnt)) == 0) {
if(mnt->mnt_mountp == NULL) {
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
STRDUP(mp->mount_dir, mnt->mnt_mountp, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir_len = strlen(mp->mount_dir);
@ -169,10 +161,6 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
for(; entries-- > 0; fsp++) {
if(fsp->f_mntonname == NULL) {
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
STRDUP(mp->mount_dir, fsp->f_mntonname, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir_len = strlen(mp->mount_dir);
@ -371,7 +359,7 @@ static int check_mountpoint(alpm_handle_t *handle, alpm_mountpoint_t *mp)
}
int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir,
size_t num_files, const off_t *file_sizes)
size_t num_files, off_t *file_sizes)
{
alpm_list_t *mount_points;
alpm_mountpoint_t *cachedir_mp;
@ -512,3 +500,5 @@ finish:
return 0;
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* diskspace.h
*
* Copyright (c) 2010-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@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
@ -43,7 +43,7 @@ enum mount_fsinfo {
MOUNT_FSINFO_FAIL,
};
typedef struct _alpm_mountpoint_t {
typedef struct __alpm_mountpoint_t {
/* mount point information */
char *mount_dir;
size_t mount_dir_len;
@ -58,6 +58,8 @@ typedef struct _alpm_mountpoint_t {
int _alpm_check_diskspace(alpm_handle_t *handle);
int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir,
size_t num_files, const off_t *file_sizes);
size_t num_files, off_t *file_sizes);
#endif /* ALPM_DISKSPACE_H */
/* vim: set noet: */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*
* dload.h
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -26,24 +26,13 @@
struct dload_payload {
alpm_handle_t *handle;
const char *tempfile_openmode;
/* name of the remote file */
char *remote_name;
/* temporary file name, to which the payload is downloaded */
char *tempfile_name;
/* name to which the downloaded file will be renamed */
char *destfile_name;
/* client has to provide either
* 1) fileurl - full URL to the file
* 2) pair of (servers, filepath), in this case ALPM iterates over the
* server list and tries to download "$server/$filepath"
*/
char *content_disp_name;
char *fileurl;
char *filepath; /* download URL path */
alpm_list_t *cache_servers;
alpm_list_t *servers;
long respcode;
/* the mtime of the existing version of this file, if there is one */
long mtime_existing_file;
off_t initial_size;
off_t max_size;
off_t prevprogress;
@ -51,22 +40,17 @@ struct dload_payload {
int allow_resume;
int errors_ok;
int unlink_on_fail;
int download_signature; /* specifies if an accompanion *.sig file need to be downloaded*/
int signature_optional; /* *.sig file is optional */
int trust_remote_name;
#ifdef HAVE_LIBCURL
CURL *curl;
char error_buffer[CURL_ERROR_SIZE];
int signature; /* specifies if this payload is for a signature file */
int request_errors_ok; /* per-request errors-ok */
CURLcode curlerr; /* last error produced by curl */
#endif
FILE *localf; /* temp download file */
};
void _alpm_dload_payload_reset(struct dload_payload *payload);
int _alpm_download(alpm_handle_t *handle,
alpm_list_t *payloads /* struct dload_payload */,
const char *localpath,
const char *temporary_localpath);
int _alpm_download(struct dload_payload *payload, const char *localpath,
char **final_file, const char **final_url);
#endif /* ALPM_DLOAD_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* error.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -90,8 +90,6 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
return _("transaction not initialized");
case ALPM_ERR_TRANS_DUP_TARGET:
return _("duplicate target");
case ALPM_ERR_TRANS_DUP_FILENAME:
return _("duplicate filename");
case ALPM_ERR_TRANS_NOT_INITIALIZED:
return _("transaction not initialized");
case ALPM_ERR_TRANS_NOT_PREPARED:
@ -125,11 +123,18 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
return _("package filename is not valid");
case ALPM_ERR_PKG_INVALID_ARCH:
return _("package architecture is not valid");
case ALPM_ERR_PKG_REPO_NOT_FOUND:
return _("could not find repository for target");
/* Signatures */
case ALPM_ERR_SIG_MISSING:
return _("missing PGP signature");
case ALPM_ERR_SIG_INVALID:
return _("invalid PGP signature");
/* Deltas */
case ALPM_ERR_DLT_INVALID:
return _("invalid or corrupted delta");
case ALPM_ERR_DLT_PATCHFAILED:
return _("delta patch failed");
/* Dependencies */
case ALPM_ERR_UNSATISFIED_DEPS:
return _("could not satisfy dependencies");
@ -137,7 +142,7 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
return _("conflicting dependencies");
case ALPM_ERR_FILE_CONFLICTS:
return _("conflicting files");
/* Miscellaneous */
/* Miscellaenous */
case ALPM_ERR_RETRIEVE:
return _("failed to retrieve some files");
case ALPM_ERR_INVALID_REGEX:
@ -154,11 +159,10 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
return _("gpgme error");
case ALPM_ERR_EXTERNAL_DOWNLOAD:
return _("error invoking external downloader");
/* Missing compile-time features */
case ALPM_ERR_MISSING_CAPABILITY_SIGNATURES:
return _("compiled without signature support");
/* Unknown error! */
default:
return _("unexpected error");
}
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* filelist.c
*
* Copyright (c) 2012-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2012-2016 Pacman Development Team <pacman-dev@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
@ -111,19 +111,19 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
/* Helper function for comparing files list entries
*/
static int _alpm_files_cmp(const void *f1, const void *f2)
int _alpm_files_cmp(const void *f1, const void *f2)
{
const alpm_file_t *file1 = f1;
const alpm_file_t *file2 = f2;
return strcmp(file1->name, file2->name);
}
alpm_file_t SYMEXPORT *alpm_filelist_contains(const alpm_filelist_t *filelist,
alpm_file_t SYMEXPORT *alpm_filelist_contains(alpm_filelist_t *filelist,
const char *path)
{
alpm_file_t key;
if(!filelist || filelist->count == 0) {
if(!filelist) {
return NULL;
}
@ -133,15 +133,4 @@ alpm_file_t SYMEXPORT *alpm_filelist_contains(const alpm_filelist_t *filelist,
sizeof(alpm_file_t), _alpm_files_cmp);
}
void _alpm_filelist_sort(alpm_filelist_t *filelist)
{
size_t i;
for(i = 1; i < filelist->count; i++) {
if(strcmp(filelist->files[i - 1].name, filelist->files[i].name) > 0) {
/* filelist is not pre-sorted */
qsort(filelist->files, filelist->count,
sizeof(alpm_file_t), _alpm_files_cmp);
return;
}
}
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* filelist.h
*
* Copyright (c) 2012-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2012-2016 Pacman Development Team <pacman-dev@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
@ -27,6 +27,8 @@ alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA,
alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
alpm_filelist_t *filesB);
void _alpm_filelist_sort(alpm_filelist_t *filelist);
int _alpm_files_cmp(const void *f1, const void *f2);
#endif /* ALPM_FILELIST_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* graph.c - helpful graph structure and setup/teardown methods
*
* Copyright (c) 2007-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2007-2016 Pacman Development Team <pacman-dev@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
@ -36,3 +36,5 @@ void _alpm_graph_free(void *data)
alpm_list_free(graph->children);
free(graph);
}
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* graph.h - helpful graph structure and setup/teardown methods
*
* Copyright (c) 2007-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2007-2016 Pacman Development Team <pacman-dev@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
@ -23,22 +23,18 @@
#include "alpm_list.h"
enum _alpm_graph_vertex_state {
ALPM_GRAPH_STATE_UNPROCESSED,
ALPM_GRAPH_STATE_PROCESSING,
ALPM_GRAPH_STATE_PROCESSED
};
typedef struct _alpm_graph_t {
typedef struct __alpm_graph_t {
void *data;
struct _alpm_graph_t *parent; /* where did we come from? */
struct __alpm_graph_t *parent; /* where did we come from? */
alpm_list_t *children;
alpm_list_t *iterator; /* used for DFS without recursion */
alpm_list_t *childptr; /* points to a child in children list */
off_t weight; /* weight of the node */
enum _alpm_graph_vertex_state state;
signed char state; /* 0: untouched, -1: entered, other: leaving time */
} alpm_graph_t;
alpm_graph_t *_alpm_graph_new(void);
void _alpm_graph_free(void *data);
#endif /* ALPM_GRAPH_H */
/* vim: set noet: */

View file

@ -1,7 +1,7 @@
/*
* group.c
*
* Copyright (c) 2006-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@ -49,3 +49,5 @@ void _alpm_group_free(alpm_group_t *grp)
alpm_list_free(grp->packages);
FREE(grp);
}
/* vim: set noet: */

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