public void SendDirectory(IoStream ioStream, List <FileStruct> fileList, string dir) { var directoryInfo = new DirectoryInfo(dir); if (directoryInfo.Exists) { if (_options.CvsExclude) { var excl = new Exclude(_options); excl.AddExcludeFile(ref _options.LocalExcludeList, dir, (int)(Options.XflgWordSplit & Options.XflgWordsOnly)); //@todo (int)(Options.XFLG_WORD_SPLIT & Options.XFLG_WORDS_ONLY) evaluates to 0 unconditionally. May be change & with | ? } var files = directoryInfo.GetFiles(); for (var i = 0; i < files.Length; i++) { // TODO: path length SendFileName(ioStream, fileList, files[i].FullName.Replace(@"\", "/"), _options.Recurse, 0); } var dirs = directoryInfo.GetDirectories(); for (var i = 0; i < dirs.Length; i++) { // TODO: path length SendFileName(ioStream, fileList, dirs[i].FullName.Replace(@"\", "/"), _options.Recurse, 0); } } else { Log.WriteLine("Can't find directory '" + Util.FullFileName(dir) + "'"); } }
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); } }
public int ReceiveToken(IoStream ioStream, ref byte[] data, int offset) { int token; if (!_options.DoCompression) { token = SimpleReceiveToken(ioStream, ref data, offset); } else { token = ReceiveDeflatedToken(ioStream, data, offset); } return(token); }
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 MatchReport(IoStream f) { if (_options.Verbose <= 1) { return; } var report = "total: matches=" + _totalMatches + " tagHits=" + _totalTagHits + " falseAlarms=" + _totalFalseAlarms + " data=" + Options.Stats.LiteralData; Log.WriteLine(report); if (_options.AmServer) { f.MultiplexWrite(MsgCode.MsgInfo, Encoding.ASCII.GetBytes(report), report.Length); } }
public static IoStream OpenSocketOut(string host, int port, string bindAddress) { TcpClient client = null; try { client = new TcpClient(host, port); } catch (Exception) { Exit("Can't connect to server", null); } var stream = new IoStream(client.GetStream()); return(stream); }
/// <summary> /// Receives exclude list from stream /// </summary> /// <param name="ioStream"></param> public void ReceiveExcludeList(IoStream ioStream) { var line = String.Empty; int length; while ((length = ioStream.ReadInt()) != 0) { if (length >= Options.Maxpathlen + 3) { Log.Write("Overflow: recv_exclude_list"); continue; } line = ioStream.ReadStringFromBuffer(length); AddExclude(ref _options.ExcludeList, line, 0); } }
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 SimpleSendToken(IoStream f, int token, MapFile buf, int offset, int n) { if (n > 0) { var l = 0; while (l < n) { var n1 = Math.Min(Match.ChunkSize, n - l); f.WriteInt(n1); var off = buf.MapPtr(offset + l, n1); f.Write(buf.P, off, n1); l += n1; } } if (token != -2) { f.WriteInt(-(token + 1)); } }
public int SimpleReceiveToken(IoStream ioStream, ref byte[] data, int offset) { int n; if (Residue == 0) { var i = ioStream.ReadInt(); if (i <= 0) { return(i); } Residue = i; } n = Math.Min(Match.ChunkSize, Residue); Residue -= n; data = ioStream.ReadBuffer(n); return(n); }
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 SendExcludeList(IoStream f) { if (_options.ListOnly && !_options.Recurse) { AddExclude(ref _options.ExcludeList, "/*/*", 0); } foreach (var ent in _options.ExcludeList) { int l; string p; if (ent.Pattern.Length == 0 || ent.Pattern.Length > Options.Maxpathlen) { continue; } l = ent.Pattern.Length; p = ent.Pattern; if ((ent.MatchFlags & Options.MatchflgDirectory) != 0) { p += "/\0"; } if ((ent.MatchFlags & Options.MatchflgInclude) != 0) { f.WriteInt(l + 2); f.IoPrintf("+ "); } else if ((p[0] == '-' || p[0] == '+') && p[1] == ' ') { f.WriteInt(l + 2); f.IoPrintf("- "); } else { f.WriteInt(l); } f.IoPrintf(p); } f.WriteInt(0); }
public void SendFileName(IoStream ioStream, List <FileStruct> fileList, string fileName, bool recursive, UInt32 baseFlags) { var file = MakeFile(fileName, fileList, ioStream == null && _options.DeleteExcluded ? Options.ServerExcludes : Options.AllExcludes); if (file == null) { return; } EmitFileListProgress(fileList); if (!string.IsNullOrEmpty(file.BaseName)) { fileList.Add(file); SendFileEntry(file, ioStream, baseFlags); if (recursive && Util.S_ISDIR(file.Mode) && (file.Flags & Options.FlagMountPoint) == 0) { _options.LocalExcludeList.Clear(); SendDirectory(ioStream, fileList, file.GetFullName()); } } }
public void ReceiveGenerator(string fileName, FileStruct file, int i, IoStream f) { fileName = Path.Combine(_options.Dir, fileName); if (UnchangedFile(fileName, file)) { return; } if (_options.Verbose > 2) { Log.WriteLine("Receive Generator(" + fileName + "," + i + ")\n"); } int statRet; var st = new FStat(); if (_options.DryRun) { statRet = -1; } else { statRet = 0; try { var fi = new FileInfo(fileName); // TODO: path length st.Size = fi.Length; // TODO: path length st.MTime = fi.LastWriteTime; } catch { statRet = -1; } } if (_options.OnlyExisting && statRet == -1) { /* we only want to update existing files */ if (_options.Verbose > 1) { Log.WriteLine("not creating new file \"" + fileName + "\""); } return; } var fNameCmp = fileName; if (_options.WholeFile > 0) { f.WriteInt(i); WriteSumHead(f, null); return; } FileStream fd; try { fd = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read); } catch { if (_options.Verbose > 3) { Log.WriteLine("failed to open " + Util.FullFileName(fNameCmp) + ", continuing"); } f.WriteInt(i); WriteSumHead(f, null); return; } if (_options.Verbose > 3) { Log.WriteLine("gen mapped " + fNameCmp + " of size " + st.Size); } if (_options.Verbose > 2) { Log.WriteLine("generating and sending sums for " + i); } f.WriteInt(i); Stream fCopy = null; GenerateAndSendSums(fd, st.Size, f, fCopy); if (fCopy != null) { fCopy.Close(); } fd.Close(); }
public void GenerateFiles(IoStream f, List <FileStruct> fileList, string localName) { int i; var phase = 0; if (_options.Verbose > 2) { Log.WriteLine("generator starting count=" + fileList.Count); } for (i = 0; i < fileList.Count; i++) { var file = (fileList[i]); if (file.BaseName == null) { continue; } if (Util.S_ISDIR(file.Mode)) { continue; } ReceiveGenerator(localName != null ? localName : file.GetFullName(), file, i, f); } phase++; _checkSum.Length = CheckSum.SumLength; if (_options.Verbose > 2) { Log.WriteLine("GenerateFiles phase=" + phase); } f.WriteInt(-1); phase++; if (_options.Verbose > 2) { Log.WriteLine("GenerateFiles phase=" + phase); } f.WriteInt(-1); if (_options.ProtocolVersion >= 29 && !_options.DelayUpdates) { f.WriteInt(-1); } /* now we need to fix any directory permissions that were * modified during the transfer * */ for (i = 0; i < fileList.Count; i++) { var file = (fileList[i]); if (file.BaseName != null || Util.S_ISDIR(file.Mode)) { continue; } ReceiveGenerator(localName != null ? localName : file.GetFullName(), file, i, null); } if (_options.Verbose > 2) { Log.WriteLine("GenerateFiles finished"); } }
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 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 SendDeflatedToken(IoStream f, int token, MapFile buf, int offset, int nb, int toklen) { }
public int ReceiveDeflatedToken(IoStream f, byte[] data, int offset) { return(0); }
public void SendFileEntry(FileStruct file, IoStream ioStream, UInt32 baseflags) { var flags = baseflags; int l1 = 0, l2 = 0; if (ioStream == null) { return; } if (file == null) { ioStream.WriteByte(0); _lastName = String.Empty; return; } var fileName = file.GetFullName().Replace(":", String.Empty); for (l1 = 0; _lastName.Length > l1 && (fileName[l1] == _lastName[l1]) && (l1 < 255); l1++) { } l2 = fileName.Substring(l1).Length; flags |= Options.XmitSameName; if (l2 > 255) { flags |= Options.XmitLongName; } if (_options.ProtocolVersion >= 28) { if (flags == 0 && !Util.S_ISDIR(file.Mode)) { flags |= Options.XmitTopDir; } /*if ((flags & 0xFF00) > 0 || flags == 0) * { * flags |= Options.XMIT_EXTENDED_FLAGS; * f.writeByte((byte)flags); * f.writeByte((byte)(flags >> 8)); * } * else */ ioStream.WriteByte((byte)flags); } else { if ((flags & 0xFF) == 0 && !Util.S_ISDIR(file.Mode)) { flags |= Options.XmitTopDir; } if ((flags & 0xFF) == 0) { flags |= Options.XmitLongName; } ioStream.WriteByte((byte)flags); } if ((flags & Options.XmitSameName) != 0) { ioStream.WriteByte((byte)l1); } if ((flags & Options.XmitLongName) != 0) { ioStream.WriteInt(l2); } else { ioStream.WriteByte((byte)l2); } var b = Encoding.ASCII.GetBytes(fileName); ioStream.Write(b, l1, l2); ioStream.WriteLongInt(file.Length); if ((flags & Options.XmitSameTime) == 0) { ioStream.WriteInt(file.ModTime.Second); } if ((flags & Options.XmitSameMode) == 0) { ioStream.WriteInt((int)file.Mode); } if (_options.PreserveUid && (flags & Options.XmitSameUid) == 0) { ioStream.WriteInt(file.Uid); } if (_options.PreserveGid && (flags & Options.XmitSameGid) == 0) { ioStream.WriteInt(file.Gid); } if (_options.AlwaysChecksum) { byte[] sum; if (!Util.S_ISDIR(file.Mode)) { sum = file.Sum; } else if (_options.ProtocolVersion < 28) { sum = new byte[16]; } else { sum = null; } if (sum != null) { ioStream.Write(sum, 0, _options.ProtocolVersion < 21 ? 2 : CheckSum.Md4SumLength); } } _lastName = fileName; }
/// <summary> /// Do nothing /// </summary> /// <param name="f"></param> public static void SendListing(IoStream f) //@todo_long empty method { }
public List <FileStruct> SendFileList(ClientInfo clientInfo, string[] argv) { IoStream ioStream = null; if (clientInfo != null) { ioStream = clientInfo.IoStream; } string dir, oldDir; var lastPath = String.Empty; //@todo_long seems to be Empty all the time var fileName = String.Empty; var useFffd = false; //@todo_long seems to be false all the time if (ShowFileListProgress() && ioStream != null) { StartFileListProgress("building file list"); } var startWrite = Options.Stats.TotalWritten; var fileList = new List <FileStruct>(); if (ioStream != null) { ioStream.IoStartBufferingOut(); if (Options.FilesFromFd != null) //@todo_long seems to be unused because filesFromFD seems to be null all the time { if (!string.IsNullOrEmpty(argv[0]) && !Util.PushDir(argv[0])) { WinRsync.Exit("pushDir " + Util.FullFileName(argv[0]) + " failed", clientInfo); } useFffd = true; } } while (true) { if (useFffd) //@todo_long seems to be unused because useFFFD seems to be false all the time { if ((fileName = ioStream.ReadFilesFromLine(Options.FilesFromFd, _options)).Length == 0) { break; } } else { if (argv.Length == 0) { break; } fileName = argv[0]; argv = Util.DeleteFirstElement(argv); if (fileName != null && fileName.Equals(".")) { continue; } if (fileName != null) { fileName = fileName.Replace(@"\", "/"); } } // TODO: path length if (Directory.Exists(fileName) && !_options.Recurse && _options.FilesFrom == null) { Log.WriteLine("skipping directory " + fileName); continue; } dir = null; oldDir = String.Empty; if (!_options.RelativePaths) { var index = fileName.LastIndexOf('/'); if (index != -1) { if (index == 0) { dir = "/"; } else { dir = fileName.Substring(0, index); } fileName = fileName.Substring(index + 1); } } else { if (ioStream != null && _options.ImpliedDirs && fileName.LastIndexOf('/') > 0) { var fileDir = fileName.Substring(0, fileName.LastIndexOf('/')); var slash = fileName; var i = 0; //@todo_long seems to be 0 all the time while (i < fileDir.Length && i < lastPath.Length && fileDir[i] == lastPath[i]) //@todo_long seems that it is never executed because lastPath is allways Empty { if (fileDir[i] == '/') { slash = fileName.Substring(i); } i++; } if (i != fileName.LastIndexOf('/') || (i < lastPath.Length && lastPath[i] != '/'))//@todo_long seems to be executed unconditionally because i=0 and fileName.LastIndexOf('/') > 0 { var copyLinksSaved = _options.CopyLinks; var recurseSaved = _options.Recurse; _options.CopyLinks = _options.CopyUnsafeLinks; _options.Recurse = true; int j; while ((j = slash.IndexOf('/')) != -1) { SendFileName(ioStream, fileList, fileName.Substring(0, j), false, 0); slash = slash.Substring(0, j) + ' ' + slash.Substring(j + 1); } _options.CopyLinks = copyLinksSaved; _options.Recurse = recurseSaved; lastPath = fileName.Substring(0, i); } } } if (!string.IsNullOrEmpty(dir)) { oldDir = Util.CurrDir; if (!Util.PushDir(dir)) { Log.WriteLine("pushDir " + Util.FullFileName(dir) + " failed"); continue; } if (_lastDir != null && _lastDir.Equals(dir)) { _fileListDir = _lastDir; } else { _fileListDir = _lastDir = dir; } } SendFileName(ioStream, fileList, fileName, _options.Recurse, Options.XmitTopDir); if (!string.IsNullOrEmpty(oldDir)) { _fileListDir = null; if (Util.PopDir(oldDir)) { WinRsync.Exit("pop_dir " + Util.FullFileName(dir) + " failed", clientInfo); } } } if (ioStream != null) { SendFileEntry(null, ioStream, 0); if (ShowFileListProgress()) { FinishFileListProgress(fileList); } } CleanFileList(fileList, false, false); if (ioStream != null) { ioStream.WriteInt(0); Options.Stats.FileListSize = (int)(Options.Stats.TotalWritten - startWrite); Options.Stats.NumFiles = fileList.Count; } if (_options.Verbose > 3) { OutputFileList(fileList); } if (_options.Verbose > 2) { Log.WriteLine("sendFileList done"); } return(fileList); }