bsdiff-portable

A more portable version of Colin Percival's bsdiff
git clone git://git.sgregoratto.me/bsdiff-portable
Log | Files | Refs | README | LICENSE

commit 816770e54fb3e8e4c036291e61bd5122bcfd0a55
parent 5a7ce9d3017394a673f6babd691d6aad44af4e75
Author: Stephen Gregoratto <dev@sgregoratto.me>
Date:   Mon, 19 Oct 2020 17:40:47 +1100

bspatch: delete newfile if an error occured

Requires two clones of err/x that call the cleanup func at the end, but
whatever.

Diffstat:
Mbsdiff.h | 4++++
Mbspatch.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
2 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/bsdiff.h b/bsdiff.h @@ -50,5 +50,9 @@ off_t search(off_t *, uint8_t *, off_t, uint8_t *, off_t, off_t, void offtout(off_t, uint8_t *); off_t offtin(uint8_t *buf); uint8_t * readfile(char *, off_t *, struct stat *); + DEAD void usage(void); +DEAD void cleanup_newfile(void); +void err_rm(const char *, ...); +void errx_rm(const char *, ...); #endif /* BSDIFF_H */ diff --git a/bspatch.c b/bspatch.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59: #include <err.h> #endif #include <fcntl.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -47,6 +48,42 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59: #include "bsdiff.h" +char *newpath; +FILE *newfile; + +void +cleanup_newfile(void) +{ + if (fclose(newfile) == EOF) + warn("fclose(%s)", newpath); + if (remove(newpath) == -1) + warn("remove(%s)", newpath); + + exit(1); +} + +void +err_rm(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarn(fmt, ap); + va_end(ap); + + cleanup_newfile(); +} + +void +errx_rm(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); + + cleanup_newfile(); +} + static BZFILE * bz_openat(const char *path, FILE **f, off_t o) { @@ -54,11 +91,11 @@ bz_openat(const char *path, FILE **f, off_t o) BZFILE *bzf; if ((*f = fopen(path, "r")) == NULL) - err(1, "fopen(%s)", path); + err_rm("fopen(%s)", path); if (fseeko(*f, o, SEEK_SET) == -1) - err(1, "fseeko(%s, %lld)", path, (long long)o); + err_rm("fseeko(%s, %lld)", path, (long long)o); if ((bzf = BZ2_bzReadOpen(&bzerr, *f, 0, 0, NULL, 0)) == NULL) - errx(1, "BZ2_bzReadOpen returned %d", bzerr); + errx_rm("BZ2_bzReadOpen returned %d", bzerr); return bzf; } @@ -69,7 +106,6 @@ main(int argc, char **argv) FILE *f, *cpf, *dpf, *epf; BZFILE *cpfbz2, *dpfbz2, *epfbz2; int bzerr; - FILE *newfile; struct stat st; off_t oldsize, newsize; off_t bzctrllen, bzdatalen; @@ -82,64 +118,65 @@ main(int argc, char **argv) if (argc != 4) usage(); + newpath = argv[2]; #if HAVE_PLEDGE && HAVE_UNVEIL if (pledge("stdio rpath wpath cpath fattr unveil", NULL) == -1) err(1, "pledge"); if (unveil(argv[1], "r") == -1) err(1, "unveil(%s, r)", argv[1]); - if (unveil(argv[2], "wc") == -1) - err(1, "unveil(%s, wc)", argv[2]); + if (unveil(newpath, "wc") == -1) + err(1, "unveil(%s, wc)", newpath); if (unveil(argv[3], "r") == -1) err(1, "unveil(%s, r)", argv[3]); if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) err(1, "pledge"); #endif /* Open patch file */ - if ((f = fopen(argv[3], "r")) == NULL) - err(1, "fopen(%s)", argv[3]); + if ((f = fopen(newpath, "r")) == NULL) + err_rm("fopen(%s)", newpath); /* Open the new file */ - if ((newfile = fopen(argv[2], "w")) == NULL) - err(1, "fopen(%s)", argv[2]); + if ((newfile = fopen(newpath, "w")) == NULL) + err_rm("fopen(%s)", newpath); #if HAVE_PLEDGE && HAVE_UNVEIL - if (pledge("stdio rpath fattr", NULL) == -1) - err(1, "pledge"); + if (pledge("stdio rpath cpath fattr", NULL) == -1) + err_rm("pledge"); #endif /* Read header */ if (fread(header, 1, 32, f) != 32) { if (feof(f)) - errx(1, "Corrupt patch"); - err(1, "fread(%s)", argv[3]); + errx_rm("Corrupt patch"); + err_rm("fread(%s)", newpath); } /* Check for appropriate magic */ if (memcmp(header, "BSDIFF40", 8) != 0) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); /* Read lengths from header */ bzctrllen = offtin(header + 8); bzdatalen = offtin(header + 16); newsize = offtin(header + 24); if (bzctrllen < 0 || bzdatalen < 0 || newsize < 0) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); /* Close patch file and re-open it via libbzip2 at the right places */ if (fclose(f)) - err(1, "fclose(%s)", argv[3]); - cpfbz2 = bz_openat(argv[3], &cpf, 32); - dpfbz2 = bz_openat(argv[3], &dpf, 32 + bzctrllen); - epfbz2 = bz_openat(argv[3], &epf, 32 + bzctrllen + bzdatalen); + err_rm("fclose(%s)", newpath); + cpfbz2 = bz_openat(newpath, &cpf, 32); + dpfbz2 = bz_openat(newpath, &dpf, 32 + bzctrllen); + epfbz2 = bz_openat(newpath, &epf, 32 + bzctrllen + bzdatalen); old = readfile(argv[1], &oldsize, &st); if (fchmod(fileno(newfile), st.st_mode) == -1) - err(1, "fchmod(%s, %04o)", argv[2], st.st_mode); + err_rm("fchmod(%s, %04o)", newpath, st.st_mode); #if HAVE_PLEDGE && HAVE_UNVEIL - if (pledge("stdio", NULL) == -1) - err(1, "pledge"); + if (pledge("stdio cpath", NULL) == -1) + err_rm("pledge"); #endif if ((new = reallocarray(NULL, newsize + 1, 1)) == NULL) - err(1, "reallocarray"); + err_rm("reallocarray"); oldpos = newpos = 0; while (newpos < newsize) { @@ -147,20 +184,20 @@ main(int argc, char **argv) for (i = 0; i <= 2; i++) { lenread = BZ2_bzRead(&bzerr, cpfbz2, buf, 8); if (lenread < 8 || (bzerr != BZ_OK && bzerr != BZ_STREAM_END)) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); ctrl[i] = offtin(buf); } /* Sanity-check */ if (ctrl[0] < 0 || ctrl[1] < 0) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); if (newpos + ctrl[0] > newsize) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); /* Read diff string */ lenread = BZ2_bzRead(&bzerr, dpfbz2, new + newpos, ctrl[0]); if (lenread < ctrl[0] || (bzerr != BZ_OK && bzerr != BZ_STREAM_END)) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); /* Add old data to diff string */ for (i = 0; i < ctrl[0]; i++) @@ -173,12 +210,12 @@ main(int argc, char **argv) /* Sanity-check */ if (newpos + ctrl[1] > newsize) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); /* Read extra string */ lenread = BZ2_bzRead(&bzerr, epfbz2, new + newpos, ctrl[1]); if (lenread < ctrl[1] || (bzerr != BZ_OK && bzerr != BZ_STREAM_END)) - errx(1, "Corrupt patch"); + errx_rm("Corrupt patch"); /* Adjust pointers */ newpos += ctrl[1]; @@ -189,18 +226,18 @@ main(int argc, char **argv) #define BZ_CLOSE(f, bzf) \ BZ2_bzReadClose(&bzerr, (bzf)); \ if (bzerr != BZ_OK) \ - err(1, "BZ2_bzReadClose(%s) returned %d", argv[3], bzerr); \ + err_rm("BZ2_bzReadClose(%s) returned %d", newpath, bzerr); \ if (fclose((f)) == EOF) \ - err(1, "fclose(%s)", argv[3]); + err_rm("fclose(%s)", newpath); BZ_CLOSE(cpf, cpfbz2) BZ_CLOSE(dpf, dpfbz2) BZ_CLOSE(epf, epfbz2) /* Write the new file */ if (fwrite(new, 1, newsize, newfile) != (size_t)newsize) - err(1, "fwrite(%s, %lld)", argv[2], (long long)newsize); + err_rm("fwrite(%s, %lld)", newpath, (long long)newsize); if (fclose(newfile) == -1) - err(1, "fclose(%s)", argv[2]); + err_rm("fclose(%s)", newpath); free(new); free(old);