Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
bspatch.cpp File Reference
#include "bspatch.h"
#include "errors.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <arpa/inet.h>

Go to the source code of this file.




int MBS_ReadHeader (int fd, MBSPatchHeader *header)
 Read the header of a patch file into the MBSPatchHeader structure.
int MBS_ApplyPatch (const MBSPatchHeader *header, int patchfd, unsigned char *fbuffer, int filefd)
 Apply a patch.

Define Documentation


Definition at line 55 of file bspatch.cpp.

Function Documentation

int MBS_ApplyPatch ( const MBSPatchHeader header,
int  patchfd,
unsigned char *  fbuffer,
int  filefd 

Apply a patch.

This method does not validate the checksum of the original file: client code should validate the checksum before calling this method.

patchfdMust have been processed by MBS_ReadHeader
fbufferThe original file read into a memory buffer of length header->slen.
filefdMust have been opened for writing. Should be truncated to header->dlen if it is an existing file. The offset should be at the beginning of the file.

Definition at line 90 of file bspatch.cpp.

  unsigned char *fbufend = fbuffer + header->slen;

  unsigned char *buf = (unsigned char*) malloc(header->cblen +
                                               header->difflen +
  if (!buf)
    return MEM_ERROR;

  int rv = OK;

  int r = header->cblen + header->difflen + header->extralen;
  unsigned char *wb = buf;
  while (r) {
    int c = read(patchfd, wb, (r > SSIZE_MAX) ? SSIZE_MAX : r);
    if (c < 0) {
      rv = READ_ERROR;
      goto end;

    r -= c;

    if (c == 0 && r) {
      goto end;

    MBSPatchTriple *ctrlsrc = (MBSPatchTriple*) buf;
    unsigned char *diffsrc = buf + header->cblen;
    unsigned char *extrasrc = diffsrc + header->difflen;

    MBSPatchTriple *ctrlend = (MBSPatchTriple*) diffsrc;
    unsigned char *diffend = extrasrc;
    unsigned char *extraend = extrasrc + header->extralen;

    do {
      ctrlsrc->x = ntohl(ctrlsrc->x);
      ctrlsrc->y = ntohl(ctrlsrc->y);
      ctrlsrc->z = ntohl(ctrlsrc->z);

#ifdef DEBUG_bsmedberg
      printf("Applying block:\n"
             " x: %u\n"
             " y: %u\n"
             " z: %i\n",

      /* Add x bytes from oldfile to x bytes from the diff block */

      if (fbuffer + ctrlsrc->x > fbufend ||
          diffsrc + ctrlsrc->x > diffend) {
        rv = UNEXPECTED_ERROR;
        goto end;
      for (PRUint32 i = 0; i < ctrlsrc->x; ++i) {
        diffsrc[i] += fbuffer[i];
      if ((PRUint32) write(filefd, diffsrc, ctrlsrc->x) != ctrlsrc->x) {
        rv = WRITE_ERROR;
        goto end;
      fbuffer += ctrlsrc->x;
      diffsrc += ctrlsrc->x;

      /* Copy y bytes from the extra block */

      if (extrasrc + ctrlsrc->y > extraend) {
        rv = UNEXPECTED_ERROR;
        goto end;
      if ((PRUint32) write(filefd, extrasrc, ctrlsrc->y) != ctrlsrc->y) {
        rv = WRITE_ERROR;
        goto end;
      extrasrc += ctrlsrc->y;

      /* "seek" forwards in oldfile by z bytes */

      if (fbuffer + ctrlsrc->z > fbufend) {
        rv = UNEXPECTED_ERROR;
        goto end;
      fbuffer += ctrlsrc->z;

      /* and on to the next control block */

    } while (ctrlsrc < ctrlend);

  return rv;

Here is the caller graph for this function:

int MBS_ReadHeader ( int  fd,
MBSPatchHeader header 

Read the header of a patch file into the MBSPatchHeader structure.

fdMust have been opened for reading, and be at the beginning of the file.

Definition at line 59 of file bspatch.cpp.

  int s = read(fd, header, sizeof(MBSPatchHeader));
  if (s != sizeof(MBSPatchHeader))
    return READ_ERROR;

  header->slen      = ntohl(header->slen);
  header->scrc32    = ntohl(header->scrc32);
  header->dlen      = ntohl(header->dlen);
  header->cblen     = ntohl(header->cblen);
  header->difflen   = ntohl(header->difflen);
  header->extralen  = ntohl(header->extralen);

  struct stat hs;
  s = fstat(fd, &hs);
  if (s)
    return READ_ERROR;

  if (memcmp(header->tag, "MBDIFF10", 8) != 0)

  if (sizeof(MBSPatchHeader) +
      header->cblen +
      header->difflen +
      header->extralen != PRUint32(hs.st_size))

  return OK;

Here is the call graph for this function:

Here is the caller graph for this function: