Annotation of researchv10dc/cmd/odist/pax/src/lib/libodelta/update.c, revision 1.1.1.1

1.1       root        1: #include       "update.h"
                      2: 
                      3: /*
                      4: **     Reconstruct a target file from a source file and a delta file.
                      5: **     The delta file contain block move instructions computed by delta().
                      6: **
                      7: **     Written by Kiem-Phong Vo, 5/20/88
                      8: */
                      9: 
                     10: /* buffers for delta and target files */
                     11: static unsigned char   *Ddata, *Dnext, *Dend,
                     12:                        *Tdata, *Tnext, *Tend;
                     13: static int             Dfd, Tfd;
                     14: 
                     15: #define delinit(buf,size,fd)   (Ddata=Dnext=Dend=buf, Dfd=fd)
                     16: #define tarinit(buf,size,fd)   (Tdata=Tnext=buf, Tend=buf+size, Tfd=fd)
                     17: #define tarflush()     (write(Tfd,Tdata,Tnext-Tdata) >= 0 ? (Tnext=Tdata,0) : -1)
                     18: 
                     19: /* read a byte from delta file */
                     20: static int delgetc()
                     21: {
                     22:        if(Dnext >= Dend)
                     23:        {
                     24:                register int n;
                     25:                if((n = read(Dfd,Ddata,BUFSIZE)) <= 0)
                     26:                        return -1;
                     27:                Dnext = Ddata, Dend = Ddata+n;
                     28:        }
                     29:        return (int)(*Dnext++);
                     30: }
                     31: 
                     32: /* read a long value from delta file */
                     33: static long delgetl(n)
                     34: register int   n;
                     35: {
                     36:        register long   lv;
                     37: 
                     38:        lv = 0;
                     39:        for(; n > 0; --n)
                     40:        {
                     41:                register int v;
                     42:                if((v = delgetc()) < 0)
                     43:                        return -1;
                     44:                lv = lv*256 + v;
                     45:        }
                     46:        return lv;
                     47: }
                     48: 
                     49: /* transfer a number of bytes from a file to the target file */
                     50: static int filetransfer(fd,n)
                     51: int    fd;
                     52: long   n;
                     53: {
                     54:        while(n > 0)
                     55:        {
                     56:                register int r;
                     57: 
                     58:                if(Tnext >= Tend)
                     59:                        if(tarflush() < 0)
                     60:                                return -1;
                     61:                r = n > (Tend-Tnext) ? (Tend-Tnext) : n;
                     62:                if(read(fd,Tnext,r) != r)
                     63:                        return -1;
                     64:                Tnext += r;
                     65:                n -= r;
                     66:        }
                     67:        return 0;
                     68: }
                     69: 
                     70: /* transfer a number of bytes from a memory area to the target file */
                     71: static int memtransfer(addr,n)
                     72: unsigned char  *addr;
                     73: register long  n;
                     74: {
                     75:        while(n > 0)
                     76:        {
                     77:                register int r;
                     78: 
                     79:                if(Tnext >= Tend)
                     80:                        if(tarflush() < 0)
                     81:                                return -1;
                     82:                r = n > (Tend-Tnext) ? (Tend-Tnext) : n;
                     83:                memcopy(Tnext,addr,r);
                     84:                Tnext += r;
                     85:                addr += r;
                     86:                n -= r;
                     87:        }
                     88:        return 0;
                     89: }
                     90: 
                     91: /* transfer a number of bytes from delta to target */
                     92: static int deltransfer(n)
                     93: long   n;
                     94: {
                     95:        register int d;
                     96: 
                     97:        /* transfer what's already in core */
                     98:        if((d = Dend-Dnext) > 0)
                     99:        {
                    100:                register int w = n <= d ? n : d;
                    101: 
                    102:                if(w > (Tend-Tnext))
                    103:                        if(tarflush() < 0)
                    104:                                return -1;
                    105: 
                    106:                /* copy from the delta buffer */
                    107:                memcopy(Tnext,Dnext,w);
                    108:                Dnext += w;
                    109:                Tnext += w;
                    110:                n -= w;
                    111:        }
                    112: 
                    113:        return n > 0 ? filetransfer(Dfd,n) : 0;
                    114: }
                    115: 
                    116: update(srcfd,offset,delfd,tarfd)
                    117: int    srcfd;
                    118: long   offset;
                    119: int    delfd;
                    120: int    tarfd;
                    121: {
                    122:        register int    i;
                    123:        register long   n_src, n_tar;
                    124:        unsigned char   delbuf[BUFSIZE], tarbuf[BUFSIZE];
                    125:        unsigned char   *src, *tar, *malloc();
                    126: 
                    127:        /* start buffering system for delta file */
                    128:        delinit(delbuf,BUFSIZE,delfd);
                    129: 
                    130:        /* read the file sizes */
                    131:        if((i = delgetc()) < 0 || (i&DELTA_TYPE) != DELTA_TYPE)
                    132:                return -1;
                    133:        if((n_src = delgetl((i>>3)&07)) < 0 || (n_tar = delgetl(i&07)) < 0)
                    134:                return -1;
                    135: 
                    136:        /* make data area for target file */
                    137:        if(tar = malloc(n_tar)) /* assignment = */
                    138:                tarinit(tar,n_tar,tarfd);
                    139:        else    tarinit(tarbuf,BUFSIZE,tarfd);
                    140: 
                    141:        /* read in source file if possible to avoid lseek */
                    142:        if(src = malloc(n_src)) /* assignment = */
                    143:        {
                    144:                lseek(srcfd,offset,0);
                    145:                if(read(srcfd,src,n_src) != n_src)
                    146:                        return -1;
                    147:        }
                    148: 
                    149:        while((i = delgetc()) >= 0)
                    150:        {
                    151:                register long   size, addr;
                    152: 
                    153:                if((size = delgetl((i>>3)&07)) < 0)
                    154:                        return -1;
                    155:                switch(i&DELTA_TYPE)
                    156:                {
                    157:                default :
                    158:                        return -1;
                    159:                case DELTA_TYPE :
                    160:                        /* sync delta file pointer */ 
                    161:                        if((addr = Dend-Dnext) > 0)
                    162:                                lseek(Dfd,-addr,1);
                    163:                        /* flush output buffer */
                    164:                        if(tarflush() < 0)
                    165:                                return -1;
                    166:                        /* free space used */
                    167:                        if(src)
                    168:                                free(src);
                    169:                        if(tar)
                    170:                                free(tar);
                    171:                        return 0;
                    172:                case DELTA_MOVE :
                    173:                        if((addr = delgetl(i&07)) < 0)
                    174:                                return -1;
                    175:                        if(src)
                    176:                        {
                    177:                                if(memtransfer(src+addr,size) < 0)
                    178:                                        return -1;
                    179:                        }
                    180:                        else
                    181:                        {
                    182:                                if(lseek(srcfd,offset+addr,0) < 0)
                    183:                                        return -1;
                    184:                                if(filetransfer(srcfd,size) < 0)
                    185:                                        return -1;
                    186:                        }
                    187:                        break;
                    188:                case DELTA_ADD :
                    189:                        if(deltransfer(size) < 0)
                    190:                                return -1;
                    191:                        break;
                    192:                }
                    193:        }
                    194: 
                    195:        /* should never get here */
                    196:        return -1;
                    197: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.