Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
nsInstallPatch.cpp File Reference
#include "zlib.h"
#include "nsCRT.h"
#include "prmem.h"
#include "nsXPIDLString.h"
#include "nsInstall.h"
#include "nsInstallPatch.h"
#include "nsInstallResources.h"
#include "nsIDOMInstallVersion.h"
#include "nsILocalFile.h"
#include "nsNativeCharsetUtils.h"
#include "gdiff.h"
#include "VerReg.h"
#include "ScheduledTasks.h"
#include "plstr.h"
#include "prlog.h"

Go to the source code of this file.

Defines

#define BUFSIZE   32768
#define OPSIZE   1
#define MAXCMDSIZE   12
#define SRCFILE   0
#define OUTFILE   1
#define getshort(s)   (uint16)( ((uchar)*(s) << 8) + ((uchar)*((s)+1)) )
#define getlong(s)

Functions

static int32 gdiff_parseHeader (pDIFFDATA dd)
static int32 gdiff_validateFile (pDIFFDATA dd, int file)
static int32 gdiff_valCRC32 (pDIFFDATA dd, PRFileDesc *fh, uint32 chksum)
static int32 gdiff_ApplyPatch (pDIFFDATA dd)
static int32 gdiff_getdiff (pDIFFDATA dd, uchar *buffer, uint32 length)
static int32 gdiff_add (pDIFFDATA dd, uint32 count)
static int32 gdiff_copy (pDIFFDATA dd, uint32 position, uint32 count)

Define Documentation

#define BUFSIZE   32768

Definition at line 65 of file nsInstallPatch.cpp.

#define getlong (   s)
Value:
(uint32)( ((uchar)*(s) << 24) + ((uchar)*((s)+1) << 16 ) + \
                      ((uchar)*((s)+2) << 8) + ((uchar)*((s)+3)) )

Definition at line 73 of file nsInstallPatch.cpp.

#define getshort (   s)    (uint16)( ((uchar)*(s) << 8) + ((uchar)*((s)+1)) )

Definition at line 71 of file nsInstallPatch.cpp.

#define MAXCMDSIZE   12

Definition at line 67 of file nsInstallPatch.cpp.

#define OPSIZE   1

Definition at line 66 of file nsInstallPatch.cpp.

#define OUTFILE   1

Definition at line 69 of file nsInstallPatch.cpp.

#define SRCFILE   0

Definition at line 68 of file nsInstallPatch.cpp.


Function Documentation

static int32 gdiff_add ( pDIFFDATA  dd,
uint32  count 
) [static]

Definition at line 1089 of file nsInstallPatch.cpp.

{
    int32   err = GDIFF_OK;
    uint32  nRead;
    uint32  chunksize;

    while ( count > 0 ) {
        chunksize = ( count > dd->bufsize) ? dd->bufsize : count;
              nRead = PR_Read (dd->fDiff, dd->databuf, chunksize);
        if ( nRead != chunksize ) {
            err = GDIFF_ERR_BADDIFF;
            break;
        }

              PR_Write (dd->fOut, dd->databuf, chunksize);

        count -= chunksize;
    }

    return (err);
}

Here is the caller graph for this function:

static int32 gdiff_ApplyPatch ( pDIFFDATA  dd) [static]

Definition at line 953 of file nsInstallPatch.cpp.

{
    int32   err;
    PRBool done;
    uint32  position;
    uint32  count;
    uchar   opcode;
    uchar   cmdbuf[MAXCMDSIZE];

    done = FALSE;
    while ( !done ) {
        err = gdiff_getdiff( dd, &opcode, OPSIZE );
        if ( err != GDIFF_OK )
            break;

        switch (opcode)
        {
            case ENDDIFF:
                done = TRUE;
                break;

            case ADD16:
                err = gdiff_getdiff( dd, cmdbuf, ADD16SIZE );
                if ( err == GDIFF_OK ) {
                    err = gdiff_add( dd, getshort( cmdbuf ) );
                }
                break;

            case ADD32:
                err = gdiff_getdiff( dd, cmdbuf, ADD32SIZE );
                if ( err == GDIFF_OK ) {
                    err = gdiff_add( dd, getlong( cmdbuf ) );
                }
                break;

            case COPY16BYTE:
                err = gdiff_getdiff( dd, cmdbuf, COPY16BYTESIZE );
                if ( err == GDIFF_OK ) {
                    position = getshort( cmdbuf );
                    count = *(cmdbuf + sizeof(short));
                    err = gdiff_copy( dd, position, count );
                }
                break;

            case COPY16SHORT:
                err = gdiff_getdiff( dd, cmdbuf, COPY16SHORTSIZE );
                if ( err == GDIFF_OK ) {
                    position = getshort( cmdbuf );
                    count = getshort(cmdbuf + sizeof(short));
                    err = gdiff_copy( dd, position, count );
                }
                break;

            case COPY16LONG:
                err = gdiff_getdiff( dd, cmdbuf, COPY16LONGSIZE );
                if ( err == GDIFF_OK ) {
                    position = getshort( cmdbuf );
                    count =  getlong(cmdbuf + sizeof(short));
                    err = gdiff_copy( dd, position, count );
                }
                break;

            case COPY32BYTE:
                err = gdiff_getdiff( dd, cmdbuf, COPY32BYTESIZE );
                if ( err == GDIFF_OK ) {
                    position = getlong( cmdbuf );
                    count = *(cmdbuf + sizeof(long));
                    err = gdiff_copy( dd, position, count );
                }
                break;

            case COPY32SHORT:
                err = gdiff_getdiff( dd, cmdbuf, COPY32SHORTSIZE );
                if ( err == GDIFF_OK ) {
                    position = getlong( cmdbuf );
                    count = getshort(cmdbuf + sizeof(long));
                    err = gdiff_copy( dd, position, count );
                }
                break;

            case COPY32LONG:
                err = gdiff_getdiff( dd, cmdbuf, COPY32LONGSIZE );
                if ( err == GDIFF_OK ) {
                    position = getlong( cmdbuf );
                    count = getlong(cmdbuf + sizeof(long));
                    err = gdiff_copy( dd, position, count );
                }
                break;

            case COPY64:
                /* we don't support 64-bit file positioning yet */
                err = GDIFF_ERR_OPCODE;
                break;

            default:
                err = gdiff_add( dd, opcode );
                break;
        }

        if ( err != GDIFF_OK )
            done = TRUE;
    }

    /* return status */
    return (err);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int32 gdiff_copy ( pDIFFDATA  dd,
uint32  position,
uint32  count 
) [static]

Definition at line 1120 of file nsInstallPatch.cpp.

{
    int32 err = GDIFF_OK;
    uint32 nRead;
    uint32 chunksize;

       PR_Seek (dd->fSrc, position, PR_SEEK_SET);

    while ( count > 0 ) {
        chunksize = (count > dd->bufsize) ? dd->bufsize : count;

              nRead = PR_Read (dd->fSrc, dd->databuf, chunksize);
        if ( nRead != chunksize ) {
            err = GDIFF_ERR_OLDFILE;
            break;
        }

              PR_Write (dd->fOut, dd->databuf, chunksize);

        count -= chunksize;
    }

    return (err);
}

Here is the caller graph for this function:

static int32 gdiff_getdiff ( pDIFFDATA  dd,
uchar buffer,
uint32  length 
) [static]

Definition at line 1070 of file nsInstallPatch.cpp.

{
    uint32 bytesRead;

       bytesRead = PR_Read (dd->fDiff, buffer, length);
    if ( bytesRead != length )
        return GDIFF_ERR_BADDIFF;

    return GDIFF_OK;
}

Here is the caller graph for this function:

static int32 gdiff_parseHeader ( pDIFFDATA  dd) [static]

Definition at line 746 of file nsInstallPatch.cpp.

{
    int32   err = GDIFF_OK;
    uint8   cslen;
    uint8   oldcslen;
    uint8   newcslen;
    uint32  nRead;
    uchar   header[GDIFF_HEADERSIZE];

    /* Read the fixed-size part of the header */

       nRead = PR_Read (dd->fDiff, header, GDIFF_HEADERSIZE);
    if ( nRead != GDIFF_HEADERSIZE ||
         memcmp( header, GDIFF_MAGIC, GDIFF_MAGIC_LEN ) != 0  ||
         header[GDIFF_VER_POS] != GDIFF_VER )
    {
        err = GDIFF_ERR_HEADER;
    }
    else
    {
        /* get the checksum information */

        dd->checksumType = header[GDIFF_CS_POS];
        cslen = header[GDIFF_CSLEN_POS];

        if ( cslen > 0 )
        {
            oldcslen = cslen / 2;
            newcslen = cslen - oldcslen;
            PR_ASSERT( newcslen == oldcslen );

            dd->checksumLength = oldcslen;
            dd->oldChecksum = (uchar*)PR_MALLOC(oldcslen);
            dd->newChecksum = (uchar*)PR_MALLOC(newcslen);

            if ( dd->oldChecksum != NULL && dd->newChecksum != NULL )
            {
                            nRead = PR_Read (dd->fDiff, dd->oldChecksum, oldcslen);
                if ( nRead == oldcslen )
                {
                                   nRead = PR_Read (dd->fDiff, dd->newChecksum, newcslen);
                    if ( nRead != newcslen ) {
                        err = GDIFF_ERR_HEADER;
                    }
                }
                else {
                    err = GDIFF_ERR_HEADER;
                }
            }
            else {
                err = GDIFF_ERR_MEM;
            }
        }


        /* get application data, if any */

        if ( err == GDIFF_OK )
        {
            uint32  appdataSize;
            uchar   *buf;
            uchar   lenbuf[GDIFF_APPDATALEN];

                     nRead = PR_Read(dd->fDiff, lenbuf, GDIFF_APPDATALEN);
            if ( nRead == GDIFF_APPDATALEN ) 
            {
                appdataSize = getlong(lenbuf);

                if ( appdataSize > 0 ) 
                {
                    buf = (uchar *)PR_MALLOC( appdataSize );

                    if ( buf != NULL )
                    {
                                          nRead = PR_Read (dd->fDiff, buf, appdataSize);
                        if ( nRead == appdataSize ) 
                        {
                            if ( 0 == memcmp( buf, APPFLAG_W32BOUND, appdataSize ) )
                                dd->bWin32BoundImage = TRUE;

                            if ( 0 == memcmp( buf, APPFLAG_APPLESINGLE, appdataSize ) )
                                dd->bMacAppleSingle = TRUE;
                        }
                        else {
                            err = GDIFF_ERR_HEADER;
                        }

                        PR_DELETE( buf );
                    }
                    else {
                        err = GDIFF_ERR_MEM;
                    }
                }
            }
            else {
                err = GDIFF_ERR_HEADER;
            }
        }
    }

    return (err);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int32 gdiff_valCRC32 ( pDIFFDATA  dd,
PRFileDesc fh,
uint32  chksum 
) [static]

Definition at line 920 of file nsInstallPatch.cpp.

{
    uint32 crc;
    uint32 nRead;

    crc = crc32(0L, Z_NULL, 0);

       nRead = PR_Read (fh, dd->databuf, dd->bufsize);
    while ( nRead > 0 ) 
    {
        crc = crc32( crc, dd->databuf, nRead );
              nRead = PR_Read (fh, dd->databuf, dd->bufsize);
    }

    if ( crc == chksum )
        return GDIFF_OK;
    else
        return GDIFF_ERR_CHECKSUM;
}

Here is the caller graph for this function:

static int32 gdiff_validateFile ( pDIFFDATA  dd,
int  file 
) [static]

Definition at line 858 of file nsInstallPatch.cpp.

{
    int32            result;
    PRFileDesc*      fh;
    uchar*           chksum;

    /* which file are we dealing with? */
    if ( file == SRCFILE ) {
        fh = dd->fSrc;
        chksum = dd->oldChecksum;
    }
    else { /* OUTFILE */
        fh = dd->fOut;
        chksum = dd->newChecksum;
    }

    /* make sure file's at beginning */
    PR_Seek( fh, 0, PR_SEEK_SET );

    /* calculate appropriate checksum */
    switch (dd->checksumType)
    {
        case GDIFF_CS_NONE:
            result = GDIFF_OK;
            break;


        case GDIFF_CS_CRC32:
            if ( dd->checksumLength == CRC32_LEN )
                result = gdiff_valCRC32( dd, fh, getlong(chksum) );
            else
                result = GDIFF_ERR_HEADER;
            break;


        case GDIFF_CS_MD5:


        case GDIFF_CS_SHA:


        default:
            /* unsupported checksum type */
            result = GDIFF_ERR_CHKSUMTYPE;
            break;
    }

    /* reset file position to beginning and return status */
    PR_Seek( fh, 0, PR_SEEK_SET );
    return (result);
}

Here is the call graph for this function:

Here is the caller graph for this function: