PERFORCE change 181156 for review

Ivan Voras ivoras at FreeBSD.org
Sun Jul 18 23:55:19 UTC 2010


http://p4web.freebsd.org/@@181156?ac=10

Change 181156 by ivoras at betelgeuse on 2010/07/18 23:55:00

	Sort the patches by dependencies (if there are inter-patch dependanices)
	and apply them.

Affected files ...

.. //depot/projects/soc2010/pkg_patch/src/patch/Makefile#28 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.c#18 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.h#18 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#27 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#27 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/main.c#28 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#26 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#26 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.c#11 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.h#10 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#26 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/support.c#25 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/updateweb.c#6 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/updateweb.h#6 edit

Differences ...

==== //depot/projects/soc2010/pkg_patch/src/patch/Makefile#28 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/applypatch.c#18 (text+ko) ====

@@ -275,6 +275,7 @@
 	FILE **fpvect;
 	unsigned int err_count, n_patched_files, i;
 	
+	baton_twirl();
 	if (realpath(file_patch, fpatch) == NULL)
 		err(1, "Error resolving path: %s", file_patch);
 	if (access(fpatch, F_OK) != 0)
@@ -325,6 +326,9 @@
 	if (read_package_contents_file(tmp, &pkg_new) != 0)
 		err(1, "Cannot read package information from %s", tmp);
 	
+	/* Check for conflicts from the new package */
+	check_conflicts(&pkg_new, NULL);
+	
 	/* Step 3 - verify that the live system and the patch file agree */
 	if (Verbose > 1)
 		printf("Verifying live system and patch data consistency...\n");
@@ -379,6 +383,7 @@
 	if (err_count != 0)
 		errx(1, "Found %u errors. Cannot continue.", err_count);
 	
+	baton_twirl();
 	/* Step 4 - backup the existing package */
 	if (pkg_backup(pp.source, backup_pkg) != 0)
 		err(1, "Cannot backup package: %s", pp.source);
@@ -394,6 +399,7 @@
 	STAILQ_FOREACH(pl, &pp.pp_patch, linkage) {
 		char newfile[PATH_MAX], patchfile[PATH_MAX];
 	 	
+		baton_twirl();
 		if (pl->filename[0] == '+')
 			continue;
 		if (pkg_to_live_filename(tmp, pl->filename, &pkg_live,
@@ -459,6 +465,7 @@
 			    tmp, newfile);
 			goto error_cleanup;
 		}
+		baton_twirl();
 	}
 	/* All is well, we can rename() the new files to the live ones. */
 	STAILQ_FOREACH(pl, &pp.pp_patch, linkage) {
@@ -491,6 +498,7 @@
 			goto error_cleanup;
 		}
 	}
+	baton_twirl();
 	STAILQ_FOREACH(pl, &pp.pp_remove, linkage) {
 		if (pkg_to_live_filename(tmp, pl->filename, &pkg_live,
 		    "pp_remove2") != 0) {

==== //depot/projects/soc2010/pkg_patch/src/patch/applypatch.h#18 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#27 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#27 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/main.c#28 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#26 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#26 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.c#11 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.h#10 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#26 (text+ko) ====

@@ -155,5 +155,6 @@
 char *time_ctime(time_t t);
 void baton_twirl(void);
 Package *pkg_read_plist(char *pfilename);
+int check_conflicts(Package *pnew, char **pkglist);
 
 #endif

==== //depot/projects/soc2010/pkg_patch/src/patch/support.c#25 (text+ko) ====

@@ -676,6 +676,7 @@
 				if (fwrite(buf, 1, bs, fplist) != bs)
 					err(1, "Cannot extract plist");
 		}
+		free(buf);
 		fseek(fplist, 0, 0);
 		pkg = calloc(1, sizeof(*pkg));
 		read_plist(pkg, fplist);
@@ -685,3 +686,35 @@
 	archive_read_finish(arc);
 	return (pkg);
 }
+
+
+/* Check for conflicts from metadata in the new package to recorded packages */
+int
+check_conflicts(Package *pnew, char **pkglist)
+{
+	int er, i;
+	PackingList pl;
+	
+	if (pkglist == NULL) {
+		pkglist = matchinstalled(MATCH_ALL, NULL, &er);
+		if (pkglist == NULL || er != 0) {
+			warnx("Cannot fetch a list of installed packages "
+			    "(matchinstalled(MATCH_ALL...))");
+			return (-1);
+		}
+	}
+	pl = pnew->head;
+	while (pl != NULL) {
+		if (pl->type == PLIST_CONFLICTS) {
+			for (i = 0; pkglist[i] != NULL; i++) {
+				if (strncmp(pl->name, pkglist[i], PKGNAME_MAX)
+				    == 0)
+					return (i); /* It's ok, cannot be 0 */
+			}
+		}
+		pl = pl->next;
+	}
+	/* XXX: When libpkg grows a storefree() API, use it to free pkglist
+	 * if needed. */
+	return (0);
+}

==== //depot/projects/soc2010/pkg_patch/src/patch/updateweb.c#6 (text+ko) ====

@@ -32,18 +32,20 @@
 #include <pkg.h>
 #include "pkg_patch.h"
 #include "updateweb.h"
+#include "applypatch.h"
 #include "hashjob.h"
 
 
-STAILQ_HEAD(patchrec_list, patchrec);
+TAILQ_HEAD(patchrec_list, patchrec);
 struct patchrec {
 	char 	source[PKGNAME_MAX];
 	char 	target[PKGNAME_MAX];
 	char 	patch_name[PATH_MAX];
 	time_t 	patch_timestamp;
+	Package *plist;
 	Boolean	match;
-	Package *plist;
-	STAILQ_ENTRY(patchrec)	linkage;
+	Boolean found_deps;
+	TAILQ_ENTRY(patchrec)	linkage;
 };
 
 static int
@@ -106,7 +108,7 @@
 			strncpy(pr->target, tgt, PKGNAME_MAX);
 			strncpy(pr->patch_name, patch, PATH_MAX);
 			pr->patch_timestamp = iso8601_to_time(tstamp);
-			STAILQ_INSERT_TAIL(prlist, pr, linkage);
+			TAILQ_INSERT_TAIL(prlist, pr, linkage);
 		}
 	}
 	fclose(f);
@@ -163,7 +165,7 @@
 	struct patchrec_list prlist;
 	struct patchrec *pr;
 	char **instpkg;
-	int er, i, pcount = 0;
+	int er, i, pcount = 0, scount;
 	
 	if (in_url == NULL)
 		in_url = PKGPATCH_SITE_URL;
@@ -205,11 +207,11 @@
 		if (Verbose > 2)
 			printf("Decompressed index to: %s\n", local_index);
 	}
-	STAILQ_INIT(&prlist);
+	TAILQ_INIT(&prlist);
 	if (read_pkgpatchindex_file(&prlist, local_index) != 0)
 		err(1, "Cannot read pkgpatchindex: %s", local_index);
 	if (Verbose > 2)
-		STAILQ_FOREACH(pr, &prlist, linkage)
+		TAILQ_FOREACH(pr, &prlist, linkage)
 			printf("Available: %s to %s via %s\n", pr->source,
 			    pr->target, pr->patch_name);
 	
@@ -219,7 +221,7 @@
 	for (i = 0; instpkg[i] != NULL; i++) {
 		if (Verbose > 2)
 			printf("Installed: %s\n", instpkg[i]);
-		STAILQ_FOREACH(pr, &prlist, linkage)
+		TAILQ_FOREACH(pr, &prlist, linkage)
 			if (strncmp(instpkg[i], pr->source, PKGNAME_MAX) == 0) {
 				pr->match = TRUE;
 				pcount++;
@@ -234,7 +236,7 @@
 	/* Show this information even if we're in non-verbose mode, it's
 	 * important! */
 	printf("Patch candidates:\n");
-	STAILQ_FOREACH(pr, &prlist, linkage) {
+	TAILQ_FOREACH(pr, &prlist, linkage) {
 		if (pr->match)
 			printf("%s\t", pr->source);
 	}
@@ -247,7 +249,7 @@
 	/* Ok now, fetch the patches */
 	if (Verbose)
 		printf("Downloading: ");
-	STAILQ_FOREACH(pr, &prlist, linkage) {
+	TAILQ_FOREACH(pr, &prlist, linkage) {
 		char local_file[PATH_MAX], remote_file[PATH_MAX];
 		
 		if (pr->match) {
@@ -268,8 +270,8 @@
 	if (Verbose)
 		printf(".\n");
 	
-	/* Sort the package patches by dependancies */
-	STAILQ_FOREACH(pr, &prlist, linkage) {
+	/* Read the package patches' plists */
+	TAILQ_FOREACH(pr, &prlist, linkage) {
 		char local_file[PATH_MAX];
 		
 		if (!pr->match)
@@ -280,5 +282,84 @@
 		pr->plist = pkg_read_plist(local_file);
 		if (pr->plist == NULL)
 			err(1, "Cannot read %s file", CONTENTS_FNAME);
+		er = check_conflicts(pr->plist, instpkg);
+		if (er != 0) {
+			if (er < 0)
+				err(1, "Error processing package conflicts");
+			else if (er > 0)
+				errx(1, "Package %s conflicts with %s",
+				    pr->source, instpkg[er]);
+		}
+	}
+	
+	
+	scount = 1;
+	while (scount != 0) {
+		int ndeps = 0, ndeps_found = 0;
+		PackingList pl;
+		
+		scount = 0;
+		/* Sort the package patches by dependancies */
+		TAILQ_FOREACH(pr, &prlist, linkage) {
+			struct patchrec *pr2 = NULL;
+			int foundit = FALSE;
+			
+			if (!pr->match)
+				continue;
+			pl = pr->plist->head;
+			while (pl != NULL) {
+				if (pl->type != PLIST_PKGDEP)
+					continue;
+				ndeps++;
+				/* Search deps in installed live packages */
+				for (i = 0; instpkg[i] != NULL; i++)
+					if (strncmp(pl->name, instpkg[i],
+					    PKGNAME_MAX) == 0) {
+						ndeps_found++;
+						foundit = TRUE;
+						break;
+					}
+				if (foundit) {
+					pl = pl->next;
+					continue;
+				}
+				TAILQ_FOREACH(pr2, &prlist, linkage) {
+					if (strncmp(pl->name, pr2->target,
+					    PKGNAME_MAX) == 0) {
+						ndeps_found++;
+						foundit = TRUE;
+						break;
+					}
+				}
+				if (!foundit) {
+					printf("Cannot resolve dependancy "
+					    "%s -> %s\n", pr->target, pl->name);
+					pl = pl->next;
+					continue;
+				}
+				/* Reshuffle the found (depended-on) package to
+				 * the front. */
+				assert(pr2 != NULL);
+				TAILQ_REMOVE(&prlist, pr2, linkage);
+				TAILQ_INSERT_HEAD(&prlist, pr2, linkage);
+				scount++;
+				pl = pl->next;
+			}
+		}
+		if (ndeps != ndeps_found)
+			errx(1, "Cannot satisfy %d dependancies", ndeps -
+			    ndeps_found);
+	}
+	
+	/* Ok, apply the gathered patches now */
+	TAILQ_FOREACH(pr, &prlist, linkage) {
+		char local_file[PATH_MAX];
+		
+		if (!pr->match)
+			continue;
+		
+		snprintf(local_file, PATH_MAX, "%s/%s", my_tmp,
+		    pr->patch_name);
+		perform_applypatch(local_file);
 	}
 }

==== //depot/projects/soc2010/pkg_patch/src/patch/updateweb.h#6 (text+ko) ====



More information about the p4-projects mailing list