#include <string.h>
#include <unistd.h>
+struct bsdiff_header
+{
+ uint8_t signature[8];
+ uint64_t ctrl_block_length;
+ uint64_t diff_block_length;
+ uint64_t new_file_length;
+};
+
#if defined(__linux__)
#include <err.h>
#else
if(x<0) buf[7]|=0x80;
}
-int bsdiff(uint8_t* old, off_t oldsize, uint8_t* new, off_t newsize, FILE* pf)
+int bsdiff(uint8_t* old, off_t oldsize, uint8_t* new, off_t newsize, FILE* pf, struct bsdiff_header* header)
{
off_t *I,*V;
off_t scan,pos,len;
off_t dblen,eblen;
uint8_t *db,*eb;
uint8_t buf[8];
- uint8_t header[32];
BZFILE * pfbz2;
int bz2err;
32 ?? Bzip2ed ctrl block
?? ?? Bzip2ed diff block
?? ?? Bzip2ed extra block */
- memcpy(header,"BSDIFF40",8);
- offtout(0, header + 8);
- offtout(0, header + 16);
- offtout(newsize, header + 24);
- if (fwrite(header, 32, 1, pf) != 1)
- err(1, "fwrite(%s)", "patch");
+ memcpy(header->signature,"BSDIFF40",sizeof(header->signature));
+ header->ctrl_block_length = 0;
+ header->diff_block_length = 0;
+ header->new_file_length = newsize;
/* Compute the differences, writing ctrl as we go */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
/* Compute size of compressed ctrl data */
if ((len = ftello(pf)) == -1)
- err(1, "ftello");
- offtout(len-32, header + 8);
+ err(1, "ftello64");
+ header->ctrl_block_length = len-32;
/* Write compressed diff data */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
/* Compute size of compressed diff data */
if ((newsize = ftello(pf)) == -1)
- err(1, "ftello");
- offtout(newsize - len, header + 16);
+ err(1, "ftello64");
+ header->diff_block_length = newsize - len;
/* Write compressed extra data */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
- /* Seek to the beginning, write the header, and close the file */
- if (fseeko(pf, 0, SEEK_SET))
- err(1, "fseeko");
- if (fwrite(header, 32, 1, pf) != 1)
- err(1, "fwrite(%s)", "patch");
-
/* Free the memory we used */
free(db);
free(eb);
int fd;
uint8_t *old,*new;
off_t oldsize,newsize;
+ struct bsdiff_header header;
FILE * pf;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
if ((pf = fopen(argv[3], "w")) == NULL)
err(1, "%s", argv[3]);
- if (bsdiff(old, oldsize, new, newsize, pf))
+ /* Save space for header */
+ if (fwrite(&header, sizeof(header), 1, pf) != 1)
+ err(1, "Failed to write header");
+
+ if (bsdiff(old, oldsize, new, newsize, pf, &header))
err(1, "bsdiff");
+ if (fseek(pf, 0, SEEK_SET) ||
+ fwrite(&header, sizeof(header), 1, pf) != 1)
+ err(1, "Failed to write header");
+
if (fclose(pf))
err(1, "fclose");