From owner-p4-projects@FreeBSD.ORG Sun Jul 18 23:55:19 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id F3E011065672; Sun, 18 Jul 2010 23:55:18 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B83EF106566C for ; Sun, 18 Jul 2010 23:55:18 +0000 (UTC) (envelope-from ivoras@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id A553A8FC0A for ; Sun, 18 Jul 2010 23:55:18 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o6INtIvG033926 for ; Sun, 18 Jul 2010 23:55:18 GMT (envelope-from ivoras@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o6INtIwi033924 for perforce@freebsd.org; Sun, 18 Jul 2010 23:55:18 GMT (envelope-from ivoras@FreeBSD.org) Date: Sun, 18 Jul 2010 23:55:18 GMT Message-Id: <201007182355.o6INtIwi033924@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to ivoras@FreeBSD.org using -f From: Ivan Voras To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 181156 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Jul 2010 23:55:19 -0000 http://p4web.freebsd.org/@@181156?ac=10 Change 181156 by ivoras@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 #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) ====