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 (???):
|
||||
|
||||
* 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
|
||||
with xbps_transaction_commit() which expects the transaction dictionary
|
||||
as its argument. This function will execute transaction tasks, like
|
||||
|
@ -55,7 +55,7 @@
|
||||
*/
|
||||
#define XBPS_PKGINDEX_VERSION "1.2"
|
||||
|
||||
#define XBPS_API_VERSION "20110729"
|
||||
#define XBPS_API_VERSION "20110731"
|
||||
#define XBPS_VERSION "0.10.0"
|
||||
|
||||
/**
|
||||
@ -1430,7 +1430,7 @@ char *xbps_file_hash(const char *file);
|
||||
* @return The sha256 hash string if found, NULL otherwise
|
||||
* 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 *file);
|
||||
|
||||
@ -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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* pattern string.
|
||||
|
@ -157,6 +157,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
||||
{
|
||||
prop_dictionary_t propsd = NULL, filesd = NULL, old_filesd = NULL;
|
||||
prop_array_t array;
|
||||
const struct stat *entry_statp;
|
||||
struct archive_entry *entry;
|
||||
size_t nmetadata = 0, entry_idx = 0;
|
||||
const char *entry_pname, *transact;
|
||||
@ -200,6 +201,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
||||
* Process the archive files.
|
||||
*/
|
||||
while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
|
||||
entry_statp = archive_entry_stat(entry);
|
||||
entry_pname = archive_entry_pathname(entry);
|
||||
flags = set_extract_flags();
|
||||
|
||||
@ -324,6 +326,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
||||
xhp->xucd->entry_total_count +=
|
||||
(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
|
||||
@ -352,6 +355,28 @@ unpack_archive(prop_dictionary_t pkg_repod,
|
||||
RUN_PROGRESS_CB();
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Current entry is not a configuration file,
|
||||
* check if installed file matches sha256 hash.
|
||||
* If true, there is no need to extract it.
|
||||
*/
|
||||
rv = xbps_file_hash_check_dictionary(filesd,
|
||||
"files", entry_pname);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Extract entry from archive.
|
||||
|
@ -137,7 +137,7 @@ xbps_file_hash_check(const char *file, const char *sha256)
|
||||
}
|
||||
|
||||
const char *
|
||||
xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
||||
xbps_file_hash_dictionary(prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *file)
|
||||
{
|
||||
@ -152,8 +152,10 @@ xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
||||
curfile = sha256 = NULL;
|
||||
|
||||
iter = xbps_array_iter_from_dict(d, key);
|
||||
if (iter == NULL)
|
||||
if (iter == NULL) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
prop_dictionary_get_cstring_nocopy(obj,
|
||||
"file", &curfile);
|
||||
@ -170,3 +172,32 @@ xbps_file_hash_from_dictionary(prop_dictionary_t d,
|
||||
|
||||
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…
Reference in New Issue
Block a user