libxbps: [unpack] only extract files if they have been modified.
This commit is contained in:
parent
890bdd368f
commit
ba5913cbb9
4
NEWS
4
NEWS
@ -1,5 +1,9 @@
|
|||||||
xbps-0.10.0 (???):
|
xbps-0.10.0 (???):
|
||||||
|
|
||||||
|
* libxbps: when updating packages, only files that have been modified
|
||||||
|
(compared to current installed file) are now unpacked. This should
|
||||||
|
save some writes to storage and make the process a bit smoother as well.
|
||||||
|
|
||||||
* Moved install transaction code to libxbps. The API has been extended
|
* Moved install transaction code to libxbps. The API has been extended
|
||||||
with xbps_transaction_commit() which expects the transaction dictionary
|
with xbps_transaction_commit() which expects the transaction dictionary
|
||||||
as its argument. This function will execute transaction tasks, like
|
as its argument. This function will execute transaction tasks, like
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
*/
|
*/
|
||||||
#define XBPS_PKGINDEX_VERSION "1.2"
|
#define XBPS_PKGINDEX_VERSION "1.2"
|
||||||
|
|
||||||
#define XBPS_API_VERSION "20110729"
|
#define XBPS_API_VERSION "20110731"
|
||||||
#define XBPS_VERSION "0.10.0"
|
#define XBPS_VERSION "0.10.0"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1430,9 +1430,9 @@ char *xbps_file_hash(const char *file);
|
|||||||
* @return The sha256 hash string if found, NULL otherwise
|
* @return The sha256 hash string if found, NULL otherwise
|
||||||
* and errno is set appropiately.
|
* and errno is set appropiately.
|
||||||
*/
|
*/
|
||||||
const char *xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
const char *xbps_file_hash_dictionary(prop_dictionary_t d,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *file);
|
const char *file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the sha256 hash of the file \a file with the sha256
|
* Compares the sha256 hash of the file \a file with the sha256
|
||||||
@ -1446,6 +1446,20 @@ const char *xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
|||||||
*/
|
*/
|
||||||
int xbps_file_hash_check(const char *file, const char *sha256);
|
int xbps_file_hash_check(const char *file, const char *sha256);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if \a file matches the sha256 hash specified in the array
|
||||||
|
* with key \a key in the proplib dictionary \a d.
|
||||||
|
*
|
||||||
|
* @param[in] d Proplib dictionary to look in.
|
||||||
|
* @param[in] key Proplib array key to match for file.
|
||||||
|
* @param[in] file Pathname to a file.
|
||||||
|
*
|
||||||
|
* @return 0 if hash is matched, -1 on error and 1 if no match.
|
||||||
|
*/
|
||||||
|
int xbps_file_hash_check_dictionary(prop_dictionary_t d,
|
||||||
|
const char *key,
|
||||||
|
const char *file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a package is currently installed by matching a package
|
* Checks if a package is currently installed by matching a package
|
||||||
* pattern string.
|
* pattern string.
|
||||||
|
@ -157,6 +157,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
|||||||
{
|
{
|
||||||
prop_dictionary_t propsd = NULL, filesd = NULL, old_filesd = NULL;
|
prop_dictionary_t propsd = NULL, filesd = NULL, old_filesd = NULL;
|
||||||
prop_array_t array;
|
prop_array_t array;
|
||||||
|
const struct stat *entry_statp;
|
||||||
struct archive_entry *entry;
|
struct archive_entry *entry;
|
||||||
size_t nmetadata = 0, entry_idx = 0;
|
size_t nmetadata = 0, entry_idx = 0;
|
||||||
const char *entry_pname, *transact;
|
const char *entry_pname, *transact;
|
||||||
@ -200,6 +201,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
|||||||
* Process the archive files.
|
* Process the archive files.
|
||||||
*/
|
*/
|
||||||
while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
|
while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
|
||||||
|
entry_statp = archive_entry_stat(entry);
|
||||||
entry_pname = archive_entry_pathname(entry);
|
entry_pname = archive_entry_pathname(entry);
|
||||||
flags = set_extract_flags();
|
flags = set_extract_flags();
|
||||||
|
|
||||||
@ -324,33 +326,56 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
|||||||
xhp->xucd->entry_total_count +=
|
xhp->xucd->entry_total_count +=
|
||||||
(ssize_t)prop_array_count(array);
|
(ssize_t)prop_array_count(array);
|
||||||
|
|
||||||
/*
|
if (update && S_ISREG(entry_statp->st_mode)) {
|
||||||
* Handle configuration files. Check if current entry is
|
/*
|
||||||
* a configuration file and take action if required. Skip
|
* Handle configuration files. Check if current entry is
|
||||||
* packages that don't have the "conf_files" array in
|
* a configuration file and take action if required. Skip
|
||||||
* the XBPS_PKGPROPS dictionary.
|
* packages that don't have the "conf_files" array in
|
||||||
*/
|
* the XBPS_PKGPROPS dictionary.
|
||||||
rv = xbps_entry_is_a_conf_file(propsd, entry_pname);
|
*/
|
||||||
if (rv == -1) {
|
rv = xbps_entry_is_a_conf_file(propsd, entry_pname);
|
||||||
/* error */
|
|
||||||
goto out;
|
|
||||||
} else if (rv == 1) {
|
|
||||||
if (xhp->xucd != NULL)
|
|
||||||
xhp->xucd->entry_is_conf = true;
|
|
||||||
|
|
||||||
rv = xbps_entry_install_conf_file(filesd,
|
|
||||||
entry, entry_pname, pkgname, version);
|
|
||||||
if (rv == -1) {
|
if (rv == -1) {
|
||||||
/* error */
|
/* error */
|
||||||
goto out;
|
goto out;
|
||||||
} else if (rv == 0) {
|
} else if (rv == 1) {
|
||||||
|
if (xhp->xucd != NULL)
|
||||||
|
xhp->xucd->entry_is_conf = true;
|
||||||
|
|
||||||
|
rv = xbps_entry_install_conf_file(filesd,
|
||||||
|
entry, entry_pname, pkgname, version);
|
||||||
|
if (rv == -1) {
|
||||||
|
/* error */
|
||||||
|
goto out;
|
||||||
|
} else if (rv == 0) {
|
||||||
|
/*
|
||||||
|
* Keep current configuration file
|
||||||
|
* as is now and pass to next entry.
|
||||||
|
*/
|
||||||
|
archive_read_data_skip(ar);
|
||||||
|
RUN_PROGRESS_CB();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Keep current configuration file
|
* Current entry is not a configuration file,
|
||||||
* as is now and pass to next entry.
|
* check if installed file matches sha256 hash.
|
||||||
|
* If true, there is no need to extract it.
|
||||||
*/
|
*/
|
||||||
archive_read_data_skip(ar);
|
rv = xbps_file_hash_check_dictionary(filesd,
|
||||||
RUN_PROGRESS_CB();
|
"files", entry_pname);
|
||||||
continue;
|
if (rv == -1) {
|
||||||
|
xbps_dbg_printf("%s-%s: failed to check"
|
||||||
|
" hash for `%s': %s\n", pkgname,
|
||||||
|
version, entry_pname,
|
||||||
|
strerror(errno));
|
||||||
|
/* error */
|
||||||
|
goto out;
|
||||||
|
} else if (rv == 0) {
|
||||||
|
/* hash match, skip */
|
||||||
|
archive_read_data_skip(ar);
|
||||||
|
RUN_PROGRESS_CB();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -137,9 +137,9 @@ xbps_file_hash_check(const char *file, const char *sha256)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
xbps_file_hash_dictionary(prop_dictionary_t d,
|
||||||
const char *key,
|
const char *key,
|
||||||
const char *file)
|
const char *file)
|
||||||
{
|
{
|
||||||
prop_object_t obj;
|
prop_object_t obj;
|
||||||
prop_object_iterator_t iter;
|
prop_object_iterator_t iter;
|
||||||
@ -152,8 +152,10 @@ xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
|||||||
curfile = sha256 = NULL;
|
curfile = sha256 = NULL;
|
||||||
|
|
||||||
iter = xbps_array_iter_from_dict(d, key);
|
iter = xbps_array_iter_from_dict(d, key);
|
||||||
if (iter == NULL)
|
if (iter == NULL) {
|
||||||
|
errno = ENOENT;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||||
prop_dictionary_get_cstring_nocopy(obj,
|
prop_dictionary_get_cstring_nocopy(obj,
|
||||||
"file", &curfile);
|
"file", &curfile);
|
||||||
@ -170,3 +172,32 @@ xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
|||||||
|
|
||||||
return sha256;
|
return sha256;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xbps_file_hash_check_dictionary(prop_dictionary_t d,
|
||||||
|
const char *key,
|
||||||
|
const char *file)
|
||||||
|
{
|
||||||
|
const char *sha256d;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
assert(d != NULL);
|
||||||
|
assert(key != NULL);
|
||||||
|
assert(file != NULL);
|
||||||
|
|
||||||
|
sha256d = xbps_file_hash_dictionary(d, key, file);
|
||||||
|
if (sha256d == NULL) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
return 1; /* no match, file not found */
|
||||||
|
|
||||||
|
return -1; /* error */
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = xbps_file_hash_check(file, sha256d);
|
||||||
|
if (rv == 0)
|
||||||
|
return 0; /* matched */
|
||||||
|
else if (rv == ERANGE || rv == ENOENT)
|
||||||
|
return 1; /* no match */
|
||||||
|
else
|
||||||
|
return -1; /* error */
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user