summaryrefslogtreecommitdiff
path: root/lib/libalpm/sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/sync.c')
-rw-r--r--lib/libalpm/sync.c239
1 files changed, 143 insertions, 96 deletions
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index e500d90f..ca6b507e 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -1,7 +1,7 @@
/*
* sync.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
@@ -21,8 +21,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <sys/types.h> /* off_t */
#include <stdlib.h>
#include <stdio.h>
@@ -251,7 +249,7 @@ alpm_list_t SYMEXPORT *alpm_find_group_pkgs(alpm_list_t *dbs,
for(i = dbs; i; i = i->next) {
alpm_db_t *db = i->data;
- alpm_group_t *grp = alpm_db_readgroup(db, name);
+ alpm_group_t *grp = alpm_db_get_group(db, name);
if(!grp)
continue;
@@ -291,7 +289,7 @@ static int compute_download_size(alpm_pkg_t *newpkg)
alpm_handle_t *handle = newpkg->handle;
int ret = 0;
- if(newpkg->origin != PKG_FROM_SYNCDB) {
+ if(newpkg->origin != ALPM_PKG_FROM_SYNCDB) {
newpkg->infolevel |= INFRQ_DSIZE;
newpkg->download_size = 0;
return 0;
@@ -321,13 +319,13 @@ static int compute_download_size(alpm_pkg_t *newpkg)
/* tell the caller that we have a partial */
ret = 1;
- } else if(handle->usedelta) {
+ } else if(handle->deltaratio > 0.0) {
off_t dltsize;
dltsize = _alpm_shortest_delta_path(handle, newpkg->deltas,
newpkg->filename, &newpkg->delta_path);
- if(newpkg->delta_path && (dltsize < newpkg->size * MAX_DELTA_RATIO)) {
+ if(newpkg->delta_path && (dltsize < newpkg->size * handle->deltaratio)) {
_alpm_log(handle, ALPM_LOG_DEBUG, "using delta size\n");
size = dltsize;
} else {
@@ -368,7 +366,7 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
for(i = trans->add; i; i = i->next) {
alpm_pkg_t *spkg = i->data;
- from_sync += (spkg->origin == PKG_FROM_SYNCDB);
+ from_sync += (spkg->origin == ALPM_PKG_FROM_SYNCDB);
}
/* ensure all sync database are valid if we will be using them */
@@ -424,7 +422,7 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
see if they'd like to ignore them rather than failing the sync */
if(unresolvable != NULL) {
int remove_unresolvable = 0;
- enum _alpm_errno_t saved_err = handle->pm_errno;
+ alpm_errno_t saved_err = handle->pm_errno;
QUESTION(handle, ALPM_QUESTION_REMOVE_PKGS, unresolvable,
NULL, NULL, &remove_unresolvable);
if(remove_unresolvable) {
@@ -696,11 +694,11 @@ static int apply_deltas(alpm_handle_t *handle)
} else {
/* len = cachedir len + from len + '/' + null */
len = strlen(cachedir) + strlen(d->from) + 2;
- CALLOC(from, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, 1));
+ MALLOC(from, len, RET_ERR(handle, ALPM_ERR_MEMORY, 1));
snprintf(from, len, "%s/%s", cachedir, d->from);
}
len = strlen(cachedir) + strlen(d->to) + 2;
- CALLOC(to, len, sizeof(char), RET_ERR(handle, ALPM_ERR_MEMORY, 1));
+ MALLOC(to, len, RET_ERR(handle, ALPM_ERR_MEMORY, 1));
snprintf(to, len, "%s/%s", cachedir, d->to);
/* build the patch command */
@@ -758,7 +756,7 @@ static int apply_deltas(alpm_handle_t *handle)
* @return 1 if file was removed, 0 otherwise
*/
static int prompt_to_delete(alpm_handle_t *handle, const char *filepath,
- enum _alpm_errno_t reason)
+ alpm_errno_t reason)
{
int doremove = 0;
QUESTION(handle, ALPM_QUESTION_CORRUPTED_PKG, (char *)filepath,
@@ -783,7 +781,7 @@ static int validate_deltas(alpm_handle_t *handle, alpm_list_t *deltas)
alpm_delta_t *d = i->data;
char *filepath = _alpm_filecache_find(handle, d->delta);
- if(_alpm_test_checksum(filepath, d->delta_md5, ALPM_CSUM_MD5)) {
+ if(_alpm_test_checksum(filepath, d->delta_md5, ALPM_PKG_VALIDATION_MD5SUM)) {
errors = alpm_list_add(errors, filepath);
} else {
FREE(filepath);
@@ -804,11 +802,96 @@ static int validate_deltas(alpm_handle_t *handle, alpm_list_t *deltas)
return 0;
}
+static struct dload_payload *build_payload(alpm_handle_t *handle,
+ const char *filename, size_t size, alpm_list_t *servers)
+{
+ struct dload_payload *payload;
+
+ CALLOC(payload, 1, sizeof(*payload), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
+ STRDUP(payload->remote_name, filename, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
+ payload->max_size = size;
+ payload->servers = servers;
+ return payload;
+}
+
+static int find_dl_candidates(alpm_db_t *repo, alpm_list_t **files, alpm_list_t **deltas)
+{
+ alpm_list_t *i;
+ alpm_handle_t *handle = repo->handle;
+
+ for(i = handle->trans->add; i; i = i->next) {
+ alpm_pkg_t *spkg = i->data;
+
+ if(spkg->origin != ALPM_PKG_FROM_FILE && repo == spkg->origin_data.db) {
+ alpm_list_t *delta_path = spkg->delta_path;
+
+ if(!repo->servers) {
+ handle->pm_errno = ALPM_ERR_SERVER_NONE;
+ _alpm_log(handle, ALPM_LOG_ERROR, "%s: %s\n",
+ alpm_strerror(handle->pm_errno), repo->treename);
+ return 1;
+ }
+
+ if(delta_path) {
+ /* using deltas */
+ alpm_list_t *dlts;
+ for(dlts = delta_path; dlts; dlts = dlts->next) {
+ alpm_delta_t *delta = dlts->data;
+ if(delta->download_size != 0) {
+ struct dload_payload *payload = build_payload(
+ handle, delta->delta, delta->delta_size, repo->servers);
+ ASSERT(payload, return -1);
+ *files = alpm_list_add(*files, payload);
+ }
+ /* keep a list of all the delta files for md5sums */
+ *deltas = alpm_list_add(*deltas, delta);
+ }
+
+ } else if(spkg->download_size != 0) {
+ struct dload_payload *payload;
+ ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
+ payload = build_payload(handle, spkg->filename, spkg->size, repo->servers);
+ ASSERT(payload, return -1);
+ *files = alpm_list_add(*files, payload);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int download_single_file(alpm_handle_t *handle, struct dload_payload *payload,
+ const char *cachedir)
+{
+ const alpm_list_t *server;
+
+ payload->handle = handle;
+ payload->allow_resume = 1;
+
+ for(server = payload->servers; server; server = server->next) {
+ const char *server_url = server->data;
+ size_t len;
+
+ /* print server + filename into a buffer */
+ len = strlen(server_url) + strlen(payload->remote_name) + 2;
+ MALLOC(payload->fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
+ snprintf(payload->fileurl, len, "%s/%s", server_url, payload->remote_name);
+
+ if(_alpm_download(payload, cachedir, NULL) != -1) {
+ return 0;
+ }
+
+ FREE(payload->fileurl);
+ payload->unlink_on_fail = 0;
+ }
+
+ return -1;
+}
+
static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
{
const char *cachedir;
- alpm_list_t *i, *j;
- alpm_list_t *files = NULL;
+ alpm_list_t *i, *files = NULL;
int errors = 0;
cachedir = _alpm_filecache_setup(handle);
@@ -827,93 +910,53 @@ static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
handle->totaldlcb(total_size);
}
- /* group sync records by repository and download */
for(i = handle->dbs_sync; i; i = i->next) {
- alpm_db_t *current = i->data;
-
- for(j = handle->trans->add; j; j = j->next) {
- alpm_pkg_t *spkg = j->data;
-
- if(spkg->origin != PKG_FROM_FILE && current == spkg->origin_data.db) {
- alpm_list_t *delta_path = spkg->delta_path;
- if(delta_path) {
- /* using deltas */
- alpm_list_t *dlts;
- for(dlts = delta_path; dlts; dlts = dlts->next) {
- alpm_delta_t *delta = dlts->data;
- if(delta->download_size != 0) {
- struct dload_payload *dpayload;
-
- CALLOC(dpayload, 1, sizeof(*dpayload), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
- STRDUP(dpayload->remote_name, delta->delta, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
- dpayload->max_size = delta->delta_size;
-
- files = alpm_list_add(files, dpayload);
- }
- /* keep a list of all the delta files for md5sums */
- *deltas = alpm_list_add(*deltas, delta);
- }
+ errors += find_dl_candidates(i->data, &files, deltas);
+ }
- } else if(spkg->download_size != 0) {
- struct dload_payload *payload;
+ if(files) {
+ /* check for necessary disk space for download */
+ if(handle->checkspace) {
+ off_t *file_sizes;
+ size_t idx, num_files;
+ int ret;
- ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
- CALLOC(payload, 1, sizeof(*payload), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
- STRDUP(payload->remote_name, spkg->filename, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
- payload->max_size = spkg->size;
+ _alpm_log(handle, ALPM_LOG_DEBUG, "checking available disk space for download\n");
- files = alpm_list_add(files, payload);
- }
+ num_files = alpm_list_count(files);
+ CALLOC(file_sizes, num_files, sizeof(off_t), goto finish);
+ for(i = files, idx = 0; i; i = i->next, idx++) {
+ const struct dload_payload *payload = i->data;
+ file_sizes[idx] = payload->max_size;
}
- }
- if(files) {
- if(!current->servers) {
- handle->pm_errno = ALPM_ERR_SERVER_NONE;
- _alpm_log(handle, ALPM_LOG_ERROR, "%s: %s\n",
- alpm_strerror(handle->pm_errno), current->treename);
+ ret = _alpm_check_downloadspace(handle, cachedir, num_files, file_sizes);
+ free(file_sizes);
+
+ if(ret != 0) {
errors++;
- continue;
+ goto finish;
}
+ }
- EVENT(handle, ALPM_EVENT_RETRIEVE_START, current->treename, NULL);
- for(j = files; j; j = j->next) {
- struct dload_payload *payload = j->data;
- alpm_list_t *server;
- int ret = -1;
- for(server = current->servers; server; server = server->next) {
- const char *server_url = server->data;
- size_t len;
-
- /* print server + filename into a buffer */
- len = strlen(server_url) + strlen(payload->remote_name) + 2;
- MALLOC(payload->fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
- snprintf(payload->fileurl, len, "%s/%s", server_url, payload->remote_name);
- payload->handle = handle;
- payload->allow_resume = 1;
-
- ret = _alpm_download(payload, cachedir, NULL);
- if(ret != -1) {
- break;
- }
- FREE(payload->fileurl);
- payload->unlink_on_fail = 0;
- }
- if(ret == -1) {
- errors++;
- _alpm_log(handle, ALPM_LOG_WARNING, _("failed to retrieve some files from %s\n"),
- current->treename);
- }
+ EVENT(handle, ALPM_EVENT_RETRIEVE_START, NULL, NULL);
+ for(i = files; i; i = i->next) {
+ if(download_single_file(handle, i->data, cachedir) == -1) {
+ errors++;
+ _alpm_log(handle, ALPM_LOG_WARNING, _("failed to retrieve some files\n"));
}
-
- alpm_list_free_inner(files, (alpm_list_fn_free)_alpm_dload_payload_reset);
- FREELIST(files);
}
}
- for(j = handle->trans->add; j; j = j->next) {
- alpm_pkg_t *pkg = j->data;
+finish:
+ if(files) {
+ alpm_list_free_inner(files, (alpm_list_fn_free)_alpm_dload_payload_reset);
+ FREELIST(files);
+ }
+
+ for(i = handle->trans->add; i; i = i->next) {
+ alpm_pkg_t *pkg = i->data;
pkg->infolevel &= ~INFRQ_DSIZE;
pkg->download_size = 0;
}
@@ -934,7 +977,8 @@ static int check_validity(alpm_handle_t *handle,
char *path;
alpm_siglist_t *siglist;
alpm_siglevel_t level;
- enum _alpm_errno_t error;
+ alpm_pkgvalidation_t validation;
+ alpm_errno_t error;
};
size_t current = 0, current_bytes = 0;
alpm_list_t *i, *errors = NULL;
@@ -943,12 +987,12 @@ static int check_validity(alpm_handle_t *handle,
EVENT(handle, ALPM_EVENT_INTEGRITY_START, NULL, NULL);
for(i = handle->trans->add; i; i = i->next, current++) {
- struct validity v = { i->data, NULL, NULL, 0, 0 };
+ struct validity v = { i->data, NULL, NULL, 0, 0, 0 };
int percent = (int)(((double)current_bytes / total_bytes) * 100);
PROGRESS(handle, ALPM_PROGRESS_INTEGRITY_START, "", percent,
total, current);
- if(v.pkg->origin == PKG_FROM_FILE) {
+ if(v.pkg->origin == ALPM_PKG_FROM_FILE) {
continue; /* pkg_load() has been already called, this package is valid */
}
@@ -957,7 +1001,7 @@ static int check_validity(alpm_handle_t *handle,
v.level = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg));
if(_alpm_pkg_validate_internal(handle, v.path, v.pkg,
- v.level, &v.siglist) == -1) {
+ v.level, &v.siglist, &v.validation) == -1) {
v.error = handle->pm_errno;
struct validity *invalid = malloc(sizeof(struct validity));
memcpy(invalid, &v, sizeof(struct validity));
@@ -966,6 +1010,7 @@ static int check_validity(alpm_handle_t *handle,
alpm_siglist_cleanup(v.siglist);
free(v.siglist);
free(v.path);
+ v.pkg->validation = v.validation;
}
}
@@ -1023,7 +1068,7 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
PROGRESS(handle, ALPM_PROGRESS_LOAD_START, "", percent,
total, current);
- if(spkg->origin == PKG_FROM_FILE) {
+ if(spkg->origin == ALPM_PKG_FROM_FILE) {
continue; /* pkg_load() has been already called, this package is valid */
}
@@ -1045,6 +1090,8 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
free(filepath);
/* copy over the install reason */
pkgfile->reason = spkg->reason;
+ /* copy over validation method */
+ pkgfile->validation = spkg->validation;
i->data = pkgfile;
/* spkg has been removed from the target list, so we can free the
* sync-specific fields */
@@ -1091,7 +1138,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
* realistically if there are small and huge packages involved */
for(i = trans->add; i; i = i->next) {
alpm_pkg_t *spkg = i->data;
- if(spkg->origin != PKG_FROM_FILE) {
+ if(spkg->origin != ALPM_PKG_FROM_FILE) {
total_bytes += spkg->size;
}
total++;
@@ -1120,7 +1167,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
trans->state = STATE_COMMITING;
/* fileconflict check */
- if(!(trans->flags & ALPM_TRANS_FLAG_FORCE)) {
+ if(!(trans->flags & (ALPM_TRANS_FLAG_FORCE|ALPM_TRANS_FLAG_DBONLY))) {
EVENT(handle, ALPM_EVENT_FILECONFLICTS_START, NULL, NULL);
_alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n");
@@ -1145,7 +1192,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
_alpm_log(handle, ALPM_LOG_DEBUG, "checking available disk space\n");
if(_alpm_check_diskspace(handle) == -1) {
- _alpm_log(handle, ALPM_LOG_ERROR, "%s\n", _("not enough free disk space"));
+ _alpm_log(handle, ALPM_LOG_ERROR, _("not enough free disk space\n"));
return -1;
}