diff options
Diffstat (limited to 'utils/bspatch')
-rw-r--r-- | utils/bspatch/LICENSE | 23 | ||||
-rw-r--r-- | utils/bspatch/Makefile | 17 | ||||
-rw-r--r-- | utils/bspatch/bspatch.c | 218 | ||||
-rw-r--r-- | utils/bspatch/bspatch.h | 19 | ||||
-rw-r--r-- | utils/bspatch/main.c | 34 |
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 | |||
10 | LIBSOURCES := bspatch.c | ||
11 | |||
12 | SOURCES := main.c | ||
13 | |||
14 | OUTPUT := bspatch | ||
15 | EXTRADEPS := libbz2.a | ||
16 | |||
17 | include ../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 | ||
40 | void 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 | |||
49 | static 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 | |||
67 | int 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 | ||
9 | extern "C" { | ||
10 | #endif | ||
11 | |||
12 | int 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 | |||
29 | int 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 | } | ||