Compare commits

...

7 Commits

Author SHA1 Message Date
Andrew Gregory
8b4f29af39 add --preremove option
Allows adding and removing packages within a single transaction. This is
particularly useful for complicated conflicts that ALPM cannot resolve
on its own, e.g.:

https://archlinux.org/news/linux-firmware-2025061312fe085f-5-upgrade-requires-manual-intervention/

Currently, dealing with these situations requires doing something
complicated like bypassing dependency checking to break and then repair
the database in two separate steps. By allowing installation and removal
within a single transaction no bypass is required:

 pacman -Syu --preremove linux-firmware linux-firmware

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2025-06-28 14:31:33 -07:00
morganamilo
45c4eef61d libalpm: move tempdir cleanup into _alpm_download
this ensures the dir still gets cleaned up even if killed by a signal
2025-05-26 16:13:06 +10:00
morganamilo
5c451cd976 libalpm: propagate signal from child to parent
If we ^C while downloading the parent should propagate so pacman can
exit as it did before the sandboxing.
2025-05-26 16:13:06 +10:00
morganamilo
d87dd153fc libalpm: finalize tempfile if destfile doesn't exist
On setup we move the termfile into the temp download dir to resume
downloads. We don't move these back losing any tempfiles we already had.
2025-05-26 16:13:06 +10:00
morganamilo
6fcecbd08d libalpm: set errno if child exited via signal 2025-05-26 16:13:06 +10:00
Diego Viola
528709131f Fix whitespace in README
Also ensure consistent style in API section
2025-05-26 16:11:13 +10:00
Dominik
9fca328caf makepkg: provide a field for tracking generic metadata
The xdata field is an array of key=value entries that allow a packager to
include arbitrary metadata in the generated .PKGINFO.

Fixes #241.

Signed-off-by: Dominik Peteler <archlinux+gitlab@with-h.at>
2025-05-26 16:09:02 +10:00
14 changed files with 243 additions and 115 deletions

218
README
View File

@@ -6,7 +6,7 @@ Package Management) library. This document, while not exhaustive, also
indicates some limitations (on purpose, or sometimes due to its poor design) of
the library at the present time.
There is one special file,"alpm.h", which is the public interface that
There is one special file, "alpm.h", which is the public interface that
should be distributed and installed on systems with the library. Only
structures, data and functions declared within this file are made available to
the frontend. Lots of structures are of an opaque type and their fields are
@@ -239,7 +239,7 @@ API CHANGES BETWEEN 3.1 AND 3.2
- alpm_checkdbconflicts()
- alpm_sync_newversion()
- alpm_deptest()
- error codes :
- error codes:
PM_ERR_DLT_INVALID, PM_ERR_LIBARCHIVE, PM_ERR_LIBDOWNLOAD and
PM_ERR_EXTERNAL_DOWNLOAD
- flags:
@@ -362,11 +362,11 @@ API CHANGES BETWEEN 3.4 AND 3.5
- alpm_find_grp_pkgs()
- alpm_trans_get_flags()
- error codes:
PM_ERR_DISK_SPACE, PM_ERR_WRITE
- flags
PM_TRANS_FLAG_NODEPVERSION, PM_TRANS_EVT_DISKSPACE_START,
PM_TRANS_EVT_DISKSPACE_DONE, PM_TRANS_CONV_SELECT_PROVIDER,
PM_TRANS_PROGRESS_DISKSPACE_START, PM_TRANS_PROGRESS_INTEGRITY_START
PM_ERR_DISK_SPACE, PM_ERR_WRITE
- flags:
PM_TRANS_FLAG_NODEPVERSION, PM_TRANS_EVT_DISKSPACE_START,
PM_TRANS_EVT_DISKSPACE_DONE, PM_TRANS_CONV_SELECT_PROVIDER,
PM_TRANS_PROGRESS_DISKSPACE_START, PM_TRANS_PROGRESS_INTEGRITY_START
API CHANGES BETWEEN 3.5 AND 4.0
@@ -419,7 +419,7 @@ API CHANGES BETWEEN 3.5 AND 4.0
- alpm_release
- alpm_remove_pkg
- alpm_sync_sysupgrade
- several structs are no longer opaque
- several structs are no longer opaque:
- alpm_conflict_t
- alpm_delta_t
- alpm_depend_t
@@ -431,19 +431,33 @@ API CHANGES BETWEEN 3.5 AND 4.0
[ADDED]
- option functions:
alpm_{get,set}_eventcb(), alpm_option_{get,set}_convcb(),
alpm_option_{get,set}_progresscb()
- alpm_{get,set}_eventcb()
- alpm_option_{get,set}_convcb()
- alpm_option_{get,set}_progresscb()
- package signing functions:
alpm_option_get_default_siglevel(), alpm_option_set_default_siglevel(),
alpm_option_get_gpgdir(), alpm_option_set_gpgdir(), alpm_db_get_siglevel(),
alpm_siglist_cleanup(), alpm_db_check_pgp_signature(), alpm_pkg_check_pgp_signature(),
alpm_pkg_get_origin(), alpm_pkg_get_sha256sum(), alpm_pkg_get_base64_sig()
- alpm_option_get_default_siglevel()
- alpm_option_set_default_siglevel()
- alpm_option_get_gpgdir()
- alpm_option_set_gpgdir()
- alpm_db_get_siglevel()
- alpm_siglist_cleanup()
- alpm_db_check_pgp_signature()
- alpm_pkg_check_pgp_signature()
- alpm_pkg_get_origin()
- alpm_pkg_get_sha256sum()
- alpm_pkg_get_base64_sig()
- list functions:
alpm_list_to_array(), alpm_list_previous()
- alpm_list_to_array()
- alpm_list_previous()
- structs:
alpm_backup_t, alpm_file_t, alpm_filelist_t
- alpm_backup_t
- alpm_file_t
- alpm_filelist_t
- enums:
alpm_siglevel_t, alpm_sigstatus_t, alpm_sigvalidity_t, alpm_pkgfrom_t
- alpm_siglevel_t
- alpm_sigstatus_t
- alpm_sigvalidity_t
- alpm_pkgfrom_t
- error codes:
ALPM_ERR_DB_INVALID, ALPM_ERR_DB_INVALID_SIG, ALPM_ERR_GPGME,
ALPM_ERR_PKG_INVALID_CHECKSUM, ALPM_ERR_PKG_INVALID_SIG, ALPM_ERR_SIG_INVALID,
@@ -470,10 +484,10 @@ API CHANGES BETWEEN 4.0 AND 4.1
- alpm_db_unregister_all -> alpm_unregister_all_syncdbs
- alpm_db_readgroup -> alpm_db_get_group
- alpm_db_set_pkgreason -> alpm_pkg_set_reason (handle parameter removed)
- alpm_time_t typedef used for all times
- alpm_time_t typedef used for all times:
- members of alpm_pgpkey_t
- return types of alpm_pkg_get_builddate and alpm_pkg_get_installdate
- delta options now use required ratio rather than on/off
- delta options now use required ratio rather than on/off:
- alpm_option_get_usedelta -> alpm_option_get_deltaratio
- alpm_option_set_usedelta -> alpm_option_set_deltaratio
@@ -490,21 +504,21 @@ API CHANGES BETWEEN 4.0 AND 4.1
- alpm_db_usage_t
- alpm_db_set_usage()
- alpm_db_get_usage()
- wrapper functions for reading mtree files
- wrapper functions for reading mtree files:
- alpm_pkg_mtree_open()
- alpm_pkg_mtree_next()
- alpm_pkg_mtree_close()
- utility functions
- utility functions:
- alpm_pkg_find()
- alpm_pkg_compute_optionalfor()
- alpm_filelist_contains()
- types
- types:
- alpm_time_t
- alpm_errno_t
- flags
ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING,
ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START,
ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START
- flags:
ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING,
ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START,
ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START
API CHANGES BETWEEN 4.1 AND 4.2
@@ -513,49 +527,49 @@ API CHANGES BETWEEN 4.1 AND 4.2
[CHANGED]
- alpm_filelist_t - removed member resolved_path
- alpm_filelist_contains - now returns alpm_file_t
- event callback
- alpm_event_t renamed to alpm_event_type_t
- alpm_event_t union added
- alpm_event_cb now takes only an alpm_event_t parameter
- alpm_event_any_t, alpm_package_operation_t, alpm_event_package_operation_t,
alpm_event_optdep_removal_t, alpm_event_delta_patch_t, alpm_event_scriptlet_info_t,
alpm_event_database_missing_t, alpm_event_pkgdownload_t, alpm_event_pacnew_created_t,
alpm_event_pacsave_created_t, alpm_event_pacorig_created_t added
- ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START
- ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE
- question callback
- alpm_question_t renamed to alpm_question_type_t
- alpm_question_t union added
- alpm_cb_question now takes only an alpm_question_t parameter
- alpm_question_any_t, alpm_question_install_ignorepkg_t, alpm_question_replace_t
alpm_question_conflict_t, alpm_question_corrupted_t, alpm_question_remove_pkgs_t,
alpm_question_select_provider_t, alpm_question_import_key_t added
- event callback:
- alpm_event_t renamed to alpm_event_type_t
- alpm_event_t union added
- alpm_event_cb now takes only an alpm_event_t parameter
- alpm_event_any_t, alpm_package_operation_t, alpm_event_package_operation_t,
alpm_event_optdep_removal_t, alpm_event_delta_patch_t, alpm_event_scriptlet_info_t,
alpm_event_database_missing_t, alpm_event_pkgdownload_t, alpm_event_pacnew_created_t,
alpm_event_pacsave_created_t, alpm_event_pacorig_created_t added
- ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START
- ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE
- question callback:
- alpm_question_t renamed to alpm_question_type_t
- alpm_question_t union added
- alpm_cb_question now takes only an alpm_question_t parameter
- alpm_question_any_t, alpm_question_install_ignorepkg_t, alpm_question_replace_t
alpm_question_conflict_t, alpm_question_corrupted_t, alpm_question_remove_pkgs_t,
alpm_question_select_provider_t, alpm_question_import_key_t added
[ADDED]
- memory management
- memory management:
- alpm_fileconflict_free()
- alpm_depmissing_free()
- alpm_conflict_free()
- alpm_dep_free()
- database usage
- database usage:
- alpm_db_usage_t
- alpm_db_set_usage()
- alpm_db_get_usage()
- assume installed
- assume installed:
- alpm_option_get_assumeinstalled()
- alpm_option_add_assumeinstalled()
- alpm_option_set_assumeinstalled()
- alpm_option_remove_assumeinstalled()
- using noupgrade/noextract
- using noupgrade/noextract:
- alpm_option_match_noupgrade()
- alpm_option_match_noextract()
- utility functions
- utility functions:
- alpm_dep_from_string()
- alpm_pkg_should_ignore()
- alpm_decode_signature()
- alpm_extract_keyid()
- flags
- ALPM_EVENT_RETRIEVE_DONE, ALPM_EVENT_RETRIEVE_FAILED, ALPM_EVENT_PKGDOWNLOAD_START,
- flags:
ALPM_EVENT_RETRIEVE_DONE, ALPM_EVENT_RETRIEVE_FAILED, ALPM_EVENT_PKGDOWNLOAD_START,
ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED, ALPM_EVENT_OPTDEP_REMOVAL,
ALPM_EVENT_PACNEW_CREATED, ALPM_EVENT_PACSVAE_CREATED, ALPM_EVENT_PACORIG_CREATED
@@ -565,13 +579,13 @@ API CHANGES BETWEEN 4.2 AND 5.0
[REMOVED]
- alpm_siglevel_t - removed members ALPM_SIG_PACKAGE_SET, ALPM_SIG_PACKAGE_TRUST_SET
- removed .pacorig generation
- removed .pacorig generation:
- ALPM_EVENT_PACORIG_CREATED
- alpm_event_pacorig_created_t
- alpm_event_t.pacorig_created
[ADDED]
- hook support
- hook support:
- alpm_option_get_hookdirs()
- alpm_option_set_hookdirs()
- alpm_option_add_hookdir()
@@ -581,14 +595,14 @@ API CHANGES BETWEEN 4.2 AND 5.0
- ALPM_EVENT_HOOK_START, ALPM_EVENT_HOOK_DONE
- ALPM_EVENT_HOOK_RUN_START, ALPM_EVENT_HOOK_RUN_DONE
- ALPM_ERR_TRANS_HOOK_FAILED
- different database extension support
- different database extension support:
- alpm_option_get_dbext()
- alpm_option_set_dbext()
- pkgbase accessor
- pkgbase accessor:
- alpm_pkg_get_base()
- transaction events
- transaction events:
- ALPM_EVENT_TRANSACTION_START, ALPM_EVENT_TRANSACTION_DONE
- database unlocking
- database unlocking:
- alpm_unlock()
@@ -598,7 +612,7 @@ API CHANGES BETWEEN 5.0 AND 5.1
[CHANGED]
- alpm_errno_t - added member ALPM_ERR_OK
- alpm_siglevel_t - value of ALPM_SIG_USE_DEFAULT changed
- functions using bitfields return/pass an int instead of an enum
- functions using bitfields return/pass an int instead of an enum:
- alpm_option_get_default_siglevel()
- alpm_option_set_default_siglevel()
- alpm_option_get_remote_file_siglevel()
@@ -615,19 +629,19 @@ API CHANGES BETWEEN 5.0 AND 5.1
- alpm_option_set_local_file_siglevel()
[ADDED]
- overwrite support
- overwrite support:
- alpm_option_get_overwrite_files()
- alpm_option_set_overwrite_files()
- alpm_option_add_overwrite_file()
- alpm_option_remove_overwrite_file()
- download timeout control
- download timeout control:
- alpm_option_set_disable_dl_timeout()
- access make/checkdepends info
- access make/checkdepends info:
- alpm_pkg_get_checkdepends()
- alpm_pkg_get_makedepends()
- check pacman capabilities
- check pacman capabilities:
- alpm_capabilities()
- duplicate and add to list
- duplicate and add to list:
- alpm_list_append_strdup()
@@ -635,7 +649,7 @@ API CHANGES BETWEEN 5.1 AND 5.2
===============================
[REMOVED]
- package delta support
- package delta support:
- alpm_delta_t
- alpm_event_delta_patch_t
- alpm_event_t union - removed alpm_event_delta_patch_t
@@ -662,10 +676,10 @@ API CHANGES BETWEEN 5.2 AND 6.0
[REMOVED]
- ALPM_EVENT_PKGDOWNLOAD_START, ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED
- ALPM_ERR_PKG_REPO_NOT_FOUND
- old TotalDownload implementation
- alpm_cb_totaldl
- alpm_option_get_totaldlcb()
- alpm_option_set_totaldlcb()
- old TotalDownload implementation:
- alpm_cb_totaldl
- alpm_option_get_totaldlcb()
- alpm_option_set_totaldlcb()
[CHANGED]
- alpm_db_update() now accepts a list of databases rather than a single database.
@@ -673,29 +687,29 @@ API CHANGES BETWEEN 5.2 AND 6.0
- alpm_db_search() now has an additional parameter and returns success status
- ALPM_EVENT_RETRIEVE_* -> ALPM_EVENT_DB_RETRIEVE_* and ALPM_EVENT_PKG_RETRIEVE_*
- alpm_cb_download pass event and data
- multi architecture support
- alpm_option_get_arch() -> alpm_option_get_architectures()
- alpm_option_set_arch() -> alpm_option_set_architectures()
- multi architecture support:
- alpm_option_get_arch() -> alpm_option_get_architectures()
- alpm_option_set_arch() -> alpm_option_set_architectures()
- alpm_db_get_servers() copies parameter data
[ADDED]
- parallel download support
- alpm_option_set_parallel_downloads()
- alpm_option_get_parallel_downloads()
- file download events
- alpm_download_event_type_t
- alpm_download_event_init_t
- alpm_download_event_progress_t
- alpm_download_event_completed_t
- download misc
- ALPM_DOWNLOAD_RETRY
- alpm_download_event_retry_t
- alpm_event_pkg_retrieve_t
- multiarchitecture support
- alpm_option_add_architecture()
- alpm_option_remove_architecture()
- misc
- alpm_pkg_get_sig()
- parallel download support:
- alpm_option_set_parallel_downloads()
- alpm_option_get_parallel_downloads()
- file download events:
- alpm_download_event_type_t
- alpm_download_event_init_t
- alpm_download_event_progress_t
- alpm_download_event_completed_t
- download misc:
- ALPM_DOWNLOAD_RETRY
- alpm_download_event_retry_t
- alpm_event_pkg_retrieve_t
- multiarchitecture support:
- alpm_option_add_architecture()
- alpm_option_remove_architecture()
- misc:
- alpm_pkg_get_sig()
- callbacks add front-end provided context
@@ -713,27 +727,27 @@ API CHANGES BETWEEN 6.0 AND 6.1
- alpm_transflag_t - added ALPM_TRANS_FLAG_NOHOOKS
[ADDED]
- extensible package data type
- alpm_pkg_xdata_t
- alpm_pkg_get_xdata()
- accessor functions
- alpm_db_get_handle()
- alpm_pkg_get_handle()
- cache server support
- alpm_db_get_cache_servers()
- alpm_db_set_cache_servers()
- alpm_db_add_cache_server()
- extensible package data type:
- alpm_pkg_xdata_t
- alpm_pkg_get_xdata()
- accessor functions:
- alpm_db_get_handle()
- alpm_pkg_get_handle()
- cache server support:
- alpm_db_get_cache_servers()
- alpm_db_set_cache_servers()
- alpm_db_add_cache_server()
API CHANGES BETWEEN 6.1 AND 7.0
===============================
[ADDED]
- sandbox functions
- alpm_option_get_sandboxuser()
- alpm_option_set_sandboxuser()
- alpm_option_set_disable_sandbox()
- alpm_sandbox_setup_child()
- sandbox functions:
- alpm_option_get_sandboxuser()
- alpm_option_set_sandboxuser()
- alpm_option_set_disable_sandbox()
- alpm_sandbox_setup_child()
API CHANGES BETWEEN 7.0 AND 7.1

View File

@@ -313,6 +313,15 @@ underscore and the architecture name e.g., 'replaces_x86_64=()'.
Enable building packages using link time optimization. Adds '-flto'
to both CFLAGS and CXXFLAGS.
*xdata (array)*::
This array allows you to add additional metadata to the package.
This data is neither used by pacman nor by makepkg;
It has purely informational purpose, or may be interpreted by third-party tools.
+
All entries in that array must have the form 'key=value', where
'key' is an arbitrary non-empty string and 'value' must not contain an equal sign.
Furthermore, the key ``pkgtype'' is reserved for the makepkg program.
Packaging Functions
-------------------

View File

@@ -292,6 +292,9 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
exclamation mark. Subsequent matches will override previous ones. A leading
literal exclamation mark or backslash needs to be escaped.
*\--preremove <package>::
Uninstall 'package' before performing the requested installation. Multiple
packages can be specified by separating them with commas.
Query Options (apply to '-Q')[[QO]]
-----------------------------------

View File

@@ -268,7 +268,6 @@ cleanup:
alpm_list_free_inner(payloads, (alpm_list_fn_free)_alpm_dload_payload_reset);
FREELIST(payloads);
}
_alpm_remove_temporary_download_dir(temporary_syncpath);
FREE(temporary_syncpath);
FREE(syncpath);
umask(oldmask);

View File

@@ -916,7 +916,8 @@ static int curl_download_internal(alpm_handle_t *handle,
*/
static int curl_download_internal_sandboxed(alpm_handle_t *handle,
alpm_list_t *payloads /* struct dload_payload */,
const char *localpath)
const char *localpath,
int *childsig)
{
int pid, err = 0, ret = -1, callbacks_fd[2];
sigset_t oldblock;
@@ -1021,8 +1022,12 @@ static int curl_download_internal_sandboxed(alpm_handle_t *handle,
int wret;
while((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR);
if(wret > 0) {
if(WIFSIGNALED(ret)) {
*childsig = WTERMSIG(ret);
}
if(!WIFEXITED(ret)) {
/* the child did not terminate normally */
handle->pm_errno = ALPM_ERR_RETRIEVE;
ret = -1;
}
else {
@@ -1101,17 +1106,24 @@ static int finalize_download_locations(alpm_list_t *payloads, const char *localp
ASSERT(payloads != NULL, return -1);
ASSERT(localpath != NULL, return -1);
alpm_list_t *p;
struct stat st;
int returnvalue = 0;
for(p = payloads; p; p = p->next) {
struct dload_payload *payload = p->data;
const char *filename;
const char *filename = NULL;
if(payload->destfile_name) {
if(payload->destfile_name && stat(payload->destfile_name, &st) == 0) {
filename = payload->destfile_name;
} else {
} else if(stat(payload->tempfile_name, &st) == 0) {
filename = payload->tempfile_name;
}
/* if neither file exists then the download failed and logged an error for us */
if(!filename) {
returnvalue = -1;
continue;
}
int ret = move_file(filename, localpath);
if(ret == -1) {
@@ -1188,12 +1200,14 @@ int _alpm_download(alpm_handle_t *handle,
const char *temporary_localpath)
{
int ret;
int finalize_ret;
int childsig = 0;
prepare_resumable_downloads(payloads, localpath, handle->sandboxuser);
if(handle->fetchcb == NULL) {
#ifdef HAVE_LIBCURL
if(handle->sandboxuser) {
ret = curl_download_internal_sandboxed(handle, payloads, temporary_localpath);
ret = curl_download_internal_sandboxed(handle, payloads, temporary_localpath, &childsig);
} else {
ret = curl_download_internal(handle, payloads);
}
@@ -1268,9 +1282,17 @@ download_signature:
ret = updated ? 0 : 1;
}
if (finalize_download_locations(payloads, localpath) != 0 && ret == 0) {
finalize_ret = finalize_download_locations(payloads, localpath);
_alpm_remove_temporary_download_dir(temporary_localpath);
/* propagate after finalizing so .part files get copied over */
if(childsig != 0) {
kill(getpid(), childsig);
}
if(finalize_ret != 0 && ret == 0) {
RET_ERR(handle, ALPM_ERR_RETRIEVE, -1);
}
return ret;
}
@@ -1395,13 +1417,11 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
FREELIST(payloads);
}
_alpm_remove_temporary_download_dir(temporary_cachedir);
FREE(temporary_cachedir);
return 0;
err:
alpm_list_free_inner(payloads, (alpm_list_fn_free)_alpm_dload_payload_reset);
_alpm_remove_temporary_download_dir(temporary_cachedir);
FREE(temporary_cachedir);
FREELIST(payloads);
FREELIST(*fetched);

View File

@@ -882,7 +882,6 @@ finish:
pkg->infolevel &= ~INFRQ_DSIZE;
pkg->download_size = 0;
}
_alpm_remove_temporary_download_dir(temporary_cachedir);
FREE(temporary_cachedir);
return ret;

View File

@@ -25,6 +25,7 @@ sources = [
'source.sh.in',
'util.sh.in',
'variable.sh.in',
'xdata.sh.in',
]
foreach src : sources

View File

@@ -0,0 +1,58 @@
#!/bin/bash
#
# xdata.sh - Check the 'xdata' array conforms to requirements.
#
# Copyright (c) 2014-2025 Pacman Development Team <pacman-dev@lists.archlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_XDATA_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_XDATA_SH=1
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_xdata')
lint_xdata() {
local xdata_list entry key value ret=0
get_pkgbuild_all_split_attributes xdata xdata_list
for entry in "${xdata_list[@]}"; do
key="${entry%%=*}"
value="${entry##*=}"
if [[ "${entry}" == "${key}=${value}" ]]; then
# Entries must contain exactly one equal sign.
error "$(gettext "%s array: Entries must contain exactly one equal sign, e.g. key=value.")" "xdata"
ret=1
elif [[ "${key}" == '' ]]; then
# Do not allow keys without values.
error "$(gettext "%s array: The key part of an entry must not be empty.")" "xdata"
ret=1
elif [[ "${key}" == "pkgtype" ]]; then
# The key "pkgtype" is reserved for makepkg.
error "$(gettext "%s array: The key 'pkgtype' is reserved for makepkg.")" "xdata"
ret=1
fi
done
return $ret
}

View File

@@ -30,7 +30,7 @@ known_hash_algos=({ck,md5,sha{1,224,256,384,512},b2})
pkgbuild_schema_arrays=(arch backup checkdepends conflicts depends groups
license makedepends noextract optdepends options
provides replaces source validpgpkeys
provides replaces source validpgpkeys xdata
"${known_hash_algos[@]/%/sums}")
pkgbuild_schema_strings=(changelog epoch install pkgbase pkgdesc pkgrel pkgver

View File

@@ -493,7 +493,7 @@ write_pkginfo() {
write_kv_pair "pkgname" "$pkgname"
write_kv_pair "pkgbase" "$pkgbase"
write_kv_pair "xdata" "pkgtype=$pkgtype"
write_kv_pair "xdata" "pkgtype=$pkgtype" "${xdata[@]}"
local fullver=$(get_full_version)
write_kv_pair "pkgver" "$fullver"

View File

@@ -150,6 +150,7 @@ int config_free(config_t *oldconfig)
FREELIST(oldconfig->noupgrade);
FREELIST(oldconfig->noextract);
FREELIST(oldconfig->overwrite_files);
FREELIST(oldconfig->preremove);
free(oldconfig->configfile);
free(oldconfig->sysroot);
free(oldconfig->rootdir);

View File

@@ -134,6 +134,8 @@ typedef struct __config_t {
/* our connection to libalpm */
alpm_handle_t *handle;
alpm_list_t *preremove;
alpm_list_t *explicit_adds;
alpm_list_t *explicit_removes;
@@ -214,7 +216,8 @@ enum {
OP_REFRESH,
OP_ASSUMEINSTALLED,
OP_DISABLEDLTIMEOUT,
OP_DISABLESANDBOX
OP_DISABLESANDBOX,
OP_PREREMOVE,
};
/* clean method */

View File

@@ -196,6 +196,8 @@ static void usage(int op, const char * const myname)
addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n"));
addlist(_(" --ignoregroup <grp>\n"
" ignore a group upgrade (can be used more than once)\n"));
addlist(_(" --preremove <pkg>\n"));
addlist(_(" uninstall <pkg> before performing installation\n"));
__attribute__((fallthrough));
case PM_OP_REMOVE:
addlist(_(" -d, --nodeps skip dependency version checks (-dd to skip all checks)\n"));
@@ -770,6 +772,9 @@ static int parsearg_upgrade(int opt)
case OP_IGNOREGROUP:
parsearg_util_addlist(&(config->ignoregrp));
break;
case OP_PREREMOVE:
parsearg_util_addlist(&(config->preremove));
break;
case OP_DOWNLOADONLY:
case 'w':
config->op_s_downloadonly = 1;
@@ -982,6 +987,7 @@ static int parseargs(int argc, char *argv[])
{"color", required_argument, 0, OP_COLOR},
{"disable-download-timeout", no_argument, 0, OP_DISABLEDLTIMEOUT},
{"disable-sandbox", no_argument, 0, OP_DISABLESANDBOX},
{"preremove", required_argument, 0, OP_PREREMOVE},
{0, 0, 0, 0}
};

View File

@@ -717,6 +717,21 @@ static int sync_trans(alpm_list_t *targets)
}
}
for(i = config->preremove; i; i = i->next) {
alpm_pkg_t *pkg;
const char *pname = i->data;
alpm_db_t *db_local = alpm_get_localdb(config->handle);
if((pkg = alpm_db_get_pkg(db_local, pname)) != NULL) {
if(alpm_remove_pkg(config->handle, pkg) == -1) {
alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", pname, alpm_strerror(err));
retval = 1;
}
config->explicit_removes = alpm_list_add(config->explicit_removes, pkg);
}
}
if(retval) {
trans_release();
return retval;