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:
M | bsdiff.h | | | 4 | ++++ |
M | bspatch.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);