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>