libxbps: [unpack] only extract files if they have been modified.

This commit is contained in:
Juan RP
2011-08-01 12:35:47 +02:00
parent 890bdd368f
commit ba5913cbb9
4 changed files with 104 additions and 30 deletions

View File

@@ -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,33 +326,56 @@ unpack_archive(prop_dictionary_t pkg_repod,
xhp->xucd->entry_total_count +=
(ssize_t)prop_array_count(array);
/*
* Handle configuration files. Check if current entry is
* a configuration file and take action if required. Skip
* 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) {
/* 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 (update && S_ISREG(entry_statp->st_mode)) {
/*
* Handle configuration files. Check if current entry is
* a configuration file and take action if required. Skip
* 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) {
/* error */
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
* as is now and pass to next entry.
* Current entry is not a configuration file,
* check if installed file matches sha256 hash.
* If true, there is no need to extract it.
*/
archive_read_data_skip(ar);
RUN_PROGRESS_CB();
continue;
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;
}
}
}
/*

View File

@@ -137,9 +137,9 @@ xbps_file_hash_check(const char *file, const char *sha256)
}
const char *
xbps_file_hash_from_dictionary(prop_dictionary_t d,
const char *key,
const char *file)
xbps_file_hash_dictionary(prop_dictionary_t d,
const char *key,
const char *file)
{
prop_object_t obj;
prop_object_iterator_t iter;
@@ -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 */
}