Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Jun 2010 01:17:41 GMT
From:      Ivan Voras <ivoras@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 180279 for review
Message-ID:  <201006280117.o5S1Hfxd024831@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@180279?ac=10

Change 180279 by ivoras@betelgeuse on 2010/06/28 01:17:39

	Finish the patch package "apply" function. Basically, this
	completes Milestone 2.

Affected files ...

.. //depot/projects/soc2010/pkg_patch/src/patch/Makefile#18 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.c#8 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.h#8 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#17 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#17 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/main.c#18 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#16 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#16 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#16 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/support.c#15 edit

Differences ...

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


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

@@ -42,10 +42,8 @@
  * by its full name, e.g. "apache-2.2.13").
  */
 static int
-pkg_backup(char *name)
+pkg_backup(char *name, char *pkg_file)
 {
-	char pkg_file[PATH_MAX];
-	
 	if (!isinstalledpkg(name)) {
 		warnx("Package not installed: %s", name);
 		return (-1);
@@ -231,18 +229,51 @@
 
 
 /*
+ * Rudely overwrites metadata files in the package given by target_pkg_name
+ * with the ones in sourcedir referenced by package metadata pkg.
+ */
+static int
+pkg_install_metadata(char *sourcedir, Package *pkg, char *target_pkg_name)
+{
+	PackingList pli;
+	char sourcef[PATH_MAX], destf[PATH_MAX];
+	
+	pli = pkg->head;
+	while (pli != NULL) {
+		if (pli->type == PLIST_FILE && pli->name[0] == '+') {
+			snprintf(sourcef, PATH_MAX, "%s/%s", sourcedir,
+			    pli->name);
+			if (access(sourcef, R_OK) != 0) {
+				warn("Cannot access file: %s", sourcef);
+				return (-1);
+			}
+			snprintf(destf, PATH_MAX, "%s/%s/%s", LOG_DIR,
+			    target_pkg_name, pli->name);
+			if (copy_file_absolute(sourcef, destf) != 0) {
+				warn("Cannot copy %s to %s", sourcef, destf);
+				return (-1);
+			}
+		}
+		pli = pli->next;
+	}
+	return (0);
+}
+
+
+/*
  * Apply patch command
  */
 void
 perform_applypatch()
 {
-	unsigned int err_count, n_patched_files, i;
 	char fpatch[PATH_MAX], dpatch[PATH_MAX], tmp[PATH_MAX], pext[10];
+	char backup_pkg[PATH_MAX];
 	struct pkgxjob xpatch;
 	struct pkg_patch pp;
 	Package pkg_live, pkg_new;
 	struct pplist *pl;
 	FILE **fpvect;
+	unsigned int err_count, n_patched_files, i;
 	
 	if (argc < 1)
 		errx(1, "Expecting argument: patch filename");
@@ -351,7 +382,7 @@
 		errx(1, "Found %u errors. Cannot continue.", err_count);
 	
 	/* Step 4 - backup the existing package */
-	if (pkg_backup(pp.source) != 0)
+	if (pkg_backup(pp.source, backup_pkg) != 0)
 		err(1, "Cannot backup package: %s", pp.source);
 	
 	/*
@@ -449,14 +480,78 @@
 	}
 	/* Step 6 - apply other classes - files to add, remove, dirs to rmdir */
 	STAILQ_FOREACH(pl, &pp.pp_add, linkage) {
+		char livefile[PATH_MAX];
+		
+		snprintf(tmp, PATH_MAX, "%s/%s", dpatch, pl->filename);
+		if (pkg_to_live_filename(livefile, pl->filename, &pkg_new,
+		    "pp_add2") != 0) {
+			warnx("Cannot resolve %s in new pkg", pl->filename);
+			goto error_cleanup;
+		}
+		if (copy_file_absolute(tmp, livefile) != 0) {
+			warn("Cannot copy %s to %s", tmp, livefile);
+			goto error_cleanup;
+		}
 	}
 	STAILQ_FOREACH(pl, &pp.pp_remove, linkage) {
+		if (pkg_to_live_filename(tmp, pl->filename, &pkg_live,
+		    "pp_remove2") != 0) {
+			warnx("Cannot resolve %s on live system", pl->filename);
+			goto error_cleanup;
+		}
+		if (unlink(tmp) != 0) {
+			warn("Cannot unlink: %s -- continuing", tmp);
+			/* goto error_cleanup; */
+		}
 	}
 	STAILQ_FOREACH(pl, &pp.pp_rmdir, linkage) {
+		if (pkg_to_live_dirname(tmp, pl->filename, &pkg_live,
+		    "pp_rmdir2") != 0) {
+			warnx("Cannot resolve directory %s on live system",
+			    pl->filename);
+		}
+		if (rmdir(tmp) != 0) {
+			warn("Cannot rmdir: %s -- continuing", tmp);
+			/* goto error_cleanup; */
+		}
+	}
+	/*
+	 * Step 7 - fixup metadata: copy new metadata over the old, then rename
+	 * the pkgdb directory.
+	 */
+	if (pkg_install_metadata(dpatch, &pkg_new, pp.source) != 0) {
+	 	warn("Cannot install new metadata for %s", pp.target);
+	 	goto error_cleanup;
+	} else {
+		char newpkgdir[PATH_MAX];
+		
+		snprintf(tmp, PATH_MAX, "%s/%s", LOG_DIR, pp.source);
+		snprintf(newpkgdir, PATH_MAX, "%s/%s", LOG_DIR, pp.target);
+		if (rename(tmp, newpkgdir) != 0) {
+			warn("Cannot rename %s to %s", tmp, newpkgdir);
+			goto error_cleanup;
+		}
 	}
-	/* Step 7 - fixup metadata */
+	/* Plaudite, amici, comoedia finita est. */
 	return;
 error_cleanup:
-	/* Remove temp patch files, restore backed-up package */
+	/* Remove temp patch files, restore backed-up package. */
 	warnx("Error detected! Rolling back package.");
+	/* Remove any temp patch files */
+	STAILQ_FOREACH(pl, &pp.pp_patch, linkage) {
+		if (pkg_to_live_filename(tmp, pl->filename, &pkg_new,
+		    "pp_patch rollback") == 0) {
+			strncat(tmp, pext, PATH_MAX);
+			if (access(tmp, F_OK) == 0)
+				if (unlink(tmp) != 0)
+					warn("Cannot unlink %s", tmp);
+		}
+	}
+	/* Obliterate old package */
+	if (vsystem("%s -f %s", _PATH_PKG_DELETE, pp.source) != 0)
+		printf("pkg_delete on %s failed.\n", pp.source);
+	if (vsystem("%s -F %s", _PATH_PKG_ADD, backup_pkg) != 0) {
+		printf("pkg_add on %s failed!\n", backup_pkg);
+		err(1, "Critical! Package rollback probably failed!");
+	}
 }

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


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


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


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


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


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


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

@@ -32,6 +32,12 @@
 #ifndef _PATH_PKG_CREATE
 #define _PATH_PKG_CREATE	"/usr/sbin/pkg_create"
 #endif
+#ifndef _PATH_PKG_DELETE
+#define _PATH_PKG_DELETE	"/usr/sbin/pkg_delete"
+#endif
+#ifndef	_PATH_PKG_ADD
+#define	_PATH_PKG_ADD		"/usr/sbin/pkg_add"
+#endif
 
 #ifndef PKG_FORMAT_EXT
 #define PKG_FORMAT_EXT	"tbz"

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

@@ -314,10 +314,6 @@
 int
 copy_file_absolute(char *from, char *to)
 {
-	char *buf;
-	const ssize_t bufsize = 256*1024;
-	ssize_t bs;
-	int fdfrom, fdto;
 	struct stat st;
 	
 	if (lstat(from, &st) != 0)
@@ -327,37 +323,17 @@
 		char tmp[PATH_MAX];
 		
 		if (readlink(from, tmp, PATH_MAX) < 0)
-			return (errno);
+			return (-errno);
 		if (symlink(tmp, to) < 0)
-			return (errno);
+			return (-errno);
 		return (0);
 	}
 	
-	fdfrom = open(from, O_RDONLY);
-	if (fdfrom < 0)
-		return (errno);
-	fdto = open(to, O_CREAT | O_WRONLY | O_TRUNC);
-	if (fdto < 0)
-		return (errno);
-	buf = malloc(bufsize);
-	if (buf == NULL)
-		return (ENOMEM);
-	while (1) {
-		bs = read(fdfrom, buf, bufsize);
-		if (bs < 0)
-			err(1, "read() failure");
-		else if (bs > 0)
-			if (write(fdto, buf, bs) != bs)
-				err(1, "write() failure");
-		if (bs == 0)
-			break;
-	}
-	free(buf);
-	close(fdto);
-	close(fdfrom);
+	if (cp(from, to) != 0)
+		return (-errno);
 	
 	if (copy_file_attrs(from, &st, to) != 0)
-		return (errno);
+		return (-errno);
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006280117.o5S1Hfxd024831>