Compare commits

..

9 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
14 changed files with 264 additions and 215 deletions

114
README
View file

@ -363,7 +363,7 @@ API CHANGES BETWEEN 3.4 AND 3.5
- 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
@ -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,18 +504,18 @@ 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
@ -513,7 +527,7 @@ 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
@ -523,7 +537,7 @@ API CHANGES BETWEEN 4.1 AND 4.2
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
@ -532,30 +546,30 @@ API CHANGES BETWEEN 4.1 AND 4.2
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,7 +676,7 @@ 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()
@ -673,28 +687,28 @@ 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,13 +727,13 @@ 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()
@ -729,7 +743,7 @@ 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()

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

@ -308,8 +308,6 @@ typedef enum _alpm_errno_t {
/** Files conflict */ /** Files conflict */
ALPM_ERR_FILE_CONFLICTS, ALPM_ERR_FILE_CONFLICTS,
/* Misc */ /* Misc */
/** Download setup failed */
ALPM_ERR_RETRIEVE_PREPARE,
/** Download failed */ /** Download failed */
ALPM_ERR_RETRIEVE, ALPM_ERR_RETRIEVE,
/** Invalid Regex */ /** Invalid Regex */

View file

@ -153,7 +153,7 @@ int SYMEXPORT alpm_db_update(alpm_handle_t *handle, alpm_list_t *dbs, int force)
syncpath = get_sync_dir(handle); syncpath = get_sync_dir(handle);
ASSERT(syncpath != NULL, return -1); ASSERT(syncpath != NULL, return -1);
temporary_syncpath = _alpm_temporary_download_dir_setup(handle, syncpath); temporary_syncpath = _alpm_temporary_download_dir_setup(syncpath, handle->sandboxuser);
ASSERT(temporary_syncpath != NULL, FREE(syncpath); return -1); ASSERT(temporary_syncpath != NULL, FREE(syncpath); return -1);
/* make sure we have a sane umask */ /* make sure we have a sane umask */
@ -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

@ -916,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;
@ -1021,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 {
@ -1101,36 +1106,46 @@ 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;
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; filename = payload->destfile_name;
} else { } else if(stat(payload->tempfile_name, &st) == 0) {
filename = payload->tempfile_name; filename = payload->tempfile_name;
} }
if(filename) {
int ret = move_file(filename, localpath); 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"),
filename, 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(filename) + 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", filename, 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);
}
} }
} }
return returnvalue; return returnvalue;
@ -1188,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);
} }
@ -1268,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, '/');
@ -1287,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,
@ -1304,14 +1329,31 @@ int SYMEXPORT alpm_fetch_pkgurl(alpm_handle_t *handle, const alpm_list_t *urls,
/* find a valid cache dir to download to */ /* find a valid cache dir to download to */
cachedir = _alpm_filecache_setup(handle); cachedir = _alpm_filecache_setup(handle);
temporary_cachedir = _alpm_temporary_download_dir_setup(handle, cachedir); temporary_cachedir = _alpm_temporary_download_dir_setup(cachedir, handle->sandboxuser);
ASSERT(temporary_cachedir != NULL, return -1); ASSERT(temporary_cachedir != NULL, return -1);
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 */ /* attempt to find the file in our pkgcache */
char *filepath = filecache_find_url(handle, url); 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);
}
}
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);
@ -1395,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);

View file

@ -138,8 +138,6 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
case ALPM_ERR_FILE_CONFLICTS: case ALPM_ERR_FILE_CONFLICTS:
return _("conflicting files"); return _("conflicting files");
/* Miscellaneous */ /* Miscellaneous */
case ALPM_ERR_RETRIEVE_PREPARE:
return _("failed to initialize download");
case ALPM_ERR_RETRIEVE: case ALPM_ERR_RETRIEVE:
return _("failed to retrieve some files"); return _("failed to retrieve some files");
case ALPM_ERR_INVALID_REGEX: case ALPM_ERR_INVALID_REGEX:

View file

@ -780,7 +780,7 @@ static int download_files(alpm_handle_t *handle)
alpm_list_t *payloads = NULL; alpm_list_t *payloads = NULL;
cachedir = _alpm_filecache_setup(handle); cachedir = _alpm_filecache_setup(handle);
temporary_cachedir = _alpm_temporary_download_dir_setup(handle, cachedir); temporary_cachedir = _alpm_temporary_download_dir_setup(cachedir, handle->sandboxuser);
if(temporary_cachedir == NULL) { if(temporary_cachedir == NULL) {
ret = -1; ret = -1;
goto finish; goto finish;
@ -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

@ -23,7 +23,6 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <dirent.h> #include <dirent.h>
@ -950,53 +949,32 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle)
/** Create a temporary directory under the supplied directory. /** Create a temporary directory under the supplied directory.
* The new directory is writable by the download user, and will be * The new directory is writable by the download user, and will be
* removed after the download operation has completed. * removed after the download operation has completed.
* @param handle an alpm handle
* @param dir existing sync or cache directory * @param dir existing sync or cache directory
* @param user download user name
* @return pointer to a sub-directory writable by the download user inside the existing directory. * @return pointer to a sub-directory writable by the download user inside the existing directory.
*/ */
char *_alpm_temporary_download_dir_setup(alpm_handle_t *handle, const char *dir) char *_alpm_temporary_download_dir_setup(const char *dir, const char *user)
{ {
const char *user = handle->sandboxuser;
uid_t myuid = getuid();
struct passwd const *pw = NULL; struct passwd const *pw = NULL;
ASSERT(dir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL)); ASSERT(dir != NULL, return NULL);
if(myuid == 0 && user != NULL) { if(user != NULL) {
errno = 0; ASSERT((pw = getpwnam(user)) != NULL, return NULL);
pw = getpwnam(user);
if(pw == NULL) {
if(errno == 0) {
_alpm_log(handle, ALPM_LOG_ERROR,
_("download user '%s' does not exist\n"), user);
} else {
_alpm_log(handle, ALPM_LOG_ERROR,
_("failed to get download user '%s': %s\n"),
user, strerror(errno));
}
RET_ERR(handle, ALPM_ERR_RETRIEVE_PREPARE, NULL);
}
} }
const char template[] = "download-XXXXXX"; const char template[] = "download-XXXXXX";
size_t newdirlen = strlen(dir) + sizeof(template) + 1; size_t newdirlen = strlen(dir) + sizeof(template) + 1;
char *newdir = NULL; char *newdir = NULL;
MALLOC(newdir, newdirlen, RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); MALLOC(newdir, newdirlen, return NULL);
snprintf(newdir, newdirlen - 1, "%s%s", dir, template); snprintf(newdir, newdirlen - 1, "%s%s", dir, template);
if(mkdtemp(newdir) == NULL) { if(mkdtemp(newdir) == NULL) {
_alpm_log(handle, ALPM_LOG_ERROR,
_("failed to create temporary download directory %s: %s\n"),
newdir, strerror(errno));
free(newdir); free(newdir);
RET_ERR(handle, ALPM_ERR_RETRIEVE_PREPARE, NULL); return NULL;
} }
if(pw != NULL) { if(pw != NULL) {
if(chown(newdir, pw->pw_uid, pw->pw_gid) == -1) { if(chown(newdir, pw->pw_uid, pw->pw_gid) == -1) {
_alpm_log(handle, ALPM_LOG_ERROR,
_("failed to chown temporary download directory %s: %s\n"),
newdir, strerror(errno));
free(newdir); free(newdir);
RET_ERR(handle, ALPM_ERR_RETRIEVE_PREPARE, NULL); return NULL;
} }
} }
newdir[newdirlen-2] = '/'; newdir[newdirlen-2] = '/';

View file

@ -139,7 +139,7 @@ char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename);
/* Checks whether a file exists in cache */ /* Checks whether a file exists in cache */
int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename); int _alpm_filecache_exists(alpm_handle_t *handle, const char *filename);
const char *_alpm_filecache_setup(alpm_handle_t *handle); const char *_alpm_filecache_setup(alpm_handle_t *handle);
char *_alpm_temporary_download_dir_setup(alpm_handle_t *handle, const char *dir); char *_alpm_temporary_download_dir_setup(const char *dir, const char *user);
void _alpm_remove_temporary_download_dir(const char *dir); void _alpm_remove_temporary_download_dir(const char *dir);
/* Unlike many uses of alpm_pkgvalidation_t, _alpm_test_checksum expects /* Unlike many uses of alpm_pkgvalidation_t, _alpm_test_checksum expects

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

@ -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"