Thread: Rebuild file from original file and differences file in RAM

  1. #1
    Registered User
    Join Date
    Dec 2015
    Posts
    4

    Rebuild file from original file and differences file in RAM

    Dear friends, I am trying to implement a program that reconstructs a binary file, starting from the old file and a file of differences. The work is based on the ingenious thesis Olin Percival, Naive differences of executable code, Binary diff , 2003. I want to use the rebuilder (bspatch) on a microcontroller ARM M4. I'm trying to eliminate disk access with operations on simple vectors. The operation is not trivial because the Olin program is complicated! Of course in addition to the file pointer, the Olin program uses functions to access the file, such as fgetc FSEEK that must be replaced. To start I am working in C in visual studio and when the program will work on the PC i will move it on ARM M4.
    To begin with, I add static vectors of char as long as the files in input,then I copy-paste the files in to the vectors. From this point on I no longer want to make disk accesses. However, the program keeps making unwanted disk access.

    Has anyone ever replaced a file pointer with a vector of char to use only RAM?

    Look the original program of Olin (found in the link) there is a Visual Studio project.

    Thank You and Happy Happy Happy New Year
    Stefano Fredella

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I'm not sure why you keep saying 'olin' when the link you refer to quite clearly says "Colin Percival"

    As for the rest, start with a global edit which changes fseek(FILE *stream, long offset, int whence) into my_fseek(FILE *stream, long offset, int whence)

    And you implement
    Code:
    int my_fseek(FILE *stream, long offset, int whence) {
      return fseek(stream,offset,whence);
    }
    When you have done that for all the FILE* API you're using, then you can start to redefine the interface to use arrays.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2015
    Posts
    4
    Thank You, I made the changement and also load the files in array of chars:

    Code:
        /*-
         * Copyright 2003-2005 Colin Percival
         * All rights reserved
         *
         * Redistribution and use in source and binary forms, with or without
         * modification, are permitted providing that the following conditions 
         * are met:
         * 1. Redistributions of source code must retain the above copyright
         *    notice, this list of conditions and the following disclaimer.
         * 2. Redistributions in binary form must reproduce the above copyright
         *    notice, this list of conditions and the following disclaimer in the
         *    documentation and/or other materials provided with the distribution.
         *
         * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
         * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
         * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
         * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
         * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
         * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
         * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
         * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
         * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
         * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
         * POSSIBILITY OF SUCH DAMAGE.
        */
    
    
        #include <stdlib.h>
        #include <stdio.h>
        //#include <err.h>
        #include "bzlib.h"
        #include <io.h>
        #include <fcntl.h>
    
    
    
    
        #include <sys/types.h>
        typedef unsigned char u_char;
        typedef signed int ssize_t;
    
    
        template<class T1, class T2>
        void err(int i, const char* str, T1 arg1, T2 arg2) {
            char lastErrorTxt[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL);
            printf("%s",lastErrorTxt);
            printf(str, arg1, arg2);
            exit(i);
        }
        template<class T>
        void err(int i, const char* str, T arg) {
            char lastErrorTxt[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL);
            printf("%s",lastErrorTxt);
            printf(str, arg);
            exit(i);
        }
        void err(int i, const char* str) {
            char lastErrorTxt[1024];
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL);
            printf("%s",lastErrorTxt);
            if (str!=NULL) {
                printf("%s",str);
            }
            exit(i);
        }
        template<class T>
        void errx(int i, const char* str, T arg) {
            printf(str, arg);
            exit(i);
        }
        void errx(int i, const char* str) {
            printf("%s",str);
            exit(i);
        }
    
    
    
    
        static off_t offtin(u_char *buf)
        {
            off_t y;
    
    
            y=buf[7]&0x7F;
            y=y*256;y+=buf[6];
            y=y*256;y+=buf[5];
            y=y*256;y+=buf[4];
            y=y*256;y+=buf[3];
            y=y*256;y+=buf[2];
            y=y*256;y+=buf[1];
            y=y*256;y+=buf[0];
    
    
            if(buf[7]&0x80) y=-y;
    
    
            return y;
        }
    
    
        int my_fseek(FILE *stream, long offset, int whence)
        {
            return fseek(stream, offset, whence);
        }
    
    
        int main(void)
        {
            FILE * f, * cpf, * dpf, * epf;
            BZFILE * cpfbz2, * dpfbz2, * epfbz2;
            int cbz2err, dbz2err, ebz2err;
            int fd;
            ssize_t oldsize,newsize;
            ssize_t bzctrllen,bzdatalen;
            u_char header[32],buf[8];
            u_char *old, *_new;
            off_t oldpos,newpos;
            off_t ctrl[3];
            off_t lenread;
            off_t i;
    
    
            char OldFile[]= "old.txt";
            char NewFile[]= "newPatched.txt";
            char PatchFile[]= "patch.txt";
            char * VECTOR_PATCH;//[10*1024];
            char * VECTOR_OLD;//[200*1024];
            unsigned char c;
            int j,k,m,fileLen;
        
            /* load the file old in a vector---------------------------------------------------------------*/
            //Open file
            f = fopen(PatchFile, "rb");
            if (!f)
            {
                fprintf(stderr, "Unable to open file %s", PatchFile);
                return 1;
            }
        
            //Get file length
            my_fseek(f, 0, SEEK_END);                //fseek(f, 0, SEEK_END);
            fileLen=ftell(f);
            my_fseek(f, 0, SEEK_SET);                //fseek(f, 0, SEEK_END);
    
    
            //Allocate memory
            VECTOR_PATCH=(char *)malloc(fileLen+1);
            if (!VECTOR_PATCH)
            {
                fprintf(stderr, "Memory error!");
                                        fclose(f);
                return 1;
            }
    
    
            //Read file contents into buffer
            fread(VECTOR_PATCH, fileLen, 1, f);
            fclose(f);
    
    
    
    
            /* load the file old in a vector--------------------------------------------------------------------------------------*/
    
    
            f = fopen(OldFile, "rb");
            if (!f)
            {
                fprintf(stderr, "Unable to open file %s", OldFile);
                return 1;
            }
        
            //Get file length
            my_fseek(f, 0, SEEK_END);
            fileLen=ftell(f);
            my_fseek(f, 0, SEEK_SET);
    
    
            //Allocate memory
            VECTOR_OLD=(char *)malloc(fileLen+1);
            if (!VECTOR_OLD)
            {
                fprintf(stderr, "Memory error!");
                                        fclose(f);
                return 1;
            }
    
    
            //Read file contents into buffer
            fread(VECTOR_OLD, fileLen, 1, f);
            fclose(f);
    
    
    
    
    
    
    
    
            /*
            File format:
                0    8    "BSDIFF40"
                8    8    X
                16    8    Y
                24    8    sizeof(newfile)
                32    X    bzip2(control block)
                32+X    Y    bzip2(diff block)
                32+X+Y    ???    bzip2(extra block)
            with control block a set of triples (x,y,z) meaning "add x bytes
            from oldfile to x bytes from the diff block; copy y bytes from the
            extra block; seek forwards in oldfile by z bytes".
            */
    
    
            /* Read header */
    
    
            for(i=0; i<32;i++)
                header[i] = VECTOR_PATCH[i];
    
    
            /* Check for appropriate magic */
            if (memcmp(header, "BSDIFF40", 8) != 0)
                errx(1, "Corrupt patch\n");
    
    
            /* Read lengths from header */
            bzctrllen=offtin(header+8);
            bzdatalen=offtin(header+16);
            newsize=offtin(header+24);
            if((bzctrllen<0) || (bzdatalen<0) || (newsize<0))
                errx(1,"Corrupt patch\n");
    
    
            /* open it via libbzip2 at the right places */
            if ((cpf = fopen(PatchFile, "rb")) == NULL)
                err(1, "fopen(%s)", PatchFile);
            if (my_fseek(cpf, 32, SEEK_SET))
                err(1, "fseeko(%s, %d)", PatchFile, 32);
        
            if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, (FILE *)&VECTOR_PATCH[32], 0, 0, NULL, 0)) == NULL)
                errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
    
    
        /*----------------------------------------------------------------------------------*/
            if ((cpf = fopen(PatchFile, "rb")) == NULL)
                err(1, "fopen(%s)", PatchFile);
            if (my_fseek(cpf, 32, SEEK_SET))
                err(1, "fseeko(%s, %d)", PatchFile, 32);
            if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
                errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
        /*----------------------------------------------------------------------------------*/
    
    
            if ((dpf = fopen(PatchFile, "rb")) == NULL)
                err(1, "fopen(%s)", PatchFile);
            if (my_fseek(dpf, 32 + bzctrllen, SEEK_SET))
                err(1, "fseeko(%s, %d)", PatchFile,
                    (32 + bzctrllen));
            if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
                errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
            if ((epf = fopen(PatchFile, "rb")) == NULL)
                err(1, "fopen(%s)", PatchFile);
            if (my_fseek(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
                err(1, "fseeko(%s, %d)", PatchFile,
                    (32 + bzctrllen + bzdatalen));
            if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
                errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
    
    
            //org:
            //if(((fd=open(argv[1],O_RDONLY,0))<0) ||
            //    ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
            //    ((old=malloc(oldsize+1))==NULL) ||
            //    (lseek(fd,0,SEEK_SET)!=0) ||
            //    (read(fd,old,oldsize)!=oldsize) ||
            //    (close(fd)==-1)) err(1,"%s",argv[1]);
            //new:
            //Read in chunks, don't rely on read always returns full data!
            if(((fd=open(OldFile,O_RDONLY|O_BINARY|O_NOINHERIT,0))<0) ||
                ((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
                ((old=(u_char*)malloc(oldsize+1))==NULL) ||
                (_lseek(fd,0,SEEK_SET)!=0))
                        err(1,"%s",OldFile);
            int r=oldsize;
            while (r>0 && (i=read(fd,old+oldsize-r,r))>0) r-=i;
            if (r>0 || close(fd)==-1) err(1,"%s",OldFile);
    
    
            if((_new=(u_char*)malloc(newsize+1))==NULL)
                err(1,NULL);
    
    
            oldpos=0;newpos=0;
            while(newpos<newsize) {
                /* Read control data */
                for(i=0;i<=2;i++) {
                    lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
                    if ((lenread < 8) || ((cbz2err != BZ_OK) &&
                        (cbz2err != BZ_STREAM_END)))
                        errx(1, "Corrupt patch\n");
                    ctrl[i]=offtin(buf);
                };
    
    
                /* Sanity-check */
                if(newpos+ctrl[0]>newsize)
                    errx(1,"Corrupt patch\n");
    
    
                /* Read diff string */
                lenread = BZ2_bzRead(&dbz2err, dpfbz2, _new + newpos, ctrl[0]);
                if ((lenread < ctrl[0]) ||
                    ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
                    errx(1, "Corrupt patch\n");
    
    
                /* Add old data to diff string */
                for(i=0;i<ctrl[0];i++)
                    if((oldpos+i>=0) && (oldpos+i<oldsize))
                        _new[newpos+i]+=old[oldpos+i];
    
    
                /* Adjust pointers */
                newpos+=ctrl[0];
                oldpos+=ctrl[0];
    
    
                /* Sanity-check */
                if(newpos+ctrl[1]>newsize)
                    errx(1,"Corrupt patch\n");
    
    
                /* Read extra string */
                lenread = BZ2_bzRead(&ebz2err, epfbz2, _new + newpos, ctrl[1]);
                if ((lenread < ctrl[1]) ||
                    ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
                    errx(1, "Corrupt patch\n");
    
    
                /* Adjust pointers */
                    newpos+=ctrl[1];
                    oldpos+=ctrl[2];
                };
    
    
            /* Clean up the bzip2 reads */
            BZ2_bzReadClose(&cbz2err, cpfbz2);
            BZ2_bzReadClose(&dbz2err, dpfbz2);
            BZ2_bzReadClose(&ebz2err, epfbz2);
            if (fclose(cpf) || fclose(dpf) || fclose(epf))
                err(1, "fclose(%s)", PatchFile);
    
    
            /* Write the new file */
            //org:
            //if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
            //new:
            if(((fd=open(NewFile,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))<0) ||
                (write(fd,_new,newsize)!=newsize) || (close(fd)==-1))
                err(1,"%s",NewFile);
    
    
            free(_new);
            free(old);
    
    
            return 0;
        }
    But now how can pass vector to openread function and read?

  4. #4
    Registered User
    Join Date
    Dec 2015
    Posts
    4
    Unfortunatly row 243 that i added not produce the same effect of row 252 that I want eliminate.

    I think these functions must be cange to accept vector instead file pointer:

    Code:
    BZFILE* BZ_API(BZ2_bzReadOpen) 
                       ( int*  bzerror, 
                         FILE* f, 
                         int   verbosity,
                         int   small,
                         void* unused,
                         int   nUnused )
    {
       bzFile* bzf = NULL;
       int     ret;
     
       BZ_SETERR(BZ_OK);
     
       if (f == NULL || 
           (small != 0 && small != 1) ||
           (verbosity < 0 || verbosity > 4) ||
           (unused == NULL && nUnused != 0) ||
           (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
          { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
     
       if (ferror(f))
          { BZ_SETERR(BZ_IO_ERROR); return NULL; };
     
       bzf = malloc ( sizeof(bzFile) );
       if (bzf == NULL) 
          { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
     
       BZ_SETERR(BZ_OK);
     
       bzf->initialisedOk = False;
       bzf->handle        = f;
       bzf->bufN          = 0;
       bzf->writing       = False;
       bzf->strm.bzalloc  = NULL;
       bzf->strm.bzfree   = NULL;
       bzf->strm.opaque   = NULL;
     
       while (nUnused > 0) {
          bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
          unused = ((void*)( 1 + ((UChar*)(unused))  ));
          nUnused--;
       }
     
       ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
       if (ret != BZ_OK)
          { BZ_SETERR(ret); free(bzf); return NULL; };
     
       bzf->strm.avail_in = bzf->bufN;
       bzf->strm.next_in  = bzf->buf;
     
       bzf->initialisedOk = True;
       return bzf;   
    }
     
    int BZ_API(BZ2_bzRead) 
               ( int*    bzerror, 
                 BZFILE* b, 
                 void*   buf, 
                 int     len )
    {
       Int32   n, ret;
       bzFile* bzf = (bzFile*)b;
     
       BZ_SETERR(BZ_OK);
     
       if (bzf == NULL || buf == NULL || len < 0)
          { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
     
       if (bzf->writing)
          { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
     
       if (len == 0)
          { BZ_SETERR(BZ_OK); return 0; };
     
       bzf->strm.avail_out = len;
       bzf->strm.next_out = buf;
     
       while (True) {
     
          if (ferror(bzf->handle)) 
             { BZ_SETERR(BZ_IO_ERROR); return 0; };
     
          if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
             n = fread ( bzf->buf, sizeof(UChar), 
                         BZ_MAX_UNUSED, bzf->handle );
             if (ferror(bzf->handle))
                { BZ_SETERR(BZ_IO_ERROR); return 0; };
             bzf->bufN = n;
             bzf->strm.avail_in = bzf->bufN;
             bzf->strm.next_in = bzf->buf;
          }
     
          ret = BZ2_bzDecompress ( &(bzf->strm) );
     
          if (ret != BZ_OK && ret != BZ_STREAM_END)
             { BZ_SETERR(ret); return 0; };
     
          if (ret == BZ_OK && myfeof(bzf->handle) && 
              bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
             { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
     
          if (ret == BZ_STREAM_END)
             { BZ_SETERR(BZ_STREAM_END);
               return len - bzf->strm.avail_out; };
          if (bzf->strm.avail_out == 0)
             { BZ_SETERR(BZ_OK); return len; };
     
       }
     
       return 0; /*not reached*/
    }
    static Bool myfeof ( FILE* f )
    {
       Int32 c = fgetc ( f );
       if (c == EOF) return True;
       ungetc ( c, f );
       return False;
    }
    Last edited by Salem; 12-27-2015 at 03:51 PM. Reason: fixed code tags, but it's hopeless

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You've only done an half-assed job of what I told you to do.

    Do the same for
    fopen
    fclose
    fread
    fwrite
    ftell
    f....anyotherfunctiontakingFILE* as a parameter.

    But then you have to also consider what the POSIX API functions open/read/write/close etc have to do as well.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Dec 2015
    Posts
    4
    I have change all functions:

    Code:
    	/*-
    	 * Copyright 2003-2005 Colin Percival
    	 * All rights reserved
    	 *
    	 * Redistribution and use in source and binary forms, with or without
    	 * modification, are permitted providing that the following conditions 
    	 * are met:
    	 * 1. Redistributions of source code must retain the above copyright
    	 *    notice, this list of conditions and the following disclaimer.
    	 * 2. Redistributions in binary form must reproduce the above copyright
    	 *    notice, this list of conditions and the following disclaimer in the
    	 *    documentation and/or other materials provided with the distribution.
    	 *
    	 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    	 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    	 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    	 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
    	 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    	 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    	 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    	 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    	 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    	 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    	 * POSSIBILITY OF SUCH DAMAGE.
    	*/
    
    
    	#include <stdlib.h>
    	#include <stdio.h>
    	//#include <err.h>
    	#include "bzlib.h"
    	#include <io.h>
    	#include <fcntl.h>
    
    
    
    
    	#include <sys/types.h>
    	typedef unsigned char u_char;
    	typedef signed int ssize_t;
    
    
    	template<class T1, class T2>
    	void err(int i, const char* str, T1 arg1, T2 arg2) {
    		char lastErrorTxt[1024];
    		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL);
    		printf("%s",lastErrorTxt);
    		printf(str, arg1, arg2);
    		exit(i);
    	}
    	template<class T>
    	void err(int i, const char* str, T arg) {
    		char lastErrorTxt[1024];
    		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL);
    		printf("%s",lastErrorTxt);
    		printf(str, arg);
    		exit(i);
    	}
    	void err(int i, const char* str) {
    		char lastErrorTxt[1024];
    		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL);
    		printf("%s",lastErrorTxt);
    		if (str!=NULL) {
    			printf("%s",str);
    		}
    		exit(i);
    	}
    	template<class T>
    	void errx(int i, const char* str, T arg) {
    		printf(str, arg);
    		exit(i);
    	}
    	void errx(int i, const char* str) {
    		printf("%s",str);
    		exit(i);
    	}
    
    
    
    
    	static off_t offtin(u_char *buf)
    	{
    		off_t y;
    
    
    		y=buf[7]&0x7F;
    		y=y*256;y+=buf[6];
    		y=y*256;y+=buf[5];
    		y=y*256;y+=buf[4];
    		y=y*256;y+=buf[3];
    		y=y*256;y+=buf[2];
    		y=y*256;y+=buf[1];
    		y=y*256;y+=buf[0];
    
    
    		if(buf[7]&0x80) y=-y;
    
    
    		return y;
    	}
    
    
    	int my_fseek(FILE *stream, long offset, int whence)
    	{
    		return fseek(stream, offset, whence);
    	}
    	
    	FILE *my_fopen(const char * filename, const char * mode)
    	{
    		return fopen(filename, mode);
    	}
    	
    	size_t my_fread(void *buffer, size_t size, size_t count, FILE *stream)
    	{
    
    
    		return fread(buffer, size, count, stream);
    	}
    
    
    	int my_fclose(FILE * filestream)
    	{
    		return fclose(filestream);
    	}
    
    
    	int my_ftell(FILE *filestream)
    	{
    		return ftell(filestream);
    	}
    
    
    	int main(void)
    	{
    		FILE * f, * cpf, * dpf, * epf;
    		BZFILE * cpfbz2, * dpfbz2, * epfbz2;
    		int cbz2err, dbz2err, ebz2err;
    		int fd;
    		ssize_t oldsize,newsize;
    		ssize_t bzctrllen,bzdatalen;
    		u_char header[32],buf[8];
    		u_char *old, *_new;
    		off_t oldpos,newpos;
    		off_t ctrl[3];
    		off_t lenread;
    		off_t i;
    
    
    		char OldFile[]= "old.txt";
    		char NewFile[]= "newPatched.txt";
    		char PatchFile[]= "patch.txt";
    		char * VECTOR_PATCH;//[10*1024];
    		char * VECTOR_OLD;//[200*1024];
    		unsigned char c;
    		int j,k,m,fileLen;
    	
    		/* load the file old in a vector---------------------------------------------------------------*/
    		//Open file
    		f = my_fopen(PatchFile, "rb");
    		if (!f)
    		{
    			fprintf(stderr, "Unable to open file %s", PatchFile);
    			return 1;
    		}
    	
    		//Get file length
    		my_fseek(f, 0, SEEK_END);				//fseek(f, 0, SEEK_END);
    		fileLen=my_ftell(f);
    		my_fseek(f, 0, SEEK_SET);				//fseek(f, 0, SEEK_END);
    
    
    		//Allocate memory
    		VECTOR_PATCH=(char *)malloc(fileLen+1);
    		if (!VECTOR_PATCH)
    		{
    			fprintf(stderr, "Memory error!");
    									my_fclose(f);
    			return 1;
    		}
    
    
    		//Read file contents into buffer
    		my_fread(VECTOR_PATCH, fileLen, 1, f);
    		my_fclose(f);
    
    
    
    
    		/* load the file old in a vector--------------------------------------------------------------------------------------*/
    
    
    		f = my_fopen(OldFile, "rb");
    		if (!f)
    		{
    			fprintf(stderr, "Unable to open file %s", OldFile);
    			return 1;
    		}
    	
    		//Get file length
    		my_fseek(f, 0, SEEK_END);
    		fileLen=my_ftell(f);
    		my_fseek(f, 0, SEEK_SET);
    
    
    		//Allocate memory
    		VECTOR_OLD=(char *)malloc(fileLen+1);
    		if (!VECTOR_OLD)
    		{
    			fprintf(stderr, "Memory error!");
    									fclose(f);
    			return 1;
    		}
    
    
    		//Read file contents into buffer
    		my_fread(VECTOR_OLD, fileLen, 1, f);
    		my_fclose(f);
    
    
    
    
    
    
    
    
    		/*
    		File format:
    			0	8	"BSDIFF40"
    			8	8	X
    			16	8	Y
    			24	8	sizeof(newfile)
    			32	X	bzip2(control block)
    			32+X	Y	bzip2(diff block)
    			32+X+Y	???	bzip2(extra block)
    		with control block a set of triples (x,y,z) meaning "add x bytes
    		from oldfile to x bytes from the diff block; copy y bytes from the
    		extra block; seek forwards in oldfile by z bytes".
    		*/
    
    
    		/* Read header */
    
    
    		for(i=0; i<32;i++)
    			header[i] = VECTOR_PATCH[i];
    
    
    		/* Check for appropriate magic */
    		if (memcmp(header, "BSDIFF40", 8) != 0)
    			errx(1, "Corrupt patch\n");
    
    
    		/* Read lengths from header */
    		bzctrllen=offtin(header+8);
    		bzdatalen=offtin(header+16);
    		newsize=offtin(header+24);
    		if((bzctrllen<0) || (bzdatalen<0) || (newsize<0))
    			errx(1,"Corrupt patch\n");
    
    
    		/* open it via libbzip2 at the right places */
    		if ((cpf = my_fopen(PatchFile, "rb")) == NULL)
    			err(1, "fopen(%s)", PatchFile);
    		if (my_fseek(cpf, 32, SEEK_SET))
    			err(1, "fseeko(%s, %d)", PatchFile, 32);
    	
    
    
    	/*----------------------------------------------------------------------------------*/
    		if ((cpf = my_fopen(PatchFile, "rb")) == NULL)
    			err(1, "fopen(%s)", PatchFile);
    		if (my_fseek(cpf, 32, SEEK_SET))
    			err(1, "fseeko(%s, %d)", PatchFile, 32);
    		if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
    			errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
    	/*----------------------------------------------------------------------------------*/
    
    
    		if ((dpf = fopen(PatchFile, "rb")) == NULL)
    			err(1, "fopen(%s)", PatchFile);
    		if (my_fseek(dpf, 32 + bzctrllen, SEEK_SET))
    			err(1, "fseeko(%s, %d)", PatchFile,
    				(32 + bzctrllen));
    		if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
    			errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
    		if ((epf = fopen(PatchFile, "rb")) == NULL)
    			err(1, "fopen(%s)", PatchFile);
    		if (my_fseek(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
    			err(1, "fseeko(%s, %d)", PatchFile,
    				(32 + bzctrllen + bzdatalen));
    		if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
    			errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
    
    
    		//org:
    		//if(((fd=open(argv[1],O_RDONLY,0))<0) ||
    		//	((oldsize=lseek(fd,0,SEEK_END))==-1) ||
    		//	((old=malloc(oldsize+1))==NULL) ||
    		//	(lseek(fd,0,SEEK_SET)!=0) ||
    		//	(read(fd,old,oldsize)!=oldsize) ||
    		//	(close(fd)==-1)) err(1,"%s",argv[1]);
    		//new:
    		//Read in chunks, don't rely on read always returns full data!
    		if(((fd=open(OldFile,O_RDONLY|O_BINARY|O_NOINHERIT,0))<0) ||
    			((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
    			((old=(u_char*)malloc(oldsize+1))==NULL) ||
    			(_lseek(fd,0,SEEK_SET)!=0))
    					err(1,"%s",OldFile);
    		int r=oldsize;
    		while (r>0 && (i=read(fd,old+oldsize-r,r))>0) r-=i;
    		if (r>0 || close(fd)==-1) err(1,"%s",OldFile);
    
    
    		if((_new=(u_char*)malloc(newsize+1))==NULL)
    			err(1,NULL);
    
    
    		oldpos=0;newpos=0;
    		while(newpos<newsize) {
    			/* Read control data */
    			for(i=0;i<=2;i++) {
    				lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
    				if ((lenread < 8) || ((cbz2err != BZ_OK) &&
    					(cbz2err != BZ_STREAM_END)))
    					errx(1, "Corrupt patch\n");
    				ctrl[i]=offtin(buf);
    			};
    
    
    			/* Sanity-check */
    			if(newpos+ctrl[0]>newsize)
    				errx(1,"Corrupt patch\n");
    
    
    			/* Read diff string */
    			lenread = BZ2_bzRead(&dbz2err, dpfbz2, _new + newpos, ctrl[0]);
    			if ((lenread < ctrl[0]) ||
    				((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
    				errx(1, "Corrupt patch\n");
    
    
    			/* Add old data to diff string */
    			for(i=0;i<ctrl[0];i++)
    				if((oldpos+i>=0) && (oldpos+i<oldsize))
    					_new[newpos+i]+=old[oldpos+i];
    
    
    			/* Adjust pointers */
    			newpos+=ctrl[0];
    			oldpos+=ctrl[0];
    
    
    			/* Sanity-check */
    			if(newpos+ctrl[1]>newsize)
    				errx(1,"Corrupt patch\n");
    
    
    			/* Read extra string */
    			lenread = BZ2_bzRead(&ebz2err, epfbz2, _new + newpos, ctrl[1]);
    			if ((lenread < ctrl[1]) ||
    				((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
    				errx(1, "Corrupt patch\n");
    
    
    			/* Adjust pointers */
    				newpos+=ctrl[1];
    				oldpos+=ctrl[2];
    			};
    
    
    		/* Clean up the bzip2 reads */
    		BZ2_bzReadClose(&cbz2err, cpfbz2);
    		BZ2_bzReadClose(&dbz2err, dpfbz2);
    		BZ2_bzReadClose(&ebz2err, epfbz2);
    		if (my_fclose(cpf) || my_fclose(dpf) || my_fclose(epf))
    			err(1, "fclose(%s)", PatchFile);
    
    
    		/* Write the new file */
    		//org:
    		//if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
    		//new:
    		if(((fd=open(NewFile,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))<0) ||
    			(write(fd,_new,newsize)!=newsize) || (close(fd)==-1))
    			err(1,"%s",NewFile);
    
    
    		free(_new);
    		free(old);
    
    
    		return 0;
    	}
    When You write: "When you have done that for all the FILE* API you're using, then you can start to redefine the interface to use arrays" You are talking about fill the FILE structure with all field to obtain file from vector of chars?
    I thinking this structure:

    Code:
    struct _iobuf {
            char *_ptr;
            int   _cnt;
            char *_base;
            int   _flag;
            int   _file;
            int   _charbuf;
            int   _bufsiz;
            char *_tmpfname;
            };
    typedef struct _iobuf FILE;

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    OK, so now you refactor all the my_ functions to use arrays in memory.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 11-28-2012, 09:16 AM
  2. Replies: 11
    Last Post: 09-25-2011, 12:22 AM
  3. Replies: 4
    Last Post: 07-06-2006, 02:53 AM
  4. differences between fopen & Create/WriteFile creating a file?
    By willc0de4food in forum C Programming
    Replies: 16
    Last Post: 04-25-2006, 04:37 PM
  5. Replies: 3
    Last Post: 12-22-2002, 02:48 PM

Tags for this Thread