Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/bsdiff/bspatch/bspatch.c
Show All 21 Lines | |||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
* POSSIBILITY OF SUCH DAMAGE. | * POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#if defined(__FreeBSD__) | |||||
#include <sys/param.h> | |||||
#if __FreeBSD_version >= 1100014 | |||||
#include <sys/capsicum.h> | |||||
#define HAVE_CAPSICUM | |||||
#elif __FreeBSD_version >= 1000000 | |||||
#include <sys/capability.h> | |||||
#define HAVE_CAPSICUM | |||||
#endif | |||||
#endif | |||||
#include <bzlib.h> | #include <bzlib.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#ifndef O_BINARY | #ifndef O_BINARY | ||||
#define O_BINARY 0 | #define O_BINARY 0 | ||||
Show All 35 Lines | int main(int argc, char *argv[]) | ||||
ssize_t oldsize, newsize; | ssize_t oldsize, newsize; | ||||
ssize_t bzctrllen, bzdatalen; | ssize_t bzctrllen, bzdatalen; | ||||
u_char header[32], buf[8]; | u_char header[32], buf[8]; | ||||
u_char *old, *new; | u_char *old, *new; | ||||
off_t oldpos, newpos; | off_t oldpos, newpos; | ||||
off_t ctrl[3]; | off_t ctrl[3]; | ||||
off_t lenread; | off_t lenread; | ||||
off_t i; | off_t i; | ||||
#ifdef HAVE_CAPSICUM | |||||
cap_rights_t rights_ro, rights_wr; | |||||
#endif | |||||
if (argc != 4) | if (argc != 4) | ||||
usage(); | usage(); | ||||
/* Open patch file */ | /* Open patch file */ | ||||
if ((f = fopen(argv[3], "rb")) == NULL) | if ((f = fopen(argv[3], "rb")) == NULL) | ||||
err(1, "fopen(%s)", argv[3]); | err(1, "fopen(%s)", argv[3]); | ||||
/* Open patch file for control block */ | |||||
if ((cpf = fopen(argv[3], "rb")) == NULL) | |||||
err(1, "fopen(%s)", argv[3]); | |||||
/* open patch file for diff block */ | |||||
if ((dpf = fopen(argv[3], "rb")) == NULL) | |||||
err(1, "fopen(%s)", argv[3]); | |||||
/* open patch file for extra block */ | |||||
if ((epf = fopen(argv[3], "rb")) == NULL) | |||||
err(1, "fopen(%s)", argv[3]); | |||||
/* open oldfile */ | |||||
if ((oldfd = open(argv[1], O_RDONLY | O_BINARY, 0)) < 0) | |||||
err(1, "open(%s)", argv[1]); | |||||
/* open newfile */ | |||||
if ((newfd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, | |||||
0666)) < 0) | |||||
err(1, "open(%s)", argv[2]); | |||||
#ifdef HAVE_CAPSICUM | |||||
if (cap_enter() < 0) { | |||||
/* Failed to sandbox, fatal if CAPABILITY_MODE enabled */ | |||||
if (errno != ENOSYS) | |||||
err(1, "failed to enter security sandbox"); | |||||
} else { | |||||
/* Capsicum Available */ | |||||
cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK); | |||||
cap_rights_init(&rights_wr, CAP_WRITE); | |||||
if (cap_rights_limit(fileno(f), &rights_ro) < 0 || | |||||
cap_rights_limit(fileno(cpf), &rights_ro) < 0 || | |||||
cap_rights_limit(fileno(dpf), &rights_ro) < 0 || | |||||
cap_rights_limit(fileno(epf), &rights_ro) < 0 || | |||||
cap_rights_limit(oldfd, &rights_ro) < 0 || | |||||
cap_rights_limit(newfd, &rights_wr) < 0) | |||||
err(1, "cap_rights_limit() failed, could not restrict" | |||||
" capabilities"); | |||||
} | |||||
#endif | |||||
/* | /* | ||||
File format: | File format: | ||||
0 8 "BSDIFF40" | 0 8 "BSDIFF40" | ||||
8 8 X | 8 8 X | ||||
16 8 Y | 16 8 Y | ||||
24 8 sizeof(newfile) | 24 8 sizeof(newfile) | ||||
32 X bzip2(control block) | 32 X bzip2(control block) | ||||
32+X Y bzip2(diff block) | 32+X Y bzip2(diff block) | ||||
Show All 19 Lines | #endif | ||||
bzdatalen = offtin(header + 16); | bzdatalen = offtin(header + 16); | ||||
newsize = offtin(header + 24); | newsize = offtin(header + 24); | ||||
if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0)) | if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0)) | ||||
errx(1, "Corrupt patch\n"); | errx(1, "Corrupt patch\n"); | ||||
/* Close patch file and re-open it via libbzip2 at the right places */ | /* Close patch file and re-open it via libbzip2 at the right places */ | ||||
if (fclose(f)) | if (fclose(f)) | ||||
err(1, "fclose(%s)", argv[3]); | err(1, "fclose(%s)", argv[3]); | ||||
if ((cpf = fopen(argv[3], "rb")) == NULL) | |||||
err(1, "fopen(%s)", argv[3]); | |||||
if (fseeko(cpf, 32, SEEK_SET)) | if (fseeko(cpf, 32, SEEK_SET)) | ||||
err(1, "fseeko(%s, %lld)", argv[3], | err(1, "fseeko(%s, %lld)", argv[3], | ||||
(long long)32); | (long long)32); | ||||
if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL) | if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL) | ||||
errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err); | errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err); | ||||
if ((dpf = fopen(argv[3], "rb")) == NULL) | |||||
err(1, "fopen(%s)", argv[3]); | |||||
if (fseeko(dpf, 32 + bzctrllen, SEEK_SET)) | if (fseeko(dpf, 32 + bzctrllen, SEEK_SET)) | ||||
err(1, "fseeko(%s, %lld)", argv[3], | err(1, "fseeko(%s, %lld)", argv[3], | ||||
(long long)(32 + bzctrllen)); | (long long)(32 + bzctrllen)); | ||||
if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL) | if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL) | ||||
errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err); | errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err); | ||||
if ((epf = fopen(argv[3], "rb")) == NULL) | |||||
err(1, "fopen(%s)", argv[3]); | |||||
if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET)) | if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET)) | ||||
err(1, "fseeko(%s, %lld)", argv[3], | err(1, "fseeko(%s, %lld)", argv[3], | ||||
(long long)(32 + bzctrllen + bzdatalen)); | (long long)(32 + bzctrllen + bzdatalen)); | ||||
if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) | if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) | ||||
errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); | errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); | ||||
oldfd = open(argv[1], O_RDONLY | O_BINARY, 0); | |||||
if (oldfd < 0) | |||||
err(1, "%s", argv[1]); | |||||
if ((oldsize = lseek(oldfd, 0, SEEK_END)) == -1 || | if ((oldsize = lseek(oldfd, 0, SEEK_END)) == -1 || | ||||
(old = malloc(oldsize+1)) == NULL || | (old = malloc(oldsize+1)) == NULL || | ||||
lseek(oldfd, 0, SEEK_SET) != 0 || | lseek(oldfd, 0, SEEK_SET) != 0 || | ||||
read(oldfd, old, oldsize) != oldsize || | read(oldfd, old, oldsize) != oldsize || | ||||
close(oldfd) == -1) | close(oldfd) == -1) | ||||
err(1, "%s", argv[1]); | err(1, "%s", argv[1]); | ||||
if ((new = malloc(newsize + 1)) == NULL) | if ((new = malloc(newsize + 1)) == NULL) | ||||
err(1, NULL); | err(1, NULL); | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | #endif | ||||
/* Clean up the bzip2 reads */ | /* Clean up the bzip2 reads */ | ||||
BZ2_bzReadClose(&cbz2err, cpfbz2); | BZ2_bzReadClose(&cbz2err, cpfbz2); | ||||
BZ2_bzReadClose(&dbz2err, dpfbz2); | BZ2_bzReadClose(&dbz2err, dpfbz2); | ||||
BZ2_bzReadClose(&ebz2err, epfbz2); | BZ2_bzReadClose(&ebz2err, epfbz2); | ||||
if (fclose(cpf) || fclose(dpf) || fclose(epf)) | if (fclose(cpf) || fclose(dpf) || fclose(epf)) | ||||
err(1, "fclose(%s)", argv[3]); | err(1, "fclose(%s)", argv[3]); | ||||
/* Write the new file */ | /* Write the new file */ | ||||
newfd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666); | |||||
if (newfd < 0) | |||||
err(1, "%s", argv[2]); | |||||
if (write(newfd, new, newsize) != newsize || close(newfd) == -1) | if (write(newfd, new, newsize) != newsize || close(newfd) == -1) | ||||
err(1, "%s", argv[2]); | err(1, "%s", argv[2]); | ||||
free(new); | free(new); | ||||
free(old); | free(old); | ||||
return (0); | return (0); | ||||
} | } |