From feb9889f22639c214606dcb387af6d0a51ea5e85 Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Fri, 8 Oct 2010 08:39:23 -0500
Subject: Add epoch support to pacman/libalpm

This will allow for better control of what was previously the 'force' option
in a PKGBUILD and transferred into the built package.

Signed-off-by: Dan McGee <dan@archlinux.org>
---
 lib/libalpm/alpm.h       |  2 +-
 lib/libalpm/be_local.c   | 22 ++++++++++++++++------
 lib/libalpm/be_package.c |  2 ++
 lib/libalpm/be_sync.c    | 11 ++++++++++-
 lib/libalpm/package.c    | 28 ++++++++++++++++------------
 lib/libalpm/package.h    |  4 ++--
 6 files changed, 47 insertions(+), 22 deletions(-)

(limited to 'lib')

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 0c01f214..3dea6be9 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -235,7 +235,7 @@ size_t alpm_pkg_changelog_read(void *ptr, size_t size,
 /*int alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp);*/
 int alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp);
 int alpm_pkg_has_scriptlet(pmpkg_t *pkg);
-int alpm_pkg_has_force(pmpkg_t *pkg);
+int alpm_pkg_get_epoch(pmpkg_t *pkg);
 
 off_t alpm_pkg_download_size(pmpkg_t *newpkg);
 alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg);
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index 76a14df3..22127520 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -157,10 +157,10 @@ alpm_list_t *_cache_get_groups(pmpkg_t *pkg)
 	return pkg->groups;
 }
 
-int _cache_has_force(pmpkg_t *pkg)
+int _cache_get_epoch(pmpkg_t *pkg)
 {
 	LAZY_LOAD(INFRQ_DESC, -1);
-	return pkg->force;
+	return pkg->epoch;
 }
 
 alpm_list_t *_cache_get_depends(pmpkg_t *pkg)
@@ -301,7 +301,7 @@ static struct pkg_operations local_pkg_ops = {
 	.get_size        = _cache_get_size,
 	.get_isize       = _cache_get_isize,
 	.get_reason      = _cache_get_reason,
-	.has_force       = _cache_has_force,
+	.get_epoch       = _cache_get_epoch,
 	.get_licenses    = _cache_get_licenses,
 	.get_groups      = _cache_get_groups,
 	.get_depends     = _cache_get_depends,
@@ -603,8 +603,17 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 					STRDUP(linedup, _alpm_strtrim(line), goto error);
 					info->replaces = alpm_list_add(info->replaces, linedup);
 				}
+			} else if(strcmp(line, "%EPOCH%") == 0) {
+				if(fgets(line, sizeof(line), fp) == NULL) {
+					goto error;
+				}
+				info->epoch = atoi(_alpm_strtrim(line));
 			} else if(strcmp(line, "%FORCE%") == 0) {
-				info->force = 1;
+				/* For backward compatibility, treat force as a non-zero epoch
+				 * but only if we didn't already have a known epoch value. */
+				if(!info->epoch) {
+					info->epoch = 1;
+				}
 			}
 		}
 		fclose(fp);
@@ -779,8 +788,9 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 			}
 			fprintf(fp, "\n");
 		}
-		if(info->force) {
-			fprintf(fp, "%%FORCE%%\n\n");
+		if(info->epoch) {
+			fprintf(fp, "%%EPOCH%%\n"
+							"%d\n\n", info->epoch);
 		}
 		if(info->url) {
 			fprintf(fp, "%%URL%%\n"
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 4a8624e5..ddcad596 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -184,6 +184,8 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg)
 				STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1));
 			} else if(strcmp(key, "pkgdesc") == 0) {
 				STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1));
+			} else if(strcmp(key, "epoch") == 0) {
+				newpkg->epoch = atoi(ptr);
 			} else if(strcmp(key, "group") == 0) {
 				newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr));
 			} else if(strcmp(key, "url") == 0) {
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 414a9f37..e1c76638 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -345,8 +345,17 @@ int _alpm_sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entry
 					STRDUP(linedup, _alpm_strtrim(line), goto error);
 					pkg->replaces = alpm_list_add(pkg->replaces, linedup);
 				}
+			} else if(strcmp(line, "%EPOCH%") == 0) {
+				if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
+					goto error;
+				}
+				pkg->epoch = atoi(_alpm_strtrim(line));
 			} else if(strcmp(line, "%FORCE%") == 0) {
-				pkg->force = 1;
+				/* For backward compatibility, treat force as a non-zero epoch
+				 * but only if we didn't already have a known epoch value. */
+				if(!pkg->epoch) {
+					pkg->epoch = 1;
+				}
 			}
 		}
 	} else if(strcmp(filename, "depends") == 0) {
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 27ffc918..f4322bf1 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -111,7 +111,7 @@ const char *_pkg_get_arch(pmpkg_t *pkg)        { return pkg->arch; }
 off_t _pkg_get_size(pmpkg_t *pkg)              { return pkg->size; }
 off_t _pkg_get_isize(pmpkg_t *pkg)             { return pkg->isize; }
 pmpkgreason_t _pkg_get_reason(pmpkg_t *pkg)    { return pkg->reason; }
-int _pkg_has_force(pmpkg_t *pkg)               { return pkg->force; }
+int _pkg_get_epoch(pmpkg_t *pkg)               { return pkg->epoch; }
 
 alpm_list_t *_pkg_get_licenses(pmpkg_t *pkg)   { return pkg->licenses; }
 alpm_list_t *_pkg_get_groups(pmpkg_t *pkg)     { return pkg->groups; }
@@ -141,7 +141,7 @@ struct pkg_operations default_pkg_ops = {
 	.get_size        = _pkg_get_size,
 	.get_isize       = _pkg_get_isize,
 	.get_reason      = _pkg_get_reason,
-	.has_force       = _pkg_has_force,
+	.get_epoch       = _pkg_get_epoch,
 	.get_licenses    = _pkg_get_licenses,
 	.get_groups      = _pkg_get_groups,
 	.get_depends     = _pkg_get_depends,
@@ -222,9 +222,9 @@ pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg)
 	return pkg->ops->get_reason(pkg);
 }
 
-int SYMEXPORT alpm_pkg_has_force(pmpkg_t *pkg)
+int SYMEXPORT alpm_pkg_get_epoch(pmpkg_t *pkg)
 {
-	return pkg->ops->has_force(pkg);
+	return pkg->ops->get_epoch(pkg);
 }
 
 alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg)
@@ -435,7 +435,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
 	newpkg->size = pkg->size;
 	newpkg->isize = pkg->isize;
 	newpkg->scriptlet = pkg->scriptlet;
-	newpkg->force = pkg->force;
+	newpkg->epoch = pkg->epoch;
 	newpkg->reason = pkg->reason;
 
 	newpkg->licenses   = alpm_list_strdup(pkg->licenses);
@@ -523,21 +523,25 @@ void _alpm_pkg_free_trans(pmpkg_t *pkg)
 	pkg->removes = NULL;
 }
 
-/* Is spkg an upgrade for locapkg? */
+/* Is spkg an upgrade for localpkg? */
 int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg)
 {
-	int cmp = 0;
+	int spkg_epoch, localpkg_epoch;
 
 	ALPM_LOG_FUNC;
 
-	cmp = alpm_pkg_vercmp(alpm_pkg_get_version(spkg),
-			alpm_pkg_get_version(localpkg));
+	spkg_epoch = alpm_pkg_get_epoch(spkg);
+	localpkg_epoch = alpm_pkg_get_epoch(localpkg);
 
-	if(cmp < 0 && alpm_pkg_has_force(spkg)) {
-		cmp = 1;
+	if(spkg_epoch > localpkg_epoch) {
+		return(1);
+	} else if(spkg_epoch < localpkg_epoch) {
+		return(-1);
 	}
 
-	return(cmp);
+	/* equal epoch values, move on to version comparison */
+	return alpm_pkg_vercmp(alpm_pkg_get_version(spkg),
+			alpm_pkg_get_version(localpkg));
 }
 
 /* Helper function for comparing packages
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index 5ad553ac..77f8f8fd 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -57,7 +57,7 @@ struct pkg_operations {
 	off_t (*get_size) (pmpkg_t *);
 	off_t (*get_isize) (pmpkg_t *);
 	pmpkgreason_t (*get_reason) (pmpkg_t *);
-	int (*has_force) (pmpkg_t *);
+	int (*get_epoch) (pmpkg_t *);
 
 	alpm_list_t *(*get_licenses) (pmpkg_t *);
 	alpm_list_t *(*get_groups) (pmpkg_t *);
@@ -105,7 +105,7 @@ struct __pmpkg_t {
 	off_t isize;
 	off_t download_size;
 	int scriptlet;
-	int force;
+	int epoch;
 	pmpkgreason_t reason;
 	alpm_list_t *licenses;
 	alpm_list_t *replaces;
-- 
cgit v1.2.3-70-g09d2