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