Compare commits

...
Sign in to create a new pull request.

16 commits

Author SHA1 Message Date
Allan McRae
fe6e678e59 libmakepkg: remove pkglist linting
The ability to build only selected packages from a split package was
removed from makepkg, so this lint is no longer needed.

Signed-off-by: Allan McRae <allan@archlinux.org>
2025-08-02 14:26:44 +10:00
morganamilo
48a784dde8 libalpm: fix -U when pkg exists but not sig 2025-06-21 23:39:57 +10:00
morganamilo
67e3a7be36
libalpm: fix regression in downloader
Fixes failure to finalize download path if the package file already
exists but the .sig file does not.

This patch also moves .sig.part files which should be done for
completeness although it's probably rare/inconsequential for them to
exist.

Hopefully this is now the right approach now. The logic is as follows:

  Check if dest_name or temp_name exists and try to move whichever
  does.

  If neither exist assume we're just downloading sig files and don't
  error.

  Figure out the .sig base filename.

  Try to move the .sig file if one was needed and if that fails try
  move the .sig.part file.

The patch leaves the logging as is. Maybe we should check if moves fail
for reasons other than non existence and log it properly. Though this is
probably rare and pacman will error out later anyway.

Fixes #256
2025-05-30 14:48:14 +01: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
Rudy
af54cd4ee1 libmakepkg/tidy: give scripts a priority order
This ensures (e.g.) that the "emptydirs" script runs last after
unneeded files have been deleted.

Fixes #184.

Signed-off-by: Allan McRae <allan@archlinux.org>
2025-05-17 13:20:16 +10:00
morganamilo
e392f01a94 libalpm: move sig files when download is unnamed 2025-05-17 12:03:42 +10:00
morganamilo
f722b86990 libalpm: return final final temp path in pkgurl
When downloading unnamed files via alpm_fetch_pkgurl the returned path
would point to the temp pkgcache instead of the final download location.
2025-05-17 12:03:42 +10:00
Aidan Epstein
4ddc642398 Add remove option for repo-remove to remove old package files.
Also update documentation.
2025-05-17 10:43:58 +10:00
Allan McRae
53b1db84ef Fix memory leak in download payload
The file stream associated with downloads without a filename is not
being freed when downloading using the sandbox user.

Signed-off-by: Allan McRae <allan@archlinux.org>
2025-05-17 10:40:09 +10:00
Allan McRae
571c13236f pacman.8: document interaction between --cachedir and DownloadUser
Note that the user provided in the DownloadUser configuration option (if
set) needs to be able to access the directory specified with the --cachedir
argument.

Fixes #216.

Signed-off-by: Allan McRae <allan@archlinux.org>
2025-05-17 10:37:30 +10:00
Felix Yan
64299ccfbb makepkg.sh: skip checking buildtime deps when runtime check already failed
This could help locate the real failure (instead of scrolling through the whole possibly-successful buildtime dep installation section) and also saves time on the operation.
2025-05-09 08:55:42 +10:00
21 changed files with 290 additions and 196 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 indicates some limitations (on purpose, or sometimes due to its poor design) of
the library at the present time. 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 should be distributed and installed on systems with the library. Only
structures, data and functions declared within this file are made available to 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 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_checkdbconflicts()
- alpm_sync_newversion() - alpm_sync_newversion()
- alpm_deptest() - alpm_deptest()
- error codes : - error codes:
PM_ERR_DLT_INVALID, PM_ERR_LIBARCHIVE, PM_ERR_LIBDOWNLOAD and PM_ERR_DLT_INVALID, PM_ERR_LIBARCHIVE, PM_ERR_LIBDOWNLOAD and
PM_ERR_EXTERNAL_DOWNLOAD PM_ERR_EXTERNAL_DOWNLOAD
- flags: - flags:
@ -362,11 +362,11 @@ API CHANGES BETWEEN 3.4 AND 3.5
- alpm_find_grp_pkgs() - alpm_find_grp_pkgs()
- alpm_trans_get_flags() - alpm_trans_get_flags()
- error codes: - error codes:
PM_ERR_DISK_SPACE, PM_ERR_WRITE PM_ERR_DISK_SPACE, PM_ERR_WRITE
- flags - flags:
PM_TRANS_FLAG_NODEPVERSION, PM_TRANS_EVT_DISKSPACE_START, PM_TRANS_FLAG_NODEPVERSION, PM_TRANS_EVT_DISKSPACE_START,
PM_TRANS_EVT_DISKSPACE_DONE, PM_TRANS_CONV_SELECT_PROVIDER, PM_TRANS_EVT_DISKSPACE_DONE, PM_TRANS_CONV_SELECT_PROVIDER,
PM_TRANS_PROGRESS_DISKSPACE_START, PM_TRANS_PROGRESS_INTEGRITY_START PM_TRANS_PROGRESS_DISKSPACE_START, PM_TRANS_PROGRESS_INTEGRITY_START
API CHANGES BETWEEN 3.5 AND 4.0 API CHANGES BETWEEN 3.5 AND 4.0
@ -419,7 +419,7 @@ API CHANGES BETWEEN 3.5 AND 4.0
- alpm_release - alpm_release
- alpm_remove_pkg - alpm_remove_pkg
- alpm_sync_sysupgrade - alpm_sync_sysupgrade
- several structs are no longer opaque - several structs are no longer opaque:
- alpm_conflict_t - alpm_conflict_t
- alpm_delta_t - alpm_delta_t
- alpm_depend_t - alpm_depend_t
@ -431,19 +431,33 @@ API CHANGES BETWEEN 3.5 AND 4.0
[ADDED] [ADDED]
- option functions: - option functions:
alpm_{get,set}_eventcb(), alpm_option_{get,set}_convcb(), - alpm_{get,set}_eventcb()
alpm_option_{get,set}_progresscb() - alpm_option_{get,set}_convcb()
- alpm_option_{get,set}_progresscb()
- package signing functions: - package signing functions:
alpm_option_get_default_siglevel(), alpm_option_set_default_siglevel(), - alpm_option_get_default_siglevel()
alpm_option_get_gpgdir(), alpm_option_set_gpgdir(), alpm_db_get_siglevel(), - alpm_option_set_default_siglevel()
alpm_siglist_cleanup(), alpm_db_check_pgp_signature(), alpm_pkg_check_pgp_signature(), - alpm_option_get_gpgdir()
alpm_pkg_get_origin(), alpm_pkg_get_sha256sum(), alpm_pkg_get_base64_sig() - 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: - list functions:
alpm_list_to_array(), alpm_list_previous() - alpm_list_to_array()
- alpm_list_previous()
- structs: - structs:
alpm_backup_t, alpm_file_t, alpm_filelist_t - alpm_backup_t
- alpm_file_t
- alpm_filelist_t
- enums: - 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: - error codes:
ALPM_ERR_DB_INVALID, ALPM_ERR_DB_INVALID_SIG, ALPM_ERR_GPGME, 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, 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_unregister_all -> alpm_unregister_all_syncdbs
- alpm_db_readgroup -> alpm_db_get_group - alpm_db_readgroup -> alpm_db_get_group
- alpm_db_set_pkgreason -> alpm_pkg_set_reason (handle parameter removed) - 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 - members of alpm_pgpkey_t
- return types of alpm_pkg_get_builddate and alpm_pkg_get_installdate - 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_get_usedelta -> alpm_option_get_deltaratio
- alpm_option_set_usedelta -> alpm_option_set_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_usage_t
- alpm_db_set_usage() - alpm_db_set_usage()
- alpm_db_get_usage() - alpm_db_get_usage()
- wrapper functions for reading mtree files - wrapper functions for reading mtree files:
- alpm_pkg_mtree_open() - alpm_pkg_mtree_open()
- alpm_pkg_mtree_next() - alpm_pkg_mtree_next()
- alpm_pkg_mtree_close() - alpm_pkg_mtree_close()
- utility functions - utility functions:
- alpm_pkg_find() - alpm_pkg_find()
- alpm_pkg_compute_optionalfor() - alpm_pkg_compute_optionalfor()
- alpm_filelist_contains() - alpm_filelist_contains()
- types - types:
- alpm_time_t - alpm_time_t
- alpm_errno_t - alpm_errno_t
- flags - flags:
ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING, ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING,
ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START, ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START,
ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START
API CHANGES BETWEEN 4.1 AND 4.2 API CHANGES BETWEEN 4.1 AND 4.2
@ -513,49 +527,49 @@ API CHANGES BETWEEN 4.1 AND 4.2
[CHANGED] [CHANGED]
- alpm_filelist_t - removed member resolved_path - alpm_filelist_t - removed member resolved_path
- alpm_filelist_contains - now returns alpm_file_t - alpm_filelist_contains - now returns alpm_file_t
- event callback - event callback:
- alpm_event_t renamed to alpm_event_type_t - alpm_event_t renamed to alpm_event_type_t
- alpm_event_t union added - alpm_event_t union added
- alpm_event_cb now takes only an alpm_event_t parameter - 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_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_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_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_pacsave_created_t, alpm_event_pacorig_created_t added
- ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START - ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START
- ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE - ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE
- question callback - question callback:
- alpm_question_t renamed to alpm_question_type_t - alpm_question_t renamed to alpm_question_type_t
- alpm_question_t union added - alpm_question_t union added
- alpm_cb_question now takes only an alpm_question_t parameter - 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_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_conflict_t, alpm_question_corrupted_t, alpm_question_remove_pkgs_t,
alpm_question_select_provider_t, alpm_question_import_key_t added alpm_question_select_provider_t, alpm_question_import_key_t added
[ADDED] [ADDED]
- memory management - memory management:
- alpm_fileconflict_free() - alpm_fileconflict_free()
- alpm_depmissing_free() - alpm_depmissing_free()
- alpm_conflict_free() - alpm_conflict_free()
- alpm_dep_free() - alpm_dep_free()
- database usage - database usage:
- alpm_db_usage_t - alpm_db_usage_t
- alpm_db_set_usage() - alpm_db_set_usage()
- alpm_db_get_usage() - alpm_db_get_usage()
- assume installed - assume installed:
- alpm_option_get_assumeinstalled() - alpm_option_get_assumeinstalled()
- alpm_option_add_assumeinstalled() - alpm_option_add_assumeinstalled()
- alpm_option_set_assumeinstalled() - alpm_option_set_assumeinstalled()
- alpm_option_remove_assumeinstalled() - alpm_option_remove_assumeinstalled()
- using noupgrade/noextract - using noupgrade/noextract:
- alpm_option_match_noupgrade() - alpm_option_match_noupgrade()
- alpm_option_match_noextract() - alpm_option_match_noextract()
- utility functions - utility functions:
- alpm_dep_from_string() - alpm_dep_from_string()
- alpm_pkg_should_ignore() - alpm_pkg_should_ignore()
- alpm_decode_signature() - alpm_decode_signature()
- alpm_extract_keyid() - alpm_extract_keyid()
- flags - flags:
- ALPM_EVENT_RETRIEVE_DONE, ALPM_EVENT_RETRIEVE_FAILED, ALPM_EVENT_PKGDOWNLOAD_START, 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_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED, ALPM_EVENT_OPTDEP_REMOVAL,
ALPM_EVENT_PACNEW_CREATED, ALPM_EVENT_PACSVAE_CREATED, ALPM_EVENT_PACORIG_CREATED 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] [REMOVED]
- alpm_siglevel_t - removed members ALPM_SIG_PACKAGE_SET, ALPM_SIG_PACKAGE_TRUST_SET - 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
- alpm_event_pacorig_created_t - alpm_event_pacorig_created_t
- alpm_event_t.pacorig_created - alpm_event_t.pacorig_created
[ADDED] [ADDED]
- hook support - hook support:
- alpm_option_get_hookdirs() - alpm_option_get_hookdirs()
- alpm_option_set_hookdirs() - alpm_option_set_hookdirs()
- alpm_option_add_hookdir() - 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_START, ALPM_EVENT_HOOK_DONE
- ALPM_EVENT_HOOK_RUN_START, ALPM_EVENT_HOOK_RUN_DONE - ALPM_EVENT_HOOK_RUN_START, ALPM_EVENT_HOOK_RUN_DONE
- ALPM_ERR_TRANS_HOOK_FAILED - ALPM_ERR_TRANS_HOOK_FAILED
- different database extension support - different database extension support:
- alpm_option_get_dbext() - alpm_option_get_dbext()
- alpm_option_set_dbext() - alpm_option_set_dbext()
- pkgbase accessor - pkgbase accessor:
- alpm_pkg_get_base() - alpm_pkg_get_base()
- transaction events - transaction events:
- ALPM_EVENT_TRANSACTION_START, ALPM_EVENT_TRANSACTION_DONE - ALPM_EVENT_TRANSACTION_START, ALPM_EVENT_TRANSACTION_DONE
- database unlocking - database unlocking:
- alpm_unlock() - alpm_unlock()
@ -598,7 +612,7 @@ API CHANGES BETWEEN 5.0 AND 5.1
[CHANGED] [CHANGED]
- alpm_errno_t - added member ALPM_ERR_OK - alpm_errno_t - added member ALPM_ERR_OK
- alpm_siglevel_t - value of ALPM_SIG_USE_DEFAULT changed - 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_get_default_siglevel()
- alpm_option_set_default_siglevel() - alpm_option_set_default_siglevel()
- alpm_option_get_remote_file_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() - alpm_option_set_local_file_siglevel()
[ADDED] [ADDED]
- overwrite support - overwrite support:
- alpm_option_get_overwrite_files() - alpm_option_get_overwrite_files()
- alpm_option_set_overwrite_files() - alpm_option_set_overwrite_files()
- alpm_option_add_overwrite_file() - alpm_option_add_overwrite_file()
- alpm_option_remove_overwrite_file() - alpm_option_remove_overwrite_file()
- download timeout control - download timeout control:
- alpm_option_set_disable_dl_timeout() - alpm_option_set_disable_dl_timeout()
- access make/checkdepends info - access make/checkdepends info:
- alpm_pkg_get_checkdepends() - alpm_pkg_get_checkdepends()
- alpm_pkg_get_makedepends() - alpm_pkg_get_makedepends()
- check pacman capabilities - check pacman capabilities:
- alpm_capabilities() - alpm_capabilities()
- duplicate and add to list - duplicate and add to list:
- alpm_list_append_strdup() - alpm_list_append_strdup()
@ -635,7 +649,7 @@ API CHANGES BETWEEN 5.1 AND 5.2
=============================== ===============================
[REMOVED] [REMOVED]
- package delta support - package delta support:
- alpm_delta_t - alpm_delta_t
- alpm_event_delta_patch_t - alpm_event_delta_patch_t
- alpm_event_t union - removed 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] [REMOVED]
- ALPM_EVENT_PKGDOWNLOAD_START, ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED - ALPM_EVENT_PKGDOWNLOAD_START, ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED
- ALPM_ERR_PKG_REPO_NOT_FOUND - ALPM_ERR_PKG_REPO_NOT_FOUND
- old TotalDownload implementation - old TotalDownload implementation:
- alpm_cb_totaldl - alpm_cb_totaldl
- alpm_option_get_totaldlcb() - alpm_option_get_totaldlcb()
- alpm_option_set_totaldlcb() - alpm_option_set_totaldlcb()
[CHANGED] [CHANGED]
- alpm_db_update() now accepts a list of databases rather than a single database. - 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_db_search() now has an additional parameter and returns success status
- ALPM_EVENT_RETRIEVE_* -> ALPM_EVENT_DB_RETRIEVE_* and ALPM_EVENT_PKG_RETRIEVE_* - ALPM_EVENT_RETRIEVE_* -> ALPM_EVENT_DB_RETRIEVE_* and ALPM_EVENT_PKG_RETRIEVE_*
- alpm_cb_download pass event and data - alpm_cb_download pass event and data
- multi architecture support - multi architecture support:
- alpm_option_get_arch() -> alpm_option_get_architectures() - alpm_option_get_arch() -> alpm_option_get_architectures()
- alpm_option_set_arch() -> alpm_option_set_architectures() - alpm_option_set_arch() -> alpm_option_set_architectures()
- alpm_db_get_servers() copies parameter data - alpm_db_get_servers() copies parameter data
[ADDED] [ADDED]
- parallel download support - parallel download support:
- alpm_option_set_parallel_downloads() - alpm_option_set_parallel_downloads()
- alpm_option_get_parallel_downloads() - alpm_option_get_parallel_downloads()
- file download events - file download events:
- alpm_download_event_type_t - alpm_download_event_type_t
- alpm_download_event_init_t - alpm_download_event_init_t
- alpm_download_event_progress_t - alpm_download_event_progress_t
- alpm_download_event_completed_t - alpm_download_event_completed_t
- download misc - download misc:
- ALPM_DOWNLOAD_RETRY - ALPM_DOWNLOAD_RETRY
- alpm_download_event_retry_t - alpm_download_event_retry_t
- alpm_event_pkg_retrieve_t - alpm_event_pkg_retrieve_t
- multiarchitecture support - multiarchitecture support:
- alpm_option_add_architecture() - alpm_option_add_architecture()
- alpm_option_remove_architecture() - alpm_option_remove_architecture()
- misc - misc:
- alpm_pkg_get_sig() - alpm_pkg_get_sig()
- callbacks add front-end provided context - 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 - alpm_transflag_t - added ALPM_TRANS_FLAG_NOHOOKS
[ADDED] [ADDED]
- extensible package data type - extensible package data type:
- alpm_pkg_xdata_t - alpm_pkg_xdata_t
- alpm_pkg_get_xdata() - alpm_pkg_get_xdata()
- accessor functions - accessor functions:
- alpm_db_get_handle() - alpm_db_get_handle()
- alpm_pkg_get_handle() - alpm_pkg_get_handle()
- cache server support - cache server support:
- alpm_db_get_cache_servers() - alpm_db_get_cache_servers()
- alpm_db_set_cache_servers() - alpm_db_set_cache_servers()
- alpm_db_add_cache_server() - alpm_db_add_cache_server()
API CHANGES BETWEEN 6.1 AND 7.0 API CHANGES BETWEEN 6.1 AND 7.0
=============================== ===============================
[ADDED] [ADDED]
- sandbox functions - sandbox functions:
- alpm_option_get_sandboxuser() - alpm_option_get_sandboxuser()
- alpm_option_set_sandboxuser() - alpm_option_set_sandboxuser()
- alpm_option_set_disable_sandbox() - alpm_option_set_disable_sandbox()
- alpm_sandbox_setup_child() - alpm_sandbox_setup_child()
API CHANGES BETWEEN 7.0 AND 7.1 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' Enable building packages using link time optimization. Adds '-flto'
to both CFLAGS and CXXFLAGS. 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 Packaging Functions
------------------- -------------------

View file

@ -151,7 +151,8 @@ Options
+{localstatedir}/cache/pacman/pkg+). Multiple cache directories can be +{localstatedir}/cache/pacman/pkg+). Multiple cache directories can be
specified, and they are tried in the order they are passed to pacman. specified, and they are tried in the order they are passed to pacman.
*NOTE*: This is an absolute path, and the root path is not automatically *NOTE*: This is an absolute path, and the root path is not automatically
prepended. prepended. If DownloadUser is set in linkman:pacman.conf[5], then the
specified user must have permission to access the cache directory.
*\--color* <when>:: *\--color* <when>::
Specify when to enable coloring. Valid options are 'always', 'never', or Specify when to enable coloring. Valid options are 'always', 'never', or

View file

@ -60,6 +60,10 @@ Common Options
*\--nocolor*:: *\--nocolor*::
Remove color from 'repo-add' and 'repo-remove' output. Remove color from 'repo-add' and 'repo-remove' output.
*-R, \--remove*::
Remove old package files from the disk when updating or removing their
entry in the database.
*-w, \--wait-for-lock*:: *-w, \--wait-for-lock*::
Wait for the lock file to be acquired. If unset, command will fail with Wait for the lock file to be acquired. If unset, command will fail with
exit code 2 if acquiring the lock fails. If set, it will retry to acquire exit code 2 if acquiring the lock fails. If set, it will retry to acquire
@ -71,10 +75,6 @@ repo-add Options
Only add packages that are not already in the database. Warnings will be Only add packages that are not already in the database. Warnings will be
printed upon detection of existing packages, but they will not be re-added. printed upon detection of existing packages, but they will not be re-added.
*-R, \--remove*::
Remove old package files from the disk when updating their entry in the
database.
*\--include-sigs*:: *\--include-sigs*::
Include package PGP signatures in the repository database (if available) Include package PGP signatures in the repository database (if available)

View file

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

View file

@ -698,9 +698,9 @@ cleanup:
* only applies to FTP transfers. */ * only applies to FTP transfers. */
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, (char *)NULL); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, (char *)NULL);
if(payload->localf != NULL) { if(payload->localf != NULL) {
fclose(payload->localf); fclose(payload->localf);
payload->localf = NULL;
utimes_long(payload->tempfile_name, remote_time); utimes_long(payload->tempfile_name, remote_time);
} }
@ -880,7 +880,6 @@ static int curl_download_internal(alpm_handle_t *handle,
p = NULL; p = NULL;
err = -1; err = -1;
} }
while(true) { while(true) {
int msgs_left = 0; int msgs_left = 0;
CURLMsg *msg = curl_multi_info_read(curlm, &msgs_left); CURLMsg *msg = curl_multi_info_read(curlm, &msgs_left);
@ -904,7 +903,6 @@ static int curl_download_internal(alpm_handle_t *handle,
} }
} }
} }
int ret = err ? -1 : updated ? 0 : 1; int ret = err ? -1 : updated ? 0 : 1;
_alpm_log(handle, ALPM_LOG_DEBUG, "curl_download_internal return code is %d\n", ret); _alpm_log(handle, ALPM_LOG_DEBUG, "curl_download_internal return code is %d\n", ret);
alpm_list_free(payloads); alpm_list_free(payloads);
@ -918,7 +916,8 @@ static int curl_download_internal(alpm_handle_t *handle,
*/ */
static int curl_download_internal_sandboxed(alpm_handle_t *handle, static int curl_download_internal_sandboxed(alpm_handle_t *handle,
alpm_list_t *payloads /* struct dload_payload */, alpm_list_t *payloads /* struct dload_payload */,
const char *localpath) const char *localpath,
int *childsig)
{ {
int pid, err = 0, ret = -1, callbacks_fd[2]; int pid, err = 0, ret = -1, callbacks_fd[2];
sigset_t oldblock; sigset_t oldblock;
@ -1023,8 +1022,12 @@ static int curl_download_internal_sandboxed(alpm_handle_t *handle,
int wret; int wret;
while((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR); while((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR);
if(wret > 0) { if(wret > 0) {
if(WIFSIGNALED(ret)) {
*childsig = WTERMSIG(ret);
}
if(!WIFEXITED(ret)) { if(!WIFEXITED(ret)) {
/* the child did not terminate normally */ /* the child did not terminate normally */
handle->pm_errno = ALPM_ERR_RETRIEVE;
ret = -1; ret = -1;
} }
else { else {
@ -1103,32 +1106,45 @@ static int finalize_download_locations(alpm_list_t *payloads, const char *localp
ASSERT(payloads != NULL, return -1); ASSERT(payloads != NULL, return -1);
ASSERT(localpath != NULL, return -1); ASSERT(localpath != NULL, return -1);
alpm_list_t *p; alpm_list_t *p;
struct stat st;
int returnvalue = 0; int returnvalue = 0;
for(p = payloads; p; p = p->next) { for(p = payloads; p; p = p->next) {
struct dload_payload *payload = p->data; struct dload_payload *payload = p->data;
if(payload->tempfile_name) { const char *filename = NULL;
move_file(payload->tempfile_name, localpath);
if(payload->destfile_name && stat(payload->destfile_name, &st) == 0) {
filename = payload->destfile_name;
} else if(stat(payload->tempfile_name, &st) == 0) {
filename = payload->tempfile_name;
} }
if(payload->destfile_name) {
int ret = move_file(payload->destfile_name, localpath); if(filename) {
int ret = move_file(filename, localpath);
if(ret == -1) { if(ret == -1) {
/* ignore error if the file already existed - only signature file was downloaded */
if(payload->mtime_existing_file == 0) { if(payload->mtime_existing_file == 0) {
_alpm_log(payload->handle, ALPM_LOG_ERROR, _("could not move %s into %s (%s)\n"), _alpm_log(payload->handle, ALPM_LOG_ERROR, _("could not move %s into %s (%s)\n"),
payload->destfile_name, localpath, strerror(errno)); filename, localpath, strerror(errno));
returnvalue = -1; returnvalue = -1;
} }
} }
}
if (payload->download_signature) { if (payload->download_signature) {
const char sig_suffix[] = ".sig"; char *sig_filename;
char *sig_filename = NULL; int ret;
size_t sig_filename_len = strlen(payload->destfile_name) + sizeof(sig_suffix);
MALLOC(sig_filename, sig_filename_len, continue); filename = payload->destfile_name ? payload->destfile_name : payload->tempfile_name;
snprintf(sig_filename, sig_filename_len, "%s%s", payload->destfile_name, sig_suffix); sig_filename = _alpm_get_fullpath("", filename, ".sig");
ASSERT(sig_filename, RET_ERR(payload->handle, ALPM_ERR_MEMORY, -1));
ret = move_file(sig_filename, localpath);
free(sig_filename);
if(ret == -1) {
sig_filename = _alpm_get_fullpath("", filename, ".sig.part");
ASSERT(sig_filename, RET_ERR(payload->handle, ALPM_ERR_MEMORY, -1));
move_file(sig_filename, localpath); move_file(sig_filename, localpath);
FREE(sig_filename); free(sig_filename);
} }
} }
} }
@ -1187,12 +1203,14 @@ int _alpm_download(alpm_handle_t *handle,
const char *temporary_localpath) const char *temporary_localpath)
{ {
int ret; int ret;
int finalize_ret;
int childsig = 0;
prepare_resumable_downloads(payloads, localpath, handle->sandboxuser); prepare_resumable_downloads(payloads, localpath, handle->sandboxuser);
if(handle->fetchcb == NULL) { if(handle->fetchcb == NULL) {
#ifdef HAVE_LIBCURL #ifdef HAVE_LIBCURL
if(handle->sandboxuser) { if(handle->sandboxuser) {
ret = curl_download_internal_sandboxed(handle, payloads, temporary_localpath); ret = curl_download_internal_sandboxed(handle, payloads, temporary_localpath, &childsig);
} else { } else {
ret = curl_download_internal(handle, payloads); ret = curl_download_internal(handle, payloads);
} }
@ -1267,13 +1285,21 @@ download_signature:
ret = updated ? 0 : 1; 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); RET_ERR(handle, ALPM_ERR_RETRIEVE, -1);
} }
return ret; return ret;
} }
static char *filecache_find_url(alpm_handle_t *handle, const char *url) static const char *url_basename(const char *url)
{ {
const char *filebase = strrchr(url, '/'); const char *filebase = strrchr(url, '/');
@ -1286,7 +1312,7 @@ static char *filecache_find_url(alpm_handle_t *handle, const char *url)
return NULL; return NULL;
} }
return _alpm_filecache_find(handle, filebase); return filebase;
} }
int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls, int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
@ -1308,9 +1334,26 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
for(i = urls; i; i = i->next) { for(i = urls; i; i = i->next) {
char *url = i->data; char *url = i->data;
char *filepath = NULL;
const char *urlbase = url_basename(url);
if(urlbase) {
/* attempt to find the file in our pkgcache */
filepath = _alpm_filecache_find(handle, urlbase);
if(filepath && (handle->siglevel & ALPM_SIG_PACKAGE)) {
char *sig_filename = _alpm_get_fullpath("", urlbase, ".sig");
/* if there's no .sig file then forget about the pkg file and go for download */
if(!_alpm_filecache_exists(handle, sig_filename)) {
free(filepath);
filepath = NULL;
}
free(sig_filename);
}
}
/* attempt to find the file in our pkgcache */
char *filepath = filecache_find_url(handle, url);
if(filepath) { if(filepath) {
/* the file is locally cached so add it to the output right away */ /* the file is locally cached so add it to the output right away */
alpm_list_append(fetched, filepath); alpm_list_append(fetched, filepath);
@ -1365,7 +1408,6 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
_alpm_log(handle, ALPM_LOG_WARNING, _("failed to retrieve some files\n")); _alpm_log(handle, ALPM_LOG_WARNING, _("failed to retrieve some files\n"));
event.type = ALPM_EVENT_PKG_RETRIEVE_FAILED; event.type = ALPM_EVENT_PKG_RETRIEVE_FAILED;
EVENT(handle, &event); EVENT(handle, &event);
GOTO_ERR(handle, ALPM_ERR_RETRIEVE, err); GOTO_ERR(handle, ALPM_ERR_RETRIEVE, err);
} else { } else {
event.type = ALPM_EVENT_PKG_RETRIEVE_DONE; event.type = ALPM_EVENT_PKG_RETRIEVE_DONE;
@ -1380,7 +1422,8 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
const char *filename = mbasename(payload->destfile_name); const char *filename = mbasename(payload->destfile_name);
filepath = _alpm_filecache_find(handle, filename); filepath = _alpm_filecache_find(handle, filename);
} else { } else {
STRDUP(filepath, payload->tempfile_name, GOTO_ERR(handle, ALPM_ERR_MEMORY, err)); const char *filename = mbasename(payload->tempfile_name);
filepath = _alpm_filecache_find(handle, filename);
} }
if(filepath) { if(filepath) {
alpm_list_append(fetched, filepath); alpm_list_append(fetched, filepath);
@ -1394,13 +1437,11 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
FREELIST(payloads); FREELIST(payloads);
} }
_alpm_remove_temporary_download_dir(temporary_cachedir);
FREE(temporary_cachedir); FREE(temporary_cachedir);
return 0; return 0;
err: err:
alpm_list_free_inner(payloads, (alpm_list_fn_free)_alpm_dload_payload_reset); alpm_list_free_inner(payloads, (alpm_list_fn_free)_alpm_dload_payload_reset);
_alpm_remove_temporary_download_dir(temporary_cachedir);
FREE(temporary_cachedir); FREE(temporary_cachedir);
FREELIST(payloads); FREELIST(payloads);
FREELIST(*fetched); FREELIST(*fetched);
@ -1412,6 +1453,11 @@ void _alpm_dload_payload_reset(struct dload_payload *payload)
{ {
ASSERT(payload, return); ASSERT(payload, return);
if(payload->localf != NULL) {
fclose(payload->localf);
payload->localf = NULL;
}
FREE(payload->remote_name); FREE(payload->remote_name);
FREE(payload->tempfile_name); FREE(payload->tempfile_name);
FREE(payload->destfile_name); FREE(payload->destfile_name);

View file

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

View file

@ -17,7 +17,6 @@ sources = [
'package_function.sh.in', 'package_function.sh.in',
'package_function_variable.sh.in', 'package_function_variable.sh.in',
'pkgbase.sh.in', 'pkgbase.sh.in',
'pkglist.sh.in',
'pkgname.sh.in', 'pkgname.sh.in',
'pkgrel.sh.in', 'pkgrel.sh.in',
'pkgver.sh.in', 'pkgver.sh.in',
@ -25,6 +24,7 @@ sources = [
'source.sh.in', 'source.sh.in',
'util.sh.in', 'util.sh.in',
'variable.sh.in', 'variable.sh.in',
'xdata.sh.in',
] ]
foreach src : sources foreach src : sources

View file

@ -1,44 +0,0 @@
#!/bin/bash
#
# pkglist.sh - Check the packages selected to build exist.
#
# 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_PKGLIST_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_PKGLIST_SH=1
MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/util.sh"
lint_pkgbuild_functions+=('lint_pkglist')
lint_pkglist() {
local i ret=0
for i in "${PKGLIST[@]}"; do
if ! in_array "$i" "${pkgname[@]}"; then
error "$(gettext "Requested package %s is not provided in %s")" "$i" "$BUILDFILE"
ret=1
fi
done
return $ret
}

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

@ -1,13 +1,13 @@
libmakepkg_module = 'tidy' libmakepkg_module = 'tidy'
sources = [ sources = [
'docs.sh.in', '10-docs.sh.in',
'emptydirs.sh.in', '10-libtool.sh.in',
'libtool.sh.in', '10-staticlibs.sh.in',
'purge.sh.in', '50-purge.sh.in',
'staticlibs.sh.in', '50-strip.sh.in',
'strip.sh.in', '50-zipman.sh.in',
'zipman.sh.in', '90-emptydirs.sh.in',
] ]
foreach src : sources foreach src : sources

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 pkgbuild_schema_arrays=(arch backup checkdepends conflicts depends groups
license makedepends noextract optdepends options license makedepends noextract optdepends options
provides replaces source validpgpkeys provides replaces source validpgpkeys xdata
"${known_hash_algos[@]/%/sums}") "${known_hash_algos[@]/%/sums}")
pkgbuild_schema_strings=(changelog epoch install pkgbase pkgdesc pkgrel pkgver 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 "pkgname" "$pkgname"
write_kv_pair "pkgbase" "$pkgbase" write_kv_pair "pkgbase" "$pkgbase"
write_kv_pair "xdata" "pkgtype=$pkgtype" write_kv_pair "xdata" "pkgtype=$pkgtype" "${xdata[@]}"
local fullver=$(get_full_version) local fullver=$(get_full_version)
write_kv_pair "pkgver" "$fullver" write_kv_pair "pkgver" "$fullver"
@ -1319,11 +1319,13 @@ else
original_pkglist=($(run_pacman -Qq)) # required by remove_dep original_pkglist=($(run_pacman -Qq)) # required by remove_dep
fi fi
msg "$(gettext "Checking buildtime dependencies...")" if (( ! deperr )); then
if (( CHECKFUNC )); then msg "$(gettext "Checking buildtime dependencies...")"
resolve_deps "${makedepends[@]}" "${checkdepends[@]}" || deperr=1 if (( CHECKFUNC )); then
else resolve_deps "${makedepends[@]}" "${checkdepends[@]}" || deperr=1
resolve_deps "${makedepends[@]}" || deperr=1 else
resolve_deps "${makedepends[@]}" || deperr=1
fi
fi fi
if (( RMDEPS )); then if (( RMDEPS )); then

View file

@ -67,7 +67,6 @@ Multiple packages to add can be specified on the command line.\n")"
printf -- "\n" printf -- "\n"
printf -- "$(gettext "Options:\n")" printf -- "$(gettext "Options:\n")"
printf -- "$(gettext " -n, --new only add packages that are not already in the database\n")" printf -- "$(gettext " -n, --new only add packages that are not already in the database\n")"
printf -- "$(gettext " -R, --remove remove old package file from disk after updating database\n")"
printf -- "$(gettext " -p, --prevent-downgrade do not add package to database if a newer version is already present\n")" printf -- "$(gettext " -p, --prevent-downgrade do not add package to database if a newer version is already present\n")"
elif [[ $cmd == "repo-remove" ]] ; then elif [[ $cmd == "repo-remove" ]] ; then
printf -- "$(gettext "Usage: repo-remove [options] <path-to-db> <packagename> ...\n")" printf -- "$(gettext "Usage: repo-remove [options] <path-to-db> <packagename> ...\n")"
@ -87,6 +86,7 @@ packages to remove can be specified on the command line.\n")"
printf -- "$(gettext " -s, --sign sign database with GnuPG after update\n")" printf -- "$(gettext " -s, --sign sign database with GnuPG after update\n")"
printf -- "$(gettext " -k, --key <key> use the specified key to sign the database\n")" printf -- "$(gettext " -k, --key <key> use the specified key to sign the database\n")"
printf -- "$(gettext " -v, --verify verify database's signature before update\n")" printf -- "$(gettext " -v, --verify verify database's signature before update\n")"
printf -- "$(gettext " -R, --remove remove old package file from disk after updating database\n")"
printf -- "$(gettext " -w, --wait-for-lock retry to acquire lock file until success\n")" printf -- "$(gettext " -w, --wait-for-lock retry to acquire lock file until success\n")"
printf -- "$(gettext "\n\ printf -- "$(gettext "\n\
See %s(8) for more details and descriptions of the available options.\n")" $cmd See %s(8) for more details and descriptions of the available options.\n")" $cmd
@ -355,11 +355,21 @@ db_remove_entry() {
local pkgname=$1 local pkgname=$1
local notfound=1 local notfound=1
local pkgentry=$(find_pkgentry "$pkgname") local pkgentry=$(find_pkgentry "$pkgname")
local repodir=${LOCKFILE%/*}/
while [[ -n $pkgentry ]]; do while [[ -n $pkgentry ]]; do
notfound=0 notfound=0
msg2 "$(gettext "Removing existing entry '%s'...")" \ msg2 "$(gettext "Removing existing entry '%s'...")" \
"${pkgentry##*/}" "${pkgentry##*/}"
if (( RMEXISTING )); then
local oldfilename="$(sed -n '/^%FILENAME%$/ {n;p;q;}' "$pkgentry/desc")"
local oldfile="$repodir/$oldfilename"
msg2 "$(gettext "Removing old package file '%s'")" "$oldfilename"
rm -f ${oldfile} ${oldfile}.sig
fi
rm -rf "$pkgentry" rm -rf "$pkgentry"
# remove entries in "files" database # remove entries in "files" database