summaryrefslogtreecommitdiff
path: root/utils/bspatch
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2021-12-15 21:04:28 +0100
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2021-12-24 18:05:53 +0100
commitc876d3bbefe0dc00c27ca0c12d29da5874946962 (patch)
tree69f468a185a369b01998314bc3ecc19b70f4fcaa /utils/bspatch
parent6c6f0757d7a902feb293be165d1490c42bc8e7ad (diff)
downloadrockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.tar.gz
rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.zip
rbutil: Merge rbutil with utils folder.
rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21
Diffstat (limited to 'utils/bspatch')
-rw-r--r--utils/bspatch/LICENSE23
-rw-r--r--utils/bspatch/Makefile17
-rw-r--r--utils/bspatch/bspatch.c218
-rw-r--r--utils/bspatch/bspatch.h19
-rw-r--r--utils/bspatch/main.c34
5 files changed, 311 insertions, 0 deletions
diff --git a/utils/bspatch/LICENSE b/utils/bspatch/LICENSE
new file mode 100644
index 0000000000..c82090b3eb
--- /dev/null
+++ b/utils/bspatch/LICENSE
@@ -0,0 +1,23 @@
1 Copyright 2003-2005 Colin Percival
2 All rights reserved
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted providing that the following conditions
6 are met:
7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12
13 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 POSSIBILITY OF SUCH DAMAGE.
diff --git a/utils/bspatch/Makefile b/utils/bspatch/Makefile
new file mode 100644
index 0000000000..8f287a5ebb
--- /dev/null
+++ b/utils/bspatch/Makefile
@@ -0,0 +1,17 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10LIBSOURCES := bspatch.c
11
12SOURCES := main.c
13
14OUTPUT := bspatch
15EXTRADEPS := libbz2.a
16
17include ../libtools.make
diff --git a/utils/bspatch/bspatch.c b/utils/bspatch/bspatch.c
new file mode 100644
index 0000000000..d1d7a5aa7a
--- /dev/null
+++ b/utils/bspatch/bspatch.c
@@ -0,0 +1,218 @@
1/*-
2 * Copyright 2003-2005 Colin Percival
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifdef WIN32
28#include <io.h>
29#else
30#include <stdarg.h>
31#include <sys/types.h>
32#endif
33#include "../bzip2/bzlib.h"
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include <fcntl.h>
38
39#define errx err
40void err(int exitcode, const char * fmt, ...)
41{
42 va_list valist;
43 va_start(valist, fmt);
44 vprintf(fmt, valist);
45 va_end(valist);
46 exit(exitcode);
47}
48
49static long offtin(u_char *buf)
50{
51 long y;
52
53 y = buf[7] & 0x7F;
54 y = y * 256;y += buf[6];
55 y = y * 256;y += buf[5];
56 y = y * 256;y += buf[4];
57 y = y * 256;y += buf[3];
58 y = y * 256;y += buf[2];
59 y = y * 256;y += buf[1];
60 y = y * 256;y += buf[0];
61
62 if (buf[7] & 0x80) y = -y;
63
64 return y;
65}
66
67int apply_bspatch(const char *infile, const char *outfile, const char *patchfile)
68{
69 FILE * f, *cpf, *dpf, *epf;
70 BZFILE * cpfbz2, *dpfbz2, *epfbz2;
71 int cbz2err, dbz2err, ebz2err;
72 FILE * fs;
73 long oldsize, newsize;
74 long bzctrllen, bzdatalen;
75 u_char header[32], buf[8];
76 u_char *pold, *pnew;
77 long oldpos, newpos;
78 long ctrl[3];
79 long lenread;
80 long i;
81
82 /* Open patch file */
83 if ((f = fopen(patchfile, "r")) == NULL)
84 err(1, "fopen(%s)", patchfile);
85
86 /*
87 File format:
88 0 8 "BSDIFF40"
89 8 8 X
90 16 8 Y
91 24 8 sizeof(newfile)
92 32 X bzip2(control block)
93 32+X Y bzip2(diff block)
94 32+X+Y ??? bzip2(extra block)
95 with control block a set of triples (x,y,z) meaning "add x bytes
96 from oldfile to x bytes from the diff block; copy y bytes from the
97 extra block; seek forwards in oldfile by z bytes".
98 */
99
100 /* Read header */
101 if (fread(header, 1, 32, f) < 32) {
102 if (feof(f))
103 errx(1, "Corrupt patch\n");
104 err(1, "fread(%s)", patchfile);
105 }
106
107 /* Check for appropriate magic */
108 if (memcmp(header, "BSDIFF40", 8) != 0)
109 errx(1, "Corrupt patch\n");
110
111 /* Read lengths from header */
112 bzctrllen = offtin(header + 8);
113 bzdatalen = offtin(header + 16);
114 newsize = offtin(header + 24);
115 if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0))
116 errx(1, "Corrupt patch\n");
117
118 /* Close patch file and re-open it via libbzip2 at the right places */
119 if (fclose(f))
120 err(1, "fclose(%s)", patchfile);
121 if ((cpf = fopen(patchfile, "rb")) == NULL)
122 err(1, "fopen(%s)", patchfile);
123 if (fseek(cpf, 32, SEEK_SET))
124 err(1, "fseeko(%s, %lld)", patchfile,
125 (long long)32);
126 if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
127 errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
128 if ((dpf = fopen(patchfile, "rb")) == NULL)
129 err(1, "fopen(%s)", patchfile);
130 if (fseek(dpf, 32 + bzctrllen, SEEK_SET))
131 err(1, "fseeko(%s, %lld)", patchfile,
132 (long long)(32 + bzctrllen));
133 if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
134 errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
135 if ((epf = fopen(patchfile, "rb")) == NULL)
136 err(1, "fopen(%s)", patchfile);
137 if (fseek(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
138 err(1, "fseeko(%s, %lld)", patchfile,
139 (long long)(32 + bzctrllen + bzdatalen));
140 if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
141 errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
142
143 fs = fopen(infile, "rb");
144 if (fs == NULL)err(1, "Open failed :%s", infile);
145 if (fseek(fs, 0, SEEK_END) != 0)err(1, "Seek failed :%s", infile);
146 oldsize = ftell(fs);
147 pold = (u_char *)malloc(oldsize + 1);
148 if (pold == NULL) err(1, "Malloc failed :%s", infile);
149 fseek(fs, 0, SEEK_SET);
150 if (fread(pold, 1, oldsize, fs) == -1) err(1, "Read failed :%s", infile);
151 if (fclose(fs) == -1) err(1, "Close failed :%s", infile);
152
153 pnew = malloc(newsize + 1);
154 if (pnew == NULL)err(1, NULL);
155
156 oldpos = 0;newpos = 0;
157 while (newpos < newsize) {
158 /* Read control data */
159 for (i = 0;i <= 2;i++) {
160 lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
161 if ((lenread < 8) || ((cbz2err != BZ_OK) &&
162 (cbz2err != BZ_STREAM_END)))
163 errx(1, "Corrupt patch\n");
164 ctrl[i] = offtin(buf);
165 };
166
167 /* Sanity-check */
168 if (newpos + ctrl[0] > newsize)
169 errx(1, "Corrupt patch\n");
170
171 /* Read diff string */
172 lenread = BZ2_bzRead(&dbz2err, dpfbz2, pnew + newpos, ctrl[0]);
173 if ((lenread < ctrl[0]) ||
174 ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
175 errx(1, "Corrupt patch\n");
176
177 /* Add pold data to diff string */
178 for (i = 0;i < ctrl[0];i++)
179 if ((oldpos + i >= 0) && (oldpos + i < oldsize))
180 pnew[newpos + i] += pold[oldpos + i];
181
182 /* Adjust pointers */
183 newpos += ctrl[0];
184 oldpos += ctrl[0];
185
186 /* Sanity-check */
187 if (newpos + ctrl[1] > newsize)
188 errx(1, "Corrupt patch\n");
189
190 /* Read extra string */
191 lenread = BZ2_bzRead(&ebz2err, epfbz2, pnew + newpos, ctrl[1]);
192 if ((lenread < ctrl[1]) ||
193 ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
194 errx(1, "Corrupt patch\n");
195
196 /* Adjust pointers */
197 newpos += ctrl[1];
198 oldpos += ctrl[2];
199 };
200
201 /* Clean up the bzip2 reads */
202 BZ2_bzReadClose(&cbz2err, cpfbz2);
203 BZ2_bzReadClose(&dbz2err, dpfbz2);
204 BZ2_bzReadClose(&ebz2err, epfbz2);
205 if (fclose(cpf) || fclose(dpf) || fclose(epf))
206 err(1, "fclose(%s)", patchfile);
207
208 /* Write the pnew file */
209 fs = fopen(outfile, "wb");
210 if (fs == NULL)err(1, "Create failed :%s", outfile);
211 if (fwrite(pnew, 1, newsize, fs) == -1)err(1, "Write failed :%s", outfile);
212 if (fclose(fs) == -1)err(1, "Close failed :%s", outfile);
213
214 free(pnew);
215 free(pold);
216
217 return 0;
218}
diff --git a/utils/bspatch/bspatch.h b/utils/bspatch/bspatch.h
new file mode 100644
index 0000000000..46edd5db0c
--- /dev/null
+++ b/utils/bspatch/bspatch.h
@@ -0,0 +1,19 @@
1/*
2 * Simple wrapper for the bspatch entry point.
3 */
4
5#ifndef _BSPATCH_H
6#define _BSPATCH_H
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12int apply_bspatch(const char *infile, const char *outfile, const char *patchfile);
13
14#ifdef __cplusplus
15}
16#endif
17
18
19#endif /* _BSPATCH_H */
diff --git a/utils/bspatch/main.c b/utils/bspatch/main.c
new file mode 100644
index 0000000000..e130457256
--- /dev/null
+++ b/utils/bspatch/main.c
@@ -0,0 +1,34 @@
1/*-
2 * Copyright 2003-2005 Colin Percival
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "bspatch.c"
28
29int main(int argc, char * argv[])
30{
31 if (argc != 4) errx(1, "usage: %s oldfile newfile patchfile\n", argv[0]);
32
33 apply_bspatch(argv[1], argv[2], argv[3]);
34}