public void BuildHashTable(SumStruct s) { for (var i = 0; i < s.Count; i++) { _targets.Add(new Target()); } for (var i = 0; i < s.Count; i++) { _targets[i].I = i; _targets[i].T = GetTag(s.Sums[i].Sum1); } _targets.Sort(0, s.Count, new TargetComparer()); for (var i = 0; i < Tablesize; i++) { _tagTable[i] = NullTag; } for (var i = s.Count; i-- > 0;) { _tagTable[_targets[i].T] = i; } }
public void BuildHashTable(SumStruct s) { for (int i = 0; i < s.count; i++) { targets.Add(new Target()); } for (int i = 0; i < s.count; i++) { ((Target)targets[i]).i = i; ((Target)targets[i]).t = GetTag(s.sums[i].sum1); } targets.Sort(0, s.count, new TargetComparer()); for (int i = 0; i < TABLESIZE; i++) { tagTable[i] = NULL_TAG; } for (int i = s.count; i-- > 0;) { tagTable[((Target)targets[i]).t] = i; } }
public void WriteSumHead(IOStream f, SumStruct sum) { if(sum == null) sum = new SumStruct(); f.writeInt(sum.count); f.writeInt((int)sum.bLength); if (options.protocolVersion >= 27) f.writeInt(sum.s2Length); f.writeInt((int)sum.remainder); }
public void WriteSumHead(IOStream f, SumStruct sum) { if (sum == null) { sum = new SumStruct(); } f.writeInt(sum.count); f.writeInt((int)sum.bLength); if (options.protocolVersion >= 27) { f.writeInt(sum.s2Length); } f.writeInt((int)sum.remainder); }
public void WriteSumHead(IoStream f, SumStruct sum) { if (sum == null) { sum = new SumStruct(); } f.WriteInt(sum.Count); f.WriteInt((int)sum.BLength); if (_options.ProtocolVersion >= 27) { f.WriteInt(sum.S2Length); } f.WriteInt((int)sum.Remainder); }
public SumStruct ReceiveSums(ClientInfo cInfo) { var f = cInfo.IoStream; var s = new SumStruct(); int i; var offset = 0; ReadSumHead(cInfo, ref s); s.Sums = null; if (_options.Verbose > 3) { Log.WriteLine("count=" + s.Count + " n=" + s.BLength + " rem=" + s.Remainder); } if (s.Count == 0) { return(s); } s.Sums = new SumBuf[s.Count]; for (i = 0; i < s.Count; i++) { s.Sums[i] = new SumBuf(); s.Sums[i].Sum1 = (UInt32)f.ReadInt(); s.Sums[i].Sum2 = f.ReadBuffer(s.S2Length); s.Sums[i].Offset = offset; s.Sums[i].Flags = 0; if (i == s.Count - 1 && s.Remainder != 0) { s.Sums[i].Len = s.Remainder; } else { s.Sums[i].Len = s.BLength; } offset += (int)s.Sums[i].Len; if (_options.Verbose > 3) { Log.WriteLine("chunk[" + i + "] len=" + s.Sums[i].Len); } } s.FLength = offset; return(s); }
public SumStruct ReceiveSums(ClientInfo cInfo) { IOStream f = cInfo.IoStream; SumStruct s = new SumStruct(); int i; int offset = 0; ReadSumHead(cInfo, ref s); s.sums = null; if (options.verbose > 3) { Log.WriteLine("count=" + s.count + " n=" + s.bLength + " rem=" + s.remainder); } if (s.count == 0) { return(s); } s.sums = new SumBuf[s.count]; for (i = 0; i < s.count; i++) { s.sums[i] = new SumBuf(); s.sums[i].sum1 = (UInt32)f.readInt(); s.sums[i].sum2 = f.ReadBuffer(s.s2Length); s.sums[i].offset = offset; s.sums[i].flags = 0; if (i == s.count - 1 && s.remainder != 0) { s.sums[i].len = s.remainder; } else { s.sums[i].len = s.bLength; } offset += (int)s.sums[i].len; if (options.verbose > 3) { Log.WriteLine("chunk[" + i + "] len=" + s.sums[i].len); } } s.fLength = offset; return(s); }
public void Matched(IoStream f, SumStruct s, MapFile buf, int offset, int i, Sum sum) { var n = offset - _lastMatch; int j; if (_options.Verbose > 2 && i >= 0) { Log.WriteLine("match at " + offset + " last_match=" + _lastMatch + " j=" + i + " len=" + s.Sums[i].Len + " n=" + n); } var token = new Token(_options); token.SendToken(f, i, buf, _lastMatch, n, (int)(i < 0 ? 0 : s.Sums[i].Len)); _dataTransfer += n; if (i >= 0) { Options.Stats.MatchedData += s.Sums[i].Len; n += (int)s.Sums[i].Len; } for (j = 0; j < n; j += ChunkSize) { var n1 = Math.Min(ChunkSize, n - j); var off = buf.MapPtr(_lastMatch + j, n1); sum.Update(buf.P, off, n1); } if (i >= 0) { _lastMatch = (int)(offset + s.Sums[i].Len); } else { _lastMatch = offset; } if (buf != null && _options.DoProgress) { Progress.ShowProgress(_lastMatch, buf.FileSize); if (i == -1) { Progress.EndProgress(buf.FileSize); } } }
public void Matched(IOStream f, SumStruct s, MapFile buf, int offset, int i, Sum sum) { int n = offset - lastMatch; int j; if (options.verbose > 2 && i >= 0) { Log.WriteLine("match at " + offset + " last_match=" + lastMatch + " j=" + i + " len=" + s.sums[i].len + " n=" + n); } Token token = new Token(options); token.SendToken(f, i, buf, lastMatch, n, (int)(i < 0?0:s.sums[i].len)); dataTransfer += n; if (i >= 0) { Options.stats.matchedData += s.sums[i].len; n += (int)s.sums[i].len; } for (j = 0; j < n; j += CHUNK_SIZE) { int n1 = Math.Min(CHUNK_SIZE, n - j); int off = buf.MapPtr(lastMatch + j, n1); sum.Update(buf.p, off, n1); } if (i >= 0) { lastMatch = (int)(offset + s.sums[i].len); } else { lastMatch = offset; } if (buf != null && options.doProgress) { Progress.ShowProgress(lastMatch, buf.fileSize); if (i == -1) { Progress.EndProgress(buf.fileSize); } } }
public void GenerateAndSendSums(Stream fd, long len, IoStream f, Stream fCopy) { long i; MapFile mapBuf; var sum = new SumStruct(); long offset = 0; SumSizesSqroot(sum, (UInt64)len); if (len > 0) { mapBuf = new MapFile(fd, (int)len, Options.MaxMapSize, (int)sum.BLength); } else { mapBuf = null; } WriteSumHead(f, sum); for (i = 0; i < sum.Count; i++) { var n1 = (UInt32)Math.Min(len, sum.BLength); var off = mapBuf.MapPtr((int)offset, (int)n1); var map = mapBuf.P; var sum1 = CheckSum.GetChecksum1(map, off, (int)n1); var sum2 = new byte[CheckSum.SumLength]; sum2 = _checkSum.GetChecksum2(map, off, (int)n1); if (_options.Verbose > 3) { Log.WriteLine("chunk[" + i + "] offset=" + offset + " len=" + n1 + " sum1=" + sum1); } f.WriteInt((int)sum1); f.Write(sum2, 0, sum.S2Length); len -= n1; offset += n1; } if (mapBuf != null) { mapBuf = null; } }
public void GenerateAndSendSums(Stream fd, long len, IOStream f, Stream fCopy) { long i; MapFile mapBuf; SumStruct sum = new SumStruct(); long offset = 0; SumSizesSqroot(sum, (UInt64)len); if (len > 0) { mapBuf = new MapFile(fd, (int)len, Options.MAX_MAP_SIZE, (int)sum.bLength); } else { mapBuf = null; } WriteSumHead(f, sum); for (i = 0; i < sum.count; i++) { UInt32 n1 = (UInt32)Math.Min(len, sum.bLength); int off = mapBuf.MapPtr((int)offset, (int)n1); byte[] map = mapBuf.p; UInt32 sum1 = CheckSum.GetChecksum1(map, off, (int)n1); byte[] sum2 = new byte[CheckSum.SUM_LENGTH]; sum2 = checkSum.GetChecksum2(map, off, (int)n1); if (options.verbose > 3) { Log.WriteLine("chunk[" + i + "] offset=" + offset + " len=" + n1 + " sum1=" + sum1); } f.writeInt((int)sum1); f.Write(sum2, 0, sum.s2Length); len -= n1; offset += n1; } if (mapBuf != null) { mapBuf = null; } }
public void ReadSumHead(ClientInfo clientInfo, ref SumStruct sum) { var ioStream = clientInfo.IoStream; sum.Count = ioStream.ReadInt(); sum.BLength = (UInt32)ioStream.ReadInt(); if (_options.ProtocolVersion < 27) { sum.S2Length = _checkSum.Length; } else { sum.S2Length = ioStream.ReadInt(); if (sum.S2Length > CheckSum.Md4SumLength) { WinRsync.Exit("Invalid checksum length " + sum.S2Length, clientInfo); } } sum.Remainder = (UInt32)ioStream.ReadInt(); }
public void ReadSumHead(ClientInfo clientInfo, ref SumStruct sum) { IOStream ioStream = clientInfo.IoStream; sum.count = ioStream.readInt(); sum.bLength = (UInt32)ioStream.readInt(); if (options.protocolVersion < 27) { sum.s2Length = checkSum.length; } else { sum.s2Length = ioStream.readInt(); if (sum.s2Length > CheckSum.MD4_SUM_LENGTH) { MainClass.Exit("Invalid checksum length " + sum.s2Length, clientInfo); } } sum.remainder = (UInt32)ioStream.readInt(); }
public void BuildHashTable(SumStruct s) { for(int i = 0; i < s.count; i++) targets.Add(new Target()); for (int i = 0; i < s.count; i++) { ((Target)targets[i]).i = i; ((Target)targets[i]).t = GetTag(s.sums[i].sum1); } targets.Sort(0, s.count, new TargetComparer()); for (int i = 0; i < TABLESIZE; i++) tagTable[i] = NULL_TAG; for (int i = s.count; i-- > 0;) { tagTable[((Target)targets[i]).t] = i; } }
public void HashSearch(IOStream f,SumStruct s, MapFile buf, int len, Sum _sum) { int offset, end, backup; UInt32 k; int wantI; byte[] sum2 = new byte[CheckSum.SUM_LENGTH]; UInt32 s1, s2, sum; int more; byte[] map; wantI = 0; if (options.verbose > 2) Log.WriteLine("hash search ob=" + s.bLength +" len=" + len); k = (UInt32)Math.Min(len, s.bLength); int off = buf.MapPtr(0, (int)k); map = buf.p; UInt32 g = s.sums[0].sum1; sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (options.verbose > 3) Log.WriteLine("sum=" + sum +" k=" + k); offset = 0; end = (int)(len + 1 - s.sums[s.count-1].len); if (options.verbose > 3) Log.WriteLine("hash search s.bLength=" + s.bLength +" len=" + len +" count=" + s.count); do { UInt32 t = GetTag2(s1,s2); bool doneCsum2 = false; int j = tagTable[t]; if (options.verbose > 4) Log.WriteLine("offset=" + offset + " sum=" + sum); if (j == NULL_TAG) goto null_tag; sum = (s1 & 0xffff) | (s2 << 16); tagHits++; do { UInt32 l; int i = ((Target)targets[j]).i; if (sum != s.sums[i].sum1) continue; l = (UInt32)Math.Min(s.bLength, len-offset); if (l != s.sums[i].len) continue; if (options.verbose > 3) Log.WriteLine("potential match at " + offset + " target=" + j +" " + i + " sum=" + sum); if (!doneCsum2) { off = buf.MapPtr(offset, (int)l); map = buf.p; CheckSum cs = new CheckSum(options); sum2 = cs.GetChecksum2(map, off, (int)l); doneCsum2 = true; } if (Util.MemCmp(sum2, 0, s.sums[i].sum2, 0, s.s2Length) != 0) { falseAlarms++; continue; } if (i != wantI && wantI < s.count && (!options.inplace || options.makeBackups || s.sums[wantI].offset >= offset || (s.sums[wantI].flags & SUMFLG_SAME_OFFSET) != 0) && sum == s.sums[wantI].sum1 && Util.MemCmp(sum2, 0, s.sums[wantI].sum2, 0, s.s2Length) == 0) { i = wantI; } set_want_i: wantI = i + 1; Matched(f,s,buf,offset,i,_sum); offset += (int)(s.sums[i].len - 1); k = (UInt32)Math.Min(s.bLength, len-offset); off = buf.MapPtr(offset, (int)k); sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; matches++; break; } while (++j < s.count && ((Target)targets[j]).t == t); null_tag: backup = offset - lastMatch; if (backup < 0) backup = 0; more = (offset + k) < len ? 1 : 0; off = buf.MapPtr(offset - backup, (int)(k + more + backup))+ backup; s1 -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET); s2 -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET); off = (k + off >= map.Length) ? (int)(map.Length-k-1) : off; if (more != 0) { s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CHAR_OFFSET); s2 += s1; } else --k; if (backup >= CHUNK_SIZE + s.bLength && end - offset > CHUNK_SIZE) Matched(f,s,buf,(int)(offset - s.bLength), -2, _sum); } while (++offset < end); Matched(f,s,buf,len,-1, _sum); buf.MapPtr(len-1,1); }
public void Matched(IOStream f, SumStruct s, MapFile buf, int offset, int i, Sum sum) { int n = offset - lastMatch; int j; if (options.verbose > 2 && i >= 0) Log.WriteLine("match at " + offset +" last_match=" + lastMatch + " j=" + i + " len=" + s.sums[i].len + " n=" + n); Token token = new Token(options); token.SendToken(f,i,buf,lastMatch,n,(int)(i<0?0:s.sums[i].len)); dataTransfer += n; if (i >= 0) { Options.stats.matchedData += s.sums[i].len; n += (int)s.sums[i].len; } for (j = 0; j < n; j += CHUNK_SIZE) { int n1 = Math.Min(CHUNK_SIZE,n-j); int off = buf.MapPtr(lastMatch + j, n1); sum.Update(buf.p , off, n1); } if (i >= 0) lastMatch = (int)(offset + s.sums[i].len); else lastMatch = offset; if (buf != null && options.doProgress) { Progress.ShowProgress(lastMatch, buf.fileSize); if (i == -1) Progress.EndProgress(buf.fileSize); } }
public void MatchSums(IOStream f, SumStruct s, MapFile buf, int len) { byte[] fileSum = new byte[CheckSum.MD4_SUM_LENGTH]; lastMatch = 0; falseAlarms = 0; tagHits = 0; matches = 0; dataTransfer = 0; Sum sum = new Sum(options); sum.Init(options.checksumSeed); if (len > 0 && s.count>0) { BuildHashTable(s); if (options.verbose > 2) Log.WriteLine("built hash table"); HashSearch(f,s,buf,len, sum); if (options.verbose > 2) Log.WriteLine("done hash search"); } else { for (int j = 0; j < len - CHUNK_SIZE; j += CHUNK_SIZE) { int n1 = Math.Min(CHUNK_SIZE,(len-CHUNK_SIZE)-j); Matched(f,s,buf,j+n1,-2, sum); } Matched(f,s,buf,len,-1,sum); } fileSum = sum.End(); if (buf != null && buf.status) fileSum[0]++; if (options.verbose > 2) Log.WriteLine("sending fileSum"); f.Write(fileSum, 0, CheckSum.MD4_SUM_LENGTH); targets.Clear(); if (options.verbose > 2) Log.WriteLine("falseAlarms=" + falseAlarms + " tagHits=" + tagHits + " matches=" + matches); totalTagHits += tagHits; totalFalseAlarms += falseAlarms; totalMatches += matches; Options.stats.literalData += dataTransfer; }
public bool ReceiveData(ClientInfo clientInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize) { IOStream f = clientInfo.IoStream; byte[] fileSum1 = new byte[CheckSum.MD4_SUM_LENGTH]; byte[] fileSum2 = new byte[CheckSum.MD4_SUM_LENGTH]; byte[] data = new byte[Match.CHUNK_SIZE]; SumStruct sumStruct = new SumStruct(); MapFile mapBuf = null; Sender sender = new Sender(options); sender.ReadSumHead(clientInfo, ref sumStruct); int offset = 0; UInt32 len; if (fdR != null && sizeR > 0) { int mapSize = (int)Math.Max(sumStruct.bLength * 2, 16 * 1024); mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sumStruct.bLength); if (options.verbose > 2) { Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR); } } Sum sum = new Sum(options); sum.Init(options.checksumSeed); int i; Token token = new Token(options); while ((i = token.ReceiveToken(f, ref data, 0)) != 0) { if (options.doProgress) { Progress.ShowProgress(offset, totalSize); } if (i > 0) { if (options.verbose > 3) { Log.WriteLine("data recv " + i + " at " + offset); } Options.stats.literalData += i; sum.Update(data, 0, i); if (fd != null && FileIO.WriteFile(fd, data, 0, i) != i) { goto report_write_error; } offset += i; continue; } i = -(i + 1); int offset2 = (int)(i * sumStruct.bLength); len = sumStruct.bLength; if (i == sumStruct.count - 1 && sumStruct.remainder != 0) { len = sumStruct.remainder; } Options.stats.matchedData += len; if (options.verbose > 3) { Log.WriteLine("chunk[" + i + "] of size " + len + " at " + offset2 + " offset=" + offset); } byte[] map = null; int off = 0; if (mapBuf != null) { off = mapBuf.MapPtr(offset2, (int)len); map = mapBuf.p; token.SeeToken(map, offset, (int)len); sum.Update(map, off, (int)len); } if (options.inplace) { if (offset == offset2 && fd != null) { offset += (int)len; if (fd.Seek(len, SeekOrigin.Current) != offset) { MainClass.Exit("seek failed on " + Util.fullFileName(fileName), clientInfo); } continue; } } if (fd != null && FileIO.WriteFile(fd, map, off, (int)len) != (int)len) { goto report_write_error; } offset += (int)len; } if (options.doProgress) { Progress.EndProgress(totalSize); } if (fd != null && offset > 0 && FileIO.SparseEnd(fd) != 0) { MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo); } fileSum1 = sum.End(); if (mapBuf != null) { mapBuf = null; } fileSum2 = f.ReadBuffer(CheckSum.MD4_SUM_LENGTH); if (options.verbose > 2) { Log.WriteLine("got fileSum"); } if (fd != null && Util.MemoryCompare(fileSum1, 0, fileSum2, 0, CheckSum.MD4_SUM_LENGTH) != 0) { return false; } return true; report_write_error: { MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo); } return true; }
public void SendFiles(List <FileStruct> fileList, ClientInfo clientInfo) { ShowMessage("Processing..."); try { IOStream ioStream = clientInfo.IoStream; string fileName = String.Empty, fileName2 = String.Empty; SumStruct s = null; int phase = 0; bool saveMakeBackups = options.makeBackups; Match match = new Match(options); if (options.verbose > 2) { Log.WriteLine("SendFiles starting"); } while (true) { fileName = String.Empty; int i = ioStream.readInt(); if (i == -1) { if (phase == 0) { phase++; checkSum.length = CheckSum.SUM_LENGTH; ioStream.writeInt(-1); if (options.verbose > 2) { Log.WriteLine("SendFiles phase=" + phase); } options.makeBackups = false; continue; } break; } if (i < 0 || i >= fileList.Count) { MainClass.Exit("Invalid file index " + i + " (count=" + fileList.Count + ")", clientInfo); } FileStruct file = fileList[i]; Options.stats.currentFileIndex = i; Options.stats.numTransferredFiles++; Options.stats.totalTransferredSize += file.length; if (!string.IsNullOrEmpty(file.baseDir)) { fileName = file.baseDir; if (!fileName.EndsWith("/")) { fileName += "/"; } } fileName2 = file.GetFullName(); fileName += file.GetFullName(); ShowMessage("uploading " + fileName); if (options.verbose > 2) { Log.WriteLine("sendFiles(" + i + ", " + fileName + ")"); } if (options.dryRun) { if (!options.amServer && options.verbose != 0) { Log.WriteLine(fileName2); } ioStream.writeInt(i); continue; } Stats initialStats = Options.stats; s = ReceiveSums(clientInfo); Stream fd; try { fd = new FileStream(fileName, FileMode.Open, FileAccess.Read); } catch (FileNotFoundException) { Log.WriteLine("file has vanished: " + Util.fullFileName(fileName)); s = null; continue; } catch (Exception) { Log.WriteLine("SendFiles failed to open " + Util.fullFileName(fileName)); s = null; continue; } FStat st = new FStat(); FileInfo fi = new FileInfo(fileName); // TODO: path length st.mTime = fi.LastWriteTime; // TODO: path length st.size = fi.Length; MapFile mbuf = null; if (st.size != 0) { int mapSize = (int)Math.Max(s.bLength * 3, Options.MAX_MAP_SIZE); mbuf = new MapFile(fd, (int)st.size, mapSize, (int)s.bLength); } if (options.verbose > 2) { Log.WriteLine("SendFiles mapped " + fileName + " of size " + st.size); } ioStream.writeInt(i); Generator gen = new Generator(options); gen.WriteSumHead(ioStream, s); if (options.verbose > 2) { Log.WriteLine("calling MatchSums " + fileName); } if (!options.amServer && options.verbose != 0) { Log.WriteLine(fileName2); } Token token = new Token(options); token.SetCompression(fileName); match.MatchSums(ioStream, s, mbuf, (int)st.size); Log.LogSend(file, initialStats); if (mbuf != null) { bool j = mbuf.UnMapFile(); if (j) { Log.WriteLine("read errors mapping " + Util.fullFileName(fileName)); } } fd.Close(); s.sums = null; if (options.verbose > 2) { Log.WriteLine("sender finished " + fileName); } } options.makeBackups = saveMakeBackups; if (options.verbose > 2) { Log.WriteLine("send files finished"); } match.MatchReport(ioStream); ioStream.writeInt(-1); } finally { HideMessage(); } }
public void MatchSums(IOStream f, SumStruct s, MapFile buf, int len) { byte[] fileSum = new byte[CheckSum.MD4_SUM_LENGTH]; lastMatch = 0; falseAlarms = 0; tagHits = 0; matches = 0; dataTransfer = 0; Sum sum = new Sum(options); sum.Init(options.checksumSeed); if (len > 0 && s.count > 0) { BuildHashTable(s); if (options.verbose > 2) { Log.WriteLine("built hash table"); } HashSearch(f, s, buf, len, sum); if (options.verbose > 2) { Log.WriteLine("done hash search"); } } else { for (int j = 0; j < len - CHUNK_SIZE; j += CHUNK_SIZE) { int n1 = Math.Min(CHUNK_SIZE, (len - CHUNK_SIZE) - j); Matched(f, s, buf, j + n1, -2, sum); } Matched(f, s, buf, len, -1, sum); } fileSum = sum.End(); if (buf != null && buf.status) { fileSum[0]++; } if (options.verbose > 2) { Log.WriteLine("sending fileSum"); } f.Write(fileSum, 0, CheckSum.MD4_SUM_LENGTH); targets.Clear(); if (options.verbose > 2) { Log.WriteLine("falseAlarms=" + falseAlarms + " tagHits=" + tagHits + " matches=" + matches); } totalTagHits += tagHits; totalFalseAlarms += falseAlarms; totalMatches += matches; Options.stats.literalData += dataTransfer; }
public bool ReceiveData(ClientInfo clientInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize) { IOStream f = clientInfo.IoStream; byte[] fileSum1 = new byte[CheckSum.MD4_SUM_LENGTH]; byte[] fileSum2 = new byte[CheckSum.MD4_SUM_LENGTH]; byte[] data = new byte[Match.CHUNK_SIZE]; SumStruct sumStruct = new SumStruct(); MapFile mapBuf = null; Sender sender = new Sender(options); sender.ReadSumHead(clientInfo, ref sumStruct); int offset = 0; UInt32 len; if (fdR != null && sizeR > 0) { int mapSize = (int)Math.Max(sumStruct.bLength * 2, 16 * 1024); mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sumStruct.bLength); if (options.verbose > 2) { Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR); } } Sum sum = new Sum(options); sum.Init(options.checksumSeed); int i; Token token = new Token(options); while ((i = token.ReceiveToken(f, ref data, 0)) != 0) { if (options.doProgress) { Progress.ShowProgress(offset, totalSize); } if (i > 0) { if (options.verbose > 3) { Log.WriteLine("data recv " + i + " at " + offset); } Options.stats.literalData += i; sum.Update(data, 0, i); if (fd != null && FileIO.WriteFile(fd, data, 0, i) != i) { goto report_write_error; } offset += i; continue; } i = -(i + 1); int offset2 = (int)(i * sumStruct.bLength); len = sumStruct.bLength; if (i == sumStruct.count - 1 && sumStruct.remainder != 0) { len = sumStruct.remainder; } Options.stats.matchedData += len; if (options.verbose > 3) { Log.WriteLine("chunk[" + i + "] of size " + len + " at " + offset2 + " offset=" + offset); } byte[] map = null; int off = 0; if (mapBuf != null) { off = mapBuf.MapPtr(offset2, (int)len); map = mapBuf.p; token.SeeToken(map, offset, (int)len); sum.Update(map, off, (int)len); } if (options.inplace) { if (offset == offset2 && fd != null) { offset += (int)len; if (fd.Seek(len, SeekOrigin.Current) != offset) { MainClass.Exit("seek failed on " + Util.fullFileName(fileName), clientInfo); } continue; } } if (fd != null && FileIO.WriteFile(fd, map, off, (int)len) != (int)len) { goto report_write_error; } offset += (int)len; } if (options.doProgress) { Progress.EndProgress(totalSize); } if (fd != null && offset > 0 && FileIO.SparseEnd(fd) != 0) { MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo); } fileSum1 = sum.End(); if (mapBuf != null) { mapBuf = null; } fileSum2 = f.ReadBuffer(CheckSum.MD4_SUM_LENGTH); if (options.verbose > 2) { Log.WriteLine("got fileSum"); } if (fd != null && Util.MemoryCompare(fileSum1, 0, fileSum2, 0, CheckSum.MD4_SUM_LENGTH) != 0) { return(false); } return(true); report_write_error: { MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo); } return(true); }
public void HashSearch(IOStream f, SumStruct s, MapFile buf, int len, Sum _sum) { int offset, end, backup; UInt32 k; int wantI; byte[] sum2 = new byte[CheckSum.SUM_LENGTH]; UInt32 s1, s2, sum; int more; byte[] map; wantI = 0; if (options.verbose > 2) { Log.WriteLine("hash search ob=" + s.bLength + " len=" + len); } k = (UInt32)Math.Min(len, s.bLength); int off = buf.MapPtr(0, (int)k); map = buf.p; UInt32 g = s.sums[0].sum1; sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (options.verbose > 3) { Log.WriteLine("sum=" + sum + " k=" + k); } offset = 0; end = (int)(len + 1 - s.sums[s.count - 1].len); if (options.verbose > 3) { Log.WriteLine("hash search s.bLength=" + s.bLength + " len=" + len + " count=" + s.count); } do { UInt32 t = GetTag2(s1, s2); bool doneCsum2 = false; int j = tagTable[t]; if (options.verbose > 4) { Log.WriteLine("offset=" + offset + " sum=" + sum); } if (j == NULL_TAG) { goto null_tag; } sum = (s1 & 0xffff) | (s2 << 16); tagHits++; do { UInt32 l; int i = ((Target)targets[j]).i; if (sum != s.sums[i].sum1) { continue; } l = (UInt32)Math.Min(s.bLength, len - offset); if (l != s.sums[i].len) { continue; } if (options.verbose > 3) { Log.WriteLine("potential match at " + offset + " target=" + j + " " + i + " sum=" + sum); } if (!doneCsum2) { off = buf.MapPtr(offset, (int)l); map = buf.p; CheckSum cs = new CheckSum(options); sum2 = cs.GetChecksum2(map, off, (int)l); doneCsum2 = true; } if (Util.MemCmp(sum2, 0, s.sums[i].sum2, 0, s.s2Length) != 0) { falseAlarms++; continue; } if (i != wantI && wantI < s.count && (!options.inplace || options.makeBackups || s.sums[wantI].offset >= offset || (s.sums[wantI].flags & SUMFLG_SAME_OFFSET) != 0) && sum == s.sums[wantI].sum1 && Util.MemCmp(sum2, 0, s.sums[wantI].sum2, 0, s.s2Length) == 0) { i = wantI; } set_want_i: wantI = i + 1; Matched(f, s, buf, offset, i, _sum); offset += (int)(s.sums[i].len - 1); k = (UInt32)Math.Min(s.bLength, len - offset); off = buf.MapPtr(offset, (int)k); sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; matches++; break; } while (++j < s.count && ((Target)targets[j]).t == t); null_tag: backup = offset - lastMatch; if (backup < 0) { backup = 0; } more = (offset + k) < len ? 1 : 0; off = buf.MapPtr(offset - backup, (int)(k + more + backup)) + backup; s1 -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET); s2 -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET); off = (k + off >= map.Length) ? (int)(map.Length - k - 1) : off; if (more != 0) { s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CHAR_OFFSET); s2 += s1; } else { --k; } if (backup >= CHUNK_SIZE + s.bLength && end - offset > CHUNK_SIZE) { Matched(f, s, buf, (int)(offset - s.bLength), -2, _sum); } } while (++offset < end); Matched(f, s, buf, len, -1, _sum); buf.MapPtr(len - 1, 1); }
public void SumSizesSqroot(SumStruct sum, UInt64 len) { UInt32 bLength; int s2Length; UInt32 c; UInt64 l; if (_options.BlockSize != 0) { bLength = (UInt32)_options.BlockSize; } else if (len <= Options.MaxBlockSize * Options.MaxBlockSize) { bLength = Options.MaxBlockSize; } else { l = len; c = 1; while ((l = (l >> 1)) != 0) { c <<= 1; } bLength = 0; do { bLength |= c; if (len < bLength * bLength) { bLength &= ~c; } c >>= 1; } while (c >= 8); /* round to multiple of 8 */ bLength = Math.Max(bLength, Options.MaxBlockSize); } if (_options.ProtocolVersion < 27) { s2Length = _checkSum.Length; } else { if (_checkSum.Length == CheckSum.SumLength) { s2Length = CheckSum.SumLength; } else { var b = BlocksumBias; l = len; while ((l = (l >> 1)) != 0) { b += 2; } c = bLength; while ((c = (c >> 1)) != 0 && b != 0) { b--; } s2Length = (b + 1 - 32 + 7) / 8; s2Length = Math.Max(s2Length, _checkSum.Length); s2Length = Math.Min(s2Length, CheckSum.SumLength); } } sum.FLength = (int)len; sum.BLength = bLength; sum.S2Length = s2Length; sum.Count = (int)((len + (bLength - 1)) / bLength); sum.Remainder = (UInt32)(len % bLength); if (sum.Count != 0 && _options.Verbose > 2) { Log.WriteLine("count=" + sum.Count + " rem=" + sum.Remainder + " blength=" + sum.BLength + " s2length=" + sum.S2Length + " flength=" + sum.FLength); } }
public void HashSearch(IoStream f, SumStruct s, MapFile buf, int len, Sum _sum) { int offset, end, backup; UInt32 k; int wantI; var sum2 = new byte[CheckSum.SumLength]; UInt32 s1, s2, sum; int more; byte[] map; wantI = 0; if (_options.Verbose > 2) { Log.WriteLine("hash search ob=" + s.BLength + " len=" + len); } k = (UInt32)Math.Min(len, s.BLength); var off = buf.MapPtr(0, (int)k); map = buf.P; var g = s.Sums[0].Sum1; sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (_options.Verbose > 3) { Log.WriteLine("sum=" + sum + " k=" + k); } offset = 0; end = (int)(len + 1 - s.Sums[s.Count - 1].Len); if (_options.Verbose > 3) { Log.WriteLine("hash search s.bLength=" + s.BLength + " len=" + len + " count=" + s.Count); } do { var t = GetTag2(s1, s2); var doneCsum2 = false; var j = _tagTable[t]; if (_options.Verbose > 4) { Log.WriteLine("offset=" + offset + " sum=" + sum); } if (j == NullTag) { goto null_tag; } sum = (s1 & 0xffff) | (s2 << 16); _tagHits++; do { UInt32 l; var i = _targets[j].I; if (sum != s.Sums[i].Sum1) { continue; } l = (UInt32)Math.Min(s.BLength, len - offset); if (l != s.Sums[i].Len) { continue; } if (_options.Verbose > 3) { Log.WriteLine("potential match at " + offset + " target=" + j + " " + i + " sum=" + sum); } if (!doneCsum2) { off = buf.MapPtr(offset, (int)l); map = buf.P; var cs = new CheckSum(_options); sum2 = cs.GetChecksum2(map, off, (int)l); doneCsum2 = true; } if (Util.MemoryCompare(sum2, 0, s.Sums[i].Sum2, 0, s.S2Length) != 0) { _falseAlarms++; continue; } if (i != wantI && wantI < s.Count && (!_options.Inplace || _options.MakeBackups || s.Sums[wantI].Offset >= offset || (s.Sums[wantI].Flags & SumflgSameOffset) != 0) && sum == s.Sums[wantI].Sum1 && Util.MemoryCompare(sum2, 0, s.Sums[wantI].Sum2, 0, s.S2Length) == 0) { i = wantI; } //set_want_i: wantI = i + 1; Matched(f, s, buf, offset, i, _sum); offset += (int)(s.Sums[i].Len - 1); k = (UInt32)Math.Min(s.BLength, len - offset); off = buf.MapPtr(offset, (int)k); sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; _matches++; break; } while (++j < s.Count && _targets[j].T == t); null_tag: backup = offset - _lastMatch; if (backup < 0) { backup = 0; } more = (offset + k) < len ? 1 : 0; off = buf.MapPtr(offset - backup, (int)(k + more + backup)) + backup; s1 -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CharOffset); s2 -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CharOffset); off = (k + off >= map.Length) ? (int)(map.Length - k - 1) : off; if (more != 0) { s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CharOffset); s2 += s1; } else { --k; } if (backup >= ChunkSize + s.BLength && end - offset > ChunkSize) { Matched(f, s, buf, (int)(offset - s.BLength), -2, _sum); } } while (++offset < end); Matched(f, s, buf, len, -1, _sum); buf.MapPtr(len - 1, 1); }
public void SumSizesSqroot(SumStruct sum, UInt64 len) { UInt32 bLength; int s2Length; UInt32 c; UInt64 l; if (options.blockSize != 0) { bLength = (UInt32)options.blockSize; } else if (len <= Options.BLOCK_SIZE * Options.BLOCK_SIZE) { bLength = Options.BLOCK_SIZE; } else { l = len; c = 1; while ((l = (l >> 1)) != 0) { c <<= 1; } bLength = 0; do { bLength |= c; if (len < bLength * bLength) { bLength &= ~c; } c >>= 1; } while (c >= 8); /* round to multiple of 8 */ bLength = Math.Max(bLength, Options.BLOCK_SIZE); } if (options.protocolVersion < 27) { s2Length = checkSum.length; } else { if (checkSum.length == CheckSum.SUM_LENGTH) { s2Length = CheckSum.SUM_LENGTH; } else { int b = BLOCKSUM_BIAS; l = len; while ((l = (l >> 1)) != 0) { b += 2; } c = bLength; while ((c = (c >> 1)) != 0 && b != 0) { b--; } s2Length = (b + 1 - 32 + 7) / 8; s2Length = Math.Max(s2Length, checkSum.length); s2Length = Math.Min(s2Length, CheckSum.SUM_LENGTH); } } sum.fLength = (int)len; sum.bLength = bLength; sum.s2Length = s2Length; sum.count = (int)((len + (bLength - 1)) / bLength); sum.remainder = (UInt32)(len % bLength); if (sum.count != 0 && options.verbose > 2) { Log.WriteLine("count=" + sum.count + " rem=" + sum.remainder + " blength=" + sum.bLength + " s2length=" + sum.s2Length + " flength=" + sum.fLength); } }
public void MatchSums(IoStream f, SumStruct s, MapFile buf, int len) { var fileSum = new byte[CheckSum.Md4SumLength]; _lastMatch = 0; _falseAlarms = 0; _tagHits = 0; _matches = 0; _dataTransfer = 0; var sum = new Sum(_options); sum.Init(_options.ChecksumSeed); if (len > 0 && s.Count > 0) { BuildHashTable(s); if (_options.Verbose > 2) { Log.WriteLine("built hash table"); } HashSearch(f, s, buf, len, sum); if (_options.Verbose > 2) { Log.WriteLine("done hash search"); } } else { for (var j = 0; j < len - ChunkSize; j += ChunkSize) { var n1 = Math.Min(ChunkSize, (len - ChunkSize) - j); Matched(f, s, buf, j + n1, -2, sum); } Matched(f, s, buf, len, -1, sum); } fileSum = sum.End(); if (buf != null && buf.Status) { fileSum[0]++; } if (_options.Verbose > 2) { Log.WriteLine("sending fileSum"); } f.Write(fileSum, 0, CheckSum.Md4SumLength); _targets.Clear(); if (_options.Verbose > 2) { Log.WriteLine("falseAlarms=" + _falseAlarms + " tagHits=" + _tagHits + " matches=" + _matches); } _totalTagHits += _tagHits; _totalFalseAlarms += _falseAlarms; _totalMatches += _matches; Options.Stats.LiteralData += _dataTransfer; }
public bool ReceiveData(ClientInfo clientInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize) { var f = clientInfo.IoStream; var fileSum1 = new byte[CheckSum.Md4SumLength]; var fileSum2 = new byte[CheckSum.Md4SumLength]; var data = new byte[Match.ChunkSize]; var sumStruct = new SumStruct(); MapFile mapBuf = null; var sender = new Sender(_options); sender.ReadSumHead(clientInfo, ref sumStruct); var offset = 0; UInt32 len; if (fdR != null && sizeR > 0) { var mapSize = (int)Math.Max(sumStruct.BLength * 2, 16 * 1024); mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sumStruct.BLength); if (_options.Verbose > 2) { Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR); } } var sum = new Sum(_options); sum.Init(_options.ChecksumSeed); int i; var token = new Token(_options); while ((i = token.ReceiveToken(f, ref data, 0)) != 0) { if (_options.DoProgress) { Progress.ShowProgress(offset, totalSize); } if (i > 0) { if (_options.Verbose > 3) { Log.WriteLine("data recv " + i + " at " + offset); } Options.Stats.LiteralData += i; sum.Update(data, 0, i); if (fd != null && FileIo.WriteFile(fd, data, 0, i) != i) { goto report_write_error; } offset += i; continue; } i = -(i + 1); var offset2 = (int)(i * sumStruct.BLength); len = sumStruct.BLength; if (i == sumStruct.Count - 1 && sumStruct.Remainder != 0) { len = sumStruct.Remainder; } Options.Stats.MatchedData += len; if (_options.Verbose > 3) { Log.WriteLine("chunk[" + i + "] of size " + len + " at " + offset2 + " offset=" + offset); } byte[] map = null; var off = 0; if (mapBuf != null) { off = mapBuf.MapPtr(offset2, (int)len); map = mapBuf.P; token.SeeToken(map, offset, (int)len); sum.Update(map, off, (int)len); } if (_options.Inplace) { if (offset == offset2 && fd != null) { offset += (int)len; if (fd.Seek(len, SeekOrigin.Current) != offset) { WinRsync.Exit("seek failed on " + Util.FullFileName(fileName), clientInfo); } continue; } } if (fd != null && FileIo.WriteFile(fd, map, off, (int)len) != (int)len) { goto report_write_error; } offset += (int)len; } if (_options.DoProgress) { Progress.EndProgress(totalSize); } if (fd != null && offset > 0 && FileIo.SparseEnd(fd) != 0) { WinRsync.Exit("write failed on " + Util.FullFileName(fileName), clientInfo); } fileSum1 = sum.End(); if (mapBuf != null) { mapBuf = null; } fileSum2 = f.ReadBuffer(CheckSum.Md4SumLength); if (_options.Verbose > 2) { Log.WriteLine("got fileSum"); } if (fd != null && Util.MemoryCompare(fileSum1, 0, fileSum2, 0, CheckSum.Md4SumLength) != 0) { return(false); } return(true); report_write_error: { WinRsync.Exit("write failed on " + Util.FullFileName(fileName), clientInfo); } return(true); }
public SumStruct ReceiveSums(ClientInfo cInfo) { IOStream f = cInfo.IoStream; SumStruct s = new SumStruct(); int i; int offset = 0; ReadSumHead(cInfo, ref s); s.sums = null; if (options.verbose > 3) { Log.WriteLine("count=" + s.count + " n=" + s.bLength + " rem=" + s.remainder); } if (s.count == 0) { return s; } s.sums = new SumBuf[s.count]; for (i = 0; i < s.count; i++) { s.sums[i] = new SumBuf(); s.sums[i].sum1 = (UInt32)f.readInt(); s.sums[i].sum2 = f.ReadBuffer(s.s2Length); s.sums[i].offset = offset; s.sums[i].flags = 0; if (i == s.count - 1 && s.remainder != 0) { s.sums[i].len = s.remainder; } else { s.sums[i].len = s.bLength; } offset += (int)s.sums[i].len; if (options.verbose > 3) { Log.WriteLine("chunk[" + i + "] len=" + s.sums[i].len); } } s.fLength = offset; return s; }
public void SendFiles(List <FileStruct> fileList, ClientInfo clientInfo) { ShowMessage("Processing..."); try { var ioStream = clientInfo.IoStream; string fileName = String.Empty, fileName2 = String.Empty; SumStruct s = null; var phase = 0; var saveMakeBackups = _options.MakeBackups; var match = new Match(_options); if (_options.Verbose > 2) { Log.WriteLine("SendFiles starting"); } while (true) { fileName = String.Empty; var i = ioStream.ReadInt(); if (i == -1) { if (phase == 0) { phase++; _checkSum.Length = CheckSum.SumLength; ioStream.WriteInt(-1); if (_options.Verbose > 2) { Log.WriteLine("SendFiles phase=" + phase); } _options.MakeBackups = false; continue; } break; } if (i < 0 || i >= fileList.Count) { WinRsync.Exit("Invalid file index " + i + " (count=" + fileList.Count + ")", clientInfo); } var file = fileList[i]; Options.Stats.CurrentFileIndex = i; Options.Stats.NumTransferredFiles++; Options.Stats.TotalTransferredSize += file.Length; if (!string.IsNullOrEmpty(file.BaseDir)) { fileName = file.BaseDir; if (!fileName.EndsWith("/")) { fileName += "/"; } } fileName2 = file.GetFullName(); fileName += file.GetFullName(); ShowMessage("uploading " + fileName); if (_options.Verbose > 2) { Log.WriteLine("sendFiles(" + i + ", " + fileName + ")"); } if (_options.DryRun) { if (!_options.AmServer && _options.Verbose != 0) { Log.WriteLine(fileName2); } ioStream.WriteInt(i); continue; } var initialStats = Options.Stats; s = ReceiveSums(clientInfo); Stream fd; try { fd = new FileStream(fileName, FileMode.Open, FileAccess.Read); } catch (FileNotFoundException) { Log.WriteLine("file has vanished: " + Util.FullFileName(fileName)); s = null; continue; } catch (Exception) { Log.WriteLine("SendFiles failed to open " + Util.FullFileName(fileName)); s = null; continue; } var st = new FStat(); var fi = new FileInfo(fileName); // TODO: path length st.MTime = fi.LastWriteTime; // TODO: path length st.Size = fi.Length; MapFile mbuf = null; if (st.Size != 0) { var mapSize = (int)Math.Max(s.BLength * 3, Options.MaxMapSize); mbuf = new MapFile(fd, (int)st.Size, mapSize, (int)s.BLength); } if (_options.Verbose > 2) { Log.WriteLine("SendFiles mapped " + fileName + " of size " + st.Size); } ioStream.WriteInt(i); var gen = new Generator(_options); gen.WriteSumHead(ioStream, s); if (_options.Verbose > 2) { Log.WriteLine("calling MatchSums " + fileName); } if (!_options.AmServer && _options.Verbose != 0) { Log.WriteLine(fileName2); } var token = new Token(_options); token.SetCompression(fileName); match.MatchSums(ioStream, s, mbuf, (int)st.Size); Log.LogSend(file, initialStats); if (mbuf != null) { var j = mbuf.UnMapFile(); if (j) { Log.WriteLine("read errors mapping " + Util.FullFileName(fileName)); } } fd.Close(); s.Sums = null; if (_options.Verbose > 2) { Log.WriteLine("sender finished " + fileName); } } _options.MakeBackups = saveMakeBackups; if (_options.Verbose > 2) { Log.WriteLine("send files finished"); } match.MatchReport(ioStream); ioStream.WriteInt(-1); } finally { HideMessage(); } }