2 * Copyright 2003,2004 Colin Percival
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
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.
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.
27 * 2005-04-26 - Define the header as a C structure, add a CRC32 checksum to
28 * the header, and make all the types 32-bit.
29 * --Benjamin Smedberg <benjamin@smedbergs.us>
50 # include <winsock2.h>
52 # include <arpa/inet.h>
56 # define SSIZE_MAX LONG_MAX
60 MBS_ReadHeader(FILE* file
, MBSPatchHeader
*header
)
62 size_t s
= fread(header
, 1, sizeof(MBSPatchHeader
), file
);
63 if (s
!= sizeof(MBSPatchHeader
))
66 header
->slen
= ntohl(header
->slen
);
67 header
->scrc32
= ntohl(header
->scrc32
);
68 header
->dlen
= ntohl(header
->dlen
);
69 header
->cblen
= ntohl(header
->cblen
);
70 header
->difflen
= ntohl(header
->difflen
);
71 header
->extralen
= ntohl(header
->extralen
);
74 s
= fstat(fileno(file
), &hs
);
78 if (memcmp(header
->tag
, "MBDIFF10", 8) != 0)
79 return UNEXPECTED_BSPATCH_ERROR
;
81 if (sizeof(MBSPatchHeader
) +
84 header
->extralen
!= uint32_t(hs
.st_size
))
85 return UNEXPECTED_BSPATCH_ERROR
;
91 MBS_ApplyPatch(const MBSPatchHeader
*header
, FILE* patchFile
,
92 unsigned char *fbuffer
, FILE* file
)
94 unsigned char *fbufend
= fbuffer
+ header
->slen
;
96 unsigned char *buf
= (unsigned char*) malloc(header
->cblen
+
100 return BSPATCH_MEM_ERROR
;
104 size_t r
= header
->cblen
+ header
->difflen
+ header
->extralen
;
105 unsigned char *wb
= buf
;
108 const size_t count
= std::min(r
, size_t(SSIZE_MAX
));
109 size_t c
= fread(wb
, 1, count
, patchFile
);
121 MBSPatchTriple
*ctrlsrc
= (MBSPatchTriple
*) buf
;
122 unsigned char *diffsrc
= buf
+ header
->cblen
;
123 unsigned char *extrasrc
= diffsrc
+ header
->difflen
;
125 MBSPatchTriple
*ctrlend
= (MBSPatchTriple
*) diffsrc
;
126 unsigned char *diffend
= extrasrc
;
127 unsigned char *extraend
= extrasrc
+ header
->extralen
;
131 ctrlsrc
->x
= ntohl(ctrlsrc
->x
);
132 ctrlsrc
->y
= ntohl(ctrlsrc
->y
);
133 ctrlsrc
->z
= ntohl(ctrlsrc
->z
);
135 #ifdef DEBUG_bsmedberg
136 printf("Applying block:\n"
145 /* Add x bytes from oldfile to x bytes from the diff block */
147 if (fbuffer
+ ctrlsrc
->x
> fbufend
||
148 diffsrc
+ ctrlsrc
->x
> diffend
)
150 rv
= UNEXPECTED_BSPATCH_ERROR
;
153 for (uint32_t i
= 0; i
< ctrlsrc
->x
; ++i
)
155 diffsrc
[i
] += fbuffer
[i
];
157 if ((uint32_t) fwrite(diffsrc
, 1, ctrlsrc
->x
, file
) != ctrlsrc
->x
)
159 rv
= WRITE_ERROR_PATCH_FILE
;
162 fbuffer
+= ctrlsrc
->x
;
163 diffsrc
+= ctrlsrc
->x
;
165 /* Copy y bytes from the extra block */
167 if (extrasrc
+ ctrlsrc
->y
> extraend
)
169 rv
= UNEXPECTED_BSPATCH_ERROR
;
172 if ((uint32_t) fwrite(extrasrc
, 1, ctrlsrc
->y
, file
) != ctrlsrc
->y
)
174 rv
= WRITE_ERROR_PATCH_FILE
;
177 extrasrc
+= ctrlsrc
->y
;
179 /* "seek" forwards in oldfile by z bytes */
181 if (fbuffer
+ ctrlsrc
->z
> fbufend
)
183 rv
= UNEXPECTED_BSPATCH_ERROR
;
186 fbuffer
+= ctrlsrc
->z
;
188 /* and on to the next control block */
192 while (ctrlsrc
< ctrlend
);