From 670fadf0411bbdd75a8db75ef46f55b1d9db339a Mon Sep 17 00:00:00 2001 From: Chantry Xavier Date: Wed, 27 Feb 2008 16:09:49 +0100 Subject: Get rid of the delta patches list As Nathan noticed, the new informations in the delta struct allows us to get rid of this list : http://www.archlinux.org/pipermail/pacman-dev/2008-February/011163.html So I rewrote apply_deltas for that. The previous apply_deltas also had a limitation: it assumed that the initial package and the deltas were in the first cache dir, which is not necessarily the case. That situation is supported now. Signed-off-by: Chantry Xavier Signed-off-by: Dan McGee --- lib/libalpm/sync.c | 143 +++++++++++++++++++++++++---------------------------- 1 file changed, 67 insertions(+), 76 deletions(-) (limited to 'lib') diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 3a4169e8..8148cfdc 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -671,83 +671,82 @@ unsigned long SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg) * ending package files. * * @param trans the transaction - * @param patches A list of alternating pmpkg_t * and pmdelta_t * - * objects. The patch command will be built using the pmpkg_t, pmdelta_t - * pair. * * @return 0 if all delta files were able to be applied, 1 otherwise. */ -static int apply_deltas(pmtrans_t *trans, alpm_list_t *patches) +static int apply_deltas(pmtrans_t *trans) { - /* keep track of the previous package in the loop to decide if a - * package file should be deleted */ - pmpkg_t *lastpkg = NULL; - int lastpkg_failed = 0; + alpm_list_t *i; int ret = 0; const char *cachedir = _alpm_filecache_setup(); - alpm_list_t *p = patches; - while(p) { - pmpkg_t *pkg; - pmdelta_t *d; - char command[PATH_MAX], fname[PATH_MAX]; + for(i = trans->packages; i; i = i->next) { + pmsyncpkg_t *sync = i->data; + pmpkg_t *spkg = sync->pkg; + alpm_list_t *delta_path = spkg->delta_path; + alpm_list_t *dlts = NULL; - pkg = alpm_list_getdata(p); - p = alpm_list_next(p); + if(!delta_path) { + continue; + } - d = alpm_list_getdata(p); - p = alpm_list_next(p); + for(dlts = delta_path; dlts; dlts = dlts->next) { + pmdelta_t *d = dlts->data; + char *delta, *from, *to; + char command[PATH_MAX]; + int len = 0; - /* if patching fails, ignore the rest of that package's deltas */ - if(lastpkg_failed) { - if(pkg == lastpkg) { - continue; + delta = _alpm_filecache_find(d->delta); + /* the initial package might be in a different cachedir */ + if(dlts == delta_path) { + from = _alpm_filecache_find(d->from); } else { - lastpkg_failed = 0; + /* len = cachedir len + from len + '/' + null */ + len = strlen(cachedir) + strlen(d->from) + 2; + CALLOC(from, len, sizeof(char), RET_ERR(PM_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(PM_ERR_MEMORY, 1)); + snprintf(to, len, "%s/%s", cachedir, d->to); - /* an example of the patch command: (using /cache for cachedir) - * xdelta patch /cache/pacman_3.0.0-1_to_3.0.1-1-i686.delta \ - * /cache/pacman-3.0.0-1-i686.pkg.tar.gz \ - * /cache/pacman-3.0.1-1-i686.pkg.tar.gz - */ - - /* build the patch command */ - snprintf(command, PATH_MAX, - "xdelta patch" /* the command */ - " %s/%s" /* the delta */ - " %s/%s" /* the 'from' package */ - " %s/%s", /* the 'to' package */ - cachedir, d->delta, - cachedir, d->from, - cachedir, d->to); - - _alpm_log(PM_LOG_DEBUG, _("command: %s\n"), command); - - EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_START, d->to, d->delta); - - if(system(command) == 0) { - EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_DONE, NULL, NULL); - - /* delete the delta file */ - snprintf(fname, PATH_MAX, "%s/%s", cachedir, d->delta); - unlink(fname); - - /* Delete the 'from' package but only if it is an intermediate - * package. The starting 'from' package should be kept, just - * as if deltas were not used. Delete the package file if the - * previous iteration of the loop used the same package. */ - if(pkg == lastpkg) { - snprintf(fname, PATH_MAX, "%s/%s", cachedir, d->from); - unlink(fname); - } else { - lastpkg = pkg; + /* an example of the patch command: (using /cache for cachedir) + * xdelta patch /path/to/pacman_3.0.0-1_to_3.0.1-1-i686.delta \ + * /path/to/pacman-3.0.0-1-i686.pkg.tar.gz \ + * /cache/pacman-3.0.1-1-i686.pkg.tar.gz + */ + + /* build the patch command */ + snprintf(command, PATH_MAX, "xdelta patch %s %s %s", delta, from, to); + + _alpm_log(PM_LOG_DEBUG, _("command: %s\n"), command); + + EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_START, d->to, d->delta); + + int retval = system(command); + if(retval == 0) { + EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_DONE, NULL, NULL); + + /* delete the delta file */ + unlink(delta); + + /* Delete the 'from' package but only if it is an intermediate + * package. The starting 'from' package should be kept, just + * as if deltas were not used. */ + if(dlts != delta_path) { + unlink(from); + } + } + FREE(from); + FREE(to); + FREE(delta); + + if(retval != 0) { + /* one delta failed for this package, cancel the remaining ones */ + EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_FAILED, NULL, NULL); + ret = 1; + break; } - } else { - EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_FAILED, NULL, NULL); - lastpkg_failed = 1; - ret = 1; } } @@ -792,7 +791,7 @@ static int test_md5sum(pmtrans_t *trans, const char *filename, int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) { alpm_list_t *i, *j, *files = NULL; - alpm_list_t *patches = NULL, *deltas = NULL; + alpm_list_t *deltas = NULL; pmtrans_t *tr = NULL; int replaces = 0; int errors = 0; @@ -828,21 +827,15 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) if(delta_path) { alpm_list_t *dlts = NULL; - for(dlts = delta_path; dlts; dlts = alpm_list_next(dlts)) { - pmdelta_t *d = (pmdelta_t *)alpm_list_getdata(dlts); - char *fpath2 = _alpm_filecache_find(d->delta); + for(dlts = delta_path; dlts; dlts = dlts->next) { + pmdelta_t *d = dlts->data; - if(!fpath2) { + if(d->download_size != 0) { /* add the delta filename to the download list if * it's not in the cache */ files = alpm_list_add(files, strdup(d->delta)); } - /* save the package and delta so that the xdelta patch - * command can be run after the downloads finish */ - patches = alpm_list_add(patches, spkg); - patches = alpm_list_add(patches, d); - /* keep a list of the delta files for md5sums */ deltas = alpm_list_add(deltas, d); } @@ -897,11 +890,9 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) /* Use the deltas to generate the packages */ EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); - ret = apply_deltas(trans, patches); + ret = apply_deltas(trans); EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); - alpm_list_free(patches); - patches = NULL; alpm_list_free(deltas); deltas = NULL; } -- cgit v1.2.3-70-g09d2