From d080809c45af4ac7a393533316a9db38b9d51312 Mon Sep 17 00:00:00 2001
From: Aaron Griffin <aaron@archlinux.org>
Date: Sat, 10 Feb 2007 23:44:39 +0000
Subject: * Package file parsing - fixed size and isize - isize is the "size"
 variable   from the PKGINFO, and size is the stat() size of the archive *
 Removed the useless 'output' param from package.c:parse_descfile *
 Installation progress   - Call progress callback once at 0% for
 initialization   - 'needdisp' was useless   - alpm_list_count is called an
 excessive amount in these nested loops.  Now we     only call it once per
 iteration   - Use the compressed sizes for PROGRESS calcs as uncompressed
 (isize) is not     exact (it is missing metadata sizes), and thus produces >
 100% numbers

---
 lib/libalpm/add.c     | 41 +++++++++++++++++++++++------------------
 lib/libalpm/package.c | 26 +++++++++++++-------------
 2 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index cad5ae13..d7a4a5ca 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -351,8 +351,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
 
 int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
 {
-	int i, ret = 0, errors = 0, needdisp = 0;
-	double percent = 0.0;
+	int i, ret = 0, errors = 0, pkg_count = 0;
 	register struct archive *archive;
 	struct archive_entry *entry;
 	char expath[PATH_MAX], cwd[PATH_MAX] = "", *what;
@@ -369,7 +368,11 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
 		return(0);
 	}
 
+	pkg_count = alpm_list_count(trans->targets);
+	
 	for(targ = trans->packages; targ; targ = targ->next) {
+		int targ_count = 0;
+		double percent = 0.0;
 		unsigned short pmo_upgrade;
 		char pm_install[PATH_MAX];
 		pmpkg_t *info = (pmpkg_t *)targ->data;
@@ -468,13 +471,14 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
 			_alpm_log(PM_LOG_DEBUG, _("extracting files"));
 
 			/* Extract the package */
-			if ((archive = archive_read_new ()) == NULL)
+			if ((archive = archive_read_new()) == NULL) {
 				RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1);
+			}
 
-			archive_read_support_compression_all (archive);
-			archive_read_support_format_all (archive);
+			archive_read_support_compression_all(archive);
+			archive_read_support_format_all(archive);
 
-			if (archive_read_open_file (archive, info->data, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
+			if(archive_read_open_file(archive, info->data, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
 				RET_ERR(PM_ERR_PKG_OPEN, -1);
 			}
 
@@ -488,6 +492,10 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
 			/* libarchive requires this for extracting hard links */
 			chdir(handle->root);
 
+			targ_count = alpm_list_count(targ);
+			/* call PROGRESS once with 0 percent, as we sort-of skip that here */
+			PROGRESS(trans, cb_state, what, 0, pkg_count, (pkg_count - targ_count +1));
+
 			for(i = 0; archive_read_next_header (archive, &entry) == ARCHIVE_OK; i++) {
 				int nb = 0;
 				int notouch = 0;
@@ -498,21 +506,19 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
 
 				STRNCPY(pathname, archive_entry_pathname(entry), PATH_MAX);
 
-				if (info->size != 0) {
-					/* There's a problem here.  These sizes don't match up.  info->size is
-					 * the COMPRESSED size, and info->isize is uncompressed.  It appears,
-					 * however, that these are the only two sizes available.  It appears
-					 * to be close enough, BUT easilly goes over 100%, so we'll stall
-					 * there for now */
-					percent = (double)archive_position_uncompressed(archive) / info->size;
+				if(info->size != 0) {
+					/* Using compressed size for calculations here, as info->isize is not
+					 * exact when it comes to comparing to the ACTUAL uncompressed size
+					 * (missing metadata sizes) */
+					unsigned long pos = archive_position_compressed(archive);
+					percent = (double)pos / (double)info->size;
+					_alpm_log(PM_LOG_DEBUG, "decompression progress: %f%% (%ld / %ld)", percent*100.0, pos, info->size);
 					if(percent >= 1.0) {
 						percent = 1.0;
 					}
 				}
 				
-				if (needdisp == 0) {
-					PROGRESS(trans, cb_state, what, (int)(percent * 100), alpm_list_count(trans->packages), (alpm_list_count(trans->packages) - alpm_list_count(targ) +1));
-				}
+				PROGRESS(trans, cb_state, what, (int)(percent * 100), pkg_count, (pkg_count - targ_count +1));
 
 				if(strcmp(pathname, ".PKGINFO") == 0 || strcmp(pathname, ".FILELIST") == 0) {
 					archive_read_data_skip (archive);
@@ -855,8 +861,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
 			}
 		}
 
-		PROGRESS(trans, cb_state, what, 100, alpm_list_count(trans->packages), (alpm_list_count(trans->packages) - alpm_list_count(targ) +1));
-		needdisp = 0;
+		PROGRESS(trans, cb_state, what, 100, pkg_count, (pkg_count - targ_count +1));
 		EVENT(trans, PM_TRANS_EVT_EXTRACT_DONE, NULL, NULL);
 		FREE(what);
 
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index efc2345a..7ac2ca8e 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -30,6 +30,9 @@
 #include <libintl.h>
 #include <locale.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 /* pacman */
 #include "package.h"
 #include "log.h"
@@ -177,7 +180,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2)
  * Returns: 0 on success, 1 on error
  *
  */
-static int parse_descfile(char *descfile, pmpkg_t *info, int output)
+static int parse_descfile(char *descfile, pmpkg_t *info)
 {
 	FILE* fp = NULL;
 	char line[PATH_MAX];
@@ -199,14 +202,11 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
 		if(strlen(line) == 0 || line[0] == '#') {
 			continue;
 		}
-		if(output) {
-			_alpm_log(PM_LOG_DEBUG, "%s", line);
-		}
 		ptr = line;
 		key = strsep(&ptr, "=");
 		if(key == NULL || ptr == NULL) {
 			_alpm_log(PM_LOG_DEBUG, _("%s: syntax error in description file line %d"),
-				info->name[0] != '\0' ? info->name : "error", linenum);
+								info->name[0] != '\0' ? info->name : "error", linenum);
 		} else {
 			_alpm_strtrim(key);
 			key = _alpm_strtoupper(key);
@@ -245,12 +245,7 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
 			} else if(!strcmp(key, "ARCH")) {
 				STRNCPY(info->arch, ptr, sizeof(info->arch));
 			} else if(!strcmp(key, "SIZE")) {
-				char tmp[32];
-				STRNCPY(tmp, ptr, sizeof(tmp));
-				info->size = atol(ptr);
-			} else if(!strcmp(key, "ISIZE")) {
-				char tmp[32];
-				STRNCPY(tmp, ptr, sizeof(tmp));
+				/* size in the raw package is uncompressed (installed) size */
 				info->isize = atol(ptr);
 			} else if(!strcmp(key, "DEPEND")) {
 				info->depends = alpm_list_add(info->depends, strdup(ptr));
@@ -266,7 +261,7 @@ static int parse_descfile(char *descfile, pmpkg_t *info, int output)
 				info->backup = alpm_list_add(info->backup, strdup(ptr));
 			} else {
 				_alpm_log(PM_LOG_DEBUG, _("%s: syntax error in description file line %d"),
-					info->name[0] != '\0' ? info->name : "error", linenum);
+									info->name[0] != '\0' ? info->name : "error", linenum);
 			}
 		}
 		line[0] = '\0';
@@ -290,6 +285,7 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
 	char *descfile = NULL;
 	int fd = -1;
 	alpm_list_t *all_files = NULL;
+	struct stat st;
 
 	ALPM_LOG_FUNC;
 
@@ -314,6 +310,10 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
 		RET_ERR(PM_ERR_MEMORY, NULL);
 	}
 
+  if(stat(pkgfile, &st) == 0) {
+		info->size = st.st_size;
+	}
+
 	/* TODO there is no reason to make temp files to read
 	 * from a libarchive archive, it can be done by reading
 	 * directly from the archive
@@ -333,7 +333,7 @@ pmpkg_t *_alpm_pkg_load(char *pkgfile)
 			fd = mkstemp(descfile);
 			archive_read_data_into_fd (archive, fd);
 			/* parse the info file */
-			if(parse_descfile(descfile, info, 0) == -1) {
+			if(parse_descfile(descfile, info) == -1) {
 				_alpm_log(PM_LOG_ERROR, _("could not parse the package description file"));
 				goto pkg_invalid;
 			}
-- 
cgit v1.2.3-70-g09d2