[pacman-dev] [PATCH] Use correct C type for file sizes

Dan McGee dan at archlinux.org
Sun Jun 1 22:50:39 EDT 2008


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 at 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 at zeroflux.org>
+ *  Copyright (c) 2002-2008 by Judd Vinet <jvinet at zeroflux.org>
  *  Copyright (c) 2005 by Aurelien Foret <orelien at chez.com>
  *  Copyright (c) 2005 by Christian Hamar <krics at linuxforum.hu>
  *  Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos at 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





More information about the pacman-dev mailing list