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 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 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 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 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); }
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; }
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 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(); }