public void SendToken(IOStream f, int token, MapFile buf, int offset, int n, int toklen) { if (!options.doCompression) SimpleSendToken(f,token,buf,offset,n); else SendDeflatedToken(f, token, buf, offset, n, toklen); }
/// <summary> /// /// </summary> /// <param name="fileName"></param> /// <param name="sum"></param> /// <param name="size"></param> /// <returns></returns> public bool FileCheckSum(string fileName, ref byte[] sum, int size) { int i; MDFour mdFour = new MDFour(options); sum = new byte[MD4_SUM_LENGTH]; try { using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { MapFile buf = new MapFile(fileStream, size, Options.MAX_MAP_SIZE, CSUM_CHUNK); mdFour.Begin(); for (i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK) { int offset = buf.MapPtr(i, CSUM_CHUNK); mdFour.Update(buf.p, offset, CSUM_CHUNK); } if (size - i > 0 || options.protocolVersion >= 27) { int offset = buf.MapPtr(i, size - i); mdFour.Update(buf.p, offset, (UInt32)(size - i)); } sum = mdFour.Result(); fileStream.Close(); //buf.UnMapFile(); //@fixed useless string return(true); } } catch (Exception) { } return(false); }
public bool FileCheckSum(string fileName, ref byte[] sum, int size) { int i; MDFour m = new MDFour(options); sum = new byte[MD4_SUM_LENGTH]; Stream fd; try { fd = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (Exception) { return(false); } MapFile buf = new MapFile(fd, size, Options.MAX_MAP_SIZE, CSUM_CHUNK); m.Begin(); for (i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK) { int offset = buf.MapPtr(i, CSUM_CHUNK); m.Update(buf.p, offset, CSUM_CHUNK); } if (size - i > 0 || options.protocolVersion >= 27) { int offset = buf.MapPtr(i, size - i); m.Update(buf.p, offset, (UInt32)(size - i)); } sum = m.Result(); fd.Close(); buf.UnMapFile(); return(true); }
public void SendDeflatedToken(IoStream f, int token, MapFile buf, int offset, int nb, int toklen) { }
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 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 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); } }
/// <summary> /// Reads socket into buffer /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public int ReadSocketUnbuffered(byte[] buffer, int offset, int count) { int tag, result = 0; byte[] line = new byte[1024]; if (IOBufIn == null) { return(socketIn.Read(buffer, offset, count)); } if (!IOMultiplexingIn && remaining == 0) { Flush(); remaining = socketIn.Read(IOBufIn, 0, IOBufInSize); IOBufInIndex = 0; } while (result == 0) { if (remaining != 0) { count = Math.Min(count, remaining); Util.MemoryCopy(buffer, offset, IOBufIn, IOBufInIndex, count); IOBufInIndex += count; remaining -= count; result = count; break; } ReadLoop(line, 4); tag = (int)IVAL(line, 0); remaining = tag & 0xFFFFFF; tag = (tag >> 24) - MPLEX_BASE; switch ((MsgCode)tag) { case MsgCode.MSG_DATA: if (remaining > IOBufInSize) { MapFile.ExtendArray(ref IOBufIn, remaining); IOBufInSize = remaining; } ReadLoop(IOBufIn, remaining); IOBufInIndex = 0; break; case MsgCode.MSG_INFO: case MsgCode.MSG_ERROR: if (remaining >= line.Length) { throw new Exception("Multiplexing overflow " + tag + ":" + remaining); } ReadLoop(line, remaining); remaining = 0; break; default: throw new Exception("Read unknown message from stream"); } } if (remaining == 0) { Flush(); } return(result); }
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 { 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(); } }
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; } }
/// <summary> /// /// </summary> /// <param name="fileName"></param> /// <param name="sum"></param> /// <param name="size"></param> /// <returns></returns> public bool FileCheckSum(string fileName, ref byte[] sum, int size) { int i; MDFour mdFour = new MDFour(options); sum = new byte[MD4_SUM_LENGTH]; try { using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { MapFile buf = new MapFile(fileStream, size, Options.MAX_MAP_SIZE, CSUM_CHUNK); mdFour.Begin(); for (i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK) { int offset = buf.MapPtr(i, CSUM_CHUNK); mdFour.Update(buf.p, offset, CSUM_CHUNK); } if (size - i > 0 || options.protocolVersion >= 27) { int offset = buf.MapPtr(i, size - i); mdFour.Update(buf.p, offset, (UInt32)(size - i)); } sum = mdFour.Result(); fileStream.Close(); //buf.UnMapFile(); //@fixed useless string return true; } } catch (Exception) { } return false; }
/// <summary> /// Reads socket into buffer /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public int ReadSocketUnbuffered(byte[] buffer, int offset, int count) { int tag, result = 0; var line = new byte[1024]; if (_ioBufIn == null) { return(_socketIn.Read(buffer, offset, count)); } if (!_ioMultiplexingIn && _remaining == 0) { Flush(); _remaining = _socketIn.Read(_ioBufIn, 0, _ioBufInSize); _ioBufInIndex = 0; } while (result == 0) { if (_remaining != 0) { count = Math.Min(count, _remaining); Util.MemoryCopy(buffer, offset, _ioBufIn, _ioBufInIndex, count); _ioBufInIndex += count; _remaining -= count; result = count; break; } ReadLoop(line, 4); tag = (int)Ival(line, 0); _remaining = tag & 0xFFFFFF; tag = (tag >> 24) - MplexBase; switch ((MsgCode)tag) { case MsgCode.MsgData: if (_remaining > _ioBufInSize) { MapFile.ExtendArray(ref _ioBufIn, _remaining); _ioBufInSize = _remaining; } ReadLoop(_ioBufIn, _remaining); _ioBufInIndex = 0; break; case MsgCode.MsgInfo: case MsgCode.MsgError: if (_remaining >= line.Length) { throw new Exception("Multiplexing overflow " + tag + ":" + _remaining); } ReadLoop(line, _remaining); _remaining = 0; break; default: throw new Exception("Read unknown message from stream"); } } if (_remaining == 0) { Flush(); } return(result); }
public int ReadfdUnbuffered(byte[] data, int off, int len) { int tag, ret = 0; byte[] line = new byte[1024]; if (iobuf_in == null) { return(sockIn.Read(data, off, len)); } if (!IOMultiplexingIn && remaining == 0) { Flush(); remaining = sockIn.Read(iobuf_in, 0, iobuf_in_siz); iobuf_in_ndx = 0; } while (ret == 0) { if (remaining != 0) { len = Math.Min(len, remaining); Util.MemCpy(data, off, iobuf_in, iobuf_in_ndx, len); iobuf_in_ndx += len; remaining -= len; ret = len; break; } ReadLoop(line, 4); tag = (int)IVAL(line, 0); remaining = tag & 0xFFFFFF; tag = (tag >> 24) - MPLEX_BASE; switch ((MsgCode)tag) { case MsgCode.MSG_DATA: if (remaining > iobuf_in_siz) { MapFile.ReallocArray(ref iobuf_in, remaining); iobuf_in_siz = remaining; } ReadLoop(iobuf_in, remaining); iobuf_in_ndx = 0; break; case MsgCode.MSG_INFO: case MsgCode.MSG_ERROR: if (remaining >= line.Length) { throw new Exception("multiplexing overflow " + tag + ":" + remaining); } ReadLoop(line, remaining); remaining = 0; break; default: throw new Exception("Read unknown message from stream"); break; } } if (remaining == 0) { Flush(); } return(ret); }
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 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 SendDeflatedToken(IOStream f, int token, MapFile buf, int offset, int nb, int toklen) { }
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 SimpleSendToken(IOStream f,int token, MapFile buf, int offset, int n) { if (n > 0) { int l = 0; while (l < n) { int n1 = Math.Min(Match.CHUNK_SIZE,n-l); f.writeInt(n1); int off = buf.MapPtr(offset + l, n1); f.Write(buf.p, off, n1); l += n1; } } if (token != -2) f.writeInt(-(token+1)); }
public static int RsyncModule(ClientInfo cInfo, int moduleNumber) { string path = Daemon.config.GetModule(moduleNumber).Path; string name = Daemon.config.GetModuleName(moduleNumber); IOStream f = cInfo.IoStream; Options options = cInfo.Options; string[] args = new string[Options.MAX_ARGS]; int argc = 0, maxargs = Options.MAX_ARGS; string line = ""; if (path[0] == '/') { path = path.Remove(0, 1); } path = path.Replace("\n", ""); Access ac = new Access(); if (!ac.AllowAccess(options.remoteAddr, options.remoteHost, Daemon.config.GetHostsAllow(moduleNumber), Daemon.config.GetHostsDeny(moduleNumber))) { Log.Write("rsync denied on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")"); f.IOPrintf("@ERROR: access denied to " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n"); return(-1); } if (!Authentication.AuthServer(cInfo, moduleNumber, options.remoteAddr, "@RSYNCD: AUTHREQD ")) { Log.Write("auth failed on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n"); f.IOPrintf("@ERROR: auth failed on module " + name + "\n"); return(-1); } // TODO: path length if (FileSystem.Directory.Exists(path)) { f.IOPrintf("@RSYNCD: OK\n"); } else { try { // TODO: path length FileSystem.Directory.CreateDirectory(path); f.IOPrintf("@RSYNCD: OK\n"); } catch (Exception) { f.IOPrintf("@ERROR: Path not found\n"); MainClass.Exit("@ERROR: Path not found: " + path, cInfo); } } options.amServer = true; //to fix error in SetupProtocol options.dir = path; while (true) { line = f.ReadLine(); line = line.Substring(0, line.Length - 1); if (line.CompareTo("") == 0) { break; } if (argc == maxargs) { maxargs += Options.MAX_ARGS; MapFile.ReallocArrayString(ref args, maxargs); } args[argc++] = line; } args[argc++] = path; options.verbose = 0; int argsNotUsed = CommandLineParser.ParseArguments(args, options); if (argsNotUsed == -1) { MainClass.Exit("Error parsing options", cInfo); } string[] args2 = new string[argsNotUsed]; for (int i = 0; i < argsNotUsed; i++) { args2[i] = args[args.Length - argsNotUsed + i]; } MainClass.SetupProtocol(cInfo); f.IOStartMultiplexOut(); Daemon.StartServer(cInfo, args2); return(-1); }
/// <summary> /// /// </summary> /// <param name="clientInfo"></param> /// <param name="moduleNumber"></param> /// <returns></returns> public static void RsyncModule(ClientInfo clientInfo, int moduleNumber) //@fixed Why return something if result not used? { var path = Daemon.Config.GetModule(moduleNumber).Path; var name = Daemon.Config.GetModuleName(moduleNumber); var ioStream = clientInfo.IoStream; var options = clientInfo.Options; var args = new string[Options.MaxArgs]; int argc = 0, maxArgs = Options.MaxArgs; var line = String.Empty; if (path[0] == '/') { path = path.Remove(0, 1); } path = path.Replace("\n", String.Empty); var ac = new Access(); if ( !ac.AllowAccess(options.RemoteAddr, options.RemoteHost, Daemon.Config.GetHostsAllow(moduleNumber), Daemon.Config.GetHostsDeny(moduleNumber))) { Log.Write("rsync denied on module " + name + " from " + options.RemoteHost + " (" + options.RemoteAddr + ")"); ioStream.IoPrintf("@ERROR: access denied to " + name + " from " + options.RemoteHost + " (" + options.RemoteAddr + ")\n"); return; } if (!Authentication.AuthorizeServer(clientInfo, moduleNumber, options.RemoteAddr, "@RSYNCD: AUTHREQD ")) { Log.Write("auth failed on module " + name + " from " + options.RemoteHost + " (" + options.RemoteAddr + ")\n"); ioStream.IoPrintf("@ERROR: auth failed on module " + name + "\n"); return; } // TODO: path length if (Directory.Exists(path)) { ioStream.IoPrintf("@RSYNCD: OK\n"); } else { try { // TODO: path length Directory.CreateDirectory(path); ioStream.IoPrintf("@RSYNCD: OK\n"); } catch (Exception) { ioStream.IoPrintf("@ERROR: Path not found\n"); WinRsync.Exit("@ERROR: Path not found: " + path, clientInfo); } } options.AmServer = true; //to fix error in SetupProtocol options.Dir = path; do { line = ioStream.ReadLine(); line = line.Substring(0, line.Length - 1); if (argc == maxArgs) { maxArgs += Options.MaxArgs; MapFile.ExtendArray(ref args, maxArgs); } args[argc++] = line; } while (!string.IsNullOrEmpty(line)); args[argc++] = path; options.Verbose = 0; var argsNotUsed = CommandLineParser.ParseArguments(args, options); if (argsNotUsed == -1) { WinRsync.Exit("Error parsing options", clientInfo); } var args2 = new string[argsNotUsed]; for (var i = 0; i < argsNotUsed; i++) { args2[i] = args[args.Length - argsNotUsed + i]; } WinRsync.SetupProtocol(clientInfo); ioStream.IoStartMultiplexOut(); Daemon.StartServer(clientInfo, args2); }
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 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 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 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 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 bool FileCheckSum(string fileName, ref byte[] sum, int size) { int i; MDFour m =new MDFour(options); sum = new byte[MD4_SUM_LENGTH]; Stream fd; try { fd = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); } catch(Exception) { return false; } MapFile buf = new MapFile(fd, size, Options.MAX_MAP_SIZE, CSUM_CHUNK); m.Begin(); for(i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK) { int offset = buf.MapPtr(i, CSUM_CHUNK); m.Update(buf.p, offset, CSUM_CHUNK); } if (size - i > 0 || options.protocolVersion >= 27) { int offset = buf.MapPtr(i, size-i); m.Update(buf.p, offset, (UInt32)(size-i)); } sum = m.Result(); fd.Close(); buf.UnMapFile(); return true; }