We have been using unsigned long as a file size type for a while, which works but isn't quite correct and could easily break. Worse was probably our use of int in the download callback functions, which could be restrictive for packages > 2GB in size. Switch all file size variables to use off_t, which is the preferred type for file sizes. Note that at least on Linux, all applications compiled against libalpm must now be sure to use large file support, where _FILE_OFFSET_BITS is defined to be 64 or there will be some weird issues that crop up. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/add.c | 12 ++++++++---- lib/libalpm/alpm.h | 14 ++++++++------ lib/libalpm/be_files.c | 6 +++--- lib/libalpm/delta.c | 10 +++++----- lib/libalpm/delta.h | 8 +++++--- lib/libalpm/dload.c | 6 +++--- lib/libalpm/graph.h | 4 +++- lib/libalpm/package.c | 4 ++-- lib/libalpm/package.h | 11 ++++++----- lib/libalpm/sync.c | 13 +++++++------ src/pacman/callback.c | 9 +++++---- src/pacman/callback.h | 4 +++- src/pacman/util.c | 2 +- 13 files changed, 59 insertions(+), 44 deletions(-) diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index c5454ba..9176e32 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -27,6 +27,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <inttypes.h> /* int64_t */ /* libarchive */ #include <archive.h> @@ -635,7 +636,6 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, int i, ret = 0, errors = 0; char scriptlet[PATH_MAX+1]; int is_upgrade = 0; - double percent = 0.0; pmpkg_t *oldpkg = NULL; ALPM_LOG_FUNC; @@ -730,17 +730,21 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, } for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) { + double percent; + if(newpkg->size != 0) { /* Using compressed size for calculations here, as newpkg->isize is not * exact when it comes to comparing to the ACTUAL uncompressed size * (missing metadata sizes) */ - unsigned long pos = archive_position_compressed(archive); + int64_t pos = archive_position_compressed(archive); percent = (double)pos / (double)newpkg->size; - _alpm_log(PM_LOG_DEBUG, "decompression progress: %f%% (%ld / %ld)\n", - percent*100.0, pos, newpkg->size); + _alpm_log(PM_LOG_DEBUG, "decompression progress: %f%% (%lld / %lld)\n", + percent*100.0, pos, (long long)newpkg->size); if(percent >= 1.0) { percent = 1.0; } + } else { + percent = 0.0; } if(is_upgrade) { diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 62a517b..fd3be0d 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -1,7 +1,7 @@ /* * alpm.h * - * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org> + * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org> @@ -26,6 +26,7 @@ extern "C" { #endif +#include <sys/types.h> /* for off_t */ #include <time.h> /* for time_t */ #include <stdarg.h> /* for va_list */ @@ -79,7 +80,8 @@ int alpm_logaction(char *fmt, ...); * Downloading */ -typedef void (*alpm_cb_download)(const char *filename, int xfered, int total); +typedef void (*alpm_cb_download)(const char *filename, + off_t xfered, off_t total); /* * Options @@ -201,8 +203,8 @@ time_t alpm_pkg_get_installdate(pmpkg_t *pkg); const char *alpm_pkg_get_packager(pmpkg_t *pkg); const char *alpm_pkg_get_md5sum(pmpkg_t *pkg); const char *alpm_pkg_get_arch(pmpkg_t *pkg); -unsigned long alpm_pkg_get_size(pmpkg_t *pkg); -unsigned long alpm_pkg_get_isize(pmpkg_t *pkg); +off_t alpm_pkg_get_size(pmpkg_t *pkg); +off_t alpm_pkg_get_isize(pmpkg_t *pkg); pmpkgreason_t alpm_pkg_get_reason(pmpkg_t *pkg); alpm_list_t *alpm_pkg_get_licenses(pmpkg_t *pkg); alpm_list_t *alpm_pkg_get_groups(pmpkg_t *pkg); @@ -221,7 +223,7 @@ size_t alpm_pkg_changelog_read(void *ptr, size_t size, int alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp); unsigned short alpm_pkg_has_scriptlet(pmpkg_t *pkg); -unsigned long alpm_pkg_download_size(pmpkg_t *newpkg); +off_t alpm_pkg_download_size(pmpkg_t *newpkg); /* * Deltas @@ -233,7 +235,7 @@ const char *alpm_delta_get_to(pmdelta_t *delta); const char *alpm_delta_get_to_md5sum(pmdelta_t *delta); const char *alpm_delta_get_filename(pmdelta_t *delta); const char *alpm_delta_get_md5sum(pmdelta_t *delta); -unsigned long alpm_delta_get_size(pmdelta_t *delta); +off_t alpm_delta_get_size(pmdelta_t *delta); /* * Groups diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c index 2302374..bb5a258 100644 --- a/lib/libalpm/be_files.c +++ b/lib/libalpm/be_files.c @@ -713,7 +713,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) if(info->size) { /* only write installed size, csize is irrelevant once installed */ fprintf(fp, "%%SIZE%%\n" - "%lu\n\n", info->isize); + "%llu\n\n", (long long)info->isize); } if(info->reason) { fprintf(fp, "%%REASON%%\n" @@ -722,11 +722,11 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) } else { if(info->size) { fprintf(fp, "%%CSIZE%%\n" - "%lu\n\n", info->size); + "%llu\n\n", (long long)info->size); } if(info->isize) { fprintf(fp, "%%ISIZE%%\n" - "%lu\n\n", info->isize); + "%llu\n\n", (long long)info->isize); } if(info->md5sum) { fprintf(fp, "%%MD5SUM%%\n" diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c index fdb4d99..babb5c6 100644 --- a/lib/libalpm/delta.c +++ b/lib/libalpm/delta.c @@ -71,7 +71,7 @@ const char SYMEXPORT *alpm_delta_get_md5sum(pmdelta_t *delta) return(delta->delta_md5); } -unsigned long SYMEXPORT alpm_delta_get_size(pmdelta_t *delta) +off_t SYMEXPORT alpm_delta_get_size(pmdelta_t *delta) { ASSERT(delta != NULL, return(-1)); return(delta->delta_size); @@ -139,7 +139,7 @@ static alpm_list_t *delta_graph_init(alpm_list_t *deltas) return(vertices); } -static unsigned long delta_vert(alpm_list_t *vertices, +static off_t delta_vert(alpm_list_t *vertices, const char *to, const char *to_md5, alpm_list_t **path) { alpm_list_t *i; pmgraph_t *v; @@ -178,7 +178,7 @@ static unsigned long delta_vert(alpm_list_t *vertices, } v = NULL; - unsigned long bestsize = 0; + off_t bestsize = 0; for(i = vertices; i; i = i->next) { pmgraph_t *v_i = i->data; @@ -216,12 +216,12 @@ static unsigned long delta_vert(alpm_list_t *vertices, * possible with the files available. * @return the size of the path stored, or ULONG_MAX if path is unfindable */ -unsigned long _alpm_shortest_delta_path(alpm_list_t *deltas, +off_t _alpm_shortest_delta_path(alpm_list_t *deltas, const char *to, const char *to_md5, alpm_list_t **path) { alpm_list_t *bestpath = NULL; alpm_list_t *vertices; - unsigned long bestsize = ULONG_MAX; + off_t bestsize = ULONG_MAX; ALPM_LOG_FUNC; diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h index 33d47e1..5bb86b9 100644 --- a/lib/libalpm/delta.h +++ b/lib/libalpm/delta.h @@ -19,6 +19,8 @@ #ifndef _ALPM_DELTA_H #define _ALPM_DELTA_H +#include <sys/types.h> /* off_t */ + #include "alpm.h" struct __pmdelta_t { @@ -35,14 +37,14 @@ struct __pmdelta_t { /** md5sum of the delta file */ char *delta_md5; /** filesize of the delta file */ - unsigned long delta_size; + off_t delta_size; /** download filesize of the delta file */ - unsigned long download_size; + off_t download_size; }; pmdelta_t *_alpm_delta_parse(char *line); void _alpm_delta_free(pmdelta_t *delta); -unsigned long _alpm_shortest_delta_path(alpm_list_t *deltas, +off_t _alpm_shortest_delta_path(alpm_list_t *deltas, const char *to, const char *to_md5, alpm_list_t **path); #endif /* _ALPM_DELTA_H */ diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 44acec7..b5f0b87 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -112,7 +112,7 @@ static int download_internal(const char *url, const char *localpath, struct url_stat ust; struct stat st; int chk_resume = 0; - int dl_thisfile = 0; + size_t dl_thisfile = 0; char *tempfile, *destfile, *filename; int ret = 0; struct url *fileurl = url_for_string(url); @@ -200,7 +200,7 @@ static int download_internal(const char *url, const char *localpath, handle->dlcb(filename, 0, ust.size); } - int nread = 0; + size_t nread = 0; char buffer[PM_DLBUF_LEN]; while((nread = fread(buffer, 1, PM_DLBUF_LEN, dlf)) > 0) { if(ferror(dlf)) { @@ -211,7 +211,7 @@ static int download_internal(const char *url, const char *localpath, goto cleanup; } - int nwritten = 0; + size_t nwritten = 0; while(nwritten < nread) { nwritten += fwrite(buffer, 1, (nread - nwritten), localf); if(ferror(localf)) { diff --git a/lib/libalpm/graph.h b/lib/libalpm/graph.h index 3078e25..72a7136 100644 --- a/lib/libalpm/graph.h +++ b/lib/libalpm/graph.h @@ -17,6 +17,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <sys/types.h> /* off_t */ + #include "alpm_list.h" #include "util.h" /* MALLOC() */ #include "alpm.h" @@ -24,7 +26,7 @@ struct __pmgraph_t { char state; /* 0: untouched, -1: entered, other: leaving time */ void *data; - unsigned long int weight; /* weight of the node */ + off_t weight; /* weight of the node */ struct __pmgraph_t *parent; /* where did we come from? */ alpm_list_t *children; alpm_list_t *childptr; /* points to a child in children list */ diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 685a411..3708a58 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -225,7 +225,7 @@ const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg) return pkg->arch; } -unsigned long SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg) +off_t SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg) { ALPM_LOG_FUNC; @@ -239,7 +239,7 @@ unsigned long SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg) return pkg->size; } -unsigned long SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg) +off_t SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg) { ALPM_LOG_FUNC; diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index ddf1d07..d06cf15 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -23,7 +23,8 @@ #ifndef _ALPM_PACKAGE_H #define _ALPM_PACKAGE_H -#include <time.h> +#include <sys/types.h> /* off_t */ +#include <time.h> /* time_t */ #include "alpm.h" #include "db.h" @@ -44,8 +45,9 @@ struct __pmpkg_t { char *packager; char *md5sum; char *arch; - unsigned long size; - unsigned long isize; + off_t size; + off_t isize; + off_t download_size; unsigned short scriptlet; unsigned short force; pmpkgreason_t reason; @@ -59,6 +61,7 @@ struct __pmpkg_t { alpm_list_t *conflicts; alpm_list_t *provides; alpm_list_t *deltas; + alpm_list_t *delta_path; /* internal */ pmpkgfrom_t origin; /* Replaced 'void *data' with this union as follows: @@ -70,8 +73,6 @@ struct __pmpkg_t { char *file; } origin_data; pmdbinfrq_t infolevel; - unsigned long download_size; - alpm_list_t *delta_path; }; pmpkg_t* _alpm_pkg_new(void); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 0d6a6ee..2dad8bf 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -22,6 +22,7 @@ #include "config.h" +#include <sys/types.h> /* off_t */ #include <stdlib.h> #include <stdio.h> #include <fcntl.h> @@ -385,7 +386,7 @@ static int compute_download_size(pmpkg_t *newpkg) { const char *fname; char *fpath; - unsigned long size = 0; + off_t size = 0; fname = alpm_pkg_get_filename(newpkg); ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1)); @@ -395,8 +396,8 @@ static int compute_download_size(pmpkg_t *newpkg) FREE(fpath); size = 0; } else if(handle->usedelta) { - unsigned long dltsize; - unsigned long pkgsize = alpm_pkg_get_size(newpkg); + off_t dltsize; + off_t pkgsize = alpm_pkg_get_size(newpkg); dltsize = _alpm_shortest_delta_path( alpm_pkg_get_deltas(newpkg), @@ -417,8 +418,8 @@ static int compute_download_size(pmpkg_t *newpkg) size = alpm_pkg_get_size(newpkg); } - _alpm_log(PM_LOG_DEBUG, "setting download size %ld for pkg %s\n", size, - alpm_pkg_get_name(newpkg)); + _alpm_log(PM_LOG_DEBUG, "setting download size %lld for pkg %s\n", + (long long)size, alpm_pkg_get_name(newpkg)); newpkg->download_size = size; return(0); @@ -670,7 +671,7 @@ cleanup: * @param newpkg the new package to upgrade to * @return the size of the download */ -unsigned long SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg) +off_t SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg) { return(newpkg->download_size); } diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 4c415e1..1942aef 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> #include <sys/time.h> +#include <sys/types.h> /* off_t */ #include <unistd.h> #include <dirent.h> #include <wchar.h> @@ -36,7 +37,7 @@ /* download progress bar */ static float rate_last; -static int xfered_last; +static off_t xfered_last; static struct timeval initial_time; /* transaction progress bar */ @@ -410,7 +411,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, } /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int xfered, int total) +void cb_dl_progress(const char *filename, off_t xfered, off_t total) { const int infolen = 50; const int filenamelen = infolen - 27; @@ -428,12 +429,12 @@ void cb_dl_progress(const char *filename, int xfered, int total) return; } - /* this is basically a switch on file_xferred: 0, file_total, and + /* this is basically a switch on xfered: 0, total, and * anything else */ if(xfered == 0) { /* set default starting values */ gettimeofday(&initial_time, NULL); - xfered_last = 0; + xfered_last = (off_t)0; rate_last = 0.0; timediff = get_update_timediff(1); } else if(xfered == total) { diff --git a/src/pacman/callback.h b/src/pacman/callback.h index 39d59d8..28d396e 100644 --- a/src/pacman/callback.h +++ b/src/pacman/callback.h @@ -19,6 +19,8 @@ #ifndef _PM_CALLBACK_H #define _PM_CALLBACK_H +#include <sys/types.h> /* off_t */ + #include <alpm.h> /* callback to handle messages/notifications from libalpm transactions */ @@ -33,7 +35,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, int howmany, int remain); /* callback to handle display of download progress */ -void cb_dl_progress(const char *filename, int file_xfered, int file_total); +void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total); /* callback to handle messages/notifications from pacman library */ void cb_log(pmloglevel_t level, char *fmt, va_list args); diff --git a/src/pacman/util.c b/src/pacman/util.c index 2e4ee86..e702886 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -493,7 +493,7 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local) const alpm_list_t *i, *j; alpm_list_t *targets = NULL, *to_remove = NULL; /* TODO these are some messy variable names */ - unsigned long isize = 0, rsize = 0, dispsize = 0, dlsize = 0; + off_t isize = 0, rsize = 0, dispsize = 0, dlsize = 0; double mbisize = 0.0, mbrsize = 0.0, mbdispsize = 0.0, mbdlsize = 0.0; for(i = syncpkgs; i; i = alpm_list_next(i)) { -- 1.5.5.3