diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt index fa212947..2f1fe3df 100644 --- a/doc/pacman.conf.5.txt +++ b/doc/pacman.conf.5.txt @@ -144,7 +144,7 @@ Options *UseDelta*:: Download delta files instead of complete packages if possible. Requires - the xdelta program to be installed. + the xdelta3 program to be installed. *TotalDownload*:: When downloading, display the amount downloaded, download rate, ETA, diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c index 9e4bcb42..de5dd601 100644 --- a/lib/libalpm/delta.c +++ b/lib/libalpm/delta.c @@ -21,6 +21,7 @@ #include #include +#include /* intmax_t */ #include #include #include @@ -215,13 +216,13 @@ off_t _alpm_shortest_delta_path(alpm_list_t *deltas, return(bestsize); } - _alpm_log(PM_LOG_DEBUG, "started delta shortest-path search\n"); + _alpm_log(PM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to); vertices = delta_graph_init(deltas); bestsize = delta_vert(vertices, to, &bestpath); - _alpm_log(PM_LOG_DEBUG, "delta shortest-path search complete\n"); + _alpm_log(PM_LOG_DEBUG, "delta shortest-path search complete : '%jd'\n", (intmax_t)bestsize); alpm_list_free_inner(vertices, _alpm_graph_free); alpm_list_free(vertices); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index fca96d8f..49ea3c27 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -27,6 +27,7 @@ #include #include #include +#include /* intmax_t */ #include #include #include @@ -387,8 +388,8 @@ static int compute_download_size(pmpkg_t *newpkg) size = alpm_pkg_get_size(newpkg); } - _alpm_log(PM_LOG_DEBUG, "setting download size %lld for pkg %s\n", - (long long)size, alpm_pkg_get_name(newpkg)); + _alpm_log(PM_LOG_DEBUG, "setting download size %jd for pkg %s\n", + (intmax_t)size, alpm_pkg_get_name(newpkg)); newpkg->download_size = size; return(0); @@ -679,6 +680,12 @@ off_t SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg) return(newpkg->download_size); } +static int endswith(char *filename, char *extension) +{ + char *s = filename + strlen(filename) - strlen(extension); + return (strcmp(s, extension) == 0); +} + /** Applies delta files to create an upgraded package file. * * All intermediate files are deleted, leaving only the starting and @@ -724,16 +731,18 @@ static int apply_deltas(pmtrans_t *trans) 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 /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); + /* compression command */ + char *compress = "cat"; + if(endswith(to, ".gz")) { + compress = "gzip -n"; + } else if(endswith(to, ".bz2")) { + compress = "bzip"; + } + /* -R for disabling external recompression, -c for sending to stdout */ + snprintf(command, PATH_MAX, "xdelta3 -d -q -R -c -s %s %s | %s > %s", from, delta, compress, to); - _alpm_log(PM_LOG_DEBUG, _("command: %s\n"), command); + _alpm_log(PM_LOG_DEBUG, "command: %s\n", command); EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_START, d->to, d->delta); @@ -847,29 +856,31 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) fname = alpm_pkg_get_filename(spkg); ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1)); - if(spkg->download_size != 0) { - alpm_list_t *delta_path = spkg->delta_path; - if(delta_path) { - alpm_list_t *dlts = NULL; + alpm_list_t *delta_path = spkg->delta_path; + if(delta_path) { + /* using deltas */ + alpm_list_t *dlts = NULL; - for(dlts = delta_path; dlts; dlts = dlts->next) { - pmdelta_t *d = dlts->data; + for(dlts = delta_path; dlts; dlts = dlts->next) { + pmdelta_t *d = dlts->data; - 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)); - } - - /* keep a list of the delta files for md5sums */ - deltas = alpm_list_add(deltas, d); + if(d->download_size != 0) { + /* add the delta filename to the download list if needed */ + files = alpm_list_add(files, strdup(d->delta)); } - } else { - /* not using deltas, so add the file to the download list */ + /* keep a list of all the delta files for md5sums */ + deltas = alpm_list_add(deltas, d); + } + + } else { + /* not using deltas */ + if(spkg->download_size != 0) { + /* add the filename to the download list if needed */ files = alpm_list_add(files, strdup(fname)); } } + } } @@ -890,37 +901,34 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) handle->totaldlcb(0); } - if(handle->usedelta) { + /* if we have deltas to work with */ + if(handle->usedelta && deltas) { int ret = 0; + errors = 0; + /* Check integrity of deltas */ + EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); - /* only output if there are deltas to work with */ - if(deltas) { - errors = 0; - /* Check integrity of deltas */ - EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); + for(i = deltas; i; i = i->next) { + pmdelta_t *d = alpm_list_getdata(i); + const char *filename = alpm_delta_get_filename(d); + const char *md5sum = alpm_delta_get_md5sum(d); - for(i = deltas; i; i = i->next) { - pmdelta_t *d = alpm_list_getdata(i); - const char *filename = alpm_delta_get_filename(d); - const char *md5sum = alpm_delta_get_md5sum(d); - - if(test_md5sum(trans, filename, md5sum) != 0) { - errors++; - *data = alpm_list_add(*data, strdup(filename)); - } + if(test_md5sum(trans, filename, md5sum) != 0) { + errors++; + *data = alpm_list_add(*data, strdup(filename)); } - if(errors) { - pm_errno = PM_ERR_DLT_INVALID; - goto error; - } - EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); - - /* Use the deltas to generate the packages */ - EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); - ret = apply_deltas(trans); - EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); - } + if(errors) { + pm_errno = PM_ERR_DLT_INVALID; + goto error; + } + EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); + + /* Use the deltas to generate the packages */ + EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); + ret = apply_deltas(trans); + EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); + if(ret) { pm_errno = PM_ERR_DLT_PATCHFAILED; goto error; diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 0aa8a9b1..a41b0695 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -963,25 +963,34 @@ create_package() { # tar it up msg2 "$(gettext "Compressing package...")" - local TAR_OPT case "$PKGEXT" in - *tar.gz) TAR_OPT="z" ;; - *tar.bz2) TAR_OPT="j" ;; + *tar.gz) EXT=${PKGEXT%.gz} ;; + *tar.bz2) EXT=${PKGEXT%.bz2} ;; *) warning "$(gettext "'%s' is not a valid archive extension.")" \ - "$PKGEXT" ;; + "$PKGEXT" ; EXT=$PKGEXT ;; esac + local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${CARCH}${EXT}" - local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" + local ret=0 # when fileglobbing, we want * in an empty directory to expand to # the null string rather than itself shopt -s nullglob + bsdtar -cf - $comp_files * > "$pkg_file" || ret=$? + shopt -u nullglob - if ! bsdtar -c${TAR_OPT}f "$pkg_file" $comp_files *; then + if [ $ret -eq 0 ]; then + case "$PKGEXT" in + *tar.gz) gzip -f -n "$pkg_file" ;; + *tar.bz2) bzip2 -f "$pkg_file" ;; + esac + ret=$? + fi + + if [ $ret -ne 0 ]; then error "$(gettext "Failed to create package file.")" exit 1 # TODO: error code fi - shopt -u nullglob } create_srcpackage() {