1
0
forked from mirrors/pacman

Compare commits

...

567 Commits

Author SHA1 Message Date
Dan McGee
c5eccedc63 Bump version to 4.0.0rc1
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:45:27 -05:00
Dave Reisner
a58dc9283c pactest: add sync302 to test recursive syncfirst
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:36:58 -05:00
Dan McGee
0903452032 Enable recursive/needed sync on SyncFirst
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:36:50 -05:00
Dan McGee
dd865d2981 Merge branch 'maint'
Conflicts:
	scripts/repo-add.sh.in
2011-08-11 11:35:29 -05:00
Dan McGee
d0c64c4196 Attempt to update zsh_completion
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:29:49 -05:00
Dave Reisner
0bfefa87c8 bash_completion: update for adjusted options
Remove -k option excepting query operations and add --recursive for sync
and upgrade operations.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:29:49 -05:00
Dave Reisner
6e4f695a0f pacman: remove --dbonly shortopt
This is somewhat of a dangerous option with limited use cases. Don't
advertise it as an easily accessibly option.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:29:49 -05:00
Dan McGee
725edde73f Update trust level strings in -Qi display
It makes more sense to use the same tense and construction on all of
these.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:29:49 -05:00
Dan McGee
857357f940 Allow --needed and --recursive on -U operations
Trivial to implement as the same backend machinery is used anyway.
Document it and add it to the accepted options.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:29:46 -05:00
Dan McGee
f3fa77bcf1 Add -S --recursive operation
This closely matches what we had before for -R --recursive. Basically,
when specifying a target (e.g., pacman), we can now recursively pull all
dependencies, regardless of version specifiers and whether they are
already satisfied in the local database. This could be used to update
pacman on a system with an old glibc, for example, as both pacman and
glibc would get pulled into the transaction.

This is most useful with --needed to prevent needless reinstalls as
described in the man page changes.

The end goal of this change is to wire it into SyncFirst and have it be
the default mode of operation there, but that belongs in a separate
changeset.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:19:04 -05:00
Dan McGee
1f6afe6b0b Dependency code style cleanups
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:18:55 -05:00
Dan McGee
ca41470462 configure: simplify CARCH generation madness
Rather than a hardcoded list of only a few select architectures (of the
250+ case statements in config.guess), simply define CARCH to be the
first component of the "target triplet".

This introduces one "regression"- powerpc will no longer become ppc.
However, this is easily worked around in downstream distros if wanted.
This was the only CPU architecture with this oddity so it was felt worth
the price to make this change. Note that 'ppc64' wasn't handled in this
same odd fashion before anyway.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:18:48 -05:00
Dan McGee
f0803f6ece build: remove mucking with CARCHFLAGS
We've never received an update to this, and gcc has sane defaults out of
the box anyway, as do most projects in their build systems. Remove the
magic here and just let downstream distros handle any changes or
additions necessary, as we already do for LDFLAGS.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:18:39 -05:00
Dave Reisner
edd9ed6a3b stop progress callbacks after curl_easy_perform returns
This prevents possible null dereferences in FTP transfers when the
progress callback is touched during connection teardown.

http://curl.haxx.se/mail/lib-2011-08/0128.html

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:18:21 -05:00
Dave Reisner
c4112da8c3 dload: remove unnecessary cast in alpm_load_payload_free
Dan: make it compile, s/load/payload/.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-11 11:18:00 -05:00
Allan McRae
c493eef643 makepkg: fix removing symbolic link
The path was not being stripped from $file before prefixing with
$srcdir resulting in the attempted removal of a very weird
filename.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
(cherry picked from commit e92905a2c8)
2011-08-10 08:08:13 -05:00
Dan McGee
05608ee57e Fix stupid typo in NEWS file updates
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 19:52:15 -05:00
Dan McGee
82d45d66ca Merge branch 'maint'
Conflicts:
	src/pacman/callback.c
2011-08-09 16:24:55 -05:00
Dan McGee
5c1b83d9b1 Parse replaces strings as dep strings with version specs
This is done extremely crudely and is not very efficient, but it does
push us down the path of being closer to right, as one additional test
now passes.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 16:13:25 -05:00
Dan McGee
ce74f76a4c Conflict comparison performance enhancements
* Add *_hash fields to conflict struct and populate them
* Remove unnecessary backwards string comparisons

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 16:11:22 -05:00
Dan McGee
76dfea6e83 Update string catalogs after string tweaks
This also pulls in some early translations we had entered in Transifex
in the last day so those would not be lost. The diffstat is huge and not
very telling as usual, as all sorts of fuzzyness switches happened this
time around for some reason.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 16:00:48 -05:00
Dan McGee
5a6ebec7b2 Add a slightly simpler versioned replace test
It turns out we have a few problems here which are best tackled
independently. The first is simply parsing replacements as dep strings;
the second will be dealing with replaces when the original package name
still exists in the repository.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 15:46:11 -05:00
Dan McGee
96c4b1c303 Don't walk off front of string when stripping newline
If the string was zero-length to begin with, or consists of only newline
characters, nothing stopped us from incrementing right off the front of
the string. Ensure len stays above zero the whole time.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 15:41:18 -05:00
Dan McGee
a42e52a09f doc/pacman.conf: make SigLevel overview an unordered list
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 15:41:07 -05:00
Dan McGee
6803260f26 Fix compile error when curl is not used
Noticed in my PowerPC Linux VM:

    cc1: warnings being treated as errors
    dload.c:45: error: 'get_filename' defined but not used
    make[3]: *** [dload.lo] Error 1

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 15:40:21 -05:00
Dan McGee
40ea6cd607 Depend on name_hash being set
This is a fairly valid assumption at this point, or at least as good of
one as assuming packages all have names.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 15:38:54 -05:00
Dan McGee
9d3d647f00 pactest: improve speed of local DB dependent rules
We were doing some really silly stuff before and abusing the os.walk()
call, having to walk the entire local database for every single PKG
rule. We really only need top level directories, and we can cache any
generated package since calls to db_read() are well-defined and only
happen in one place.

This speeds up the running of tests that may want to add 100 PKG_VERSION
rules at once, where before we had to limit how many we used in order to
not put a serious cramp in the speed of the test suite run.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-09 15:36:05 -05:00
Dan McGee
5f38660be1 Add reason to corrupted package callback
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 19:55:44 -05:00
Dan McGee
9d09c9fdf7 Attempt to fix up some of the brokenness around failed package loads
This is a bit of a mess, due to the fact that we have a progress meter
running. It is also ironic that we are in the midst of a method named
"commit" when we haven't done a damn thing yet, and can still fail hard
if either a checksum or signature is invalid or unrecognized.

Adapt the former test_md5sum method to be invoked for any of the various
failure types, which at least gives the user some indication of what
packages are failing. A second patch will be needed to actually show
worthwhile error codes, but this is going to involve modifying the
actual data passed with the callback.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 19:42:52 -05:00
Dan McGee
1d16875db7 Update several translation strings
* Fix typos/capitalization
* Make sure large blocks of text are translated in one unit

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 19:01:26 -05:00
Dan McGee
21240d4746 Update transifex config for new translation layout
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 17:45:44 -05:00
Dan McGee
9a40927533 Update all translation files
This moves us toward staring translations for the 4.0.0 release,
although this should not be interpreted as a string freeze by any means.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 17:17:15 -05:00
Dan McGee
09f950af07 _alpm_access(): don't call gettext() in debug level loggers
This is standard procedure elsewhere and cuts down on translations that
won't be seen (and we don't want if we need English debug output
anyway).

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 17:11:14 -05:00
Dan McGee
8fa330335f Merge branch 'maint'
Conflicts:
	lib/libalpm/dload.c
	lib/libalpm/po/fi.po
	lib/libalpm/po/libalpm.pot
	po/de.po
	po/fi.po
	src/pacman/po/pacman.pot
	src/pacman/util.c
2011-08-08 17:05:25 -05:00
Dan McGee
ef4757afa5 Store a package info level flag if we fail to load data
If we are missing a local database file, we get repeated messages over
and over telling us the same thing, rather than being sane and erroring
only once. This package adds an INFRQ_ERROR level that is added to the
mask if we encounter any errors on a local_db_read() operation, and
short circuits future calls if found in the value. This fixes FS#25313.

Note that this does not make any behavior changes other than suppressing
error messages and repeated code calls to failure cases; we still have
more to do in the "local database is hosed" department.

Also make a small update to the wrong but unused flags set in
be_package; using INFRQ_ALL there was not totally correct.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:56:48 -05:00
Dan McGee
d9f9b87d3f Add a test harness for new pacsort command
Note that this is meant to exercise pacsort more than the underlying
version comparsion; that is better left to the standalone vercmptest.sh
test script.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:55:01 -05:00
Dave Reisner
1d37c19e04 mark option structs as const
These are never modified and even getopt_long's prototype shows this
modifier on the parameter.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:50:03 -05:00
Dave Reisner
5136df0f39 paccache: use pacsort instead of sort -V
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:49:56 -05:00
Dave Reisner
b283a1e065 src/util/Makefile.am: alphabetize targets
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:49:49 -05:00
Dave Reisner
0b57da2a43 pacsort: add new utility
pacsort is a command line sorting utility that implements libalpm's
alpm_pkg_vercmp algorithm.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:49:43 -05:00
Dan McGee
fab66f157d Bash-ify test/util/vercmptest.sh
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:49:19 -05:00
Dave Reisner
1a919a11b8 makepkg: ignore epoch when undeclared
In this case, we skip the epoch versioning entirely, as if it were
declared as 0.

Prevents errors such as:

/usr/bin/makepkg: line 244: ((: !  : syntax error: operand expected
(error token is " ")
==> Finished making: cower-git :20110808-1 (Mon Aug  8 17:17:27 EDT
2011)

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 16:47:47 -05:00
Dave Reisner
1e16b94a85 contrib/paccache: misc cleanup and bugfix
* change error verbiage when run as root
* delete sigs along with packages
* fix bug in diskspace calculations
* merge END block in pkgfilter

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 13:29:45 -05:00
Dan McGee
07a1292721 Check return value of rename() calls
We did a good job checking this in add.c, but not necessarily anywhere
else. Fix this up by adding checks into dload.c, remove.c, and conf.c in
the frontend. Also add loggers where appropriate and make the message
syntax more consistent.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-08 13:29:45 -05:00
Dan McGee
f10aea73e4 docs/pacman.conf: Document SigLevel option
This adds docs for SigLevel, which can exist in both [options] and
[repository] sections. It also does a bit of reworking of the structure
of this manpage and adds a labeled list under the repo sections where we
didn't have one before.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-02 08:25:23 -04:00
Dan McGee
b03b06cfd3 Implement parsing of the new SigLevel directive
Add code to conf.c that parses the new SigLevel directive. An
overwhelming number of options are presented, but most users will still
be fine with the Never/Optional/Required trio. More advanced users can
combine these or any of the other options on a 'SigLevel = ' line, which
is parsed in a left-to-right fashion and flags turned on and off
accordingly. For example, all three of these will net the same config:

    SigLevel = Required PackageOptional
    SigLevel = Optional DatabaseRequired
    SigLevel = DatabaseRequired PackageOptional

Additionally, database-specific lines assume you wish to start with any
global default that has been set. For example, if any of the above lines
were in the [options] section, something such as:

    SigLevel = PackageRequired PackageAllowMarginal

Would continue to enforce required database signatures.

Inspiration-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-02 08:25:09 -04:00
Dave Reisner
6997a738bb paccache: add new contrib script
paccache is a robust and flexible package cache cleaner with a variety
of options. Much credit goes to DJ Mills and Pat Brisbin for ideas
behind this script.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
[Dan: add .gitignore entry]
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-02 08:24:06 -04:00
Allan McRae
c55cbfbd5f pacman-key: follow gpg options for listing keys
The current --list option outputed the keys and all their signatures
which can be overly verbose.  It also did not take a list of keys on
the command line to limit its output (although the code suggests that
was intended).

That patch brings consistency with gpg, providing --list-keys and
--list-sigs options that function equivalently to those provided by
gpg.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-02 08:20:42 -04:00
Dan McGee
cbaff216b3 Don't trim whitespace when reading database entries
We don't write with extra or unknown whitespace, so there is little
reason for us to trim it when reading either. This also fixes the
hopefully never encountered "paths that start or end with spaces" issue,
for which two pactests have been added. The tests also contain other
evil characters that we have encountered before and handle just fine,
but it doesn't hurt to ensure we don't break such support in the future.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-02 08:20:34 -04:00
Dan McGee
573260556d pactest: use subprocess module instead of os.system
This is more in line with standard Python practice, and makes keyboard
interrupts behave a lot more sanely. It also prevents the useless
spawning of a shell as well as simplifies the command building and
working directory stuff.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-08-02 08:20:27 -04:00
Dan McGee
66d9995711 Revamp signing checks
This ensures we are actually making correct use of the information gpgme
is returning to us. Marginal being allowed was obvious before, but
Unknown should deal with trust level, and not the presence or lack
thereof of a public key to validate the signature with.

Return status and validity information in two separate values so check
methods and the frontend can use them independently. For now, we treat
expired keys as valid, while expired signatures are invalid.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-28 18:46:52 -05:00
Dan McGee
aecd0740cf Tidy up testdb to match coding styles
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-28 15:01:39 -05:00
Dan McGee
a3def7ac87 Make free_groupcache() private
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-28 15:01:31 -05:00
Dan McGee
dffff9659b Merge remote-tracking branch 'dave/scripts-fixup' 2011-07-28 12:48:38 -05:00
Dave Reisner
e42d97b737 scripts/pkgdelta: exit properly on missing args
Removes usage of 'nounset' which, when combined with 'errexit' can cause
undesirable early exits.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-28 13:10:10 -04:00
Dave Reisner
e99b6a131e scripts/repo-add: show usage when no DB file specified
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-28 13:07:25 -04:00
Dan McGee
cd8747ba6d Unify modelines in Asciidoc files
This gets us close to using the same modeline in all files we run
through Asciidoc, as well as adding the spell and spelllang
declarations, just as we had in NEWS already.

The choice of 'en_us' is mainly for consistency and because the body of
work already uses these spellings.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-28 11:42:08 -05:00
Pang Yan Han
804e2505cf pacman-key: Add --import and --import-trustdb
Currently, pacman-key allows the user to import their keys using the --add
option. However, no similar functionality exists for importing ownertrust
values.

The --import-trustdb option takes a list of directories and imports ownertrust
values if the directories have a trustdb.gpg database.

The --import option takes a list of directories and imports keys from
pubring.gpg and ownertrust values from trustdb.gpg. Think of it as a combination
of --add and --import-trustdb

Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:47:53 -05:00
DJ Mills
c5d4c92ad4 pacman-key: change GPG_PACMAN and GPG_NOKEYRING to arrays
Allows the commands to safely handle any possible arguments

Signed-off-by: DJ Mills <danielmills1@gmail.com>
Allan: rebase patch
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:47:46 -05:00
Allan McRae
d9875c5e6c pacman-key: fix syntax error in -r arg parsing
Previous fix did not work...

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:47:37 -05:00
Allan McRae
49d9426b6a makepkg: refactor checking source integrity
Move the source integrity checking into its own function as the code
was duplicated and is now more complicated with the separation of the
two checks types.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:47:23 -05:00
Allan McRae
2b3405e01b makepkg: more control of skipping integrity checks
Allows the skipping of all integrity checks (checksum and PGP) or
either the checksum or PGP checks individually.

Original-patch-by: Wieland Hoffman <theminew@googlemail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:47:13 -05:00
Wieland Hoffmann
94f61c5b29 makepkg: Add support for verifying pgp signatures
Many projects provide signature files along with the source code
archives. It's good to check these, too, when verifying the integrity
of source code archives.
Not everybody is using gpg so the verification can be disabled with
--skippgpcheck.
Additionally, only a warning is displayed when the key that signed the
source file is unknown.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:47:06 -05:00
Dan McGee
9929a34a6d Remove duplicate code shared between sync and upgrade
Pacman did a great job of having almost (but not quite) duplicate code
paths through the sync and upgrade code. We can use the same logic in
both upgrade in sync once the targets are resolved, so extract a
function and delete a bunch of code.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:46:15 -05:00
Allan McRae
ccdb2fa800 makepkg: get package version with overrides
When epoch, pkgver and/or pkgrel were overridden in a split package
function, makepkg failed hard finding the real version for checking
if packages were already built or trying to install packages. Fix
the get_full_version function to deal with overrides and return the
actual package version.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:45:25 -05:00
Allan McRae
03447ce39c makepkg: allow epoch to be overridden
We can override pkgver and pkgrel so it is only logical to add epoch
to that list

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:45:18 -05:00
Allan McRae
a7940e7419 makepkg: check arch overrides for required architecture
Check any overrides of the "arch" variable contain the required
architecture.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:45:12 -05:00
Allan McRae
819f675004 makepkg: check overrides for pkgrel and pkgver
Enforce syntax checking for pkgrel and pkgver overrides in package
functions.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:45:06 -05:00
Allan McRae
00949db191 makepkg: pkgver and pkgrel can not have whitespace
There is always someone who tries to break things (cough *Dave* cough...)

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:44:59 -05:00
Dan McGee
06974ebf2f contrib/pacsearch: skip non-matching lines
This prevents some perl errors from popping up when pacman prints error
or warning messages.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-27 12:44:17 -05:00
Dave Reisner
98073afe55 pacman-key: refactor post parse opt check into a case
This is a cleaner expression of the same information.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-21 15:05:52 -05:00
Dave Reisner
768d3589a3 pacman-key: s/UPDATEBD/UPDATEDB/
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-21 15:05:39 -05:00
Dave Reisner
2bd1687f51 pacman-key: fix syntax error in -r arg parsing
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-21 15:05:30 -05:00
Dave Reisner
9f500f684d pacman-key: return $ret, not errors
fixes: /usr/bin/pacman-key: line 286: return: errors: numeric argument required

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-21 15:04:49 -05:00
Dan McGee
bb3dada871 Convert package filelists to an array instead of linked list
This accomplishes quite a few things with one rather invasive change.

1. Iteration is much more performant, due to a reduction in pointer
   chasing and linear item access.
2. Data structures are smaller- we no longer have the overhead of the
   linked list as the file struts are now laid out consecutively in
   memory.
3. Memory allocation has been massively reworked. Before, we would
   allocate three different pieces of memory per file item- the list
   struct, the file struct, and the copied filename. What this resulted
   in was massive fragmentation of memory when loading filelists since
   the memory allocator had to leave holes all over the place. The new
   situation here now removes the need for any list item allocation;
   allocates the file structs in contiguous memory (and reallocs as
   necessary), leaving only the strings as individually allocated. Tests
   using valgrind (massif) show some pretty significant memory
   reductions on the worst case `pacman -Ql > /dev/null` (366387 files
   on my machine):

   Before:
     Peak heap:   54,416,024 B
	 Useful heap: 36,840,692 B
	 Extra heap:  17,575,332 B

   After:
     Peak heap:   38,004,352 B
	 Useful heap: 28,101,347 B
	 Extra heap:   9,903,005 B

Several small helper methods have been introduced, including a list to
array conversion helper as well as a filelist merge sort that works
directly on arrays.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-21 15:04:30 -05:00
Dan McGee
058ee17371 contrib: add paclog-pkglist to gitignore
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-21 15:03:33 -05:00
Dan McGee
70d6fe6632 Clean up my debug logger mess
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-19 00:23:42 -05:00
Dan McGee
61410814c2 Merge remote-tracking branch 'allan/pacman-key' 2011-07-18 21:10:56 -05:00
Dan McGee
05f7c0280e Fix test suite when GPGME is disabled
As noted by Allan, we failed pretty hard if gpgme was compiled out. With
these changes, only sign001.py fails. This can/will be fixed later once
we beef up the test suite with more signing tests anyway.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 21:06:24 -05:00
Dave Reisner
f1d25ba2dd pacman/callback: show .sig suffix on sig download
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 21:01:12 -05:00
Pang Yan Han
333269482a pacman-key: --init: correct creation of gpg.conf
Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Pang Yan Han
fa3aaa41e3 pacman-key: correct spelling mistake
Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Allan McRae
7e5dea5d32 pacman-key: add dependency on parse_options to Makefile
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Allan McRae
31c9a521b4 pacman-key: check required permissions on keyring
Makes sure that the pacman keyring is readable and that the user
has permissions to create a lock file if lock-never is not specified
in the gpg.conf file.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Allan McRae
0c9e86bab1 pacman-key: add --init option
Add an --init option that ensures that the pacman keyring has all
the necessary files and they have the correct permissions for being
read as a user.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Dave Reisner
0be9e4a4cd pacman-key: tidy up logic for finding pacman keyring directory
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Dave Reisner
df7b390514 pacman-key: refactor get_from
This function had a variety of pitfalls, including the inability to
successfully find a key=value pair where no whitespace surrounded the
equals sign. Make it more robust by splitting the line on the equals
itself, and performing whitespace trimming on the resulting key/value
pair.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Allan McRae
0e85c4989b pacman-key: add --verify option
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:54 +10:00
Allan McRae
fec10d4a65 pacman-key: check only a single operation has been specified
Follow the example of gpg and only allow a single operation to be
specified each time.  Prevents having to deal with conflicting
variable names and potential issues due to the order in which the
operations are run.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
74f6d717a3 pacman-key: move verifying keyring files to own function
Also check all files before bailing on errors.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
74e5a494b0 pacman-key: move --edit-key and --receive processing to functions
This moves the processing of the --edit-key and --receive options
to functions, keeping the final option processing to be all single
line statements.

Also rework the --edit-key option to validate all input before
processing.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
7963c5d000 pacman-key: update man page
Update man page to reflect current options.  Also add a description
on how to manually interact with the pacman keyring with gpg.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Ivan Kanakarakis
e37adcd664 pacman-key: hide output of executed commands on logic checks
This commit correctly redirects to /dev/null the output of several
commands that get executed on logic checks.

Original-patch-by: Denis A. Altoé Falqueto <denisfalqueto@gmail.com>
Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
e458606ad2 pacman-key: rename --trust to --edit-key
This keeps the naming of the option more consistent with what is
actually being called by gpg.

Original-patch-by: Denis A. Altoé Falqueto <denisfalqueto@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Ivan Kanakarakis
15ca6dca5c pacman-key: fix quotation on several variable assignments
This commit adds quotes to several variable assignments. Unquoted values
can cause problems on several occasions if the value is empty. It is
safer to have every assignment quoted.

Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
2011-07-19 10:27:53 +10:00
Allan McRae
b300b991a7 pacman-key: allow the export of all key ids
The gpg --export will exprt all keys if none are specified. Replicate
this behavior in pacman-key.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
8ee0724558 pacman-key: rename --del to --delete
There is already the short -d alias provided, so stay verbose with
the longer option name.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
95d7e16163 pacman-key: remove the --adv option
The conversion to using parse_options causes this option to break.
It is preferable to remove the option rather than fix it as it is
simply a wrapper for "gpg --homedir @sysconfdir@/pacman.d/gnupg".
Any user using more advanced keyring management than provided by
pacman-key can manage to point gpg at the right place themselves...

How to manually edit the keyring with gpg will instead be documented
in the man page in a later commit.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Allan McRae
7d205a70a2 pacman-key: use our option parser
The pacman-key script is complicated enough to warrent usage of the
parse_options script.  This is especially helpful in dealing with
all the configuration file override flags as the no longer need to
be specified first.  It also allows us to do the right thing early
with --help/--version and no option cases cleanly. This change also
makde the check for root privileges only occur on operations where
they are needed.

This patch is inspired by and supercedes some patches submitted by
Denis A. Altoé Falqueto and Ivan Kanakarakis who were altering the
previous option handling in an attempt to deal with the above issues.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-19 10:27:53 +10:00
Dave Reisner
d86a60c694 PKGBUILD.vim: add new var and assert bash syntax
* assert is_bash to pickup more valid syntax
* add checkdepends highlighting

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-18 11:50:47 -04:00
Florian Pritz
dad96ccce2 replace access() calls for debug info where applicable
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:44:28 -05:00
Florian Pritz
89c070b263 signing.c: check if needed files are readable
If we can't read the keyring, gpgme will output confusing debug
information and fail to verify the signature, so we should log some
debug information.

Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:44:07 -05:00
Florian Pritz
29a96bcfe1 add _alpm_access() wrapper
This is a wrapper function for access() which logs some debug
information and eases handling in case of split directory and filename.

Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:42:48 -05:00
Dan McGee
48e2a1a119 Merge branch 'maint' 2011-07-18 10:41:37 -05:00
Allan McRae
c0fe1743e5 Fix compilation without gpgme
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:36:41 -05:00
Allan McRae
f0e34be990 configure: output more compile settings
Add information on CPPFLAGS, LDFLAGS and LIBS to the end of the
configure output. This is very helpful in tracing issues when
adjusting the configure file and also will allow us to more
easily replicate any issues discovered due to a users build
environment.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:36:28 -05:00
Allan McRae
36db8c5047 makepkg.conf: remove curl from other common tools
It is now set as the main tool, so make wget another common one.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:36:13 -05:00
Allan McRae
49427d1fb4 repo-add: do not print full path of signature file
The full path to the signature file when it is created is in a temporary
directory so only print the filename.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:35:57 -05:00
Allan McRae
bf120635a7 repo-add: always remove repo signature symlink
This prevents a dangling symlink being left behind if the repo goes
from being signed to unsigned.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:35:47 -05:00
Dave Reisner
3934a842b8 contrib/paclog-pkglist: whitespace cleanup
add a modeline and change 2 space indent to a tab.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:35:12 -05:00
Dave Reisner
3294039a00 contrib/paclog-pkglist: rework as bash wrapping awk
Avoid some pain in awk's limited handling of command line arguments by
wrapping this in a Bash script. We also default to
@localstatedir@/log/pacman.log when no args are specified, meaning that
-h or --help is required to get the help message.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:34:56 -05:00
Dan McGee
0b92d9ed9c Add a new epoch pactest
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:34:39 -05:00
Dan McGee
1c39e4fbad Handle removal of empty directories properly
This addresses FS#25141. We shouldn't remove every empty directory we
come across during the removal process unless it is truly not known to
any other package. This will prevent removal of essential directories
such as '/var/lock/'.

This is accomplished by first checking the empty/non-empty status of a
directory, which was previously done implicitly by calling rmdir() and
ignoring errors. We do this to avoid the next (new) check in most cases,
which is to look at all local packages to see if the to-be-removed
directory is present in another packages' filelist. If we do not find it
anywhere, then we remove it, else we keep the file around.

The pactest has been updated to test more cases, as well as finding a
flaw in the original expected to fail case- we need separate DIR and
FILE based EXIST rules.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:34:05 -05:00
Rogutės Sparnuotos
3a04267cdd makepkg: only test for writable PKGDEST when needed.
There is no need for a writable PKGDEST when using the --nobuild or
--geninteg flags.

Allan: added --geninteg
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:28:19 -05:00
Allan McRae
65847fad44 Move some .gitignore entries
Put a .gitignore entry at the right level and sort that file
alphabetically.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-18 10:28:19 -05:00
Dan McGee
e209955606 doc/PKGBUILD: clarify scriptlet version arguments
It was a bit unclear that both pkgver and pkgrel were included in the
passed version strings; clarify this fact in the manpage. Also include
epoch in the mix now that it exists.

Also make two other minor consistency touchups to code-print variables
in text.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 16:12:15 -05:00
Dan McGee
8f72ffbc45 Make alpm_db_set_pkgreason() arguments more sane
This can only ever operate on the local database, and a local package at
that. Change the function signature to take a handle and package object,
add the relevant asserts, and ensure the frontend can detect the package
not found condition when finding packages to pass to this method.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 15:59:57 -05:00
Dave Reisner
0fe93bc34c contrib/paclog-pkglist: new contribution
converts a pacman log file to a list of installed packages, which should
match the output of `pacman -Q'.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 15:49:34 -05:00
Dave Reisner
1376ba5b0e contrib/bash_completion: update with new makepkg opts
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 15:49:21 -05:00
Dave Reisner
6907a22b27 makepkg: remove unused -C option from option list
We nuke it from the completion file as well along with its longopt.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 15:49:13 -05:00
Dave Reisner
727e03fe19 makepkg: skip devel_check when reading from a pipe
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 15:44:48 -05:00
DJ Mills
282be6bf4b makepkg: Remove pre-optimization from in_array()
The '[[ -z' test in in_array() is redundant, so remove it.

Signed-off-by: DJ Mills <danielmills1@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-14 15:42:37 -05:00
DJ Mills
7f5b24597b makepkg: Remove OPT_TEMP hack in parse_options call
Instead of hacking around the error trap, simply do an explicit
test for failure.

Signed-off-by: DJ Mills <danielmills1@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-14 15:42:29 -05:00
Dan McGee
af357d6ab0 Allow fileconflict if unowned file moving into backup array
The bulk of this commit is adding new tests to ensure the new behavior
works without disrupting old behavior. This is a relatively sane maneuver
when a package adds a conf file (e.g. '/etc/mercurial/hgrc') that was
not previously in the package, but it is placed in the backup array. In
essence, we can treat the existing file as having always been a part of
the package and do our normal compare/install as pacnew logic checks.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 15:34:04 -05:00
Dan McGee
36e48573ce Add 'compress' compression format as an available option
This adds the '.tar.Z' option to both repo-add and makepkg for no other
reason than "why not", and because bsdtar supports it natively with the
'-Z' flag. Also update the documentation accordingly.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-14 14:58:46 -05:00
Dan McGee
00628c7268 Unify package removal code
This code duplication has always been a rather clumsy casuality of
fixing some past upgrade issues. Unify the removal code across upgrade
and remove operations into  a new _alpm_remove_single_package() method
wihch makes it very clear how we handle upgrade and remove differently,
via several conditionals on newpkg.

This commit highlights interesting behavior such as the fact that the
implicit removal in every package upgrade never gets transaction events
or progress callbacks.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-06 09:26:09 -05:00
Dan McGee
1d53dd716d include util.h in rawstr.c
Fixes "error: no previous prototype for '_alpm_raw_cmp'
[-Werror=missing-prototypes]" warnings, and also prevents someone from
getting the prototypes and functions out of sync.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 22:36:40 -05:00
Dan McGee
b678e00271 Merge remote-tracking branch 'dave/download' 2011-07-05 22:01:29 -05:00
Dave Reisner
57eac093c4 absorb fileinfo struct into dload_payload
This transitional struct becomes delicious noms for dload_payload.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-05 23:00:03 -04:00
Dave Reisner
3eec745910 absorb some _alpm_download params into payload struct
Restore some sanity to the number of arguments passed to _alpm_download
and curl_download_internal.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-05 23:00:02 -04:00
Dave Reisner
6dc71926f9 lib/dload: prevent large file attacks
This means creating a new struct which can pass more descriptive data
from the back end sync functions to the downloader. In particular, we're
interested in the download size read from the sync DB. When the remote
server reports a size larger than this (via a content-length header),
abort the transfer.

In cases where the size is unknown, we set a hard upper limit of:

* 25MiB for a sync DB
* 16KiB for a signature

For reference, 25MiB is more than twice the size of all of the current
binary repos (with files) combined, and 16KiB is a truly gargantuan
signature.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-05 22:58:55 -04:00
Dave Reisner
6c9b82e72a dload: handle irregular URLs
URLs might end with a slash and follow redirects, or could be a
generated by a script such as /getpkg.php?id=12345. In both cases, we
may have a better filename that we can write to, taken from either
content-disposition header, or the effective URL.

Specific to the first case, we write to a temporary file of the format
'alpmtmp.XXXXXX', where XXXXXX is randomized by mkstemp(3). Since this
is a randomly generated file, we cannot support resuming and the file is
unlinked in the event of an interrupt.

We also run into the possibility of changing out the filename from under
alpm on a -U operation, so callers of _alpm_download can optionally pass
a pointer to a *char to be filled in by curl_download_internal with the
actual filename we wrote to. Any sync operation will pass a NULL pointer
here, as we rely on specific names for packages from a mirror.

Fixes FS#22645.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-07-05 22:58:27 -04:00
Allan McRae
eda741ae93 repo-add: backup old database signature too
If you are keeping a copy of the old database, you probably want
to keep a copy of its signature too.  Also, delete the previously
backed-up database signature if no new one is being copied.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 21:40:26 -05:00
Dan McGee
043931ca45 Rework -Si display logic
We did some funny stuff here before to allow specifying fully-qualified
package names, such as 'testing/gcc' or 'core/gcc'. However, it was done
by duplicating code, not to mention an early escape if a repository
could not be found for an early target. Something like `pacman -Si
foo/bar core/gcc' would not give expected results, although `pacman -Si
bar gcc' would.

Clean up the code, remove strncpy() usage, and clarify the error
messages a bit.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 21:38:32 -05:00
Allan McRae
e2f00abe26 pacman-key: fix syntax highlighting
The lone quotation mark in "pacman's" causes issues for some syntax
highlighting. Change the printing of the nessage from echo to printf
so we can invisibly escape it.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 21:38:07 -05:00
Dave Reisner
62880d7568 contrib/paclist: rewrite in bash
The original concept for this script was a bash implementation, but
turned out to be unreasonable at the time due to the efficiencies of the
database format. Since those have been resolved, we can rewrite this in
bash as a much simpler script.

All the action happens in a single line, but we add extend this a
little, binding to gettext to keep our pacman translations intact.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 21:37:18 -05:00
Florian Pritz
36474af463 fix segfault if pacman.conf can't be read
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 21:36:46 -05:00
Dan McGee
ae7139adcf Remove most usages of strncmp()
The supposed safety blanket of this function is better handled by
explicit length checking and usages of strlen() on known NULL-terminated
strings rather than hoping things fit in a buffer. We also have no need
to fully fill a PATH_MAX length variable with NULLs every time as long
as a single terminating byte is there. Remove usages of it by using
strcpy() or memcpy() as appropriate, after doing length checks via
strlen().

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 21:29:02 -05:00
Dave Reisner
44889da5b7 dload: rearrange code to avoid extra cpp block
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-05 17:18:23 -04:00
Dave Reisner
6cce517f1a lib/rawstr: borrow raw string functions from curl
We'll need these functions to do locale agnostic and case insensitive
string comparisons.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
2011-07-05 17:18:23 -04:00
Allan McRae
dfc532668d makepkg: update --pkg desciption in man page
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:45 -05:00
Allan McRae
77a93328cf Add library files to POTFILES.in
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:37 -05:00
Allan McRae
bfd6d22be2 parse_options: accept multiple arguments
Allow command-line options to accept multiple arguments without
additional quoting by taking the list of arguments until one
starting with a "-" is reached.

The only current use of this is the --pkg option in makepkg.  This
allows (e.g.)

makepkg --pkg foo bar

and packages "foo" and "bar" will be built.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:31 -05:00
Allan McRae
87ee38d8b3 parse_options: implement optional arguments
This allows options specified with a trailing "::" to optionally
take arguments.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:25 -05:00
Allan McRae
ddb8617d96 parse_options: add missing newlines
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:20 -05:00
Allan McRae
24324ff0e1 Simplify alpm_list_previous
We can readily detect the first node in a list by checking if
node->prev->next is NULL. So there is no need to pass the head
of the list to this function and its prototype now looks like
all the other item accessors.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:11 -05:00
Allan McRae
97103f860d Remove alpm_list_first
The only thing this accessor did was remove the const qualifier
given our entire list implementation requires passing around the
head anyway.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:22:05 -05:00
Dan McGee
c748eadc80 Allow invalid sync DBs to be returned by the library
They are placeholders, but important for things like trying to re-sync a
database missing a signature. By using the alpm_db_validity() method at
the right time, a client can take the appropriate action with these
invalid databases as necessary.

In pacman's case, we disallow just about anything that involves looking
at a sync database outside of an '-Sy' operation (although we do check
the validity immediately after). A few operations are still permitted-
'-Q' ops that don't touch sync databases as well as '-R'.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:13:20 -05:00
Dan McGee
07502f2d82 Allow frontend access to signature verification information
Show output in -Qip for each package signature, which includes the UID
string from the key ("Joe User <joe@example.com>") and the validity of
said key. Example output:

Signatures     : Valid signature from "Dan McGee <dpmcgee@gmail.com>"
                 Unknown signature from "<Key Unknown>"
                 Invalid signature from "Dan McGee <dpmcgee@gmail.com>"

Also add a backend alpm_sigresult_cleanup() function since memory
allocation took place on this object, and we need some way of freeing
it.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:13:20 -05:00
Dan McGee
e8443b1685 Correctly check the GPG error codes
The error code is in fact a bitmask value of an error code and an error
source, so use the proper function to get only the relevant bits. For
the no error case, this shouldn't ever matter, but it bit me when I was
trying to compare the error code to other values and wondered why it
wasn't working, so set a good example.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:13:20 -05:00
Dan McGee
7af0ab1cde signing: move to new signing verification and return scheme
This gives us more granularity than the former Never/Optional/Always
trifecta. The frontend still uses these values temporarily but that will
be changed in a future patch.

* Use 'siglevel' consistenly in method names, 'level' as variable name
* The level becomes an enum bitmask value for flexibility
* Signature check methods now return a array of status codes rather than
  a simple integer success/failure value. This allows callers to
  determine whether things such as an unknown signature are valid.
* Specific signature error codes mostly disappear in favor of the above
  returned status code; pm_errno is now set only to PKG_INVALID_SIG or
  DB_INVALID_SIG as appropriate.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-05 10:13:20 -05:00
Dan McGee
1ce7f39ad7 Merge remote-tracking branch 'allan/ALPM'
Conflicts:
	lib/libalpm/be_local.c
	lib/libalpm/be_package.c
	lib/libalpm/conflict.c
	lib/libalpm/diskspace.c
	lib/libalpm/dload.c
	lib/libalpm/remove.c
2011-07-03 14:44:57 -05:00
Dan McGee
c839415e3f conflict code tweaks and cleanups
We can take advantage of a few things on our new and improved filelist
in this code.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 14:29:30 -05:00
Dan McGee
26195f8da1 diskspace: remove all libarchive usage
Now that the filelists capture mode and size information, we can read
the data from there and prevent having to loop through and uncompress
every archive to check required diskspace usage.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 14:29:30 -05:00
Dan McGee
6a6fc3107f Move alpm filelists to a struct object
This allows us to capture size and mode data when building filelists
from package files. Future patches will take advantage of this newly
available information, and frontends can use it as well.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 14:29:30 -05:00
Dan McGee
a2995f586e pactest: add a few more checks to fileconflict checks
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:44:45 -05:00
Dan McGee
06840f14b4 Fix debug logger without a newline
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:44:26 -05:00
Allan McRae
a7b02d07f4 Do not replicate files list when removing packages
This saves replicating the potentially large list of files in a package
that is being removed.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:42:43 -05:00
Allan McRae
ab79b13079 Add alpm_list_previous method
Helper function to get the previous item in a list

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:42:24 -05:00
Dan McGee
f612e5ede7 checkdeps: remove unnecessary list join and copy
We can just perform the same search operation on both lists.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:39:13 -05:00
Dan McGee
925d74f38d be_local: use macros in database loading similar to be_sync
This removes some of the repetition in the code for reading and parsing
database file lines.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:37:04 -05:00
Dan McGee
de8b9a85a5 be_sync: make READ_NEXT() a no-arg macro
We passed in 'line', but not 'buf.line'. In addition, the macros
building off of READ_NEXT() assume variable names anyway. Since we only
use these macros in one function, might as well simplify them.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-03 13:07:19 -05:00
Allan McRae
afc96f2ab3 Prefix _alpm_errno_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:39 +10:00
Allan McRae
bd88a8d551 Prefix alpm_transprog_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:39 +10:00
Allan McRae
495ba26e63 Prefix alpm_transconv_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:39 +10:00
Allan McRae
3189d3bc4a Prefix alpm_transevt_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:39 +10:00
Allan McRae
39262acab6 Prefix alpm_transflag_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:39 +10:00
Allan McRae
ca43fdd92f Prefix alpm_loglevel_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:38 +10:00
Allan McRae
d796d1cdda Prefix alpm_fileconflicttype_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:38 +10:00
Allan McRae
f818f570c5 Prefix alpm_depmod_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:38 +10:00
Allan McRae
eb39a9482b Prefix alpm_pkgreason_t members with ALPM
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-07-02 02:01:38 +10:00
Dan McGee
cf1401a04d signing: check validity of all available signatures
Change the check into a loop over all signatures present and returned by
GPGME. Also modify the return values and checks slightly now that I know
a little bit more about what type of values are returned.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 17:25:53 -05:00
Dan McGee
23a2d2c16a Make alpm_db_get_sigverify_level() public
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 16:16:41 -05:00
Dan McGee
68284da0d7 Add an alpm_db_get_valid() public function
This allows one to check if a database is valid or invalid.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 16:05:20 -05:00
Dave Reisner
6633b8e5c2 move proto files to new subdirectory, proto/
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 13:37:58 -05:00
Dave Reisner
98a2fc8deb pacman: return with 128+signum on signaled exit
This is a convention that is widely followed in *nix and posix-ish
environments. We should follow it, too.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 12:43:57 -05:00
Dan McGee
35ffe6af2d pactest: remove no longer necessary newline hacks
libalpm can now cope with this as of commit 719e0d3ddb.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 12:02:33 -05:00
Dan McGee
0ed848a9ea pactest: create packages in memory
This is similar to what was just done for the sync databases. Move a few
pieces around so we never need to actually write out the filesystem to
create a package, and simply stream the tarfile out from the data we've
collected.

Once again, a few newline addition hacks and other things have to be
left in place in order not to break everything; this time however most
of the assumptions are in pactest and not libalpm.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 11:55:00 -05:00
Dan McGee
13235ba65a Make local_db_read() private to the local backend
There is little need to expose the guts of this function even within the
library. Make it static in be_local.c, and clean up a few other things
since we know exactly where it is being called from:

* Remove unnecessary origin checks in _cache_get_*() methods- if you are
  calling a cache method your package type will be correct.
* Remove sanity checks within local_db_read() itself- packages will
  always have a name and version if they get this far, and the package
  object will never be NULL either.

The one case calling this from outside the backend was in add.c, where
we forced a full load of a package before we duplicated it. Move this
concern elsewhere and have pkg_dup() always force a full package load
via a new force_load() function on the operations callback struct.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 11:51:49 -05:00
Dan McGee
b94e8ecd1f Fix a few warnings pointed out via clang scan-build
Some of these are legit (the backup hash NULL checks), while others are
either extemely unlikely or just impossible for the static code
analysis to prove, but are worth adding anyway because they have little
overhead.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 11:51:36 -05:00
Florian Pritz
9efd10cd2a fix vim syntax highlighting of .sh files
vim recognises what type of shell script it's dealing with by looking at
the shebang. If detection fails it falls back to sh which doesn't
support some bash features. Adding a normal, possibly broken, shebang
which gets fixed by the Makefile allows vim to detect bash syntax.

Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:44:45 -05:00
Dan McGee
c2cce4f3f5 Merge remote-tracking branch 'dave/makepkg' 2011-06-30 10:41:49 -05:00
Dan McGee
ad577b3cb4 Merge remote-tracking branch 'allan/breakshit' 2011-06-30 10:37:08 -05:00
Dave Reisner
0f4aaeee42 lib/util: modify entry_prefix, not prefix
Modifying prefix caused tmp directories to be left behind after
running scriptlets, and the path '/' to be passed to _alpm_rmrf. Broken
in f01c6f.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:34:32 -05:00
Dave Reisner
002d2fda7a lib/alpm: unlock the handle before freeing it
This avoids, probably among other things, leaving the lock file in place
after a SIGINT'd sync DB update.

Fixes regression introduced in 4f8ae2b.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:33:24 -05:00
Dave Reisner
2860ade2f5 repo-add.sh.in: avoid being clever with repo repacking
Revert to the old behavior that 6f5a90 attempted to simplify and go with
the original proposed solution of using "ugly" bash to detect empty
directories.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:32:15 -05:00
Dan McGee
84974ed04c repo-add: fix db creation one last time
We fubar-ed this pretty good.

1. The whole old/new move shuffle was totally busted if you used a
relative path to your database, as we would just build the database in
place.
2. Our prior temp directory layout had the database files extracted
directly into it. When we tried to create a xxx.db.tar.gz file in this
same directory, due to the fact that we were no longer using a shell
wildcard, we tried to include the db in ourself, which is a big failure.
Fix all this by extracting to tree/ so we can have a clean top-level
temp directory.
3. Fix the inclusion of the './' directory entry; ensure the regex
prunes both leading paths of '.' as well as './'.

Where is that test suite again?

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:29:55 -05:00
Dan McGee
c2e6a01a28 makepkg: only source user override if using default config file
Otherwise there is no way to easily test or run with a standalone config
file without outside interference.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:29:49 -05:00
Rémy Oudompheng
4c80f994c3 makepkg: fix typo (missing quotes)
Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:28:24 -05:00
Allan McRae
e92905a2c8 makepkg: fix removing symbolic link
The path was not being stripped from $file before prefixing with
$srcdir resulting in the attempted removal of a very weird
filename.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-30 10:28:18 -05:00
Allan McRae
fed3e09c94 Use ignoregroup rather than ignoregrp in the handle
This matches the naming in pacman.conf.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-29 16:00:25 +10:00
Allan McRae
b1894ccf06 Rename internal functions with grp in their name
The following function renames take place for the same reasoning as
the previous commit:

  _alpm_grp_new -> _alpm_group_new
  _alpm_grp_free -> _alpm_group_free
  _alpm_db_free_grpcache -> _alpm_db_free_groupcache
  _alpm_db_get_grpfromcache -> _alpm_db_get_groupfromcache

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-29 15:52:33 +10:00
Allan McRae
f1bb56cebf Rename public functions with grp in their name
Using grp instead of group is a small saving at the cost of clarity.
Rename the following functions:

  alpm_option_get_ignoregrps -> alpm_option_get_ignoregroups
  alpm_option_add_ignoregrp -> alpm_option_add_ignoregroup
  alpm_option_set_ignoregrps -> alpm_option_set_ignoregroups
  alpm_option_remove_ignoregrp -> alpm_option_remove_ignoregroup
  alpm_db_readgrp -> alpm_db_readgroup
  alpm_db_get_grpcache -> alpm_db_get_groupcache
  alpm_find_grp_pkgs -> alpm_find_group_pkgs

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-29 15:46:49 +10:00
Dave Reisner
9a29888ba7 makepkg: simplify SIGNPKG check
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-28 23:15:58 -04:00
Dave Reisner
5f6e8c9274 makepkg: fix vim syntax highlighting
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-28 23:05:57 -04:00
Dave Reisner
452bf71cec makepkg: remove unneeded echo
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-28 23:05:57 -04:00
Allan McRae
3bb469d558 Update README with changes to struct names
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
7633c14bd5 Rename _pmdbstatus_t to _alpm_dbstatus_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
028b965e1a Rename pmdbinfrq_t to alpm_dbinfrq_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
925f42e460 Rename pmtransstate_t to alpm_transstate_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
71fa9f912d Rename pmpkghash_t to alpm_pkghash_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
57b9b19b10 Rename pmgraph_t to alpm_graph_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
08fc1db24c Rename pmpkgfrom_t to alpm_pkgfrom_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
ddad400900 Rename pmerrno_t to alpm_errno_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
1059df7486 Rename pmtransprog_t to alpm_transprog_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
565e167356 Rename pmtransconv_t to alpm_transconv_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
011ef6be0e Rename pmtransevt_t to alpm_transevt_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
590a8fcb1e Rename pmtransflag_t to alpm_transflag_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
0aef91bc4f Rename pmloglevel_t to alpm_loglevel_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:24 +10:00
Allan McRae
cd1e39ba62 Rename pmbackup_t to alpm_backup_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
bfe1771067 Rename pmdelta_t to alpm_delta_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
1fdbe79022 Rename pmgrp_t to alpm_group_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
37b6cceed4 Rename pmfileconflict_t to alpm_fileconflict_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
220842b37b Rename pmconflict_t to alpm_conflict_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
6d876f9b6b Rename pmdepmissing_t to alpm_depmissing_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
9540dfc4d9 Rename pmdepend_t to alpm_depend_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:28:23 +10:00
Allan McRae
6b62508c86 Rename pmtrans_t to alpm_trans_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:27:16 +10:00
Allan McRae
8a04bc25a1 Rename pmpkg_t to alpm_pkg_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 23:26:39 +10:00
Allan McRae
939d5a9511 Rename pmdb_t to alpm_db_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 14:16:12 +10:00
Allan McRae
64c1cf7921 Rename pmhandle_t to alpm_handle_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 14:04:00 +10:00
Allan McRae
1c5c7c907c Rename pmfileconflicttype_t to alpm_fileconflicttype_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 13:58:59 +10:00
Allan McRae
0a80cf31cf Rename pmdepmod_t to alpm_depmod_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 13:56:46 +10:00
Allan McRae
7ce674491b Rename pmpkgreason_t to alpm_pkgreason_t
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-28 13:54:04 +10:00
Dan McGee
9aab1440ca Revert "Merge branch 'master' of git://projects.archlinux.org/pacman"
This reverts the merge of 2d32a9a3a3,
which reverts the commit 8581694ceb.

Thanks Dave for the dirty branch and non-clean rebase! :) Dave broke it.
2011-06-27 21:43:58 -05:00
Dan McGee
97e1dd9318 repo-add: remove extra exit call
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 15:08:14 -05:00
Dan McGee
09c803783d pacman-optimize: use output library
We already use msg() and error() in here, might as well just use the
standard functions. In addition, fix one translated message that would
have printed ERROR twice if anyone ever saw it.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 13:30:41 -05:00
Dan McGee
a12acbc2ff Merge remote-tracking branch 'dave/repo-add' 2011-06-27 13:30:37 -05:00
Dave Reisner
db172b09c5 repo-add: add new command, repo-elephant
_    _
  / \__/ \_____
 /  /  \  \    `\
 )  \''/  (     |\
 `\__)/__/'_\  / `
    //_|_|~|_|_|
    ^""'"' ""'"'

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-27 14:10:03 -04:00
Dave Reisner
399184d68f repo-add: enforce file extensions
Allow one of 4 archive extensions: .tar{,.gz,.xz,.bz2} for each of the 2
valid repo extensions: .db and .files. Check for this via
'verify_repo_extension' directly after option parsing to assert that
this extension is present, and again after files have been added to get
the proper archive option for bsdtar.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-27 13:39:02 -04:00
Dave Reisner
122b4c2187 repo-add: move command invocation out of arg parsing loop
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-27 13:39:02 -04:00
Dave Reisner
6f5a90edb3 repo-add: refactor repacking of repo file
Dump the whole conditional and filter the contents of the directory to
create an empty or non-empty archive.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-27 13:39:02 -04:00
Dan McGee
865ac0f055 Remove setter for DB signature level
This should have been removed with commit db3b86e7f3 but was
erroniously left behind.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 11:57:43 -05:00
Dan McGee
f01c6f814a Fix several -Wshadow warnings
Only one of these looked like a real red flag, in find_requiredby(), but
it doesn't hurt to fix several of them up anyway.

Unfortunately, we can't turn this on universally due to things like the
sync(), remove(), etc. builtins which we often use as variable names.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 10:10:08 -05:00
Dan McGee
77a09c92c6 Merge branch 'maint'
Conflicts:
	lib/libalpm/conflict.c
2011-06-27 09:33:27 -05:00
Eric Bélanger
51ed7dff0d Remove -f option from ln for POSIX compliance
Fixes FS#24893.

Signed-off-by: Eric Bélanger <snowmaniscool@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 09:24:41 -05:00
Eric Bélanger
f5dc5c46e0 makepkg: Add warning if VCS tool is not present when determining latest VCS revision
Signed-off-by: Eric Bélanger <snowmaniscool@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 09:24:28 -05:00
Eric Bélanger
bdd8ebd631 makepkg: Move check for sudo into check_software function
Signed-off-by: Eric Bélanger <snowmaniscool@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 09:24:19 -05:00
Allan McRae
6a413fe72f Remove two alpm_list_count usages
We have just looped through the list of files, so might as well get
the count as we go.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 09:19:08 -05:00
Allan McRae
93c77565f6 Add scripts po directory to autoclean.sh
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-27 09:16:47 -05:00
Dave Reisner
3725998cbc pactree: add -s option to walk sync DBs
Add a whole lot of bloat to parse pacman.conf and only a few lines to
use the list of sync DBs instead of the local DB.

Dan: I fully plan on this being temporary and us finding a better way in
the future to parse pacman.conf from multiple binaries. Adding a
standalone config parser is probably not the right way of going about
things, but for now it is by far the easiest.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 14:18:07 -05:00
Dan McGee
777bdc6c50 Make sync DB reading a bit more flexible
We can reorganize things a bit to not require reading a directory-only
entry first (or at all). This was noticed while working on some pactest
improvements, but should be a good step forward anyway.

Also make _alpm_splitname() a bit more generic in where it stores the
data it parses.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 14:04:39 -05:00
Dan McGee
719e0d3ddb archive_fgets(): ensure we return any trailing text with no newline
Discovered this when doing some pactest rewrite work to generate
archives in memory only. If a sync database file or PKGINFO file is
missing a newline on the final line, the text from that line gets tossed
aside and never read into the package struct. This is pretty critical
when that last line is a depend or something.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 14:03:51 -05:00
Dan McGee
1187edb38c valgrind.supp: add known leaks from GPGME
Thank you too, GPGME, for these. Why don't you provide a way to
clean up your static variable mess?

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 14:03:35 -05:00
Dave Reisner
112858ae61 repo-add.8.txt: document valid DB file extensions
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-24 14:55:49 -04:00
Dave Reisner
7d8e9b8ed6 repo-add: use format_entry for all desc/depends fields
This ranks high on the code readability scale. The same function formats
all of our data and writes to the metadata file at once.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-24 14:55:49 -04:00
Dave Reisner
5246fdecf6 repo-add: store multi-value fields as arrays
Fields like groups and depends should be stored as arrays. This requires
rewriting our write_list_entry function to accomodate our new data type.
This new function will not write to a file, but rather only format it.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-24 14:55:49 -04:00
Dave Reisner
522c94f168 repo-add: bashify reading of .PKGINFO file
grep and sed aren't needed here, and this removes the truly ugly
manipulation of IFS. The process substituion could just as well be a
herestring, but it breaks vim's syntax highlighting. Style over
substance, mang.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-24 14:55:49 -04:00
Dave Reisner
2d32a9a3a3 Merge branch 'master' of git://projects.archlinux.org/pacman
* 'master' of git://projects.archlinux.org/pacman:
  pactree: carry a list of databases for dep resolution
  makepkg: Remove a lone quotation mark
  makepkg: remove the cleancache option
  Don't require a transaction for sync DB updates
  Move locking functions to handle
  Add a 'valid' flag to the database object
  Move database 'version' check to registration time
  Do database signature checking at load time
2011-06-24 14:55:32 -04:00
Dave Reisner
e06586ceb4 pactree: carry a list of databases for dep resolution
Declare an alpm_list which, for now, only holds our local database.
walk_deps and walk_reverse_deps are refactored to account for this, and
a helper function is added to wrap alpm_db_get_pkg for traversing a
list.

This is groundwork for letting pactree walk the sync DBs.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 13:37:09 -05:00
Wieland Hoffmann
61cb8e76c3 makepkg: Remove a lone quotation mark
Allan broke it in 4bdb868.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 13:36:46 -05:00
Allan McRae
c45cfb1741 makepkg: remove the cleancache option
This is a fairly useless feature given all it does is an "rm" on a
directory.  It is also unlikely that you would want to remove the
entire SRCDEST anyway, but rather just the old files.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 13:36:38 -05:00
Dave Reisner
8581694ceb makepkg: fix incorrect parenthesis in gettext call
allan broke it in 4bdb868a.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-24 08:36:54 -04:00
Dan McGee
4f8ae2bab6 Don't require a transaction for sync DB updates
Instead, just do the required locking directly in the backend in calls
to alpm_db_update().

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 04:11:38 -05:00
Dan McGee
7b8f8f69f1 Move locking functions to handle
These operate on the handle, and the state is stored on the handle, so
move them where they belong. Up until now only the transaction stuff
calls them, but this will soon change and alpm_db_update() will handle
locking all on its own.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 04:02:58 -05:00
Dan McGee
79e98316ea Add a 'valid' flag to the database object
Start by converting all of our flags to a 'status' bitmask (pkgcache
status, grpcache status). Add a new 'valid' flag as well. This will let
us keep track if the database itself has been marked valid in whatever
fashion.

For local databases at the moment we ensure there are no depends files;
for sync databases we ensure the PGP signature is valid if
required/requested. The loading of the pkgcache is prohibited if the
database is invalid.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 03:46:12 -05:00
Dan McGee
1150d9e15a Move database 'version' check to registration time
This is another step toward doing both local database validation
(ensuring we don't have depends files) and sync database validation (via
signatures if present) when the database is registered.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 03:31:32 -05:00
Dan McGee
db3b86e7f3 Do database signature checking at load time
This is the ideal place to do it as all clients should be checking the
return value and ensuring there are no errors. This is similar to
pkg_load().

We also add an additional step of validation after we download a new
database; a subsequent '-y' operation can potentially invalidate the
original check at registration time.

Note that this implementation is still a bit naive; if a signature is
invalid it is currently impossible to refresh and re-download the file
without manually deleting it first. Similarly, if one downloads a
database and the check fails, the database object is still there and can
be used. These shortcomings will be addressed in a future commit.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 02:34:50 -05:00
Allan McRae
94d22f9309 Document group and providers selection
The format required for selection of packages within the group selection
dialog is not entirely obvious, so provide some documentation.

Fixes FS#24134.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-24 02:02:40 -05:00
Allan McRae
4bdb868ac8 makepkg: clean-up of output messages
There was a lot of inconsistency in how strings that should not be
translated (program names, option flags, PKGBUILD directives, etc) were
handled. This patch moves them all outside the gettext invocation for
consistency and to prevent accidental translation.

Note that some of these may need reverted if they cause difficulties in
translation due to gettext usage in bash not taking positional parameters
for arguments. A quick survey of current translations indicates that this
issue will be rare.  Also, we should be able to catch these before a full
string freeze given we are going to probably need a "developer preview"
release before the next release series.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-24 02:02:21 -05:00
Dan McGee
624a878701 pactest: generate sync DB's in memory
Sync database are no longer exploded on the filesystem. Rework the logic
used to generate our test databases so we can create them completely in
memory without having to write the individual files to disk at all. The
local database is unaffected.

Note that several shortcomings in libalpm parsing were discovered by
this change, which have since been temporarily patched around in this
test suite:

* archive_fgets() did not properly handle a file that ended in a
  non-newline, and would silently drop the data in this line.
* sync database with only the file entries and not the directories would
  fail to parse properly, and even cause segfaults in some cases.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:48 -05:00
Dan McGee
63335859d1 pactest: refactor install file creation
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:48 -05:00
Dan McGee
f15cce1d41 pactest: move filelist/backup generation into package object
These are definite methods that operate on a package, so move them there
which cleans up util a bit more.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:48 -05:00
Dan McGee
3ace8ceb23 pactest: make pmfile a bit more pythonic
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:48 -05:00
Dan McGee
11d8418737 pactest: small cleanups and chmod -x most files
Remove empty docstrings, small and easy pylint fixes, etc.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:48 -05:00
Dan McGee
763d638ca1 pactest: clean up database section writing
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:48 -05:00
Dan McGee
a8c3202836 pactest: add isize attribute, fix url attribute
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:47 -05:00
Dan McGee
f12ead2cf2 Remove three unnecessary usages of alpm_list_count()
For the files count when loading from a package, we can keep a counter.
The two in the frontend were completely useless due to the fact that if
sync_dbs is non-NULL, alpm_list_count() will always be greater than 0.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:47 -05:00
Dan McGee
d589a7b5db Prevent segfault when parsing unexpected sync database file
This doesn't fix the real (bigger) problem of failing to parse sync
databases without directory entries, but it does prevent the parser from
segfaulting when the first desc file encountered did not have a
directory entry, among other conditions.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-24 01:36:47 -05:00
Dave Reisner
e27a5c8851 parse-options: simplify unused-arg & parameter printing
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-24 00:02:06 -05:00
Dan McGee
ac7d17f88e Merge branch 'po-split' 2011-06-23 23:44:35 -05:00
Dave Reisner
d8d287b4d2 repo-add: fix path designation regression
b899099 made path checking a bit more strict than I had intended, and
would actually forbid creation of a repo in $PWD if only the filename
was specified. readlink would be the fun and easy solution here, but
it's avoided due to portability issues, making the validation process a
bit more verbose.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 23:27:07 -05:00
Dan McGee
d62a429b92 scripts/po/: add pacman-key
This has gettext strings, but wasn't added to the list of files in
POTFILES.in just yet. Add it and update the catalogs.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 22:55:57 -05:00
Dan McGee
c699c0b154 src/pacman/po/: prune message catalog and translations
Now that we have performed the split, prune the catalogs of all
scripts-only messages.

All old messages were pruned from the files using the following command:
    sed -i -e '/^#\~/,$d' *.po

Note: the diff on this commit looks much less insane if the --patience
option is used.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 22:55:56 -05:00
Dan McGee
963b942bb9 scripts/po/: prune message catalog and translations
Now that we have performed the split, prune the catalogs of all
pacman-only messages.

All old messages were pruned from the files using the following command:
    sed -i -e '/^#\~/,' *.po

Note: the diff on this commit looks much less insane if the --patience
option is used.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 22:50:30 -05:00
Dan McGee
a4a7006a13 po/: split into scripts/po/ and src/pacman/po/
This is the first step at separating the pacman message catalog and the
scripts message catalog. Makefiles, configure.ac, and other such files
are adjusted accordingly, as well as renaming files. The TEXTDOMAIN of
scripts is also adjusted.

Note that no actual pot or po files get changed here; these will get
pruned in a future commit so each catalog contains only the necessary
messages.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 22:50:01 -05:00
Dan McGee
78f297dabe Update all translation files
This is for the eventual 4.0.0 release, but more importantly to
logically separate new translations and strings from the PO split about
to happen between pacman and scripts.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 22:49:59 -05:00
Dan McGee
fa3aa6441c Let configure gettext setup know we use ngettext()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 22:49:59 -05:00
Eric Bélanger
eedd56f320 makepkg: Added checks in check_software for distcc, ccache, strip and gzip
Dan: slightly shorten some of the messages.

Signed-off-by: Eric Bélanger <snowmaniscool@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 21:39:37 -05:00
Dan McGee
aa89a65a83 makepkg: remove distcc/makeflags option interaction
Way back in c94bfbaba when refactoring makepkg options handling, I added
these lines to unset MAKEFLAGS if '!distcc' was set in a PKGBUILD (not
taking into account makepkg.conf settings). This was an attempt to say
"if it is broken in distcc, it is probably broken even more". However,
this is silly as one should be using '!makeflags' as well. Remove the
linkage.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-23 21:35:52 -05:00
Dan McGee
54ef162a1a Convert backup list to new pmbackup_t type
This allows us to separate the name and hash elements in one place and
not scatter different parsing code all over the place, including both
the frontend and backend.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 12:31:12 -05:00
Dan McGee
886a31ef20 makepkg: fix 'check_sofware' typo
Allan broke it!

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 11:51:58 -05:00
Dave Reisner
85902d98e8 repo-add: style cleanup
Unify function braces to be top right opening, bottom left closing.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 11:22:36 -05:00
Kerrick Staley
3d4bf3b3fd Fixed outdated documentation in test/pacman/README
test/pacman/README mentioned the -A flag, which no longer exists.

Signed-off-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 11:13:52 -05:00
Allan McRae
7468956236 makepkg: add software check function
Add a function that checks for the software needed by makepkg to
process a PKGBUILD with the requested options.  This allows makepkg
to bail early in the packaging process.

Many other checks can be added to this function...

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 10:49:33 -05:00
Allan McRae
e97541c208 Remove old TODO lists
These had not been touched since 2007 and had lost most of their
relevance.  The bug tracker is a better place for the filing of
ideas.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 10:48:14 -05:00
Allan McRae
41f9fa9bed makepkg: move comment into correct place
Oops... Introduced by commit d21f6ca4.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 10:47:12 -05:00
Allan McRae
3497eb4e2c makepkg: adjust libprovides/depends messages
Contractions are less clear for non-native speakers so should be
avoided (and cause syntax highlighting issues).  Also, the 'provides'
and 'depends' strings are not to be translated.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 10:46:38 -05:00
Allan McRae
508b360c24 makepkg: allow specifying alternative build directory
Add a BUILDDIR variable (which can be overridden in the environment)
to specify an alternative location for building the package. This is
useful for people who want to build on a different filesystem for
improved performance (e.g. tmpfs).

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 10:45:55 -05:00
Allan McRae
b803a33a8f makepkg: Add UPX compression support
This patch enables the automatic compression of executable binaries
using UPX when the 'upx' options is specified in makepkg.conf or the
PKGBUILD.  Additional arguments can be passed to UPX by specifying
the UPXFLAGS variable.

Original-patch-by: Bryce Gibson <bryce@gibson-consulting.com.au>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-22 10:45:18 -05:00
Dave Reisner
b899099327 repo-add: show better error when path to repo does not exist
Previously, the error message when trying to add to a repo where a
parent directory didn't exist was:

==> ERROR: Failed to acquire lockfile: /path/to/noexist/repo.tar.gz.lck

This sucks. Make an explicit check to ensure that the path to the repo
really does exist, and throw a meaningful error message when it can't be
found.

Dan: reuse an existing (translated) error message.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 11:22:39 -05:00
Dan McGee
ee638415e3 repo-add: allow creating a database with no compression
A plain '.tar' ending should be allowed. This corresponds to how we
handle this extension in makepkg. Also fix up the other extension
checks, which were missing a leading '.' character.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 11:08:40 -05:00
Dave Reisner
ab53aa3e3c repo-add: use bash equivalents of basename/dirname
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-20 10:44:20 -05:00
Dave Reisner
3847446603 lib/util: call _alpm_log before setting handle->pm_errno
This is an unfortunate chain of events. RET_ERR and RET_ERR_VOID will
eventually call CHECK_HANDLE, which resets the handle's pm_errno member.
Dan probably had a reason for doing this, so we merely switch the order
of operations in the RET_ERR macros to avoid stomping on our pm_errno.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-20 10:43:54 -05:00
Dan McGee
81e6071e0f pactest: add retcode=0 to several tests
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:36:01 -05:00
Florian Pritz
34876e4fe9 makepkg: fix broken syntax (double $)
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:20:52 -05:00
Dan McGee
36d98b3919 Improve cachedir removal and error handling
* Check the return value of canonicalize_path() for non-NULL
* Use ASSERT and RET_ERR as appropriate
* Make remove_cachedir() use same path munge logic as add_cachedir()

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:18:29 -05:00
Kerrick Staley
83071f579c Documented _alpm_download()
Documented the _alpm_download() function in dload.c

Signed-off-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:18:03 -05:00
Kerrick Staley
d980bd403d Documented purpose of be_*.c
Added a line to the top of each of be_local.c, be_package.c, and
be_sync.c indicating their purposes.

Signed-off-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:17:54 -05:00
Dave Reisner
620cddfc13 pacman/util.c: support terminals with unknown width
Add detection for stdout being attached to a tty device. When this check
fails, return a default width of 0, which callers interpret to mean
"don't wrap". Conversely, when our term ioctl suceeds but returns 0, we
interpret this to mean a tty with an unknown width (e.g., a serial
console), in which case we default to a sane value of 80.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-06-20 00:11:46 -05:00
Dan McGee
0f26e3aa5b Correctly duplicate delta objects
We were using copy_data before; this works for the struct itself but not
the strings contained within. Fix it up by duplicating all the data as
we do with our other structures.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:10:11 -05:00
Dan McGee
deb5601d8d Clean up util md5sum method
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:08:15 -05:00
Dan McGee
0ee9ced4cb Merge branch 'public-structs' 2011-06-20 00:07:10 -05:00
Dave Reisner
eb2d607899 lib/handle: use CALLOC macro instead of bare calloc
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:05:03 -05:00
Dan McGee
36ae77dd49 Don't call public API in _alpm_log()
Calling get_logcb() here would reset any previous setting of
handle->pm_errno due to the CHECK_HANDLE() macro contained within. This
would make error setting a bit funny if one set pm_errno before calling
_alpm_log(), such as in the RET_ERR() macro.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-20 00:03:53 -05:00
Dan McGee
25b7df4dab Make pmgrp_t public
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-16 11:58:04 -05:00
Dan McGee
51359e6d33 Make pmdelta_t public
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-16 11:58:04 -05:00
Dan McGee
7f6c1a76c6 Make pmdepend_t and pmdepmissing_t public
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-16 11:57:33 -05:00
Dan McGee
19fcc74016 Make struct pmconflict_t public
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-16 11:57:30 -05:00
Dan McGee
bdf00d3dbd Make pmfileconflict_t type public
This removes the need to write accessor methods for every type we have,
and simplifies the API. Any type that doesn't need magic* can be
converted in this fashion to make it easier for frontend applications to
use, as well as make it less of a pain to introduce new such structs in
the future.

* "magic" meaning something like pmpkg_t where values can be lazy loaded.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-16 11:57:06 -05:00
Dan McGee
1cd6515af0 API: change 'signaturedir' to 'gpgdir'
This is more in line with reality and what we have our makepkg, etc.
options named anyway.

Original-patch-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 12:02:29 -05:00
Allan McRae
d21f6ca4aa makepkg: create source package inside fakeroot
Create source package files inside the fakeroot environment to
ensure reasonable ownership of files within the archive.

Fixes FS#24330.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:20:52 -05:00
Allan McRae
06cb713f39 Clean up makefile for script generation
We no longer have any python scripts in our scripts/ directory so
we can simplify the makefile a bit.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:19:56 -05:00
Allan McRae
e27e658033 parse_options: adjust error messages
Provide consistent error messages for unknown long and short options.
Also get full string translation for the messages.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:19:45 -05:00
Allan McRae
53f4e43191 scripts/library: add README file
Add a README file to briefly document the code snippets in the scripts
library folder.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:19:10 -05:00
Allan McRae
4272b37d3d scripts: refactor output formatting functions
Move the common output formatting functions into a separate
library file and import that into each script.  makepkg is
excluded due to its additional color formatting.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:18:05 -05:00
Allan McRae
6f3a2145b0 makepkg: move option parsing code to separate file
This move the getopt replacement function parse_options out of
makepkg.sh.in and into a separate file.  The code is inserted
into the relevant place in makepkg using m4.

This will allow the reuse of the option parsing code in other
scripts (i.e. pacman-key) while avoiding code duplication.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:16:38 -05:00
Dan McGee
5f404f2cb7 Merge branch 'maint' 2011-06-15 09:16:08 -05:00
Jakob Gruber
e92083798c Ensure humanize_size works for negative values
Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:14:00 -05:00
Jakob Gruber
5b33f48389 Use pm_fprintpf in table_create_format
Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:13:51 -05:00
Allan McRae
700a5374f1 makepkg: reword purge message
Clarfiy that it is unwanted files are being removed rather than "other"
files (whatever they are...).

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-15 09:13:02 -05:00
Dan McGee
82a701401c valgrind.supp: add known leak exposed by cURL
This one comes courtesy of OpenSSL and some static initialization.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 12:01:07 -05:00
Florian Pritz
ef3ec2603d doc/PKGBUILD: misc changes
Acked-by: matt mooney <mfm@muteddisk.com>
Signed-off-by: Florian Pritz <bluewind@xinu.at>
2011-06-14 10:21:57 -05:00
Dan McGee
2f5f157274 Rename and rework signing helper methods
* Don't name static methods with a gpgme_ prefix to avoid confusion with
  methods provided by the library. These are static and local to our
  file so just give them sane non-prefixed names.
* Rework sigsum_test_bit() to not require assignment.
* Don't balk if there is more than one signature available (for now,
  only check the first).
* Fix error codes in publicly visible methods to return -1, not 0, if pkg
  or db are not provided.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 10:18:43 -05:00
Dan McGee
71fd34e596 Alpm pkg accessors: ensure pkg argument is non-NULL
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 10:09:35 -05:00
Dan McGee
ee015f086f Ensure handle is valid and pm_errno is reset when calling into API
We didn't do due diligence before and ensure prior pm_errno values
weren't influencing what happened in further ALPM calls. I observed one
case of early setup code setting pm_errno to PM_ERR_WRONG_ARGS and that
flag persisting the entire time we were calling library code.

Add a new CHECK_HANDLE() macro that does two things: 1) ensures the
handle variable passed to it is non-NULL and 2) clears any existing
pm_errno flag set on the handle. This macro can replace many places we
used the ASSERT(handle != NULL, ...) pattern before.

Several other other places only need a simple 'set to zero' of the
pm_errno field.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 10:01:08 -05:00
Dan McGee
be97276735 Avoid setting sigverify option twice
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 09:32:39 -05:00
Dan McGee
76a991c117 Conflict check and skip_remove code cleanups
* Move several variables into better scope
* const-ify a few variables
* Avoid duplicating filelists if it is unnecessary
* Better handling out out of memory condition when adding file conflicts
  to our list

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 09:30:46 -05:00
Dan McGee
ba63e31cc7 Small handle related cleanups
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 08:39:02 -05:00
Dan McGee
0074cadb3b Add handle argument to _alpm_pkg_should_ignore()
This allows callers to retrieve it from wherever is convenient, which
may or may not be on the package object itself.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 08:38:51 -05:00
Dan McGee
c206b3a6d5 Merge remote-tracking branch 'florian/sodeps' 2011-06-14 08:30:23 -05:00
Florian Pritz
d355376865 doc/PKGBUILD: misc changes
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 08:30:18 -05:00
Dan McGee
fbb44a6e0d Merge branch 'maint'
Conflicts:
	doc/makepkg.conf.5.txt
2011-06-14 08:29:39 -05:00
Dan McGee
00a1b1deeb Remove alpm_db_get_url()
This method is old, it doesn't adequately check for a NULL server list,
and can easily be done using better API method we provide these days.
All former users of this method can get similar results by calling
alpm_db_get_servers() and using the data from the returned server list.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-14 08:26:58 -05:00
Dan McGee
8be4db8caf Add a helper method for retrieving the DB signature path
Note that is a bit different than the normal _alpm_db_path() method; the
caller is expected to free the result.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:37 -05:00
Dan McGee
f6700d5c98 alpm_db_update(): refactor out sync dir create/check
This was a lot of stuff that can stand by itself for the most part.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:37 -05:00
Dan McGee
a775530941 conf: do batch processing of repo sections
We now parse an entire repo section and store all information about it.
When the next section is encountered or the end of the root config file
is reached, we will then process the stored information.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:37 -05:00
Dan McGee
c730ca5997 conf: _parseconfig() cleanups and documentation
* Function doxygen documentation
* Reuse a single strlen() call
* Prevent infinite recursion (limit to 10 levels)
* Other small cleanups

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:37 -05:00
Dan McGee
29ea0fa09f Always pass data to trans_commit()
Even though we currently don't use it here in the backend, we might as
well pass it in since we used it earlier.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:16 -05:00
Dan McGee
4d9278f87f Remove global handle variable
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:16 -05:00
Dan McGee
52bffd2457 Switch all logging to use handle directly
This is the last user of our global handle object. Once again the diff
is large but the functional changes are not.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:41:16 -05:00
Dan McGee
e2aa952689 Move pm_errno onto the handle
This involves some serious changes and a very messy diff, unfortunately.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:38:38 -05:00
Dan McGee
8b62d9bc0a Add handle argument to two more alpm methods
This takes care of alpm_checkdeps() and alpm_find_dbs_satisfier().

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:35:22 -05:00
Dan McGee
70a86c14f4 Require handle for alpm_checkconflicts()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:35:22 -05:00
Dan McGee
d76341297a Require handle for alpm_pkg_load()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:35:22 -05:00
Dan McGee
fb3ad7f882 Add handle argument to alpm_(add|remove)_pkg()
This makes these functions consistent with the rest of the transaction
related API calls. We do an additional assert to ensure the handle
attached to the package is the same as the handle passed in.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:32:59 -05:00
Kerrick Staley
01ad3faee9 Added initialization code for database siglevel
The siglevel field of a newly created pmdb_t struct is now
initialized when it is created in _alpm_db_new().

Signed-off-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 19:32:59 -05:00
Dan McGee
bcd442761b Fix memory leak if package sig was invalid
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 17:44:49 -05:00
Dan McGee
c5761bfe41 Fix all current return(x) usages
A few of these snuck in as of late, some from the table display patches
that were using the previous format before we changed it after the 3.5.X
major release.

Noticed-by: Kerrick Staley <mail@kerrickstaley.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-13 17:43:11 -05:00
Florian Pritz
5689478c68 doc/PKGBUILD: document libdeps
Signed-off-by: Florian Pritz <bluewind@xinu.at>
2011-06-09 23:18:23 +02:00
Dan McGee
ff7ad5fd73 commit_single_pkg(): Use handle object directly
Commit e68f5d9a30 did something a bit silly and changed the
scriptlet calls to use 'newpkg->handle' rather than the 'handle'
argument passed in. Use the handle directly.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 15:32:28 -05:00
Dan McGee
ff8e519d4b Require handle for alpm_sync_sysupgrade()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:24:45 -05:00
Dan McGee
7d27cf8364 Require handle for alpm_db_register_sync()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:24:45 -05:00
Dan McGee
24000b83c9 Require handle argument to all alpm_trans_*() methods
Begin enforcing the need to pass a handle. This allows us to remove one
more extern handle declaration from the backend.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:24:45 -05:00
Dan McGee
17a6ac5675 Require handle argument to all alpm_option_(get|set)_*() methods
This requires a lot of line changes, but not many functional changes as
more often than not our handle variable is already available in some
fashion.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:24:45 -05:00
Dan McGee
7968d30510 Require handle argument to alpm_logaction()
This is the first in a series of patches to update the API to remove the
implicit global handle variable.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:24:45 -05:00
Dan McGee
e826c143d3 Kill all remaining 'PATH_MAX + 1' usages
The few remaining instances were utilized for buffers in calls to
snprintf() and realpath(). Both of these functions will always ensure
the returned value is padded with '\0', so there is no need for the
extra byte.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:16:55 -05:00
Dan McGee
9d6568da0f _alpm_lstat: only duplicate string if necessary
The vast majority of the time we will just be passing the same string
value on to the lstat() call. The only time we need to duplicate it is
if the path ends in '/'. In one run using a profiler, only 400 of the
200,000 calls (0.2%) required the string to be copied first.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:14:55 -05:00
Allan McRae
451cd2c88d Fix bracket type in makefile
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-09 14:14:46 -05:00
Dan McGee
dfaeb6bb2c Merge remote-tracking branch 'allan/working' 2011-06-08 02:49:09 -05:00
Dan McGee
11ba7a0e8a Fix graph free valgrind warnings
Due to the way we set up the graph structure, we don't always have good
parent information. The changes made in dd8cf0c12d assumed this, so
back them out and just live with the dead pointers being there in the
memory while we are cleaning up after ourselves.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-08 02:49:03 -05:00
Dan McGee
beffab02c4 pactest: only create install file if necessary
We were testing whether there were any values in the array, rather than
looking if the values contained anything.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-08 02:48:52 -05:00
Dan McGee
2668782db2 Plug a memory leak
Introduced by me in commit cc25576f8b.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-08 02:48:43 -05:00
Allan McRae
87072ff639 Fix name of original files in scripts
Our scripts all currently say:

Generated from foo.in; do not edit by hand.

Fix this to say foo.sh.in, which is the actual original file name.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-08 17:36:03 +10:00
Allan McRae
361b6a9403 pacman-key: add vim modeline and fix whitespace issues
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-08 16:48:56 +10:00
Allan McRae
80b024d56a pkgdelta: add vim modeline
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-08 16:44:38 +10:00
Allan McRae
45fe92bf39 Remove incorrect output with download only and IgnorePkg
When only downloading a package that is in IgnorePkg, pacman
incorrectly asks about installing.

e.g. with <pkg> in IgnorePkg in pacman.conf:

> pacman -Sddw <pkg>
:: <pkg> is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n]

This output is now silenced when downloading only.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-08 15:34:47 +10:00
Dan McGee
8c6a636cd9 Merge branch 'maint'
Conflicts:
	lib/libalpm/add.c
2011-06-07 11:43:12 -05:00
Allan McRae
c750114894 pacman-key: update copyright
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-06-07 11:39:18 -05:00
Dan McGee
4fdcf50d66 Revamp pacman setup code to handle new alpm initialize routine
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:37:05 -05:00
Dan McGee
19755b648c Update utilities for new initialize/release methods
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:37:05 -05:00
Dan McGee
fb4b422fc4 New signatures for alpm initialize and release
These new method signatures return and take handle objects to operate on
so we can move away from the idea of one global handle in the API. There
is also another important change and that deals with the setting of root
and dbpaths. These are now done at initialization time instead of using
setter methods. This allows the library to operate more safely knowing
that paths won't change underneath it.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:37:05 -05:00
Dan McGee
992fa50dfd Add cachedirs one-by-one in set_cachedirs()
This addresses the issue where calling set_cachedirs() didn't
canonicalize the passed-in paths.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:36:30 -05:00
Dan McGee
c1a5b11f11 Be consistent with memory treatment for plural option setters
In all cases we should duplicate the passed-in list so the caller is
free to do with it as it pleases.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:33:29 -05:00
Dan McGee
991b3ff7e6 Add helper methods for setting directory options
This keeps duplicate code to a minimum. This will come in more handy as
we refactor some of these option setters away.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:30:44 -05:00
Dan McGee
cc25576f8b Use standard errno codes in return from _alpm_archive_fgets
This allows us to not require the context (e.g. handle) when calling
this function. Also beef up the checks in the two callers of this
function to bail if the last return code is not ARCHIVE_EOF, which is
the expected value.

This requires a change to one of the pactest return codes and the
overall result of the test, but results in a much safer operating
condition whereby invalid database entries will stop the operation.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 14:37:51 -05:00
Dan McGee
e68f5d9a30 Remove global handle dependencies from sync/upgrade paths
This kills a lot more global handle business off. sync.c still requires
the handle declaration for one reference that can't be changed yet; it
will be removed in a future patch which isolates all of the necesary API
changes.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 13:18:36 -05:00
Dan McGee
d2f05f72f0 Remove global handle from remove.c
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:53:53 -05:00
Dan McGee
307a6de17a Remove global handle from some package and db code
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:44:01 -05:00
Dan McGee
4015b23e8e Remove global handle from diskspace.c
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:36:13 -05:00
Dan McGee
7fc635fee0 Remove global handle from util.c
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:33:18 -05:00
Dan McGee
de36c5fac4 Push down extern handle variable to files that need it
This will make the patching process less invasive as we start to remove
this variable from all source files.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:23:32 -05:00
Dan McGee
7f98460e37 Add handle attribute to pmpkg_t struct
Similar to what we just did for the database; this will make it easy to
always know what handle a given package originated from.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:13:22 -05:00
Dan McGee
c47d25d74b Add handle attribute to pmdb_t struct
This is the first step in a long process to remove our dependence on the
global handle variable we currently share in libalpm, with the goal to
make things a bit more thread-safe and re-entrant.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 12:06:25 -05:00
Dan McGee
2102d1a2eb Remove unnecessary handle != NULL asserts
These are simple accessor functions for a struct; the handle never even
comes into play when calling these functions.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 11:54:58 -05:00
Dan McGee
78cbc045c1 Remove ALPM_LOG_FUNC macro
The usefulness of this is rather limited due to it not being compiled
into production builds. When you do choose to see the output, it is
often overwhelming and not helpful. The best bet is to use a debugger
and/or well-placed fprintf() statements.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-03 11:48:24 -05:00
Dan McGee
9d73b261cf Merge branch 'maint'
Conflicts:
	src/pacman/callback.c
2011-06-02 17:34:12 -05:00
Dan McGee
8f30e1b110 Show net upgrade size on -U/-S operations
If it is different than the raw installed size metric we already show,
compute the net upgrade size. For some sync operations, this can even be
negative if newer packages are smaller than the ones they replace
locally. Implements FS#12566.

Example:

    Targets (1): telepathy-glib-0.14.7-1

    Total Download Size:    1.07 MiB
    Total Installed Size:   15.72 MiB
    Net Upgrade Size:       -0.29 MiB

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-02 17:21:38 -05:00
Dan McGee
142c2132cf Add two currently failing test cases from bug reports
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-02 17:20:45 -05:00
Dave Reisner
0d1fcd329f lib/dload.c: remove assumption in continuation logic
Callers to curl_download_internal now tell us if its okay to continue a
transfer, so obey this instead of using a heuristic.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-01 15:05:41 -05:00
Dave Reisner
8807cac100 dload: abort transfer on CURLOPT_LOW_SPEED_LIMIT
If a connection drops below 1kb/s for 10s, curl will kill the transfer
and we'll report failure. This is the average transfer speed over the
delta defined by CURLOPT_LOW_SPEED_TIME, so setting a low value here
shouldn't bother folks using 14.4k dial-up.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-01 15:05:30 -05:00
Florian Pritz
73d5eb1edf makepkg: add libdepends support
The user adds libaries to the depends array without a version. These
must end with .so.
Example: depends=(glibc libc.so)

find_libdepends() looks for ELF files (not symlinks because these could
point outside of pkgdir) in $pkgdir, extracts the library sonames the
binary links to and outputs depends seperated by spaces.
This list contains all libraries needed by the package.
Example: libfoo.so=3-64

write_pkginfo() only keeps .so depends with version information and warns
the user about unneded ones.

Support-by: Thomas Bächler <thomas@archlinux.org>
Support-by: Christoph Schied <Christoph.Schied@uni-ulm.de>
Signed-off-by: Florian Pritz <bluewind@server-speed.net>
2011-06-01 21:34:16 +02:00
Dan McGee
8f1c873b5f doc: monospace attribute escape fixes
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-01 12:56:38 -05:00
Pang Yan Han
5842dad7e7 pacman-key: print default gpgdir in usage
Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-01 12:27:03 -05:00
Dan McGee
41da225336 Merge branch 'maint' 2011-06-01 12:13:49 -05:00
Pang Yan Han
fe9804a96d Update pacman manpage and pacman.conf for gpgdir
pacman.8.txt --gpgdir section is updated based on the pacman.conf manpage

pacman.conf is updated to include the default GPGDir

Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-01 12:13:43 -05:00
Pang Yan Han
7b26167580 Let pacman -v print GPG Dir
Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-01 11:30:34 -05:00
Florian Pritz
79f1a3c4a1 makepkg: add libprovides support
The user adds libaries to the provides array without a version. These
must end with .so.
Example: provides=(readline libreadline.so)

find_libprovides() looks for .so files (not symlinks because these could
point outside of pkgdir) in $pkgdir, extracts the library soname (ld
links the binary to this name) and outputs provides seperated by spaces.
This list contains all libraries provided by the package.
Example: libfoo.so=3-64

write_pkginfo() only keeps .so provides with version information and warns
the user about unneded ones.

Support-by: Thomas Bächler <thomas@archlinux.org>
Support-by: Christoph Schied <Christoph.Schied@uni-ulm.de>
Signed-off-by: Florian Pritz <bluewind@server-speed.net>
2011-05-27 13:29:22 +02:00
Dan McGee
11fb9c7674 Merge branch 'maint'
Conflicts:
	lib/libalpm/trans.c
	src/pacman/query.c
2011-05-19 17:17:32 -05:00
Dan McGee
70cf4546d6 Don't balk on .sig files being invalid in package cache
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-10 17:39:22 -05:00
Dan McGee
2cd79bc853 Remove sync DB reregister check
It's your own damn fault if you do this, and this code is remnants from
an old time when we weren't very good at coding.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 15:26:19 -05:00
Dan McGee
dd95c96b8a Rework config parsing to reduce variable duplication
This removes the need to strdup() the section name at every decent into
an Include statement, as well as having duplicate DB pointers around
that are never used independently.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 15:16:52 -05:00
Dan McGee
0fbdfd02dc Refactor VerifySig option value parsing into standalone method
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 15:01:35 -05:00
Dan McGee
6b308d89f9 Merge branch 'maint' 2011-05-05 13:25:10 -05:00
Dan McGee
f2d696cd51 Don't null-check handle lists before setting
This needlessly prevents the easiest way available of clearing any of these
values. We can also do the same for the 'arch' value.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 12:46:42 -05:00
Dan McGee
42ab639bf7 Improve database server API
Currently we have one call that has all sorts of crazy behavior and doesn't
make a whole lot of sense. Go from one method to the normal four methods we
have for all of our other lists we use in the library to make it a lot
easier for a frontend to manipulate server lists.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 12:31:09 -05:00
Dan McGee
3045f09ef4 Logging changes during DB load
The switch from FUNCTION to DEBUG was ill-advised inside the local
database load. Instead, add a DEBUG level logger to both local and sync
database loads that shows the number of packages processed.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 12:08:59 -05:00
Dan McGee
73c74355ab Make config parsing a two-part affair
This ensures we call any alpm_option type functions before registering
databases, making sure all paths and other defaults (e.g. sig
verification levels) have been set first. This will ensure we can
continue to allow crazy config files where [options] doesn't come first.

The diffstat on this commit is misleading; view with
-w/--ignore-all-space to get a better idea of what needed to be touched.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 11:48:12 -05:00
Dan McGee
bda208f823 Move parseconfig to conf.c
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 11:12:49 -05:00
Dan McGee
d360153bc6 pactest: run with root in /tmp and clean up automatically
This moves the generated root/ directory into /tmp, or at least a path
returned by tempfile.mkdtemp(), by default. This can make test runs
significantly faster if done when /tmp is a tmpfs.

If you are debugging a failed test, use the new --keep-root option to
not clean up and pactest will print the location of the generated root/
test directory.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 11:12:26 -05:00
Dan McGee
47de7973fd dload: ensure we return success if we found files on any mirror
We were erroring out in the case where a first (possibly bogus) mirror
would cause the download process to return a failure code, even though
subsequent servers had the file.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-05 10:01:01 -05:00
Allan McRae
500a6f576d Dan broke my patch
Add a missing space.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-05-05 11:12:46 +10:00
Dan McGee
73553e60ec Fix incorrect memory allocation assignment
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-04 16:46:52 -05:00
Dan McGee
22b1338390 dload: make sure we never print a bogus error buffer
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-04 16:29:41 -05:00
Dan McGee
991bfb7cbf Merge branch 'maint' 2011-05-04 15:54:42 -05:00
Allan McRae
7680f46157 Deal with unused function parameters correctly
This started off removing the "(void)foo" hacks to work around
unused function parameters and ended up fixing every warning
generated by -Wunused-parameter.

Dan: rename to UNUSED.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-04 15:53:49 -05:00
Dan McGee
c4fccfe3e6 pactree: make -Wwrite-strings friendly
Use a few structs to hold configuration values we change given certain
options so we can be const-correct with string assignment across the
board. Behavior should be completely unchanged.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-04 15:49:47 -05:00
Dan McGee
e8a40526cb Fix warnings reported by -Wwrite-strings
These are places where we stuck a string constant in a variable not
marked as const.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-04 15:48:47 -05:00
Dan McGee
c03faa32f3 Reduce duplicate signing debug code and fix logic condition
We had a lot of similar looking code that we can collapse down into a
function. This also fixes errors seen when turning on some gcc warnings
and implicitly casting away the const-ness of the string. Free the list
when we are done with it as well.

Also, fix a logic error where we should be checking with &&, not ||.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-05-04 15:46:18 -05:00
Dan McGee
4758cfe33f Merge branch 'maint' 2011-04-29 16:05:59 -05:00
Dan McGee
9c552272e8 configure: add output showing what libraries will be used
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-27 16:59:08 -05:00
Dan McGee
97be2f0e0a Allow conditional compilation with GPGME
This makes it possible to omit usage of -lgpgme, just as we can do for
-lcurl and -lcrypto.

Thanks to Rémy Oudompheng for an initial stab at this.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-27 16:58:58 -05:00
Dan McGee
b7b3fc2386 signing: add more detail to unexpected signature count error
Do a quick loop and count of the returned data so we can show how many
signatures were parsed and read.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:50:06 -05:00
Dan McGee
1d7ad5d24b Enhance GPGME debug output
Add some lookup functions for nice names for the various types used by
the library, and remove some fields that are of little use to us in the
debug output. This should make looking at key loading and verification a
bit easier, especially in determining what makes up our good and bad
criteria.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:48:34 -05:00
Dan McGee
4d63ebe2fb Perform package verification at package load time
Both md5sum verification and PGP verification can and should be done at
package load time. This allows verification to happen as early as
possible for packages provided by filename and loaded in the frontend,
and moves more stuff out of sync_commit that doesn't really belong
there. This should also set the stage for simplified parallel loading of
packages later down the road.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:48:34 -05:00
Dan McGee
1cf79eb8c8 sync_commit: refactor out validate_deltas
More stuff going on in the pre-committing stage that can be in a static
method to make things a bit more clear.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:48:34 -05:00
Dan McGee
2df1534b78 sync_commit: refactor out file downloads
This part is almost completely self-contained, except building the list
of delta filenames that we use later to check their md5sums. Refactor it
into a static method so we can bring most of the code in sync_commit
closer to the method name.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:48:34 -05:00
Dan McGee
225acbbff1 Rein in the complexity of the signature type
Given that we offer no transparency into the pmpgpsig_t type, we don't
really need to expose it outside of the library, and at this point, we
don't need it at all. Don't decode anything except when checking
signatures. For packages/files not from a sync database, we now just
read the signature file directly anyway.

Also push the decoding logic down further into the check method so we
don't need this hanging out in a less than ideal place. This will make
it easier to conditionally compile things down the road.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:48:33 -05:00
Dan McGee
31e55b8049 signing: let GPGME handle loading signatures from files
Rather than go through all the hassle of doing this ourselves, just let
GPGME handle the work by passing it a file handle.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:48:33 -05:00
Allan McRae
a7d33d0c36 repo-add: update copyright message
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:44:52 -05:00
Allan McRae
1cb1b0a52c repo-add: document -k option
Also unify the usage output with that given by repo-add itself.

Dan: use 'options', not 'option(s)'.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:44:22 -05:00
Allan McRae
036f98575c repo-add: check for gpg early
Check for the presence of gpg as soon as we know we need it.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:43:43 -05:00
Allan McRae
fade60088e repo-add: check for valid key when signing is requested
Follow the example of makepkg

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:43:25 -05:00
Denis A. Altoé Falqueto
59da64146d repo-add: add option to specify a different key to sign with
Add -k/--key option to specify a non-default key for signing
a package database.

Original-patch-by: Denis A. Altoé Falqueto <denisfalqueto@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:43:01 -05:00
Allan McRae
2eab4ab033 repo-add: simplify usage message
Listing every option on the usage line becomes unweildly as more
options get added so simplify it. Also, provide a standard package
name in the repo-add example.

Dan: just use 'options' as we use elsewhere, not 'option(s)'.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-24 10:41:52 -05:00
Dan McGee
8b34aa50b9 Make dump_pkg_full a little less insane
The various "level" values were a bit crazy to decipher, and we were
doing some very interesting comparisons in certain places. Break it out
into two parameters instead so we can seperate the type from the extra
information display, and do things accordingly.

Nothing changes with the display of any of the five types we currently
show: -Si, -Sii, -Qi, -Qii, -Qip.

Something to note- we should expose the PKG_FROM enum type somehow, this
patch leaves the door open to do that quite easily.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-22 17:08:33 -05:00
Dan McGee
9579879b1b libalpm/dload: major refactor of signature downloading
There's a lot of related moving parts here:
* Iteration through mirrors is moved back to the calling functions. This
  allows removal of _alpm_download_single_file and _alpm_download_files.
* The download function gets a few more arguments to influence behavior.
  This allows several different scenarios to customize behavior:
  - database
  - database signature (req'd and optional)
  - package
  - package via direct URL
  - package signature via direct URL (req'd and optional)
* For databases, we need signatures from the same mirror, so structure
  the code accordingly.

Some-inspiration-from: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-22 17:08:33 -05:00
Dan McGee
204bbc4714 libalpm/dload: add allow_resume and reorder error checks
The allow_resume is the start of the fix to the "don't ever resume
database downloads" problem, as well as being useful for '.sig'
downloads as well. For now, we say "always allow resume", but this will
eventually get pushed down as necessary.

Error checks are reworked in order to correctly error out when a file is
not found on the remote end and reports 0 bytes downloaded. In addition,
the two error messages printed are now different as one reports a more
specific error message provided via the cURL error buffer.

Some example output from an -Sy run with [testing], [community],
[community2], [eee], and [nonexistant] defined as repos. [community2]
and [nonexistant] are both invalid, one using FTP and one using HTTP.

    :: Synchronizing package databases...
    testing is up to date
    community is up to date
    error: failed retrieving file 'community2.db' from ftp.archlinux.org : Given file does not exist
    error: failed to update community2 (FTP: couldn't retrieve (RETR failed) the specified file)
    eee is up to date
    error: failed retrieving file 'nonexistant.db' from code.toofishes.net : The requested URL returned error: 404
    error: failed to update nonexistant (HTTP response code said error)

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-22 17:08:33 -05:00
Dan McGee
934e8c79af Merge branch 'maint' 2011-04-22 17:08:12 -05:00
Dan McGee
e39c104d13 cleanup: add_pkg() and remove_pkg()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-22 15:58:34 -05:00
Dan McGee
53c749ce0a libalpm/dload: const and static correctness
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-22 15:58:19 -05:00
Dan McGee
1ff04b980f be_sync: use _alpm_db_get_sigverify_level()
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-22 15:58:09 -05:00
Rémy Oudompheng
10b8cd75b3 sync.c: remove unnecessary check for PM_PGP_VERIFY_UNKNOWN
The value PM_PGP_VERIFY_UNKNOWN is reserved to error cases,
now that the signature verification level defaults to the
globally set level. The only error case is when handle == NULL,
which is false in the context of _alpm_sync_commit().

Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-21 12:14:34 -05:00
Rémy Oudompheng
dd7b17aa0a handle.c: force sigverify level not to be PM_PGP_VERIFY_UNKNOWN
Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-21 12:14:23 -05:00
Dan McGee
ada5bc1404 Merge remote-tracking branch 'remy/doxygen' 2011-04-21 12:12:29 -05:00
Ivan Kanakarakis
908e9f41ed pacman-key: improved reading of the configuration file
This commit replaces the find_config() function with the get_from()
function. get_from expects two arguments, the first is the file to
read and the second is the key to look for in the given file.
get_from returns the first matching value for the given key. The
file is expected to be in the format:
key = value
Each of 'key' 'equal sign' 'value' can be surrounded be random
whitespace.

Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-21 12:10:31 -05:00
Ivan Kanakarakis
fdbcc9847d pacman-key: display the unsupported command to the user
If the user provides an unsupported command, inform the user that this
switch is unknown, display usage and exit.

Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-21 12:09:23 -05:00
Ivan Kanakarakis
6f19a8c9f7 makepkg, pacman-key: unify help message with other scripts
The help message changed to match the one rankmirrors script has.
It's clearer as to what the --help switch does.

Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-21 12:09:18 -05:00
Rémy Oudompheng
36737aebb7 alpm.h: add several missing documentation strings
Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
2011-04-21 07:45:27 +02:00
Rémy Oudompheng
96ad414d73 alpm.h: rationalize option getters/setters documentation
Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
2011-04-21 07:43:32 +02:00
Rémy Oudompheng
670b315c4d alpm.h: add/improve function documentation
Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
2011-04-21 07:08:35 +02:00
Dan McGee
442e1420f9 Rename gpgsig struct fields for clarity
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 20:11:26 -05:00
Dan McGee
3c5661ec3c Form the signature file location in one place
Since we do this for all cases anyway.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 20:10:27 -05:00
Dan McGee
791928dc48 Header inclusion cleanup
This does touch a lot of things, and hopefully doesn't break things on
other platforms, but allows us to also clean up a bunch of crud that no
longer needs to be there.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 20:09:13 -05:00
Dan McGee
4af6c72d79 syntax: if/while statements should have no trailing space
This is the standard, and we have had a few of these introduced lately
that should not be here.

Done with:
  find -name '*.c' | xargs sed -i -e 's#if (#if(#g'
  find -name '*.c' | xargs sed -i -e 's#while (#while(#g'

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 19:47:39 -05:00
Dave Reisner
6760ec2b77 Allow VerifySig to act as a default verification in [options]
* add _alpm_db_get_sigverify_level
* add alpm_option_{get,set}_default_sigverify

And set the default verification level to OPTIONAL if not set otherwise.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 19:42:01 -05:00
Dan McGee
2c8c763723 alpm.h: forward-declare shared enumerations
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 19:29:14 -05:00
Dave Reisner
91594a1ef8 style cleanup: cast as (type *) not (type*)
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 19:04:53 -05:00
Dave Reisner
fdcfcf28a2 lib: remove dead code in be_local and be_package
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-04-20 19:04:27 -05:00
Dan McGee
a6c05458d4 Put comments on their own line
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 19:00:59 -05:00
Allan McRae
4c31bc6e3f Add configure option to specify package signing key
Add the "GPGKEY" option to makepkg.conf for specifying signing packages
with the non-default key from the keyring.  Is overridded by makepkg's
--key option.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 18:58:55 -05:00
Allan McRae
cb35affd1b Document makepkg package signing options
Dan: fix some grammar issues.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 18:54:42 -05:00
Jakob Gruber
e95be3379a New VerbosePkgLists option
If enabled, displays package lists for upgrade, sync and remove
operations formatted as a table. Falls back to default list display if
insufficient terminal columns are available.

Example output:

:: Starting full system upgrade...
:: Replace libjpeg with testing/libjpeg-turbo? [Y/n]
resolving dependencies...
looking for inter-conflicts...

Remove (1):

Name     Old Version       Size

libjpeg  8.3.0-1        0.83 MB

Total Removed Size:   0.83 MB

Targets (5):

Name            Old Version  New Version       Size

libjpeg-turbo                1.1.0-1        0.20 MB
linux-firmware  20110201-1   20110227-1     8.23 MB
ncurses         5.7-4        5.8-1          0.92 MB
ppl             0.11.1-1     0.11.2-1       2.74 MB
v4l-utils       0.8.1-1      0.8.3-1        0.23 MB

Total Download Size:    12.32 MB
Total Installed Size:   58.82 MB

Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 18:13:02 -05:00
Jakob Gruber
0152266dd3 Table formatted output functions
table_display takes a list of lists of strings (representing the table
cells) and displays them formatted as a table.
The exact format depends on the longest string in each column.

Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 17:41:13 -05:00
Dan McGee
50de7019c0 Merge branch 'maint' 2011-04-20 17:35:33 -05:00
Jakob Gruber
c3f3d0b81a Refactor display_targets for readability
Row handling is moved to its own function in preparation for verbose
package lists.

Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 17:33:13 -05:00
Dan McGee
ecf15be0a7 Remove outdated comments
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 17:32:16 -05:00
Jakob Gruber
84cfc13589 Use IEC unit prefixes
Display {KiB, MiB, ...} instead of {KB, MB, ...} since that's what's
actually being displayed.

Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 17:31:56 -05:00
Jakob Gruber
3c8a448a2f Add a utility function to humanize sizes
Converts the given size in bytes in two possible ways:
1) target_unit is specified (!= 0): size is converted to target unit.
2) target_unit is not specified (== '\0'): size is converted to the first
   unit which will bring size to below 2048.

If specified, label will point to the long label ('MB') if long_labels is
set or the short label ('M') if it is not.

Dan: use '\0' rather than 0 for the special value as a matter of coding
style for char variables.

Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 17:29:32 -05:00
Jakob Gruber
dcb6fb224d Remove ShowSize option
Dan: The commit message originally referenced "VerbosePkgLists", but I'm
going to change the name of the option. In addition, this patch serves
a purpose being standalone- we should really do things like this with
-S --print and hopefully -Q --print in the future.

Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-20 17:13:20 -05:00
Dan McGee
efd8ae483f Merge branch 'maint'
Conflicts:
	lib/libalpm/alpm.h
	lib/libalpm/trans.c

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-15 18:41:49 -05:00
Dan McGee
202ade1398 Include "config.h" in header files using off_t
This makes it absolutely dead easy to ensure off_t has the same length
in all compilation units. I just spent 2.5 hours bashing my head on an
issue related to this so damn it I'm fixing it for good.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-15 18:40:32 -05:00
Rémy Oudompheng
4ffda3f05b libalpm: consistently use int as return type for option setters
Currently the only error case then when handle == NULL.
However several handle functions return -1 on this error,
and a uniform API makes things simpler.

Signed-off-by: Rémy Oudompheng <remy@archlinux.org>
2011-04-15 18:37:10 -05:00
Dan McGee
dff2d916ba Remove indirection on get_name and get_version operations
For a package to be loaded from any of our backends, these two fields
are always required upfront. Due to this fact, we don't need them to be
backend-specific operations and can just refer to the field directly.

Additionally, our static (and thus private) cache package accessors had
a NULL check on pkg before returning the relevant field. Eliminate this
since they only way they are ever called is via the packages attached
callback struct, which would have caused the NULL pointer dereference in
the first place.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-15 18:37:09 -05:00
Dan McGee
dd8cf0c12d Move graph.h functions into graph.c
So we only need one copy in the final library, not one copy per time
used. Ensure all necessary includes are in place (especially to get the
right size of off_t each time it is compiled) by including "config.h" in
the new graph.c.

One small adjustment here makes the graph_free code more robust- ensure
we don't have invalid pointers after each iteration by looking at the
parents and children and adjusting accordingly.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-15 18:36:53 -05:00
Dan McGee
8df7208d7b Don't create two pmpkg_t objects in be_package
Ensure we only have one- this looks like the result of a bad merge from
old 2008 signing code with the current stuff which has changed quite a
bit.

Originally-seen-by: Rémy Oudompheng <remyoudompheng@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-11 15:56:34 -05:00
Dan McGee
c5addd94e3 Merge branch 'maint'
Conflicts:
	lib/libalpm/be_sync.c
	lib/libalpm/db.c
	src/pacman/util.c
2011-04-05 00:49:30 -05:00
Xavier Chantry
2f71d1dc00 pacman.c : useless extra parenthesis
clang 3.0 git complained about these

Signed-off-by: Xavier Chantry <chantry.xavier@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-04 23:33:39 -05:00
Xavier Chantry
a461837835 dload: dont forget to initialize open_mode
That's a funny one, building with optimization levels (with both gcc and
clang) caused open_mode to always be set to "ab", which worked.

This was spotted both with clang-analyzer, and by Jakob who reported a
segfault as he was using an un-optimized build.

Signed-off-by: Xavier Chantry <chantry.xavier@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-02 12:37:17 -05:00
Xavier Chantry
0e03c0849d configure.ac: we use fabs now so -lm is needed
Signed-off-by: Xavier Chantry <chantry.xavier@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-04-02 12:37:03 -05:00
Dan McGee
3089c833ff Unify filelist operation functions in conflict checking
We had two functions that were oh so similar but slightly different. We
can combine them and add some conditional operation stuff to decide what
to return.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-30 20:20:16 -05:00
Dan McGee
d3d18a42d2 Merge branch 'maint' 2011-03-29 12:21:07 -05:00
Dave Reisner
9477abc359 pacman/util: flush terminal input before reading response
Addresses FS#20538

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-28 09:04:15 -05:00
Denis A. Altoé Falqueto
e8069cfc3d makepkg: command line options for signing packages
Three new command line options were added:

--sign: forces the generation of a signature for the resulting package,
taking precedence over the value in makepkg.conf

--nosign: do not sign the resulting package

--key <key>: use a different key than the user's default for signing
the package.

A check is performed to ensure the user has (provided) a valid gpg key
for signing.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-28 09:03:28 -05:00
Ray Kohler
4ef664f485 Create pacman keyring directory if missing
Use mode 755, so non-root users can see inside.
Add "--no-permission-warning" to GPG_PACMAN to suppress the noise that
otherwise comes of not using mode 700 - this is not private data.

GPGme turns out not to issue this warning itself, so no problem there.

TODO: should non-root users be allowed to use the read-only operations
(--list, --export, --finger)?

Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 21:50:52 -05:00
Dan McGee
c3ae209246 Documentation formatting updates
Be consistent in the Synopsis and Description sections with the use of
quotes around command names.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 21:27:15 -05:00
Ray Kohler
f6c8532fd0 Add manpage for pkgdelta
Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 21:26:52 -05:00
Ray Kohler
c0190798e1 Update repo-add manpage
Add -v, mention delta support (other than -d), and split
repo-add-specific options out from those common to repo-add and
repo-remove.

Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 21:20:20 -05:00
Ray Kohler
86ff381ac2 Clean up repo-add usage message
This now includes -s and -v, tailors itself to the current command,
and is formatted more like that of other pacman commands.

Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 21:13:52 -05:00
Dan McGee
4a3cd364d0 Temporary fix for new warnings from gcc 4.6
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:48:26 -05:00
Dan McGee
3f269503d5 Merge branch 'maint'
Conflicts:
	lib/libalpm/deps.c
2011-03-27 20:41:23 -05:00
Ray Kohler
630b7b94c3 Sign database even if empty
Move the create_signature() call outside the case of non-empty
databases, so it will be called regardless.

Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:35:43 -05:00
Ray Kohler
43dacceb6b makepkg: allow PKGEXT and SRCEXT to be overridden by env variables
Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:15:52 -05:00
Dave Reisner
c02556e290 Rely on the return value of type instead of its output
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:15:20 -05:00
Dave Reisner
a9fb4d9d5b lib/dload: abstract out helper function to set utimes
This greatly simplifies the cleanup fallthrough in our download function
and we'll be able to reuse this for signatures.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:14:47 -05:00
Dave Reisner
98c8ab18ff lib/dload: remove proxy debug output
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:14:20 -05:00
Dave Reisner
33c08ac91e lib/dload: code simplification
Based on the fact that localf always points to the same file, there's no
need to code in multiple fopen calls with varying results. Instead,
track the desired file open mode and make a single call to fopen.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:14:10 -05:00
Dave Reisner
fd64988c80 lib/dload: merge get_{destfile,tempfile} into get_fullpath
Create a more general function that allows appending a suffix to a
filepath.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:12:51 -05:00
Dave Reisner
55f790ebe4 pacman/pacman.c: fix setting of useragent string
libcurl doesn't natively honor the HTTP_USER_AGENT environment variable.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:12:29 -05:00
Dave Reisner
283bf7e87c lib/dload: pass a struct with filename and size to curl_progress
This lets us determine the real size of the file on disk so that we can
properly bump the progress bar when we're resuming a download.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-27 20:12:17 -05:00
Dan McGee
86e7f60756 Merge branch 'maint' 2011-03-24 21:18:09 -05:00
Ray Kohler
cfa2eebdaf Fix use of relative paths for packages in repo-add
Move checksum and pgpsig calcluation before changing into the
tmpdir, otherwise we can't find the files if a relative path
was used.

Signed-off-by: Ray Kohler <ataraxia937@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-24 17:15:35 -05:00
Allan McRae
a8b22e16ef Do not reuse old signature
After updating a database, remove the old signature to prevent it
being used in validation if the new signature fails to download.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 22:58:32 -05:00
Allan McRae
38da050f31 Download and verify package database signatures
If signature verification is needed, attempt to download a signature
file for a repo when it is updated. Return an error if unable to
download signature only when checking is mandatory, or if signature is
invalid.

TODO: At the moment the database signature is only checked on download.
Should we do anything with a database if it fails to be verified to prevent
its future usage?

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 22:58:00 -05:00
Dan McGee
9a3325a56d Refactor signature loading code into common function
We can use this for both standalone package signatures as well as
standalone database signatures.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 22:56:54 -05:00
Allan McRae
ed6fda2f98 Add functions for verifying database signature
Add a pmpgpsig_t struct to the database entry struct and functions for
the lazy loading of database signatures.  Add a function for checking
database signatures, reusing (and generalizing) the code currently used
for checking package signatures.

TODO: The code for reading in signature files from the filesystem is
duplicated for local packages and database and needs refactoring.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 22:22:33 -05:00
Dave Reisner
ef26c44524 etc/makepkg.conf: use curl in place of wget as a DLAGENT
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 20:37:20 -05:00
Dave Reisner
b9263fb4e1 lib/dload.c: Check for dlcb == NULL earlier
Our curl callback does a whole lot of work for nothing if the front end
never defined a callback to receive the data we'd calculate for it.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 11:04:42 -05:00
Dave Reisner
47e41b2023 lib/dload.c: don't use deprecated curl symbols
CURLINFO_HTTP_CODE is deprecated in favor of CURLINFO_RESPONSE_CODE.
Both yield the same values.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:44:16 -05:00
Dave Reisner
e29301954c lib/dload.c: don't request compressed transport
The files we transfer are generally compressed already, so this just
adds unnecessary overhead.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:44:10 -05:00
Dave Reisner
82fb7a0202 lib/dload.c: Fix progress callback issues on download
Use a static variable to effectively track the initialization state of
the progress callback via the last byte amount reported as downloaded by
libcurl.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:43:58 -05:00
Dave Reisner
768451c5e3 lib/dload.c: fix compiler warnings generated by -Wfloat-equal
* introduces new macro in util.h (DOUBLE_EQ) for properly comparing
  floating point values

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:43:53 -05:00
Dave Reisner
db49c4a7f0 buildsys: use libcurl's m4 macro for buildtime detection
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:43:17 -05:00
Allan McRae
2f060dec6a Report output from signature checking to debug log
Move the (possibly still temporary) output generated during signature
checking into the --debug output.

Signed-off-by: Allan McRae <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:36:48 -05:00
Xavier Chantry
f9505063f8 Added gpg verification options per repo to the config file.
Once we do this, add support for VerifySig to pactest. We just check if
the repo name contains Always, Never or Optional to determine the value
of VerifySig. The default is Never. pacman uses Always by default but
this is not suitable for pactest.

Original-work-by: shankar <jatheendra@gmail.com>
Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:35:50 -05:00
Dan McGee
18c6946961 Remove unnecessary sanity check on db->setserver
We pass in a db object, so no need to go looking for it in the list on
the handle. This is a remnant of when we passed in a treename, more than
likely.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:33:31 -05:00
Chris Brannon
ac88e90557 Let pacman specify GnuPG's home directory.
GnuPG looks for configuration files and keyrings in its home directory.
For a user, that is typically ~/.gnupg.
This patch causes pacman to use /etc/pacman.d/gnupg/ as the default
GnuPG home.  One may override the default using --gpgdir on the command-line
or GPGDir in pacman's configuration file.

Signed-off-by: Chris Brannon <cmbrannon@cox.net>
Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:22:36 -05:00
Dan McGee
5b962f0d1c Add a pactest showing failed GPG verification
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:16:29 -05:00
Dan McGee
39c75c7000 Integrate GPGME into libalpm
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:16:29 -05:00
Dan McGee
061948597d Add some error codes for signature verification
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:16:29 -05:00
Dan McGee
4ae902ec5f Add signature directory as option on libalpm handle
This will serve as the home directory we pass to GPGME when making calls so
we can have a libalpm-utilized keyring.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:16:29 -05:00
Dan McGee
39ce9b3afc Actually read PGPSIG field in sync DB code
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 03:07:08 -05:00
Dan McGee
f7b577dc77 Merge branch 'gpg-libalpm-basics' 2011-03-23 02:34:51 -05:00
Dan McGee
cedc633757 Add a few pactests for PGP integration
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 02:33:07 -05:00
Dan McGee
8584c25903 Remove libfetch error code
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 02:29:35 -05:00
Dan McGee
88746ec067 Read in .sig files when opening a package file
If a .sig file sits side-by-side on the filesystem with a package archive,
read it in during the package struct creation process so we can verify it at
a later time if necessary.

Signed-off-by: Dan McGee <dan@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 02:22:00 -05:00
Dan McGee
39da0198cd Add PGP signature support to pactest
Allow pkg.pgpsig to end up in the created sync databases.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 02:22:00 -05:00
Dan McGee
60159c2e77 Allow PGP signature to be read from sync database
Add a new field to the package struct to hold PGP information and
instruct db_read to pick it up from the database. It is currently unused
internally but this is the first step.

Due to the fact that we store the PGP sig as binary data, we need to store
both the data and the length so we have a small utility struct to assist us.

Signed-off-by: Dan McGee <dan@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 02:22:00 -05:00
Dan McGee
9f2a3023f8 Add base64 algorithms from PolarSSL to libalpm
We will need these for GPG functionality (decoding the base64 encoded
signature stored in the databases).

Signed-off-by: Dan McGee <dan@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 02:22:00 -05:00
Dan McGee
0908533127 Merge branch 'gpg-build-tools' 2011-03-23 02:18:57 -05:00
Dan McGee
a31d091fb3 repo-add: add sha256sum values to repo database
Implements FS#23103. Also modify libalpm so it ignores this value
without any warning as we know it is likely to exist.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 02:18:48 -05:00
Dan McGee
36747e4a7f Merge branch 'gpg-pacman-key' 2011-03-23 02:17:58 -05:00
Dan McGee
3df49acb30 Merge branch 'maint' 2011-03-23 02:16:13 -05:00
Dan McGee
b625d03dd6 pacman-key manpage updates
Make consistent in formatting, syntax, and prose with the rest of our
documentation.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 01:59:43 -05:00
Dan McGee
964e8c5bf2 pacman-key help, round three
Make it actually like all our other tools rather than some homegrown
format. Also make it translator friendly by not wrapping messages across
lines in different strings.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 01:59:42 -05:00
Guillaume Alaux
482da2eceb Add man-page for pacman-key
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 01:59:42 -05:00
Allan McRae
5a89a12aa0 pacman-key: improve usage output
Make the usage output display nicely on 80 character width terminals.

Also fix parsing of "-h" and "-v" options and avoid root check when
run with no commands.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 01:59:42 -05:00
Denis A. Altoé Falqueto
422925a65e pacman-key: remake of --reload command
The --reload command was refactored to allow a more flexible management.
There are two sets of keys that will be added, one that will be
removed and one that will be kept.

The set of keys to be kept are configured in pacman.conf, with the
option HoldKeys, with the same meaning of HoldPkgs. It can be repeated
and several values can be put in the same entry.

The new behavior allows a key to be marked for removal, but the user
can decide if that key must be kept. For example, if a developer has
a public repository, signed with his own key, that key must be added
to the HoldKeys option. If the key is marked for removal from pacman's
keyring, it will not be removed for the users that have configured
HoldKeys correctly.

There are other minor fixes, mainly in the handling of --add command
when there is no aditional parameter. In that case, pacman-key will
behave just like gpg, adding the contents of stdin into pacman's keyring.

Signed-off-by: Denis A. Altoé Falqueto <denisfalqueto@gmail.com>
2011-03-23 01:59:42 -05:00
Denis A. Altoé Falqueto
ae20f88202 pacman-key: keyring management tool
The script pacman-key will manage pacman's keyring. It imports, exports,
fetches from keyservers, helps in the process of trusting and updates
the trust database.

Signed-off-by: Denis A. Altoé Falqueto <denisfalqueto@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 01:59:42 -05:00
Allan McRae
93591d428f repo-add: add symlink to signature file
Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-23 00:26:54 -05:00
Dan McGee
f0f8319769 repo-add: Fix up usage with GPG options
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 00:26:54 -05:00
Dan McGee
38f94da47d repo-add: add -v/--verify option
This is intended to verify an existing signature on a database before
making further changes to it and performing updates. Rarely would you
use this without immediately resigning it via the -s/--sign option.
Instead, it is intended as a "chain of trust" operation where the
previous signature is verified to give you some sense that what you sign
off on is also safe.

Still todo: don't make changes unless the signature is not only good,
but also in the accepted list of keys.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 00:26:54 -05:00
Dan McGee
a4120f2015 repo-add: allow signing of the package database
In order to be fully secure, we can't only sign packages. We also need
to sign our repository metadata to prevent database falsification,
dependency injection, etc. Add an '-s/--sign' option that allows this
functionality, and will generate a .sig file side-by-side with the
package database.

While at it, fix the issue where a signature file would never be found
because of 'cd' madness (this needs fixing in another commit).

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 00:26:54 -05:00
Geoffroy Carrier
8fde399fe6 Add PGPSIG field in repo-add
Use base64 encoding to store the value in the database if a .sig file exists
for the package being added.

Signed-off-by: Geoffroy Carrier <geoffroy.carrier@koon.fr>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-23 00:26:54 -05:00
Allan McRae
2f2f53ddc9 makepkg: place signature symlink in build dir
Be consistent in package and signature placements when using
PKGDEST.

Signed-off-by: Allan McRae <allan@archlinux.org>
2011-03-22 23:52:00 -05:00
Dan McGee
82e22596d8 makepkg: allow signatures to work with split packages
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-22 23:52:00 -05:00
Geoffroy Carrier
ee34869e89 Add GPG signature support to makepkg
This is a rather simple patch to add signing support to makepkg. Add a
create_signature() to makepkg, add a 'sign' BUILDENV option in makepkg.conf,
and document the changes in the makepkg.conf manpage.

Signed-off-by: Geoffroy Carrier <geoffroy.carrier@koon.fr>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-22 23:52:00 -05:00
Dan McGee
0ff52b6845 Merge branch 'maint'
Conflicts due to change in return calling style.

Conflicts:
	src/pacman/pacman.c
	src/pacman/sync.c
2011-03-21 07:53:13 -05:00
Lukas Fleischer
c67c864ffd Don't initialize progress to zero before calling curl_easy_perform().
Drawing progress bars before calling curl_easy_perform() is needless as
the curl progress callback is called with zero progress before actually
downloading the file anyways. Fixes display of "0%" progress bars when
sync'ing package databases that are already up to date.

Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-21 07:51:27 -05:00
Dan McGee
488f341f57 Ensure dlcb is defined before calling it
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-21 07:50:31 -05:00
Dan McGee
0303b26b1e Style change: return(x) --> return x
This was discussed and more or less agreed upon on the mailing list. A
huge checkin, but if we just do it and let people adjust the pain will
end soon enough. Rebasing should be relatively straighforward for anyone
that sees conflicts; just be sure you use the new return style if
possible.

The following semantic patch was used to do the change, along with some
hand-massaging in order to preserve parenthesis where appropriate:

The semantic match that finds this problem is as follows, although some
hand-massaging was done in order to keep parenthesis where appropriate:
(http://coccinelle.lip6.fr/)

// <smpl>
@@
expression a;
@@
- return(a);
+ return a;

// </smpl>

A macros_file was also provided with the following content:

Additional steps taken, mainly for ASSERT() macros:
$ sed -i -e 's#return(NULL)#return NULL#' lib/libalpm/*.c
$ sed -i -e 's#return(-1)#return -1#' lib/libalpm/*.c

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-20 19:49:45 -05:00
Dave Reisner
0cf05c77ad lib/dload.c: fix opening braces to conform with coding style
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-20 18:49:01 -05:00
Dan McGee
b2fde01c54 Merge branch 'maint' 2011-03-20 11:49:42 -05:00
Dave Reisner
524b338974 INSTALL: replace libfetch with libcurl
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-20 11:32:08 -05:00
Dave Reisner
352b799efc lib/dload.c: remove lingering libfetch specific headers
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-20 11:32:02 -05:00
Dave Reisner
ff713a51bd remove antiquated contrib/wget-xdelta.sh
Support for this script was removed in makepkg by commit b4e1365. Delta
creation support has been provided by scripts/pkgdelta.

Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-17 10:05:33 -05:00
Dave Reisner
0da6c591c0 Fix triple progress bars on download
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-03-17 10:05:26 -05:00
Dan McGee
e6c9076a74 Merge branch 'maint' 2011-03-16 19:55:28 -05:00
Dan McGee
cff36093f3 Merge branch 'download' 2011-03-16 19:25:35 -05:00
Dave Reisner
f2eac18a6e Remove all traces of libfetch
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
4ad4527d10 dload: temp patch to allow curl/fetch coexistance
this is just some debuggery to allow pacman to operate with both fetch
and curl at the same time. use the PACMANDL variable to control which
library is used.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
96e458b705 dload.c: add curl_download_internal
This is a feature complete re-implementation of the fetch based internal
downloader, with a few improvements:

* support for SSL
* gzip and deflate compression on HTTP connections
* reuses a single connection over the entire session for lower resource
  usage.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
8a58648471 handle error case for PM_ERR_LIBCURL
Add PM_ERR_LIBCURL to error enum and handle case in error.c by returning
curl_easy_strerror() based on the error number carried by the gloabl alpm
handle.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
a5b6a75787 share code between libfetch and libcurl
no actual code changes here. change preprocessor logic to include
get_tempfile, get_destfile, signal handler enum, and the interrupt
handler logic when either HAVE_LIBCURL or HAVE_LIBFETCH are defined.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
159e1b06a5 prefix fetch based functions with fetch_
Do this in preparation for implementing similar curl based
functionality. We want the ability to test these side by side.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
278c847106 handle: Add CURL* and CURLcode vars to struct
Adding the CURLcode is necessary in order to return an error string from
pm_error. Unlike libfetch, curl returns numerical error numbers and does
not maintain a staticly allocated string with the last error generated.

Adding the curl object itself to the handle is advantageous (and
encouraged by curl_easy_perform(3)) because the handle is reusable for
successive operations. This cuts back on overhead when downloading
multiple files in a single transaction.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
75bfe825fc add curl to alpm initialization and teardown routines
Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
Dave Reisner
67391c2c6c Add configure.ac option for --with-curl
To avoid breaking compilation, fetch defaults to 'no', and curl defaults
to 'check'.

Signed-off-by: Dave Reisner <d@falconindy.com>
2011-03-09 15:22:32 -05:00
294 changed files with 71207 additions and 57253 deletions

View File

@@ -7,7 +7,12 @@ source_file = lib/libalpm/po/libalpm.pot
source_lang = en
[archlinux-pacman.pacman-pot]
file_filter = po/<lang>.po
source_file = po/pacman.pot
file_filter = src/pacman/po/<lang>.po
source_file = src/pacman/po/pacman.pot
source_lang = en
[archlinux-pacman.pacman-scripts-pot]
file_filter = scripts/po/<lang>.po
source_file = scripts/po/pacman-scripts.pot
source_lang = en

10
HACKING
View File

@@ -35,7 +35,7 @@ while(it) {
if(fn) {
fn(it->data);
} else {
return(1);
return 1;
}
free(it);
it = ptr;
@@ -67,11 +67,11 @@ alpm_list_t *alpm_list_add(alpm_list_t *list, void *data)
NOT
// This is a comment
5. Return statements should be written like a function call.
5. Return statements should *not* be written like function calls.
return(0);
NOT
return 0;
NOT
return(0);
6. The sizeof() operator should accept a type, not a value. (TODO: in certain
cases, it may be better- should this be a set guideline? Read "The Practice
@@ -147,5 +147,5 @@ For example, to run valgrind:
valgrind --leak-check=full -- src/pacman/.libs/lt-pacman -Syu
/////
vim: set ts=2 sw=2 syntax=asciidoc et:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

View File

@@ -16,8 +16,8 @@ properly build pacman.
libarchive
http://code.google.com/p/libarchive/
libfetch
ftp://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/net/libfetch/README.html
libcurl
http://curl.haxx.se/libcurl/
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following

View File

@@ -1,4 +1,4 @@
SUBDIRS = lib/libalpm src/util src/pacman scripts etc po test/pacman test/util contrib
SUBDIRS = lib/libalpm src/util src/pacman scripts etc test/pacman test/util contrib
if WANT_DOC
SUBDIRS += doc
endif
@@ -14,14 +14,19 @@ EXTRA_DIST = HACKING
# Sample makepkg prototype files
pkgdatadir = ${datadir}/${PACKAGE}
dist_pkgdata_DATA = PKGBUILD.proto PKGBUILD-split.proto proto.install ChangeLog.proto
dist_pkgdata_DATA = \
proto/PKGBUILD.proto \
proto/PKGBUILD-split.proto \
proto/proto.install \
proto/ChangeLog.proto
# run the pactest test suite and vercmp tests
check-local: test/pacman test/util src/pacman src/util
$(PYTHON) $(top_srcdir)/test/pacman/pactest.py --debug=1 \
--test $(top_srcdir)/test/pacman/tests/*.py \
-p $(top_builddir)/src/pacman/pacman
rm -rf $(top_builddir)/root
$(SH) $(top_srcdir)/test/util/pacsorttest.sh \
$(top_builddir)/src/util/pacsort
$(SH) $(top_srcdir)/test/util/vercmptest.sh \
$(top_builddir)/src/util/vercmp

2
NEWS
View File

@@ -6,7 +6,7 @@ VERSION DESCRIPTION
- flush terminal input before reading response (FS#20538)
- allow files to be replaced by directories (FS#24904)
- makepkg: fix filenames with spaces and noextract (FS#25100)
- scripts: remove ln -f option for POSIX compliance (FS24893)
- scripts: remove ln -f option for POSIX compliance (FS#24893)
- various small documentation updates
- minor translation updates: de, fi
3.5.3 - segfault when creating lock in non-existent dir (FS#24292)

8
README
View File

@@ -73,8 +73,8 @@ The following options are read-only, having ONLY alpm_option_get_* functions:
* lockfile: The file used for locking the database
(Default: <dbpath>/db.lck)
* localdb: A pmdb_t structure for the local (installed) database
* syncdbs: A list of pmdb_t structures to which pacman can sync from.
* localdb: A alpm_db_t structure for the local (installed) database
* syncdbs: A list of alpm_db_t structures to which pacman can sync from.
The following options are write-only, having ONLY alpm_option_set_* functions:
@@ -192,8 +192,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 showsize or totaldownload, or the behavior with
cleanmethod and syncfirst). 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]

View File

@@ -1,57 +0,0 @@
== This is my custom TODO file ==
* transaction object should contain two package list (install and remove)
instead of a single list of syncpkgs - this should allow us to get rid of that
type. This also requires seperate functionality to return a list of
"replaces" packages to the front end, so the frontend can handle the QUESTION()
stuff in that case
* libalpm -> front end communication needs a work-up. Both progress functions
can be combined into one callback, IFF we adjust it to accept a prefix string
for the progress bars, and format it at the lib side. Question functions
should also do the same - create the string at the library side, and simply
call some sort of int yes_no = ask_question("Do foo with bar?");
* move logging (alpm_logaction) out of the library. log files should be
written by the app, not the library. Adding a PM_LOG_* constant that
frontends can recognize and send to a file is probably a good idea.
* clear up list allocation/deallocation - some lists need to be free'd, some
do not and there is no clear indication WHEN this should happen.
* remove DB entries (directories) on a read error?
* Add a pm_errstr error string, which will allow us to do things like:
pm_errno = PM_ERR_LIBARCHIVE;
pm_errstr = archive_error_string(archive);
or:
pm_errno = PM_ERR_LIBDOWNLOAD;
pm_errstr = downloadLastErrString;
This way we don't break abstraction when returning specific errors in
cases like the above.
* pacman: A LOT of functions are way too long. There should be an upper limit of
100-200 lines. _alpm_add_commit is around 600 lines, and is far too complex.
* pacman: fixup doxygen documentation for public interface
* feature for 3.1: package file hooks *
I've been planning on this one for some time. Here's a simple rundown:
in /etc/pacman.d/hooks:
Hook /usr/include/* : /usr/bin/ctags -R /usr/include/*.h -f /usr/include/systags
This will allow us to make "global hooks" to simplify a lot of repetitive
install files (scrollkeeper, depmod, etc). This also allows us to move
ldconfig out of pacman entirely.
possible: /etc/pacman.hooks/* files for hooks, so packages can add them too
* feature for 3.1: multiple search/match types
option: MatchType regex (current way)
MatchType fnmatch (use fnmatch to match things like 'pacman -S gnome*')
MatchType plain (no matching. expect plain text).
* feature for 3.1: revamp the autotools system. I'd LOVE to use a manual system
like wmii and friends do. It'd be real nice if we could just do away with
autotools altogether.
**** BUGS ****
* Removal of conflicts on -A and -U (INCOMPLETE)

101
TODO.dan
View File

@@ -1,101 +0,0 @@
TODO.dan
========
This is my personal TODO list. No guarantees if it is out of date and things no
longer apply. If you want to help out with any of it, send me an email.
Pacman 3.1:
-----------
Downgrade feature - allow users to see cached packages and downgrade to
(previous or any?) available options.
Installed size and download size in -Si/Qi output should scale with package
size- KB to MB to GB. We should also get consistancy of K/KB, M/MB, etc.
Extreme similarity between some of the sync and add code...we have to be able
to abstract more away from sync actions and add actions to just 'actions'
(example: sync,c, add.c, and deptest.c all contain a switch on PM_DEP_MOD_*).
Merge update, add, and sync code when possible, so we reduce duplication.
Review progress/transaction event subsystem. (from TODO)
Add Doxygen comments to every function in libalpm including private functions.
Ensure functions are doing exactly their purpose and nothing more. Find
functions that perform duplicate behavior and merge them. Combine and refactor
others. Delete unnecessary functions. Stop keeping everything clustered in
little add/sync/remove parts, allow transactions to share code.
Go through options list. Decide if namings are good, all options are still
relevant, etc. Ideas for -Re (#6273), changing meaning of -c (has two meanings,
another FS bug), etc. Remove the -A flag and possibly -D, -T, and -Y (-Y is
killed now in favor of vercmp binary) if they can be done by other actions.
Possible switch of -U --> -I (#5571).
Review display and logging functions. There seems to be an abundance of them.
Make it extensible to use color, review what verbose/debug means. Perhaps
separate logging functionality- Pacman has its normal log, and alpm backend
keeps a very simple log file - listing only adds (including syncs) and removes.
This way a consistency list can be kept of what is currently installed and what
isn't, without all the logging junk from the front end.
Profile the code. Find the functions that are being called a lot, and see what
can be done about it. Find out if all these calls are necessary (e.g. excessive
alpm_list_count calls), and maybe think about changing data structures to speed
operations up (e.g. a 'count' field). NOTE: already found two huge issues with
quick profiling- excessive setlocale calls, and extremely excessive strcmp
calls.
Fix other localized issues- use non-printf when necessary. We may need to use
some wchar_t output on the progress bar as char/byte counts differ here. Sizes
of packages (e.g. 10,400.23 MB) should all be localized with correct
seperators.
Rewrite makepkg to use terminal-safe coloring/bolding. tput utility should
allow us to do this. Make universal message functions for systemwide use,
including all pacman utilites- abs, pacman-optimize, etc.
Bugs/FRs to smash: 6468, 6437, 6430?, 6420, 6404, 6389, 6312?, 6284, 6273?,
6255?, 6208, 5987, 5885, 5571, 4182, 3492, 2810?, 1769, 1588, 1571
Update doxygen comments, they may need some work. Try to document all of the
private internal functions too- it helps a ton for people just getting a
start on pacman hacking.
Other smaller things:
---------------------
unsigned int vs. unsigned- determine a standard and stick with it
FS #4185 - move where message is logged, perhaps?
Update copyrights (2007)
Update pacman website, and add/finish pacman coding style page
Refine makepkg error codes. Each kind of failure could have its own code:
--package already built
--failed integ checks
--failed build
--etc.
Add utility function to either frontend or backend to convert sizes: e.g. bytes
to KB, MB, GB.
Revamp the downloadprog function a bit. Seems kind of messy.
--print-uri option to sync should not require saying yes or no to up to date
Build a replacement for this, or at least standardize its use. We shouldn't
always need to pass handle->root around, it is constant. Something like char*
buildpath(file).
/* build the new entryname relative to handle->root */
snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
Random ideas:
-------------
Possibly split utilities/extras from pacman package
Make .indent.pro file for GNU indent (started, but didn't finish)

View File

@@ -26,12 +26,7 @@ rm -f test/pacman/*.pyc
rm -f doc/html/*.html
rm -f doc/man3/*.3
rm -f po/{Makefile.in,Makefile}
rm -f po/POTFILES
rm -f po/stamp-po
rm -f po/*.gmo
rm -f lib/libalpm/po/{Makefile.in,Makefile}
rm -f lib/libalpm/po/POTFILES
rm -f lib/libalpm/po/stamp-po
rm -f lib/libalpm/po/*.gmo
rm -f {lib/libalpm,scripts,src/pacman}/po/{Makefile.in,Makefile}
rm -f {lib/libalpm,scripts,src/pacman}/po/POTFILES
rm -f {lib/libalpm,scripts,src/pacman}/po/stamp-po
rm -f {lib/libalpm,scripts,src/pacman}/po/*.gmo

View File

@@ -41,13 +41,13 @@ AC_PREREQ(2.62)
# Bugfix releases:
# pacman_version_micro += 1
m4_define([lib_current], [6])
m4_define([lib_revision], [4])
m4_define([lib_current], [7])
m4_define([lib_revision], [0])
m4_define([lib_age], [0])
m4_define([pacman_version_major], [3])
m4_define([pacman_version_minor], [5])
m4_define([pacman_version_micro], [4])
m4_define([pacman_version_major], [4])
m4_define([pacman_version_minor], [0])
m4_define([pacman_version_micro], [0rc1])
m4_define([pacman_version],
[pacman_version_major.pacman_version_minor.pacman_version_micro])
@@ -93,10 +93,13 @@ AC_ARG_WITH(openssl,
AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations instead of internal routines]),
[], [with_openssl=check])
# Help line for libfetch
AC_ARG_WITH(fetch,
AS_HELP_STRING([--with-fetch], [use libfetch as an internal downloader]),
[], [with_fetch=check])
# Help line for using gpgme
AC_ARG_WITH(gpgme,
AS_HELP_STRING([--with-gpgme], [use GPGME for PGP signature verification]),
[], [with_gpgme=check])
# Check for useable libcurl
LIBCURL_CHECK_CONFIG([yes], [7.19.4], [with_libcurl=yes], [with_libcurl=no])
# Help line for documentation
AC_ARG_ENABLE(doc,
@@ -130,9 +133,12 @@ AC_CHECK_PROGS([PYTHON], [python2.7 python2.6 python2.5 python2 python], [false]
AC_PATH_PROGS([BASH_SHELL], [bash bash4 bash3], [false])
# find installed gettext
AM_GNU_GETTEXT([external])
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
AC_CHECK_LIB([archive], [archive_read_data], ,
AC_MSG_ERROR([libarchive is needed to compile pacman!]))
@@ -145,28 +151,23 @@ AS_IF([test "x$with_openssl" != "xno"],
[if test "x$with_openssl" != "xcheck"; then
AC_MSG_FAILURE([--with-openssl was given, but -lssl was not found])
fi],
[-lcrypto])],
[-lcrypto])
with_openssl=$ac_cv_lib_ssl_MD5_Final],
AC_MSG_RESULT(no))
AM_CONDITIONAL([HAVE_LIBSSL], [test "x$ac_cv_lib_ssl_MD5_Final" = "xyes"])
AM_CONDITIONAL([HAVE_LIBSSL], [test "x$with_openssl" = "xyes"])
# Enable or disable usage of libfetch
AC_MSG_CHECKING(whether to link with libfetch)
AS_IF([test "x$with_fetch" != "xno"],
# Check for gpgme
AC_MSG_CHECKING(whether to link with libgpgme)
AS_IF([test "x$with_gpgme" != "xno"],
[AC_MSG_RESULT(yes)
AC_CHECK_LIB([fetch], [fetchParseURL], ,
[if test "x$with_fetch" != "xcheck"; then
AC_MSG_FAILURE([--with-fetch was given, but -lfetch was not found])
AC_CHECK_LIB([gpgme], [gpgme_check_version], ,
[if test "x$with_gpgme" != "xcheck"; then
AC_MSG_FAILURE([--with-ggpme was given, but -lgpgme was not found])
fi],
[-lcrypto -ldl])
# Check if libfetch supports connnection caching which we use
AS_IF([test "x$ac_cv_lib_fetch_fetchParseURL" = "xyes"],
[AC_CHECK_DECL(fetchConnectionCacheInit, ,
AC_MSG_ERROR([libfetch must be version 2.28 or greater]),
[#include <fetch.h>])
])
],
[-lgpgme])
with_gpgme=$ac_cv_lib_gpgme_gpgme_check_version],
AC_MSG_RESULT(no))
AM_CONDITIONAL([HAVE_LIBFETCH], [test "x$ac_cv_lib_fetch_fetchParseURL" = "xyes"])
AM_CONDITIONAL([HAVE_LIBGPGME], [test "x$with_gpgme" = "xyes"])
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h glob.h libintl.h locale.h mntent.h string.h \
@@ -241,48 +242,10 @@ AC_SUBST(STRIP_BINARIES)
AC_SUBST(STRIP_SHARED)
AC_SUBST(STRIP_STATIC)
# Check for architecture, used in default makepkg.conf
# (Note single space left after CARCHFLAGS)
case "${host}" in
i686-*)
CARCH="i686"
CARCHFLAGS="-march=i686 "
;;
x86_64-*)
CARCH="x86_64"
CARCHFLAGS="-march=x86-64 "
;;
ia64-*)
CARCH="ia64"
CARCHFLAGS="-march=ia64 "
;;
sparc-*)
CARCH="sparc"
CARCHFLAGS="-mcpu=v9 "
;;
ppc-* | powerpc-*)
CARCH="ppc"
CARCHFLAGS="-mcpu=750 "
;;
i386-*)
CARCH="i386"
CARCHFLAGS="-march=i386 "
;;
arm-*)
CARCH="arm"
CARCHFLAGS="-march=armv4 "
;;
*)
AC_MSG_WARN([[Your architecture is unknown for makepkg.conf, consider adding it to configure.ac]])
CARCH="unknown"
CARCHFLAGS=""
;;
esac
# Now do some things common to all architectures
# Variables plugged into makepkg.conf
CARCH="${host%%-*}"
CHOST="${host}"
AC_SUBST(CARCH)
AC_SUBST(CARCHFLAGS)
AC_SUBST(CHOST)
# Check for documentation support and status
@@ -372,11 +335,12 @@ AC_CONFIG_FILES([
lib/libalpm/Makefile
lib/libalpm/po/Makefile.in
src/pacman/Makefile
src/pacman/po/Makefile.in
src/util/Makefile
scripts/Makefile
scripts/po/Makefile.in
doc/Makefile
etc/Makefile
po/Makefile.in
test/pacman/Makefile
test/pacman/tests/Makefile
test/util/Makefile
@@ -396,12 +360,15 @@ ${PACKAGE_NAME}:
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 : ${CFLAGS}
defines : ${DEFS}
library flags : ${LIBS}
linker flags : ${LDFLAGS}
Architecture : ${CARCH}
Architecture flags : ${CARCHFLAGS}
Host Type : ${CHOST}
Filesize command : ${SIZECMD}
In-place sed command : ${SEDINPLACE}
@@ -418,6 +385,9 @@ ${PACKAGE_NAME}:
build script name : ${BUILDSCRIPT}
Compilation options:
Use libcurl : ${with_libcurl}
Use GPGME : ${with_gpgme}
Use OpenSSL : ${with_openssl}
Run make in doc/ dir : ${wantdoc} ${asciidoc}
Doxygen support : ${usedoxygen}
debug support : ${debug}

2
contrib/.gitignore vendored
View File

@@ -1,7 +1,9 @@
bacman
bash_completion
paccache
pacdiff
paclist
paclog-pkglist
pacscripts
pacsearch
wget-xdelta.sh

View File

@@ -1,10 +1,11 @@
OURSCRIPTS = \
bacman \
paccache \
pacdiff \
paclist \
paclog-pkglist \
pacscripts \
pacsearch \
wget-xdelta.sh
pacsearch
OURFILES = \
bash_completion \
@@ -14,12 +15,13 @@ EXTRA_DIST = \
PKGBUILD.vim \
bacman.in \
bash_completion.in \
paccache.in \
paclog-pkglist.in \
pacdiff.in \
paclist.in \
pacscripts.in \
pacsearch.in \
vimprojects \
wget-xdelta.sh.in \
zsh_completion.in \
README
@@ -29,7 +31,8 @@ MOSTLYCLEANFILES = $(OURSCRIPTS) $(OURFILES) *.tmp
edit = sed \
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@BASH_SHELL[@]|$(BASH_SHELL)|g'
-e 's|@SIZECMD[@]|$(SIZECMD)|g' \
-e '1s|!/bin/bash|!$(BASH_SHELL)|g'
$(OURSCRIPTS): Makefile
@echo ' ' GEN $@;
@@ -50,12 +53,13 @@ all-am: $(OURSCRIPTS) $(OURFILES)
bacman: $(srcdir)/bacman.in
bash_completion: $(srcdir)/bash_completion.in
paccache: $(srcdir)/paccache.in
pacdiff: $(srcdir)/pacdiff.in
paclist: $(srcdir)/paclist.in
paclog-pkglist: $(srcdir)/paclog-pkglist.in
pacscripts: $(srcdir)/pacscripts.in
pacsearch: $(srcdir)/pacsearch.in
pactree: $(srcdir)/pactree.in
wget-xdelta.sh: $(srcdir)/wget-xdelta.sh.in
zsh_completion: $(srcdir)/zsh_completion.in
# vim:set ts=2 sw=2 noet:

View File

@@ -13,6 +13,7 @@ elseif exists("b:current_syntax")
endif
let b:main_syntax = "sh"
let b:is_bash = 1
runtime! syntax/sh.vim
" case on
@@ -106,6 +107,11 @@ 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 ckdepends 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
@@ -228,6 +234,7 @@ 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

View File

@@ -28,6 +28,3 @@ database entries. Useful for reuse, or possible config file extension.
vimprojects - a project file for the vim project plugin.
wget-xdelta.sh - A download script for pacman which allows binary deltas
generated with makepkg to be used instead of downloading full binary packages.
This should cut download sizes for some package upgrades significantly.

View File

@@ -1,4 +1,4 @@
#!@BASH_SHELL@
#!/bin/bash
#
# bacman: recreate a package from a running system
# This script rebuilds an already installed package using metadata

View File

@@ -31,11 +31,11 @@ _makepkg() {
local cur opts prev
COMPREPLY=()
_get_comp_words_by_ref cur prev
if [[ $cur = -* && ! $prev =~ ^-(-(cleancache|config|help)$|\w*[Chp]) ]]; then
opts=('allsource asroot clean cleancache config force geninteg help holdver
ignorearch install log nobuild nocolor noconfirm nodeps noextract
noprogressbar pkg repackage rmdeps skipinteg source syncdeps'
'A C L R c d e f g h i m o p r s')
if [[ $cur = -* && ! $prev =~ ^-(-(config|help)$|\w*[Chp]) ]]; then
opts=('allsource asroot check clean config force geninteg help holdver ignorearch
install log nobuild nocheck nocolor noconfirm nodeps noextract noprogressbar
nosign pkg repackage rmdeps sign skipinteg source syncdeps'
'A L R c d e f g h i m o p r s')
_arch_ptr2comp opts
fi
true
@@ -58,11 +58,11 @@ _pacman() {
database=('asdeps asexplicit')
query=('changelog check deps explicit file foreign groups info list owns
search unrequired upgrades' 'c e g i k l m o p s t u')
remove=('cascade dbonly nodeps nosave print recursive unneeded' 'c k n p s u')
remove=('cascade dbonly nodeps nosave print recursive unneeded' 'c n p s u')
sync=('asdeps asexplicit clean downloadonly force groups ignore ignoregroup
info list needed nodeps print refresh search sysupgrade'
info list needed nodeps print refresh recursive search sysupgrade'
'c f g i l p s u w y')
upgrade=('asdeps asexplicit force nodeps print' 'f p')
upgrade=('asdeps asexplicit force needed nodeps print recursive' 'f p')
common=('arch cachedir config dbpath debug help logfile noconfirm
noprogressbar noscriptlet quiet root verbose' 'b d h q r v')
core=('database help query remove sync upgrade version' 'D Q R S U V h')

300
contrib/paccache.in Executable file
View File

@@ -0,0 +1,300 @@
#!/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 -a candidates=() cmdopts=() whitelist=() blacklist=()
declare -i delete=0 dryrun=0 filecount=0 keep=3 move=0 totalsaved=0
declare cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' movedir= scanarch=
msg() {
local mesg=$1; shift
printf "==> $mesg\n" "$@"
} >&2
error() {
local mesg=$1; shift
printf "==> ERROR: $mesg\n" "$@"
} >&2
die() {
error "$@"
exit 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 parse_filename(filename, parts, count, i, pkgname, arch) {
count = split(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)
if (count > keep) {
for(i = 1; i <= count - keep; i++) {
print pkgs[i]
}
}
}
}
}' "${@:3}"
}
size_to_human() {
awk -v size="$1" '
BEGIN {
suffix[1] = "B"
suffix[2] = "KiB"
suffix[3] = "MiB"
suffix[4] = "GiB"
suffix[5] = "TiB"
count = 1
while (size > 1024) {
size /= 1024
count++
}
sizestr = sprintf("%.2f", size)
sub(/.?0+$/, "", sizestr)
printf("%s %s", sizestr, suffix[count])
}'
}
runcmd() {
if (( needsroot )); then
msg "Privilege escalation required"
if sudo -v &>/dev/null && sudo -l &>/dev/null; then
sudo "$@"
else
printf '%s ' 'root'
su -c "$(printf '%q ' "$@")"
fi
else
"$@"
fi
}
summarize() {
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
printf '%s (%s):\n' "$name" "$arch"
fi
printf ' %s\n' "$pkg"
elif (( verbose >= 2 )); then
printf "$PWD/%s$delim" "$pkg"
else
printf "%s$delim" "$pkg"
fi
done < <(printf '%s\n' "$@" | pacsort)
fi
printf -v output 'finished dry run: %d candidates' "$filecount"
fi
printf '\n' >&2
msg "$output (diskspace saved: %s)" "$(size_to_human "$totalsaved")"
}
usage() {
cat <<EOF
usage: ${0##*/} <operation> [options] [targets...]
${0##*/} is a flexible pacman cache cleaning utility, which has numerous
options to help control how much, and what, is deleted from any directory
containing pacman package tarballs.
Operations:
-d perform a dry run, only finding candidate packages.
-m <movedir> move candidate packages to 'movedir'.
-r remove candidate packages.
Options:
-a <arch> scan for 'arch' (default: all architectures).
-c <cachedir> scan 'cachedir' for packages (default: @localstatedir@/cache/pacman/pkg).
-f apply force to mv(1) and rm(1) operations.
-h display this help message.
-i <pkgs> ignore 'pkgs', which is a comma separated. Alternatively,
specify '-' to read package names from stdin, newline delimited.
-k <num> keep 'num' of each package in 'cachedir' (default: 3).
-u target uninstalled packages.
-v increase verbosity. specify up to 3 times.
-z use null delimiters for candidate names (only with -v and -vv)
EOF
}
if (( ! UID )); then
error "Do not run this script as root. You will be prompted for privilege escalation."
exit 42
fi
while getopts ':a:c:dfhi:k:m:rsuvz' opt; do
case $opt in
a) scanarch=$OPTARG ;;
c) cachedir=$OPTARG ;;
d) dryrun=1 ;;
f) cmdopts=(-f) ;;
h) usage
exit 0 ;;
i) if [[ $OPTARG = '-' ]]; then
[[ ! -t 0 ]] && IFS=$'\n' read -r -d '' -a ign
else
IFS=',' read -r -a ign <<< "$OPTARG"
fi
blacklist+=("${ign[@]}")
unset i ign ;;
k) keep=$OPTARG
if [[ $keep != $OPTARG ]] || (( keep < 0 )); then
die 'argument to option -k must be a non-negative integer'
fi ;;
m) move=1 movedir=$OPTARG ;;
r) delete=1 ;;
u) IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq)
blacklist+=("${ign[@]}")
unset ign ;;
v) (( ++verbose )) ;;
z) delim='\0' ;;
:) die "option '--%s' requires an argument" "$OPTARG" ;;
?) die "invalid option -- '%s'" "$OPTARG" ;;
esac
done
shift $(( OPTIND - 1 ))
# 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
[[ -d $cachedir ]] ||
die "cachedir \`%s' does not exist or is not a directory" "$cachedir"
[[ $movedir && ! -d $movedir ]] &&
die "move-to 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:0:1} != '/' ]] && movedir=$PWD/$movedir
[[ ! -w $cachedir || ( $movedir && ! -w $movedir ) ]] && needsroot=1
fi
# unlikely that this will fail, but better make sure
cd "$cachedir" || 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 candidates < \
<(printf '%s\n' *.pkg.tar?(.+([^.])) | pacsort |
pkgfilter "$keep" "$scanarch" \
"${#whitelist[*]}" "${whitelist[@]}" \
"${#blacklist[*]}" "${blacklist[@]}")
if (( ! ${#candidates[*]} )); then
msg 'no candidate packages found for pruning'
exit 1
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
runcmd rm "${cmdopts[@]}" "${candidates[@]}"
elif (( move )); then
runcmd mv "${cmdopts[@]}" "${candidates[@]}" "$movedir"
fi
summarize "$pkgcount" "${candidates[@]}"

View File

@@ -1,4 +1,4 @@
#!@BASH_SHELL@
#!/bin/bash
# pacdiff : a simple pacnew/pacorig/pacsave updater
#
# Copyright (c) 2007 Aaron Griffin <aaronmgriffin@gmail.com>

View File

@@ -1,7 +1,8 @@
#!/usr/bin/perl
#!/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
@@ -16,73 +17,27 @@
# 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;
export TEXTDOMAIN='pacman'
export TEXTDOMAINDIR='/usr/share/locale'
my $progname = "paclist";
my $version = "1.0";
if ($#ARGV != 0 || $ARGV[0] eq "--help" || $ARGV[0] eq "-h") {
print "$progname - List all packages installed from a given repo\n";
print "Usage: $progname <repo>\n";
print "Example: $progname testing\n";
if ($#ARGV != 0) {
exit 1;
# determine whether we have gettext; make it a no-op if we do not
if ! type gettext &>/dev/null; then
gettext() {
echo "$@"
}
exit 0;
}
fi
if ( $ARGV[0] eq "--version" || $ARGV[0] eq "-v") {
print "$progname version $version\n";
print "Copyright (C) 2008 Dan McGee\n";
exit 0;
}
if [[ -z $1 ]]; then
printf '%s - List all packages installed from a given repo\n' "${0##*/}"
printf 'Usage: %s <repo>\n' "${0##*/}"
printf 'Example: %s testing\n' "${0##*/}"
exit 1
fi
# This hash table will be used to store pairs of ('name version', count) from
# the return of both pacman -Sl <repo> and pacman -Q output. We then check to
# see if a value was added twice (count = 2)- if so, we will print that package
# as it is both in the repo we queried and installed on our local system.
my %packages = ();
my $output;
printf -v installed '[%s]' "$(gettext installed)"
pacman -Sl $1 | awk -v i="$installed" '$NF == i { print $2,$3 }'
$output = `pacman -Sl $ARGV[0]`;
if ($? != 0) {
exit 1;
}
my @sync = split(/\n/, $output);
# sample output from pacman -Sl:
# testing foobar 1.0-1
foreach $_ (@sync) {
my @info = split(/ /);
# we only want to store 'foobar 1.0-1' in our hash table
my $pkg = $info[1] . " " . $info[2];
$packages{$pkg}++;
}
# exit with pacman's return value, not awk's
exit ${PIPESTATUS[0]}
$output = `pacman -Q`;
if ($? != 0) {
exit 1;
}
# sample output from pacman -Q:
# foobar 1.0-1
my @local = split(/\n/, $output);
foreach $_ (@local) {
# store 'foobar 1.0-1' in our hash table
$packages{$_}++;
}
# run comparison check- if value was added twice, it was in the intersection
my @intersection;
foreach $_ (keys %packages) {
if ($packages{$_} == 2) {
push @{ \@intersection }, $_;
}
}
# print our intersection, and bask in the glory and speed of perl
@intersection = sort @intersection;
foreach $_ (@intersection) {
print $_ . "\n";
}
#vim: set noet:
# vim: set ts=2 sw=2 noet:

68
contrib/paclog-pkglist.in Executable file
View File

@@ -0,0 +1,68 @@
#!/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/>.
export TEXTDOMAIN='pacman'
export TEXTDOMAINDIR='/usr/share/locale'
declare logfile=${1:-@localstatedir@/log/pacman.log}
if [[ $1 ]]; then
if [[ $1 = -@(h|-help) ]]; then
printf 'usage: %s [pacman log]\n' "${0##*/}"
printf 'example: %s @localstatedir@/log/pacman.log\n' "${0##*/}"
printf '\ndefaults to: @localstatedir@/log/pacman.log\n'
exit 0
elif [[ ! -e $logfile ]]; then
printf $"target not found: %s\n" "$1"
exit 1
fi
fi
<"$logfile" awk '
{
action = $3
pkgname = $4
pkgver = $5
upgver = $7
}
NF == 5 && action == "installed" {
gsub(/[()]/, "", pkgver)
pkg[pkgname] = pkgver
next
}
NF == 7 && action == "upgraded" {
sub(/\)/, "", upgver)
pkg[pkgname] = upgver
next
}
NF == 5 && action == "removed" {
pkg[pkgname] = -1
}
END {
for (i in pkg) {
if (pkg[i] != -1) {
printf "%s %s\n",i,pkg[i]
}
}
}' | sort
# vim: set ts=2 sw=2 noet:

View File

@@ -1,4 +1,4 @@
#!@BASH_SHELL@
#!/bin/bash
#
# pacscripts : tries to print out the {pre,post}_{install,remove,upgrade}
# scripts of a given package
@@ -61,7 +61,7 @@ spacman() {
if [ $EUID -eq 0 ]; then
pacman "$@"
else
if [ ! "$(type -p sudo)" ]; then
if ! type -p sudo; then
error "Cannot find the sudo binary! Is sudo installed?"
error "Otherwise try to run the program as root"
exit 1

View File

@@ -111,6 +111,8 @@ if ($#querypkgs >= 0) {
foreach $_ (@querypkgs) {
# we grab 4 fields here: repo, name/ver, installed, and desc
my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
# skip any non-matching line
next if not defined $pkgfields[1];
# since installed is optional, we should fill it in if necessary
$pkgfields[2] = "" if not defined $pkgfields[2];
# check if the package was listed in the sync out

View File

@@ -1,70 +0,0 @@
#!@BASH_SHELL@
if [ -r "@sysconfdir@/makepkg.conf" ]; then
source @sysconfdir@/makepkg.conf
else
echo "wget-xdelta: Unable to find makepkg.conf"
exit 1
fi
if [ -r ~/.makepkg.conf ]; then
source ~/.makepkg.conf
fi
out_file=$(basename $1)
file_url=$2
if ! [[ "$out_file" =~ "pkg.tar.gz" ]]; then
# If it's not a package file download as normal and exit.
#wget --passive-ftp -c -O "$out_file" "$file_url"
exit $?
fi
# Get the package name and version
[[ "$out_file" =~ "$CARCH" ]] && arch="-$CARCH" || arch=""
pkg_data=$(echo $out_file | \
sed "s|^\(.*\)-\([[:alnum:]_\.]*-[[:alnum:]_\.]*\)${arch}${PKGEXT}.part|\1 \2|")
pkgname=$(echo $pkg_data | cut -d ' ' -f 1)
new_version=$(echo $pkg_data | cut -d ' ' -f 2)
base_url=${file_url%/*}
# Look for the last version
for file in $(ls -r @localstatedir@/cache/pacman/pkg/${pkgname}-*-*{,-$CARCH}$PKGEXT 2>/dev/null); do
[[ "$file" =~ "$CARCH" ]] && arch="-$CARCH" || arch=""
check_version=$(echo $file | \
sed "s|^.*/${pkgname}-\([[:alnum:]_\.]*-[[:alnum:]_\.]*\)${arch}$PKGEXT$|\1|" | \
grep -v "^@localstatedir@/cache/pacman/pkg")
[ "$check_version" = "" ] && continue
vercmp=$(vercmp "$check_version" "$old_version")
if [ "$check_version" != "$new_version" -a $vercmp -gt 0 ]; then
old_version=$check_version
old_file=$file
fi
done
if [ "$old_version" != "" -a "$old_version" != "$new_version" ]; then
# Great, we have a cached file, now calculate a patch name from it
delta_name="$pkgname-${old_version}_to_${new_version}-${CARCH}.delta"
echo "wget-xdelta: Attempting to download delta $delta_name..." >&2
if wget --passive-ftp -c "$base_url/$delta_name"; then
echo "wget-xdelta: Applying delta..."
if xdelta patch "$delta_name" "$old_file" "$out_file"; then
echo "wget-xdelta: Delta applied successfully!"
rm "$delta_name"
exit 0
else
echo "wget-xdelta: Failed to apply delta!"
rm $delta_name
fi
fi
fi
echo "wget-xdelta: Downloading new package..."
wget --passive-ftp -c -O "$out_file" "$file_url"
exit $?
# vim:set ts=4 sw=4 noet:

View File

@@ -33,6 +33,9 @@ _pacman_opts_common=(
_pacman_opts_pkgfile=(
'-d[Skip dependency checks]'
'-f[Overwrite conflicting files]'
'--dbonly[Only remove database entry, do not remove files]'
'--needed[Do not reinstall up to date packages]'
'--recursive[Reinstall all dependencies of target packages]'
'*:package file:_files -g "*.pkg.tar.*(.)"'
)
@@ -62,9 +65,9 @@ _pacman_opts_query_modifiers=(
_pacman_opts_remove=(
'-c[Remove all dependent packages]'
'-d[Skip dependency checks]'
'-k[Only remove database entry, do not remove files]'
'-n[Remove protected configuration files]'
'-s[Remove dependencies not required by other packages]'
'--dbonly[Only remove database entry, do not remove files]'
'*:installed package:_pacman_completions_installed_packages'
)
@@ -74,6 +77,9 @@ _pacman_opts_sync_actions=(
'*-cc[Remove all packages from cache]:*:clean:->sync_clean'
'-g[View all members of a package group]:*:package groups:->sync_group'
'-s[Search package names and descriptions]:*:search text:->sync_search'
'--dbonly[Only remove database entry, do not remove files]'
'--needed[Do not reinstall up to date packages]'
'--recursive[Reinstall all dependencies of target packages]'
)
# options for passing to _arguments: options for --sync command

2
doc/.gitignore vendored
View File

@@ -3,7 +3,9 @@ libalpm.3
makepkg.8
makepkg.conf.5
pacman.8
pacman-key.8
pacman.conf.5
pkgdelta.8
repo-add.8
repo-remove.8
vercmp.8

View File

@@ -8,6 +8,8 @@ ASCIIDOC_MANS = \
makepkg.8 \
repo-add.8 \
vercmp.8 \
pkgdelta.8 \
pacman-key.8 \
PKGBUILD.5 \
makepkg.conf.5 \
pacman.conf.5 \
@@ -20,6 +22,8 @@ HTML_MANPAGES = \
makepkg.8.html \
repo-add.8.html \
vercmp.8.html \
pkgdelta.8.html \
pacman-key.8.html \
PKGBUILD.5.html \
makepkg.conf.5.html \
pacman.conf.5.html \
@@ -41,6 +45,8 @@ EXTRA_DIST = \
makepkg.8.txt \
repo-add.8.txt \
vercmp.8.txt \
pkgdelta.8.txt \
pacman-key.8.txt \
PKGBUILD.5.txt \
PKGBUILD-example.txt \
makepkg.conf.5.txt \
@@ -134,6 +140,8 @@ pacman.8 pacman.8.html: pacman.8.txt
makepkg.8 makepkg.8.html: makepkg.8.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
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

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
PKGBUILD(5)
===========
@@ -16,12 +16,12 @@ PKGBUILD
Description
-----------
This manual page is meant to describe general rules about PKGBUILDs. Once a
This manual page describes general rules about PKGBUILDs. Once a
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}'.
Also located there are other example files such as a ChangeLog and an install
NOTE: An example PKGBUILD, useful for reference, is located in '{pkgdatadir}'
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.
@@ -30,33 +30,33 @@ Options and Directives
----------------------
The following is a list of standard options and directives available for use
in a PKGBUILD. These are all understood and interpreted by makepkg, and most
will be directly transferred to the built package.
of them will be directly transferred to the built package.
If you need to create any custom variables for use in your build process, it is
recommended to name your custom variables with an '_' (underscore) prefix.
recommended to prefix their name with an '_' (underscore).
This will prevent any possible name clashes with internal makepkg variables.
For example, to store the base kernel version in a variable, use something
similar to `$_basekernver`.
*pkgname (array)*::
The name of the package. This has be a unix-friendly name as it will be
used in the package filename. Members of the array are not allowed to start
with hyphens.
Either the name of the package or an array of names for split packages.
Because it will be used in the package filename, this has to be unix-friendly.
Members of the array are not allowed to start with hyphens.
*pkgver*::
The version of the software as released from the author (e.g. '2.7.1').
The version of the software as released from the author (e.g., '2.7.1').
The variable is not allowed to contain colons or hyphens.
*pkgrel*::
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. A pkgrel of '1' is typically used for each upstream
software release and is incremented for intermediate PKGBUILD updates. The
flags, for example. This is typically set to '1' for each new upstream
software release and incremented for intermediate PKGBUILD updates. The
variable is not allowed to contain hyphens.
*pkgdesc*::
This should be a brief description of the package and its functionality.
Try to keep the description to one line of text.
Try to keep the description to one line of text and not use the package's name.
*epoch*::
Used to force the package to be seen as newer than any previous versions
@@ -69,50 +69,49 @@ similar to `$_basekernver`.
*url*::
This field contains a URL that is associated with the software being
packaged. This is typically the project's website.
packaged. Typically the project's website.
*license (array)*::
This field specifies the license(s) that apply to the package.
Commonly-used licenses are found in '/usr/share/licenses/common'. If you
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
found in '/usr/share/licenses/common', then you should include 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 for a package, list all of them:
'$pkgdir/usr/share/licenses/$pkgname/' when building the package. If
multiple licenses are applicable, list all of them:
`license=('GPL' 'FDL')`.
*install*::
Specifies a special install script that is to be included in the package.
This file should reside in the same directory as the PKGBUILD, and will
be copied into the package by makepkg. It does not need to be included
in the source array (e.g. `install=pkgname.install`).
in the source array (e.g., `install=pkgname.install`).
*changelog*::
Specifies a changelog file that is to be included in the package.
This file should reside in the same directory as the PKGBUILD, and will
be copied into the package by makepkg. It does not need to be included
in the source array (e.g. `changelog=$pkgname.changelog`).
in the source array (e.g., `changelog=$pkgname.changelog`).
*source (array)*::
An array of source files required to build the package. Source files
must either reside in the same directory as the PKGBUILD file, or be a
fully-qualified URL that makepkg will use to download the file. In order
to make the PKGBUILD as useful as possible, use the $pkgname and $pkgver
variables if possible when specifying the download location. Any files
that are compressed will automatically be extracted, unless found in
the noextract array listed below.
must either reside in the same directory as the PKGBUILD, or be a
fully-qualified URL that makepkg can use to download the file.
To make the PKGBUILD as useful as possible, use the `$pkgname` and `$pkgver`
variables if possible when specifying the download location. Compressed files
will be extracted automatically unless found in
the noextract array described below.
+
It is also possible to specify an optional filename, which is helpful
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
name. The syntax is: `source=('filename::url')`.
*noextract (array)*::
An array of filenames corresponding to those from the source array. Files
listed here will not be extracted with the rest of the source files. This
is useful for packages which use compressed data which is downloaded but
not necessary to uncompress.
is useful for packages that use compressed data directly.
*md5sums (array)*::
This array contains an MD5 hash for every source file specified in the
@@ -133,31 +132,36 @@ name. The syntax is: `source=('filename::url')`.
example, one could install all KDE packages by installing the 'kde' group.
*arch (array)*::
Defines on which architectures the given package is available (e.g.
Defines on which architectures the given package is available (e.g.,
`arch=('i686' 'x86_64')`). Packages that contain no architecture specific
files may use arch=('any').
files should use arch=('any').
*backup (array)*::
A space-delimited array of filenames, without preceding slashes, that
An array of filenames, without preceding slashes, that
should be backed up if the package is removed or upgraded. This is
commonly used for packages placing configuration files in /etc. See
Handling Config Files in linkman:pacman[8] for more information.
*depends (array)*::
An array of packages that this package depends on to run. Packages in
An array of packages this package depends on to run. Entries in
this list should be surrounded with single quotes and contain at least
the package name. Entries can also include a version requirement of the
form 'name<>version', where <> is one of five comparisons: >= (greater
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 auto detection.
*makedepends (array)*::
An array of packages that this package depends on to build, but are not
An array of packages this package depends on to build but are not
needed at runtime. Packages in this list follow the same format as
depends.
*checkdepends (array)*::
An array of packages that this package depends on to run its test suite,
An array of packages this package depends on to run its test suite
but are not needed at runtime. Packages in this list follow the same
format as depends. These dependencies are only considered when the
check() function is present and is to be run by makepkg.
@@ -177,7 +181,7 @@ name. The syntax is: `source=('filename::url')`.
same format as depends. Versioned conflicts are also supported.
*provides (array)*::
An array of ``virtual provisions'' that this package provides. This allows
An array of ``virtual provisions'' this package provides. This allows
a package to provide dependencies other than its own package name. For
example, the dcron package can provide 'cron', which allows packages to
depend on 'cron' rather than 'dcron OR fcron'.
@@ -186,9 +190,13 @@ name. The syntax is: `source=('filename::url')`.
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 auto detection.
*replaces (array)*::
An array of packages that this package should replace, and can be used
An array of packages this package should replace. This can be used
to handle renamed/combined packages. For example, if the 'j2re' package
is renamed to 'jre', this directive allows future upgrades to continue
as expected even though the package has moved. Sysupgrade is currently
@@ -223,6 +231,9 @@ name. The syntax is: `source=('filename::url')`.
*zipman*;;
Compress man and info pages with gzip.
*upx*;;
Compress binary executable files using UPX.
*ccache*;;
Allow the use of ccache during build. More useful in its negative
form `!ccache` with select packages that have problems building
@@ -248,27 +259,27 @@ name. The syntax is: `source=('filename::url')`.
build() Function
----------------
In addition to the above directives, the optional build() bash function usually
In addition to the above directives, the optional build() function usually
comprises the remainder of the PKGBUILD. This is directly sourced and executed
by makepkg, so anything that bash or the system has available is available for
use here. The function is run in `bash -e` mode, meaning any command that exits
with a non-zero status will cause the function to exit. Be sure any exotic
commands used are covered by `makedepends`.
All of the above variables such as `pkgname` and `pkgver` are available for use
in the build function. In addition, makepkg defines three variables for your
use during the build and install process. These three variables are as follows:
All of the above variables such as `$pkgname` and `$pkgver` are available for use
in the build function. In addition, makepkg defines the following three
variables for use during the build and install process:
*startdir*::
This contains the absolute path to the directory where the PKGBUILD was
This contains the absolute path to the directory where the PKGBUILD is
located, which is usually the output of `$(pwd)` when makepkg is started.
*srcdir*::
This points to the directory where makepkg extracts or copies all source
This contains the directory where makepkg extracts, or copies, all source
files.
*pkgdir*::
This points to the directory where makepkg bundles the installed package
This contains the directory where makepkg bundles the installed package
(this directory will become the root directory of your built package).
If you create any variables of your own in the build function, it is
@@ -301,9 +312,9 @@ Each split package uses a corresponding packaging function with name
`package_foo()`, where `foo` is the name of the split package.
All options and directives for the split packages default to the global values
given within the PKGBUILD. However, some of these can be overridden within each
split package's packaging function. The following variables can be overridden:
`pkgver`, `pkgrel`, `pkgdesc`, `arch`, `license`, `groups`, `depends`,
given in the PKGBUILD. Nevertheless, the following ones can be overridden within
each split package's packaging function:
`pkgver`, `pkgrel`, `epoch`, `pkgdesc`, `arch`, `license`, `groups`, `depends`,
`optdepends`, `provides`, `conflicts`, `replaces`, `backup`, `options`,
`install` and `changelog`.
@@ -321,31 +332,37 @@ Pacman has the ability to store and execute a package-specific script when it
installs, removes, or upgrades a package. This allows a package to configure
itself after installation and perform an opposite action upon removal.
The exact time the script is run varies with each operation:
The exact time the script is run varies with each operation, and should be
self-explanatory. Note that during an upgrade operation, none of the install
or remove scripts will be called.
Scripts are passed either one or two ``full version strings'', where a full
version string is either 'pkgver-pkgrel' or 'epoch:pkgver-pkgrel' if epoch is
non-zero.
*pre_install*::
script is run right before files are extracted. One argument is passed:
new package version.
Run right before files are extracted. One argument is passed:
new package full version string.
*post_install*::
script is run right after files are extracted. One argument is passed:
new package version.
Run right after files are extracted. One argument is passed:
new package full version string.
*pre_upgrade*::
script is run right before files are extracted. Two arguments are passed
in the following order: new package version, old package version.
Run right before files are extracted. Two arguments are passed in this
order: new package full version string, old package full version string.
*post_upgrade*::
script is run after files are extracted. Two arguments are passed
in the following order: new package version, old package version.
Run after files are extracted. Two arguments are passed in this order:
new package full version string, old package full version string.
*pre_remove*::
script is run right before files are removed. One argument is passed:
old package version.
Run right before files are removed. One argument is passed:
old package full version string.
*post_remove*::
script is run right after files are removed. One argument is passed:
old package version.
Run right after files are removed. One argument is passed:
old package full version string.
To use this feature, create a file such as 'pkgname.install' and put it in the
same directory as the PKGBUILD script. Then use the install directive:
@@ -363,7 +380,7 @@ makepkg supports building development versions of packages without having to
manually update the pkgver in the PKGBUILD. This was formerly done using the
separate utility 'versionpkg'. In order to utilize this functionality, your
PKGBUILD must use correct variable names depending on the SCM being fetched
from.
from (e.g., 'makepkg-git', 'mplayer-svn').
*CVS*::
The generated pkgver will be the date the package is built.

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
See the pacman website at http://www.archlinux.org/pacman/[] for current

View File

@@ -41,7 +41,9 @@ configuration files dealing with pacman.
* linkman:makepkg[8]
* linkman:makepkg.conf[5]
* linkman:pacman[8]
* linkman:pacman-key[8]
* linkman:pacman.conf[5]
* linkman:pkgdelta[8]
* linkman:repo-add[8]
* linkman:vercmp[8]
@@ -107,9 +109,9 @@ link:ftp://ftp.archlinux.org/other/pacman/[]. To install, download the newest
available source tarball, unpack it in a directory, and run the three magic
commands:
$ ./configure
$ make
# make install
$ ./configure
$ make
# make install
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.
@@ -132,7 +134,7 @@ these trees).
The current development tree can be fetched with the following command:
git clone git://projects.archlinux.org/pacman.git pacman
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
@@ -206,5 +208,5 @@ pacman is Copyright (C) 2006-2011 Pacman Development Team
version 2 or later.
/////
vim: set ts=2 sw=2 syntax=asciidoc et:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
libalpm(3)
==========

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
makepkg(8)
==========
@@ -11,24 +11,24 @@ makepkg - package build utility
Synopsis
--------
makepkg [options]
'makepkg' [options]
Description
-----------
makepkg is a script to automate the building of packages. The requirements for
'makepkg' is a script to automate the building of packages. The requirements for
using the script are a build-capable \*nix platform and a custom build script
for each package you wish to build (known as a PKGBUILD). See
linkman:PKGBUILD[5] for details on creating your own build scripts.
The advantage to a script-based build is that the work is only done once. Once
you have the build script for a package, makepkg will do the rest: download and
you have the build script for a package, 'makepkg' will do the rest: download and
validate source files, check dependencies, configure the build-time settings,
build the package, install the package into a temporary root, make
customizations, generate meta-info, and package the whole thing up for pacman
to use.
NOTE: makepkg uses your current locale by default and does not unset it when
NOTE: 'makepkg' uses your current locale by default and does not unset it when
building packages. If you wish to share your build output with others when
seeking help or for other purposes, you may wish to run "`LC_ALL=C makepkg`" so
your logs and output are not localized.
@@ -48,10 +48,6 @@ Options
*-c, \--clean*::
Clean up leftover work files and directories after a successful build.
*-C, \--cleancache*::
Removes all cached source files from the directory specified in `SRCDEST`
in linkman:makepkg.conf[5].
*\--config* <file>::
Use an alternate config file instead of the +{sysconfdir}/makepkg.conf+
default.
@@ -89,7 +85,13 @@ Options
using "`makepkg -g >> PKGBUILD`".
*--skipinteg*::
Do not perform any integrity checks, just print a warning instead.
Do not perform any integrity checks (checksum and PGP) on source files.
*\--skipchecksums*::
Do not verify checksums of source files.
*\--skippgpcheck*::
Do not verify PGP signatures of source files.
*-h, \--help*::
Output syntax and command line options.
@@ -151,8 +153,7 @@ Options
all source files of the package need to be present or downloadable.
*\--pkg <list>*::
Only build listed packages from a split package. The use of quotes is
necessary when specifying multiple packages. e.g. `--pkg "pkg1 pkg3"`
Only build listed packages from a split package.
*\--check*::
Run the check() function in the PKGBUILD, overriding the setting in
@@ -161,6 +162,18 @@ Options
*\--nocheck*::
Do not run the check() function in the PKGBUILD or handle the checkdepends.
*\--sign*::
Sign the resulting package with gpg, overriding the setting in
linkman:makepkg.conf[5].
*\--nosign*::
Do not create a signature for the built package.
*\--key* <key>::
Specify a key to use when signing packages, overriding the GPGKEY setting
in linkman:makepkg.conf[5]. If not specified in either location, the
default key from the keyring will be used.
*\--noconfirm*::
(Passed to pacman) Prevent pacman from waiting for user input before
proceeding with operations.
@@ -194,6 +207,9 @@ Environment Variables
Folder where the downloaded sources will be stored. Overrides the
corresponding value defined in linkman:makepkg.conf[5].
**BUILDDIR=**"/path/to/folder"::
Folder where the package will be built. Overrides the corresponding
value defined in linkman:makepkg.conf[5].
Configuration
-------------

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
makepkg.conf(5)
===============
@@ -70,7 +70,7 @@ Options
This is often used to set the number of jobs used, for example, `-j2`.
Other flags that make accepts can also be passed.
**BUILDENV=(**fakeroot !distcc color !ccache check**)**::
**BUILDENV=(**fakeroot !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 place an ``!'' at the front of the
@@ -98,12 +98,31 @@ Options
enabled or disabled for individual packages through the use of
makepkg's `--check` and `--nocheck` options respectively.
*sign*;;
Generate a PGP signature file using GnuPG. This will execute `gpg
--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 filename of the package with a ``.sig''
extension.
**DISTCC_HOSTS=**"host1 ..."::
If using DistCC, this is used to specify a space-delimited list of hosts
running in the DistCC cluster. In addition, you will want to modify your
`MAKEFLAGS`.
**OPTIONS=(**strip !docs libtool emptydirs zipman**)**::
**BUILDDIR=**"/path/to/folder"::
If this value is not set, packages will by default be built in
subdirectories of the directory that makepkg is called from. This
option allows setting the build location to another folder.
Incorrect use of `$startdir` in a PKGBUILD may cause building with
this option to fail.
**GPGKEY=**""::
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 emptydirs zipman purge !upx**)**::
This array contains options that affect the 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
@@ -135,6 +154,10 @@ 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` variable.
**INTEGRITY_CHECK=(**check1 ...**)**::
File integrity checks to use. Multiple checks may be specified; this
affects both generation and checking. The current valid options are:
@@ -192,7 +215,8 @@ Options
**PKGEXT=**".pkg.tar.gz", **SRCEXT=**".src.tar.gz"::
Sets the compression used when making compiled or source packages. The
current valid suffixes are `.tar`, `.tar.gz`, `.tar,bz2` and `.tar.xz`.
current valid suffixes are `.tar`, `.tar.gz`, `.tar,bz2`, `.tar.xz`, and
`.tar.Z`.
Do not touch these unless you know what you are doing.
See Also

100
doc/pacman-key.8.txt Normal file
View File

@@ -0,0 +1,100 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pacman-key(8)
=============
Name
----
pacman-key - manage pacman's list of trusted keys
Synopsis
--------
'pacman-key' [options]
Description
-----------
'pacman-key' is a wrapper script for GnuPG used to manage pacman's keyring, which
is the collection of PGP keys used to check signed packages and databases. It
provides the ability to import and export keys, fetch keys from keyservers and
update the key trust database.
More complex keyring management can be achieved using GnuPG directly combined with
the `--homedir` option pointing at the pacman keyring (located in
+{sysconfdir}/pacman.d/gnupg+ by default).
Options
-------
*-a, \--add* [file(s)]::
Add the key(s) contained in the specified file or files to pacman's
keyring. If a key already exists, update it.
*\--config* <file>::
Use an alternate config file instead of the +{sysconfdir}/pacman.conf+
default.
*-d, \--delete* <keyid(s)>::
Remove the key(s) identified by the specified keyid(s) from pacman's
keyring.
*-e, \--export* [keyid(s)]::
Export key(s) identified by the specified keyid(s) to 'stdout'. If no keyid
is specified, all keys will be exported.
*\--edit-key * <keyid(s)>::
Present a menu for key management task on the specified keyids. Useful for
adjusting a keys trust level.
*-f, \--finger* [keyid(s)]::
List a fingerprint for each specified keyid, or for all known keys if no
keyids are specified.
*\--gpgdir* <dir>::
Set an alternate home directory for GnuPG. If unspecified, the value is
read from +{sysconfdir}/pacman.conf+.
*-h, \--help*::
Output syntax and command line options.
*--import* <dir(s)>::
Adds keys from pubring.gpg into pacman's keyring and imports ownertrust
values from trustdb.gpg in the specified directories.
*--import-dirs* <dir(s)> ::
Imports ownertrust values from trustdb.gpg in the specified directories.
*--init*::
Ensure the keyring is properly initialized and has the required access
permissions.
*-l, \--list-keys* [keyid(s)]::
Lists all or specified keys from the public keyring.
*--list-sigs* [keyid(s)]::
Same as --list-keys, but the signatures are listed too.
*-r, \--receive* <keyserver> <keyid(s)>::
Fetch the specified keyids from the specified key server URL.
*\--reload*::
Reloads the keys from the keyring package.
*-u, \--updatedb*::
Equivalent to \--check-trustdb in GnuPG.
* -v, \--verify* <signature>::
Verify the given signature file.
*-V, \--version*::
Displays the program version.
See Also
--------
linkman:pacman[8], linkman:pacman.conf[5]
include::footer.txt[]

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pacman(8)
=========
@@ -153,6 +153,14 @@ Options
Display debug messages. When reporting bugs, this option is recommended
to be used.
*\--gpgdir* <dir>::
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, the root path is not automatically prepended.
*\--logfile* <file>::
Specify an alternate log file. This is an absolute path, regardless of
the installation root setting.
@@ -169,7 +177,7 @@ Transaction Options (apply to '-S', '-R' and '-U')
dependencies are installed and there are no package conflicts in the
system. Specify this option twice to skip all dependency checks.
*-k, \--dbonly*::
*\--dbonly*::
Adds/Removes the database entry only, leaves all files in place.
*\--noprogressbar*::
@@ -221,6 +229,17 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
there is one available. Multiple groups can be specified by
separating them with a comma.
*\--needed*::
Do not reinstall the targets that are already up to date.
*\--recursive*::
Recursively reinstall all dependencies of the targets. This forces upgrades
or reinstalls of all dependencies without requiring explicit version
requirements. This is most useful in combination with the '\--needed' flag,
which will induce a deep dependency upgrade without any unnecessary
reinstalls.
Query Options[[QO]]
-------------------
*-c, \--changelog*::
@@ -390,7 +409,14 @@ system upgrade and install/upgrade the foo package in the same operation.
to date.
*\--needed*::
Don't reinstall the targets that are already up to date.
Do not reinstall the targets that are already up to date.
*\--recursive*::
Recursively reinstall all dependencies of the targets. This forces upgrades
or reinstalls of all dependencies without requiring explicit version
requirements. This is most useful in combination with the '\--needed' flag,
which will induce a deep dependency upgrade without any unnecessary
reinstalls.
Handling Config Files[[HCF]]

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pacman.conf(5)
==============
@@ -69,6 +69,15 @@ Options
to the first cache directory with write access. *NOTE*: this is an absolute
path, the root path is not automatically prepended.
*GPGDir =* path/to/gpg/dir::
Overrides the default location of the directory containing configuration
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
authentic and trusted.
*NOTE*: this is an absolute path, the root path is not automatically
prepended.
*LogFile =* '/path/to/file'::
Overrides the default location of the pacman log file. A typical default
@@ -147,13 +156,14 @@ Options
packages are only cleaned if not installed locally and not present in any
known sync database.
*SigLevel =* ...::
Set the default signature verification level. For more information, see
<<SC,Package and Database Signature Checking>> below.
*UseSyslog*::
Log action messages through syslog(). This will insert log entries into
+{localstatedir}/log/messages+ or equivalent.
*ShowSize*::
Display the size of individual packages for '\--sync' and '\--query' modes.
*UseDelta*::
Download delta files instead of complete packages if possible. Requires
the xdelta3 program to be installed.
@@ -168,6 +178,10 @@ Options
Performs an approximate check for adequate available disk space before
installing packages.
*VerbosePkgLists*::
Displays name, version and size of target packages formatted
as a table for upgrade, sync and remove operations.
Repository Sections
-------------------
Each repository section defines a section name and at least one location where
@@ -183,27 +197,99 @@ contain a file that lists the servers for that repository.
--------
[core]
# use this repository first
Server = ftp://ftp.archlinux.org/core/os/arch
# use this server first
Server = ftp://ftp.archlinux.org/$repo/os/$arch
# next use servers as defined in the mirrorlist below
Include = {sysconfdir}/pacman.d/mirrorlist
--------
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 value of `Architecture`, so the same mirrorfile can
even be used for different architectures.
--------
Server = ftp://ftp.archlinux.org/$repo/os/$arch
--------
The order of repositories in the configuration files matters; repositories
listed first will take precedence over those listed later in the file when
packages in two repositories have identical names, regardless of version
number.
*Include =* path::
Include another config file. This file can include repositories or
general configuration options. Wildcards in the specified paths will get
expanded based on linkman:glob[7] rules.
*Server =* url::
A full URL to a location where the database, packages, and signatures (if
available) for this repository can be found.
+
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 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
information, see <<SC,Package and Database Signature Checking>> below.
Package and Database Signature Checking
---------------------------------------
The 'SigLevel' directive is valid in both the `[options]` and repository
sections. If used in `[options]`, it sets a default value for any repository
that does not provide the setting.
* If set to *Never*, no signature checking will take place.
* If set to *Optional* , signatures will be checked when present, but unsigned
databases and packages will also be accepted.
* If set to *Required*, signatures will be required on all packages and
databases.
Alternatively, you can get more fine-grained control by combining some of
the options and prefixes described below. All options in a config file are
processed in top-to-bottom, left-to-right fashion, where later options override
and/or supplement earlier ones. If 'SigLevel' is specified in a repository
section, the starting value is that from the `[options]` section, or the
built-in system default as shown below if not specified.
The options are split into two main groups, described below. Terms used such as
``marginally trusted'' are terms used by GnuPG, for more information please
consult linkman:gpg[1].
When to Check::
These options control if and when signature checks should take place.
*Never*;;
All signature checking is suppressed, even if signatures are present.
*Optional* (default);;
Signatures are checked if present; absence of a signature is not an
error. An invalid signature is a fatal error, as is a signature from a
key not in the keyring.
*Required*;;
Signatures are required; absence of a signature or an invalid signature
is a fatal error, as is a signature from a key not in the keyring.
What is Allowed::
These options control what signatures are viewed as permissible. Note that
neither of these options allows acceptance of invalid or expired
signatures, or those from revoked keys.
*TrustedOnly* (default);;
If a signature is checked, it must be in the keyring and fully trusted;
marginal trust does not meet this criteria.
*TrustAll*;;
If a signature is checked, it must be in the keyring, but is not
required to be assigned a trust level (e.g., unknown or marginal
trust).
Options in both groups can additionally be prefixed with either *Package* or
*Database*, which will cause it to only take effect on the specified object
type. For example, `PackageTrustAll` would allow marginal and unknown trust
level signatures for packages.
The built-in default is the following:
--------
SigLevel = Optional TrustedOnly
--------
Using Your Own Repository
-------------------------
If you have numerous custom packages of your own, it is often easier to generate
@@ -215,11 +301,12 @@ directory with these packages so pacman can find it when run with '\--refresh'.
The above command will generate a compressed database named
'/home/pkgs/custom.db.tar.gz'. Note that the database must be of the form
'\{treename\}.db.tar.gz', where '\{treename\}' is the name of the section defined in
the configuration file. That's it! Now configure your custom section in the
configuration file as shown in the config example above. Pacman will now use your
package repository. If you add new packages to the repository, remember to
re-generate the database and use pacman's '\--refresh' option.
'\{treename\}.db.tar.{ext}', where '\{treename\}' is the name of the section
defined in the configuration file and '\{ext\}' is a valid compression type as
documented in linkman:repo-add[8]. That's it! Now configure your custom section
in the configuration file as shown in the config example above. Pacman will now
use your package repository. If you add new packages to the repository,
remember to re-generate the database and use pacman's '\--refresh' option.
For more information on the repo-add command, see ``repo-add \--help'' or
linkman:repo-add[8].

42
doc/pkgdelta.8.txt Normal file
View File

@@ -0,0 +1,42 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
pkgdelta(8)
=========
Name
----
pkgdelta - package delta generation utility
Synopsis
--------
'pkgdelta' [-q] <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
-------
*-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,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
repo-add(8)
==========
@@ -10,26 +10,55 @@ repo-add - package database maintenance utility
Synopsis
--------
repo-add [-d] [-f] [-q] <path-to-db> <package1> [<package2> ...]
'repo-add' [options] <path-to-db> <package|delta> [<package|delta> ...]
repo-remove [-q] <path-to-db> <packagename> [<packagename2> ...]
'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
'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.
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'' or ``.files'' 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.
Options
-------
Common Options
--------------
*-q, \--quiet*::
Force this program to keep quiet and run silent except for warning and
error messages.
*-s, \--sign*::
Generate a PGP signature file using GnuPG. This will execute `gpg
--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 environmental variable. If not specified in either location, the
default key from the keyring will be used.
*-v, \--verify*::
Verify the PGP signature of the database before updating the database.
If the signature is invalid, an error is produced and the update does not
proceed.
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.
@@ -39,12 +68,8 @@ Options
specified packages. This is useful for creating databases listing all files
in a given sync repository for tools that may use this information.
*-q, \--quiet*::
Force this program to keep quiet and run silent except for warning and
error messages.
See Also
--------
linkman:makepkg[8], linkman:pacman[8]
linkman:makepkg[8], linkman:pacman[8], linkman:pkgdelta[8]
include::footer.txt[]

View File

@@ -20,7 +20,7 @@ started with GIT if you have not worked with it before.
The pacman code can be fetched using the following command:
git clone git://projects.archlinux.org/pacman.git
git clone git://projects.archlinux.org/pacman.git
Creating your patch
@@ -32,7 +32,7 @@ Creating your patch
The -s allows you to credit yourself by adding a "Signed Off By" line to
indicate who has "signed" the patch - who has approved it.
Signed-off-by: Aaron Griffin <aaron@archlinux.org>
Signed-off-by: Aaron Griffin <aaron@archlinux.org>
Please use your real name and email address. Feel free to "scramble" the
address if you're afraid of spam.
@@ -94,5 +94,5 @@ aren't their own.
--
/////
vim: set ts=2 sw=2 syntax=asciidoc et:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

View File

@@ -40,15 +40,15 @@ not worried about any local translations being overwritten. The .tx/ directory
is checked into the git repository so is preconfigured with the two project
resources (See `tx status` output for a quick overview).
tx pull -f
poedit po/<mylang>.po
poedit lib/libalpm/po/<mylang>.po
tx push -t -l <mylang>
tx pull -f
poedit po/<mylang>.po
poedit lib/libalpm/po/<mylang>.po
tx push -t -l <mylang>
Or to just push one of the two available resources:
tx push -r archlinux-pacman.pacman-pot -t -l fi
tx push -r archlinux-pacman.libalpm-pot -t -l fi
tx push -r archlinux-pacman.pacman-pot -t -l fi
tx push -r archlinux-pacman.libalpm-pot -t -l fi
See the <<Notes,Notes>> section for additional hints on translating.
@@ -79,7 +79,7 @@ Incremental Updates
If you have more advanced needs you will have to get a copy of the pacman
repository.
git clone git://projects.archlinux.org/pacman.git pacman
git clone git://projects.archlinux.org/pacman.git pacman
Next, you will need to run `./autogen.sh` and `./configure` in the base
directory to generate the correct Makefiles. At this point, all necessary
@@ -91,11 +91,11 @@ We need to first update the main message catalog file. Navigate into either the
work on first, and execute the following command. If you are working in the
`po/` tree, replace 'libalpm.pot' with 'pacman.pot':
make libalpm.pot-update
make libalpm.pot-update
Next, update your specific language's translation file:
make <po file>-update
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
@@ -104,7 +104,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:
make update-po
make update-po
Adding a New Language
~~~~~~~~~~~~~~~~~~~~~
@@ -133,16 +133,16 @@ msgid and msgstr 'variables' can be on as many lines as necessary. Line breaks
are ignored- if you need a literal line break, use an `\n` in your string. The
following two translations are equivalent:
msgstr "This is a test translation"
msgstr "This is a test translation"
msgstr ""
"This is a test translation"
msgstr ""
"This is a test translation"
If you want to test the translation (for example, the frontend one):
rm *.gmo stamp-po
make
cp <lang code>.gmo /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
@@ -160,5 +160,5 @@ check there first before undergoing a translation effort to ensure you are not
duplicating efforts.
/////
vim: set ts=2 sw=2 syntax=asciidoc et:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////

View File

@@ -1,5 +1,5 @@
/////
vim:set ts=4 sw=4 syntax=asciidoc noet:
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
/////
vercmp(8)
=========

View File

@@ -19,7 +19,6 @@ edit = sed \
-e 's|@CARCH[@]|$(CARCH)|g' \
-e 's|@CHOST[@]|$(CHOST)|g' \
-e 's|@ARCHSWITCH[@]|$(ARCHSWITCH)|g' \
-e 's|@CARCHFLAGS[@]|$(CARCHFLAGS)|g' \
-e 's|@ROOTDIR[@]|$(ROOTDIR)|g'
$(dist_sysconf_DATA): Makefile

View File

@@ -8,16 +8,16 @@
#
#-- The download utilities that makepkg should use to acquire sources
# Format: 'protocol::agent'
DLAGENTS=('ftp::/usr/bin/wget -c --passive-ftp -t 3 --waitretry=3 -O %o %u'
'http::/usr/bin/wget -c -t 3 --waitretry=3 -O %o %u'
'https::/usr/bin/wget -c -t 3 --waitretry=3 --no-check-certificate -O %o %u'
DLAGENTS=('ftp::/usr/bin/curl -fC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
'http::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
'https::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
'rsync::/usr/bin/rsync -z %u %o'
'scp::/usr/bin/scp -C %u %o')
# Other common tools:
# /usr/bin/snarf
# /usr/bin/lftpget -c
# /usr/bin/curl
# /usr/bin/wget
#########################################################################
# ARCHITECTURE, COMPILE FLAGS
@@ -26,11 +26,9 @@ DLAGENTS=('ftp::/usr/bin/wget -c --passive-ftp -t 3 --waitretry=3 -O %o %u'
CARCH="@CARCH@"
CHOST="@CHOST@"
#-- Exclusive: will only run on @CARCH@
# -march (or -mcpu) builds exclusively for an architecture
# -mtune optimizes for an architecture, but builds for whole processor family
CFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe"
CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe"
#-- Compiler and Linker Flags
#CFLAGS="-O2 -pipe"
#CXXFLAGS="-O2 -pipe"
#LDFLAGS=""
#-- Make Flags: change this for DistCC/SMP systems
#MAKEFLAGS="-j2"
@@ -39,7 +37,7 @@ CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe"
# BUILD ENVIRONMENT
#########################################################################
#
# Defaults: BUILDENV=(fakeroot !distcc color !ccache check)
# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign)
# A negated environment option will do the opposite of the comments below.
#
#-- fakeroot: Allow building packages as a non-root user
@@ -47,19 +45,23 @@ CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe"
#-- color: Colorize output messages
#-- ccache: Use ccache to cache compilation
#-- check: Run the check() function if present in the PKGBUILD
#-- sign: Generate PGP signature file
#
BUILDENV=(fakeroot !distcc color !ccache check)
BUILDENV=(fakeroot !distcc color !ccache check !sign)
#
#-- If using DistCC, your MAKEFLAGS will also need modification. In addition,
#-- specify a space-delimited list of hosts running in the DistCC cluster.
#DISTCC_HOSTS=""
#
#-- Specify a directory for package building.
#BUILDDIR=/tmp/makepkg
#########################################################################
# GLOBAL PACKAGE OPTIONS
# These are default values for the options=() settings
#########################################################################
#
# Default: OPTIONS=(strip docs libtool emptydirs zipman purge)
# Default: OPTIONS=(strip docs libtool emptydirs zipman purge !upx)
# A negated option will do the opposite of the comments below.
#
#-- strip: Strip symbols from binaries/libraries
@@ -68,8 +70,9 @@ BUILDENV=(fakeroot !distcc color !ccache check)
#-- 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
#
OPTIONS=(strip docs libtool emptydirs zipman purge)
OPTIONS=(strip docs libtool emptydirs zipman purge !upx)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5)
@@ -100,6 +103,8 @@ PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#SRCPKGDEST=/home/srcpackages
#-- Packager: name/email of the person or organization building packages
#PACKAGER="John Doe <john@doe.com>"
#-- Specify a key to use for package signing
#GPGKEY=""
#########################################################################
# EXTENSION DEFAULTS

View File

@@ -13,6 +13,7 @@
#DBPath = @localstatedir@/lib/pacman/
#CacheDir = @localstatedir@/cache/pacman/pkg/
#LogFile = @localstatedir@/log/pacman.log
#GPGDir = @sysconfdir@/pacman.d/gnupg/
HoldPkg = pacman glibc
# If upgrades are available for these packages they will be asked for first
SyncFirst = pacman
@@ -30,10 +31,10 @@ Architecture = auto
# Misc options (all disabled by default)
#UseSyslog
#ShowSize
#UseDelta
#TotalDownload
#CheckSpace
#VerbosePkgLists
#
# REPOSITORIES

View File

@@ -35,13 +35,15 @@ libalpm_la_SOURCES = \
diskspace.h diskspace.c \
dload.h dload.c \
error.c \
graph.h \
graph.h graph.c \
group.h group.c \
handle.h handle.c \
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 \
@@ -52,7 +54,12 @@ libalpm_la_SOURCES += \
md5.h md5.c
endif
libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO)
if HAVE_LIBGPGME
libalpm_la_SOURCES += \
base64.h base64.c
endif
libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) @LIBCURL@
libalpm_la_LIBADD = $(LTLIBINTL)
# vim:set ts=2 sw=2 noet:

View File

@@ -37,82 +37,76 @@
/* libalpm */
#include "add.h"
#include "alpm.h"
#include "alpm_list.h"
#include "handle.h"
#include "trans.h"
#include "util.h"
#include "log.h"
#include "backup.h"
#include "package.h"
#include "db.h"
#include "conflict.h"
#include "deps.h"
#include "remove.h"
#include "handle.h"
/** Add a package to the transaction.
* @param pkg the package to add
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg)
/** Add a package to the transaction. */
int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
{
const char *pkgname, *pkgver;
pmtrans_t *trans;
pmdb_t *db_local;
pmpkg_t *local;
ALPM_LOG_FUNC;
alpm_trans_t *trans;
alpm_pkg_t *local;
/* Sanity checks */
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
ASSERT(handle == pkg->handle, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
trans = handle->trans;
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
db_local = handle->db_local;
ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
ASSERT(trans->state == STATE_INITIALIZED,
RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1));
pkgname = alpm_pkg_get_name(pkg);
pkgver = alpm_pkg_get_version(pkg);
pkgname = pkg->name;
pkgver = pkg->version;
_alpm_log(PM_LOG_DEBUG, "adding package '%s'\n", pkgname);
_alpm_log(handle, ALPM_LOG_DEBUG, "adding package '%s'\n", pkgname);
if(_alpm_pkg_find(trans->add, pkgname)) {
RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
RET_ERR(handle, ALPM_ERR_TRANS_DUP_TARGET, -1);
}
local = _alpm_db_get_pkgfromcache(db_local, pkgname);
local = _alpm_db_get_pkgfromcache(handle->db_local, pkgname);
if(local) {
const char *localpkgname = alpm_pkg_get_name(local);
const char *localpkgver = alpm_pkg_get_version(local);
int cmp = _alpm_pkg_compare_versions(pkg, local);
if(cmp == 0) {
if(trans->flags & PM_TRANS_FLAG_NEEDED) {
if(trans->flags & ALPM_TRANS_FLAG_NEEDED) {
/* with the NEEDED flag, packages up to date are not reinstalled */
_alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"),
_alpm_log(handle, ALPM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"),
localpkgname, localpkgver);
return(0);
} else if(!(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
_alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"),
return 0;
} else if(!(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY)) {
_alpm_log(handle, ALPM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"),
localpkgname, localpkgver);
}
} else if(cmp < 0) {
/* local version is newer */
_alpm_log(PM_LOG_WARNING, _("downgrading package %s (%s => %s)\n"),
_alpm_log(handle, ALPM_LOG_WARNING, _("downgrading package %s (%s => %s)\n"),
localpkgname, localpkgver, pkgver);
}
}
/* add the package to the transaction */
pkg->reason = PM_PKG_REASON_EXPLICIT;
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
pkg->reason = ALPM_PKG_REASON_EXPLICIT;
_alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s-%s to the transaction add list\n",
pkgname, pkgver);
trans->add = alpm_list_add(trans->add, pkg);
return(0);
return 0;
}
static int perform_extraction(struct archive *archive,
static int perform_extraction(alpm_handle_t *handle, struct archive *archive,
struct archive_entry *entry, const char *filename, const char *origname)
{
int ret;
@@ -125,27 +119,26 @@ static int perform_extraction(struct archive *archive,
ret = archive_read_extract(archive, entry, archive_flags);
if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) {
/* operation succeeded but a "non-critical" error was encountered */
_alpm_log(PM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
_alpm_log(handle, ALPM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
origname, archive_error_string(archive));
} else if(ret != ARCHIVE_OK) {
_alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not extract %s (%s)\n"),
origname, archive_error_string(archive));
alpm_logaction("error: could not extract %s (%s)\n",
alpm_logaction(handle, "error: could not extract %s (%s)\n",
origname, archive_error_string(archive));
return(1);
return 1;
}
return(0);
return 0;
}
static int extract_single_file(struct archive *archive,
struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg,
pmtrans_t *trans, pmdb_t *db)
static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
struct archive_entry *entry, alpm_pkg_t *newpkg, alpm_pkg_t *oldpkg)
{
const char *entryname;
mode_t entrymode;
char filename[PATH_MAX]; /* the actual file we're extracting */
int needbackup = 0, notouch = 0;
char *hash_orig = NULL;
const char *hash_orig = NULL;
char *entryname_orig = NULL;
int errors = 0;
@@ -157,19 +150,19 @@ static int extract_single_file(struct archive *archive,
if(strcmp(entryname, ".INSTALL") == 0) {
/* the install script goes inside the db */
snprintf(filename, PATH_MAX, "%s%s-%s/install",
_alpm_db_path(db), newpkg->name, newpkg->version);
_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);
archive_entry_set_perm(entry, 0644);
} else if(strcmp(entryname, ".CHANGELOG") == 0) {
/* the changelog goes inside the db */
snprintf(filename, PATH_MAX, "%s%s-%s/changelog",
_alpm_db_path(db), newpkg->name, newpkg->version);
_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);
archive_entry_set_perm(entry, 0644);
} else if(*entryname == '.') {
/* for now, ignore all files starting with '.' that haven't
* already been handled (for future possibilities) */
_alpm_log(PM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname);
_alpm_log(handle, ALPM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname);
archive_read_data_skip(archive);
return(0);
return 0;
} else {
/* build the new entryname relative to handle->root */
snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
@@ -177,12 +170,12 @@ static int extract_single_file(struct archive *archive,
/* if a file is in NoExtract then we never extract it */
if(alpm_list_find_str(handle->noextract, entryname)) {
_alpm_log(PM_LOG_DEBUG, "%s is in NoExtract, skipping extraction\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract, skipping extraction\n",
entryname);
alpm_logaction("note: %s is in NoExtract, skipping extraction\n",
alpm_logaction(handle, "note: %s is in NoExtract, skipping extraction\n",
entryname);
archive_read_data_skip(archive);
return(0);
return 0;
}
/* Check for file existence. This is one of the more crucial parts
@@ -216,42 +209,42 @@ static int extract_single_file(struct archive *archive,
if(lsbuf.st_mode != entrymode) {
/* if filesystem perms are different than pkg perms, warn user */
mode_t mask = 07777;
_alpm_log(PM_LOG_WARNING, _("directory permissions differ on %s\n"
_alpm_log(handle, ALPM_LOG_WARNING, _("directory permissions differ on %s\n"
"filesystem: %o package: %o\n"), entryname, lsbuf.st_mode & mask,
entrymode & mask);
alpm_logaction("warning: directory permissions differ on %s\n"
alpm_logaction(handle, "warning: directory permissions differ on %s\n"
"filesystem: %o package: %o\n", entryname, lsbuf.st_mode & mask,
entrymode & mask);
}
_alpm_log(PM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
entryname);
archive_read_data_skip(archive);
return(0);
return 0;
} else {
/* case 10/11: trying to overwrite dir with file/symlink, don't allow it */
_alpm_log(PM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
entryname);
archive_read_data_skip(archive);
return(1);
return 1;
}
} else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(entrymode)) {
/* case 9: existing symlink, dir in package */
if(S_ISDIR(sbuf.st_mode)) {
/* the symlink on FS is to a directory, so we'll use it */
_alpm_log(PM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n",
entryname);
archive_read_data_skip(archive);
return(0);
return 0;
} else {
/* this is BAD. symlink was not to a directory */
_alpm_log(PM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"),
entryname);
archive_read_data_skip(archive);
return(1);
return 1;
}
} else if(S_ISREG(lsbuf.st_mode) && S_ISDIR(entrymode)) {
/* case 6: trying to overwrite file with dir */
_alpm_log(PM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
entryname);
} else if(S_ISREG(entrymode)) {
/* case 4,7: */
@@ -259,24 +252,24 @@ static int extract_single_file(struct archive *archive,
if(alpm_list_find_str(handle->noupgrade, entryname)) {
notouch = 1;
} else {
alpm_backup_t *backup;
/* go to the backup array and see if our conflict is there */
/* check newpkg first, so that adding backup files is retroactive */
if(alpm_list_find_str(alpm_pkg_get_backup(newpkg), entryname) != NULL) {
backup = _alpm_needbackup(entryname, newpkg);
if(backup) {
/* if we force hash_orig to be non-NULL retroactive backup works */
hash_orig = "";
needbackup = 1;
}
/* check oldpkg for a backup entry, store the hash if available */
if(oldpkg) {
hash_orig = _alpm_needbackup(entryname, alpm_pkg_get_backup(oldpkg));
if(hash_orig) {
backup = _alpm_needbackup(entryname, oldpkg);
if(backup) {
hash_orig = backup->hash;
needbackup = 1;
}
}
/* if we force hash_orig to be non-NULL retroactive backup works */
if(needbackup && !hash_orig) {
STRDUP(hash_orig, "", RET_ERR(PM_ERR_MEMORY, -1));
}
}
}
/* else if(S_ISLNK(entrymode)) */
@@ -285,7 +278,7 @@ static int extract_single_file(struct archive *archive,
/* we need access to the original entryname later after calls to
* archive_entry_set_pathname(), so we need to dupe it and free() later */
STRDUP(entryname_orig, entryname, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(entryname_orig, entryname, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
if(needbackup) {
char checkfile[PATH_MAX];
@@ -294,44 +287,36 @@ static int extract_single_file(struct archive *archive,
snprintf(checkfile, PATH_MAX, "%s.paccheck", filename);
ret = perform_extraction(archive, entry, checkfile, entryname_orig);
ret = perform_extraction(handle, archive, entry, checkfile, entryname_orig);
if(ret == 1) {
/* error */
FREE(hash_orig);
FREE(entryname_orig);
return(1);
return 1;
}
hash_local = alpm_compute_md5sum(filename);
hash_pkg = alpm_compute_md5sum(checkfile);
/* append the new md5 hash to it's respective entry
* in newpkg's backup (it will be the new orginal) */
alpm_list_t *backups;
for(backups = alpm_pkg_get_backup(newpkg); backups;
backups = alpm_list_next(backups)) {
char *oldbackup = alpm_list_getdata(backups);
if(!oldbackup || strcmp(oldbackup, entryname_orig) != 0) {
/* update the md5 hash in newpkg's backup (it will be the new orginal) */
alpm_list_t *i;
for(i = alpm_pkg_get_backup(newpkg); i; i = i->next) {
alpm_backup_t *backup = i->data;
char *newhash;
if(!backup->name || strcmp(backup->name, entryname_orig) != 0) {
continue;
}
char *backup = NULL;
/* length is tab char, null byte and MD5 (32 char) */
size_t backup_len = strlen(oldbackup) + 34;
MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(backup, "%s\t%s", oldbackup, hash_pkg);
backup[backup_len-1] = '\0';
FREE(oldbackup);
backups->data = backup;
STRDUP(newhash, hash_pkg, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
FREE(backup->hash);
backup->hash = newhash;
}
_alpm_log(PM_LOG_DEBUG, "checking hashes for %s\n", entryname_orig);
_alpm_log(PM_LOG_DEBUG, "current: %s\n", hash_local);
_alpm_log(PM_LOG_DEBUG, "new: %s\n", hash_pkg);
_alpm_log(PM_LOG_DEBUG, "original: %s\n", hash_orig);
_alpm_log(handle, ALPM_LOG_DEBUG, "checking hashes for %s\n", entryname_orig);
_alpm_log(handle, ALPM_LOG_DEBUG, "current: %s\n", hash_local);
_alpm_log(handle, ALPM_LOG_DEBUG, "new: %s\n", hash_pkg);
_alpm_log(handle, ALPM_LOG_DEBUG, "original: %s\n", hash_orig);
if(!oldpkg) {
if(strcmp(hash_local, hash_pkg) != 0) {
if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) != 0) {
/* looks like we have a local file that has a different hash as the
* file in the package, move it to a .pacorig */
char newpath[PATH_MAX];
@@ -339,22 +324,22 @@ static int extract_single_file(struct archive *archive,
/* move the existing file to the "pacorig" */
if(rename(filename, newpath)) {
_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
filename, newpath, strerror(errno));
alpm_logaction("error: could not rename %s to %s (%s)\n",
alpm_logaction(handle, "error: could not rename %s to %s (%s)\n",
filename, newpath, strerror(errno));
errors++;
} else {
/* rename the file we extracted to the real name */
if(rename(checkfile, filename)) {
_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
checkfile, filename, strerror(errno));
alpm_logaction("error: could not rename %s to %s (%s)\n",
alpm_logaction(handle, "error: could not rename %s to %s (%s)\n",
checkfile, filename, strerror(errno));
errors++;
} else {
_alpm_log(PM_LOG_WARNING, _("%s saved as %s\n"), filename, newpath);
alpm_logaction("warning: %s saved as %s\n", filename, newpath);
_alpm_log(handle, ALPM_LOG_WARNING, _("%s saved as %s\n"), filename, newpath);
alpm_logaction(handle, "warning: %s saved as %s\n", filename, newpath);
}
}
} else {
@@ -364,51 +349,51 @@ static int extract_single_file(struct archive *archive,
} else if(hash_orig) {
/* the fun part */
if(strcmp(hash_orig, hash_local) == 0) {
if(hash_local && strcmp(hash_orig, hash_local) == 0) {
/* installed file has NOT been changed by user */
if(strcmp(hash_orig, hash_pkg) != 0) {
_alpm_log(PM_LOG_DEBUG, "action: installing new file: %s\n",
if(hash_pkg && strcmp(hash_orig, hash_pkg) != 0) {
_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
entryname_orig);
if(rename(checkfile, filename)) {
_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
checkfile, filename, strerror(errno));
alpm_logaction("error: could not rename %s to %s (%s)\n",
alpm_logaction(handle, "error: could not rename %s to %s (%s)\n",
checkfile, filename, strerror(errno));
errors++;
}
} else {
/* there's no sense in installing the same file twice, install
* ONLY is the original and package hashes differ */
_alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n");
/* no sense in installing the same file twice, install
* ONLY if the original and package hashes differ */
_alpm_log(handle, ALPM_LOG_DEBUG, "action: leaving existing file in place\n");
unlink(checkfile);
}
} else if(strcmp(hash_orig, hash_pkg) == 0) {
} else if(hash_pkg && strcmp(hash_orig, hash_pkg) == 0) {
/* originally installed file and new file are the same - this
* implies the case above failed - i.e. the file was changed by a
* user */
_alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "action: leaving existing file in place\n");
unlink(checkfile);
} else if(strcmp(hash_local, hash_pkg) == 0) {
} else if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) == 0) {
/* this would be magical. The above two cases failed, but the
* user changes just so happened to make the new file exactly the
* same as the one in the package... skip it */
_alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "action: leaving existing file in place\n");
unlink(checkfile);
} else {
char newpath[PATH_MAX];
_alpm_log(PM_LOG_DEBUG, "action: keeping current file and installing"
_alpm_log(handle, ALPM_LOG_DEBUG, "action: keeping current file and installing"
" new one with .pacnew ending\n");
snprintf(newpath, PATH_MAX, "%s.pacnew", filename);
if(rename(checkfile, newpath)) {
_alpm_log(PM_LOG_ERROR, _("could not install %s as %s (%s)\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not install %s as %s (%s)\n"),
filename, newpath, strerror(errno));
alpm_logaction("error: could not install %s as %s (%s)\n",
alpm_logaction(handle, "error: could not install %s as %s (%s)\n",
filename, newpath, strerror(errno));
} else {
_alpm_log(PM_LOG_WARNING, _("%s installed as %s\n"),
_alpm_log(handle, ALPM_LOG_WARNING, _("%s installed as %s\n"),
filename, newpath);
alpm_logaction("warning: %s installed as %s\n",
alpm_logaction(handle, "warning: %s installed as %s\n",
filename, newpath);
}
}
@@ -416,126 +401,113 @@ static int extract_single_file(struct archive *archive,
FREE(hash_local);
FREE(hash_pkg);
FREE(hash_orig);
} else {
int ret;
/* we didn't need a backup */
if(notouch) {
/* change the path to a .pacnew extension */
_alpm_log(PM_LOG_DEBUG, "%s is in NoUpgrade -- skipping\n", filename);
_alpm_log(PM_LOG_WARNING, _("extracting %s as %s.pacnew\n"), filename, filename);
alpm_logaction("warning: extracting %s as %s.pacnew\n", filename, filename);
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoUpgrade -- skipping\n", filename);
_alpm_log(handle, ALPM_LOG_WARNING, _("extracting %s as %s.pacnew\n"), filename, filename);
alpm_logaction(handle, "warning: extracting %s as %s.pacnew\n", filename, filename);
strncat(filename, ".pacnew", PATH_MAX - strlen(filename));
} else {
_alpm_log(PM_LOG_DEBUG, "extracting %s\n", filename);
_alpm_log(handle, ALPM_LOG_DEBUG, "extracting %s\n", filename);
}
if(trans->flags & PM_TRANS_FLAG_FORCE) {
if(handle->trans->flags & ALPM_TRANS_FLAG_FORCE) {
/* if FORCE was used, unlink() each file (whether it's there
* or not) before extracting. This prevents the old "Text file busy"
* error that crops up if forcing a glibc or pacman upgrade. */
unlink(filename);
}
ret = perform_extraction(archive, entry, filename, entryname_orig);
ret = perform_extraction(handle, archive, entry, filename, entryname_orig);
if(ret == 1) {
/* error */
FREE(entryname_orig);
return(1);
return 1;
}
/* calculate an hash if this is in newpkg's backup */
alpm_list_t *b;
for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
char *backup = NULL, *hash = NULL;
char *oldbackup = alpm_list_getdata(b);
/* length is tab char, null byte and MD5 (32 char) */
size_t backup_len = strlen(oldbackup) + 34;
if(!oldbackup || strcmp(oldbackup, entryname_orig) != 0) {
alpm_list_t *i;
for(i = alpm_pkg_get_backup(newpkg); i; i = i->next) {
alpm_backup_t *backup = i->data;
char *newhash;
if(!backup->name || strcmp(backup->name, entryname_orig) != 0) {
continue;
}
_alpm_log(PM_LOG_DEBUG, "appending backup entry for %s\n", filename);
hash = alpm_compute_md5sum(filename);
MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(backup, "%s\t%s", oldbackup, hash);
backup[backup_len-1] = '\0';
FREE(hash);
FREE(oldbackup);
b->data = backup;
_alpm_log(handle, ALPM_LOG_DEBUG, "appending backup entry for %s\n", entryname_orig);
newhash = alpm_compute_md5sum(filename);
FREE(backup->hash);
backup->hash = newhash;
}
}
FREE(entryname_orig);
return(errors);
return errors;
}
static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,
size_t pkg_count, pmtrans_t *trans, pmdb_t *db)
static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
size_t pkg_current, size_t pkg_count)
{
int i, ret = 0, errors = 0;
char scriptlet[PATH_MAX+1];
char scriptlet[PATH_MAX];
int is_upgrade = 0;
pmpkg_t *oldpkg = NULL;
alpm_pkg_t *oldpkg = NULL;
alpm_db_t *db = handle->db_local;
alpm_trans_t *trans = handle->trans;
ALPM_LOG_FUNC;
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(trans != NULL, return -1);
snprintf(scriptlet, PATH_MAX, "%s%s-%s/install",
_alpm_db_path(db), alpm_pkg_get_name(newpkg),
alpm_pkg_get_version(newpkg));
/* see if this is an upgrade. if so, remove the old package first */
pmpkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name);
alpm_pkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name);
if(local) {
is_upgrade = 1;
/* we'll need to save some record for backup checks later */
oldpkg = _alpm_pkg_dup(local);
/* make sure all infos are loaded because the database entry
* will be removed soon */
_alpm_local_db_read(oldpkg->origin_data.db, oldpkg, INFRQ_ALL);
EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg);
_alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
EVENT(trans, ALPM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg);
_alpm_log(handle, ALPM_LOG_DEBUG, "upgrading package %s-%s\n",
newpkg->name, newpkg->version);
/* copy over the install reason */
newpkg->reason = alpm_pkg_get_reason(oldpkg);
/* pre_upgrade scriptlet */
if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
_alpm_runscriptlet(handle->root, newpkg->origin_data.file,
"pre_upgrade", newpkg->version, oldpkg->version, trans);
if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
_alpm_runscriptlet(handle, newpkg->origin_data.file,
"pre_upgrade", newpkg->version, oldpkg->version);
}
} else {
is_upgrade = 0;
EVENT(trans, PM_TRANS_EVT_ADD_START, newpkg, NULL);
_alpm_log(PM_LOG_DEBUG, "adding package %s-%s\n",
EVENT(trans, ALPM_TRANS_EVT_ADD_START, newpkg, NULL);
_alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s-%s\n",
newpkg->name, newpkg->version);
/* pre_install scriptlet */
if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
_alpm_runscriptlet(handle->root, newpkg->origin_data.file,
"pre_install", newpkg->version, NULL, trans);
if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
_alpm_runscriptlet(handle, newpkg->origin_data.file,
"pre_install", newpkg->version, NULL);
}
}
/* we override any pre-set reason if we have alldeps or allexplicit set */
if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
newpkg->reason = PM_PKG_REASON_DEPEND;
} else if(trans->flags & PM_TRANS_FLAG_ALLEXPLICIT) {
newpkg->reason = PM_PKG_REASON_EXPLICIT;
if(trans->flags & ALPM_TRANS_FLAG_ALLDEPS) {
newpkg->reason = ALPM_PKG_REASON_DEPEND;
} else if(trans->flags & ALPM_TRANS_FLAG_ALLEXPLICIT) {
newpkg->reason = ALPM_PKG_REASON_EXPLICIT;
}
if(oldpkg) {
/* set up fake remove transaction */
if(_alpm_upgraderemove_package(oldpkg, newpkg, trans) == -1) {
pm_errno = PM_ERR_TRANS_ABORT;
if(_alpm_remove_single_package(handle, oldpkg, newpkg, 0, 0) == -1) {
handle->pm_errno = ALPM_ERR_TRANS_ABORT;
ret = -1;
goto cleanup;
}
@@ -544,23 +516,23 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,
/* prepare directory for database entries so permission are correct after
changelog/install script installation (FS#12263) */
if(_alpm_local_db_prepare(db, newpkg)) {
alpm_logaction("error: could not create database entry %s-%s\n",
alpm_logaction(handle, "error: could not create database entry %s-%s\n",
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
pm_errno = PM_ERR_DB_WRITE;
handle->pm_errno = ALPM_ERR_DB_WRITE;
ret = -1;
goto cleanup;
}
if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
struct archive *archive;
struct archive_entry *entry;
char cwd[PATH_MAX] = "";
int restore_cwd = 0;
_alpm_log(PM_LOG_DEBUG, "extracting files\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "extracting files\n");
if ((archive = archive_read_new()) == NULL) {
pm_errno = PM_ERR_LIBARCHIVE;
if((archive = archive_read_new()) == NULL) {
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
ret = -1;
goto cleanup;
}
@@ -568,34 +540,35 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,
archive_read_support_compression_all(archive);
archive_read_support_format_all(archive);
_alpm_log(PM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file);
_alpm_log(handle, ALPM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file);
if(archive_read_open_filename(archive, newpkg->origin_data.file,
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
pm_errno = PM_ERR_PKG_OPEN;
handle->pm_errno = ALPM_ERR_PKG_OPEN;
ret = -1;
goto cleanup;
}
/* save the cwd so we can restore it later */
if(getcwd(cwd, PATH_MAX) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not get current working directory\n"));
_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
} else {
restore_cwd = 1;
}
/* libarchive requires this for extracting hard links */
if(chdir(handle->root) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), handle->root, strerror(errno));
_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
handle->root, strerror(errno));
ret = -1;
goto cleanup;
}
/* call PROGRESS once with 0 percent, as we sort-of skip that here */
if(is_upgrade) {
PROGRESS(trans, PM_TRANS_PROGRESS_UPGRADE_START,
PROGRESS(trans, ALPM_TRANS_PROGRESS_UPGRADE_START,
alpm_pkg_get_name(newpkg), 0, pkg_count, pkg_current);
} else {
PROGRESS(trans, PM_TRANS_PROGRESS_ADD_START,
PROGRESS(trans, ALPM_TRANS_PROGRESS_ADD_START,
alpm_pkg_get_name(newpkg), 0, pkg_count, pkg_current);
}
@@ -608,7 +581,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,
* (missing metadata sizes) */
int64_t pos = archive_position_compressed(archive);
percent = (pos * 100) / newpkg->size;
_alpm_log(PM_LOG_DEBUG, "decompression progress: "
_alpm_log(handle, ALPM_LOG_DEBUG, "decompression progress: "
"%d%% (%"PRId64" / %jd)\n",
percent, pos, (intmax_t)newpkg->size);
if(percent >= 100) {
@@ -619,37 +592,36 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,
}
if(is_upgrade) {
PROGRESS(trans, PM_TRANS_PROGRESS_UPGRADE_START,
PROGRESS(trans, ALPM_TRANS_PROGRESS_UPGRADE_START,
alpm_pkg_get_name(newpkg), percent, pkg_count,
pkg_current);
} else {
PROGRESS(trans, PM_TRANS_PROGRESS_ADD_START,
PROGRESS(trans, ALPM_TRANS_PROGRESS_ADD_START,
alpm_pkg_get_name(newpkg), percent, pkg_count,
pkg_current);
}
/* extract the next file from the archive */
errors += extract_single_file(archive, entry, newpkg, oldpkg,
trans, db);
errors += extract_single_file(handle, archive, entry, newpkg, oldpkg);
}
archive_read_finish(archive);
/* restore the old cwd if we have it */
if(restore_cwd && chdir(cwd) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));
_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));
}
if(errors) {
ret = -1;
if(is_upgrade) {
_alpm_log(PM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
newpkg->name);
alpm_logaction("error: problem occurred while upgrading %s\n",
alpm_logaction(handle, "error: problem occurred while upgrading %s\n",
newpkg->name);
} else {
_alpm_log(PM_LOG_ERROR, _("problem occurred while installing %s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"),
newpkg->name);
alpm_logaction("error: problem occurred while installing %s\n",
alpm_logaction(handle, "error: problem occurred while installing %s\n",
newpkg->name);
}
}
@@ -658,69 +630,65 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,
/* make an install date (in UTC) */
newpkg->installdate = time(NULL);
_alpm_log(PM_LOG_DEBUG, "updating database\n");
_alpm_log(PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);
_alpm_log(handle, ALPM_LOG_DEBUG, "updating database\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);
if(_alpm_local_db_write(db, newpkg, INFRQ_ALL)) {
_alpm_log(PM_LOG_ERROR, _("could not update database entry %s-%s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not update database entry %s-%s\n"),
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
alpm_logaction("error: could not update database entry %s-%s\n",
alpm_logaction(handle, "error: could not update database entry %s-%s\n",
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
pm_errno = PM_ERR_DB_WRITE;
handle->pm_errno = ALPM_ERR_DB_WRITE;
ret = -1;
goto cleanup;
}
if(_alpm_db_add_pkgincache(db, newpkg) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not add entry '%s' in cache\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not add entry '%s' in cache\n"),
alpm_pkg_get_name(newpkg));
}
if(is_upgrade) {
PROGRESS(trans, PM_TRANS_PROGRESS_UPGRADE_START,
PROGRESS(trans, ALPM_TRANS_PROGRESS_UPGRADE_START,
alpm_pkg_get_name(newpkg), 100, pkg_count, pkg_current);
} else {
PROGRESS(trans, PM_TRANS_PROGRESS_ADD_START,
PROGRESS(trans, ALPM_TRANS_PROGRESS_ADD_START,
alpm_pkg_get_name(newpkg), 100, pkg_count, pkg_current);
}
/* run the post-install script if it exists */
if(alpm_pkg_has_scriptlet(newpkg)
&& !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
&& !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
if(is_upgrade) {
_alpm_runscriptlet(handle->root, scriptlet, "post_upgrade",
_alpm_runscriptlet(handle, scriptlet, "post_upgrade",
alpm_pkg_get_version(newpkg),
oldpkg ? alpm_pkg_get_version(oldpkg) : NULL, trans);
oldpkg ? alpm_pkg_get_version(oldpkg) : NULL);
} else {
_alpm_runscriptlet(handle->root, scriptlet, "post_install",
alpm_pkg_get_version(newpkg), NULL, trans);
_alpm_runscriptlet(handle, scriptlet, "post_install",
alpm_pkg_get_version(newpkg), NULL);
}
}
if(is_upgrade) {
EVENT(trans, PM_TRANS_EVT_UPGRADE_DONE, newpkg, oldpkg);
EVENT(trans, ALPM_TRANS_EVT_UPGRADE_DONE, newpkg, oldpkg);
} else {
EVENT(trans, PM_TRANS_EVT_ADD_DONE, newpkg, oldpkg);
EVENT(trans, ALPM_TRANS_EVT_ADD_DONE, newpkg, oldpkg);
}
cleanup:
_alpm_pkg_free(oldpkg);
return(ret);
return ret;
}
int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)
int _alpm_upgrade_packages(alpm_handle_t *handle)
{
size_t pkg_count, pkg_current;
int skip_ldconfig = 0, ret = 0;
alpm_list_t *targ;
ALPM_LOG_FUNC;
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
alpm_trans_t *trans = handle->trans;
if(trans->add == NULL) {
return(0);
return 0;
}
pkg_count = alpm_list_count(trans->add);
@@ -728,15 +696,16 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)
/* loop through our package list adding/upgrading one at a time */
for(targ = trans->add; targ; targ = targ->next) {
alpm_pkg_t *newpkg = targ->data;
if(handle->trans->state == STATE_INTERRUPTED) {
return(ret);
return ret;
}
pmpkg_t *newpkg = (pmpkg_t *)targ->data;
if(commit_single_pkg(newpkg, pkg_current, pkg_count, trans, db)) {
if(commit_single_pkg(handle, newpkg, pkg_current, pkg_count)) {
/* something screwed up on the commit, abort the trans */
trans->state = STATE_INTERRUPTED;
pm_errno = PM_ERR_TRANS_ABORT;
handle->pm_errno = ALPM_ERR_TRANS_ABORT;
/* running ldconfig at this point could possibly screw system */
skip_ldconfig = 1;
ret = -1;
@@ -747,10 +716,10 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)
if(!skip_ldconfig) {
/* run ldconfig if it exists */
_alpm_ldconfig(handle->root);
_alpm_ldconfig(handle);
}
return(ret);
return ret;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -24,7 +24,7 @@
#include "alpm_list.h"
#include "trans.h"
int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db);
int _alpm_upgrade_packages(alpm_handle_t *handle);
#endif /* _ALPM_ADD_H */

View File

@@ -23,20 +23,17 @@
#include "config.h"
/* connection caching setup */
#ifdef HAVE_LIBFETCH
#include <fetch.h>
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif
/* libalpm */
#include "alpm.h"
#include "alpm_list.h"
#include "handle.h"
#include "log.h"
#include "util.h"
/* Globals */
enum _pmerrno_t pm_errno SYMEXPORT;
/** \addtogroup alpm_interface Interface Functions
* @brief Functions to initialize and release libalpm
* @{
@@ -44,64 +41,90 @@ enum _pmerrno_t pm_errno SYMEXPORT;
/** Initializes the library. This must be called before any other
* functions are called.
* @return 0 on success, -1 on error (pm_errno is set accordingly)
* @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
*/
int SYMEXPORT alpm_initialize(void)
alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
enum _alpm_errno_t *err)
{
ASSERT(handle == NULL, RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1));
enum _alpm_errno_t myerr;
const char *lf = "db.lck";
size_t lockfilelen;
alpm_handle_t *myhandle = _alpm_handle_new();
handle = _alpm_handle_new();
if(handle == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
if(myhandle == NULL) {
myerr = ALPM_ERR_MEMORY;
goto cleanup;
}
if(_alpm_db_register_local() == NULL) {
/* error code should be set */
_alpm_handle_free(handle);
handle = NULL;
return(-1);
if((myerr = _alpm_set_directory_option(root, &(myhandle->root), 1))) {
goto cleanup;
}
if((myerr = _alpm_set_directory_option(dbpath, &(myhandle->dbpath), 1))) {
goto cleanup;
}
lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1;
myhandle->lockfile = calloc(lockfilelen, sizeof(char));
snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf);
if(_alpm_db_register_local(myhandle) == NULL) {
myerr = myhandle->pm_errno;
goto cleanup;
}
#ifdef ENABLE_NLS
bindtextdomain("libalpm", LOCALEDIR);
#endif
#ifdef HAVE_LIBFETCH
fetchConnectionCacheInit(5, 1);
#ifdef HAVE_LIBCURL
curl_global_init(CURL_GLOBAL_SSL);
myhandle->curl = curl_easy_init();
#endif
return(0);
return myhandle;
cleanup:
_alpm_handle_free(myhandle);
if(err && myerr) {
*err = myerr;
}
return NULL;
}
/** Release the library. This should be the last alpm call you make.
* @return 0 on success, -1 on error (pm_errno is set accordingly)
* After this returns, handle should be considered invalid and cannot be reused
* in any way.
* @param handle the context handle
* @return 0 on success, -1 on error
*/
int SYMEXPORT alpm_release(void)
int SYMEXPORT alpm_release(alpm_handle_t *myhandle)
{
pmdb_t *db;
int ret = 0;
alpm_db_t *db;
ALPM_LOG_FUNC;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(myhandle, return -1);
/* close local database */
db = handle->db_local;
db = myhandle->db_local;
if(db) {
db->ops->unregister(db);
handle->db_local = NULL;
myhandle->db_local = NULL;
}
if(alpm_db_unregister_all() == -1) {
return(-1);
if(alpm_db_unregister_all(myhandle) == -1) {
ret = -1;
}
_alpm_handle_free(handle);
handle = NULL;
_alpm_handle_unlock(myhandle);
_alpm_handle_free(myhandle);
#ifdef HAVE_LIBFETCH
fetchConnectionCacheClose();
#ifdef HAVE_LIBCURL
curl_global_cleanup();
#endif
return(0);
return ret;
}
/** @} */
@@ -112,7 +135,7 @@ int SYMEXPORT alpm_release(void)
/* Get the version of library */
const char SYMEXPORT *alpm_version(void) {
return(LIB_VERSION);
return LIB_VERSION;
}
/* vim: set ts=2 sw=2 noet: */

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* libalpm */
#include "alpm_list.h"
@@ -92,7 +91,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
ptr = calloc(1, sizeof(alpm_list_t));
if(ptr == NULL) {
return(list);
return list;
}
ptr->data = data;
@@ -101,7 +100,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
/* Special case: the input list is empty */
if(list == NULL) {
ptr->prev = ptr;
return(ptr);
return ptr;
}
lp = alpm_list_last(list);
@@ -109,7 +108,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
ptr->prev = lp;
list->prev = ptr;
return(list);
return list;
}
/**
@@ -124,13 +123,13 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn)
{
if(!fn || !list) {
return(alpm_list_add(list, data));
return alpm_list_add(list, data);
} else {
alpm_list_t *add = NULL, *prev = NULL, *next = list;
add = calloc(1, sizeof(alpm_list_t));
if(add == NULL) {
return(list);
return list;
}
add->data = data;
@@ -146,19 +145,19 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_
add->prev = list->prev; /* list != NULL */
add->next = list;
list->prev = add;
return(add);
return add;
} else if(next == NULL) { /* another special case: add last element */
add->prev = prev;
add->next = NULL;
prev->next = add;
list->prev = add;
return(list);
return list;
} else {
add->prev = prev;
add->next = next;
next->prev = add;
prev->next = add;
return(list);
return list;
}
}
}
@@ -178,11 +177,11 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
{
alpm_list_t *tmp;
if (first == NULL) {
return(second);
if(first == NULL) {
return second;
}
if (second == NULL) {
return(first);
if(second == NULL) {
return first;
}
/* tmp is the last element of the first list */
tmp = first->prev;
@@ -193,7 +192,7 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
/* set the back reference to the tail */
second->prev = tmp;
return(first);
return first;
}
/**
@@ -209,12 +208,12 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a
{
alpm_list_t *newlist, *lp;
if (left == NULL)
if(left == NULL)
return right;
if (right == NULL)
if(right == NULL)
return left;
if (fn(left->data, right->data) <= 0) {
if(fn(left->data, right->data) <= 0) {
newlist = left;
left = left->next;
}
@@ -226,8 +225,8 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a
newlist->next = NULL;
lp = newlist;
while ((left != NULL) && (right != NULL)) {
if (fn(left->data, right->data) <= 0) {
while((left != NULL) && (right != NULL)) {
if(fn(left->data, right->data) <= 0) {
lp->next = left;
left->prev = lp;
left = left->next;
@@ -240,11 +239,11 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a
lp = lp->next;
lp->next = NULL;
}
if (left != NULL) {
if(left != NULL) {
lp->next = left;
left->prev = lp;
}
else if (right != NULL) {
else if(right != NULL) {
lp->next = right;
right->prev = lp;
}
@@ -257,7 +256,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a
}
newlist->prev = lp;
return(newlist);
return newlist;
}
/**
@@ -271,7 +270,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a
*/
alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn)
{
if (n > 1) {
if(n > 1) {
alpm_list_t *left = list;
alpm_list_t *lastleft = alpm_list_nth(list, n/2 - 1);
alpm_list_t *right = lastleft->next;
@@ -282,7 +281,7 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn
right = alpm_list_msort(right, n - (n/2), fn);
list = alpm_list_mmerge(left, right, fn);
}
return(list);
return list;
}
/**
@@ -298,7 +297,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,
alpm_list_t *item)
{
if(haystack == NULL || item == NULL) {
return(haystack);
return haystack;
}
if(item == haystack) {
@@ -328,7 +327,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,
}
}
return(haystack);
return haystack;
}
@@ -352,7 +351,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
}
if(needle == NULL) {
return(haystack);
return haystack;
}
while(i) {
@@ -373,7 +372,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
}
}
return(haystack);
return haystack;
}
/**
@@ -388,8 +387,8 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack,
const char *needle, char **data)
{
return(alpm_list_remove(haystack, (const void *)needle,
(alpm_list_fn_cmp)strcmp, (void **)data));
return alpm_list_remove(haystack, (const void *)needle,
(alpm_list_fn_cmp)strcmp, (void **)data);
}
/**
@@ -411,7 +410,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list)
}
lp = lp->next;
}
return(newlist);
return newlist;
}
/**
@@ -429,7 +428,7 @@ alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list)
newlist = alpm_list_add(newlist, strdup(lp->data));
lp = lp->next;
}
return(newlist);
return newlist;
}
/**
@@ -447,7 +446,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list)
newlist = alpm_list_add(newlist, lp->data);
lp = lp->next;
}
return(newlist);
return newlist;
}
/**
@@ -473,7 +472,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
lp = lp->next;
}
}
return(newlist);
return newlist;
}
/**
@@ -489,7 +488,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
alpm_list_t *newlist = NULL, *backup;
if(list == NULL) {
return(NULL);
return NULL;
}
lp = alpm_list_last(list);
@@ -502,27 +501,11 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
lp = lp->prev;
}
list->prev = backup; /* restore tail pointer */
return(newlist);
return newlist;
}
/* Accessors */
/**
* @brief Get the first element of a list.
*
* @param list the list
*
* @return the first element in the list
*/
inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list)
{
if(list) {
return((alpm_list_t*)list);
} else {
return(NULL);
}
}
/**
* @brief Return nth element from list (starting from 0).
*
@@ -537,7 +520,7 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n)
while(n--) {
i = i->next;
}
return((alpm_list_t*)i);
return (alpm_list_t *)i;
}
/**
@@ -550,9 +533,26 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n)
inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
{
if(node) {
return(node->next);
return node->next;
} else {
return(NULL);
return NULL;
}
}
/**
* @brief Get the previous element of a list.
*
* @param list the list head
* @param node the list node
*
* @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) {
return list->prev;
} else {
return NULL;
}
}
@@ -566,9 +566,9 @@ inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)
{
if(list) {
return(list->prev);
return list->prev;
} else {
return(NULL);
return NULL;
}
}
@@ -581,8 +581,8 @@ alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)
*/
void SYMEXPORT *alpm_list_getdata(const alpm_list_t *node)
{
if(node == NULL) return(NULL);
return(node->data);
if(node == NULL) return NULL;
return node->data;
}
/* Misc */
@@ -602,7 +602,7 @@ size_t SYMEXPORT alpm_list_count(const alpm_list_t *list)
++i;
lp = lp->next;
}
return(i);
return i;
}
/**
@@ -620,17 +620,17 @@ void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle,
const alpm_list_t *lp = haystack;
while(lp) {
if(lp->data && fn(lp->data, needle) == 0) {
return(lp->data);
return lp->data;
}
lp = lp->next;
}
return(NULL);
return NULL;
}
/* trivial helper function for alpm_list_find_ptr */
static int ptr_cmp(const void *p, const void *q)
{
return(p != q);
return (p != q);
}
/**
@@ -643,9 +643,10 @@ static int ptr_cmp(const void *p, const void *q)
*
* @return `needle` if found, NULL otherwise
*/
void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle)
void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack,
const void *needle)
{
return(alpm_list_find(haystack, needle, ptr_cmp));
return alpm_list_find(haystack, needle, ptr_cmp);
}
/**
@@ -659,8 +660,8 @@ void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *need
char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack,
const char *needle)
{
return((char *)alpm_list_find(haystack, (const void*)needle,
(alpm_list_fn_cmp)strcmp));
return (char *)alpm_list_find(haystack, (const void *)needle,
(alpm_list_fn_cmp)strcmp);
}
/**
@@ -688,7 +689,7 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left,
return;
}
while (l != NULL && r != NULL) {
while(l != NULL && r != NULL) {
int cmp = fn(l->data, r->data);
if(cmp < 0) {
if(onlyleft) {
@@ -706,13 +707,13 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left,
r = r->next;
}
}
while (l != NULL) {
while(l != NULL) {
if(onlyleft) {
*onlyleft = alpm_list_add(*onlyleft, l->data);
}
l = l->next;
}
while (r != NULL) {
while(r != NULL) {
if(onlyright) {
*onlyright = alpm_list_add(*onlyright, r->data);
}
@@ -745,7 +746,39 @@ alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs,
alpm_list_free(left);
alpm_list_free(right);
return(ret);
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)
{
size_t i;
const alpm_list_t *item;
char *array;
if(n == 0) {
return NULL;
}
array = calloc(n, size);
if(array == NULL) {
return NULL;
}
for(i = 0, item = list; i < n && item; i++, item = item->next) {
memcpy(array + i * size, item->data, size);
}
return array;
}
/** @} */

View File

@@ -67,9 +67,9 @@ alpm_list_t *alpm_list_copy_data(const alpm_list_t *list, size_t size);
alpm_list_t *alpm_list_reverse(alpm_list_t *list);
/* item accessors */
alpm_list_t *alpm_list_first(const alpm_list_t *list);
alpm_list_t *alpm_list_nth(const alpm_list_t *list, size_t n);
alpm_list_t *alpm_list_next(const alpm_list_t *list);
alpm_list_t *alpm_list_previous(const alpm_list_t *list);
alpm_list_t *alpm_list_last(const alpm_list_t *list);
void *alpm_list_getdata(const alpm_list_t *entry);
@@ -81,6 +81,7 @@ char *alpm_list_find_str(const alpm_list_t *haystack, const char *needle);
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);
void *alpm_list_to_array(const alpm_list_t *list, size_t n, size_t size);
#ifdef __cplusplus
}

View File

@@ -32,82 +32,67 @@
#include "log.h"
#include "util.h"
/* split a backup string "file\thash" into two strings : file and hash */
static int backup_split(const char *string, char **file, char **hash)
/* split a backup string "file\thash" into the relevant components */
int _alpm_split_backup(const char *string, alpm_backup_t **backup)
{
char *str = strdup(string);
char *ptr;
char *str, *ptr;
STRDUP(str, string, return -1);
/* tab delimiter */
ptr = strchr(str, '\t');
ptr = str ? strchr(str, '\t') : NULL;
if(ptr == NULL) {
if(file) {
*file = str;
} else {
/* don't need our dup as the fname wasn't requested, so free it */
FREE(str);
}
return(0);
(*backup)->name = str;
(*backup)->hash = NULL;
return 0;
}
*ptr = '\0';
ptr++;
/* now str points to the filename and ptr points to the hash */
if(file) {
*file = strdup(str);
}
if(hash) {
*hash = strdup(ptr);
}
STRDUP((*backup)->name, str, return -1);
STRDUP((*backup)->hash, ptr, return -1);
FREE(str);
return(1);
return 0;
}
char *_alpm_backup_file(const char *string)
{
char *file = NULL;
backup_split(string, &file, NULL);
return(file);
}
char *_alpm_backup_hash(const char *string)
{
char *hash = NULL;
backup_split(string, NULL, &hash);
return(hash);
}
/* Look for a filename in a pmpkg_t.backup list. If we find it,
* then we return the md5 hash (parsed from the same line)
/* Look for a filename in a alpm_pkg_t.backup list. If we find it,
* then we return the full backup entry.
*/
char *_alpm_needbackup(const char *file, const alpm_list_t *backup)
alpm_backup_t *_alpm_needbackup(const char *file, alpm_pkg_t *pkg)
{
const alpm_list_t *lp;
ALPM_LOG_FUNC;
if(file == NULL || backup == NULL) {
return(NULL);
if(file == NULL || pkg == NULL) {
return NULL;
}
/* run through the backup list and parse out the hash for our file */
for(lp = backup; lp; lp = lp->next) {
char *filename = NULL;
char *hash = NULL;
for(lp = alpm_pkg_get_backup(pkg); lp; lp = lp->next) {
alpm_backup_t *backup = lp->data;
/* no hash found */
if(!backup_split((char *)lp->data, &filename, &hash)) {
FREE(filename);
continue;
if(strcmp(file, backup->name) == 0) {
return backup;
}
if(strcmp(file, filename) == 0) {
FREE(filename);
return(hash);
}
FREE(filename);
FREE(hash);
}
return(NULL);
return NULL;
}
void _alpm_backup_free(alpm_backup_t *backup)
{
free(backup->name);
free(backup->hash);
free(backup);
}
alpm_backup_t *_alpm_backup_dup(const alpm_backup_t *backup)
{
alpm_backup_t *newbackup;
CALLOC(newbackup, 1, sizeof(alpm_backup_t), return NULL);
STRDUP(newbackup->name, backup->name, return NULL);
STRDUP(newbackup->hash, backup->hash, return NULL);
return newbackup;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -21,10 +21,12 @@
#define _ALPM_BACKUP_H
#include "alpm_list.h"
#include "alpm.h"
char *_alpm_backup_file(const char *string);
char *_alpm_backup_hash(const char *string);
char *_alpm_needbackup(const char *file, const alpm_list_t *backup);
int _alpm_split_backup(const char *string, alpm_backup_t **backup);
alpm_backup_t *_alpm_needbackup(const char *file, alpm_pkg_t *pkg);
void _alpm_backup_free(alpm_backup_t *backup);
alpm_backup_t *_alpm_backup_dup(const alpm_backup_t *backup);
#endif /* _ALPM_BACKUP_H */

190
lib/libalpm/base64.c Normal file
View File

@@ -0,0 +1,190 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* 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/>.
*/
/*
* Pacman Notes:
*
* Taken from the PolarSSL project at www.polarssl.org under terms of the
* GPL. This is from version 0.14.2 of the library, and has been modified
* as following, which may be helpful for future updates:
* * remove "polarssl/config.h" include
* * change include from "polarssl/base64.h" to "base64.h"
* * removal of SELF_TEST code
*/
#include "base64.h"
static const unsigned char base64_enc_map[64] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'
};
static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 127, 127, 127, 127, 127
};
/*
* Encode a buffer into base64 format
*/
int base64_encode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen )
{
int i, n;
int C1, C2, C3;
unsigned char *p;
if( slen == 0 )
return( 0 );
n = (slen << 3) / 6;
switch( (slen << 3) - (n * 6) )
{
case 2: n += 3; break;
case 4: n += 2; break;
default: break;
}
if( *dlen < n + 1 )
{
*dlen = n + 1;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
n = (slen / 3) * 3;
for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if( i < slen )
{
C1 = *src++;
C2 = ((i + 1) < slen) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if( (i + 1) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';
*p++ = '=';
}
*dlen = p - dst;
*p = 0;
return( 0 );
}
/*
* Decode a base64-formatted buffer
*/
int base64_decode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen )
{
int i, j, n;
unsigned long x;
unsigned char *p;
for( i = j = n = 0; i < slen; i++ )
{
if( ( slen - i ) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n' )
continue;
if( src[i] == '\n' )
continue;
if( src[i] == '=' && ++j > 2 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( base64_dec_map[src[i]] < 64 && j != 0 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
n++;
}
if( n == 0 )
return( 0 );
n = ((n * 6) + 7) >> 3;
if( *dlen < n )
{
*dlen = n;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '\r' || *src == '\n' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}
*dlen = p - dst;
return( 0 );
}

68
lib/libalpm/base64.h Normal file
View File

@@ -0,0 +1,68 @@
/**
* \file base64.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _BASE64_H
#define _BASE64_H
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the buffer
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
* *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_encode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer
* \param dlen size of the buffer
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
* POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
* correct. *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_decode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen );
#endif /* base64.h */

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* be_package.c
* be_package.c : backend for packages
*
* Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
@@ -20,10 +20,8 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
/* libarchive */
@@ -32,8 +30,10 @@
/* libalpm */
#include "alpm_list.h"
#include "alpm.h"
#include "util.h"
#include "log.h"
#include "handle.h"
#include "package.h"
#include "deps.h" /* _alpm_splitdep */
@@ -43,40 +43,38 @@
* @param pkg the package (file) to read the changelog
* @return a 'file stream' to the package changelog
*/
static void *_package_changelog_open(pmpkg_t *pkg)
static void *_package_changelog_open(alpm_pkg_t *pkg)
{
ALPM_LOG_FUNC;
ASSERT(pkg != NULL, return(NULL));
ASSERT(pkg != NULL, return NULL);
struct archive *archive = NULL;
struct archive_entry *entry;
const char *pkgfile = pkg->origin_data.file;
if((archive = archive_read_new()) == NULL) {
RET_ERR(PM_ERR_LIBARCHIVE, NULL);
RET_ERR(pkg->handle, ALPM_ERR_LIBARCHIVE, NULL);
}
archive_read_support_compression_all(archive);
archive_read_support_format_all(archive);
if (archive_read_open_filename(archive, pkgfile,
if(archive_read_open_filename(archive, pkgfile,
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
RET_ERR(PM_ERR_PKG_OPEN, NULL);
RET_ERR(pkg->handle, ALPM_ERR_PKG_OPEN, NULL);
}
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
const char *entry_name = archive_entry_pathname(entry);
if(strcmp(entry_name, ".CHANGELOG") == 0) {
return(archive);
return archive;
}
}
/* we didn't find a changelog */
archive_read_finish(archive);
errno = ENOENT;
return(NULL);
return NULL;
}
/**
@@ -89,26 +87,17 @@ static void *_package_changelog_open(pmpkg_t *pkg)
* @return the number of characters read, or 0 if there is no more data
*/
static size_t _package_changelog_read(void *ptr, size_t size,
const pmpkg_t *pkg, const void *fp)
const alpm_pkg_t UNUSED *pkg, const void *fp)
{
ssize_t sret = archive_read_data((struct archive*)fp, ptr, size);
ssize_t sret = archive_read_data((struct archive *)fp, ptr, size);
/* Report error (negative values) */
if(sret < 0) {
pm_errno = PM_ERR_LIBARCHIVE;
return(0);
RET_ERR(pkg->handle, ALPM_ERR_LIBARCHIVE, 0);
} else {
return((size_t)sret);
return (size_t)sret;
}
}
/*
static int _package_changelog_feof(const pmpkg_t *pkg, void *fp)
{
// note: this doesn't quite work, no feof in libarchive
return( archive_read_data((struct archive*)fp, NULL, 0) );
}
*/
/**
* Close a package changelog for reading. Similar to fclose in functionality,
* except that the 'file stream' is from an archive.
@@ -116,9 +105,9 @@ static int _package_changelog_feof(const pmpkg_t *pkg, void *fp)
* @param fp a 'file stream' to the package changelog
* @return whether closing the package changelog stream was successful
*/
static int _package_changelog_close(const pmpkg_t *pkg, void *fp)
static int _package_changelog_close(const alpm_pkg_t UNUSED *pkg, void *fp)
{
return( archive_read_finish((struct archive *)fp) );
return archive_read_finish((struct archive *)fp);
}
/** Package file operations struct accessor. We implement this as a method
@@ -137,72 +126,70 @@ static struct pkg_operations *get_file_pkg_ops(void)
file_pkg_ops.changelog_close = _package_changelog_close;
file_pkg_ops_initialized = 1;
}
return(&file_pkg_ops);
return &file_pkg_ops;
}
/**
* Parses the package description file for a package into a pmpkg_t struct.
* Parses the package description file for a package into a alpm_pkg_t struct.
* @param archive the archive to read from, pointed at the .PKGINFO entry
* @param newpkg an empty pmpkg_t struct to fill with package info
* @param newpkg an empty alpm_pkg_t struct to fill with package info
*
* @return 0 on success, 1 on error
* @return 0 on success, -1 on error
*/
static int parse_descfile(struct archive *a, pmpkg_t *newpkg)
static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *newpkg)
{
char *ptr = NULL;
char *key = NULL;
int linenum = 0;
int ret, linenum = 0;
struct archive_read_buffer buf;
ALPM_LOG_FUNC;
memset(&buf, 0, sizeof(buf));
/* 512K for a line length seems reasonable */
buf.max_line_size = 512 * 1024;
/* loop until we reach EOF or other error */
while(_alpm_archive_fgets(a, &buf) == ARCHIVE_OK) {
char *line = _alpm_strtrim(buf.line);
while((ret = _alpm_archive_fgets(a, &buf)) == ARCHIVE_OK) {
size_t len = _alpm_strip_newline(buf.line);
linenum++;
if(strlen(line) == 0 || line[0] == '#') {
if(len == 0 || buf.line[0] == '#') {
continue;
}
ptr = line;
ptr = buf.line;
key = strsep(&ptr, "=");
if(key == NULL || ptr == NULL) {
_alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
newpkg->name ? newpkg->name : "error", linenum);
} else {
key = _alpm_strtrim(key);
while(*ptr == ' ') ptr++;
ptr = _alpm_strtrim(ptr);
if(strcmp(key, "pkgname") == 0) {
STRDUP(newpkg->name, ptr, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(newpkg->name, ptr, return -1);
newpkg->name_hash = _alpm_hash_sdbm(newpkg->name);
} else if(strcmp(key, "pkgbase") == 0) {
/* not used atm */
} else if(strcmp(key, "pkgver") == 0) {
STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(newpkg->version, ptr, return -1);
} else if(strcmp(key, "pkgdesc") == 0) {
STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(newpkg->desc, ptr, return -1);
} else if(strcmp(key, "group") == 0) {
newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr));
} else if(strcmp(key, "url") == 0) {
STRDUP(newpkg->url, ptr, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(newpkg->url, ptr, return -1);
} else if(strcmp(key, "license") == 0) {
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) {
STRDUP(newpkg->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(newpkg->packager, ptr, return -1);
} else if(strcmp(key, "arch") == 0) {
STRDUP(newpkg->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1));
STRDUP(newpkg->arch, ptr, return -1);
} else if(strcmp(key, "size") == 0) {
/* size in the raw package is uncompressed (installed) size */
newpkg->isize = atol(ptr);
} else if(strcmp(key, "depend") == 0) {
pmdepend_t *dep = _alpm_splitdep(ptr);
alpm_depend_t *dep = _alpm_splitdep(ptr);
newpkg->depends = alpm_list_add(newpkg->depends, dep);
} else if(strcmp(key, "optdepend") == 0) {
newpkg->optdepends = alpm_list_add(newpkg->optdepends, strdup(ptr));
@@ -213,70 +200,148 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg)
} else if(strcmp(key, "provides") == 0) {
newpkg->provides = alpm_list_add(newpkg->provides, strdup(ptr));
} else if(strcmp(key, "backup") == 0) {
newpkg->backup = alpm_list_add(newpkg->backup, strdup(ptr));
alpm_backup_t *backup;
CALLOC(backup, 1, sizeof(alpm_backup_t), return -1);
STRDUP(backup->name, ptr, return -1);
newpkg->backup = alpm_list_add(newpkg->backup, backup);
} else if(strcmp(key, "force") == 0) {
/* deprecated, skip it */
} else if(strcmp(key, "makepkgopt") == 0) {
/* not used atm */
} else {
_alpm_log(PM_LOG_DEBUG, "%s: unknown key '%s' in description file line %d\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: unknown key '%s' in description file line %d\n",
newpkg->name ? newpkg->name : "error", key, linenum);
}
}
line[0] = '\0';
}
if(ret != ARCHIVE_EOF) {
_alpm_log(handle, ALPM_LOG_DEBUG, "error parsing package descfile\n");
return -1;
}
return(0);
return 0;
}
static void files_merge(alpm_file_t a[], alpm_file_t b[], alpm_file_t c[],
size_t m, size_t n)
{
size_t i = 0, j = 0, k = 0;
while(i < m && j < n) {
if(strcmp(a[i].name, b[j].name) < 0) {
c[k++] = a[i++];
} else {
c[k++] = b[j++];
}
}
while(i < m) {
c[k++] = a[i++];
}
while(j < n) {
c[k++] = b[j++];
}
}
static alpm_file_t *files_msort(alpm_file_t *files, size_t n)
{
alpm_file_t *work;
size_t blocksize = 1;
CALLOC(work, n, sizeof(alpm_file_t), return NULL);
for(blocksize = 1; blocksize < n; blocksize *= 2) {
size_t i, max_extent = 0;
for(i = 0; i < n - blocksize; i += 2 * blocksize) {
/* this limits our actual merge to the length of the array, since we will
* not likely be a perfect power of two. */
size_t right_blocksize = blocksize;
if(i + blocksize * 2 > n) {
right_blocksize = n - i - blocksize;
}
files_merge(files + i, files + i + blocksize, work + i,
blocksize, right_blocksize);
max_extent = i + blocksize + right_blocksize;
}
/* ensure we only copy what we actually touched on this merge pass,
* no more, no less */
memcpy(files, work, max_extent * sizeof(alpm_file_t));
}
free(work);
return files;
}
/**
* Load a package and create the corresponding pmpkg_t struct.
* Load a package and create the corresponding alpm_pkg_t struct.
* @param handle the context handle
* @param pkgfile path to the package file
* @param full whether to stop the load after metadata is read or continue
* through the full archive
* @return An information filled pmpkg_t struct
* @return An information filled alpm_pkg_t struct
*/
static pmpkg_t *pkg_load(const char *pkgfile, int full)
alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
int full, const char *md5sum, const char *base64_sig,
alpm_siglevel_t level)
{
int ret = ARCHIVE_OK;
int ret;
int config = 0;
struct archive *archive;
struct archive_entry *entry;
pmpkg_t *newpkg = NULL;
alpm_pkg_t *newpkg = NULL;
struct stat st;
ALPM_LOG_FUNC;
size_t files_count = 0, files_size = 0;
alpm_file_t *files = NULL;
if(pkgfile == NULL || strlen(pkgfile) == 0) {
RET_ERR(PM_ERR_WRONG_ARGS, NULL);
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL);
}
if(stat(pkgfile, &st) != 0) {
RET_ERR(PM_ERR_PKG_OPEN, NULL);
/* attempt to stat the package file, ensure it exists */
if(stat(pkgfile, &st) == 0) {
newpkg = _alpm_pkg_new();
if(newpkg == NULL) {
RET_ERR(handle, ALPM_ERR_MEMORY, NULL);
}
newpkg->filename = strdup(pkgfile);
newpkg->size = st.st_size;
} else {
/* couldn't stat the pkgfile, return an error */
RET_ERR(handle, ALPM_ERR_PKG_OPEN, NULL);
}
/* first steps- validate the package file */
_alpm_log(handle, ALPM_LOG_DEBUG, "md5sum: %s\n", md5sum);
if(md5sum) {
_alpm_log(handle, ALPM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile);
if(_alpm_test_md5sum(pkgfile, md5sum) != 0) {
alpm_pkg_free(newpkg);
RET_ERR(handle, ALPM_ERR_PKG_INVALID_CHECKSUM, NULL);
}
}
_alpm_log(handle, ALPM_LOG_DEBUG, "base64_sig: %s\n", base64_sig);
if(level & ALPM_SIG_PACKAGE &&
_alpm_check_pgp_helper(handle, pkgfile, base64_sig,
level & ALPM_SIG_PACKAGE_OPTIONAL, level & ALPM_SIG_PACKAGE_MARGINAL_OK,
level & ALPM_SIG_PACKAGE_UNKNOWN_OK, ALPM_ERR_PKG_INVALID_SIG)) {
_alpm_pkg_free(newpkg);
return NULL;
}
/* next- try to create an archive object to read in the package */
if((archive = archive_read_new()) == NULL) {
RET_ERR(PM_ERR_LIBARCHIVE, NULL);
alpm_pkg_free(newpkg);
RET_ERR(handle, ALPM_ERR_LIBARCHIVE, NULL);
}
archive_read_support_compression_all(archive);
archive_read_support_format_all(archive);
if (archive_read_open_filename(archive, pkgfile,
if(archive_read_open_filename(archive, pkgfile,
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
RET_ERR(PM_ERR_PKG_OPEN, NULL);
alpm_pkg_free(newpkg);
RET_ERR(handle, ALPM_ERR_PKG_OPEN, NULL);
}
newpkg = _alpm_pkg_new();
if(newpkg == NULL) {
archive_read_finish(archive);
RET_ERR(PM_ERR_MEMORY, NULL);
}
newpkg->filename = strdup(pkgfile);
newpkg->size = st.st_size;
_alpm_log(PM_LOG_DEBUG, "starting package load for %s\n", pkgfile);
_alpm_log(handle, ALPM_LOG_DEBUG, "starting package load for %s\n", pkgfile);
/* If full is false, only read through the archive until we find our needed
* metadata. If it is true, read through the entire archive, which serves
@@ -286,17 +351,17 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
if(strcmp(entry_name, ".PKGINFO") == 0) {
/* parse the info file */
if(parse_descfile(archive, newpkg) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not parse package description file in %s\n"),
if(parse_descfile(handle, archive, newpkg) != 0) {
_alpm_log(handle, ALPM_LOG_ERROR, _("could not parse package description file in %s\n"),
pkgfile);
goto pkg_invalid;
}
if(newpkg->name == NULL || strlen(newpkg->name) == 0) {
_alpm_log(PM_LOG_ERROR, _("missing package name in %s\n"), pkgfile);
_alpm_log(handle, ALPM_LOG_ERROR, _("missing package name in %s\n"), pkgfile);
goto pkg_invalid;
}
if(newpkg->version == NULL || strlen(newpkg->version) == 0) {
_alpm_log(PM_LOG_ERROR, _("missing package version in %s\n"), pkgfile);
_alpm_log(handle, ALPM_LOG_ERROR, _("missing package version in %s\n"), pkgfile);
goto pkg_invalid;
}
config = 1;
@@ -308,13 +373,33 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
* already been handled (for future possibilities) */
} else if(full) {
/* Keep track of all files for filelist generation */
newpkg->files = alpm_list_add(newpkg->files, strdup(entry_name));
if(files_count >= files_size) {
size_t old_size = files_size;
if(files_size == 0) {
files_size = 4;
} else {
files_size *= 2;
}
files = realloc(files, sizeof(alpm_file_t) * files_size);
if(!files) {
ALLOC_FAIL(sizeof(alpm_file_t) * files_size);
goto error;
}
/* ensure all new memory is zeroed out, in both the initial
* allocation and later reallocs */
memset(files + old_size, 0,
sizeof(alpm_file_t) * (files_size - old_size));
}
STRDUP(files[files_count].name, entry_name, goto error);
files[files_count].size = archive_entry_size(entry);
files[files_count].mode = archive_entry_mode(entry);
files_count++;
}
if(archive_read_data_skip(archive)) {
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
pm_errno = PM_ERR_LIBARCHIVE;
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
@@ -325,14 +410,14 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
}
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occured */
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
pm_errno = PM_ERR_LIBARCHIVE;
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
goto error;
}
if(!config) {
_alpm_log(PM_LOG_ERROR, _("missing package metadata in %s\n"), pkgfile);
_alpm_log(handle, ALPM_LOG_ERROR, _("missing package metadata in %s\n"), pkgfile);
goto pkg_invalid;
}
@@ -340,49 +425,46 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
/* internal fields for package struct */
newpkg->origin = PKG_FROM_FILE;
/* TODO eventually kill/move this? */
newpkg->origin_data.file = strdup(pkgfile);
newpkg->ops = get_file_pkg_ops();
newpkg->handle = handle;
if(full) {
/* attempt to hand back any memory we don't need */
files = realloc(files, sizeof(alpm_file_t) * files_count);
/* "checking for conflicts" requires a sorted list, ensure that here */
_alpm_log(PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);
newpkg->files = alpm_list_msort(newpkg->files, alpm_list_count(newpkg->files),
_alpm_str_cmp);
newpkg->infolevel = INFRQ_ALL;
_alpm_log(handle, ALPM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);
newpkg->files.files = files_msort(files, files_count);
newpkg->files.count = files_count;
newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_FILES | INFRQ_SCRIPTLET;
} else {
/* get rid of any partial filelist we may have collected, it is invalid */
FREELIST(newpkg->files);
newpkg->infolevel = INFRQ_BASE | INFRQ_DESC;
newpkg->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_SCRIPTLET;
}
return(newpkg);
return newpkg;
pkg_invalid:
pm_errno = PM_ERR_PKG_INVALID;
handle->pm_errno = ALPM_ERR_PKG_INVALID;
error:
_alpm_pkg_free(newpkg);
archive_read_finish(archive);
return(NULL);
return NULL;
}
int SYMEXPORT alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg)
int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full,
alpm_siglevel_t level, alpm_pkg_t **pkg)
{
ALPM_LOG_FUNC;
CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
/* Sanity checks */
ASSERT(filename != NULL && strlen(filename) != 0,
RET_ERR(PM_ERR_WRONG_ARGS, -1));
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
*pkg = pkg_load(filename, full);
*pkg = _alpm_pkg_load_internal(handle, filename, full, NULL, NULL, level);
if(*pkg == NULL) {
/* pm_errno is set by pkg_load */
return(-1);
return -1;
}
return(0);
return 0;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -1,5 +1,5 @@
/*
* be_sync.c
* be_sync.c : backend for sync databases
*
* Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
@@ -21,7 +21,8 @@
#include "config.h"
#include <errno.h>
#include <limits.h>
#include <sys/stat.h>
#include <unistd.h>
/* libarchive */
#include <archive.h>
@@ -38,32 +39,93 @@
#include "deps.h"
#include "dload.h"
static char *get_sync_dir(alpm_handle_t *handle)
{
const char *dbpath = alpm_option_get_dbpath(handle);
size_t len = strlen(dbpath) + 6;
char *syncpath;
struct stat buf;
MALLOC(syncpath, len, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
sprintf(syncpath, "%s%s", dbpath, "sync/");
if(stat(syncpath, &buf) != 0) {
_alpm_log(handle, ALPM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
syncpath);
if(_alpm_makepath(syncpath) != 0) {
free(syncpath);
RET_ERR(handle, ALPM_ERR_SYSTEM, NULL);
}
} else if(!S_ISDIR(buf.st_mode)) {
_alpm_log(handle, ALPM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath);
if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) {
free(syncpath);
RET_ERR(handle, ALPM_ERR_SYSTEM, NULL);
}
}
return syncpath;
}
static int sync_db_validate(alpm_db_t *db)
{
alpm_siglevel_t level;
if(db->status & DB_STATUS_VALID) {
return 0;
}
/* this takes into account the default verification level if UNKNOWN
* was assigned to this db */
level = alpm_db_get_siglevel(db);
if(level & ALPM_SIG_DATABASE) {
const char *dbpath = _alpm_db_path(db);
if(!dbpath) {
/* pm_errno set in _alpm_db_path() */
return -1;
}
/* we can skip any validation if the database doesn't exist */
if(access(dbpath, R_OK) != 0 && errno == ENOENT) {
goto valid;
return 0;
}
if(_alpm_check_pgp_helper(db->handle, dbpath, NULL,
level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK,
level & ALPM_SIG_DATABASE_UNKNOWN_OK, ALPM_ERR_DB_INVALID_SIG)) {
return 1;
}
}
valid:
db->status |= DB_STATUS_VALID;
return 0;
}
/** 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.
*
* A transaction is necessary for this operation, in order to obtain a
* database lock. During this transaction the front-end will be informed
* of the download progress of the database via the download callback.
* 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_option_get_syncdbs();
* if(alpm_trans_init(0, NULL, NULL, NULL) == 0) {
* for(i = syncs; i; i = alpm_list_next(i)) {
* pmdb_t *db = alpm_list_getdata(i);
* result = alpm_db_update(0, db);
* alpm_trans_release();
* 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");
* }
* 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
@@ -77,78 +139,175 @@
* @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, pmdb_t *db)
int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
{
char *dbfile, *syncpath;
const char *dbpath;
struct stat buf;
size_t len;
int ret;
char *syncpath;
alpm_list_t *i;
int ret = -1;
mode_t oldmask;
ALPM_LOG_FUNC;
alpm_handle_t *handle;
alpm_siglevel_t level;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1));
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(!alpm_list_find_ptr(handle->dbs_sync, db)) {
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
syncpath = get_sync_dir(handle);
if(!syncpath) {
return -1;
}
len = strlen(db->treename) + 4;
MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(dbfile, "%s.db", db->treename);
dbpath = alpm_option_get_dbpath();
len = strlen(dbpath) + 6;
MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(syncpath, "%s%s", dbpath, "sync/");
/* make sure we have a sane umask */
oldmask = umask(0022);
if(stat(syncpath, &buf) != 0) {
_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",
syncpath);
if(_alpm_makepath(syncpath) != 0) {
free(dbfile);
free(syncpath);
RET_ERR(PM_ERR_SYSTEM, -1);
level = alpm_db_get_siglevel(db);
/* attempt to grab a lock */
if(_alpm_handle_lock(handle)) {
RET_ERR(handle, ALPM_ERR_HANDLE_LOCK, -1);
}
for(i = db->servers; i; i = i->next) {
const char *server = i->data;
struct dload_payload *payload;
size_t len;
int sig_ret = 0;
CALLOC(payload, 1, sizeof(*payload), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
/* set hard upper limit of 25MiB */
payload->max_size = 25 * 1024 * 1024;
/* print server + filename into a buffer (leave space for .sig) */
len = strlen(server) + strlen(db->treename) + 9;
CALLOC(payload->fileurl, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
snprintf(payload->fileurl, len, "%s/%s.db", server, db->treename);
payload->handle = handle;
payload->force = force;
ret = _alpm_download(payload, syncpath, NULL);
if(ret == 0 && (level & ALPM_SIG_DATABASE)) {
/* an existing sig file is no good at this point */
char *sigpath = _alpm_db_sig_path(db);
if(!sigpath) {
ret = -1;
break;
}
unlink(sigpath);
free(sigpath);
/* if we downloaded a DB, we want the .sig from the same server */
snprintf(payload->fileurl, len, "%s/%s.db.sig", server, db->treename);
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);
/* errors_ok suppresses error messages, but not the return code */
sig_ret = payload->errors_ok ? 0 : sig_ret;
}
} else if(!S_ISDIR(buf.st_mode)) {
_alpm_log(PM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath);
if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) {
free(dbfile);
free(syncpath);
RET_ERR(PM_ERR_SYSTEM, -1);
_alpm_dload_payload_free(payload);
if(ret != -1 && sig_ret != -1) {
break;
}
}
ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force);
free(dbfile);
free(syncpath);
umask(oldmask);
if(ret == 1) {
/* files match, do nothing */
pm_errno = 0;
return(1);
handle->pm_errno = 0;
goto cleanup;
} else if(ret == -1) {
/* pm_errno was set by the download code */
_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
return(-1);
_alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n",
alpm_strerror(handle->pm_errno));
goto cleanup;
}
/* Cache needs to be rebuilt */
_alpm_db_free_pkgcache(db);
return(0);
db->status &= ~DB_STATUS_VALID;
if(sync_db_validate(db)) {
/* pm_errno should be set */
ret = -1;
}
cleanup:
if(_alpm_handle_unlock(handle)) {
_alpm_log(handle, ALPM_LOG_WARNING, _("could not remove lock file %s\n"),
alpm_option_get_lockfile(handle));
}
free(syncpath);
umask(oldmask);
return ret;
}
/* Forward decl so I don't reorganize the whole file right now */
static int sync_db_read(pmdb_t *db, struct archive *archive,
struct archive_entry *entry, pmpkg_t *likely_pkg);
static int sync_db_read(alpm_db_t *db, struct archive *archive,
struct archive_entry *entry, alpm_pkg_t **likely_pkg);
static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
const char **entry_filename, alpm_pkg_t *likely_pkg)
{
char *pkgname = NULL, *pkgver = NULL;
unsigned long pkgname_hash;
alpm_pkg_t *pkg;
/* get package and db file names */
if(entry_filename) {
char *fname = strrchr(entryname, '/');
if(fname) {
*entry_filename = fname + 1;
} else {
*entry_filename = NULL;
}
}
if(_alpm_splitname(entryname, &pkgname, &pkgver, &pkgname_hash) != 0) {
_alpm_log(db->handle, ALPM_LOG_ERROR,
_("invalid name for database entry '%s'\n"), entryname);
return NULL;
}
if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) {
pkg = likely_pkg;
} else {
pkg = _alpm_pkghash_find(db->pkgcache, pkgname);
}
if(pkg == NULL) {
pkg = _alpm_pkg_new();
if(pkg == NULL) {
RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL);
}
pkg->name = pkgname;
pkg->version = pkgver;
pkg->name_hash = pkgname_hash;
pkg->origin = PKG_FROM_SYNCDB;
pkg->origin_data.db = db;
pkg->ops = &default_pkg_ops;
pkg->handle = db->handle;
/* add to the collection */
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename);
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);
} else {
free(pkgname);
free(pkgver);
}
return pkg;
}
/*
* This is the data table used to generate the estimating function below.
@@ -206,10 +365,10 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive)
/* assume it is at least somewhat compressed */
per_package = 200;
}
return((size_t)(st->st_size / per_package) + 1);
return (size_t)((st->st_size / per_package) + 1);
}
static int sync_db_populate(pmdb_t *db)
static int sync_db_populate(alpm_db_t *db)
{
const char *dbpath;
size_t est_count;
@@ -217,14 +376,10 @@ static int sync_db_populate(pmdb_t *db)
struct stat buf;
struct archive *archive;
struct archive_entry *entry;
pmpkg_t *pkg = NULL;
ALPM_LOG_FUNC;
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
alpm_pkg_t *pkg = NULL;
if((archive = archive_read_new()) == NULL) {
RET_ERR(PM_ERR_LIBARCHIVE, -1);
RET_ERR(db->handle, ALPM_ERR_LIBARCHIVE, -1);
}
archive_read_support_compression_all(archive);
@@ -236,24 +391,24 @@ static int sync_db_populate(pmdb_t *db)
return -1;
}
_alpm_log(PM_LOG_DEBUG, "opening database archive %s\n", dbpath);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "opening database archive %s\n", dbpath);
if(archive_read_open_filename(archive, dbpath,
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath,
_alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath,
archive_error_string(archive));
archive_read_finish(archive);
RET_ERR(PM_ERR_DB_OPEN, -1);
RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
}
if(stat(dbpath, &buf) != 0) {
RET_ERR(PM_ERR_DB_OPEN, -1);
RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
}
est_count = estimate_package_count(&buf, archive);
/* initialize hash at 66% full */
db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2);
if(db->pkgcache == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
}
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
@@ -262,139 +417,96 @@ static int sync_db_populate(pmdb_t *db)
st = archive_entry_stat(entry);
if(S_ISDIR(st->st_mode)) {
const char *name;
pkg = _alpm_pkg_new();
if(pkg == NULL) {
archive_read_finish(archive);
RET_ERR(PM_ERR_MEMORY, -1);
}
name = archive_entry_pathname(entry);
if(_alpm_splitname(name, pkg) != 0) {
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
name);
_alpm_pkg_free(pkg);
continue;
}
/* duplicated database entries are not allowed */
if(_alpm_pkghash_find(db->pkgcache, pkg->name)) {
_alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name);
_alpm_pkg_free(pkg);
continue;
}
pkg->origin = PKG_FROM_SYNCDB;
pkg->ops = &default_pkg_ops;
pkg->origin_data.db = db;
/* add to the collection */
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename);
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);
count++;
continue;
} else {
/* we have desc, depends or deltas - parse it */
sync_db_read(db, archive, entry, pkg);
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);
continue;
}
}
}
count = alpm_list_count(db->pkgcache->list);
if(count > 0) {
db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp);
}
archive_read_finish(archive);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n",
count, db->treename);
return(count);
return count;
}
#define READ_NEXT(s) do { \
#define READ_NEXT() do { \
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
s = _alpm_strtrim(buf.line); \
line = buf.line; \
_alpm_strip_newline(line); \
} while(0)
#define READ_AND_STORE(f) do { \
READ_NEXT(line); \
READ_NEXT(); \
STRDUP(f, line, goto error); \
} while(0)
#define READ_AND_STORE_ALL(f) do { \
char *linedup; \
READ_NEXT(line); \
if(strlen(line) == 0) break; \
STRDUP(linedup, line, goto error); \
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
if(_alpm_strip_newline(buf.line) == 0) break; \
STRDUP(linedup, buf.line, goto error); \
f = alpm_list_add(f, linedup); \
} while(1) /* note the while(1) and not (0) */
static int sync_db_read(pmdb_t *db, struct archive *archive,
struct archive_entry *entry, pmpkg_t *likely_pkg)
static int sync_db_read(alpm_db_t *db, struct archive *archive,
struct archive_entry *entry, alpm_pkg_t **likely_pkg)
{
const char *entryname = NULL, *filename;
char *pkgname, *p, *q;
pmpkg_t *pkg;
const char *entryname, *filename;
alpm_pkg_t *pkg;
struct archive_read_buffer buf;
ALPM_LOG_FUNC;
if(db == NULL) {
RET_ERR(PM_ERR_DB_NULL, -1);
}
if(entry != NULL) {
entryname = archive_entry_pathname(entry);
}
entryname = archive_entry_pathname(entry);
if(entryname == NULL) {
_alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n");
return(-1);
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"invalid archive entry provided to _alpm_sync_db_read, skipping\n");
return -1;
}
_alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n",
_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;
/* get package and db file names */
STRDUP(pkgname, entryname, RET_ERR(PM_ERR_MEMORY, -1));
p = pkgname + strlen(pkgname);
for(q = --p; *q && *q != '/'; q--);
filename = q + 1;
for(p = --q; *p && *p != '-'; p--);
for(q = --p; *q && *q != '-'; q--);
*q = '\0';
pkg = load_pkg_for_entry(db, entryname, &filename, *likely_pkg);
/* package is already in db due to parsing of directory name */
if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) {
pkg = likely_pkg;
} else {
if(db->pkgcache == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
pkg = _alpm_pkghash_find(db->pkgcache, pkgname);
}
if(pkg == NULL) {
_alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database",
pkgname, db->treename);
return(-1);
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"entry %s could not be loaded into %s sync database",
entryname, db->treename);
return -1;
}
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|| strcmp(filename, "deltas") == 0) {
while(_alpm_archive_fgets(archive, &buf) == ARCHIVE_OK) {
char *line = _alpm_strtrim(buf.line);
int ret;
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
char *line = buf.line;
_alpm_strip_newline(line);
if(strcmp(line, "%NAME%") == 0) {
READ_NEXT(line);
READ_NEXT();
if(strcmp(line, pkg->name) != 0) {
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name "
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: name "
"mismatch on package %s\n"), db->treename, pkg->name);
}
} else if(strcmp(line, "%VERSION%") == 0) {
READ_NEXT(line);
READ_NEXT();
if(strcmp(line, pkg->version) != 0) {
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version "
"mismatch on package %s\n"), db->treename, pkg->name);
}
} else if(strcmp(line, "%FILENAME%") == 0) {
@@ -410,7 +522,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
} else if(strcmp(line, "%ARCH%") == 0) {
READ_AND_STORE(pkg->arch);
} else if(strcmp(line, "%BUILDDATE%") == 0) {
READ_NEXT(line);
READ_NEXT();
pkg->builddate = _alpm_parsedate(line);
} else if(strcmp(line, "%PACKAGER%") == 0) {
READ_AND_STORE(pkg->packager);
@@ -419,29 +531,28 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
* pkginfo_t struct. This can be done b/c CSIZE is currently only used
* in sync databases, and SIZE is only used in local databases.
*/
READ_NEXT(line);
READ_NEXT();
pkg->size = atol(line);
/* also store this value to isize if isize is unset */
if(pkg->isize == 0) {
pkg->isize = pkg->size;
}
} else if(strcmp(line, "%ISIZE%") == 0) {
READ_NEXT(line);
READ_NEXT();
pkg->isize = atol(line);
} else if(strcmp(line, "%MD5SUM%") == 0) {
READ_AND_STORE(pkg->md5sum);
} else if(strcmp(line, "%SHA256SUM%") == 0) {
/* we don't do anything with this value right now */
READ_NEXT(line);
READ_NEXT();
} else if(strcmp(line, "%PGPSIG%") == 0) {
/* we don't do anything with this value right now */
READ_NEXT(line);
READ_AND_STORE(pkg->base64_sig);
} else if(strcmp(line, "%REPLACES%") == 0) {
READ_AND_STORE_ALL(pkg->replaces);
} else if(strcmp(line, "%DEPENDS%") == 0) {
/* Different than the rest because of the _alpm_splitdep call. */
while(1) {
READ_NEXT(line);
READ_NEXT();
if(strlen(line) == 0) break;
pkg->depends = alpm_list_add(pkg->depends, _alpm_splitdep(line));
}
@@ -454,62 +565,61 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
} else if(strcmp(line, "%DELTAS%") == 0) {
/* Different than the rest because of the _alpm_delta_parse call. */
while(1) {
READ_NEXT(line);
READ_NEXT();
if(strlen(line) == 0) break;
pkg->deltas = alpm_list_add(pkg->deltas, _alpm_delta_parse(line));
}
}
}
if(ret != ARCHIVE_EOF) {
goto error;
}
*likely_pkg = pkg;
} else if(strcmp(filename, "files") == 0) {
/* currently do nothing with this file */
} else {
/* unknown database file */
_alpm_log(PM_LOG_DEBUG, "unknown database file: %s\n", filename);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename);
}
error:
FREE(pkgname);
/* TODO: return 0 always? */
return(0);
}
return 0;
static int sync_db_version(pmdb_t *db)
{
return(2);
error:
_alpm_log(db->handle, ALPM_LOG_DEBUG, "error parsing database file: %s\n", filename);
return -1;
}
struct db_operations sync_db_ops = {
.validate = sync_db_validate,
.populate = sync_db_populate,
.unregister = _alpm_db_unregister,
.version = sync_db_version,
};
pmdb_t *_alpm_db_register_sync(const char *treename)
alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
alpm_siglevel_t level)
{
pmdb_t *db;
alpm_list_t *i;
alpm_db_t *db;
ALPM_LOG_FUNC;
_alpm_log(handle, ALPM_LOG_DEBUG, "registering sync database '%s'\n", treename);
for(i = handle->dbs_sync; i; i = i->next) {
pmdb_t *sdb = i->data;
if(strcmp(treename, sdb->treename) == 0) {
_alpm_log(PM_LOG_DEBUG, "attempt to re-register the '%s' database, using existing\n", sdb->treename);
return sdb;
}
#ifndef HAVE_LIBGPGME
if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL);
}
_alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename);
#endif
db = _alpm_db_new(treename, 0);
if(db == NULL) {
RET_ERR(PM_ERR_DB_CREATE, NULL);
RET_ERR(handle, ALPM_ERR_DB_CREATE, NULL);
}
db->ops = &sync_db_ops;
db->handle = handle;
db->siglevel = level;
sync_db_validate(db);
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
return(db);
return db;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -34,29 +34,30 @@
/* libalpm */
#include "conflict.h"
#include "alpm_list.h"
#include "alpm.h"
#include "handle.h"
#include "trans.h"
#include "util.h"
#include "log.h"
#include "deps.h"
pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2,
static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2,
const char *reason)
{
pmconflict_t *conflict;
alpm_conflict_t *conflict;
ALPM_LOG_FUNC;
MALLOC(conflict, sizeof(alpm_conflict_t), return NULL);
MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
conflict->package1_hash = pkg1->name_hash;
conflict->package2_hash = pkg2->name_hash;
STRDUP(conflict->package1, pkg1->name, return NULL);
STRDUP(conflict->package2, pkg2->name, return NULL);
STRDUP(conflict->reason, reason, return NULL);
STRDUP(conflict->package1, package1, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(conflict->reason, reason, RET_ERR(PM_ERR_MEMORY, NULL));
return(conflict);
return conflict;
}
void _alpm_conflict_free(pmconflict_t *conflict)
void _alpm_conflict_free(alpm_conflict_t *conflict)
{
FREE(conflict->package2);
FREE(conflict->package1);
@@ -64,55 +65,58 @@ void _alpm_conflict_free(pmconflict_t *conflict)
FREE(conflict);
}
pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict)
alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict)
{
pmconflict_t *newconflict;
CALLOC(newconflict, 1, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
alpm_conflict_t *newconflict;
CALLOC(newconflict, 1, sizeof(alpm_conflict_t), return NULL);
STRDUP(newconflict->package1, conflict->package1, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(newconflict->reason, conflict->reason, RET_ERR(PM_ERR_MEMORY, NULL));
newconflict->package1_hash = conflict->package1_hash;
newconflict->package2_hash = conflict->package2_hash;
STRDUP(newconflict->package1, conflict->package1, return NULL);
STRDUP(newconflict->package2, conflict->package2, return NULL);
STRDUP(newconflict->reason, conflict->reason, return NULL);
return(newconflict);
return newconflict;
}
static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack)
static int conflict_isin(alpm_conflict_t *needle, alpm_list_t *haystack)
{
alpm_list_t *i;
const char *npkg1 = needle->package1;
const char *npkg2 = needle->package2;
ALPM_LOG_FUNC;
for(i = haystack; i; i = i->next) {
pmconflict_t *conflict = i->data;
const char *cpkg1 = conflict->package1;
const char *cpkg2 = conflict->package2;
if((strcmp(cpkg1, npkg1) == 0 && strcmp(cpkg2, npkg2) == 0)
|| (strcmp(cpkg1, npkg2) == 0 && strcmp(cpkg2, npkg1) == 0)) {
return(1);
alpm_conflict_t *conflict = i->data;
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;
}
}
return(0);
return 0;
}
/** Adds the pkg1/pkg2 conflict to the baddeps list
* @param *baddeps list to add conflict to
/** Adds the pkg1/pkg2 conflict to the baddeps list.
* @param handle the context handle
* @param baddeps list to add conflict to
* @param pkg1 first package
* @param pkg2 package causing conflict
* @param reason reason for this conflict
*/
static void add_conflict(alpm_list_t **baddeps, const char *pkg1,
const char *pkg2, const char *reason)
static int add_conflict(alpm_handle_t *handle, alpm_list_t **baddeps,
alpm_pkg_t *pkg1, alpm_pkg_t *pkg2, const char *reason)
{
pmconflict_t *conflict = _alpm_conflict_new(pkg1, pkg2, reason);
_alpm_log(PM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",
pkg1, pkg2, reason);
if(conflict && !conflict_isin(conflict, *baddeps)) {
alpm_conflict_t *conflict = conflict_new(pkg1, pkg2, reason);
if(!conflict) {
return -1;
}
_alpm_log(handle, ALPM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",
pkg1->name, pkg2->name, reason);
if(!conflict_isin(conflict, *baddeps)) {
*baddeps = alpm_list_add(*baddeps, conflict);
} else {
_alpm_conflict_free(conflict);
}
return 0;
}
/** Check if packages from list1 conflict with packages from list2.
@@ -121,40 +125,43 @@ static void add_conflict(alpm_list_t **baddeps, const char *pkg1,
* If a conflict (pkg1, pkg2) is found, it is added to the baddeps list
* in this order if order >= 0, or reverse order (pkg2,pkg1) otherwise.
*
* @param handle the context handle
* @param list1 first list of packages
* @param list2 second list of packages
* @param *baddeps list to store conflicts
* @param baddeps list to store conflicts
* @param order if >= 0 the conflict order is preserved, if < 0 it's reversed
*/
static void check_conflict(alpm_list_t *list1, alpm_list_t *list2,
static void check_conflict(alpm_handle_t *handle,
alpm_list_t *list1, alpm_list_t *list2,
alpm_list_t **baddeps, int order) {
alpm_list_t *i, *j, *k;
alpm_list_t *i;
if(!baddeps) {
return;
}
for(i = list1; i; i = i->next) {
pmpkg_t *pkg1 = i->data;
const char *pkg1name = alpm_pkg_get_name(pkg1);
alpm_pkg_t *pkg1 = i->data;
alpm_list_t *j;
for(j = alpm_pkg_get_conflicts(pkg1); j; j = j->next) {
const char *conflict = j->data;
pmdepend_t *parsed_conflict = _alpm_splitdep(conflict);
alpm_list_t *k;
alpm_depend_t *parsed_conflict = _alpm_splitdep(conflict);
for(k = list2; k; k = k->next) {
pmpkg_t *pkg2 = k->data;
const char *pkg2name = alpm_pkg_get_name(pkg2);
alpm_pkg_t *pkg2 = k->data;
if(strcmp(pkg1name, pkg2name) == 0) {
if(pkg1->name_hash == pkg2->name_hash
&& strcmp(pkg1->name, pkg2->name) == 0) {
/* skip the package we're currently processing */
continue;
}
if(_alpm_depcmp(pkg2, parsed_conflict)) {
if(order >= 0) {
add_conflict(baddeps, pkg1name, pkg2name, conflict);
add_conflict(handle, baddeps, pkg1, pkg2, conflict);
} else {
add_conflict(baddeps, pkg2name, pkg1name, conflict);
add_conflict(handle, baddeps, pkg2, pkg1, conflict);
}
}
}
@@ -164,189 +171,183 @@ static void check_conflict(alpm_list_t *list1, alpm_list_t *list2,
}
/* Check for inter-conflicts */
alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages)
alpm_list_t *_alpm_innerconflicts(alpm_handle_t *handle, alpm_list_t *packages)
{
alpm_list_t *baddeps = NULL;
ALPM_LOG_FUNC;
_alpm_log(handle, ALPM_LOG_DEBUG, "check targets vs targets\n");
check_conflict(handle, packages, packages, &baddeps, 0);
_alpm_log(PM_LOG_DEBUG, "check targets vs targets\n");
check_conflict(packages, packages, &baddeps, 0);
return(baddeps);
return baddeps;
}
/* Check for target vs (db - target) conflicts
* In case of conflict the package1 field of pmdepconflict_t contains
* the target package, package2 field contains the local package
*/
alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages)
alpm_list_t *_alpm_outerconflicts(alpm_db_t *db, alpm_list_t *packages)
{
alpm_list_t *baddeps = NULL;
ALPM_LOG_FUNC;
if(db == NULL) {
return(NULL);
return NULL;
}
alpm_list_t *dblist = alpm_list_diff(_alpm_db_get_pkgcache(db),
packages, _alpm_pkg_cmp);
/* two checks to be done here for conflicts */
_alpm_log(PM_LOG_DEBUG, "check targets vs db\n");
check_conflict(packages, dblist, &baddeps, 1);
_alpm_log(PM_LOG_DEBUG, "check db vs targets\n");
check_conflict(dblist, packages, &baddeps, -1);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "check targets vs db\n");
check_conflict(db->handle, packages, dblist, &baddeps, 1);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "check db vs targets\n");
check_conflict(db->handle, dblist, packages, &baddeps, -1);
alpm_list_free(dblist);
return(baddeps);
return baddeps;
}
/** 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 pmconflict_t
* @return an alpm_list_t of alpm_conflict_t
*/
alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_list_t *pkglist) {
return(_alpm_innerconflicts(pkglist));
alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_handle_t *handle,
alpm_list_t *pkglist)
{
CHECK_HANDLE(handle, return NULL);
return _alpm_innerconflicts(handle, pkglist);
}
/* Returns a alpm_list_t* of file conflicts.
* Hooray for set-intersects!
* Pre-condition: both lists are sorted!
static const int DIFFERENCE = 0;
static const int INTERSECT = 1;
/* Returns a set operation on the provided two lists of files.
* Pre-condition: both lists are sorted!
* When done, free the list but NOT the contained data.
*
* Operations:
* DIFFERENCE - a difference operation is performed. filesA - filesB.
* INTERSECT - an intersection operation is performed. filesA & filesB.
*/
static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB)
static alpm_list_t *filelist_operation(alpm_filelist_t *filesA,
alpm_filelist_t *filesB, int operation)
{
alpm_list_t *ret = NULL;
alpm_list_t *pA = filesA, *pB = filesB;
size_t ctrA = 0, ctrB = 0;
while(pA && pB) {
const char *strA = pA->data;
const char *strB = pB->data;
/* skip directories, we don't care about dir conflicts */
while(ctrA < filesA->count && ctrB < filesB->count) {
alpm_file_t *fileA = filesA->files + ctrA;
alpm_file_t *fileB = filesB->files + ctrB;
const char *strA = fileA->name;
const char *strB = fileB->name;
/* skip directories, we don't care about them */
if(strA[strlen(strA)-1] == '/') {
pA = pA->next;
ctrA++;
} else if(strB[strlen(strB)-1] == '/') {
pB = pB->next;
ctrB++;
} else {
int cmp = strcmp(strA, strB);
if(cmp < 0) {
/* item only in filesA, ignore it */
pA = pA->next;
if(operation == DIFFERENCE) {
/* item only in filesA, qualifies as a difference */
ret = alpm_list_add(ret, fileA);
}
ctrA++;
} else if(cmp > 0) {
/* item only in filesB, ignore it */
pB = pB->next;
ctrB++;
} else {
/* item in both, record it */
ret = alpm_list_add(ret, strdup(strA));
pA = pA->next;
pB = pB->next;
if(operation == INTERSECT) {
/* item in both, qualifies as an intersect */
ret = alpm_list_add(ret, fileA);
}
ctrA++;
ctrB++;
}
}
}
return(ret);
}
/* Returns a alpm_list_t* of files that are in filesA but *NOT* in filesB
* This is an 'A minus B' set operation
* Pre-condition: both lists are sorted!
*/
static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB)
{
alpm_list_t *ret = NULL;
alpm_list_t *pA = filesA, *pB = filesB;
/* if both filesA and filesB have entries, do this loop */
while(pA && pB) {
const char *strA = pA->data;
const char *strB = pB->data;
/* skip directories, we don't care about dir conflicts */
if(strA[strlen(strA)-1] == '/') {
pA = pA->next;
} else if(strB[strlen(strB)-1] == '/') {
pB = pB->next;
} else {
int cmp = strcmp(strA, strB);
if(cmp < 0) {
/* item only in filesA, record it */
ret = alpm_list_add(ret, strdup(strA));
pA = pA->next;
} else if(cmp > 0) {
/* item only in fileB, but this means nothing */
pB = pB->next;
} else {
/* item in both, ignore it */
pA = pA->next;
pB = pB->next;
}
}
}
/* ensure we have completely emptied pA */
while(pA) {
const char *strA = pA->data;
/* if doing a difference, ensure we have completely emptied pA */
while(operation == DIFFERENCE && ctrA < filesA->count) {
alpm_file_t *fileA = filesA->files + ctrA;
const char *strA = fileA->name;
/* skip directories */
if(strA[strlen(strA)-1] != '/') {
ret = alpm_list_add(ret, strdup(strA));
ret = alpm_list_add(ret, fileA);
}
pA = pA->next;
ctrA++;
}
return(ret);
return ret;
}
/* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type
* (either PM_FILECONFLICT_TARGET or PM_FILECONFLICT_FILESYSTEM), a file
/* Adds alpm_fileconflict_t to a conflicts list. Pass the conflicts list, type
* (either ALPM_FILECONFLICT_TARGET or ALPM_FILECONFLICT_FILESYSTEM), a file
* string, and either two package names or one package name and NULL. This is
* a wrapper for former functionality that was done inline.
*/
static alpm_list_t *add_fileconflict(alpm_list_t *conflicts,
pmfileconflicttype_t type, const char *filestr,
const char *name1, const char *name2)
static alpm_list_t *add_fileconflict(alpm_handle_t *handle,
alpm_list_t *conflicts, alpm_fileconflicttype_t type, const char *filestr,
const char *name1, const char *name2)
{
pmfileconflict_t *conflict;
MALLOC(conflict, sizeof(pmfileconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
alpm_fileconflict_t *conflict;
MALLOC(conflict, sizeof(alpm_fileconflict_t), goto error);
conflict->type = type;
STRDUP(conflict->target, name1, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(conflict->file, filestr, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(conflict->target, name1, goto error);
STRDUP(conflict->file, filestr, goto error);
if(name2) {
STRDUP(conflict->ctarget, name2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(conflict->ctarget, name2, goto error);
} else {
conflict->ctarget = "";
STRDUP(conflict->ctarget, "", goto error);
}
conflicts = alpm_list_add(conflicts, conflict);
_alpm_log(PM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n",
filestr, name1, name2 ? name2 : "(filesystem)");
return(conflicts);
return conflicts;
error:
RET_ERR(handle, ALPM_ERR_MEMORY, conflicts);
}
void _alpm_fileconflict_free(pmfileconflict_t *conflict)
void _alpm_fileconflict_free(alpm_fileconflict_t *conflict)
{
if(strlen(conflict->ctarget) > 0) {
FREE(conflict->ctarget);
}
FREE(conflict->file);;
FREE(conflict->ctarget);
FREE(conflict->file);
FREE(conflict->target);
FREE(conflict);
}
static int dir_belongsto_pkg(const char *dirpath, pmpkg_t *pkg)
const alpm_file_t *_alpm_filelist_contains(alpm_filelist_t *filelist,
const char *name)
{
size_t i;
const alpm_file_t *file = filelist->files;
for(i = 0; i < filelist->count; i++) {
if(strcmp(file->name, name) == 0) {
return file;
}
file++;
}
return NULL;
}
static int dir_belongsto_pkg(const char *root, const char *dirpath,
alpm_pkg_t *pkg)
{
struct dirent *ent = NULL;
struct stat sbuf;
char path[PATH_MAX];
char abspath[PATH_MAX];
struct dirent *ent = NULL;
DIR *dir;
snprintf(abspath, PATH_MAX, "%s%s", handle->root, dirpath);
snprintf(abspath, PATH_MAX, "%s%s", root, dirpath);
dir = opendir(abspath);
if(dir == NULL) {
return(1);
return 1;
}
while((ent = readdir(dir)) != NULL) {
const char *name = ent->d_name;
@@ -354,44 +355,43 @@ static int dir_belongsto_pkg(const char *dirpath, pmpkg_t *pkg)
continue;
}
snprintf(path, PATH_MAX, "%s/%s", dirpath, name);
snprintf(abspath, PATH_MAX, "%s%s", handle->root, path);
snprintf(abspath, PATH_MAX, "%s%s", root, path);
if(stat(abspath, &sbuf) != 0) {
continue;
}
if(S_ISDIR(sbuf.st_mode)) {
if(dir_belongsto_pkg(path, pkg)) {
if(dir_belongsto_pkg(root, path, pkg)) {
continue;
} else {
closedir(dir);
return(0);
return 0;
}
} else {
if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) {
if(_alpm_filelist_contains(alpm_pkg_get_files(pkg), path)) {
continue;
} else {
closedir(dir);
return(0);
return 0;
}
}
}
closedir(dir);
return(1);
return 1;
}
/* Find file conflicts that may occur during the transaction with two checks:
* 1: check every target against every target
* 2: check every target against the filesystem */
alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
alpm_list_t *upgrade, alpm_list_t *remove)
{
alpm_list_t *i, *j, *conflicts = NULL;
alpm_list_t *i, *conflicts = NULL;
size_t numtargs = alpm_list_count(upgrade);
size_t current;
alpm_trans_t *trans = handle->trans;
ALPM_LOG_FUNC;
if(db == NULL || upgrade == NULL || trans == NULL) {
return(NULL);
if(!upgrade) {
return NULL;
}
/* TODO this whole function needs a huge change, which hopefully will
@@ -399,61 +399,75 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
* here as we do when we actually extract files in add.c with our 12
* different cases. */
for(current = 0, i = upgrade; i; i = i->next, current++) {
alpm_list_t *k, *tmpfiles = NULL;
pmpkg_t *p1, *p2, *dbpkg;
char path[PATH_MAX+1];
p1 = i->data;
if(!p1) {
continue;
}
alpm_pkg_t *p1 = i->data;
alpm_list_t *j;
alpm_filelist_t tmpfiles;
alpm_pkg_t *dbpkg;
size_t filenum;
int percent = (current * 100) / numtargs;
PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", percent,
PROGRESS(trans, ALPM_TRANS_PROGRESS_CONFLICTS_START, "", percent,
numtargs, current);
/* CHECK 1: check every target against every target */
_alpm_log(PM_LOG_DEBUG, "searching for file conflicts: %s\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "searching for file conflicts: %s\n",
alpm_pkg_get_name(p1));
for(j = i->next; j; j = j->next) {
p2 = j->data;
if(!p2) {
continue;
}
tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2));
alpm_list_t *common_files;
alpm_pkg_t *p2 = j->data;
common_files = filelist_operation(alpm_pkg_get_files(p1),
alpm_pkg_get_files(p2), INTERSECT);
if(tmpfiles) {
for(k = tmpfiles; k; k = k->next) {
if(common_files) {
alpm_list_t *k;
char path[PATH_MAX];
for(k = common_files; k; k = k->next) {
snprintf(path, PATH_MAX, "%s%s", handle->root, (char *)k->data);
conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_TARGET, path,
conflicts = add_fileconflict(handle, conflicts,
ALPM_FILECONFLICT_TARGET, path,
alpm_pkg_get_name(p1), alpm_pkg_get_name(p2));
if(handle->pm_errno == ALPM_ERR_MEMORY) {
FREELIST(conflicts);
FREELIST(common_files);
return NULL;
}
}
FREELIST(tmpfiles);
alpm_list_free(common_files);
}
}
/* declarations for second check */
struct stat lsbuf, sbuf;
/* CHECK 2: check every target against the filesystem */
_alpm_log(PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", p1->name);
dbpkg = _alpm_db_get_pkgfromcache(db, p1->name);
_alpm_log(handle, ALPM_LOG_DEBUG, "searching for filesystem conflicts: %s\n",
p1->name);
dbpkg = _alpm_db_get_pkgfromcache(handle->db_local, p1->name);
/* Do two different checks here. If the package is currently installed,
* then only check files that are new in the new package. If the package
* is not currently installed, then simply stat the whole filelist */
* is not currently installed, then simply stat the whole filelist. Note
* that the former list needs to be freed while the latter list should NOT
* be freed. */
if(dbpkg) {
alpm_list_t *difference;
/* older ver of package currently installed */
tmpfiles = chk_filedifference(alpm_pkg_get_files(p1),
alpm_pkg_get_files(dbpkg));
difference = filelist_operation(alpm_pkg_get_files(p1),
alpm_pkg_get_files(dbpkg), DIFFERENCE);
tmpfiles.count = alpm_list_count(difference);
tmpfiles.files = alpm_list_to_array(difference, tmpfiles.count,
sizeof(alpm_file_t));
alpm_list_free(difference);
} else {
/* no version of package currently installed */
tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1));
tmpfiles = *alpm_pkg_get_files(p1);
}
for(j = tmpfiles; j; j = j->next) {
const char *filestr = j->data, *relative_path;
for(filenum = 0; filenum < tmpfiles.count; filenum++) {
alpm_file_t *file = tmpfiles.files + filenum;
const char *filestr = file->name;
const char *relative_path;
alpm_list_t *k;
/* have we acted on this conflict? */
int resolved_conflict = 0;
struct stat lsbuf;
char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s%s", handle->root, filestr);
@@ -461,14 +475,16 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
if(_alpm_lstat(path, &lsbuf) != 0) {
continue;
}
stat(path, &sbuf);
if(path[strlen(path) - 1] == '/') {
if(S_ISDIR(file->mode)) {
struct stat sbuf;
if(S_ISDIR(lsbuf.st_mode)) {
_alpm_log(PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path);
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is a directory, not a conflict\n", path);
continue;
} else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) {
_alpm_log(PM_LOG_DEBUG,
}
stat(path, &sbuf);
if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"%s is a symlink to a dir, hopefully not a conflict\n", path);
continue;
}
@@ -478,38 +494,37 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
path[strlen(path) - 1] = '\0';
}
_alpm_log(PM_LOG_DEBUG, "checking possible conflict: %s\n", path);
_alpm_log(handle, ALPM_LOG_DEBUG, "checking possible conflict: %s\n", path);
relative_path = path + strlen(handle->root);
/* Check remove list (will we remove the conflicting local file?) */
for(k = remove; k && !resolved_conflict; k = k->next) {
pmpkg_t *rempkg = k->data;
if(alpm_list_find_str(alpm_pkg_get_files(rempkg), relative_path)) {
_alpm_log(PM_LOG_DEBUG,
"local file will be removed, not a conflict: %s\n",
relative_path);
alpm_pkg_t *rempkg = k->data;
if(rempkg && _alpm_filelist_contains(alpm_pkg_get_files(rempkg),
relative_path)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"local file will be removed, not a conflict: %s\n", path);
resolved_conflict = 1;
}
}
/* Look at all the targets to see if file has changed hands */
for(k = upgrade; k && !resolved_conflict; k = k->next) {
p2 = k->data;
alpm_pkg_t *p2 = k->data;
if(!p2 || strcmp(p1->name, p2->name) == 0) {
continue;
}
pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name);
alpm_pkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name);
/* localp2->files will be removed (target conflicts are handled by CHECK 1) */
if(localp2 && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) {
if(localp2 && _alpm_filelist_contains(alpm_pkg_get_files(localp2), filestr)) {
/* skip removal of file, but not add. this will prevent a second
* package from removing the file when it was already installed
* by its new owner (whether the file is in backup array or not */
trans->skip_remove = alpm_list_add(trans->skip_remove,
strdup(filestr));
_alpm_log(PM_LOG_DEBUG,
"file changed packages, adding to remove skiplist: %s\n",
filestr);
handle->trans->skip_remove =
alpm_list_add(handle->trans->skip_remove, strdup(filestr));
_alpm_log(handle, ALPM_LOG_DEBUG,
"file changed packages, adding to remove skiplist: %s\n", path);
resolved_conflict = 1;
}
}
@@ -518,115 +533,67 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
if(!resolved_conflict && S_ISDIR(lsbuf.st_mode) && dbpkg) {
char *dir = malloc(strlen(filestr) + 2);
sprintf(dir, "%s/", filestr);
if(alpm_list_find_str(alpm_pkg_get_files(dbpkg),dir)) {
_alpm_log(PM_LOG_DEBUG, "check if all files in %s belongs to %s\n",
if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"check if all files in %s belongs to %s\n",
dir, dbpkg->name);
resolved_conflict = dir_belongsto_pkg(filestr, dbpkg);
resolved_conflict = dir_belongsto_pkg(handle->root, filestr, dbpkg);
}
free(dir);
}
if(!resolved_conflict && dbpkg) {
char *rpath = calloc(PATH_MAX+1, sizeof(char));
char *rpath = calloc(PATH_MAX, sizeof(char));
const char *relative_rpath;
if(!realpath(path, rpath)) {
free(rpath);
continue;
}
relative_rpath = rpath + strlen(handle->root);
if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), relative_rpath)) {
if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) {
resolved_conflict = 1;
}
free(rpath);
}
/* is the file unowned and in the backup list of the new package? */
if(!resolved_conflict && _alpm_needbackup(filestr, p1)) {
alpm_list_t *local_pkgs = _alpm_db_get_pkgcache(handle->db_local);
int found = 0;
for(k = local_pkgs; k && !found; k = k->next) {
if(_alpm_filelist_contains(alpm_pkg_get_files(k->data), filestr)) {
found = 1;
}
}
if(!found) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"file was unowned but in new backup list: %s\n", path);
resolved_conflict = 1;
}
}
if(!resolved_conflict) {
conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_FILESYSTEM,
path, p1->name, NULL);
conflicts = add_fileconflict(handle, conflicts,
ALPM_FILECONFLICT_FILESYSTEM, path, p1->name, NULL);
if(handle->pm_errno == ALPM_ERR_MEMORY) {
FREELIST(conflicts);
if(dbpkg) {
/* only freed if it was generated from filelist_operation() */
free(tmpfiles.files);
}
return NULL;
}
}
}
FREELIST(tmpfiles);
if(dbpkg) {
/* only freed if it was generated from filelist_operation() */
free(tmpfiles.files);
}
}
PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", 100,
PROGRESS(trans, ALPM_TRANS_PROGRESS_CONFLICTS_START, "", 100,
numtargs, current);
return(conflicts);
return conflicts;
}
const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(conflict != NULL, return(NULL));
return conflict->package1;
}
const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(conflict != NULL, return(NULL));
return conflict->package2;
}
const char SYMEXPORT *alpm_conflict_get_reason(pmconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(conflict != NULL, return(NULL));
return conflict->reason;
}
const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(conflict != NULL, return(NULL));
return conflict->target;
}
pmfileconflicttype_t SYMEXPORT alpm_fileconflict_get_type(pmfileconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(-1));
ASSERT(conflict != NULL, return(-1));
return conflict->type;
}
const char SYMEXPORT *alpm_fileconflict_get_file(pmfileconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(conflict != NULL, return(NULL));
return conflict->file;
}
const char SYMEXPORT *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(conflict != NULL, return(NULL));
return conflict->ctarget;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -24,28 +24,17 @@
#include "db.h"
#include "package.h"
struct __pmconflict_t {
char *package1;
char *package2;
char *reason;
};
alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict);
void _alpm_conflict_free(alpm_conflict_t *conflict);
alpm_list_t *_alpm_innerconflicts(alpm_handle_t *handle, alpm_list_t *packages);
alpm_list_t *_alpm_outerconflicts(alpm_db_t *db, alpm_list_t *packages);
alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
alpm_list_t *upgrade, alpm_list_t *remove);
struct __pmfileconflict_t {
char *target;
pmfileconflicttype_t type;
char *file;
char *ctarget;
};
void _alpm_fileconflict_free(alpm_fileconflict_t *conflict);
pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, const char *reason);
pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict);
void _alpm_conflict_free(pmconflict_t *conflict);
alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages);
alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages);
alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,
alpm_list_t *upgrade, alpm_list_t *remove);
void _alpm_fileconflict_free(pmfileconflict_t *conflict);
const alpm_file_t *_alpm_filelist_contains(alpm_filelist_t *filelist,
const char *name);
#endif /* _ALPM_CONFLICT_H */

View File

@@ -26,11 +26,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <regex.h>
#include <time.h>
/* libalpm */
#include "db.h"
@@ -48,42 +45,40 @@
*/
/** Register a sync database of packages. */
pmdb_t SYMEXPORT *alpm_db_register_sync(const char *treename)
alpm_db_t SYMEXPORT *alpm_db_register_sync(alpm_handle_t *handle,
const char *treename, alpm_siglevel_t level)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, NULL));
ASSERT(treename != NULL && strlen(treename) != 0, RET_ERR(PM_ERR_WRONG_ARGS, NULL));
CHECK_HANDLE(handle, return NULL);
ASSERT(treename != NULL && strlen(treename) != 0,
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL));
/* Do not register a database if a transaction is on-going */
ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL));
ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, NULL));
return(_alpm_db_register_sync(treename));
return _alpm_db_register_sync(handle, treename, level);
}
/* Helper function for alpm_db_unregister{_all} */
void _alpm_db_unregister(pmdb_t *db)
void _alpm_db_unregister(alpm_db_t *db)
{
if(db == NULL) {
return;
}
_alpm_log(PM_LOG_DEBUG, "unregistering database '%s'\n", db->treename);
_alpm_log(db->handle, ALPM_LOG_DEBUG, "unregistering database '%s'\n", db->treename);
_alpm_db_free(db);
}
/** Unregister all package databases. */
int SYMEXPORT alpm_db_unregister_all(void)
int SYMEXPORT alpm_db_unregister_all(alpm_handle_t *handle)
{
alpm_list_t *i;
pmdb_t *db;
ALPM_LOG_FUNC;
alpm_db_t *db;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(handle, return -1);
/* Do not unregister a database if a transaction is on-going */
ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, -1));
/* unregister all sync dbs */
for(i = handle->dbs_sync; i; i = i->next) {
@@ -92,21 +87,21 @@ int SYMEXPORT alpm_db_unregister_all(void)
i->data = NULL;
}
FREELIST(handle->dbs_sync);
return(0);
return 0;
}
/** Unregister a package database. */
int SYMEXPORT alpm_db_unregister(pmdb_t *db)
int SYMEXPORT alpm_db_unregister(alpm_db_t *db)
{
int found = 0;
ALPM_LOG_FUNC;
alpm_handle_t *handle;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(db != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
ASSERT(db != NULL, return -1);
/* Do not unregister a database if a transaction is on-going */
ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
handle = db->handle;
handle->pm_errno = 0;
ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, -1));
if(db == handle->db_local) {
handle->db_local = NULL;
@@ -125,196 +120,219 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db)
}
if(!found) {
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
RET_ERR(handle, ALPM_ERR_DB_NOT_FOUND, -1);
}
db->ops->unregister(db);
return(0);
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_setserver(pmdb_t *db, const char *url)
int SYMEXPORT alpm_db_set_servers(alpm_db_t *db, alpm_list_t *servers)
{
alpm_list_t *i;
int found = 0;
char *newurl;
size_t len = 0;
ASSERT(db != NULL, return -1);
if(db->servers) FREELIST(db->servers);
db->servers = servers;
return 0;
}
ALPM_LOG_FUNC;
static char *sanitize_url(const char *url)
{
char *newurl;
size_t len = strlen(url);
STRDUP(newurl, url, return NULL);
/* strip the trailing slash if one exists */
if(newurl[len - 1] == '/') {
newurl[len - 1] = '\0';
}
return newurl;
}
/** 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, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(db != NULL, return -1);
db->handle->pm_errno = 0;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
for(i = handle->dbs_sync; i && !found; i = i->next) {
pmdb_t *sdb = i->data;
if(strcmp(db->treename, sdb->treename) == 0) {
found = 1;
}
}
if(!found) {
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
newurl = sanitize_url(url);
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);
if(url) {
len = strlen(url);
return 0;
}
/** 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;
/* Sanity checks */
ASSERT(db != NULL, return -1);
db->handle->pm_errno = 0;
ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1));
newurl = sanitize_url(url);
if(!newurl) {
return -1;
}
if(len) {
newurl = strdup(url);
/* strip the trailing slash if one exists */
if(newurl[len - 1] == '/') {
newurl[len - 1] = '\0';
}
db->servers = alpm_list_add(db->servers, newurl);
_alpm_log(PM_LOG_DEBUG, "adding new server URL to database '%s': %s\n",
db->servers = alpm_list_remove_str(db->servers, newurl, &vdata);
free(newurl);
if(vdata) {
_alpm_log(db->handle, ALPM_LOG_DEBUG, "removed server URL from database '%s': %s\n",
db->treename, newurl);
} else {
FREELIST(db->servers);
_alpm_log(PM_LOG_DEBUG, "serverlist flushed for '%s'\n", db->treename);
free(vdata);
return 0;
}
return(0);
return 1;
}
/** Get the name of a package database. */
const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db)
const char SYMEXPORT *alpm_db_get_name(const alpm_db_t *db)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
ASSERT(db != NULL, return NULL);
return db->treename;
}
/** Get a download URL for the package database. */
const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db)
/** Get the signature verification level for a database. */
alpm_siglevel_t SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db)
{
char *url;
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
ASSERT(db->servers != NULL, return(NULL));
url = (char*)db->servers->data;
return(url);
ASSERT(db != NULL, return -1);
if(db->siglevel & ALPM_SIG_USE_DEFAULT) {
return alpm_option_get_default_siglevel(db->handle);
} else {
return db->siglevel;
}
}
/** 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 = 0;
return db->ops->validate(db);
}
/** Get a package entry from a package database. */
pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name)
alpm_pkg_t SYMEXPORT *alpm_db_get_pkg(alpm_db_t *db, const char *name)
{
ALPM_LOG_FUNC;
alpm_pkg_t *pkg;
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = 0;
ASSERT(name != NULL && strlen(name) != 0,
RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, NULL));
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
ASSERT(name != NULL && strlen(name) != 0, return(NULL));
return(_alpm_db_get_pkgfromcache(db, name));
pkg = _alpm_db_get_pkgfromcache(db, name);
if(!pkg) {
RET_ERR(db->handle, ALPM_ERR_PKG_NOT_FOUND, NULL);
}
return pkg;
}
/** Get the package cache of a package database. */
alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(pmdb_t *db)
alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(alpm_db_t *db)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
return(_alpm_db_get_pkgcache(db));
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = 0;
return _alpm_db_get_pkgcache(db);
}
/** Get a group entry from a package database. */
pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name)
alpm_group_t SYMEXPORT *alpm_db_readgroup(alpm_db_t *db, const char *name)
{
ALPM_LOG_FUNC;
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = 0;
ASSERT(name != NULL && strlen(name) != 0,
RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, NULL));
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
ASSERT(name != NULL && strlen(name) != 0, return(NULL));
return(_alpm_db_get_grpfromcache(db, name));
return _alpm_db_get_groupfromcache(db, name);
}
/** Get the group cache of a package database. */
alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db)
alpm_list_t SYMEXPORT *alpm_db_get_groupcache(alpm_db_t *db)
{
ALPM_LOG_FUNC;
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = 0;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
return(_alpm_db_get_grpcache(db));
return _alpm_db_get_groupcache(db);
}
/** Searches a database. */
alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles)
alpm_list_t SYMEXPORT *alpm_db_search(alpm_db_t *db, const alpm_list_t* needles)
{
ALPM_LOG_FUNC;
ASSERT(db != NULL, return NULL);
db->handle->pm_errno = 0;
/* Sanity checks */
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
return(_alpm_db_search(db, needles));
return _alpm_db_search(db, needles);
}
/** Set install reason for a package in db. */
int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason)
int SYMEXPORT alpm_db_set_pkgreason(alpm_handle_t *handle, alpm_pkg_t *pkg,
alpm_pkgreason_t reason)
{
ALPM_LOG_FUNC;
CHECK_HANDLE(handle, return -1);
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
ASSERT(pkg->origin == PKG_FROM_LOCALDB,
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
ASSERT(pkg->origin_data.db == handle->db_local,
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(db != NULL && name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
pmpkg_t *pkg = _alpm_db_get_pkgfromcache(db, name);
if(pkg == NULL) {
RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
}
_alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name);
_alpm_log(handle, ALPM_LOG_DEBUG,
"setting install reason %u for %s\n", reason, pkg->name);
if(alpm_pkg_get_reason(pkg) == reason) {
/* we are done */
return(0);
return 0;
}
/* set reason (in pkgcache) */
pkg->reason = reason;
/* write DESC */
if(_alpm_local_db_write(db, pkg, INFRQ_DESC)) {
RET_ERR(PM_ERR_DB_WRITE, -1);
if(_alpm_local_db_write(handle->db_local, pkg, INFRQ_DESC)) {
RET_ERR(handle, ALPM_ERR_DB_WRITE, -1);
}
return(0);
return 0;
}
/** @} */
pmdb_t *_alpm_db_new(const char *treename, int is_local)
alpm_db_t *_alpm_db_new(const char *treename, int is_local)
{
pmdb_t *db;
alpm_db_t *db;
ALPM_LOG_FUNC;
CALLOC(db, 1, sizeof(pmdb_t), RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(db, 1, sizeof(alpm_db_t), return NULL);
STRDUP(db->treename, treename, return NULL);
db->is_local = is_local;
return(db);
return db;
}
void _alpm_db_free(pmdb_t *db)
void _alpm_db_free(alpm_db_t *db)
{
ALPM_LOG_FUNC;
/* cleanup pkgcache */
_alpm_db_free_pkgcache(db);
/* cleanup server list */
@@ -326,61 +344,65 @@ void _alpm_db_free(pmdb_t *db)
return;
}
const char *_alpm_db_path(pmdb_t *db)
const char *_alpm_db_path(alpm_db_t *db)
{
if(!db) {
return(NULL);
return NULL;
}
if(!db->_path) {
const char *dbpath;
size_t pathsize;
dbpath = alpm_option_get_dbpath();
dbpath = alpm_option_get_dbpath(db->handle);
if(!dbpath) {
_alpm_log(PM_LOG_ERROR, _("database path is undefined\n"));
RET_ERR(PM_ERR_DB_OPEN, NULL);
_alpm_log(db->handle, ALPM_LOG_ERROR, _("database path is undefined\n"));
RET_ERR(db->handle, ALPM_ERR_DB_OPEN, NULL);
}
if(db->is_local) {
pathsize = strlen(dbpath) + strlen(db->treename) + 2;
CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
sprintf(db->_path, "%s%s/", dbpath, db->treename);
} else {
pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4;
CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
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 */
sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename);
}
_alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, "database path for tree %s set to %s\n",
db->treename, db->_path);
}
return(db->_path);
return db->_path;
}
int _alpm_db_version(pmdb_t *db)
char *_alpm_db_sig_path(alpm_db_t *db)
{
if(!db) {
return(-1);
char *sigpath;
size_t len;
const char *dbfile = _alpm_db_path(db);
if(!db || !dbfile) {
return NULL;
}
return(db->ops->version(db));
len = strlen(dbfile) + strlen(".sig") + 1;
CALLOC(sigpath, len, sizeof(char), RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
sprintf(sigpath, "%s.sig", dbfile);
return sigpath;
}
int _alpm_db_cmp(const void *d1, const void *d2)
{
pmdb_t *db1 = (pmdb_t *)d1;
pmdb_t *db2 = (pmdb_t *)d2;
return(strcmp(db1->treename, db2->treename));
alpm_db_t *db1 = (alpm_db_t *)d1;
alpm_db_t *db2 = (alpm_db_t *)d2;
return strcmp(db1->treename, db2->treename);
}
alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
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;
/* copy the pkgcache- we will free the list var after each needle */
alpm_list_t *list = alpm_list_copy(_alpm_db_get_pkgcache(db));
ALPM_LOG_FUNC;
for(i = needles; i; i = i->next) {
char *targ;
regex_t reg;
@@ -390,14 +412,14 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
}
ret = NULL;
targ = i->data;
_alpm_log(PM_LOG_DEBUG, "searching for target '%s'\n", targ);
_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) {
RET_ERR(PM_ERR_INVALID_REGEX, NULL);
RET_ERR(db->handle, ALPM_ERR_INVALID_REGEX, NULL);
}
for(j = list; j; j = j->next) {
pmpkg_t *pkg = j->data;
alpm_pkg_t *pkg = j->data;
const char *matched = NULL;
const char *name = alpm_pkg_get_name(pkg);
const char *desc = alpm_pkg_get_desc(pkg);
@@ -407,7 +429,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
matched = name;
}
/* check desc */
else if (desc && regexec(&reg, desc, 0, 0, 0) == 0) {
else if(desc && regexec(&reg, desc, 0, 0, 0) == 0) {
matched = desc;
}
/* TODO: should we be doing this, and should we print something
@@ -415,7 +437,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
if(!matched) {
/* check provides */
for(k = alpm_pkg_get_provides(pkg); k; k = k->next) {
if (regexec(&reg, k->data, 0, 0, 0) == 0) {
if(regexec(&reg, k->data, 0, 0, 0) == 0) {
matched = k->data;
break;
}
@@ -424,7 +446,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
if(!matched) {
/* check groups */
for(k = alpm_pkg_get_groups(pkg); k; k = k->next) {
if (regexec(&reg, k->data, 0, 0, 0) == 0) {
if(regexec(&reg, k->data, 0, 0, 0) == 0) {
matched = k->data;
break;
}
@@ -432,7 +454,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
}
if(matched != NULL) {
_alpm_log(PM_LOG_DEBUG, " search target '%s' matched '%s'\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, " search target '%s' matched '%s'\n",
targ, matched);
ret = alpm_list_add(ret, pkg);
}
@@ -445,179 +467,176 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
regfree(&reg);
}
return(ret);
return ret;
}
/* Returns a new package cache from db.
* It frees the cache if it already exists.
*/
int _alpm_db_load_pkgcache(pmdb_t *db)
static int load_pkgcache(alpm_db_t *db)
{
ALPM_LOG_FUNC;
if(db == NULL) {
return(-1);
}
_alpm_db_free_pkgcache(db);
_alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, "loading package cache for repository '%s'\n",
db->treename);
if(db->ops->populate(db) == -1) {
_alpm_log(PM_LOG_DEBUG,
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"failed to load package cache for repository '%s'\n", db->treename);
return(-1);
return -1;
}
db->pkgcache_loaded = 1;
return(0);
db->status |= DB_STATUS_PKGCACHE;
return 0;
}
void _alpm_db_free_pkgcache(pmdb_t *db)
static void free_groupcache(alpm_db_t *db)
{
ALPM_LOG_FUNC;
alpm_list_t *lg;
if(db == NULL || !db->pkgcache_loaded) {
if(db == NULL || !(db->status & DB_STATUS_GRPCACHE)) {
return;
}
_alpm_log(PM_LOG_DEBUG, "freeing package cache for repository '%s'\n",
db->treename);
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"freeing group cache for repository '%s'\n", db->treename);
for(lg = db->grpcache; lg; lg = lg->next) {
_alpm_group_free(lg->data);
lg->data = NULL;
}
FREELIST(db->grpcache);
db->status &= ~DB_STATUS_GRPCACHE;
}
void _alpm_db_free_pkgcache(alpm_db_t *db)
{
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(_alpm_db_get_pkgcache(db),
(alpm_list_fn_free)_alpm_pkg_free);
_alpm_pkghash_free(db->pkgcache);
db->pkgcache_loaded = 0;
db->status &= ~DB_STATUS_PKGCACHE;
_alpm_db_free_grpcache(db);
free_groupcache(db);
}
pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db)
alpm_pkghash_t *_alpm_db_get_pkgcache_hash(alpm_db_t *db)
{
ALPM_LOG_FUNC;
if(db == NULL) {
return(NULL);
return NULL;
}
if(!db->pkgcache_loaded) {
_alpm_db_load_pkgcache(db);
if(!(db->status & DB_STATUS_VALID)) {
RET_ERR(db->handle, ALPM_ERR_DB_INVALID, NULL);
}
/* hmmm, still NULL ?*/
if(!db->pkgcache) {
_alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename);
if(!(db->status & DB_STATUS_PKGCACHE)) {
load_pkgcache(db);
}
return(db->pkgcache);
return db->pkgcache;
}
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
alpm_list_t *_alpm_db_get_pkgcache(alpm_db_t *db)
{
ALPM_LOG_FUNC;
pmpkghash_t *hash = _alpm_db_get_pkgcache_hash(db);
alpm_pkghash_t *hash = _alpm_db_get_pkgcache_hash(db);
if(hash == NULL) {
return(NULL);
return NULL;
}
return(hash->list);
return hash->list;
}
/* "duplicate" pkg then add it to pkgcache */
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
int _alpm_db_add_pkgincache(alpm_db_t *db, alpm_pkg_t *pkg)
{
pmpkg_t *newpkg;
alpm_pkg_t *newpkg;
ALPM_LOG_FUNC;
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
return(-1);
if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
return -1;
}
newpkg = _alpm_pkg_dup(pkg);
if(newpkg == NULL) {
return(-1);
return -1;
}
_alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",
alpm_pkg_get_name(newpkg), db->treename);
db->pkgcache = _alpm_pkghash_add_sorted(db->pkgcache, newpkg);
_alpm_db_free_grpcache(db);
free_groupcache(db);
return(0);
return 0;
}
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)
int _alpm_db_remove_pkgfromcache(alpm_db_t *db, alpm_pkg_t *pkg)
{
pmpkg_t *data = NULL;
alpm_pkg_t *data = NULL;
ALPM_LOG_FUNC;
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
return(-1);
if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
return -1;
}
_alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n",
alpm_pkg_get_name(pkg), db->treename);
db->pkgcache = _alpm_pkghash_remove(db->pkgcache, pkg, &data);
if(data == NULL) {
/* package not found */
_alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n",
alpm_pkg_get_name(pkg), db->treename);
return(-1);
return -1;
}
_alpm_pkg_free(data);
_alpm_db_free_grpcache(db);
free_groupcache(db);
return(0);
return 0;
}
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)
alpm_pkg_t *_alpm_db_get_pkgfromcache(alpm_db_t *db, const char *target)
{
ALPM_LOG_FUNC;
if(db == NULL) {
return(NULL);
return NULL;
}
pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db);
alpm_pkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db);
if(!pkgcache) {
_alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n",
target);
return(NULL);
return NULL;
}
return(_alpm_pkghash_find(pkgcache, target));
return _alpm_pkghash_find(pkgcache, target);
}
/* Returns a new group cache from db.
*/
int _alpm_db_load_grpcache(pmdb_t *db)
static int load_grpcache(alpm_db_t *db)
{
alpm_list_t *lp;
ALPM_LOG_FUNC;
if(db == NULL) {
return(-1);
return -1;
}
_alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n",
_alpm_log(db->handle, ALPM_LOG_DEBUG, "loading group cache for repository '%s'\n",
db->treename);
for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
const alpm_list_t *i;
pmpkg_t *pkg = lp->data;
alpm_pkg_t *pkg = lp->data;
for(i = alpm_pkg_get_groups(pkg); i; i = i->next) {
const char *grpname = i->data;
alpm_list_t *j;
pmgrp_t *grp = NULL;
alpm_group_t *grp = NULL;
int found = 0;
/* first look through the group cache for a group with this name */
@@ -635,71 +654,54 @@ int _alpm_db_load_grpcache(pmdb_t *db)
continue;
}
/* we didn't find the group, so create a new one with this name */
grp = _alpm_grp_new(grpname);
grp = _alpm_group_new(grpname);
if(!grp) {
free_groupcache(db);
return -1;
}
grp->packages = alpm_list_add(grp->packages, pkg);
db->grpcache = alpm_list_add(db->grpcache, grp);
}
}
db->grpcache_loaded = 1;
return(0);
db->status |= DB_STATUS_GRPCACHE;
return 0;
}
void _alpm_db_free_grpcache(pmdb_t *db)
alpm_list_t *_alpm_db_get_groupcache(alpm_db_t *db)
{
alpm_list_t *lg;
ALPM_LOG_FUNC;
if(db == NULL || !db->grpcache_loaded) {
return;
}
_alpm_log(PM_LOG_DEBUG, "freeing group cache for repository '%s'\n",
db->treename);
for(lg = db->grpcache; lg; lg = lg->next) {
_alpm_grp_free(lg->data);
lg->data = NULL;
}
FREELIST(db->grpcache);
db->grpcache_loaded = 0;
}
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
{
ALPM_LOG_FUNC;
if(db == NULL) {
return(NULL);
return NULL;
}
if(!db->grpcache_loaded) {
_alpm_db_load_grpcache(db);
if(!(db->status & DB_STATUS_VALID)) {
RET_ERR(db->handle, ALPM_ERR_DB_INVALID, NULL);
}
return(db->grpcache);
if(!(db->status & DB_STATUS_GRPCACHE)) {
load_grpcache(db);
}
return db->grpcache;
}
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target)
alpm_group_t *_alpm_db_get_groupfromcache(alpm_db_t *db, const char *target)
{
alpm_list_t *i;
ALPM_LOG_FUNC;
if(db == NULL || target == NULL || strlen(target) == 0) {
return(NULL);
return NULL;
}
for(i = _alpm_db_get_grpcache(db); i; i = i->next) {
pmgrp_t *info = i->data;
for(i = _alpm_db_get_groupcache(db); i; i = i->next) {
alpm_group_t *info = i->data;
if(strcmp(info->name, target) == 0) {
return(info);
return info;
}
}
return(NULL);
return NULL;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -22,81 +22,88 @@
#ifndef _ALPM_DB_H
#define _ALPM_DB_H
#include "alpm.h"
#include "pkghash.h"
#include <time.h>
/* libarchive */
#include <archive.h>
#include <archive_entry.h>
#include "alpm.h"
#include "pkghash.h"
#include "signing.h"
/* Database entries */
typedef enum _pmdbinfrq_t {
typedef enum _alpm_dbinfrq_t {
INFRQ_BASE = 1,
INFRQ_DESC = (1 << 1),
INFRQ_FILES = (1 << 2),
INFRQ_SCRIPTLET = (1 << 3),
INFRQ_DSIZE = (1 << 4),
/* ALL should be info stored in the package or database */
INFRQ_ALL = 0x1F
} pmdbinfrq_t;
INFRQ_ALL = 0x1F,
INFRQ_ERROR = (1 << 31)
} alpm_dbinfrq_t;
/** Database status. Bitflags. */
enum _alpm_dbstatus_t {
DB_STATUS_VALID = (1 << 0),
DB_STATUS_PKGCACHE = (1 << 1),
DB_STATUS_GRPCACHE = (1 << 2)
};
struct db_operations {
int (*populate) (pmdb_t *);
void (*unregister) (pmdb_t *);
int (*version) (pmdb_t *);
int (*validate) (alpm_db_t *);
int (*populate) (alpm_db_t *);
void (*unregister) (alpm_db_t *);
};
/* Database */
struct __pmdb_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;
int pkgcache_loaded;
int grpcache_loaded;
/* also indicates whether we are RO or RW */
int is_local;
pmpkghash_t *pkgcache;
/* flags determining validity, loaded caches, etc. */
enum _alpm_dbstatus_t status;
alpm_pkghash_t *pkgcache;
alpm_list_t *grpcache;
alpm_list_t *servers;
alpm_siglevel_t siglevel;
struct db_operations *ops;
};
/* db.c, database general calls */
pmdb_t *_alpm_db_new(const char *treename, int is_local);
void _alpm_db_free(pmdb_t *db);
const char *_alpm_db_path(pmdb_t *db);
int _alpm_db_version(pmdb_t *db);
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);
char *_alpm_db_sig_path(alpm_db_t *db);
int _alpm_db_cmp(const void *d1, const void *d2);
alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
pmdb_t *_alpm_db_register_local(void);
pmdb_t *_alpm_db_register_sync(const char *treename);
void _alpm_db_unregister(pmdb_t *db);
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,
alpm_siglevel_t level);
void _alpm_db_unregister(alpm_db_t *db);
/* be_*.c, backend specific calls */
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info);
int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info);
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, alpm_dbinfrq_t inforeq);
int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info);
/* cache bullshit */
/* packages */
int _alpm_db_load_pkgcache(pmdb_t *db);
void _alpm_db_free_pkgcache(pmdb_t *db);
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg);
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg);
pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db);
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db);
int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel);
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target);
void _alpm_db_free_pkgcache(alpm_db_t *db);
int _alpm_db_add_pkgincache(alpm_db_t *db, alpm_pkg_t *pkg);
int _alpm_db_remove_pkgfromcache(alpm_db_t *db, alpm_pkg_t *pkg);
alpm_pkghash_t *_alpm_db_get_pkgcache_hash(alpm_db_t *db);
alpm_list_t *_alpm_db_get_pkgcache(alpm_db_t *db);
alpm_pkg_t *_alpm_db_get_pkgfromcache(alpm_db_t *db, const char *target);
/* groups */
int _alpm_db_load_grpcache(pmdb_t *db);
void _alpm_db_free_grpcache(pmdb_t *db);
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db);
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target);
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 */

View File

@@ -34,51 +34,18 @@
#include "log.h"
#include "graph.h"
/** \addtogroup alpm_deltas Delta Functions
* @brief Functions to manipulate libalpm deltas
* @{
*/
const char SYMEXPORT *alpm_delta_get_from(pmdelta_t *delta)
{
ASSERT(delta != NULL, return(NULL));
return(delta->from);
}
const char SYMEXPORT *alpm_delta_get_to(pmdelta_t *delta)
{
ASSERT(delta != NULL, return(NULL));
return(delta->to);
}
const char SYMEXPORT *alpm_delta_get_filename(pmdelta_t *delta)
{
ASSERT(delta != NULL, return(NULL));
return(delta->delta);
}
const char SYMEXPORT *alpm_delta_get_md5sum(pmdelta_t *delta)
{
ASSERT(delta != NULL, return(NULL));
return(delta->delta_md5);
}
off_t SYMEXPORT alpm_delta_get_size(pmdelta_t *delta)
{
ASSERT(delta != NULL, return(-1));
return(delta->delta_size);
}
/** @} */
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) {
pmgraph_t *v = _alpm_graph_new();
pmdelta_t *vdelta = i->data;
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;
@@ -87,12 +54,12 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)
/* compute the edges */
for(i = vertices; i; i = i->next) {
pmgraph_t *v_i = i->data;
pmdelta_t *d_i = v_i->data;
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) {
pmgraph_t *v_j = j->data;
pmdelta_t *d_j = v_j->data;
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
* |
@@ -108,20 +75,20 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)
}
v_i->childptr = v_i->children;
}
return(vertices);
return vertices;
}
static void graph_init_size(alpm_list_t *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;
pmgraph_t *v = i->data;
pmdelta_t *vdelta = v->data;
alpm_graph_t *v = i->data;
alpm_delta_t *vdelta = v->data;
/* determine whether the delta file already exists */
fpath = _alpm_filecache_find(vdelta->delta);
fpath = _alpm_filecache_find(handle, vdelta->delta);
md5sum = alpm_compute_md5sum(fpath);
if(fpath && md5sum && strcmp(md5sum, vdelta->delta_md5) == 0) {
vdelta->download_size = 0;
@@ -130,7 +97,7 @@ static void graph_init_size(alpm_list_t *vertices)
FREE(md5sum);
/* determine whether a base 'from' file exists */
fpath = _alpm_filecache_find(vdelta->from);
fpath = _alpm_filecache_find(handle, vdelta->from);
if(fpath) {
v->weight = vdelta->download_size;
}
@@ -142,12 +109,12 @@ static void graph_init_size(alpm_list_t *vertices)
static void dijkstra(alpm_list_t *vertices)
{
alpm_list_t *i;
pmgraph_t *v;
alpm_graph_t *v;
while(1) {
v = NULL;
/* find the smallest vertice not visited yet */
for(i = vertices; i; i = i->next) {
pmgraph_t *v_i = i->data;
alpm_graph_t *v_i = i->data;
if(v_i->state == -1) {
continue;
@@ -165,8 +132,8 @@ static void dijkstra(alpm_list_t *vertices)
v->childptr = v->children;
while(v->childptr) {
pmgraph_t *v_c = v->childptr->data;
pmdelta_t *d_c = v_c->data;
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;
@@ -181,13 +148,13 @@ static void dijkstra(alpm_list_t *vertices)
static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t **path)
{
alpm_list_t *i;
pmgraph_t *v = NULL;
alpm_graph_t *v = NULL;
off_t bestsize = 0;
alpm_list_t *rpath = NULL;
for(i = vertices; i; i = i->next) {
pmgraph_t *v_i = i->data;
pmdelta_t *d_i = v_i->data;
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) {
@@ -198,54 +165,53 @@ static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t **
}
while(v != NULL) {
pmdelta_t *vdelta = v->data;
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);
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 deltas the list of pmdelta_t * objects that a file has
* @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 pmdelta_t * objects that
* @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_list_t *deltas,
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;
ALPM_LOG_FUNC;
if(deltas == NULL) {
*path = NULL;
return(bestsize);
return bestsize;
}
_alpm_log(PM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to);
_alpm_log(handle, ALPM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to);
vertices = graph_init(deltas, 0);
graph_init_size(vertices);
graph_init_size(handle, vertices);
dijkstra(vertices);
bestsize = shortest_path(vertices, to, &bestpath);
_alpm_log(PM_LOG_DEBUG, "delta shortest-path search complete : '%jd'\n", (intmax_t)bestsize);
_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);
return bestsize;
}
static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota)
@@ -256,8 +222,8 @@ static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota
vertices = graph_init(deltas, 1);
for(i = vertices; i; i = i->next) {
pmgraph_t *v = i->data;
pmdelta_t *vdelta = v->data;
alpm_graph_t *v = i->data;
alpm_delta_t *vdelta = v->data;
if(strcmp(vdelta->to, to) == 0)
{
v->weight = vdelta->download_size;
@@ -265,39 +231,45 @@ static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota
}
dijkstra(vertices);
for(i = vertices; i; i = i->next) {
pmgraph_t *v = i->data;
pmdelta_t *vdelta = v->data;
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);
return unused;
}
alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg)
/** \addtogroup alpm_deltas Delta Functions
* @brief Functions to manipulate libalpm deltas
* @{
*/
alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(alpm_pkg_t *pkg)
{
off_t pkgsize = alpm_pkg_get_size(pkg);
alpm_list_t *unused = find_unused(
alpm_pkg_get_deltas(pkg),
alpm_pkg_get_filename(pkg),
pkgsize * MAX_DELTA_RATIO);
return(unused);
return unused;
}
/** @} */
/** Parses the string representation of a pmdelta_t object.
/** 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 line the string to parse
* @return A pointer to the new pmdelta_t object
* @return A pointer to the new alpm_delta_t object
*/
/* TODO this does not really belong here, but in a parsing lib */
pmdelta_t *_alpm_delta_parse(char *line)
alpm_delta_t *_alpm_delta_parse(char *line)
{
pmdelta_t *delta;
alpm_delta_t *delta;
char *tmp = line, *tmp2;
regex_t reg;
@@ -308,21 +280,21 @@ pmdelta_t *_alpm_delta_parse(char *line)
if(regexec(&reg, line, 0, 0, 0) != 0) {
/* delta line is invalid, return NULL */
regfree(&reg);
return(NULL);
return NULL;
}
regfree(&reg);
CALLOC(delta, 1, sizeof(pmdelta_t), RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(delta, 1, sizeof(alpm_delta_t), return NULL);
tmp2 = tmp;
tmp = strchr(tmp, ' ');
*(tmp++) = '\0';
STRDUP(delta->delta, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(delta->delta, tmp2, return NULL);
tmp2 = tmp;
tmp = strchr(tmp, ' ');
*(tmp++) = '\0';
STRDUP(delta->delta_md5, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(delta->delta_md5, tmp2, return NULL);
tmp2 = tmp;
tmp = strchr(tmp, ' ');
@@ -332,23 +304,35 @@ pmdelta_t *_alpm_delta_parse(char *line)
tmp2 = tmp;
tmp = strchr(tmp, ' ');
*(tmp++) = '\0';
STRDUP(delta->from, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(delta->from, tmp2, return NULL);
tmp2 = tmp;
STRDUP(delta->to, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(delta->to, tmp2, return NULL);
_alpm_log(PM_LOG_DEBUG, "delta : %s %s '%jd'\n", delta->from, delta->to, (intmax_t)delta->delta_size);
return(delta);
return delta;
}
void _alpm_delta_free(pmdelta_t *delta)
void _alpm_delta_free(alpm_delta_t *delta)
{
FREE(delta->from);
FREE(delta->to);
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, return NULL);
STRDUP(newdelta->delta_md5, delta->delta_md5, return NULL);
STRDUP(newdelta->from, delta->from, return NULL);
STRDUP(newdelta->to, delta->to, return NULL);
newdelta->delta_size = delta->delta_size;
newdelta->download_size = delta->download_size;
return newdelta;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -20,28 +20,16 @@
#ifndef _ALPM_DELTA_H
#define _ALPM_DELTA_H
#include "config.h" /* ensure off_t is correct length */
#include <sys/types.h> /* off_t */
#include "alpm.h"
struct __pmdelta_t {
/** filename of the delta patch */
char *delta;
/** md5sum of the delta file */
char *delta_md5;
/** filesize of the delta file */
off_t delta_size;
/** filename of the 'before' file */
char *from;
/** filename of the 'after' file */
char *to;
/** download filesize of the delta file */
off_t download_size;
};
pmdelta_t *_alpm_delta_parse(char *line);
void _alpm_delta_free(pmdelta_t *delta);
off_t _alpm_shortest_delta_path(alpm_list_t *deltas,
alpm_delta_t *_alpm_delta_parse(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);
/* max percent of package size to download deltas */

View File

@@ -35,31 +35,30 @@
#include "package.h"
#include "db.h"
#include "handle.h"
#include "trans.h"
void _alpm_dep_free(pmdepend_t *dep)
void _alpm_dep_free(alpm_depend_t *dep)
{
FREE(dep->name);
FREE(dep->version);
FREE(dep);
}
static pmdepmissing_t *depmiss_new(const char *target, pmdepend_t *dep,
static alpm_depmissing_t *depmiss_new(const char *target, alpm_depend_t *dep,
const char *causingpkg)
{
pmdepmissing_t *miss;
alpm_depmissing_t *miss;
ALPM_LOG_FUNC;
MALLOC(miss, sizeof(alpm_depmissing_t), return NULL);
MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(miss->target, target, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(miss->target, target, return NULL);
miss->depend = _alpm_dep_dup(dep);
STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(miss->causingpkg, causingpkg, return NULL);
return(miss);
return miss;
}
void _alpm_depmiss_free(pmdepmissing_t *miss)
void _alpm_depmiss_free(alpm_depmissing_t *miss)
{
_alpm_dep_free(miss->depend);
FREE(miss->target);
@@ -68,18 +67,18 @@ void _alpm_depmiss_free(pmdepmissing_t *miss)
}
/* Does pkg1 depend on pkg2, ie. does pkg2 satisfy a dependency of pkg1? */
static int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2)
static int _alpm_dep_edge(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2)
{
alpm_list_t *i;
for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) {
if(_alpm_depcmp(pkg2, i->data)) {
return(1);
return 1;
}
}
return(0);
return 0;
}
/* Convert a list of pmpkg_t * to a graph structure,
/* Convert a list of alpm_pkg_t * to a graph structure,
* with a edge for each dependency.
* Returns a list of vertices (one vertex = one package)
* (used by alpm_sortbydeps)
@@ -90,19 +89,19 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)
alpm_list_t *vertices = NULL;
/* We create the vertices */
for(i = targets; i; i = i->next) {
pmgraph_t *vertex = _alpm_graph_new();
alpm_graph_t *vertex = _alpm_graph_new();
vertex->data = (void *)i->data;
vertices = alpm_list_add(vertices, vertex);
}
/* We compute the edges */
for(i = vertices; i; i = i->next) {
pmgraph_t *vertex_i = i->data;
pmpkg_t *p_i = vertex_i->data;
alpm_graph_t *vertex_i = i->data;
alpm_pkg_t *p_i = vertex_i->data;
/* TODO this should be somehow combined with alpm_checkdeps */
for(j = vertices; j; j = j->next) {
pmgraph_t *vertex_j = j->data;
pmpkg_t *p_j = vertex_j->data;
alpm_graph_t *vertex_j = j->data;
alpm_pkg_t *p_j = vertex_j->data;
if(_alpm_dep_edge(p_i, p_j)) {
vertex_i->children =
alpm_list_add(vertex_i->children, vertex_j);
@@ -110,7 +109,7 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)
}
vertex_i->childptr = vertex_i->children;
}
return(vertices);
return vertices;
}
/* Re-order a list of target packages with respect to their dependencies.
@@ -127,20 +126,19 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)
* This function returns the new alpm_list_t* target list.
*
*/
alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
alpm_list_t *targets, int reverse)
{
alpm_list_t *newtargs = NULL;
alpm_list_t *vertices = NULL;
alpm_list_t *vptr;
pmgraph_t *vertex;
ALPM_LOG_FUNC;
alpm_graph_t *vertex;
if(targets == NULL) {
return(NULL);
return NULL;
}
_alpm_log(PM_LOG_DEBUG, "started sorting dependencies\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "started sorting dependencies\n");
vertices = dep_graph_init(targets);
@@ -151,25 +149,25 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
vertex->state = -1;
int found = 0;
while(vertex->childptr && !found) {
pmgraph_t *nextchild = vertex->childptr->data;
alpm_graph_t *nextchild = vertex->childptr->data;
vertex->childptr = vertex->childptr->next;
if (nextchild->state == 0) {
if(nextchild->state == 0) {
found = 1;
nextchild->parent = vertex;
vertex = nextchild;
}
else if(nextchild->state == -1) {
pmpkg_t *vertexpkg = vertex->data;
pmpkg_t *childpkg = nextchild->data;
alpm_pkg_t *vertexpkg = vertex->data;
alpm_pkg_t *childpkg = nextchild->data;
const char *message;
_alpm_log(PM_LOG_WARNING, _("dependency cycle detected:\n"));
_alpm_log(handle, ALPM_LOG_WARNING, _("dependency cycle detected:\n"));
if(reverse) {
message =_("%s will be removed after its %s dependency\n");
} else {
message =_("%s will be installed before its %s dependency\n");
}
_alpm_log(PM_LOG_WARNING, message, vertexpkg->name, childpkg->name);
_alpm_log(handle, ALPM_LOG_WARNING, message, vertexpkg->name, childpkg->name);
}
}
if(!found) {
@@ -181,14 +179,14 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
vptr = vptr->next;
while(vptr) {
vertex = vptr->data;
if (vertex->state == 0) break;
if(vertex->state == 0) break;
vptr = vptr->next;
}
}
}
}
_alpm_log(PM_LOG_DEBUG, "sorting dependencies finished\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "sorting dependencies finished\n");
if(reverse) {
/* reverse the order */
@@ -201,111 +199,114 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
alpm_list_free_inner(vertices, _alpm_graph_free);
alpm_list_free(vertices);
return(newtargs);
return newtargs;
}
static int no_dep_version(void)
static int no_dep_version(alpm_handle_t *handle)
{
int flags = alpm_trans_get_flags();
return flags != -1 && (flags & PM_TRANS_FLAG_NODEPVERSION);
int flags = alpm_trans_get_flags(handle);
return flags != -1 && (flags & ALPM_TRANS_FLAG_NODEPVERSION);
}
static pmdepend_t *filtered_depend(pmdepend_t *dep, int nodepversion)
static alpm_depend_t *filtered_depend(alpm_depend_t *dep, int nodepversion)
{
if(nodepversion) {
pmdepend_t *newdep = _alpm_dep_dup(dep);
ASSERT(newdep, return(dep));
newdep->mod = PM_DEP_MOD_ANY;
alpm_depend_t *newdep = _alpm_dep_dup(dep);
ASSERT(newdep, return dep);
newdep->mod = ALPM_DEP_MOD_ANY;
dep = newdep;
}
return dep;
}
static void release_filtered_depend(pmdepend_t *dep, int nodepversion)
static void release_filtered_depend(alpm_depend_t *dep, int nodepversion)
{
if(nodepversion) {
free(dep);
}
}
static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)
static alpm_pkg_t *find_dep_satisfier(alpm_list_t *pkgs, alpm_depend_t *dep)
{
alpm_list_t *i;
for(i = pkgs; i; i = alpm_list_next(i)) {
pmpkg_t *pkg = i->data;
alpm_pkg_t *pkg = i->data;
if(_alpm_depcmp(pkg, dep)) {
return(pkg);
return pkg;
}
}
return(NULL);
return NULL;
}
/** Find a package satisfying a specified dependency.
* The dependency can include versions with depmod operators.
* @param pkgs an alpm_list_t* of pmpkg_t where the satisfier will be searched
* @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 pmpkg_t* satisfying depstring
* @return a alpm_pkg_t* satisfying depstring
*/
pmpkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)
alpm_pkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)
{
pmdepend_t *dep = _alpm_splitdep(depstring);
pmpkg_t *pkg = find_dep_satisfier(pkgs, dep);
alpm_depend_t *dep = _alpm_splitdep(depstring);
if(!dep) {
return NULL;
}
alpm_pkg_t *pkg = find_dep_satisfier(pkgs, dep);
_alpm_dep_free(dep);
return(pkg);
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 reversedeps handles the backward dependencies
* @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)
* @return an alpm_list_t* of pmdepmissing_t pointers.
* @param reversedeps handles the backward dependencies
* @return an alpm_list_t* of alpm_depmissing_t pointers.
*/
alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
alpm_list_t *remove, alpm_list_t *upgrade)
alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
alpm_list_t *pkglist, alpm_list_t *remove, alpm_list_t *upgrade,
int reversedeps)
{
alpm_list_t *i, *j;
alpm_list_t *targets, *dblist = NULL, *modified = NULL;
alpm_list_t *dblist = NULL, *modified = NULL;
alpm_list_t *baddeps = NULL;
int nodepversion;
ALPM_LOG_FUNC;
CHECK_HANDLE(handle, return NULL);
targets = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade));
for(i = pkglist; i; i = i->next) {
pmpkg_t *pkg = i->data;
if(_alpm_pkg_find(targets, pkg->name)) {
alpm_pkg_t *pkg = i->data;
if(_alpm_pkg_find(remove, pkg->name) || _alpm_pkg_find(upgrade, pkg->name)) {
modified = alpm_list_add(modified, pkg);
} else {
dblist = alpm_list_add(dblist, pkg);
}
}
alpm_list_free(targets);
nodepversion = no_dep_version();
nodepversion = no_dep_version(handle);
/* look for unsatisfied dependencies of the upgrade list */
for(i = upgrade; i; i = i->next) {
pmpkg_t *tp = i->data;
_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
alpm_pkg_get_name(tp), alpm_pkg_get_version(tp));
alpm_pkg_t *tp = i->data;
_alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: package %s-%s\n",
tp->name, tp->version);
for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
pmdepend_t *depend = j->data;
alpm_depend_t *depend = j->data;
depend = filtered_depend(depend, nodepversion);
/* 1. we check the upgrade list */
/* 2. we check database for untouched satisfying packages */
if(!find_dep_satisfier(upgrade, depend) &&
!find_dep_satisfier(dblist, depend)) {
!find_dep_satisfier(dblist, depend)) {
/* Unsatisfied dependency in the upgrade list */
pmdepmissing_t *miss;
alpm_depmissing_t *miss;
char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",
missdepstring, alpm_pkg_get_name(tp));
_alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",
missdepstring, tp->name);
free(missdepstring);
miss = depmiss_new(alpm_pkg_get_name(tp), depend, NULL);
miss = depmiss_new(tp->name, depend, NULL);
baddeps = alpm_list_add(baddeps, miss);
}
release_filtered_depend(depend, nodepversion);
@@ -316,23 +317,23 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
/* reversedeps handles the backwards dependencies, ie,
* the packages listed in the requiredby field. */
for(i = dblist; i; i = i->next) {
pmpkg_t *lp = i->data;
alpm_pkg_t *lp = i->data;
for(j = alpm_pkg_get_depends(lp); j; j = j->next) {
pmdepend_t *depend = j->data;
alpm_depend_t *depend = j->data;
depend = filtered_depend(depend, nodepversion);
pmpkg_t *causingpkg = find_dep_satisfier(modified, depend);
alpm_pkg_t *causingpkg = find_dep_satisfier(modified, depend);
/* we won't break this depend, if it is already broken, we ignore it */
/* 1. check upgrade list for satisfiers */
/* 2. check dblist for satisfiers */
if(causingpkg &&
!find_dep_satisfier(upgrade, depend) &&
!find_dep_satisfier(dblist, depend)) {
pmdepmissing_t *miss;
alpm_depmissing_t *miss;
char *missdepstring = alpm_dep_compute_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
missdepstring, alpm_pkg_get_name(lp));
_alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
missdepstring, lp->name);
free(missdepstring);
miss = depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg));
miss = depmiss_new(lp->name, depend, causingpkg->name);
baddeps = alpm_list_add(baddeps, miss);
}
release_filtered_depend(depend, nodepversion);
@@ -343,44 +344,43 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,
alpm_list_free(modified);
alpm_list_free(dblist);
return(baddeps);
return baddeps;
}
static int dep_vercmp(const char *version1, pmdepmod_t mod,
static int dep_vercmp(const char *version1, alpm_depmod_t mod,
const char *version2)
{
int equal = 0;
if(mod == PM_DEP_MOD_ANY) {
if(mod == ALPM_DEP_MOD_ANY) {
equal = 1;
} else {
int cmp = alpm_pkg_vercmp(version1, version2);
switch(mod) {
case PM_DEP_MOD_EQ: equal = (cmp == 0); break;
case PM_DEP_MOD_GE: equal = (cmp >= 0); break;
case PM_DEP_MOD_LE: equal = (cmp <= 0); break;
case PM_DEP_MOD_LT: equal = (cmp < 0); break;
case PM_DEP_MOD_GT: equal = (cmp > 0); break;
case ALPM_DEP_MOD_EQ: equal = (cmp == 0); break;
case ALPM_DEP_MOD_GE: equal = (cmp >= 0); break;
case ALPM_DEP_MOD_LE: equal = (cmp <= 0); break;
case ALPM_DEP_MOD_LT: equal = (cmp < 0); break;
case ALPM_DEP_MOD_GT: equal = (cmp > 0); break;
default: equal = 1; break;
}
}
return(equal);
return equal;
}
int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep)
{
alpm_list_t *i;
int satisfy = 0;
/* check (pkg->name, pkg->version) */
if(pkg->name_hash && dep->name_hash
&& pkg->name_hash != dep->name_hash) {
if(pkg->name_hash != dep->name_hash) {
/* skip more expensive checks */
} else {
satisfy = (strcmp(pkg->name, dep->name) == 0
&& dep_vercmp(pkg->version, dep->mod, dep->version));
if(satisfy) {
return(satisfy);
return satisfy;
}
}
@@ -390,7 +390,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
const char *provver = strchr(provision, '=');
if(provver == NULL) { /* no provision version */
satisfy = (dep->mod == PM_DEP_MOD_ANY
satisfy = (dep->mod == ALPM_DEP_MOD_ANY
&& strcmp(provision, dep->name) == 0);
} else {
/* This is a bit tricker than the old code for performance reasons. To
@@ -406,86 +406,85 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
}
}
return(satisfy);
return satisfy;
}
pmdepend_t *_alpm_splitdep(const char *depstring)
alpm_depend_t *_alpm_splitdep(const char *depstring)
{
pmdepend_t *depend;
alpm_depend_t *depend;
const char *ptr, *version = NULL;
if(depstring == NULL) {
return(NULL);
return NULL;
}
CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(depend, 1, sizeof(alpm_depend_t), return NULL);
/* Find a version comparator if one exists. If it does, set the type and
* increment the ptr accordingly so we can copy the right strings. */
if((ptr = strstr(depstring, ">="))) {
depend->mod = PM_DEP_MOD_GE;
depend->mod = ALPM_DEP_MOD_GE;
version = ptr + 2;
} else if((ptr = strstr(depstring, "<="))) {
depend->mod = PM_DEP_MOD_LE;
depend->mod = ALPM_DEP_MOD_LE;
version = ptr + 2;
} else if((ptr = strstr(depstring, "="))) {
/* Note: we must do =,<,> checks after <=, >= checks */
depend->mod = PM_DEP_MOD_EQ;
depend->mod = ALPM_DEP_MOD_EQ;
version = ptr + 1;
} else if((ptr = strstr(depstring, "<"))) {
depend->mod = PM_DEP_MOD_LT;
depend->mod = ALPM_DEP_MOD_LT;
version = ptr + 1;
} else if((ptr = strstr(depstring, ">"))) {
depend->mod = PM_DEP_MOD_GT;
depend->mod = ALPM_DEP_MOD_GT;
version = ptr + 1;
} else {
/* no version specified, leave version and ptr NULL */
depend->mod = PM_DEP_MOD_ANY;
depend->mod = ALPM_DEP_MOD_ANY;
}
/* copy the right parts to the right places */
STRNDUP(depend->name, depstring, ptr - depstring,
RET_ERR(PM_ERR_MEMORY, NULL));
STRNDUP(depend->name, depstring, ptr - depstring, return NULL);
depend->name_hash = _alpm_hash_sdbm(depend->name);
if(version) {
STRDUP(depend->version, version, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(depend->version, version, return NULL);
}
return(depend);
return depend;
}
pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep)
alpm_depend_t *_alpm_dep_dup(const alpm_depend_t *dep)
{
pmdepend_t *newdep;
CALLOC(newdep, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
alpm_depend_t *newdep;
CALLOC(newdep, 1, sizeof(alpm_depend_t), return NULL);
STRDUP(newdep->name, dep->name, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(newdep->name, dep->name, return NULL);
newdep->name_hash = dep->name_hash;
STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(newdep->version, dep->version, return NULL);
newdep->mod = dep->mod;
return(newdep);
return newdep;
}
/* These parameters are messy. We check if this package, given a list of
* targets and a db is safe to remove. We do NOT remove it if it is in the
* target list, or if if the package was explictly installed and
* include_explicit == 0 */
static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,
int include_explicit)
static int can_remove_package(alpm_db_t *db, alpm_pkg_t *pkg,
alpm_list_t *targets, int include_explicit)
{
alpm_list_t *i;
if(_alpm_pkg_find(targets, alpm_pkg_get_name(pkg))) {
return(0);
if(_alpm_pkg_find(targets, pkg->name)) {
return 0;
}
if(!include_explicit) {
/* see if it was explicitly installed */
if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) {
_alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed\n",
alpm_pkg_get_name(pkg));
return(0);
if(alpm_pkg_get_reason(pkg) == ALPM_PKG_REASON_EXPLICIT) {
_alpm_log(db->handle, ALPM_LOG_DEBUG,
"excluding %s -- explicitly installed\n", pkg->name);
return 0;
}
}
@@ -497,14 +496,14 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,
/* see if other packages need it */
for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
pmpkg_t *lpkg = i->data;
alpm_pkg_t *lpkg = i->data;
if(_alpm_dep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) {
return(0);
return 0;
}
}
/* it's ok to remove */
return(1);
return 1;
}
/**
@@ -517,24 +516,22 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,
* @param *targs pointer to a list of packages
* @param include_explicit if 0, explicitly installed packages are not included
*/
void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)
void _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit)
{
alpm_list_t *i, *j;
ALPM_LOG_FUNC;
if(db == NULL || targs == NULL) {
return;
}
for(i = targs; i; i = i->next) {
pmpkg_t *pkg = i->data;
alpm_pkg_t *pkg = i->data;
for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
pmpkg_t *deppkg = j->data;
alpm_pkg_t *deppkg = j->data;
if(_alpm_dep_edge(pkg, deppkg)
&& can_remove_package(db, deppkg, targs, include_explicit)) {
_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets\n",
alpm_pkg_get_name(deppkg));
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding '%s' to the targets\n",
deppkg->name);
/* add it to the target list */
targs = alpm_list_add(targs, _alpm_pkg_dup(deppkg));
}
@@ -545,6 +542,7 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)
/**
* helper function for resolvedeps: search for dep satisfier in dbs
*
* @param handle the context handle
* @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
@@ -554,8 +552,8 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)
* an error code without prompting
* @return the resolved package
**/
static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
alpm_list_t *excluding, int prompt)
static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
alpm_list_t *dbs, alpm_list_t *excluding, int prompt)
{
alpm_list_t *i, *j;
int ignored = 0;
@@ -565,44 +563,44 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
/* 1. literals */
for(i = dbs; i; i = i->next) {
pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
alpm_pkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) {
if(_alpm_pkg_should_ignore(pkg)) {
if(_alpm_pkg_should_ignore(handle, pkg)) {
int install = 0;
if (prompt) {
QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
if(prompt) {
QUESTION(handle->trans, ALPM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
NULL, NULL, &install);
} else {
_alpm_log(PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);
_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);
}
if(!install) {
ignored = 1;
continue;
}
}
return(pkg);
return pkg;
}
}
/* 2. satisfiers (skip literals here) */
for(i = dbs; i; i = i->next) {
for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) {
pmpkg_t *pkg = j->data;
alpm_pkg_t *pkg = j->data;
if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 &&
!_alpm_pkg_find(excluding, pkg->name)) {
if(_alpm_pkg_should_ignore(pkg)) {
if(_alpm_pkg_should_ignore(handle, pkg)) {
int install = 0;
if (prompt) {
QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG,
if(prompt) {
QUESTION(handle->trans, ALPM_TRANS_CONV_INSTALL_IGNOREPKG,
pkg, NULL, NULL, &install);
} else {
_alpm_log(PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);
_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);
}
if(!install) {
ignored = 1;
continue;
}
}
_alpm_log(PM_LOG_DEBUG, "provider found (%s provides %s)\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "provider found (%s provides %s)\n",
pkg->name, dep->name);
providers = alpm_list_add(providers, pkg);
/* keep looking for other providers in the all dbs */
@@ -612,66 +610,69 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,
/* first check if one provider is already installed locally */
for(i = providers; i; i = i->next) {
pmpkg_t *pkg = i->data;
if (_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) {
alpm_pkg_t *pkg = i->data;
if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) {
alpm_list_free(providers);
return(pkg);
return pkg;
}
}
count = alpm_list_count(providers);
if (count >= 1) {
if(count >= 1) {
/* default to first provider if there is no QUESTION callback */
int index = 0;
if(count > 1) {
/* if there is more than one provider, we ask the user */
QUESTION(handle->trans, PM_TRANS_CONV_SELECT_PROVIDER,
QUESTION(handle->trans, ALPM_TRANS_CONV_SELECT_PROVIDER,
providers, dep, NULL, &index);
}
if(index >= 0 && index < count) {
pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index));
alpm_pkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index));
alpm_list_free(providers);
return(pkg);
return pkg;
}
alpm_list_free(providers);
providers = NULL;
}
if(ignored) { /* resolvedeps will override these */
pm_errno = PM_ERR_PKG_IGNORED;
handle->pm_errno = ALPM_ERR_PKG_IGNORED;
} else {
pm_errno = PM_ERR_PKG_NOT_FOUND;
handle->pm_errno = ALPM_ERR_PKG_NOT_FOUND;
}
return(NULL);
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 dbs an alpm_list_t* of pmdb_t where the satisfier will be searched
* @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 pmpkg_t* satisfying depstring
* @return a alpm_pkg_t* satisfying depstring
*/
pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstring)
alpm_pkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_handle_t *handle,
alpm_list_t *dbs, const char *depstring)
{
pmdepend_t *dep;
pmpkg_t *pkg;
alpm_depend_t *dep;
alpm_pkg_t *pkg;
ASSERT(dbs, return(NULL));
CHECK_HANDLE(handle, return NULL);
ASSERT(dbs, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL));
dep = _alpm_splitdep(depstring);
ASSERT(dep, return(NULL));
pkg = resolvedep(dep, dbs, NULL, 1);
ASSERT(dep, return NULL);
pkg = resolvedep(handle, dep, dbs, NULL, 1);
_alpm_dep_free(dep);
return(pkg);
return pkg;
}
/**
* Computes resolvable dependencies for a given package and adds that package
* and those resolvable dependencies to a list.
*
* @param handle the context handle
* @param localpkgs is the list of local packages
* @param dbs_sync are the sync databases
* @param pkg is the package to resolve
* @param packages is a pointer to a list of packages which will be
* searched first for any dependency packages needed to complete the
@@ -686,9 +687,9 @@ pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstri
* unresolvable dependency, in which case the [*packages] list will be
* unmodified by this function
*/
int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pkg,
alpm_list_t *preferred, alpm_list_t **packages,
alpm_list_t *remove, alpm_list_t **data)
int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
alpm_pkg_t *pkg, alpm_list_t *preferred, alpm_list_t **packages,
alpm_list_t *remove, alpm_list_t **data)
{
int ret = 0;
alpm_list_t *i, *j;
@@ -696,10 +697,14 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
alpm_list_t *deps = NULL;
alpm_list_t *packages_copy;
ALPM_LOG_FUNC;
if(_alpm_pkg_find(*packages, pkg->name) != NULL) {
return(0);
return 0;
}
if(handle->trans->flags & ALPM_TRANS_FLAG_RECURSE) {
/* removing local packages from the equation causes the entire dep chain to
* get pulled for each target- e.g., pactree -u output */
localpkgs = NULL;
}
/* Create a copy of the packages list, so that it can be restored
@@ -709,16 +714,16 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
on that list */
*packages = alpm_list_add(*packages, pkg);
_alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n");
_alpm_log(handle, ALPM_LOG_DEBUG, "started resolving dependencies\n");
for(i = alpm_list_last(*packages); i; i = i->next) {
pmpkg_t *tpkg = i->data;
alpm_pkg_t *tpkg = i->data;
targ = alpm_list_add(NULL, tpkg);
deps = alpm_checkdeps(localpkgs, 0, remove, targ);
deps = alpm_checkdeps(handle, localpkgs, remove, targ, 0);
alpm_list_free(targ);
for(j = deps; j; j = j->next) {
pmdepmissing_t *miss = j->data;
pmdepend_t *missdep = alpm_miss_get_dep(miss);
alpm_depmissing_t *miss = j->data;
alpm_depend_t *missdep = miss->depend;
/* check if one of the packages in the [*packages] list already satisfies
* this dependency */
if(find_dep_satisfier(*packages, missdep)) {
@@ -727,15 +732,15 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
}
/* check if one of the packages in the [preferred] list already satisfies
* this dependency */
pmpkg_t *spkg = find_dep_satisfier(preferred, missdep);
alpm_pkg_t *spkg = find_dep_satisfier(preferred, missdep);
if(!spkg) {
/* find a satisfier package in the given repositories */
spkg = resolvedep(missdep, dbs_sync, *packages, 0);
spkg = resolvedep(handle, missdep, handle->dbs_sync, *packages, 0);
}
if(!spkg) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
handle->pm_errno = ALPM_ERR_UNSATISFIED_DEPS;
char *missdepstring = alpm_dep_compute_string(missdep);
_alpm_log(PM_LOG_WARNING,
_alpm_log(handle, ALPM_LOG_WARNING,
_("cannot resolve \"%s\", a dependency of \"%s\"\n"),
missdepstring, tpkg->name);
free(missdepstring);
@@ -744,8 +749,9 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
}
ret = -1;
} else {
_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg));
_alpm_log(handle, ALPM_LOG_DEBUG,
"pulling dependency %s (needed by %s)\n",
spkg->name, tpkg->name);
*packages = alpm_list_add(*packages, spkg);
_alpm_depmiss_free(miss);
}
@@ -753,91 +759,51 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
alpm_list_free(deps);
}
if(handle->trans->flags & ALPM_TRANS_FLAG_NEEDED) {
/* remove any deps that were pulled that match installed version */
/* odd loop syntax so we can modify the list as we iterate */
i = *packages;
while(i) {
alpm_pkg_t *tpkg = i->data;
alpm_pkg_t *local = _alpm_db_get_pkgfromcache(
handle->db_local, tpkg->name);
if(local && _alpm_pkg_compare_versions(tpkg, local) == 0) {
/* with the NEEDED flag, packages up to date are not reinstalled */
_alpm_log(handle, ALPM_LOG_DEBUG,
"not adding dep %s-%s as it is not needed, same version\n",
local->name, local->version);
j = i;
i = i->next;
*packages = alpm_list_remove_item(*packages, j);
free(j);
} else {
i = i->next;
}
}
}
if(ret != 0) {
alpm_list_free(*packages);
*packages = packages_copy;
} else {
alpm_list_free(packages_copy);
}
_alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n");
return(ret);
_alpm_log(handle, ALPM_LOG_DEBUG, "finished resolving dependencies\n");
return ret;
}
const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(miss != NULL, return(NULL));
return(miss->target);
}
const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(miss != NULL, return(NULL));
return miss->causingpkg;
}
pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(miss != NULL, return(NULL));
return(miss->depend);
}
pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(dep != NULL, return(-1));
return(dep->mod);
}
const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(dep != NULL, return(NULL));
return(dep->name);
}
const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(dep != NULL, return(NULL));
return(dep->version);
}
/** Reverse of splitdep; make a dep string from a pmdepend_t struct.
/** 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 pmdepend_t *dep)
char SYMEXPORT *alpm_dep_compute_string(const alpm_depend_t *dep)
{
const char *name, *opr, *ver;
char *str;
size_t len;
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(dep != NULL, return(NULL));
ASSERT(dep != NULL, return NULL);
if(dep->name) {
name = dep->name;
@@ -846,22 +812,22 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)
}
switch(dep->mod) {
case PM_DEP_MOD_ANY:
case ALPM_DEP_MOD_ANY:
opr = "";
break;
case PM_DEP_MOD_GE:
case ALPM_DEP_MOD_GE:
opr = ">=";
break;
case PM_DEP_MOD_LE:
case ALPM_DEP_MOD_LE:
opr = "<=";
break;
case PM_DEP_MOD_EQ:
case ALPM_DEP_MOD_EQ:
opr = "=";
break;
case PM_DEP_MOD_LT:
case ALPM_DEP_MOD_LT:
opr = "<";
break;
case PM_DEP_MOD_GT:
case ALPM_DEP_MOD_GT:
opr = ">";
break;
default:
@@ -869,19 +835,19 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)
break;
}
if(dep->mod != PM_DEP_MOD_ANY && dep->version) {
if(dep->mod != ALPM_DEP_MOD_ANY && dep->version) {
ver = dep->version;
} else {
ver = "";
}
/* we can always compute len and print the string like this because opr
* and ver will be empty when PM_DEP_MOD_ANY is the depend type. the
* and ver will be empty when ALPM_DEP_MOD_ANY is the depend type. the
* reassignments above also ensure we do not do a strlen(NULL). */
len = strlen(name) + strlen(opr) + strlen(ver) + 1;
MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL));
MALLOC(str, len, return NULL);
snprintf(str, len, "%s%s%s", name, opr, ver);
return(str);
return str;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -27,31 +27,16 @@
#include "package.h"
#include "alpm.h"
/* Dependency */
struct __pmdepend_t {
char *name;
char *version;
unsigned long name_hash;
pmdepmod_t mod;
};
/* Missing dependency */
struct __pmdepmissing_t {
char *target;
pmdepend_t *depend;
char *causingpkg; /* this is used in case of remove dependency error only */
};
void _alpm_dep_free(pmdepend_t *dep);
pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep);
void _alpm_depmiss_free(pmdepmissing_t *miss);
alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse);
void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit);
int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pkg,
void _alpm_dep_free(alpm_depend_t *dep);
alpm_depend_t *_alpm_dep_dup(const alpm_depend_t *dep);
void _alpm_depmiss_free(alpm_depmissing_t *miss);
alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle, alpm_list_t *targets, int reverse);
void _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit);
int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs, alpm_pkg_t *pkg,
alpm_list_t *preferred, alpm_list_t **packages, alpm_list_t *remove,
alpm_list_t **data);
pmdepend_t *_alpm_splitdep(const char *depstring);
int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep);
alpm_depend_t *_alpm_splitdep(const char *depstring);
int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep);
#endif /* _ALPM_DEPS_H */

View File

@@ -39,10 +39,6 @@
#include <sys/types.h>
#endif
/* libarchive */
#include <archive.h>
#include <archive_entry.h>
/* libalpm */
#include "diskspace.h"
#include "alpm_list.h"
@@ -56,10 +52,10 @@ static int mount_point_cmp(const void *p1, const void *p2)
const alpm_mountpoint_t *mp1 = p1;
const alpm_mountpoint_t *mp2 = p2;
/* the negation will sort all mountpoints before their parent */
return(-strcmp(mp1->mount_dir, mp2->mount_dir));
return -strcmp(mp1->mount_dir, mp2->mount_dir);
}
static alpm_list_t *mount_point_list(void)
static alpm_list_t *mount_point_list(alpm_handle_t *handle)
{
alpm_list_t *mount_points = NULL, *ptr;
alpm_mountpoint_t *mp;
@@ -71,23 +67,23 @@ static alpm_list_t *mount_point_list(void)
fp = setmntent(MOUNTED, "r");
if (fp == NULL) {
return(NULL);
if(fp == NULL) {
return NULL;
}
while((mnt = getmntent(fp))) {
if(!mnt) {
_alpm_log(PM_LOG_WARNING, _("could not get filesystem information\n"));
_alpm_log(handle, ALPM_LOG_WARNING, _("could not get filesystem information\n"));
continue;
}
if(statvfs(mnt->mnt_dir, &fsp) != 0) {
_alpm_log(PM_LOG_WARNING,
_alpm_log(handle, ALPM_LOG_WARNING,
_("could not get filesystem information for %s: %s\n"),
mnt->mnt_dir, strerror(errno));
continue;
}
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
mp->mount_dir = strdup(mnt->mnt_dir);
mp->mount_dir_len = strlen(mp->mount_dir);
memcpy(&(mp->fsp), &fsp, sizeof(struct statvfs));
@@ -103,12 +99,12 @@ static alpm_list_t *mount_point_list(void)
entries = getmntinfo(&fsp, MNT_NOWAIT);
if (entries < 0) {
return(NULL);
if(entries < 0) {
return NULL;
}
for(; entries-- > 0; fsp++) {
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(ALPM_ERR_MEMORY, NULL));
mp->mount_dir = strdup(fsp->f_mntonname);
mp->mount_dir_len = strlen(mp->mount_dir);
memcpy(&(mp->fsp), fsp, sizeof(FSSTATSTYPE));
@@ -126,9 +122,9 @@ static alpm_list_t *mount_point_list(void)
mount_point_cmp);
for(ptr = mount_points; ptr != NULL; ptr = ptr->next) {
mp = ptr->data;
_alpm_log(PM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir);
_alpm_log(handle, ALPM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir);
}
return(mount_points);
return mount_points;
}
static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points,
@@ -140,25 +136,30 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points,
alpm_mountpoint_t *data = mp->data;
if(strncmp(data->mount_dir, real_path, data->mount_dir_len) == 0) {
return(data);
return data;
}
}
/* should not get here... */
return(NULL);
return NULL;
}
static int calculate_removed_size(const alpm_list_t *mount_points,
pmpkg_t *pkg)
static int calculate_removed_size(alpm_handle_t *handle,
const alpm_list_t *mount_points, alpm_pkg_t *pkg)
{
alpm_list_t *file;
size_t i;
alpm_filelist_t *filelist = alpm_pkg_get_files(pkg);
alpm_list_t *files = alpm_pkg_get_files(pkg);
for(file = files; file; file = file->next) {
if(!filelist->count) {
return 0;
}
for(i = 0; i < filelist->count; i++) {
const alpm_file_t *file = filelist->files + i;
alpm_mountpoint_t *mp;
struct stat st;
char path[PATH_MAX];
const char *filename = file->data;
const char *filename = file->name;
snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
_alpm_lstat(path, &st);
@@ -171,7 +172,7 @@ static int calculate_removed_size(const alpm_list_t *mount_points,
mp = match_mount_point(mount_points, path);
if(mp == NULL) {
_alpm_log(PM_LOG_WARNING,
_alpm_log(handle, ALPM_LOG_WARNING,
_("could not determine mount point for file %s\n"), filename);
continue;
}
@@ -182,129 +183,104 @@ static int calculate_removed_size(const alpm_list_t *mount_points,
mp->used |= USED_REMOVE;
}
return(0);
return 0;
}
static int calculate_installed_size(const alpm_list_t *mount_points,
pmpkg_t *pkg)
static int calculate_installed_size(alpm_handle_t *handle,
const alpm_list_t *mount_points, alpm_pkg_t *pkg)
{
int ret=0;
struct archive *archive;
struct archive_entry *entry;
size_t i;
alpm_filelist_t *filelist = alpm_pkg_get_files(pkg);
if ((archive = archive_read_new()) == NULL) {
pm_errno = PM_ERR_LIBARCHIVE;
ret = -1;
goto cleanup;
if(!filelist->count) {
return 0;
}
archive_read_support_compression_all(archive);
archive_read_support_format_all(archive);
if(archive_read_open_filename(archive, pkg->origin_data.file,
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
pm_errno = PM_ERR_PKG_OPEN;
ret = -1;
goto cleanup;
}
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
for(i = 0; i < filelist->count; i++) {
const alpm_file_t *file = filelist->files + i;
alpm_mountpoint_t *mp;
const char *filename;
mode_t mode;
char path[PATH_MAX];
filename = archive_entry_pathname(entry);
mode = archive_entry_mode(entry);
const char *filename = file->name;
/* libarchive reports these as zero size anyways */
/* NOTE: if we do start accounting for directory size, a dir matching a
* mountpoint needs to be attributed to the parent, not the mountpoint. */
if(S_ISDIR(mode) || S_ISLNK(mode)) {
if(S_ISDIR(file->mode) || S_ISLNK(file->mode)) {
continue;
}
/* approximate space requirements for db entries */
if(filename[0] == '.') {
filename = alpm_option_get_dbpath();
filename = alpm_option_get_dbpath(handle);
}
snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
mp = match_mount_point(mount_points, path);
if(mp == NULL) {
_alpm_log(PM_LOG_WARNING,
_alpm_log(handle, ALPM_LOG_WARNING,
_("could not determine mount point for file %s\n"), filename);
continue;
}
/* the addition of (divisor - 1) performs ceil() with integer division */
mp->blocks_needed +=
(archive_entry_size(entry) + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize;
(file->size + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize;
mp->used |= USED_INSTALL;
if(archive_read_data_skip(archive)) {
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkg->name, archive_error_string(archive));
pm_errno = PM_ERR_LIBARCHIVE;
break;
}
}
archive_read_finish(archive);
cleanup:
return(ret);
return 0;
}
int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)
int _alpm_check_diskspace(alpm_handle_t *handle)
{
alpm_list_t *mount_points, *i;
alpm_mountpoint_t *root_mp;
size_t replaces = 0, current = 0, numtargs;
int abort = 0;
int error = 0;
alpm_list_t *targ;
alpm_trans_t *trans = handle->trans;
numtargs = alpm_list_count(trans->add);
mount_points = mount_point_list();
mount_points = mount_point_list(handle);
if(mount_points == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not determine filesystem mount points\n"));
return(-1);
_alpm_log(handle, ALPM_LOG_ERROR, _("could not determine filesystem mount points\n"));
return -1;
}
root_mp = match_mount_point(mount_points, handle->root);
if(root_mp == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not determine root mount point %s\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("could not determine root mount point %s\n"),
handle->root);
return(-1);
return -1;
}
replaces = alpm_list_count(trans->remove);
if(replaces) {
numtargs += replaces;
for(targ = trans->remove; targ; targ = targ->next, current++) {
pmpkg_t *local_pkg;
alpm_pkg_t *local_pkg;
int percent = (current * 100) / numtargs;
PROGRESS(trans, PM_TRANS_PROGRESS_DISKSPACE_START, "", percent,
PROGRESS(trans, ALPM_TRANS_PROGRESS_DISKSPACE_START, "", percent,
numtargs, current);
local_pkg = targ->data;
calculate_removed_size(mount_points, local_pkg);
calculate_removed_size(handle, mount_points, local_pkg);
}
}
for(targ = trans->add; targ; targ = targ->next, current++) {
pmpkg_t *pkg, *local_pkg;
alpm_pkg_t *pkg, *local_pkg;
int percent = (current * 100) / numtargs;
PROGRESS(trans, PM_TRANS_PROGRESS_DISKSPACE_START, "", percent,
PROGRESS(trans, ALPM_TRANS_PROGRESS_DISKSPACE_START, "", percent,
numtargs, current);
pkg = targ->data;
/* is this package already installed? */
local_pkg = _alpm_db_get_pkgfromcache(db_local, pkg->name);
local_pkg = _alpm_db_get_pkgfromcache(handle->db_local, pkg->name);
if(local_pkg) {
calculate_removed_size(mount_points, local_pkg);
calculate_removed_size(handle, mount_points, local_pkg);
}
calculate_installed_size(mount_points, pkg);
calculate_installed_size(handle, mount_points, pkg);
for(i = mount_points; i; i = alpm_list_next(i)) {
alpm_mountpoint_t *data = i->data;
@@ -314,30 +290,30 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)
}
}
PROGRESS(trans, PM_TRANS_PROGRESS_DISKSPACE_START, "", 100,
PROGRESS(trans, ALPM_TRANS_PROGRESS_DISKSPACE_START, "", 100,
numtargs, current);
for(i = mount_points; i; i = alpm_list_next(i)) {
alpm_mountpoint_t *data = i->data;
if(data->used && data->read_only) {
_alpm_log(PM_LOG_ERROR, _("Partition %s is mounted read only\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("Partition %s is mounted read only\n"),
data->mount_dir);
abort = 1;
error = 1;
} else if(data->used & USED_INSTALL) {
/* cushion is roughly min(5% capacity, 20MiB) */
long fivepc = ((long)data->fsp.f_blocks / 20) + 1;
long twentymb = (20 * 1024 * 1024 / (long)data->fsp.f_bsize) + 1;
long cushion = fivepc < twentymb ? fivepc : twentymb;
_alpm_log(PM_LOG_DEBUG, "partition %s, needed %ld, cushion %ld, free %ld\n",
_alpm_log(handle, ALPM_LOG_DEBUG, "partition %s, needed %ld, cushion %ld, free %ld\n",
data->mount_dir, data->max_blocks_needed, cushion,
(unsigned long)data->fsp.f_bfree);
if(data->max_blocks_needed + cushion >= 0 &&
(unsigned long)(data->max_blocks_needed + cushion) > data->fsp.f_bfree) {
_alpm_log(PM_LOG_ERROR, _("Partition %s too full: %ld blocks needed, %ld blocks free\n"),
_alpm_log(handle, ALPM_LOG_ERROR, _("Partition %s too full: %ld blocks needed, %ld blocks free\n"),
data->mount_dir, data->max_blocks_needed + cushion,
(unsigned long)data->fsp.f_bfree);
abort = 1;
error = 1;
}
}
}
@@ -348,11 +324,11 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)
}
FREELIST(mount_points);
if(abort) {
RET_ERR(PM_ERR_DISK_SPACE, -1);
if(error) {
RET_ERR(handle, ALPM_ERR_DISK_SPACE, -1);
}
return(0);
return 0;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -46,7 +46,7 @@ typedef struct __alpm_mountpoint_t {
FSSTATSTYPE fsp;
} alpm_mountpoint_t;
int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local);
int _alpm_check_diskspace(alpm_handle_t *handle);
#endif /* _ALPM_DISKSPACE_H */

View File

@@ -29,14 +29,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
/* the following two are needed for FreeBSD's libfetch */
#include <limits.h> /* PATH_MAX */
#if defined(HAVE_SYS_PARAM_H)
#include <sys/param.h> /* MAXHOSTNAMELEN */
#endif
#ifdef HAVE_LIBFETCH
#include <fetch.h>
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif
/* libalpm */
@@ -47,112 +42,244 @@
#include "util.h"
#include "handle.h"
static char *get_filename(const char *url) {
#ifdef HAVE_LIBCURL
static double prevprogress; /* last download amount */
static const char *get_filename(const char *url)
{
char *filename = strrchr(url, '/');
if(filename != NULL) {
filename++;
}
return(filename);
return filename;
}
#ifdef HAVE_LIBFETCH
static char *get_destfile(const char *path, const char *filename) {
char *destfile;
/* len = localpath len + filename len + null */
size_t len = strlen(path) + strlen(filename) + 1;
CALLOC(destfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
snprintf(destfile, len, "%s%s", path, filename);
return(destfile);
}
static char *get_tempfile(const char *path, const char *filename) {
char *tempfile;
/* len = localpath len + filename len + '.part' len + null */
size_t len = strlen(path) + strlen(filename) + 6;
CALLOC(tempfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
snprintf(tempfile, len, "%s%s.part", path, filename);
return(tempfile);
}
static const char *gethost(struct url *fileurl)
static char *get_fullpath(const char *path, const char *filename,
const char *suffix)
{
const char *host = _("disk");
if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) {
host = fileurl->host;
}
return(host);
}
char *filepath;
/* len = localpath len + filename len + suffix len + null */
size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1;
CALLOC(filepath, len, sizeof(char), return NULL);
snprintf(filepath, len, "%s%s%s", path, filename, suffix);
int dload_interrupted;
static void inthandler(int signum)
{
dload_interrupted = 1;
return filepath;
}
#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; }
enum sighandlers { OLD = 0, NEW = 1 };
static int download_internal(const char *url, const char *localpath,
int force) {
FILE *localf = NULL;
struct stat st;
int ret = 0;
off_t dl_thisfile = 0;
ssize_t nread = 0;
char *tempfile, *destfile, *filename;
struct sigaction sig_pipe[2], sig_int[2];
static int dload_interrupted;
static void inthandler(int UNUSED signum)
{
dload_interrupted = 1;
}
off_t local_size = 0;
time_t local_time = 0;
static int curl_progress(void *file, double dltotal, double dlnow,
double UNUSED ultotal, double UNUSED ulnow)
{
struct dload_payload *payload = (struct dload_payload *)file;
double current_size, total_size;
struct url *fileurl;
struct url_stat ust;
fetchIO *dlf = NULL;
char buffer[PM_DLBUF_LEN];
filename = get_filename(url);
if(!filename) {
_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
RET_ERR(PM_ERR_SERVER_BAD_URL, -1);
/* SIGINT sent, abort by alerting curl */
if(dload_interrupted) {
return 1;
}
fileurl = fetchParseURL(url);
if(!fileurl) {
_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
RET_ERR(PM_ERR_LIBFETCH, -1);
/* none of what follows matters if the front end has no callback */
if(payload->handle->dlcb == NULL) {
return 0;
}
destfile = get_destfile(localpath, filename);
tempfile = get_tempfile(localpath, filename);
current_size = payload->initial_size + dlnow;
total_size = payload->initial_size + dltotal;
if(stat(tempfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) {
_alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation\n");
local_time = fileurl->last_modified = st.st_mtime;
local_size = fileurl->offset = (off_t)st.st_size;
dl_thisfile = st.st_size;
localf = fopen(tempfile, "ab");
} else if(!force && stat(destfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) {
_alpm_log(PM_LOG_DEBUG, "destfile found, using mtime only\n");
local_time = fileurl->last_modified = st.st_mtime;
local_size = /* no fu->off here */ (off_t)st.st_size;
if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, total_size)) {
return 0;
}
/* initialize the progress bar here to avoid displaying it when
* a repo is up to date and nothing gets downloaded */
if(DOUBLE_EQ(prevprogress, 0)) {
payload->handle->dlcb(payload->filename, 0, (long)dltotal);
}
payload->handle->dlcb(payload->filename, (long)current_size, (long)total_size);
prevprogress = current_size;
return 0;
}
static int curl_gethost(const char *url, char *buffer)
{
size_t hostlen;
char *p;
if(strncmp(url, "file://", 7) == 0) {
strcpy(buffer, _("disk"));
} else {
_alpm_log(PM_LOG_DEBUG, "no file found matching criteria, starting from scratch\n");
p = strstr(url, "//");
if(!p) {
return 1;
}
p += 2; /* jump over the found // */
hostlen = strcspn(p, "/");
if(hostlen > 255) {
/* buffer overflow imminent */
return 1;
}
snprintf(buffer, hostlen + 1, "%s", p);
}
/* pass the raw filename for passing to the callback function */
_alpm_log(PM_LOG_DEBUG, "using '%s' for download progress\n", filename);
return 0;
}
/* print proxy info for debug purposes */
_alpm_log(PM_LOG_DEBUG, "HTTP_PROXY: %s\n", getenv("HTTP_PROXY"));
_alpm_log(PM_LOG_DEBUG, "http_proxy: %s\n", getenv("http_proxy"));
_alpm_log(PM_LOG_DEBUG, "FTP_PROXY: %s\n", getenv("FTP_PROXY"));
_alpm_log(PM_LOG_DEBUG, "ftp_proxy: %s\n", getenv("ftp_proxy"));
static int utimes_long(const char *path, long seconds)
{
if(seconds != -1) {
struct timeval tv[2];
memset(&tv, 0, sizeof(tv));
tv[0].tv_sec = tv[1].tv_sec = seconds;
return utimes(path, tv);
}
return 0;
}
/* 10s timeout */
fetchTimeout = 10;
static size_t parse_headers(void *ptr, size_t size, size_t nmemb, void *user)
{
size_t realsize = size * nmemb;
const char *fptr, *endptr = NULL;
const char * const cd_header = "Content-Disposition:";
const char * const fn_key = "filename=";
struct dload_payload *payload = (struct dload_payload *)user;
if(_alpm_raw_ncmp(cd_header, ptr, strlen(cd_header)) == 0) {
if((fptr = strstr(ptr, fn_key))) {
fptr += strlen(fn_key);
/* find the end of the field, which is either a semi-colon, or the end of
* the data. As per curl_easy_setopt(3), we cannot count on headers being
* null terminated, so we look for the closing \r\n */
endptr = fptr + strcspn(fptr, ";\r\n") - 1;
/* remove quotes */
if(*fptr == '"' && *endptr == '"') {
fptr++;
endptr--;
}
STRNDUP(payload->cd_filename, fptr, endptr - fptr + 1,
RET_ERR(payload->handle, ALPM_ERR_MEMORY, realsize));
}
}
return realsize;
}
static int curl_download_internal(struct dload_payload *payload,
const char *localpath, char **final_file)
{
int ret = -1, should_unlink = 0;
FILE *localf = NULL;
const char *useragent;
const char *open_mode = "wb";
char *destfile = NULL, *tempfile = NULL, *effective_url;
/* RFC1123 states applications should support this length */
char hostname[256];
char error_buffer[CURL_ERROR_SIZE];
struct stat st;
long timecond, remote_time = -1;
double remote_size, bytes_dl;
struct sigaction sig_pipe[2], sig_int[2];
/* shortcut to our handle within the payload */
alpm_handle_t *handle = payload->handle;
if(!payload->filename) {
payload->filename = get_filename(payload->fileurl);
}
if(!payload->filename || curl_gethost(payload->fileurl, hostname) != 0) {
_alpm_log(handle, ALPM_LOG_ERROR, _("url '%s' is invalid\n"), payload->fileurl);
RET_ERR(handle, ALPM_ERR_SERVER_BAD_URL, -1);
}
if(strlen(payload->filename) > 0 && strcmp(payload->filename, ".sig") != 0) {
destfile = get_fullpath(localpath, payload->filename, "");
tempfile = get_fullpath(localpath, payload->filename, ".part");
if(!destfile || !tempfile) {
goto cleanup;
}
} else {
/* URL isn't to a file and ended with a slash */
int fd;
char randpath[PATH_MAX];
/* we can't support resuming this kind of download, so a partial transfer
* will be destroyed */
should_unlink = 1;
/* create a random filename, which is opened with O_EXCL */
snprintf(randpath, PATH_MAX, "%salpmtmp.XXXXXX", localpath);
if((fd = mkstemp(randpath)) == -1 || !(localf = fdopen(fd, open_mode))) {
unlink(randpath);
close(fd);
_alpm_log(handle, ALPM_LOG_ERROR,
_("failed to create temporary file for download\n"));
goto cleanup;
}
/* localf now points to our alpmtmp.XXXXXX */
STRDUP(tempfile, randpath, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
payload->filename = strrchr(randpath, '/') + 1;
}
error_buffer[0] = '\0';
/* the curl_easy handle is initialized with the alpm handle, so we only need
* to reset the curl handle set parameters for each time it's used. */
curl_easy_reset(handle->curl);
curl_easy_setopt(handle->curl, CURLOPT_URL, payload->fileurl);
curl_easy_setopt(handle->curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(handle->curl, CURLOPT_ERRORBUFFER, error_buffer);
curl_easy_setopt(handle->curl, CURLOPT_CONNECTTIMEOUT, 10L);
curl_easy_setopt(handle->curl, CURLOPT_FILETIME, 1L);
curl_easy_setopt(handle->curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(handle->curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(handle->curl, CURLOPT_PROGRESSFUNCTION, curl_progress);
curl_easy_setopt(handle->curl, CURLOPT_PROGRESSDATA, (void *)payload);
curl_easy_setopt(handle->curl, CURLOPT_LOW_SPEED_LIMIT, 1024L);
curl_easy_setopt(handle->curl, CURLOPT_LOW_SPEED_TIME, 10L);
curl_easy_setopt(handle->curl, CURLOPT_HEADERFUNCTION, parse_headers);
curl_easy_setopt(handle->curl, CURLOPT_WRITEHEADER, (void *)payload);
if(payload->max_size) {
curl_easy_setopt(handle->curl, CURLOPT_MAXFILESIZE, payload->max_size);
}
useragent = getenv("HTTP_USER_AGENT");
if(useragent != NULL) {
curl_easy_setopt(handle->curl, CURLOPT_USERAGENT, useragent);
}
if(!payload->allow_resume && !payload->force && stat(destfile, &st) == 0) {
/* start from scratch, but only download if our local is out of date. */
curl_easy_setopt(handle->curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
curl_easy_setopt(handle->curl, CURLOPT_TIMEVALUE, (long)st.st_mtime);
} else if(stat(tempfile, &st) == 0 && payload->allow_resume) {
/* a previous partial download exists, resume from end of file. */
open_mode = "ab";
curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, (long)st.st_size);
_alpm_log(handle, ALPM_LOG_DEBUG, "tempfile found, attempting continuation\n");
payload->initial_size = (double)st.st_size;
}
if(localf == NULL) {
localf = fopen(tempfile, open_mode);
if(localf == NULL) {
goto cleanup;
}
}
curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, localf);
/* ignore any SIGPIPE signals- these may occur if our FTP socket dies or
* something along those lines. Store the old signal handler first. */
@@ -169,169 +296,101 @@ static int download_internal(const char *url, const char *localpath,
sigaction(SIGINT, NULL, &sig_int[OLD]);
sigaction(SIGINT, &sig_int[NEW], NULL);
/* NOTE: libfetch does not reset the error code, be sure to do it before
* calls into the library */
/* TODO: if we call fetchStat() and get a redirect (disabling automagic
* redirect following), we should repeat the file locator stuff and get a new
* filename rather than only base if off the first URL, and then verify
* get_filename() didn't return ''. Of course, libfetch might not even allow
* us to even get that URL...FS#22645. This would allow us to download things
* without totally puking like
* http://www.archlinux.org/packages/community/x86_64/exim/download/ */
/* find out the remote size *and* mtime in one go. there is a lot of
* trouble in trying to do both size and "if-modified-since" logic in a
* non-stat request, so avoid it. */
fetchLastErrCode = 0;
if(fetchStat(fileurl, &ust, "") == -1) {
pm_errno = PM_ERR_LIBFETCH;
_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
filename, gethost(fileurl), fetchLastErrString);
ret = -1;
goto cleanup;
}
check_stop();
_alpm_log(PM_LOG_DEBUG, "ust.mtime: %ld local_time: %ld compare: %ld\n",
ust.mtime, local_time, local_time - ust.mtime);
_alpm_log(PM_LOG_DEBUG, "ust.size: %jd local_size: %jd compare: %jd\n",
(intmax_t)ust.size, (intmax_t)local_size, (intmax_t)(local_size - ust.size));
if(!force && ust.mtime && ust.mtime == local_time
&& ust.size && ust.size == local_size) {
/* the remote time and size values agreed with what we have, so move on
* because there is nothing more to do. */
_alpm_log(PM_LOG_DEBUG, "files are identical, skipping %s\n", filename);
ret = 1;
goto cleanup;
}
if(!ust.mtime || ust.mtime != local_time) {
_alpm_log(PM_LOG_DEBUG, "mtimes were different or unavailable, downloading %s from beginning\n", filename);
fileurl->offset = 0;
}
fetchLastErrCode = 0;
dlf = fetchGet(fileurl, "");
check_stop();
if(fetchLastErrCode != 0 || dlf == NULL) {
pm_errno = PM_ERR_LIBFETCH;
_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
filename, gethost(fileurl), fetchLastErrString);
ret = -1;
goto cleanup;
} else {
_alpm_log(PM_LOG_DEBUG, "connected to %s successfully\n", fileurl->host);
}
if(localf && fileurl->offset == 0) {
_alpm_log(PM_LOG_WARNING, _("resuming download of %s not possible; starting over\n"), filename);
fclose(localf);
localf = NULL;
} else if(fileurl->offset) {
_alpm_log(PM_LOG_DEBUG, "resuming download at position %jd\n", (intmax_t)fileurl->offset);
}
if(localf == NULL) {
_alpm_rmrf(tempfile);
fileurl->offset = (off_t)0;
dl_thisfile = 0;
localf = fopen(tempfile, "wb");
if(localf == NULL) { /* still null? */
pm_errno = PM_ERR_RETRIEVE;
_alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"),
tempfile, strerror(errno));
ret = -1;
goto cleanup;
}
}
/* Progress 0 - initialize */
if(handle->dlcb) {
handle->dlcb(filename, 0, ust.size);
prevprogress = 0;
/* perform transfer */
handle->curlerr = curl_easy_perform(handle->curl);
/* immediately unhook the progress callback */
curl_easy_setopt(handle->curl, CURLOPT_NOPROGRESS, 1L);
/* was it a success? */
if(handle->curlerr == CURLE_ABORTED_BY_CALLBACK) {
goto cleanup;
} else if(handle->curlerr != CURLE_OK) {
if(!payload->errors_ok) {
handle->pm_errno = ALPM_ERR_LIBCURL;
_alpm_log(handle, ALPM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
payload->filename, hostname, error_buffer);
} else {
_alpm_log(handle, ALPM_LOG_DEBUG, "failed retrieving file '%s' from %s : %s\n",
payload->filename, hostname, error_buffer);
}
unlink(tempfile);
goto cleanup;
}
while((nread = fetchIO_read(dlf, buffer, PM_DLBUF_LEN)) > 0) {
check_stop();
size_t nwritten = 0;
nwritten = fwrite(buffer, 1, (size_t)nread, localf);
if((nwritten != (size_t)nread) || ferror(localf)) {
pm_errno = PM_ERR_RETRIEVE;
_alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"),
tempfile, strerror(errno));
ret = -1;
goto cleanup;
}
dl_thisfile += nread;
/* retrieve info about the state of the transfer */
curl_easy_getinfo(handle->curl, CURLINFO_FILETIME, &remote_time);
curl_easy_getinfo(handle->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &remote_size);
curl_easy_getinfo(handle->curl, CURLINFO_SIZE_DOWNLOAD, &bytes_dl);
curl_easy_getinfo(handle->curl, CURLINFO_CONDITION_UNMET, &timecond);
curl_easy_getinfo(handle->curl, CURLINFO_EFFECTIVE_URL, &effective_url);
if(handle->dlcb) {
handle->dlcb(filename, dl_thisfile, ust.size);
/* time condition was met and we didn't download anything. we need to
* clean up the 0 byte .part file that's left behind. */
if(timecond == 1 && DOUBLE_EQ(bytes_dl, 0)) {
ret = 1;
unlink(tempfile);
goto cleanup;
}
/* remote_size isn't necessarily the full size of the file, just what the
* server reported as remaining to download. compare it to what curl reported
* as actually being transferred during curl_easy_perform() */
if(!DOUBLE_EQ(remote_size, -1) && !DOUBLE_EQ(bytes_dl, -1) &&
!DOUBLE_EQ(bytes_dl, remote_size)) {
handle->pm_errno = ALPM_ERR_RETRIEVE;
_alpm_log(handle, ALPM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"),
payload->filename, (intmax_t)bytes_dl, (intmax_t)remote_size);
goto cleanup;
}
if(payload->cd_filename) {
/* content-disposition header has a better name for our file */
free(destfile);
destfile = get_fullpath(localpath, payload->cd_filename, "");
} else {
const char *effective_filename = strrchr(effective_url, '/');
if(effective_filename) {
effective_filename++;
/* if destfile was never set, we wrote to a tempfile. even if destfile is
* set, we may have followed some redirects and the effective url may
* have a better suggestion as to what to name our file. in either case,
* refactor destfile to this newly derived name. */
if(!destfile || strcmp(effective_filename, strrchr(destfile, '/') + 1) != 0) {
free(destfile);
destfile = get_fullpath(localpath, effective_filename, "");
}
}
}
/* did the transfer complete normally? */
if (nread == -1) {
/* not PM_ERR_LIBFETCH here because libfetch error string might be empty */
pm_errno = PM_ERR_RETRIEVE;
_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s\n"),
filename, gethost(fileurl));
ret = -1;
goto cleanup;
}
if (ust.size != -1 && dl_thisfile < ust.size) {
pm_errno = PM_ERR_RETRIEVE;
_alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"),
filename, (intmax_t)dl_thisfile, (intmax_t)ust.size);
ret = -1;
goto cleanup;
}
/* probably safer to close the file descriptors now before renaming the file,
* for example to make sure the buffers are flushed.
*/
fclose(localf);
localf = NULL;
fetchIO_close(dlf);
dlf = NULL;
/* set the times on the file to the same as that of the remote file */
if(ust.mtime) {
struct timeval tv[2];
memset(&tv, 0, sizeof(tv));
tv[0].tv_sec = ust.atime;
tv[1].tv_sec = ust.mtime;
utimes(tempfile, tv);
}
if(rename(tempfile, destfile)) {
_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
tempfile, destfile, strerror(errno));
ret = -1;
goto cleanup;
}
ret = 0;
cleanup:
if(localf != NULL) {
fclose(localf);
utimes_long(tempfile, remote_time);
}
if(ret == 0) {
if(rename(tempfile, destfile)) {
_alpm_log(handle, ALPM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),
tempfile, destfile, strerror(errno));
ret = -1;
} else if(final_file) {
*final_file = strdup(strrchr(destfile, '/') + 1);
}
}
if(dload_interrupted && should_unlink) {
unlink(tempfile);
}
FREE(tempfile);
FREE(destfile);
if(localf != NULL) {
/* if we still had a local file open, we got interrupted. set the mtimes on
* the file accordingly. */
fflush(localf);
if(ust.mtime) {
struct timeval tv[2];
memset(&tv, 0, sizeof(tv));
tv[0].tv_sec = ust.atime;
tv[1].tv_sec = ust.mtime;
futimes(fileno(localf), tv);
}
fclose(localf);
}
if(dlf != NULL) {
fetchIO_close(dlf);
}
fetchFreeURL(fileurl);
/* restore the old signal handlers */
sigaction(SIGINT, &sig_int[OLD], NULL);
@@ -341,106 +400,104 @@ cleanup:
raise(SIGINT);
}
return(ret);
return ret;
}
#endif
static int download(const char *url, const char *localpath,
int force) {
/** Download a file given by a URL to a local directory.
* Does not overwrite an existing file if the download fails.
* @param payload the payload context
* @param localpath the directory to save the file in
* @param final_file the real name of the downloaded file (may be NULL)
* @return 0 on success, -1 on error (pm_errno is set accordingly if errors_ok == 0)
*/
int _alpm_download(struct dload_payload *payload, const char *localpath,
char **final_file)
{
alpm_handle_t *handle = payload->handle;
if(handle->fetchcb == NULL) {
#ifdef HAVE_LIBFETCH
return(download_internal(url, localpath, force));
#ifdef HAVE_LIBCURL
return curl_download_internal(payload, localpath, final_file);
#else
RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
RET_ERR(handle, ALPM_ERR_EXTERNAL_DOWNLOAD, -1);
#endif
} else {
int ret = handle->fetchcb(url, localpath, force);
if(ret == -1) {
RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
int ret = handle->fetchcb(payload->fileurl, localpath, payload->force);
if(ret == -1 && !payload->errors_ok) {
RET_ERR(handle, ALPM_ERR_EXTERNAL_DOWNLOAD, -1);
}
return(ret);
return ret;
}
}
/*
* Download a single file
* - servers must be a list of urls WITHOUT trailing slashes.
*
* RETURN: 0 for successful download
* 1 if the files are identical
* -1 on error
*/
int _alpm_download_single_file(const char *filename,
alpm_list_t *servers, const char *localpath,
int force)
{
alpm_list_t *i;
int ret = -1;
ASSERT(servers != NULL, RET_ERR(PM_ERR_SERVER_NONE, -1));
for(i = servers; i; i = i->next) {
const char *server = i->data;
char *fileurl = NULL;
size_t len;
/* print server + filename into a buffer */
len = strlen(server) + strlen(filename) + 2;
CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
snprintf(fileurl, len, "%s/%s", server, filename);
ret = download(fileurl, localpath, force);
FREE(fileurl);
if(ret != -1) {
break;
}
}
return(ret);
}
int _alpm_download_files(alpm_list_t *files,
alpm_list_t *servers, const char *localpath)
{
int ret = 0;
alpm_list_t *lp;
for(lp = files; lp; lp = lp->next) {
char *filename = lp->data;
if(_alpm_download_single_file(filename, servers,
localpath, 0) == -1) {
ret++;
}
}
return(ret);
}
/** Fetch a remote pkg. */
char SYMEXPORT *alpm_fetch_pkgurl(const char *url)
char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
{
char *filename, *filepath;
char *filepath;
const char *cachedir;
char *final_file = NULL;
struct dload_payload *payload;
int ret;
ALPM_LOG_FUNC;
filename = get_filename(url);
CHECK_HANDLE(handle, return NULL);
/* find a valid cache dir to download to */
cachedir = _alpm_filecache_setup();
cachedir = _alpm_filecache_setup(handle);
CALLOC(payload, 1, sizeof(*payload), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
payload->handle = handle;
payload->fileurl = strdup(url);
payload->allow_resume = 1;
/* download the file */
ret = download(url, cachedir, 0);
ret = _alpm_download(payload, cachedir, &final_file);
if(ret == -1) {
_alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url);
return(NULL);
_alpm_log(handle, ALPM_LOG_WARNING, _("failed to download %s\n"), url);
return NULL;
}
_alpm_log(handle, ALPM_LOG_DEBUG, "successfully downloaded %s\n", url);
/* attempt to download the signature */
if(ret == 0 && (handle->siglevel & ALPM_SIG_PACKAGE)) {
char *sig_final_file = NULL;
size_t len;
struct dload_payload *sig_payload;
CALLOC(sig_payload, 1, sizeof(*sig_payload), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
len = strlen(url) + 5;
CALLOC(sig_payload->fileurl, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
snprintf(sig_payload->fileurl, len, "%s.sig", url);
sig_payload->handle = handle;
sig_payload->force = 1;
sig_payload->errors_ok = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL);
ret = _alpm_download(sig_payload, cachedir, &sig_final_file);
if(ret == -1 && !sig_payload->errors_ok) {
_alpm_log(handle, ALPM_LOG_WARNING, _("failed to download %s\n"), sig_payload->fileurl);
/* Warn now, but don't return NULL. We will fail later during package
* load time. */
} else if(ret == 0) {
_alpm_log(handle, ALPM_LOG_DEBUG, "successfully downloaded %s\n", sig_payload->fileurl);
}
FREE(sig_final_file);
_alpm_dload_payload_free(sig_payload);
}
_alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", url);
/* we should be able to find the file the second time around */
filepath = _alpm_filecache_find(filename);
return(filepath);
filepath = _alpm_filecache_find(handle, final_file);
FREE(final_file);
_alpm_dload_payload_free(payload);
return filepath;
}
void _alpm_dload_payload_free(struct dload_payload *payload) {
ASSERT(payload, return);
FREE(payload->fileurl);
FREE(payload->cd_filename);
FREE(payload);
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -25,14 +25,22 @@
#include <time.h>
#define PM_DLBUF_LEN (1024 * 16)
struct dload_payload {
alpm_handle_t *handle;
const char *filename;
char *cd_filename;
char *fileurl;
double initial_size;
long max_size;
int force;
int allow_resume;
int errors_ok;
};
int _alpm_download_single_file(const char *filename,
alpm_list_t *servers, const char *localpath,
int force);
void _alpm_dload_payload_free(struct dload_payload *payload);
int _alpm_download_files(alpm_list_t *files,
alpm_list_t *servers, const char *localpath);
int _alpm_download(struct dload_payload *payload, const char *localpath,
char **final_file);
#endif /* _ALPM_DLOAD_H */

View File

@@ -20,141 +20,142 @@
#include "config.h"
/* TODO: needed for the libfetch stuff, unfortunately- we should kill it */
#include <stdio.h>
/* the following two are needed for FreeBSD's libfetch */
#include <limits.h> /* PATH_MAX */
#if defined(HAVE_SYS_PARAM_H)
#include <sys/param.h> /* MAXHOSTNAMELEN */
#endif
#ifdef HAVE_LIBFETCH
#include <fetch.h> /* fetchLastErrString */
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif
/* libalpm */
#include "util.h"
#include "alpm.h"
#include "handle.h"
const char SYMEXPORT *alpm_strerrorlast(void)
enum _alpm_errno_t SYMEXPORT alpm_errno(alpm_handle_t *handle)
{
return alpm_strerror(pm_errno);
return handle->pm_errno;
}
const char SYMEXPORT *alpm_strerror(int err)
const char SYMEXPORT *alpm_strerror(enum _alpm_errno_t err)
{
switch(err) {
/* System */
case PM_ERR_MEMORY:
case ALPM_ERR_MEMORY:
return _("out of memory!");
case PM_ERR_SYSTEM:
case ALPM_ERR_SYSTEM:
return _("unexpected system error");
case PM_ERR_BADPERMS:
case ALPM_ERR_BADPERMS:
return _("insufficient privileges");
case PM_ERR_NOT_A_FILE:
case ALPM_ERR_NOT_A_FILE:
return _("could not find or read file");
case PM_ERR_NOT_A_DIR:
case ALPM_ERR_NOT_A_DIR:
return _("could not find or read directory");
case PM_ERR_WRONG_ARGS:
case ALPM_ERR_WRONG_ARGS:
return _("wrong or NULL argument passed");
case PM_ERR_DISK_SPACE:
case ALPM_ERR_DISK_SPACE:
return _("not enough free disk space");
/* Interface */
case PM_ERR_HANDLE_NULL:
case ALPM_ERR_HANDLE_NULL:
return _("library not initialized");
case PM_ERR_HANDLE_NOT_NULL:
case ALPM_ERR_HANDLE_NOT_NULL:
return _("library already initialized");
case PM_ERR_HANDLE_LOCK:
case ALPM_ERR_HANDLE_LOCK:
return _("unable to lock database");
/* Databases */
case PM_ERR_DB_OPEN:
case ALPM_ERR_DB_OPEN:
return _("could not open database");
case PM_ERR_DB_CREATE:
case ALPM_ERR_DB_CREATE:
return _("could not create database");
case PM_ERR_DB_NULL:
case ALPM_ERR_DB_NULL:
return _("database not initialized");
case PM_ERR_DB_NOT_NULL:
case ALPM_ERR_DB_NOT_NULL:
return _("database already registered");
case PM_ERR_DB_NOT_FOUND:
case ALPM_ERR_DB_NOT_FOUND:
return _("could not find database");
case PM_ERR_DB_VERSION:
case ALPM_ERR_DB_INVALID:
return _("invalid or corrupted database");
case ALPM_ERR_DB_INVALID_SIG:
return _("invalid or corrupted database (PGP signature)");
case ALPM_ERR_DB_VERSION:
return _("database is incorrect version");
case PM_ERR_DB_WRITE:
case ALPM_ERR_DB_WRITE:
return _("could not update database");
case PM_ERR_DB_REMOVE:
case ALPM_ERR_DB_REMOVE:
return _("could not remove database entry");
/* Servers */
case PM_ERR_SERVER_BAD_URL:
case ALPM_ERR_SERVER_BAD_URL:
return _("invalid url for server");
case PM_ERR_SERVER_NONE:
case ALPM_ERR_SERVER_NONE:
return _("no servers configured for repository");
/* Transactions */
case PM_ERR_TRANS_NOT_NULL:
case ALPM_ERR_TRANS_NOT_NULL:
return _("transaction already initialized");
case PM_ERR_TRANS_NULL:
case ALPM_ERR_TRANS_NULL:
return _("transaction not initialized");
case PM_ERR_TRANS_DUP_TARGET:
case ALPM_ERR_TRANS_DUP_TARGET:
return _("duplicate target");
case PM_ERR_TRANS_NOT_INITIALIZED:
case ALPM_ERR_TRANS_NOT_INITIALIZED:
return _("transaction not initialized");
case PM_ERR_TRANS_NOT_PREPARED:
case ALPM_ERR_TRANS_NOT_PREPARED:
return _("transaction not prepared");
case PM_ERR_TRANS_ABORT:
case ALPM_ERR_TRANS_ABORT:
return _("transaction aborted");
case PM_ERR_TRANS_TYPE:
case ALPM_ERR_TRANS_TYPE:
return _("operation not compatible with the transaction type");
case PM_ERR_TRANS_NOT_LOCKED:
case ALPM_ERR_TRANS_NOT_LOCKED:
return _("transaction commit attempt when database is not locked");
/* Packages */
case PM_ERR_PKG_NOT_FOUND:
case ALPM_ERR_PKG_NOT_FOUND:
return _("could not find or read package");
case PM_ERR_PKG_IGNORED:
case ALPM_ERR_PKG_IGNORED:
return _("operation cancelled due to ignorepkg");
case PM_ERR_PKG_INVALID:
case ALPM_ERR_PKG_INVALID:
return _("invalid or corrupted package");
case PM_ERR_PKG_OPEN:
case ALPM_ERR_PKG_INVALID_CHECKSUM:
return _("invalid or corrupted package (checksum)");
case ALPM_ERR_PKG_INVALID_SIG:
return _("invalid or corrupted package (PGP signature)");
case ALPM_ERR_PKG_OPEN:
return _("cannot open package file");
case PM_ERR_PKG_CANT_REMOVE:
case ALPM_ERR_PKG_CANT_REMOVE:
return _("cannot remove all files for package");
case PM_ERR_PKG_INVALID_NAME:
case ALPM_ERR_PKG_INVALID_NAME:
return _("package filename is not valid");
case PM_ERR_PKG_INVALID_ARCH:
case ALPM_ERR_PKG_INVALID_ARCH:
return _("package architecture is not valid");
case PM_ERR_PKG_REPO_NOT_FOUND:
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 PM_ERR_DLT_INVALID:
case ALPM_ERR_DLT_INVALID:
return _("invalid or corrupted delta");
case PM_ERR_DLT_PATCHFAILED:
case ALPM_ERR_DLT_PATCHFAILED:
return _("delta patch failed");
/* Dependencies */
case PM_ERR_UNSATISFIED_DEPS:
case ALPM_ERR_UNSATISFIED_DEPS:
return _("could not satisfy dependencies");
case PM_ERR_CONFLICTING_DEPS:
case ALPM_ERR_CONFLICTING_DEPS:
return _("conflicting dependencies");
case PM_ERR_FILE_CONFLICTS:
case ALPM_ERR_FILE_CONFLICTS:
return _("conflicting files");
/* Miscellaenous */
case PM_ERR_RETRIEVE:
case ALPM_ERR_RETRIEVE:
return _("failed to retrieve some files");
case PM_ERR_WRITE:
return _("failed to copy some file");
case PM_ERR_INVALID_REGEX:
case ALPM_ERR_INVALID_REGEX:
return _("invalid regular expression");
/* Errors from external libraries- our own wrapper error */
case PM_ERR_LIBARCHIVE:
case ALPM_ERR_LIBARCHIVE:
/* it would be nice to use archive_error_string() here, but that
* requires the archive struct, so we can't. Just use a generic
* error string instead. */
return _("libarchive error");
case PM_ERR_LIBFETCH:
#ifdef HAVE_LIBFETCH
return fetchLastErrString;
#else
/* obviously shouldn't get here... */
case ALPM_ERR_LIBCURL:
return _("download library error");
#endif
case PM_ERR_EXTERNAL_DOWNLOAD:
case ALPM_ERR_GPGME:
return _("gpgme error");
case ALPM_ERR_EXTERNAL_DOWNLOAD:
return _("error invoking external downloader");
/* Unknown error! */
default:

41
lib/libalpm/graph.c Normal file
View File

@@ -0,0 +1,41 @@
/*
* graph.c - helpful graph structure and setup/teardown methods
*
* Copyright (c) 2007-2011 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/>.
*/
#include "config.h"
#include "graph.h"
#include "util.h"
#include "log.h"
alpm_graph_t *_alpm_graph_new(void)
{
alpm_graph_t *graph = NULL;
CALLOC(graph, 1, sizeof(alpm_graph_t), return NULL);
return graph;
}
void _alpm_graph_free(void *data)
{
alpm_graph_t *graph = data;
alpm_list_free(graph->children);
free(graph);
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -1,8 +1,7 @@
/*
* graph.h - helpful graph structure and setup/teardown methods
*
* Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2007-2011 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
@@ -17,34 +16,27 @@
* 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_GRAPH_H
#define _ALPM_GRAPH_H
#include "config.h" /* ensure off_t is correct length */
#include <sys/types.h> /* off_t */
#include "alpm_list.h"
#include "util.h" /* CALLOC() */
struct __pmgraph_t {
typedef struct __alpm_graph_t {
char state; /* 0: untouched, -1: entered, other: leaving time */
void *data;
off_t weight; /* weight of the node */
struct __pmgraph_t *parent; /* where did we come from? */
void *data;
struct __alpm_graph_t *parent; /* where did we come from? */
alpm_list_t *children;
alpm_list_t *childptr; /* points to a child in children list */
};
typedef struct __pmgraph_t pmgraph_t;
} alpm_graph_t;
static pmgraph_t *_alpm_graph_new(void)
{
pmgraph_t *graph = NULL;
alpm_graph_t *_alpm_graph_new(void);
void _alpm_graph_free(void *data);
CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL));
return(graph);
}
static void _alpm_graph_free(void *data)
{
pmgraph_t *graph = data;
alpm_list_free(graph->children);
free(graph);
}
#endif /* _ALPM_GRAPH_H */
/* vim: set ts=2 sw=2 noet: */

View File

@@ -21,7 +21,6 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* libalpm */
@@ -31,22 +30,18 @@
#include "log.h"
#include "alpm.h"
pmgrp_t *_alpm_grp_new(const char *name)
alpm_group_t *_alpm_group_new(const char *name)
{
pmgrp_t* grp;
alpm_group_t* grp;
ALPM_LOG_FUNC;
CALLOC(grp, 1, sizeof(alpm_group_t), return NULL);
STRDUP(grp->name, name, free(grp); return NULL);
CALLOC(grp, 1, sizeof(pmgrp_t), RET_ERR(PM_ERR_MEMORY, NULL));
STRDUP(grp->name, name, RET_ERR(PM_ERR_MEMORY, NULL));
return(grp);
return grp;
}
void _alpm_grp_free(pmgrp_t *grp)
void _alpm_group_free(alpm_group_t *grp)
{
ALPM_LOG_FUNC;
if(grp == NULL) {
return;
}
@@ -57,23 +52,4 @@ void _alpm_grp_free(pmgrp_t *grp)
FREE(grp);
}
const char SYMEXPORT *alpm_grp_get_name(const pmgrp_t *grp)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(grp != NULL, return(NULL));
return grp->name;
}
alpm_list_t SYMEXPORT *alpm_grp_get_pkgs(const pmgrp_t *grp)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(grp != NULL, return(NULL));
return grp->packages;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -22,15 +22,8 @@
#include "alpm.h"
struct __pmgrp_t {
/** group name */
char *name;
/** list of pmpkg_t packages */
alpm_list_t *packages;
};
pmgrp_t *_alpm_grp_new(const char *name);
void _alpm_grp_free(pmgrp_t *grp);
alpm_group_t *_alpm_group_new(const char *name);
void _alpm_group_free(alpm_group_t *grp);
#endif /* _ALPM_GROUP_H */

View File

@@ -22,14 +22,14 @@
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <syslog.h>
#include <time.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
/* libalpm */
#include "handle.h"
@@ -39,22 +39,22 @@
#include "trans.h"
#include "alpm.h"
/* global var for handle (private to libalpm) */
pmhandle_t *handle = NULL;
pmhandle_t *_alpm_handle_new()
alpm_handle_t *_alpm_handle_new()
{
pmhandle_t *handle;
alpm_handle_t *handle;
CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
return(handle);
#ifdef HAVE_LIBGPGME
handle->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
#endif
return handle;
}
void _alpm_handle_free(pmhandle_t *handle)
void _alpm_handle_free(alpm_handle_t *handle)
{
ALPM_LOG_FUNC;
if(handle == NULL) {
return;
}
@@ -69,6 +69,11 @@ void _alpm_handle_free(pmhandle_t *handle)
closelog();
}
#ifdef HAVE_LIBCURL
/* release curl handle */
curl_easy_cleanup(handle->curl);
#endif
/* free memory */
_alpm_trans_free(handle->trans);
FREE(handle->root);
@@ -77,371 +82,326 @@ void _alpm_handle_free(pmhandle_t *handle)
FREE(handle->logfile);
FREE(handle->lockfile);
FREE(handle->arch);
FREE(handle->gpgdir);
FREELIST(handle->dbs_sync);
FREELIST(handle->noupgrade);
FREELIST(handle->noextract);
FREELIST(handle->ignorepkg);
FREELIST(handle->ignoregrp);
FREELIST(handle->ignoregroup);
FREE(handle);
}
alpm_cb_log SYMEXPORT alpm_option_get_logcb()
/** Lock the database */
int _alpm_handle_lock(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
int fd;
char *dir, *ptr;
ASSERT(handle->lockfile != NULL, return -1);
ASSERT(handle->lckstream == NULL, return 0);
/* create the dir of the lockfile first */
dir = strdup(handle->lockfile);
ptr = strrchr(dir, '/');
if(ptr) {
*ptr = '\0';
}
if(_alpm_makepath(dir)) {
FREE(dir);
return -1;
}
FREE(dir);
do {
fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000);
} while(fd == -1 && errno == EINTR);
if(fd > 0) {
FILE *f = fdopen(fd, "w");
fprintf(f, "%ld\n", (long)getpid());
fflush(f);
fsync(fd);
handle->lckstream = f;
return 0;
}
return -1;
}
/** Remove a lock file */
int _alpm_handle_unlock(alpm_handle_t *handle)
{
ASSERT(handle->lockfile != NULL, return -1);
ASSERT(handle->lckstream != NULL, return 0);
if(handle->lckstream != NULL) {
fclose(handle->lckstream);
handle->lckstream = NULL;
}
if(unlink(handle->lockfile) && errno != ENOENT) {
return -1;
}
return 0;
}
alpm_cb_log SYMEXPORT alpm_option_get_logcb(alpm_handle_t *handle)
{
CHECK_HANDLE(handle, return NULL);
return handle->logcb;
}
alpm_cb_download SYMEXPORT alpm_option_get_dlcb()
alpm_cb_download SYMEXPORT alpm_option_get_dlcb(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->dlcb;
}
alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb()
alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->fetchcb;
}
alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb()
alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->totaldlcb;
}
const char SYMEXPORT *alpm_option_get_root()
const char SYMEXPORT *alpm_option_get_root(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->root;
}
const char SYMEXPORT *alpm_option_get_dbpath()
const char SYMEXPORT *alpm_option_get_dbpath(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->dbpath;
}
alpm_list_t SYMEXPORT *alpm_option_get_cachedirs()
alpm_list_t SYMEXPORT *alpm_option_get_cachedirs(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->cachedirs;
}
const char SYMEXPORT *alpm_option_get_logfile()
const char SYMEXPORT *alpm_option_get_logfile(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->logfile;
}
const char SYMEXPORT *alpm_option_get_lockfile()
const char SYMEXPORT *alpm_option_get_lockfile(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->lockfile;
}
int SYMEXPORT alpm_option_get_usesyslog()
const char SYMEXPORT *alpm_option_get_gpgdir(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return -1;
}
CHECK_HANDLE(handle, return NULL);
return handle->gpgdir;
}
int SYMEXPORT alpm_option_get_usesyslog(alpm_handle_t *handle)
{
CHECK_HANDLE(handle, return -1);
return handle->usesyslog;
}
alpm_list_t SYMEXPORT *alpm_option_get_noupgrades()
alpm_list_t SYMEXPORT *alpm_option_get_noupgrades(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->noupgrade;
}
alpm_list_t SYMEXPORT *alpm_option_get_noextracts()
alpm_list_t SYMEXPORT *alpm_option_get_noextracts(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->noextract;
}
alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs()
alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->ignorepkg;
}
alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps()
alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->ignoregrp;
CHECK_HANDLE(handle, return NULL);
return handle->ignoregroup;
}
const char SYMEXPORT *alpm_option_get_arch()
const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->arch;
}
int SYMEXPORT alpm_option_get_usedelta()
int SYMEXPORT alpm_option_get_usedelta(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return -1;
}
CHECK_HANDLE(handle, return -1);
return handle->usedelta;
}
int SYMEXPORT alpm_option_get_checkspace()
int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return -1;
}
CHECK_HANDLE(handle, return -1);
return handle->checkspace;
}
pmdb_t SYMEXPORT *alpm_option_get_localdb()
alpm_db_t SYMEXPORT *alpm_option_get_localdb(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->db_local;
}
alpm_list_t SYMEXPORT *alpm_option_get_syncdbs()
alpm_list_t SYMEXPORT *alpm_option_get_syncdbs(alpm_handle_t *handle)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
CHECK_HANDLE(handle, return NULL);
return handle->dbs_sync;
}
void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb)
int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return;
}
CHECK_HANDLE(handle, return -1);
handle->logcb = cb;
return 0;
}
void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb)
int SYMEXPORT alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return;
}
CHECK_HANDLE(handle, return -1);
handle->dlcb = cb;
return 0;
}
void SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb)
int SYMEXPORT alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return;
}
CHECK_HANDLE(handle, return -1);
handle->fetchcb = cb;
return 0;
}
void SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb)
int SYMEXPORT alpm_option_set_totaldlcb(alpm_handle_t *handle, alpm_cb_totaldl cb)
{
if (handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return;
}
CHECK_HANDLE(handle, return -1);
handle->totaldlcb = cb;
return 0;
}
int SYMEXPORT alpm_option_set_root(const char *root)
{
static char *canonicalize_path(const char *path) {
char *new_path;
size_t len;
/* verify path ends in a '/' */
len = strlen(path);
if(path[len - 1] != '/') {
len += 1;
}
CALLOC(new_path, len + 1, sizeof(char), return NULL);
strcpy(new_path, path);
new_path[len - 1] = '/';
return new_path;
}
enum _alpm_errno_t _alpm_set_directory_option(const char *value,
char **storage, int must_exist)
{
struct stat st;
char *realroot;
size_t rootlen;
char *real = NULL;
const char *path;
ALPM_LOG_FUNC;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(!root) {
pm_errno = PM_ERR_WRONG_ARGS;
return(-1);
path = value;
if(!path) {
return ALPM_ERR_WRONG_ARGS;
}
if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) {
pm_errno = PM_ERR_NOT_A_DIR;
return(-1);
if(must_exist) {
if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
return ALPM_ERR_NOT_A_DIR;
}
CALLOC(real, PATH_MAX, sizeof(char), return ALPM_ERR_MEMORY);
if(!realpath(path, real)) {
free(real);
return ALPM_ERR_NOT_A_DIR;
}
path = real;
}
realroot = calloc(PATH_MAX+1, sizeof(char));
if(!realpath(root, realroot)) {
FREE(realroot);
pm_errno = PM_ERR_NOT_A_DIR;
return(-1);
if(*storage) {
FREE(*storage);
}
/* verify root ends in a '/' */
rootlen = strlen(realroot);
if(realroot[rootlen-1] != '/') {
rootlen += 1;
*storage = canonicalize_path(path);
if(!*storage) {
return ALPM_ERR_MEMORY;
}
if(handle->root) {
FREE(handle->root);
}
handle->root = calloc(rootlen + 1, sizeof(char));
strncpy(handle->root, realroot, rootlen);
handle->root[rootlen-1] = '/';
FREE(realroot);
_alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root);
return(0);
free(real);
return 0;
}
int SYMEXPORT alpm_option_set_dbpath(const char *dbpath)
{
struct stat st;
size_t dbpathlen, lockfilelen;
const char *lf = "db.lck";
ALPM_LOG_FUNC;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(!dbpath) {
pm_errno = PM_ERR_WRONG_ARGS;
return(-1);
}
if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) {
pm_errno = PM_ERR_NOT_A_DIR;
return(-1);
}
/* verify dbpath ends in a '/' */
dbpathlen = strlen(dbpath);
if(dbpath[dbpathlen-1] != '/') {
dbpathlen += 1;
}
if(handle->dbpath) {
FREE(handle->dbpath);
}
handle->dbpath = calloc(dbpathlen+1, sizeof(char));
strncpy(handle->dbpath, dbpath, dbpathlen);
handle->dbpath[dbpathlen-1] = '/';
_alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath);
if(handle->lockfile) {
FREE(handle->lockfile);
}
lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1;
handle->lockfile = calloc(lockfilelen, sizeof(char));
snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf);
_alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile);
return(0);
}
int SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
int SYMEXPORT alpm_option_add_cachedir(alpm_handle_t *handle, const char *cachedir)
{
char *newcachedir;
size_t cachedirlen;
ALPM_LOG_FUNC;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(!cachedir) {
pm_errno = PM_ERR_WRONG_ARGS;
return(-1);
}
CHECK_HANDLE(handle, return -1);
ASSERT(cachedir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
/* don't stat the cachedir yet, as it may not even be needed. we can
* fail later if it is needed and the path is invalid. */
/* verify cachedir ends in a '/' */
cachedirlen = strlen(cachedir);
if(cachedir[cachedirlen-1] != '/') {
cachedirlen += 1;
newcachedir = canonicalize_path(cachedir);
if(!newcachedir) {
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
}
newcachedir = calloc(cachedirlen + 1, sizeof(char));
strncpy(newcachedir, cachedir, cachedirlen);
newcachedir[cachedirlen-1] = '/';
handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
_alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir);
return(0);
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir);
return 0;
}
void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
int SYMEXPORT alpm_option_set_cachedirs(alpm_handle_t *handle, alpm_list_t *cachedirs)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
if(handle->cachedirs) FREELIST(handle->cachedirs);
if(cachedirs) handle->cachedirs = cachedirs;
alpm_list_t *i;
CHECK_HANDLE(handle, return -1);
if(handle->cachedirs) {
FREELIST(handle->cachedirs);
}
for(i = cachedirs; i; i = i->next) {
int ret = alpm_option_add_cachedir(handle, i->data);
if(ret) {
return ret;
}
}
return 0;
}
int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir)
int SYMEXPORT alpm_option_remove_cachedir(alpm_handle_t *handle, const char *cachedir)
{
char *vdata = NULL;
char *newcachedir;
size_t cachedirlen;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
/* verify cachedir ends in a '/' */
cachedirlen = strlen(cachedir);
if(cachedir[cachedirlen-1] != '/') {
cachedirlen += 1;
CHECK_HANDLE(handle, return -1);
ASSERT(cachedir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
newcachedir = canonicalize_path(cachedir);
if(!newcachedir) {
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
}
newcachedir = calloc(cachedirlen + 1, sizeof(char));
strncpy(newcachedir, cachedir, cachedirlen);
newcachedir[cachedirlen-1] = '/';
handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
FREE(newcachedir);
if(vdata != NULL) {
FREE(vdata);
return(1);
return 1;
}
return(0);
return 0;
}
int SYMEXPORT alpm_option_set_logfile(const char *logfile)
int SYMEXPORT alpm_option_set_logfile(alpm_handle_t *handle, const char *logfile)
{
char *oldlogfile = handle->logfile;
ALPM_LOG_FUNC;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(handle, return -1);
if(!logfile) {
pm_errno = PM_ERR_WRONG_ARGS;
return(-1);
handle->pm_errno = ALPM_ERR_WRONG_ARGS;
return -1;
}
handle->logfile = strdup(logfile);
@@ -455,133 +415,186 @@ int SYMEXPORT alpm_option_set_logfile(const char *logfile)
fclose(handle->logstream);
handle->logstream = NULL;
}
_alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
return(0);
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
return 0;
}
void SYMEXPORT alpm_option_set_usesyslog(int usesyslog)
int SYMEXPORT alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
if(!gpgdir) {
handle->pm_errno = ALPM_ERR_WRONG_ARGS;
return -1;
}
if(handle->gpgdir) {
FREE(handle->gpgdir);
}
handle->gpgdir = strdup(gpgdir);
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'gpgdir' = %s\n", handle->gpgdir);
return 0;
}
int SYMEXPORT alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog)
{
CHECK_HANDLE(handle, return -1);
handle->usesyslog = usesyslog;
return 0;
}
void SYMEXPORT alpm_option_add_noupgrade(const char *pkg)
int SYMEXPORT alpm_option_add_noupgrade(alpm_handle_t *handle, const char *pkg)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
return 0;
}
void SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade)
int SYMEXPORT alpm_option_set_noupgrades(alpm_handle_t *handle, alpm_list_t *noupgrade)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
if(handle->noupgrade) FREELIST(handle->noupgrade);
if(noupgrade) handle->noupgrade = noupgrade;
handle->noupgrade = alpm_list_strdup(noupgrade);
return 0;
}
int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
int SYMEXPORT alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *pkg)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(handle, return -1);
handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
if(vdata != NULL) {
FREE(vdata);
return(1);
return 1;
}
return(0);
return 0;
}
void SYMEXPORT alpm_option_add_noextract(const char *pkg)
int SYMEXPORT alpm_option_add_noextract(alpm_handle_t *handle, const char *pkg)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
return 0;
}
void SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract)
int SYMEXPORT alpm_option_set_noextracts(alpm_handle_t *handle, alpm_list_t *noextract)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
if(handle->noextract) FREELIST(handle->noextract);
if(noextract) handle->noextract = noextract;
handle->noextract = alpm_list_strdup(noextract);
return 0;
}
int SYMEXPORT alpm_option_remove_noextract(const char *pkg)
int SYMEXPORT alpm_option_remove_noextract(alpm_handle_t *handle, const char *pkg)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(handle, return -1);
handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
if(vdata != NULL) {
FREE(vdata);
return(1);
return 1;
}
return(0);
return 0;
}
void SYMEXPORT alpm_option_add_ignorepkg(const char *pkg)
int SYMEXPORT alpm_option_add_ignorepkg(alpm_handle_t *handle, const char *pkg)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
return 0;
}
void SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs)
int SYMEXPORT alpm_option_set_ignorepkgs(alpm_handle_t *handle, alpm_list_t *ignorepkgs)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
if(handle->ignorepkg) FREELIST(handle->ignorepkg);
if(ignorepkgs) handle->ignorepkg = ignorepkgs;
handle->ignorepkg = alpm_list_strdup(ignorepkgs);
return 0;
}
int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg)
int SYMEXPORT alpm_option_remove_ignorepkg(alpm_handle_t *handle, const char *pkg)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
CHECK_HANDLE(handle, return -1);
handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
if(vdata != NULL) {
FREE(vdata);
return(1);
return 1;
}
return(0);
return 0;
}
void SYMEXPORT alpm_option_add_ignoregrp(const char *grp)
int SYMEXPORT alpm_option_add_ignoregroup(alpm_handle_t *handle, const char *grp)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp));
CHECK_HANDLE(handle, return -1);
handle->ignoregroup = alpm_list_add(handle->ignoregroup, strdup(grp));
return 0;
}
void SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps)
int SYMEXPORT alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
if(handle->ignoregrp) FREELIST(handle->ignoregrp);
if(ignoregrps) handle->ignoregrp = ignoregrps;
CHECK_HANDLE(handle, return -1);
if(handle->ignoregroup) FREELIST(handle->ignoregroup);
handle->ignoregroup = alpm_list_strdup(ignoregrps);
return 0;
}
int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp)
int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata);
CHECK_HANDLE(handle, return -1);
handle->ignoregroup = alpm_list_remove_str(handle->ignoregroup, grp, &vdata);
if(vdata != NULL) {
FREE(vdata);
return(1);
return 1;
}
return(0);
return 0;
}
void SYMEXPORT alpm_option_set_arch(const char *arch)
int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
if(handle->arch) FREE(handle->arch);
if(arch) handle->arch = strdup(arch);
if(arch) {
handle->arch = strdup(arch);
} else {
handle->arch = NULL;
}
return 0;
}
void SYMEXPORT alpm_option_set_usedelta(int usedelta)
int SYMEXPORT alpm_option_set_usedelta(alpm_handle_t *handle, int usedelta)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
handle->usedelta = usedelta;
return 0;
}
void SYMEXPORT alpm_option_set_checkspace(int checkspace)
int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
{
ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL));
CHECK_HANDLE(handle, return -1);
handle->checkspace = checkspace;
return 0;
}
int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
alpm_siglevel_t level)
{
CHECK_HANDLE(handle, return -1);
#ifdef HAVE_LIBGPGME
handle->siglevel = level;
#else
if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
}
#endif
return 0;
}
alpm_siglevel_t SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle)
{
CHECK_HANDLE(handle, return -1);
return handle->siglevel;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -24,18 +24,25 @@
#include <sys/types.h>
#include "alpm_list.h"
#include "db.h"
#include "log.h"
#include "alpm.h"
#include "trans.h"
typedef struct _pmhandle_t {
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif
struct __alpm_handle_t {
/* internal usage */
pmdb_t *db_local; /* local db pointer */
alpm_list_t *dbs_sync; /* List of (pmdb_t *) */
alpm_db_t *db_local; /* local db pointer */
alpm_list_t *dbs_sync; /* List of (alpm_db_t *) */
FILE *logstream; /* log file stream pointer */
FILE *lckstream; /* lock file stream pointer if one exists */
pmtrans_t *trans;
alpm_trans_t *trans;
#ifdef HAVE_LIBCURL
/* libcurl handle */
CURL *curl; /* reusable curl_easy handle */
CURLcode curlerr; /* last error produced by curl */
#endif
/* callback functions */
alpm_cb_log logcb; /* Log callback function */
@@ -48,26 +55,34 @@ typedef struct _pmhandle_t {
char *dbpath; /* Base path to pacman's DBs */
char *logfile; /* Name of the log file */
char *lockfile; /* Name of the lock file */
char *gpgdir; /* Directory where GnuPG files are stored */
alpm_list_t *cachedirs; /* Paths to pacman cache directories */
/* package lists */
alpm_list_t *noupgrade; /* List of packages NOT to be upgraded */
alpm_list_t *noextract; /* List of files NOT to extract */
alpm_list_t *ignorepkg; /* List of packages to ignore */
alpm_list_t *ignoregrp; /* List of groups to ignore */
alpm_list_t *ignoregroup; /* List of groups to ignore */
/* options */
int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
char *arch; /* Architecture of packages we should allow */
int usedelta; /* Download deltas if possible */
int checkspace; /* Check disk space before installing */
} pmhandle_t;
int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
char *arch; /* Architecture of packages we should allow */
int usedelta; /* Download deltas if possible */
int checkspace; /* Check disk space before installing */
alpm_siglevel_t siglevel; /* Default signature verification level */
/* global handle variable */
extern pmhandle_t *handle;
/* error code */
enum _alpm_errno_t pm_errno;
};
pmhandle_t *_alpm_handle_new(void);
void _alpm_handle_free(pmhandle_t *handle);
alpm_handle_t *_alpm_handle_new(void);
void _alpm_handle_free(alpm_handle_t *handle);
int _alpm_handle_lock(alpm_handle_t *handle);
int _alpm_handle_unlock(alpm_handle_t *handle);
enum _alpm_errno_t _alpm_set_directory_option(const char *value,
char **storage, int must_exist);
#endif /* _ALPM_HANDLE_H */

View File

@@ -22,10 +22,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <time.h>
/* libalpm */
#include "log.h"
@@ -39,18 +36,16 @@
*/
/** A printf-like function for logging.
* @param handle the context handle
* @param fmt output format
* @return 0 on success, -1 on error (pm_errno is set accordingly)
*/
int SYMEXPORT alpm_logaction(const char *fmt, ...)
int SYMEXPORT alpm_logaction(alpm_handle_t *handle, const char *fmt, ...)
{
int ret;
va_list args;
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(handle != NULL, return -1);
/* check if the logstream is open already, opening it if needed */
if(handle->logstream == NULL) {
@@ -58,18 +53,18 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...)
/* if we couldn't open it, we have an issue */
if(handle->logstream == NULL) {
if(errno == EACCES) {
pm_errno = PM_ERR_BADPERMS;
handle->pm_errno = ALPM_ERR_BADPERMS;
} else if(errno == ENOENT) {
pm_errno = PM_ERR_NOT_A_DIR;
handle->pm_errno = ALPM_ERR_NOT_A_DIR;
} else {
pm_errno = PM_ERR_SYSTEM;
handle->pm_errno = ALPM_ERR_SYSTEM;
}
return(-1);
return -1;
}
}
va_start(args, fmt);
ret = _alpm_logaction(handle->usesyslog, handle->logstream, fmt, args);
ret = _alpm_logaction(handle, fmt, args);
va_end(args);
/* TODO We should add a prefix to log strings depending on who called us.
@@ -83,22 +78,21 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...)
* kpacman: "KPACMAN"
* This would allow us to share the log file between several frontends
* and know who does what */
return(ret);
return ret;
}
/** @} */
void _alpm_log(pmloglevel_t flag, const char *fmt, ...)
void _alpm_log(alpm_handle_t *handle, alpm_loglevel_t flag, const char *fmt, ...)
{
va_list args;
alpm_cb_log logcb = alpm_option_get_logcb();
if(logcb == NULL) {
if(handle == NULL || handle->logcb == NULL) {
return;
}
va_start(args, fmt);
logcb(flag, fmt, args);
handle->logcb(flag, fmt, args);
va_end(args);
}

View File

@@ -22,14 +22,8 @@
#include "alpm.h"
#ifdef PACMAN_DEBUG
/* Log funtion entry points if debugging is enabled */
#define ALPM_LOG_FUNC _alpm_log(PM_LOG_FUNCTION, "Enter %s\n", __func__)
#else
#define ALPM_LOG_FUNC
#endif
void _alpm_log(pmloglevel_t flag, const char *fmt, ...) __attribute__((format(printf,2,3)));
void _alpm_log(alpm_handle_t *handle, alpm_loglevel_t flag,
const char *fmt, ...) __attribute__((format(printf,3,4)));
#endif /* _ALPM_LOG_H */

View File

@@ -23,13 +23,9 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
/* libalpm */
#include "package.h"
@@ -47,87 +43,96 @@
*/
/** Free a package. */
int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
int SYMEXPORT alpm_pkg_free(alpm_pkg_t *pkg)
{
ALPM_LOG_FUNC;
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
ASSERT(pkg != NULL, return -1);
/* Only free packages loaded in user space */
if(pkg->origin == PKG_FROM_FILE) {
_alpm_pkg_free(pkg);
}
return(0);
return 0;
}
/** Check the integrity (with md5) of a package from the sync cache. */
int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg)
{
char *fpath;
int retval;
ALPM_LOG_FUNC;
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
/* We only inspect packages from sync repositories */
ASSERT(pkg->origin == PKG_FROM_SYNCDB, RET_ERR(PM_ERR_PKG_INVALID, -1));
ASSERT(pkg->origin == PKG_FROM_SYNCDB,
RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1));
fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg));
fpath = _alpm_filecache_find(pkg->handle, alpm_pkg_get_filename(pkg));
retval = _alpm_test_md5sum(fpath, alpm_pkg_get_md5sum(pkg));
if(retval == 0) {
return(0);
} else if (retval == 1) {
pm_errno = PM_ERR_PKG_INVALID;
return 0;
} else if(retval == 1) {
pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID;
retval = -1;
}
return(retval);
return retval;
}
/* Default package accessor functions. These will get overridden by any
* backend logic that needs lazy access, such as the local database through
* a lazy-load cache. However, the defaults will work just fine for fully-
* populated package structures. */
static const char *_pkg_get_filename(pmpkg_t *pkg) { return pkg->filename; }
static const char *_pkg_get_name(pmpkg_t *pkg) { return pkg->name; }
static const char *_pkg_get_version(pmpkg_t *pkg) { return pkg->version; }
static const char *_pkg_get_desc(pmpkg_t *pkg) { return pkg->desc; }
static const char *_pkg_get_url(pmpkg_t *pkg) { return pkg->url; }
static time_t _pkg_get_builddate(pmpkg_t *pkg) { return pkg->builddate; }
static time_t _pkg_get_installdate(pmpkg_t *pkg) { return pkg->installdate; }
static const char *_pkg_get_packager(pmpkg_t *pkg) { return pkg->packager; }
static const char *_pkg_get_md5sum(pmpkg_t *pkg) { return pkg->md5sum; }
static const char *_pkg_get_arch(pmpkg_t *pkg) { return pkg->arch; }
static off_t _pkg_get_size(pmpkg_t *pkg) { return pkg->size; }
static off_t _pkg_get_isize(pmpkg_t *pkg) { return pkg->isize; }
static pmpkgreason_t _pkg_get_reason(pmpkg_t *pkg) { return pkg->reason; }
static int _pkg_has_scriptlet(pmpkg_t *pkg) { return pkg->scriptlet; }
static const char *_pkg_get_filename(alpm_pkg_t *pkg) { return pkg->filename; }
static const char *_pkg_get_desc(alpm_pkg_t *pkg) { return pkg->desc; }
static const char *_pkg_get_url(alpm_pkg_t *pkg) { return pkg->url; }
static time_t _pkg_get_builddate(alpm_pkg_t *pkg) { return pkg->builddate; }
static time_t _pkg_get_installdate(alpm_pkg_t *pkg) { return pkg->installdate; }
static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; }
static const char *_pkg_get_md5sum(alpm_pkg_t *pkg) { return pkg->md5sum; }
static const char *_pkg_get_arch(alpm_pkg_t *pkg) { return pkg->arch; }
static off_t _pkg_get_size(alpm_pkg_t *pkg) { return pkg->size; }
static off_t _pkg_get_isize(alpm_pkg_t *pkg) { return pkg->isize; }
static alpm_pkgreason_t _pkg_get_reason(alpm_pkg_t *pkg) { return pkg->reason; }
static int _pkg_has_scriptlet(alpm_pkg_t *pkg) { return pkg->scriptlet; }
static alpm_list_t *_pkg_get_licenses(pmpkg_t *pkg) { return pkg->licenses; }
static alpm_list_t *_pkg_get_groups(pmpkg_t *pkg) { return pkg->groups; }
static alpm_list_t *_pkg_get_depends(pmpkg_t *pkg) { return pkg->depends; }
static alpm_list_t *_pkg_get_optdepends(pmpkg_t *pkg) { return pkg->optdepends; }
static alpm_list_t *_pkg_get_conflicts(pmpkg_t *pkg) { return pkg->conflicts; }
static alpm_list_t *_pkg_get_provides(pmpkg_t *pkg) { return pkg->provides; }
static alpm_list_t *_pkg_get_replaces(pmpkg_t *pkg) { return pkg->replaces; }
static alpm_list_t *_pkg_get_deltas(pmpkg_t *pkg) { return pkg->deltas; }
static alpm_list_t *_pkg_get_files(pmpkg_t *pkg) { return pkg->files; }
static alpm_list_t *_pkg_get_backup(pmpkg_t *pkg) { return pkg->backup; }
static alpm_list_t *_pkg_get_licenses(alpm_pkg_t *pkg) { return pkg->licenses; }
static alpm_list_t *_pkg_get_groups(alpm_pkg_t *pkg) { return pkg->groups; }
static alpm_list_t *_pkg_get_depends(alpm_pkg_t *pkg) { return pkg->depends; }
static alpm_list_t *_pkg_get_optdepends(alpm_pkg_t *pkg) { return pkg->optdepends; }
static alpm_list_t *_pkg_get_conflicts(alpm_pkg_t *pkg) { return pkg->conflicts; }
static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg) { return pkg->provides; }
static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces; }
static alpm_list_t *_pkg_get_deltas(alpm_pkg_t *pkg) { return pkg->deltas; }
static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); }
static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; }
static void *_pkg_changelog_open(pmpkg_t *pkg) { return NULL; }
static size_t _pkg_changelog_read(void *ptr, size_t size, const pmpkg_t *pkg, const void *fp) { return 0; }
static int _pkg_changelog_close(const pmpkg_t *pkg, void *fp) { return EOF; }
static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
{
return NULL;
}
static size_t _pkg_changelog_read(void UNUSED *ptr, size_t UNUSED size,
const alpm_pkg_t UNUSED *pkg, const UNUSED void *fp)
{
return 0;
}
static int _pkg_changelog_close(const alpm_pkg_t UNUSED *pkg,
void UNUSED *fp)
{
return EOF;
}
static int _pkg_force_load(alpm_pkg_t UNUSED *pkg) { return 0; }
/** The standard package operations struct. Get fields directly from the
* struct itself with no abstraction layer or any type of lazy loading.
*/
struct pkg_operations default_pkg_ops = {
.get_filename = _pkg_get_filename,
.get_name = _pkg_get_name,
.get_version = _pkg_get_version,
.get_desc = _pkg_get_desc,
.get_url = _pkg_get_url,
.get_builddate = _pkg_get_builddate,
@@ -154,174 +159,233 @@ struct pkg_operations default_pkg_ops = {
.changelog_open = _pkg_changelog_open,
.changelog_read = _pkg_changelog_read,
.changelog_close = _pkg_changelog_close,
.force_load = _pkg_force_load,
};
/* Public functions for getting package information. These functions
* delegate the hard work to the function callbacks attached to each
* package, which depend on where the package was loaded from. */
const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_filename(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_filename(pkg);
}
const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_name(alpm_pkg_t *pkg)
{
return pkg->ops->get_name(pkg);
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->name;
}
const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_version(alpm_pkg_t *pkg)
{
return pkg->ops->get_version(pkg);
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->version;
}
const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_desc(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_desc(pkg);
}
const char SYMEXPORT *alpm_pkg_get_url(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_url(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_url(pkg);
}
time_t SYMEXPORT alpm_pkg_get_builddate(pmpkg_t *pkg)
time_t SYMEXPORT alpm_pkg_get_builddate(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->get_builddate(pkg);
}
time_t SYMEXPORT alpm_pkg_get_installdate(pmpkg_t *pkg)
time_t SYMEXPORT alpm_pkg_get_installdate(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->get_installdate(pkg);
}
const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_packager(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_packager(pkg);
}
const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_md5sum(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_md5sum(pkg);
}
const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg)
const char SYMEXPORT *alpm_pkg_get_arch(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_arch(pkg);
}
off_t SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg)
off_t SYMEXPORT alpm_pkg_get_size(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->get_size(pkg);
}
off_t SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg)
off_t SYMEXPORT alpm_pkg_get_isize(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->get_isize(pkg);
}
pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg)
alpm_pkgreason_t SYMEXPORT alpm_pkg_get_reason(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->get_reason(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_licenses(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_groups(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_groups(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_groups(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_depends(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_depends(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_depends(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_optdepends(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_conflicts(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_provides(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_provides(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_provides(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_replaces(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_deltas(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_files(pmpkg_t *pkg)
alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_files(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->get_backup(pkg);
}
pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)
alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg)
{
/* Sanity checks */
ASSERT(pkg != NULL, return(NULL));
ASSERT(pkg->origin != PKG_FROM_FILE, return(NULL));
ASSERT(pkg != NULL, return NULL);
ASSERT(pkg->origin != PKG_FROM_FILE, return NULL);
pkg->handle->pm_errno = 0;
return(pkg->origin_data.db);
return pkg->origin_data.db;
}
/** Open a package changelog for reading. */
void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)
void SYMEXPORT *alpm_pkg_changelog_open(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
return pkg->ops->changelog_open(pkg);
}
/** Read data from an open changelog 'file stream'. */
size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size,
const pmpkg_t *pkg, const void *fp)
const alpm_pkg_t *pkg, const void *fp)
{
ASSERT(pkg != NULL, return 0);
pkg->handle->pm_errno = 0;
return pkg->ops->changelog_read(ptr, size, pkg, fp);
}
/*
int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp)
int SYMEXPORT alpm_pkg_changelog_feof(const alpm_pkg_t *pkg, void *fp)
{
return pkg->ops->changelog_feof(pkg, fp);
}
*/
/** Close a package changelog for reading. */
int SYMEXPORT alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp)
int SYMEXPORT alpm_pkg_changelog_close(const alpm_pkg_t *pkg, void *fp)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->changelog_close(pkg, fp);
}
int SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)
int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return -1);
pkg->handle->pm_errno = 0;
return pkg->ops->has_scriptlet(pkg);
}
static void find_requiredby(pmpkg_t *pkg, pmdb_t *db, alpm_list_t **reqs)
static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
{
const alpm_list_t *i;
pkg->handle->pm_errno = 0;
for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
pmpkg_t *cachepkg = i->data;
alpm_list_t *i;
for(i = alpm_pkg_get_depends(cachepkg); i; i = i->next) {
if(_alpm_depcmp(pkg, i->data)) {
alpm_pkg_t *cachepkg = i->data;
alpm_list_t *j;
for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
if(_alpm_depcmp(pkg, j->data)) {
const char *cachepkgname = cachepkg->name;
if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
*reqs = alpm_list_add(*reqs, strdup(cachepkgname));
@@ -332,16 +396,18 @@ static void find_requiredby(pmpkg_t *pkg, pmdb_t *db, alpm_list_t **reqs)
}
/** Compute the packages requiring a given package. */
alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg)
alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
{
const alpm_list_t *i;
alpm_list_t *reqs = NULL;
pmdb_t *db;
alpm_db_t *db;
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = 0;
if(pkg->origin == PKG_FROM_FILE) {
/* The sane option; search locally for things that require this. */
db = alpm_option_get_localdb();
find_requiredby(pkg, db, &reqs);
find_requiredby(pkg, pkg->handle->db_local, &reqs);
} else {
/* We have a DB package. if it is a local package, then we should
* only search the local DB; else search all known sync databases. */
@@ -349,49 +415,68 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg)
if(db->is_local) {
find_requiredby(pkg, db, &reqs);
} else {
for(i = handle->dbs_sync; i; i = i->next) {
for(i = pkg->handle->dbs_sync; i; i = i->next) {
db = i->data;
find_requiredby(pkg, db, &reqs);
}
reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp);
}
}
return(reqs);
return reqs;
}
/** @} */
pmpkg_t *_alpm_pkg_new(void)
alpm_file_t *_alpm_file_copy(alpm_file_t *dest,
const alpm_file_t *src)
{
pmpkg_t* pkg;
STRDUP(dest->name, src->name, return NULL);
dest->size = src->size;
dest->mode = src->mode;
ALPM_LOG_FUNC;
CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
return(pkg);
return dest;
}
pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
/* Helper function for comparing files list entries
*/
int _alpm_files_cmp(const void *f1, const void *f2)
{
pmpkg_t *newpkg;
const alpm_file_t *file1 = f1;
const alpm_file_t *file2 = f2;
return strcmp(file1->name, file2->name);
}
alpm_pkg_t *_alpm_pkg_new(void)
{
alpm_pkg_t* pkg;
CALLOC(pkg, 1, sizeof(alpm_pkg_t), return NULL);
return pkg;
}
alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg)
{
alpm_pkg_t *newpkg;
alpm_list_t *i;
ALPM_LOG_FUNC;
if(pkg->ops->force_load(pkg)) {
return NULL;
}
CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(newpkg, 1, sizeof(alpm_pkg_t), goto cleanup);
newpkg->name_hash = pkg->name_hash;
STRDUP(newpkg->filename, pkg->filename, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->name, pkg->name, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->version, pkg->version, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->desc, pkg->desc, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->url, pkg->url, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->filename, pkg->filename, goto cleanup);
STRDUP(newpkg->name, pkg->name, goto cleanup);
STRDUP(newpkg->version, pkg->version, goto cleanup);
STRDUP(newpkg->desc, pkg->desc, goto cleanup);
STRDUP(newpkg->url, pkg->url, goto cleanup);
newpkg->builddate = pkg->builddate;
newpkg->installdate = pkg->installdate;
STRDUP(newpkg->packager, pkg->packager, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->md5sum, pkg->md5sum, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->arch, pkg->arch, RET_ERR(PM_ERR_MEMORY, newpkg));
STRDUP(newpkg->packager, pkg->packager, goto cleanup);
STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup);
STRDUP(newpkg->arch, pkg->arch, goto cleanup);
newpkg->size = pkg->size;
newpkg->isize = pkg->isize;
newpkg->scriptlet = pkg->scriptlet;
@@ -400,33 +485,51 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
newpkg->licenses = alpm_list_strdup(pkg->licenses);
newpkg->replaces = alpm_list_strdup(pkg->replaces);
newpkg->groups = alpm_list_strdup(pkg->groups);
newpkg->files = alpm_list_strdup(pkg->files);
newpkg->backup = alpm_list_strdup(pkg->backup);
if(pkg->files.count) {
size_t filenum;
size_t len = sizeof(alpm_file_t) * pkg->files.count;
MALLOC(newpkg->files.files, len, goto cleanup);
for(filenum = 0; filenum < pkg->files.count; filenum++) {
if(!_alpm_file_copy(newpkg->files.files + filenum,
pkg->files.files + filenum)) {
goto cleanup;
}
}
newpkg->files.count = pkg->files.count;
}
for(i = pkg->backup; i; i = alpm_list_next(i)) {
newpkg->backup = alpm_list_add(newpkg->backup, _alpm_backup_dup(i->data));
}
for(i = pkg->depends; i; i = alpm_list_next(i)) {
newpkg->depends = alpm_list_add(newpkg->depends, _alpm_dep_dup(i->data));
}
newpkg->optdepends = alpm_list_strdup(pkg->optdepends);
newpkg->conflicts = alpm_list_strdup(pkg->conflicts);
newpkg->provides = alpm_list_strdup(pkg->provides);
newpkg->deltas = alpm_list_copy_data(pkg->deltas, sizeof(pmdelta_t));
for(i = pkg->deltas; i; i = alpm_list_next(i)) {
newpkg->deltas = alpm_list_add(newpkg->deltas, _alpm_delta_dup(i->data));
}
/* internal */
newpkg->infolevel = pkg->infolevel;
newpkg->origin = pkg->origin;
newpkg->ops = pkg->ops;
if(newpkg->origin == PKG_FROM_FILE) {
newpkg->origin_data.file = strdup(pkg->origin_data.file);
} else {
newpkg->origin_data.db = pkg->origin_data.db;
}
newpkg->infolevel = pkg->infolevel;
newpkg->ops = pkg->ops;
newpkg->handle = pkg->handle;
return(newpkg);
return newpkg;
cleanup:
_alpm_pkg_free(newpkg);
return NULL;
}
void _alpm_pkg_free(pmpkg_t *pkg)
void _alpm_pkg_free(alpm_pkg_t *pkg)
{
ALPM_LOG_FUNC;
if(pkg == NULL) {
return;
}
@@ -438,12 +541,20 @@ void _alpm_pkg_free(pmpkg_t *pkg)
FREE(pkg->url);
FREE(pkg->packager);
FREE(pkg->md5sum);
FREE(pkg->base64_sig);
FREE(pkg->arch);
FREELIST(pkg->licenses);
FREELIST(pkg->replaces);
FREELIST(pkg->groups);
FREELIST(pkg->files);
FREELIST(pkg->backup);
if(pkg->files.count) {
size_t i;
for(i = 0; i < pkg->files.count; i++) {
free(pkg->files.files[i].name);
}
free(pkg->files.files);
}
alpm_list_free_inner(pkg->backup, (alpm_list_fn_free)_alpm_backup_free);
alpm_list_free(pkg->backup);
alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
alpm_list_free(pkg->depends);
FREELIST(pkg->optdepends);
@@ -465,10 +576,8 @@ void _alpm_pkg_free(pmpkg_t *pkg)
* Case 2: If pkg is a pkgcache entry (PKG_FROM_CACHE), it won't be freed,
* only the transaction specific fields of pkg will be freed.
*/
void _alpm_pkg_free_trans(pmpkg_t *pkg)
void _alpm_pkg_free_trans(alpm_pkg_t *pkg)
{
ALPM_LOG_FUNC;
if(pkg == NULL) {
return;
}
@@ -483,10 +592,8 @@ void _alpm_pkg_free_trans(pmpkg_t *pkg)
}
/* Is spkg an upgrade for localpkg? */
int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg)
int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, alpm_pkg_t *localpkg)
{
ALPM_LOG_FUNC;
return alpm_pkg_vercmp(alpm_pkg_get_version(spkg),
alpm_pkg_get_version(localpkg));
}
@@ -495,72 +602,70 @@ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg)
*/
int _alpm_pkg_cmp(const void *p1, const void *p2)
{
pmpkg_t *pkg1 = (pmpkg_t *)p1;
pmpkg_t *pkg2 = (pmpkg_t *)p2;
return(strcoll(pkg1->name, pkg2->name));
const alpm_pkg_t *pkg1 = p1;
const alpm_pkg_t *pkg2 = p2;
return strcoll(pkg1->name, pkg2->name);
}
/* Test for existence of a package in a alpm_list_t*
* of pmpkg_t*
* of alpm_pkg_t*
*/
pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)
alpm_pkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)
{
alpm_list_t *lp;
unsigned long needle_hash;
ALPM_LOG_FUNC;
if(needle == NULL || haystack == NULL) {
return(NULL);
return NULL;
}
needle_hash = _alpm_hash_sdbm(needle);
for(lp = haystack; lp; lp = lp->next) {
pmpkg_t *info = lp->data;
alpm_pkg_t *info = lp->data;
if(info) {
/* a zero hash will cause a fall-through just in case */
if(info->name_hash && info->name_hash != needle_hash) {
if(info->name_hash != needle_hash) {
continue;
}
/* finally: we had hash match, verify string match */
if(strcmp(info->name, needle) == 0) {
return(info);
return info;
}
}
}
return(NULL);
return NULL;
}
/** Test if a package should be ignored.
*
* Checks if the package is ignored via IgnorePkg, or if the package is
* in a group ignored via IgnoreGrp.
* in a group ignored via IgnoreGroup.
*
* @param handle the context handle
* @param pkg the package to test
*
* @return 1 if the package should be ignored, 0 otherwise
*/
int _alpm_pkg_should_ignore(pmpkg_t *pkg)
int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg)
{
alpm_list_t *groups = NULL;
/* first see if the package is ignored */
if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(pkg))) {
return(1);
return 1;
}
/* next see if the package is in a group that is ignored */
for(groups = handle->ignoregrp; groups; groups = alpm_list_next(groups)) {
for(groups = handle->ignoregroup; groups; groups = alpm_list_next(groups)) {
char *grp = (char *)alpm_list_getdata(groups);
if(alpm_list_find_str(alpm_pkg_get_groups(pkg), grp)) {
return(1);
return 1;
}
}
return(0);
return 0;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -24,17 +24,21 @@
#ifndef _ALPM_PACKAGE_H
#define _ALPM_PACKAGE_H
#include "config.h" /* ensure off_t is correct length */
#include <sys/types.h> /* off_t */
#include <time.h> /* time_t */
#include "alpm.h"
#include "backup.h"
#include "db.h"
#include "signing.h"
typedef enum _pmpkgfrom_t {
typedef enum _alpm_pkgfrom_t {
PKG_FROM_FILE = 1,
PKG_FROM_LOCALDB,
PKG_FROM_SYNCDB
} pmpkgfrom_t;
} alpm_pkgfrom_t;
/** Package operations struct. This struct contains function pointers to
* all methods used to access data in a package to allow for things such
@@ -44,35 +48,35 @@ typedef enum _pmpkgfrom_t {
* defined default_pkg_ops struct to work just fine for their needs.
*/
struct pkg_operations {
const char *(*get_filename) (pmpkg_t *);
const char *(*get_name) (pmpkg_t *);
const char *(*get_version) (pmpkg_t *);
const char *(*get_desc) (pmpkg_t *);
const char *(*get_url) (pmpkg_t *);
time_t (*get_builddate) (pmpkg_t *);
time_t (*get_installdate) (pmpkg_t *);
const char *(*get_packager) (pmpkg_t *);
const char *(*get_md5sum) (pmpkg_t *);
const char *(*get_arch) (pmpkg_t *);
off_t (*get_size) (pmpkg_t *);
off_t (*get_isize) (pmpkg_t *);
pmpkgreason_t (*get_reason) (pmpkg_t *);
int (*has_scriptlet) (pmpkg_t *);
const char *(*get_filename) (alpm_pkg_t *);
const char *(*get_desc) (alpm_pkg_t *);
const char *(*get_url) (alpm_pkg_t *);
time_t (*get_builddate) (alpm_pkg_t *);
time_t (*get_installdate) (alpm_pkg_t *);
const char *(*get_packager) (alpm_pkg_t *);
const char *(*get_md5sum) (alpm_pkg_t *);
const char *(*get_arch) (alpm_pkg_t *);
off_t (*get_size) (alpm_pkg_t *);
off_t (*get_isize) (alpm_pkg_t *);
alpm_pkgreason_t (*get_reason) (alpm_pkg_t *);
int (*has_scriptlet) (alpm_pkg_t *);
alpm_list_t *(*get_licenses) (pmpkg_t *);
alpm_list_t *(*get_groups) (pmpkg_t *);
alpm_list_t *(*get_depends) (pmpkg_t *);
alpm_list_t *(*get_optdepends) (pmpkg_t *);
alpm_list_t *(*get_conflicts) (pmpkg_t *);
alpm_list_t *(*get_provides) (pmpkg_t *);
alpm_list_t *(*get_replaces) (pmpkg_t *);
alpm_list_t *(*get_deltas) (pmpkg_t *);
alpm_list_t *(*get_files) (pmpkg_t *);
alpm_list_t *(*get_backup) (pmpkg_t *);
alpm_list_t *(*get_licenses) (alpm_pkg_t *);
alpm_list_t *(*get_groups) (alpm_pkg_t *);
alpm_list_t *(*get_depends) (alpm_pkg_t *);
alpm_list_t *(*get_optdepends) (alpm_pkg_t *);
alpm_list_t *(*get_conflicts) (alpm_pkg_t *);
alpm_list_t *(*get_provides) (alpm_pkg_t *);
alpm_list_t *(*get_replaces) (alpm_pkg_t *);
alpm_list_t *(*get_deltas) (alpm_pkg_t *);
alpm_filelist_t *(*get_files) (alpm_pkg_t *);
alpm_list_t *(*get_backup) (alpm_pkg_t *);
void *(*changelog_open) (pmpkg_t *);
size_t (*changelog_read) (void *, size_t, const pmpkg_t *, const void *);
int (*changelog_close) (const pmpkg_t *, void *);
void *(*changelog_open) (alpm_pkg_t *);
size_t (*changelog_read) (void *, size_t, const alpm_pkg_t *, const void *);
int (*changelog_close) (const alpm_pkg_t *, void *);
int (*force_load) (alpm_pkg_t *);
/* still to add:
* checkmd5sum() ?
@@ -87,7 +91,7 @@ struct pkg_operations {
*/
extern struct pkg_operations default_pkg_ops;
struct __pmpkg_t {
struct __alpm_pkg_t {
unsigned long name_hash;
char *filename;
char *name;
@@ -96,6 +100,7 @@ struct __pmpkg_t {
char *url;
char *packager;
char *md5sum;
char *base64_sig;
char *arch;
time_t builddate;
@@ -107,20 +112,20 @@ struct __pmpkg_t {
int scriptlet;
pmpkgreason_t reason;
pmpkgfrom_t origin;
alpm_pkgreason_t reason;
alpm_dbinfrq_t infolevel;
alpm_pkgfrom_t origin;
/* origin == PKG_FROM_FILE, use pkg->origin_data.file
* origin == PKG_FROM_*DB, use pkg->origin_data.db */
union {
pmdb_t *db;
alpm_db_t *db;
char *file;
} origin_data;
pmdbinfrq_t infolevel;
alpm_handle_t *handle;
alpm_list_t *licenses;
alpm_list_t *replaces;
alpm_list_t *groups;
alpm_list_t *files;
alpm_list_t *backup;
alpm_list_t *depends;
alpm_list_t *optdepends;
@@ -131,16 +136,27 @@ struct __pmpkg_t {
alpm_list_t *removes; /* in transaction targets only */
struct pkg_operations *ops;
alpm_filelist_t files;
};
pmpkg_t* _alpm_pkg_new(void);
pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg);
void _alpm_pkg_free(pmpkg_t *pkg);
void _alpm_pkg_free_trans(pmpkg_t *pkg);
alpm_file_t *_alpm_file_copy(alpm_file_t *dest, const alpm_file_t *src);
int _alpm_files_cmp(const void *f1, const void *f2);
alpm_pkg_t* _alpm_pkg_new(void);
alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg);
void _alpm_pkg_free(alpm_pkg_t *pkg);
void _alpm_pkg_free_trans(alpm_pkg_t *pkg);
alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
int full, const char *md5sum, const char *base64_sig,
alpm_siglevel_t level);
int _alpm_pkg_cmp(const void *p1, const void *p2);
int _alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg);
pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle);
int _alpm_pkg_should_ignore(pmpkg_t *pkg);
int _alpm_pkg_compare_versions(alpm_pkg_t *local_pkg, alpm_pkg_t *pkg);
alpm_pkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle);
int _alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg);
#endif /* _ALPM_PACKAGE_H */

View File

@@ -17,9 +17,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include "pkghash.h"
#include "util.h"
#include "log.h"
/* List of primes for possible sizes of hash tables.
*
@@ -50,16 +51,12 @@ static const size_t prime_list[] =
};
/* Allocate a hash table with at least "size" buckets */
pmpkghash_t *_alpm_pkghash_create(size_t size)
alpm_pkghash_t *_alpm_pkghash_create(size_t size)
{
pmpkghash_t *hash = NULL;
alpm_pkghash_t *hash = NULL;
size_t i, loopsize;
MALLOC(hash, sizeof(pmpkghash_t), RET_ERR(PM_ERR_MEMORY, NULL));
hash->list = NULL;
hash->entries = 0;
hash->buckets = 0;
CALLOC(hash, 1, sizeof(alpm_pkghash_t), return NULL);
loopsize = sizeof(prime_list) / sizeof(*prime_list);
for(i = 0; i < loopsize; i++) {
@@ -70,18 +67,18 @@ pmpkghash_t *_alpm_pkghash_create(size_t size)
}
if(hash->buckets < size) {
_alpm_log(PM_LOG_ERROR, _("database larger than maximum size\n"));
errno = ERANGE;
free(hash);
return(NULL);
return NULL;
}
CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t*), \
free(hash); RET_ERR(PM_ERR_MEMORY, NULL));
CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t *), \
free(hash); return NULL);
return(hash);
return hash;
}
static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash)
static size_t get_hash_position(unsigned long name_hash, alpm_pkghash_t *hash)
{
size_t position;
@@ -92,13 +89,13 @@ static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash)
position = (position + 1) % hash->buckets;
}
return(position);
return position;
}
/* Expand the hash table size to the next increment and rebin the entries */
static pmpkghash_t *rehash(pmpkghash_t *oldhash)
static alpm_pkghash_t *rehash(alpm_pkghash_t *oldhash)
{
pmpkghash_t *newhash;
alpm_pkghash_t *newhash;
size_t newsize, position, i;
/* Hash tables will need resized in two cases:
@@ -123,7 +120,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash)
newhash = _alpm_pkghash_create(newsize);
if(newhash == NULL) {
/* creation of newhash failed, stick with old one... */
return(oldhash);
return oldhash;
}
newhash->list = oldhash->list;
@@ -131,7 +128,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash)
for(i = 0; i < oldhash->buckets; i++) {
if(oldhash->hash_table[i] != NULL) {
pmpkg_t *package = oldhash->hash_table[i]->data;
alpm_pkg_t *package = oldhash->hash_table[i]->data;
position = get_hash_position(package->name_hash, newhash);
@@ -144,16 +141,16 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash)
_alpm_pkghash_free(oldhash);
return(newhash);
return newhash;
}
static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted)
static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t *hash, alpm_pkg_t *pkg, int sorted)
{
alpm_list_t *ptr;
size_t position;
if(pkg == NULL || hash == NULL) {
return(hash);
return hash;
}
if((hash->entries + 1) / MAX_HASH_LOAD > hash->buckets) {
@@ -164,7 +161,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted)
ptr = calloc(1, sizeof(alpm_list_t));
if(ptr == NULL) {
return(hash);
return hash;
}
ptr->data = pkg;
@@ -179,20 +176,20 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted)
}
hash->entries += 1;
return(hash);
return hash;
}
pmpkghash_t *_alpm_pkghash_add(pmpkghash_t *hash, pmpkg_t *pkg)
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t *hash, alpm_pkg_t *pkg)
{
return(pkghash_add_pkg(hash, pkg, 0));
return pkghash_add_pkg(hash, pkg, 0);
}
pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg)
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t *hash, alpm_pkg_t *pkg)
{
return(pkghash_add_pkg(hash, pkg, 1));
return pkghash_add_pkg(hash, pkg, 1);
}
static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end)
static size_t move_one_entry(alpm_pkghash_t *hash, size_t start, size_t end)
{
/* Iterate backwards from 'end' to 'start', seeing if any of the items
* would hash to 'start'. If we find one, we move it there and break. If
@@ -203,7 +200,7 @@ static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end)
* 'start' we can stop this madness. */
while(end != start) {
alpm_list_t *i = hash->hash_table[end];
pmpkg_t *info = i->data;
alpm_pkg_t *info = i->data;
size_t new_position = get_hash_position(info->name_hash, hash);
if(new_position == start) {
@@ -217,7 +214,7 @@ static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end)
* e.g. (47 + 0 - 1) % 47 == 46 */
end = (hash->buckets + end - 1) % hash->buckets;
}
return(end);
return end;
}
/**
@@ -229,8 +226,8 @@ static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end)
*
* @return the resultant hash
*/
pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg,
pmpkg_t **data)
alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg,
alpm_pkg_t **data)
{
alpm_list_t *i;
size_t position;
@@ -240,12 +237,12 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg,
}
if(pkg == NULL || hash == NULL) {
return(hash);
return hash;
}
position = pkg->name_hash % hash->buckets;
while((i = hash->hash_table[position]) != NULL) {
pmpkg_t *info = i->data;
alpm_pkg_t *info = i->data;
if(info->name_hash == pkg->name_hash &&
strcmp(info->name, pkg->name) == 0) {
@@ -277,16 +274,16 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg,
position = prev;
}
return(hash);
return hash;
}
position = (position + 1) % hash->buckets;
}
return(hash);
return hash;
}
void _alpm_pkghash_free(pmpkghash_t *hash)
void _alpm_pkghash_free(alpm_pkghash_t *hash)
{
size_t i;
if(hash != NULL) {
@@ -298,16 +295,14 @@ void _alpm_pkghash_free(pmpkghash_t *hash)
free(hash);
}
pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name)
alpm_pkg_t *_alpm_pkghash_find(alpm_pkghash_t *hash, const char *name)
{
alpm_list_t *lp;
unsigned long name_hash;
size_t position;
ALPM_LOG_FUNC;
if(name == NULL || hash == NULL) {
return(NULL);
return NULL;
}
name_hash = _alpm_hash_sdbm(name);
@@ -315,16 +310,16 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name)
position = name_hash % hash->buckets;
while((lp = hash->hash_table[position]) != NULL) {
pmpkg_t *info = lp->data;
alpm_pkg_t *info = lp->data;
if(info->name_hash == name_hash && strcmp(info->name, name) == 0) {
return(info);
return info;
}
position = (position + 1) % hash->buckets;
}
return(NULL);
return NULL;
}
/* vim: set ts=2 sw=2 noet: */

View File

@@ -27,12 +27,12 @@
/**
* @brief A hash table for holding pmpkg_t objects.
* @brief A hash table for holding alpm_pkg_t objects.
*
* A combination of a hash table and a list, allowing for fast look-up
* by package name but also iteration over the packages.
*/
struct __pmpkghash_t {
struct __alpm_pkghash_t {
/** data held by the hash table */
alpm_list_t **hash_table;
/** number of buckets in hash table */
@@ -43,17 +43,17 @@ struct __pmpkghash_t {
alpm_list_t *list;
};
typedef struct __pmpkghash_t pmpkghash_t;
typedef struct __alpm_pkghash_t alpm_pkghash_t;
pmpkghash_t *_alpm_pkghash_create(size_t size);
alpm_pkghash_t *_alpm_pkghash_create(size_t size);
pmpkghash_t *_alpm_pkghash_add(pmpkghash_t *hash, pmpkg_t *pkg);
pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg);
pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t **data);
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t *hash, alpm_pkg_t *pkg);
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t *hash, alpm_pkg_t *pkg);
alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg, alpm_pkg_t **data);
void _alpm_pkghash_free(pmpkghash_t *hash);
void _alpm_pkghash_free(alpm_pkghash_t *hash);
pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name);
alpm_pkg_t *_alpm_pkghash_find(alpm_pkghash_t *hash, const char *name);
#define MAX_HASH_LOAD 0.7

View File

@@ -4,7 +4,7 @@
DOMAIN = libalpm
# These two variables depend on the location of this directory.
subdir = po
subdir = lib/libalpm/po
top_builddir = ../../../
# These options get passed to xgettext.

View File

@@ -1,16 +1,18 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Hector Mtz-Seara <hseara@gmail.com>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-04-12 11:15+0000\n"
"Last-Translator: hseara <hseara@gmail.com>\n"
"Language-Team: Catalan <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Catalan (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/ca/)\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +155,14 @@ msgstr "falten les metadades del paquet en %s\n"
msgid "removing invalid file: %s\n"
msgstr "Esborrant fitxer invàlid: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "no s'ha pogut eliminar el fitxer de bloqueig %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "no s'ha definit la ruta de la base de dades\n"
@@ -215,22 +225,14 @@ msgstr "disc"
msgid "url '%s' is invalid\n"
msgstr "l'url '%s' és invàlid\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "ha fallat en recuperar el fitxer '%s' des de %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "no es pot la reprendre la baixada de %s, s'està iniciant de nou\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "error en escriure al fitxer '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "ha fallat en recuperar el fitxer '%s' de %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s sembla estar truncat: %jd/%jd bytes\n"
@@ -299,6 +301,14 @@ msgstr "la base de dades ja s'ha registrat"
msgid "could not find database"
msgstr "no s'ha pogut trobar la base de dades"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "la versió de la base de dades és incorrecta"
@@ -356,9 +366,17 @@ msgstr "no s'ha pogut trobar o llegir el paquet"
msgid "operation cancelled due to ignorepkg"
msgstr "operació cancel·lada degut a ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "paquet invàlid o corrupte"
msgstr "delta invàlid o corrupte"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -380,6 +398,14 @@ msgstr "l'arquitectura del paquet no és vàlida"
msgid "could not find repository for target"
msgstr "no s'ha pogut trobar el repositori per l'objectiu"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "delta invàlid o corrupte"
@@ -404,10 +430,6 @@ msgstr "fitxers conflictius"
msgid "failed to retrieve some files"
msgstr "ha fallat en recuperar alguns fitxers"
#, c-format
msgid "failed to copy some file"
msgstr "no s'ha aconseguit copiar algun arxiu"
#, c-format
msgid "invalid regular expression"
msgstr "expressió regular invàlida"
@@ -420,6 +442,10 @@ msgstr "error de libarchive"
msgid "download library error"
msgstr "error de la llibreria de baixades"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "error en invocar el baixador extern"
@@ -428,10 +454,6 @@ msgstr "error en invocar el baixador extern"
msgid "unexpected error"
msgstr "error inesperat"
#, c-format
msgid "database larger than maximum size\n"
msgstr "base de dades sobrepassa la grandaria màxima\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "no s'ha pogut trobar %s en la base de dades -- s'està ometent\n"
@@ -444,6 +466,10 @@ msgstr "s'està eliminant %s de la llista d'objectius\n"
msgid "cannot remove file '%s': %s\n"
msgstr "no s'ha pogut eliminar el fitxer '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "no s'ha pogut eliminar la entrada de la base de dades %s-%s\n"
@@ -498,14 +524,6 @@ msgstr "no s'ha pogut publicar la transacció d'eliminació\n"
msgid "could not commit transaction\n"
msgstr "no s'ha pogut publicar la transacció\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "%s versió de la base de dades és massa vella\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "no s'ha pogut eliminar el fitxer de bloqueig %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "no s'ha pogut crear el directori temporal\n"

View File

@@ -1,16 +1,19 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Vojtěch Gondžala <vojtech.gondzala@gmail.com>, 2011.
# David Kolibáč <david@kolibac.cz>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"Last-Translator: vogo <vojtech.gondzala@gmail.com>\n"
"Language-Team: Czech <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Czech (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/cs/)\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +156,14 @@ msgstr "chybí metadata balíčku v %s\n"
msgid "removing invalid file: %s\n"
msgstr "odstraněn neplatný soubor: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "nelze odstranit zamykací soubor %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "cesta k databázi není definována\n"
@@ -214,22 +225,14 @@ msgstr "disk"
msgid "url '%s' is invalid\n"
msgstr "URL '%s' je chybná\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "selhalo získání souboru '%s' z %s: %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "nelze navázat stahování %s, začíná se znovu\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "chyba při zápisu do souboru '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "selhalo získání souboru '%s' z %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s se zdá být zkrácen: %jd/%jd bytů\n"
@@ -298,6 +301,14 @@ msgstr "databáze zaregistrována"
msgid "could not find database"
msgstr "nelze nalézt databázi"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "databáze má nesprávnou verzi"
@@ -354,9 +365,17 @@ msgstr "nelze nalézt nebo přečíst balíček"
msgid "operation cancelled due to ignorepkg"
msgstr "operace byla zrušena kvůli ignorovanému balíčku"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "neplatný nebo poškozený balíček"
msgstr "neplatný nebo poškozený delta rozdíl"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -378,6 +397,14 @@ msgstr "architektura balíčku není platná"
msgid "could not find repository for target"
msgstr "nelze nalézt repositář cíle"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "neplatný nebo poškozený delta rozdíl"
@@ -402,10 +429,6 @@ msgstr "konfliktní soubory"
msgid "failed to retrieve some files"
msgstr "selhalo získání některých souborů"
#, c-format
msgid "failed to copy some file"
msgstr "selhalo kopírování souboru"
#, c-format
msgid "invalid regular expression"
msgstr "nesprávný regulární výraz"
@@ -418,6 +441,10 @@ msgstr "chyba knihovny libarchive"
msgid "download library error"
msgstr "chyba knihovny pro stahování souborů"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "chyba volání externího programu pro stahování souborů"
@@ -426,10 +453,6 @@ msgstr "chyba volání externího programu pro stahování souborů"
msgid "unexpected error"
msgstr "neočekávaná chyba"
#, c-format
msgid "database larger than maximum size\n"
msgstr "databáze je větší než maximální přípustná velikost\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "nelze nalézt %s v databázi -- vynechat\n"
@@ -442,6 +465,10 @@ msgstr "'%s' odstraněn ze seznamu cílů\n"
msgid "cannot remove file '%s': %s\n"
msgstr "nelze odstranit soubor '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "nelze odstranit záznam databáze %s-%s\n"
@@ -494,14 +521,6 @@ msgstr "nelze provést transakci pro odstranění\n"
msgid "could not commit transaction\n"
msgstr "nelze provést transakci\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "verze databáze %s je příliš stará\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "nelze odstranit zamykací soubor %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "nelze vytvořit dočasný adresář\n"

View File

@@ -1,16 +1,17 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Joe Hansen <joedalton2@yahoo.dk>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Danish <None>\n"
"Language-Team: Danish (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/da/)\n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +154,14 @@ msgstr "manglende pakkemetadata i %s\n"
msgid "removing invalid file: %s\n"
msgstr ""
#, c-format
msgid "could not remove lock file %s\n"
msgstr "kunne ikke fjerne låsningsfil %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "databasesti er udefineret\n"
@@ -213,22 +222,14 @@ msgstr "disk"
msgid "url '%s' is invalid\n"
msgstr "adressen »%s« er ugyldig\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "fejlede i indhentning af fil »%s« fra %s: %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "det er ikke muligt at genoptage hentning af %s; starter forfra\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "fejl under skrivning til fil »%s«: %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "kunne ikke indhente fil »%s« fra %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s ser ud til at være afkortet: %jd/%jd byte\n"
@@ -297,6 +298,14 @@ msgstr "database er allerede registreret"
msgid "could not find database"
msgstr "kunne ikke finde database"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr ""
@@ -353,9 +362,17 @@ msgstr "kunne ikke finde eller læse pakke"
msgid "operation cancelled due to ignorepkg"
msgstr "handling afbrudt på grund af igonrepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "ugyldig eller ødelagt pakke"
msgstr "ugyldig eller ødelagt delta"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -377,6 +394,14 @@ msgstr "pakkearkitektur er ikke gyldig"
msgid "could not find repository for target"
msgstr "kunne ikke finde arkiv for mål"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "ugyldig eller ødelagt delta"
@@ -401,10 +426,6 @@ msgstr "konfliktende filer"
msgid "failed to retrieve some files"
msgstr "kunne ikke indhente nogle filer"
#, c-format
msgid "failed to copy some file"
msgstr ""
#, c-format
msgid "invalid regular expression"
msgstr "ugyldigt regulært udtryk"
@@ -417,6 +438,10 @@ msgstr "biblioteksarkivfejl"
msgid "download library error"
msgstr "hent biblioteksfejl"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "fejl under opstart af ekstern hentningsprogram"
@@ -425,10 +450,6 @@ msgstr "fejl under opstart af ekstern hentningsprogram"
msgid "unexpected error"
msgstr "uventet fejl"
#, c-format
msgid "database larger than maximum size\n"
msgstr ""
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "kunne ikke finde %s i database - springer over\n"
@@ -441,6 +462,10 @@ msgstr "fjerner %s fra målliste\n"
msgid "cannot remove file '%s': %s\n"
msgstr "kan ikke fjerne fil »%s«:%s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "kunne ikke fjerne databasepunkt %s-%s\n"
@@ -493,14 +518,6 @@ msgstr "kunne ikke indsende (commit) fjernelsestransaktion\n"
msgid "could not commit transaction\n"
msgstr "kunne ikke indsende (commit) transaktion\n"
#, c-format
msgid "%s database version is too old\n"
msgstr ""
#, c-format
msgid "could not remove lock file %s\n"
msgstr "kunne ikke fjerne låsningsfil %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "kunne ikke oprette midlertidig mappe\n"

View File

@@ -1,16 +1,18 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Matthias Gorissen <matthias@archlinux.de>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"Last-Translator: tlaloc <matthias@archlinux.de>\n"
"Language-Team: German <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: German (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/de/)\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -157,6 +159,14 @@ msgstr "Fehlende Paket-Metadaten in %s\n"
msgid "removing invalid file: %s\n"
msgstr "Entferne ungültige Datei: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "Konnte Sperrdatei %s nicht entfernen\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "Datenbank-Pfad ist nicht definiert\n"
@@ -218,22 +228,14 @@ msgstr "Platte"
msgid "url '%s' is invalid\n"
msgstr "URL '%s' ist ungültig\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "Konnte Datei '%s' nicht von %s übertragen : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "Kann den Download von %s nicht wieder aufnehmen, starte neu\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "Fehler beim Beschreiben von Datei '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "Konnte Datei '%s' nicht von %s übertragen\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s scheint verstümmelt zu sein: %jd/%jd Byte\n"
@@ -302,6 +304,14 @@ msgstr "Datenbank bereits registriert"
msgid "could not find database"
msgstr "Konnte Datenbank nicht finden"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "Keine korrekte Version der Datenbank"
@@ -359,9 +369,17 @@ msgstr "Konnte Paket nicht finden oder lesen"
msgid "operation cancelled due to ignorepkg"
msgstr "Vorgang abgebrochen auf Grund von IgnorePkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "Ungültiges oder beschädigtes Paket"
msgstr "Ungültiges oder beschädigtes Delta"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -383,6 +401,14 @@ msgstr "Die Paket-Architektur ist ungültig"
msgid "could not find repository for target"
msgstr "Konnte kein Repositorium für das Ziel finden"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "Ungültiges oder beschädigtes Delta"
@@ -407,10 +433,6 @@ msgstr "In Konflikt stehende Dateien"
msgid "failed to retrieve some files"
msgstr "Konnte manche Dateien nicht übertragen"
#, c-format
msgid "failed to copy some file"
msgstr "Konnte irgendeine Datei nicht kopieren"
#, c-format
msgid "invalid regular expression"
msgstr "Ungültiger Regulärer Ausdruck"
@@ -423,6 +445,10 @@ msgstr "libarchive-Fehler"
msgid "download library error"
msgstr "Fehler in der Bibliothek für Downloads"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "Fehler beim Aufruf eines externen Downloaders"
@@ -431,10 +457,6 @@ msgstr "Fehler beim Aufruf eines externen Downloaders"
msgid "unexpected error"
msgstr "Unerwarteter Fehler"
#, c-format
msgid "database larger than maximum size\n"
msgstr "Datenbank überschreitet die maximal erlaubte Größe\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "Konnte %s nicht in Datenbank finden -- Überspringe\n"
@@ -447,6 +469,10 @@ msgstr "Entferne '%s' aus der Ziel-Liste\n"
msgid "cannot remove file '%s': %s\n"
msgstr "Kann Datei '%s' nicht entfernen: %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "Konnte Datenbank-Eintrag %s-%s nicht entfernen\n"
@@ -499,14 +525,6 @@ msgstr "Konnte Lösch-Vorgang nicht durchführen\n"
msgid "could not commit transaction\n"
msgstr "Konnte den Vorgang nicht durchführen\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "Datenbank-Version %s ist zu alt\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "Konnte Sperrdatei %s nicht entfernen\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "Konnte temporäres Verzeichnis nicht erstellen\n"

View File

@@ -1,16 +1,18 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# nous <nous@archlinux.us>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-04-08 16:42+0000\n"
"Last-Translator: nous <nous@archlinux.us>\n"
"Language-Team: Greek <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Greek (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/el/)\n"
"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +155,14 @@ msgstr "απόντα μετα-δεδομένα πακέτου στο %s\n"
msgid "removing invalid file: %s\n"
msgstr "διαγραφή άκυρου αρχείου: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "αδυναμία διαγραφής αρχείου κλειδώματος %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "ακαθόριστη διαδρομή βάσης\n"
@@ -213,22 +223,14 @@ msgstr "δίσκο"
msgid "url '%s' is invalid\n"
msgstr "άκυρη διεύθυνση '%s'\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "αποτυχία λήψης αρχείου '%s' από %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "συνέχιση λήψης %s αδύνατη, επανεκκίνηση\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "σφάλμα εγγραφής στο '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "αποτυχία λήψης αρχείου '%s' από %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "το %s δείχνει ημιτελές: %jd/%jd bytes\n"
@@ -297,6 +299,14 @@ msgstr "βάση ήδη εκκινηθείσα"
msgid "could not find database"
msgstr "αδυναμία εύρεσης βάσης"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "εσφαλμένη έκδοση βάσης"
@@ -353,9 +363,17 @@ msgstr "αδυναμία εύρεσης ή ανάγνωσης πακέτου"
msgid "operation cancelled due to ignorepkg"
msgstr "ακύρωση λειτουργίας λόγω ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "άκυρο ή κατεστραμμένο πακέτο"
msgstr "άκυρο ή κατεστραμμένο delta"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -377,6 +395,14 @@ msgstr "μη έγκυρη αρχιτεκτονική πακέτου"
msgid "could not find repository for target"
msgstr "αδυναμία εύρεσης αποθήκης για διεκπεραίωση"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "άκυρο ή κατεστραμμένο delta"
@@ -401,10 +427,6 @@ msgstr "διένεξη αρχείων"
msgid "failed to retrieve some files"
msgstr "αποτυχία λήψης κάποιων αρχείων"
#, c-format
msgid "failed to copy some file"
msgstr "αποτυχία αντιγραφής αρχείου"
#, c-format
msgid "invalid regular expression"
msgstr "άκυρη κανονική έκφραση"
@@ -417,6 +439,10 @@ msgstr "σφάλμα libarchive"
msgid "download library error"
msgstr "σφάλμα βιβλιοθήκης λήψης"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "σφάλμα κλήσης προγράμματος λήψης"
@@ -425,10 +451,6 @@ msgstr "σφάλμα κλήσης προγράμματος λήψης"
msgid "unexpected error"
msgstr "απροσδόκητο σφάλμα"
#, c-format
msgid "database larger than maximum size\n"
msgstr "βάση μεγαλύτερη από μέγιστο όριο\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "δεν βρέθηκε το %s στη βάση -- παράλειψη\n"
@@ -441,6 +463,10 @@ msgstr "αφαίρεση του %s από λίστα διεκπεραίωσης\
msgid "cannot remove file '%s': %s\n"
msgstr "αδυναμία διαγραφής αρχείου '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "αδυναμία διαγραφής εγγραφής βάσης %s-%s\n"
@@ -494,14 +520,6 @@ msgstr "αδυναμία διεκπεραίωσης διαγραφής\n"
msgid "could not commit transaction\n"
msgstr "αδυναμία διεκπεραίωσης\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "πολύ παλιά έκδοση βάσης %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "αδυναμία διαγραφής αρχείου κλειδώματος %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "αδυναμία δημιουργίας προσωρινού καταλόγου\n"

View File

@@ -1,14 +1,14 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-09 01:00+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: en_GB\n"
@@ -153,6 +153,14 @@ msgstr "missing package metadata in %s\n"
msgid "removing invalid file: %s\n"
msgstr "removing invalid file: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "could not remove lock file %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr "could not parse package description file '%s' from db '%s'\n"
#, c-format
msgid "database path is undefined\n"
msgstr "database path is undefined\n"
@@ -213,22 +221,14 @@ msgstr "disk"
msgid "url '%s' is invalid\n"
msgstr "URL '%s' is invalid\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr "failed to create temporary file for download\n"
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "failed retrieving file '%s' from %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "resuming download of %s not possible; starting over\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "error writing to file '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "failed retrieving file '%s' from %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s appears to be truncated: %jd/%jd bytes\n"
@@ -297,6 +297,14 @@ msgstr "database already registered"
msgid "could not find database"
msgstr "could not find database"
#, c-format
msgid "invalid or corrupted database"
msgstr "invalid or corrupted database"
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr "invalid or corrupted database (PGP signature)"
#, c-format
msgid "database is incorrect version"
msgstr "database is incorrect version"
@@ -353,9 +361,17 @@ msgstr "could not find or read package"
msgid "operation cancelled due to ignorepkg"
msgstr "operation cancelled due to ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "invalid or corrupted package"
msgstr "invalid or corrupted database"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr "invalid or corrupted package (checksum)"
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr "invalid or corrupted package (PGP signature)"
#, c-format
msgid "cannot open package file"
@@ -377,6 +393,14 @@ msgstr "package architecture is not valid"
msgid "could not find repository for target"
msgstr "could not find repository for target"
#, c-format
msgid "missing PGP signature"
msgstr "missing PGP signature"
#, c-format
msgid "invalid PGP signature"
msgstr "invalid PGP signature"
#, c-format
msgid "invalid or corrupted delta"
msgstr "invalid or corrupted delta"
@@ -401,10 +425,6 @@ msgstr "conflicting files"
msgid "failed to retrieve some files"
msgstr "failed to retrieve some files"
#, c-format
msgid "failed to copy some file"
msgstr "failed to copy some file"
#, c-format
msgid "invalid regular expression"
msgstr "invalid regular expression"
@@ -417,6 +437,10 @@ msgstr "libarchive error"
msgid "download library error"
msgstr "download library error"
#, c-format
msgid "gpgme error"
msgstr "gpgme error"
#, c-format
msgid "error invoking external downloader"
msgstr "error invoking external downloader"
@@ -425,10 +449,6 @@ msgstr "error invoking external downloader"
msgid "unexpected error"
msgstr "unexpected error"
#, c-format
msgid "database larger than maximum size\n"
msgstr "database larger than maximum size\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "could not find %s in database -- skipping\n"
@@ -441,6 +461,10 @@ msgstr "removing %s from target list\n"
msgid "cannot remove file '%s': %s\n"
msgstr "cannot remove file '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr "cannot remove %s (%s)\n"
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "could not remove database entry %s-%s\n"
@@ -493,14 +517,6 @@ msgstr "could not commit removal transaction\n"
msgid "could not commit transaction\n"
msgstr "could not commit transaction\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "%s database version is too old\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "could not remove lock file %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "could not create temp directory\n"

View File

@@ -1,16 +1,20 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# neiko <neikokz+tsfx@gmail.com>, 2011.
# Juan Antonio Cánovas Pérez <traumness@gmail.com>, 2011.
# Angel Velasquez <angvp@archlinux.org>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"Last-Translator: angvp <angvp@archlinux.org>\n"
"Language-Team: Spanish (Castilian) <>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/"
"archlinux-pacman/team/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -157,6 +161,14 @@ msgstr "faltan los metadatos del paquete en %s\n"
msgid "removing invalid file: %s\n"
msgstr "eliminando archivo inválido: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "no se pudo eliminar el archivo de bloqueo %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "la ruta de la base de datos no está definida\n"
@@ -221,22 +233,14 @@ msgstr "disco"
msgid "url '%s' is invalid\n"
msgstr "la dirección %s no es válida\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "fallo al obtener archivo '%s' desde %s: %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "no es posible continuar la descarga de %s; empezando de nuevo\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "no se pudo escribir al archivo '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "error al obtener el archivo '%s' desde %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s parece estar truncado: %jd/%jd bytes\n"
@@ -305,6 +309,14 @@ msgstr "base de datos ya registrada"
msgid "could not find database"
msgstr "no se pudo encontrar la base de datos"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "la base de datos es de una versión incorrecta"
@@ -362,9 +374,17 @@ msgstr "no se pudo encontrar o leer el paquete"
msgid "operation cancelled due to ignorepkg"
msgstr "operación cancelada debido a ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "paquete inválido o corrupto"
msgstr "no válido o diferencial dañado"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -386,6 +406,14 @@ msgstr "la arquitectura del paquete no es válida"
msgid "could not find repository for target"
msgstr "no pudo encontrarse un repositorio para el objetivo"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "no válido o diferencial dañado"
@@ -410,10 +438,6 @@ msgstr "archivos en conflicto"
msgid "failed to retrieve some files"
msgstr "error al descargar algunos archivos"
#, c-format
msgid "failed to copy some file"
msgstr "error al copiar algún archivo"
#, c-format
msgid "invalid regular expression"
msgstr "expresión regular no válida"
@@ -426,6 +450,10 @@ msgstr "error de libarchive"
msgid "download library error"
msgstr "error de descarga de biblioteca"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "error invocando el descargador externo"
@@ -434,10 +462,6 @@ msgstr "error invocando el descargador externo"
msgid "unexpected error"
msgstr "error inesperado"
#, c-format
msgid "database larger than maximum size\n"
msgstr "la base de datos supera el tamaño máximo\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "no se pudo encontrar %s en la base de datos -- saltando\n"
@@ -450,6 +474,10 @@ msgstr "quitando %s de la lista de objetivos\n"
msgid "cannot remove file '%s': %s\n"
msgstr "no se pudo quitar el archivo '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "no se pudo quitar la entrada %s-%s de la base de datos\n"
@@ -504,14 +532,6 @@ msgstr "no se pudo enviar la operación de eliminación\n"
msgid "could not commit transaction\n"
msgstr "no se pudo asignar la transacción\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "la versión de la base de datos %s es muy antigua\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "no se pudo eliminar el archivo de bloqueo %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "no se puede crear el directorio temporal\n"

View File

@@ -11,9 +11,9 @@ msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-08-08 16:37-0500\n"
"PO-Revision-Date: 2011-07-28 22:14+0000\n"
"Last-Translator: Larso <larso@gmx.com>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Finnish (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/fi/)\n"
"Language: fi\n"
@@ -158,6 +158,14 @@ msgstr "paketin metadata puuttuu tiedostosta %s\n"
msgid "removing invalid file: %s\n"
msgstr "poistetaan virheellinen tiedosto: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "lukkotiedostoa %s ei voitu poistaa\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "tietokannan polkua ei ole määritelty\n"
@@ -218,22 +226,14 @@ msgstr "levy"
msgid "url '%s' is invalid\n"
msgstr "osoite '%s' on virheellinen\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "tiedoston '%s' nouto palvelimelta %s epäonnistui : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "tiedoston %s latauksen jatkaminen ei mahdollista; aloitetaan alusta\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "virhe kirjoitettaessa tiedostoon '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "tiedoston '%s' nouto palvelimelta %s epäonnistui\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s näyttää katkenneen: %jd/%jd tavua\n"
@@ -302,6 +302,14 @@ msgstr "tietokanta on jo rekisteröity"
msgid "could not find database"
msgstr "tietokantaa ei löytynyt"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "tietokannan versio on väärä"
@@ -358,9 +366,17 @@ msgstr "pakettia ei löytynyt tai voitu lukea"
msgid "operation cancelled due to ignorepkg"
msgstr "operaatio peruutettiin ignorepkg:n takia"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "paketti ei kelvollinen tai se on vahingoittunut"
msgstr "delta ei kelvollinen tai vahingoittunut"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -382,6 +398,14 @@ msgstr "paketin arkkitehtuuri ei ole kelvollinen"
msgid "could not find repository for target"
msgstr "kohteen varastoa ei löytynyt"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "delta ei kelvollinen tai vahingoittunut"
@@ -406,10 +430,6 @@ msgstr "ristiriidassa olevia tiedostoja"
msgid "failed to retrieve some files"
msgstr "joidenkin tiedostojen nouto epäonnistui"
#, c-format
msgid "failed to copy some file"
msgstr "jonkin tiedoston kopiointi epäonnistui"
#, c-format
msgid "invalid regular expression"
msgstr "virheellinen säännöllinen lauseke"
@@ -422,6 +442,10 @@ msgstr "libarchive-virhe"
msgid "download library error"
msgstr "latauskirjaston virhe"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "virhe kutsuttaessa ulkoista latausohjelmaa"
@@ -430,10 +454,6 @@ msgstr "virhe kutsuttaessa ulkoista latausohjelmaa"
msgid "unexpected error"
msgstr "odottamaton virhe"
#, c-format
msgid "database larger than maximum size\n"
msgstr "tietokanta enimmäiskokoa suurempi\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "%s ei löytynyt tietokannasta -- ohitetaan\n"
@@ -446,6 +466,10 @@ msgstr "poistetaan %s kohteiden listasta\n"
msgid "cannot remove file '%s': %s\n"
msgstr "tiedostoa '%s' ei voitu poistaa: %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "ei voitu poistaa tietokantamerkintää %s-%s\n"
@@ -500,14 +524,6 @@ msgstr "poistotoimenpidettä ei voitu suorittaa\n"
msgid "could not commit transaction\n"
msgstr "toimenpidettä ei voitu suorittaa\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "tietokannan %s versio on liian vanha\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "lukkotiedostoa %s ei voitu poistaa\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "väliaikaiskansiota ei voitu luoda\n"

View File

@@ -1,16 +1,18 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# shining <chantry.xavier@gmail.com>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-23 07:04+0000\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: French <>\n"
"Language-Team: French (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/fr/)\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +155,14 @@ msgstr "méta-données du paquet manquantes dans %s\n"
msgid "removing invalid file: %s\n"
msgstr "suppression du fichier invalide: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "la suppression du fichier de verrouillage %s a échoué\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "base de données non initialisée\n"
@@ -216,22 +226,14 @@ msgstr "disque"
msgid "url '%s' is invalid\n"
msgstr "l'url '%s' est invalide\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "échec de récupération du fichier '%s' depuis %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "le téléchargement de %s ne peut pas être continué, reprise au début\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "écriture dans le fichier '%s' impossible: %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "échec de récupération du fichier '%s' depuis %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s est apparemment tronqué: %jd/%jd bytes\n"
@@ -300,6 +302,14 @@ msgstr "base de données déjà enregistrée"
msgid "could not find database"
msgstr "trouver la base de données a échoué"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "la base de données n'est pas à la bonne version"
@@ -358,9 +368,17 @@ msgstr "impossible de trouver ou de lire le paquet"
msgid "operation cancelled due to ignorepkg"
msgstr "opération annulée à cause d'un paquet à ignorer (IgnorePkg)"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "paquet invalide ou corrompu"
msgstr "delta invalide ou corrompu"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -382,6 +400,14 @@ msgstr "architecture invalide"
msgid "could not find repository for target"
msgstr "impossible de trouver le dépôt pour la cible"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "delta invalide ou corrompu"
@@ -406,10 +432,6 @@ msgstr "conflit de fichiers"
msgid "failed to retrieve some files"
msgstr "échec de récupération de certains fichiers"
#, c-format
msgid "failed to copy some file"
msgstr "erreur lors d'une copie de fichier"
#, c-format
msgid "invalid regular expression"
msgstr "expression régulière incorrecte"
@@ -422,6 +444,10 @@ msgstr "erreur de libarchive"
msgid "download library error"
msgstr "erreur de la bibliothèque de téléchargement"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "erreur en invoquant le client externe de téléchargement"
@@ -430,10 +456,6 @@ msgstr "erreur en invoquant le client externe de téléchargement"
msgid "unexpected error"
msgstr "erreur non prévue"
#, c-format
msgid "database larger than maximum size\n"
msgstr "la base de données est plus grande que la taille maximale\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "trouver %s dans la base de données a échoué -- ignoré\n"
@@ -446,6 +468,10 @@ msgstr "supprime %s de la liste de cible\n"
msgid "cannot remove file '%s': %s\n"
msgstr "suppression du fichier '%s' impossible: %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "la suppression de l'entrée de base de données %s-%s a échoué\n"
@@ -498,14 +524,6 @@ msgstr "appliquer la transaction de suppression a échoué\n"
msgid "could not commit transaction\n"
msgstr "appliquer la transaction a échoué\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "La version de la base de données %s est trop vieille\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "la suppression du fichier de verrouillage %s a échoué\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "la création du répertoire temporaire a échoué\n"

View File

@@ -1,16 +1,17 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# ngaba <ngaba@bibl.u-szeged.hu>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"Last-Translator: ngaba <ngaba@bibl.u-szeged.hu>\n"
"Language-Team: Hungarian <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Hungarian (http://www.transifex.net/projects/p/archlinux-"
"pacman/team/hu/)\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +154,14 @@ msgstr "hiányzó csomaginformációs fájl itt: %s\n"
msgid "removing invalid file: %s\n"
msgstr "hibás fájl eltávolítása: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "nem sikerült a zároló fájl (%s) eltávolítása\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "az adatbázis-útvonal nincs megadva\n"
@@ -215,22 +224,14 @@ msgstr "diszk"
msgid "url '%s' is invalid\n"
msgstr "a '%s' URL hibás\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "nem sikerült a(z) '%s' fájlt letölteni a %s helyről : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "nem tudom folytatni a(z) %s letöltését; újrakezdem\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "hiba a(z) '%s' fájl írása során: %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "nem sikerült a(z) '%s' fájlt letölteni a %s helyről\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "úgy tűnik, hogy %s csonka: %jd/%jd bájt\n"
@@ -299,6 +300,14 @@ msgstr "az adatbázis már regisztrált"
msgid "could not find database"
msgstr "nem található az adatbázis"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "hibás verziójú az adatbázis"
@@ -355,9 +364,17 @@ msgstr "nem található vagy nem olvasható a csomag"
msgid "operation cancelled due to ignorepkg"
msgstr "művelet megszakítva ignorepkg miatt"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "hibás vagy sérült csomag"
msgstr "hibás vagy sérült delta"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -379,6 +396,14 @@ msgstr "érvénytelen csomag-architektúra"
msgid "could not find repository for target"
msgstr "nem található repó a célcsomaghoz"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "hibás vagy sérült delta"
@@ -403,10 +428,6 @@ msgstr "ütköző fájlok"
msgid "failed to retrieve some files"
msgstr "nem sikerült néhány fájlt letölteni"
#, c-format
msgid "failed to copy some file"
msgstr "nem sikerült néhány fájlt másolni"
#, c-format
msgid "invalid regular expression"
msgstr "hibás reguláris kifejezés"
@@ -419,6 +440,10 @@ msgstr "libarchive hiba"
msgid "download library error"
msgstr "letöltőkönyvtár hiba"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "hiba a külső letöltő meghívásakor"
@@ -427,10 +452,6 @@ msgstr "hiba a külső letöltő meghívásakor"
msgid "unexpected error"
msgstr "nemvárt hiba"
#, c-format
msgid "database larger than maximum size\n"
msgstr "az adatbázis nagyobb, mint a maximális megengedett méret\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "nem található a(z) %s az adatbázisban -- kihagyás\n"
@@ -443,6 +464,10 @@ msgstr "%s eltávolítása a cél listából\n"
msgid "cannot remove file '%s': %s\n"
msgstr "nem sikerült eltávolítani a '%s' fájlt : %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "nem sikerült eltávolítani a(z) %s-%s adatbázis-bejegyzést\n"
@@ -495,14 +520,6 @@ msgstr "nem sikerült végrehajtani az eltávolító tranzakciót\n"
msgid "could not commit transaction\n"
msgstr "nem sikerült végrehajtani a tranzakciót\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "a(z) %s adatbázis túl régi verziójú\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "nem sikerült a zároló fájl (%s) eltávolítása\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "nem sikerült létrehozni az ideiglenes könyvtárat\n"

View File

@@ -1,16 +1,18 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Giovanni Scafora <giovanni@archlinux.org>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"Last-Translator: giovanni <giovanni@archlinux.org>\n"
"Language-Team: Italian <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Italian (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/it/)\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -158,6 +160,14 @@ msgstr "manca il metadata del pacchetto in %s\n"
msgid "removing invalid file: %s\n"
msgstr "rimozione del file non valido: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "impossibile rimuovere il file di lock %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "il percorso del database non è stato definito\n"
@@ -221,22 +231,14 @@ msgstr "disco"
msgid "url '%s' is invalid\n"
msgstr "l'url '%s' non è esatto\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "impossibile scaricare il pacchetto '%s' da %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "impossibile riprendere il download di %s\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "si è verificato un errore durante la scrittura nel file '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "impossibile scaricare il pacchetto '%s' da %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s sembra essere incompleto: %jd/%jd byte\n"
@@ -305,6 +307,14 @@ msgstr "il database è già stato registrato"
msgid "could not find database"
msgstr "impossibile trovare il database"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "la versione del database non è esatta"
@@ -361,9 +371,17 @@ msgstr "impossibile trovare o leggere il pacchetto"
msgid "operation cancelled due to ignorepkg"
msgstr "l'operazione è stata ignorata a causa di ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "il pacchetto non è valido oppure è corrotto"
msgstr "il delta non è valido oppure è corrotto"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -385,6 +403,14 @@ msgstr "l'architettura del pacchetto non è valida"
msgid "could not find repository for target"
msgstr "impossibile trovare un repository contenente questo pacchetto"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "il delta non è valido oppure è corrotto"
@@ -409,10 +435,6 @@ msgstr "file in conflitto"
msgid "failed to retrieve some files"
msgstr "impossibile scaricare alcuni file"
#, c-format
msgid "failed to copy some file"
msgstr "impossibile copiare alcuni file"
#, c-format
msgid "invalid regular expression"
msgstr "l'espressione regolare non è valida"
@@ -425,6 +447,10 @@ msgstr "errore di libarchive"
msgid "download library error"
msgstr "si è verificato un errore della libreria di download"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "si è verificato un errore lanciando il downloader esterno"
@@ -433,11 +459,6 @@ msgstr "si è verificato un errore lanciando il downloader esterno"
msgid "unexpected error"
msgstr "errore inaspettato"
#, c-format
msgid "database larger than maximum size\n"
msgstr ""
"la grandezza del database è superiore alla dimensione massima consentita\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "impossibile trovare %s nel database, sarà ignorato\n"
@@ -450,6 +471,10 @@ msgstr "rimozione di %s dalla lista dei pacchetti\n"
msgid "cannot remove file '%s': %s\n"
msgstr "impossibile rimuovere il file '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "impossibile rimuovere la voce %s-%s dal database\n"
@@ -504,14 +529,6 @@ msgstr "impossibile eseguire l'operazione di rimozione\n"
msgid "could not commit transaction\n"
msgstr "impossibile eseguire l'operazione\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "la versione del database %s è troppo vecchia\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "impossibile rimuovere il file di lock %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "impossibile creare la directory temporanea\n"

View File

@@ -1,16 +1,18 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Dan McGee <dpmcgee@gmail.com>, 2011.
# Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-03-22 15:34+0000\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Kazakh <None>\n"
"Language-Team: Kazakh (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/kk/)\n"
"Language: kk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +155,14 @@ msgstr "%s ішінде дестенің мета мәліметтері жоқ\
msgid "removing invalid file: %s\n"
msgstr "қате файлды өшіру: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "%s оқшау файлын өшіру мүмкін емес\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "дерекқорға жол анықталмаған\n"
@@ -213,22 +223,14 @@ msgstr "дискі"
msgid "url '%s' is invalid\n"
msgstr "'%s' сілтемесі қате\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "'%s' файлын %s адресінен алу қатемен аяқталды : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "%s жүктемесін жалғастыру мүмкін емес; басынан басталады\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "'%s' файлына жазу қатесі: %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "'%s' файлын %s адресінен алу қатемен аяқталды\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s қысқартылған сияқты: %jd/%jd байт\n"
@@ -297,6 +299,14 @@ msgstr "дерекқор тіркелген болып тұр"
msgid "could not find database"
msgstr "дерекқорды табу мүмкін емес"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "дерекқор нұсқасы дұрыс емес"
@@ -353,9 +363,17 @@ msgstr "дестені табу не оқу мүмкін емес"
msgid "operation cancelled due to ignorepkg"
msgstr "әрекет ignorepkg салдарынан тоқтатылды"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "десте қате не зақымдалған"
msgstr "дельта файлы қате не зақымдалған"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -377,6 +395,14 @@ msgstr "десте файлдың архитектурасы қате"
msgid "could not find repository for target"
msgstr "көрсетілген мақсат үшін репозиторийді табу мүмкін емес"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "дельта файлы қате не зақымдалған"
@@ -401,10 +427,6 @@ msgstr "ерегісетін файлдар"
msgid "failed to retrieve some files"
msgstr "кейбір файлдарды алу сәтсіз аяқталды"
#, c-format
msgid "failed to copy some file"
msgstr "кейбір файлдарды көшіру сәтсіз"
#, c-format
msgid "invalid regular expression"
msgstr "тұрақты өрнек дұрыс емес"
@@ -417,6 +439,10 @@ msgstr "libarchive қатесі орын алды"
msgid "download library error"
msgstr "download library қатесі орын алды"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "сыртқы жүктемелер менеджерін шақыру қатемен аяқталды"
@@ -425,10 +451,6 @@ msgstr "сыртқы жүктемелер менеджерін шақыру қа
msgid "unexpected error"
msgstr "күтпеген қате кетті"
#, c-format
msgid "database larger than maximum size\n"
msgstr "дерекқор рұқсат етілген өлшемінен үлкен\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "дерекқор ішінде %s табылмады -- өткізіп жібереміз\n"
@@ -441,6 +463,10 @@ msgstr "мақсаттар тізімінен '%s' өшіру\n"
msgid "cannot remove file '%s': %s\n"
msgstr " '%s' файлын өшіру мүмкін емес: %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "дерекқордан %s-%s жазбасын өшіру мүмкін емес\n"
@@ -494,14 +520,6 @@ msgstr "өшіруге сұранымды орындау мүмкін емес\n
msgid "could not commit transaction\n"
msgstr "сұранымды аяқтау мүмкін емес\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "%s дерекқор нұсқасы тым ескі\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "%s оқшау файлын өшіру мүмкін емес\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "уақытша буманы құру мүмкін емес\n"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: pacman 3.5.3\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-08-08 16:37-0500\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -151,6 +151,14 @@ msgstr ""
msgid "removing invalid file: %s\n"
msgstr ""
#, c-format
msgid "could not remove lock file %s\n"
msgstr ""
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr ""
@@ -211,22 +219,14 @@ msgstr ""
msgid "url '%s' is invalid\n"
msgstr ""
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr ""
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr ""
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr ""
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr ""
@@ -295,6 +295,14 @@ msgstr ""
msgid "could not find database"
msgstr ""
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr ""
@@ -355,6 +363,14 @@ msgstr ""
msgid "invalid or corrupted package"
msgstr ""
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
msgstr ""
@@ -375,6 +391,14 @@ msgstr ""
msgid "could not find repository for target"
msgstr ""
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr ""
@@ -399,10 +423,6 @@ msgstr ""
msgid "failed to retrieve some files"
msgstr ""
#, c-format
msgid "failed to copy some file"
msgstr ""
#, c-format
msgid "invalid regular expression"
msgstr ""
@@ -415,6 +435,10 @@ msgstr ""
msgid "download library error"
msgstr ""
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr ""
@@ -423,10 +447,6 @@ msgstr ""
msgid "unexpected error"
msgstr ""
#, c-format
msgid "database larger than maximum size\n"
msgstr ""
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr ""
@@ -439,6 +459,10 @@ msgstr ""
msgid "cannot remove file '%s': %s\n"
msgstr ""
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr ""
@@ -491,14 +515,6 @@ msgstr ""
msgid "could not commit transaction\n"
msgstr ""
#, c-format
msgid "%s database version is too old\n"
msgstr ""
#, c-format
msgid "could not remove lock file %s\n"
msgstr ""
#, c-format
msgid "could not create temp directory\n"
msgstr ""

View File

@@ -1,16 +1,17 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Jon Gjengset <jon@thesquareplanet.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-04-16 00:45+0000\n"
"Last-Translator: Jonhoo <jon@thesquareplanet.com>\n"
"Language-Team: Norwegian Bokmål <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Norwegian Bokmål (http://www.transifex.net/projects/p/"
"archlinux-pacman/team/nb/)\n"
"Language: nb\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -153,6 +154,14 @@ msgstr "mangler metadata i %s\n"
msgid "removing invalid file: %s\n"
msgstr "fjerner ugyldig fil: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "kunne ikke fjerne låsingsfil %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "databaseplassering er udefinert\n"
@@ -214,22 +223,14 @@ msgstr "disk"
msgid "url '%s' is invalid\n"
msgstr "url '%s' er ugyldig\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "mottakelse av fil '%s' fra %s : %s feilet\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "kan ikke fortsette nedlastingen av %s; starter på nytt\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "skriving til fil '%s': %s feilet\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "mottakelse av fil '%s' fra %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s ser ut til å være trunkert: %jd/%jd bytes\n"
@@ -298,6 +299,14 @@ msgstr "database allerede registret"
msgid "could not find database"
msgstr "kunne ikke finne database"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "databasen har feil versjonsnummer"
@@ -354,9 +363,17 @@ msgstr "kunne ikke finne eller lese pakke"
msgid "operation cancelled due to ignorepkg"
msgstr "operasjon avsluttet grunnet ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "invalid eller korrupt pakke"
msgstr "invalid"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -378,6 +395,14 @@ msgstr "pakkearkitekturen er ikke gyldig"
msgid "could not find repository for target"
msgstr "fant ikke pakkebrønn for mål"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "invalid"
@@ -402,10 +427,6 @@ msgstr "modstridige filer"
msgid "failed to retrieve some files"
msgstr "mottagelsen av noen filer feilet"
#, c-format
msgid "failed to copy some file"
msgstr "kunne ikke kopiere en fil"
#, c-format
msgid "invalid regular expression"
msgstr "ugyldig uttrykk"
@@ -418,6 +439,10 @@ msgstr "feil i libarchive"
msgid "download library error"
msgstr "feil i nedlastingsbibliotek"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "påkalling av ekstern nedlaster feilet"
@@ -426,10 +451,6 @@ msgstr "påkalling av ekstern nedlaster feilet"
msgid "unexpected error"
msgstr "uforventet feil"
#, c-format
msgid "database larger than maximum size\n"
msgstr "databasen er større enn maksstørrelsen\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "kunne ikke finne %s i database -- hopper over\n"
@@ -442,6 +463,10 @@ msgstr "fjerner %s fra målliste\n"
msgid "cannot remove file '%s': %s\n"
msgstr "kan ikke fjerne fil '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "kunne ikke fjerne databaseelement %s-%s\n"
@@ -494,14 +519,6 @@ msgstr "kunne ikke begå fjerningstransaksjon\n"
msgid "could not commit transaction\n"
msgstr "kunne ikke begå transaksjon\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "%s databaseversjon for gammel\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "kunne ikke fjerne låsingsfil %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "kunne ikke opprette midlertidig mappe\n"

View File

@@ -1,16 +1,17 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Bartek Piotrowski <barthalion@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-04-12 20:00+0000\n"
"Last-Translator: Barthalion <barthalion@gmail.com>\n"
"Language-Team: Polish <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Polish (http://www.transifex.net/projects/p/archlinux-pacman/"
"team/pl/)\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -154,6 +155,14 @@ msgstr "brak metadanych pakietu w %s\n"
msgid "removing invalid file: %s\n"
msgstr "usuwanie nieprawidłowego pliku: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "nie udało się usunąć pliku blokującego %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "ścieżka bazy danych jest niezdefiniowana\n"
@@ -215,22 +224,14 @@ msgstr "dysk"
msgid "url '%s' is invalid\n"
msgstr "url '%s' jest błędny\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "nie udało się pobrać pliku '%s' z %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "kontynuowanie pobieranie %s jest niemożliwe; zaczynam od nowa\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "Błąd podczas zapisywania do pliku '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "nie udało się pobrać pliku '%s' z %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s wygląda, jakby został obcięty %jd/%jd bajtów\n"
@@ -299,6 +300,14 @@ msgstr "baza danych już zarejestrowana"
msgid "could not find database"
msgstr "nie udało się odnaleźć bazy danych"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "niepoprawna wersja bazy danych"
@@ -355,9 +364,17 @@ msgstr "nie udało się znaleźć bądź odczytać pakietu"
msgid "operation cancelled due to ignorepkg"
msgstr "operacja anulowana przez ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "nieprawidłowy bądź uszkodzony pakiet"
msgstr "nieprawidłowy bądź uszkodzony pakiet przyrostowy"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -379,6 +396,14 @@ msgstr "architektura pakietu jest nieprawidłowa"
msgid "could not find repository for target"
msgstr "nie mogę znaleźć repozytorium dla celu"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "nieprawidłowy bądź uszkodzony pakiet przyrostowy"
@@ -403,10 +428,6 @@ msgstr "konfliktujące pliki"
msgid "failed to retrieve some files"
msgstr "nie udało się odzyskać niektórych plików"
#, c-format
msgid "failed to copy some file"
msgstr "bład kopiowania niektórych plików"
#, c-format
msgid "invalid regular expression"
msgstr "nieprawidłowe wyrażenie regularne"
@@ -419,6 +440,10 @@ msgstr "błąd libarchive"
msgid "download library error"
msgstr "błąd pobierania biblioteki"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr ""
@@ -428,10 +453,6 @@ msgstr ""
msgid "unexpected error"
msgstr "niespodziewany błąd"
#, c-format
msgid "database larger than maximum size\n"
msgstr "baza danych jest większa, niż maksymalny rozmiar\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "nie udało się odnaleźć %s w bazie danych -- pomijanie\n"
@@ -444,6 +465,10 @@ msgstr "usuwanie %s z listy celów\n"
msgid "cannot remove file '%s': %s\n"
msgstr "nie udało się usunąć pliku '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "nie udało się usunąć wpisu %s-%s z bazy danych\n"
@@ -496,14 +521,6 @@ msgstr "nie udało się wykonać tranzakcji usuwania\n"
msgid "could not commit transaction\n"
msgstr "nie udało się wykonać tranzakcji\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "wersja bazy danych %s jest za stara\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "nie udało się usunąć pliku blokującego %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "nie udało się stworzyć katalogu tymczasowego\n"

View File

@@ -1,16 +1,17 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Gaspar Santos <omeuviolino@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-04-16 01:24+0000\n"
"Last-Translator: ArchGalileu <omeuviolino@gmail.com>\n"
"Language-Team: Portuguese <>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.net/projects/p/archlinux-"
"pacman/team/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -154,6 +155,14 @@ msgstr "em falta metadados do pacote em %s\n"
msgid "removing invalid file: %s\n"
msgstr "a remover ficheiro inválido: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "não foi possível remover o ficheiro bloqueado %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "localização da base de dados não definida\n"
@@ -218,22 +227,14 @@ msgstr "disco"
msgid "url '%s' is invalid\n"
msgstr "url '%s' é inválida\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "falha ao obter ficheiro '%s' de %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "não foi possível retomar a descarga de %s; a reiniciar a descarga\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "erro ao escrever no ficheiro '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "falha ao obter o ficheiro '%s' de %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s parece estar quebrado: %jd/%jd bytes\n"
@@ -302,6 +303,14 @@ msgstr "base de dados já registrada"
msgid "could not find database"
msgstr "não foi possível encontrar a base de dados"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "a versão da base de dados é incorrecta"
@@ -358,9 +367,17 @@ msgstr "não foi possível ler ou escrever o pacote"
msgid "operation cancelled due to ignorepkg"
msgstr "operação cancelada devido a ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "pacote inválido ou corrompido"
msgstr "delta inválido ou corrompido"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -382,6 +399,14 @@ msgstr "a arquitectura do pacote não é válida"
msgid "could not find repository for target"
msgstr "não foi possível encontrar o repositório para o pacote"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "delta inválido ou corrompido"
@@ -406,10 +431,6 @@ msgstr "ficheiros em conflito"
msgid "failed to retrieve some files"
msgstr "falha ao descarregar alguns ficheiros"
#, c-format
msgid "failed to copy some file"
msgstr "falhou ao copiar algum ficheiro"
#, c-format
msgid "invalid regular expression"
msgstr "expressão regular inválida"
@@ -422,6 +443,10 @@ msgstr "erro na libarchive"
msgid "download library error"
msgstr "erro na biblioteca de descargas"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "erro ao invocar o programa de descargas externo"
@@ -430,10 +455,6 @@ msgstr "erro ao invocar o programa de descargas externo"
msgid "unexpected error"
msgstr "erro inesperado"
#, c-format
msgid "database larger than maximum size\n"
msgstr "a base de dados é maior que o tamanho máximo\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "não foi possível encontrar %s na base de dados - a ignorar\n"
@@ -446,6 +467,10 @@ msgstr "a remover \"%s\" da lista de pacotes a serem actualizados\n"
msgid "cannot remove file '%s': %s\n"
msgstr "não foi possível remover o ficheiro '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "não foi possível remover a entrada da base de dados %s-%s\n"
@@ -498,14 +523,6 @@ msgstr "não foi possível efectuar a operação de remoção\n"
msgid "could not commit transaction\n"
msgstr "não foi possível efectuar a operação\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "%s a versão da base de dados é demasiado antiga\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "não foi possível remover o ficheiro bloqueado %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "não foi possível criar diretório temporário\n"

View File

@@ -1,16 +1,19 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Pacman Development Team <pacman-dev@archlinux.org>
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Sandro <sandrossv@hotmail.com>, 2011.
# ambaratti <ambaratti.listas@gmail.com>, 2011.
# Dan McGee <dpmcgee@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Arch Linux Pacman package manager\n"
"Report-Msgid-Bugs-To: http://bugs.archlinux.org/index.php?project=3\n"
"POT-Creation-Date: 2011-04-18 11:23-0500\n"
"PO-Revision-Date: 2011-04-12 02:29+0000\n"
"Last-Translator: ambaratti <ambaratti.listas@gmail.com>\n"
"Language-Team: Portuguese (Brazilian) <None>\n"
"POT-Creation-Date: 2011-08-09 15:51-0500\n"
"PO-Revision-Date: 2011-08-08 22:33+0000\n"
"Last-Translator: toofishes <dpmcgee@gmail.com>\n"
"Language-Team: Portuguese (Brazilian) (http://www.transifex.net/projects/p/"
"archlinux-pacman/team/pt_BR/)\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -155,6 +158,14 @@ msgstr "faltando metadados do pacote em %s\n"
msgid "removing invalid file: %s\n"
msgstr "removendo arquivo inválido: %s\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "não foi possível remover o arquivo de trava %s\n"
#, c-format
msgid "could not parse package description file '%s' from db '%s'\n"
msgstr ""
#, c-format
msgid "database path is undefined\n"
msgstr "caminho da base de dados não definido\n"
@@ -218,22 +229,14 @@ msgstr "disco"
msgid "url '%s' is invalid\n"
msgstr "a url '%s' é inválida\n"
#, c-format
msgid "failed to create temporary file for download\n"
msgstr ""
#, c-format
msgid "failed retrieving file '%s' from %s : %s\n"
msgstr "falha ao obter o arquivo '%s' de %s : %s\n"
#, c-format
msgid "resuming download of %s not possible; starting over\n"
msgstr "não foi possível retomar o download de %s; começando de novo\n"
#, c-format
msgid "error writing to file '%s': %s\n"
msgstr "erro ao escrever no arquivo '%s': %s\n"
#, c-format
msgid "failed retrieving file '%s' from %s\n"
msgstr "falha ao obter arquivo '%s' de %s\n"
#, c-format
msgid "%s appears to be truncated: %jd/%jd bytes\n"
msgstr "%s parece estar truncado: %jd/%jd bytes\n"
@@ -302,6 +305,14 @@ msgstr "base de dados já registrada"
msgid "could not find database"
msgstr "não foi possível encontrar a base de dados"
#, c-format
msgid "invalid or corrupted database"
msgstr ""
#, c-format
msgid "invalid or corrupted database (PGP signature)"
msgstr ""
#, c-format
msgid "database is incorrect version"
msgstr "a versão da base de dados é incorreta"
@@ -358,9 +369,17 @@ msgstr "não foi possível ler ou escrever o pacote"
msgid "operation cancelled due to ignorepkg"
msgstr "operação cancelada devido a ignorepkg"
#, c-format
#, fuzzy, c-format
msgid "invalid or corrupted package"
msgstr "pacote inválido ou corrompido"
msgstr "delta inválido ou corrompido"
#, c-format
msgid "invalid or corrupted package (checksum)"
msgstr ""
#, c-format
msgid "invalid or corrupted package (PGP signature)"
msgstr ""
#, c-format
msgid "cannot open package file"
@@ -382,6 +401,14 @@ msgstr "a arquitetura do pacote não é valida"
msgid "could not find repository for target"
msgstr "não foi possível encontrar o repositório para o pacote"
#, c-format
msgid "missing PGP signature"
msgstr ""
#, c-format
msgid "invalid PGP signature"
msgstr ""
#, c-format
msgid "invalid or corrupted delta"
msgstr "delta inválido ou corrompido"
@@ -406,10 +433,6 @@ msgstr "arquivos conflitantes"
msgid "failed to retrieve some files"
msgstr "falha ao obter alguns arquivos"
#, c-format
msgid "failed to copy some file"
msgstr "falha ao copiar algum arquivo"
#, c-format
msgid "invalid regular expression"
msgstr "expressão regular inválida"
@@ -422,6 +445,10 @@ msgstr "erro de libarchive"
msgid "download library error"
msgstr "erro na biblioteca de download"
#, c-format
msgid "gpgme error"
msgstr ""
#, c-format
msgid "error invoking external downloader"
msgstr "erro ao chamar o programa de download externo"
@@ -430,10 +457,6 @@ msgstr "erro ao chamar o programa de download externo"
msgid "unexpected error"
msgstr "erro inesperado"
#, c-format
msgid "database larger than maximum size\n"
msgstr "banco de dados maior que o tamanho máximo\n"
#, c-format
msgid "could not find %s in database -- skipping\n"
msgstr "não foi possível encontrar %s na base de dados -- ignorando\n"
@@ -446,6 +469,10 @@ msgstr "removendo \"%s\" da lista de pacotes a serem atualizados\n"
msgid "cannot remove file '%s': %s\n"
msgstr "não foi possível remover o arquivo '%s': %s\n"
#, c-format
msgid "cannot remove %s (%s)\n"
msgstr ""
#, c-format
msgid "could not remove database entry %s-%s\n"
msgstr "não foi possível remover o registro da base de dados %s-%s\n"
@@ -498,14 +525,6 @@ msgstr "não foi possível efetuar a transação de remoção\n"
msgid "could not commit transaction\n"
msgstr "não foi possível efetuar a transação\n"
#, c-format
msgid "%s database version is too old\n"
msgstr "a versão do banco de dados %s é muito antiga\n"
#, c-format
msgid "could not remove lock file %s\n"
msgstr "não foi possível remover o arquivo de trava %s\n"
#, c-format
msgid "could not create temp directory\n"
msgstr "não foi possível criar diretório temporário\n"

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