|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.