public static int DoReceive(ClientInfo cInfo, List <FileStruct> fileList, string localName) { var f = cInfo.IoStream; var options = cInfo.Options; var receiver = new Receiver(options); options.CopyLinks = false; f.Flush(); if (!options.DeleteAfter) { if (options.Recurse && options.DeleteMode && localName == null && fileList.Count > 0) { receiver.DeleteFiles(fileList); } } f.IoStartBufferingOut(); var gen = new Generator(options); gen.GenerateFiles(f, fileList, localName); f.Flush(); if (fileList != null && fileList.Count != 0) { receiver.ReceiveFiles(cInfo, fileList, localName); } WinRsync.Report(cInfo); if (options.ProtocolVersion >= 24) { /* send a final goodbye message */ f.WriteInt(-1); } f.Flush(); return(0); }
/// <summary> /// /// </summary> /// <param name="count"></param> /// <returns></returns> public byte[] ReadBuffer(int count) { var buffer = new byte[count]; int bytesRead; var total = 0; while (total < count) { try { bytesRead = ReadSocketUnbuffered(buffer, total, count - total); total += bytesRead; } catch (Exception) { WinRsync.Exit("Unable to read data from the transport connection", null); if (ClientThread != null) { ClientThread.Abort(); } return(null); } } CalculateTotalRead(count); return(buffer); }
public static void DoServerReceive(ClientInfo cInfo, string[] args) { var options = cInfo.Options; var f = cInfo.IoStream; if (options.Verbose > 2) { Log.Write("Server receive starting"); } if (options.AmDaemon && Config.ModuleIsReadOnly(options.ModuleId)) { WinRsync.Exit("ERROR: module " + Config.GetModuleName(options.ModuleId) + " is read only", cInfo); return; } f.IoStartBufferingIn(); if (options.DeleteMode && !options.DeleteExcluded) { var excl = new Exclude(options); excl.ReceiveExcludeList(f); } var fList = new FileList(cInfo.Options); var fileList = fList.ReceiveFileList(cInfo); DoReceive(cInfo, fileList, null); }
public static int StartDaemon(ClientInfo clientInfo) { var stream = clientInfo.IoStream; var options = clientInfo.Options; options.AmDaemon = true; stream.IoPrintf("@RSYNCD: " + options.ProtocolVersion + "\n"); var line = stream.ReadLine(); try { options.RemoteProtocol = Int32.Parse(line.Substring(9, 2)); } catch { options.RemoteProtocol = 0; } var isValidstring = line.StartsWith("@RSYNCD: ") && line.EndsWith("\n") && options.RemoteProtocol > 0; if (!isValidstring) { stream.IoPrintf("@ERROR: protocol startup error\n"); return(-1); } if (options.ProtocolVersion > options.RemoteProtocol) { options.ProtocolVersion = options.RemoteProtocol; } line = stream.ReadLine(); if (String.Compare(line, "#list\n", StringComparison.Ordinal) == 0) { ClientServer.SendListing(stream); return(-1); } if (line[0] == '#') { stream.IoPrintf("@ERROR: Unknown command '" + line.Replace("\n", String.Empty) + "'\n"); return(-1); } var i = Config.GetNumberModule(line.Replace("\n", String.Empty)); if (i < 0) { stream.IoPrintf("@ERROR: Unknown module " + line); WinRsync.Exit("@ERROR: Unknown module " + line, clientInfo); } options.DoStats = true; options.ModuleId = i; ClientServer.RsyncModule(clientInfo, i); clientInfo.IoStream.Close(); return(1); }
public int ClientRun(ClientInfo clientInfo, int pid, string[] args) { var options = clientInfo.Options; var ioStream = clientInfo.IoStream; FileList fList; List <FileStruct> fileList; WinRsync.SetupProtocol(clientInfo); if (options.ProtocolVersion >= 23 && !options.ReadBatch) { ioStream.IoStartMultiplexIn(); } if (options.AmSender) { ioStream.IoStartBufferingOut(); if (options.DeleteMode && !options.DeleteExcluded) { var excl = new Exclude(options); excl.SendExcludeList(ioStream); } if (options.Verbose > 3) { Log.Write("File list sent\n"); } ioStream.Flush(); fList = new FileList(options); fileList = fList.SendFileList(clientInfo, args); if (options.Verbose > 3) { Log.WriteLine("file list sent"); } ioStream.Flush(); var sender = new Sender(options); sender.SendFiles(fileList, clientInfo); ioStream.Flush(); ioStream.WriteInt(-1); return(-1); } options.Dir = args[0]; options.Dir = Path.GetFullPath(options.Dir ?? string.Empty); if (!options.ReadBatch) { var excl = new Exclude(options); excl.SendExcludeList(ioStream); } fList = new FileList(options); fileList = fList.ReceiveFileList(clientInfo); return(Daemon.DoReceive(clientInfo, fileList, null)); }
private static void DoServerSender(ClientInfo clientInfo, string[] args) { var dir = args[0]; var ioStream = clientInfo.IoStream; var options = clientInfo.Options; if (options.Verbose > 2) { Log.Write("Server sender starting"); } if (options.AmDaemon && Config.ModuleIsWriteOnly(options.ModuleId)) { WinRsync.Exit("ERROR: module " + Config.GetModuleName(options.ModuleId) + " is write only", clientInfo); return; } if (!options.RelativePaths && !Util.PushDir(dir)) { WinRsync.Exit("Push_dir#3 " + dir + "failed", clientInfo); return; } var fList = new FileList(options); var fileList = fList.SendFileList(clientInfo, args); if (options.Verbose > 3) { Log.WriteLine("File list sent"); } if (fileList.Count == 0) { WinRsync.Exit("File list is empty", clientInfo); return; } ioStream.IoStartBufferingIn(); ioStream.IoStartBufferingOut(); var sender = new Sender(options); sender.SendFiles(fileList, clientInfo); ioStream.Flush(); WinRsync.Report(clientInfo); if (options.ProtocolVersion >= 24) { ioStream.ReadInt(); } ioStream.Flush(); }
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(); }
/// <summary> /// Returns offset in p array /// </summary> /// <param name="offset"></param> /// <param name="length"></param> /// <returns></returns> public int MapPtr(int offset, int length) { int numberOfReadBytes; int windowStart, readStart; int windowSize, readSize, readOffset; if (length == 0) { return(-1); } if (length > (FileSize - offset)) { length = FileSize - offset; } if (offset >= _pOffset && offset + length <= _pOffset + _pLength) { return(offset - _pOffset); } windowStart = offset; windowSize = _defaultWindowSize; if (windowStart + windowSize > FileSize) { windowSize = FileSize - windowStart; } if (offset + length > windowStart + windowSize) { windowSize = (offset + length) - windowStart; } if (windowSize > _pSize) { ExtendArray(ref P, windowSize); _pSize = windowSize; } if (windowStart >= _pOffset && windowStart < _pOffset + _pLength && windowStart + windowSize >= _pOffset + _pLength) { readStart = _pOffset + _pLength; readOffset = readStart - windowStart; readSize = windowSize - readOffset; MemoryMove(ref P, P, (_pLength - readOffset), readOffset); } else { readStart = windowStart; readSize = windowSize; readOffset = 0; } if (readSize <= 0) { Log.WriteLine("Warning: unexpected read size of " + readSize + " in MapPtr"); } else { if (_pFileDescriptorOffset != readStart) { if (_fileDescriptor.Seek(readStart, SeekOrigin.Begin) != readStart) { WinRsync.Exit("Seek failed in MapPtr", null); } _pFileDescriptorOffset = readStart; } if ((numberOfReadBytes = _fileDescriptor.Read(P, readOffset, readSize)) != readSize) { //if (numberOfReadBytes < 0) //@fixed Read never returns <0 so status is false all the time //{ // numberOfReadBytes = 0; // status = true; //} FillMemory(ref P, readOffset + numberOfReadBytes, 0, readSize - numberOfReadBytes); } _pFileDescriptorOffset += numberOfReadBytes; } _pOffset = windowStart; _pLength = windowSize; return(offset - _pOffset); }
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 int ReceiveFiles(ClientInfo clientInfo, List <FileStruct> fileList, string localName) { var st = new FStat(); FileStruct file; var ioStream = clientInfo.IoStream; string fileName; string fNameCmp = String.Empty, fNameTmp = String.Empty; var saveMakeBackups = _options.MakeBackups; int i, phase = 0; bool recvOk; if (_options.Verbose > 2) { Log.WriteLine("ReceiveFiles(" + fileList.Count + ") starting"); } while (true) { i = ioStream.ReadInt(); if (i == -1) { if (phase != 0) { break; } phase = 1; _checkSum.Length = CheckSum.SumLength; if (_options.Verbose > 2) { Log.WriteLine("ReceiveFiles phase=" + phase); } ioStream.WriteInt(0); //send_msg DONE if (_options.KeepPartial) { _options.MakeBackups = false; } continue; } if (i < 0 || i >= fileList.Count) { WinRsync.Exit("Invalid file index " + i + " in receiveFiles (count=" + fileList.Count + ")", clientInfo); } file = (fileList[i]); Options.Stats.CurrentFileIndex = i; Options.Stats.NumTransferredFiles++; Options.Stats.TotalTransferredSize += file.Length; if (!localName.IsBlank()) { fileName = localName; } else { fileName = Path.Combine(_options.Dir, LocalizePath(clientInfo, file.GetFullName().Replace(":", String.Empty)).Replace("\\", "/")); //fileName = Path.Combine(options.dir, file.FNameTo().Replace(":",String.Empty)).Replace("\\", "/"); // TODO: path length Directory.CreateDirectory(Path.Combine(_options.Dir, LocalizePath(clientInfo, file.DirName.Replace(":", String.Empty))).Replace("\\", "/")); Log.WriteLine(Path.Combine(_options.Dir, file.DirName)); //FileSystem.Directory.CreateDirectory(Path.Combine(options.dir,file.dirName.Replace(":",String.Empty)).Replace("\\", "/")); } if (_options.DryRun) { if (!_options.AmServer && _options.Verbose > 0) { Log.WriteLine(fileName); } continue; } if (_options.Verbose > 2) { Log.WriteLine("receiveFiles(" + fileName + ")"); } if (_options.PartialDir != null && _options.PartialDir.CompareTo(String.Empty) != 0) { } else { fNameCmp = fileName; } FileStream fd1 = null; try { fd1 = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read); } catch (FileNotFoundException) { fNameCmp = fileName; try { fd1 = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read); } catch (FileNotFoundException) { } } catch (Exception e) { Log.Write(e.Message); } try { var fi = new FileInfo(fNameCmp); // TODO: path length st.Size = fi.Length; } catch { } var tempFileName = GetTmpName(fileName); FileStream fd2 = null; fd2 = new FileStream(tempFileName, FileMode.OpenOrCreate, FileAccess.Write); if (!_options.AmServer && _options.Verbose > 0) { Log.WriteLine(fileName); } /* recv file data */ recvOk = ReceiveData(clientInfo, fNameCmp, fd1, st.Size, fileName, fd2, file.Length); if (fd1 != null) { fd1.Close(); } if (fd2 != null) { fd2.Close(); } // TODO: path length File.Copy(tempFileName, fileName, true); // TODO: path length File.Delete(tempFileName); if (recvOk || _options.Inplace) { FinishTransfer(fileName, fNameTmp, file, recvOk); } } _options.MakeBackups = saveMakeBackups; if (_options.DeleteAfter && _options.Recurse && localName == null && fileList.Count > 0) { DeleteFiles(fileList); } if (_options.Verbose > 2) { Log.WriteLine("ReceiveFiles finished"); } return(0); }
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); }
/// <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); }
/// <summary> /// /// </summary> /// <param name="options"></param> /// <returns></returns> public bool LoadParm(Options options) { lock (this) { // TODO: path length if (!File.Exists(_confFile)) { WinRsync.Exit("Can't find .conf file: " + _confFile, null); return(false); } try { using (var cf = new StreamReader(_confFile)) { Module mod = null; if (Modules == null) { Modules = new List <Module>(); } lock (cf) { while (true) { var line = cf.ReadLine(); if (line == null) { break; } line = line.Trim(); if (!line.IsBlank() && !line.StartsWith(";") && !line.StartsWith("#")) { if (line.StartsWith("[") && line.StartsWith("]")) { line = line.TrimStart('[').TrimEnd(']'); var numberModule = -1; if ((numberModule = GetNumberModule(line)) >= 0) { mod = GetModule(numberModule); } else { mod = new Module(line); Modules.Add(mod); } } else { if (mod != null) { var parm = line.Split('='); if (parm.Length > 2) { continue; } parm[0] = parm[0].Trim().ToLower(); parm[1] = parm[1].Trim(); switch (parm[0]) { case "path": mod.Path = parm[1].Replace(@"\", "/"); break; case "comment": mod.Comment = parm[1]; break; case "read only": mod.ReadOnly = (parm[1].CompareTo("false") == 0) ? false : true; break; case "write only": mod.WriteOnly = (parm[1].CompareTo("true") == 0) ? true : false; break; case "hosts allow": mod.HostsAllow = parm[1]; break; case "hosts deny": mod.HostsDeny = parm[1]; break; case "auth users": mod.AuthUsers = parm[1]; break; case "secrets file": mod.SecretsFile = Path.GetFileName(parm[1]); break; default: continue; } } else { var parm = line.Split('='); if (parm.Length > 2) { continue; } parm[0] = parm[0].Trim(); parm[1] = parm[1].Trim(); switch (parm[0]) { case "log file": var logFile = parm[1]; try { options.LogFile = new FileStream(logFile, FileMode.OpenOrCreate | FileMode.Append, FileAccess.Write); } catch (Exception e) { Log.Write(e.Message); } break; case "port": Port = parm[1]; options.RsyncPort = Convert.ToInt32(Port); break; case "address": options.BindAddress = Address = parm[1]; break; default: continue; } } } } } cf.Close(); } } } catch { WinRsync.Exit("failed to open: " + _confFile, null); return(false); } } return(true); }
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 FileStruct ReceiveFileEntry(UInt32 flags, ClientInfo clientInfo) { if (clientInfo == null) { _lastName = String.Empty; return(null); } var f = clientInfo.IoStream; int l1 = 0, l2 = 0; if ((flags & Options.XmitSameName) != 0) { l1 = f.ReadByte(); } if ((flags & Options.XmitLongName) != 0) { l2 = f.ReadInt(); } else { l2 = f.ReadByte(); } if (l2 >= Options.Maxpathlen - l1) { WinRsync.Exit("overflow: lastname=" + _lastName, clientInfo); } var thisName = _lastName.Substring(0, l1); thisName += f.ReadStringFromBuffer(l2); _lastName = thisName; thisName = Util.CleanFileName(thisName, false); if (_options.SanitizePath) { thisName = Util.SanitizePath(thisName, String.Empty, 0); } var baseName = String.Empty; var dirName = String.Empty; if (thisName.LastIndexOf("/") != -1) { baseName = Path.GetFileName(thisName); dirName = Path.GetDirectoryName(thisName); } else { baseName = thisName; dirName = null; } var fileLength = f.ReadLongInt(); if ((flags & Options.XmitSameTime) == 0) { _modTime = DateTime.FromFileTime(f.ReadInt()); } if ((flags & Options.XmitSameMode) == 0) { _mode = (UInt32)f.ReadInt(); } if (_options.PreserveUid && (flags & Options.XmitSameUid) == 0) { var uid = f.ReadInt(); } if (_options.PreserveGid && (flags & Options.XmitSameGid) == 0) { var gid = f.ReadInt(); } var sum = new byte[0]; if (_options.AlwaysChecksum && !Util.S_ISDIR(_mode)) { sum = new byte[CheckSum.Md4SumLength]; sum = f.ReadBuffer(_options.ProtocolVersion < 21 ? 2 : CheckSum.Md4SumLength); } var fs = new FileStruct(); fs.Length = (int)fileLength; fs.BaseName = baseName; fs.DirName = dirName; fs.Sum = sum; fs.Mode = _mode; fs.ModTime = _modTime; fs.Flags = flags; return(fs); }
public static int ParseArguments(string[] args, Options options) { var argsNotUsed = 0; var i = 0; var excl = new Exclude(options); while (i < args.Length) { try { switch (args[i]) { case "--suffix": options.BackupSuffix = args[++i]; break; case "--rsync-path": options.RsyncPath = args[++i]; break; case "--password-file": options.PasswordFile = args[++i]; break; case "--ignore-times": case "-I": options.IgnoreTimes = true; break; case "--size-only": options.SizeOnly = true; break; case "--modify-window": options.UsingModifyWindow = true; options.ModifyWindow = Convert.ToInt32(args[++i]); break; case "--one-file-system": case "-x": options.OneFileSystem = true; break; case "--delete": options.DeleteMode = true; break; case "--existing": options.OnlyExisting = true; break; case "--ignore-existing": options.OptIgnoreExisting = true; break; case "--delete-after": options.DeleteMode = true; options.DeleteAfter = true; break; case "--delete-excluded": options.DeleteMode = true; options.DeleteExcluded = true; break; case "--force": options.ForceDelete = true; break; case "--numeric-ids": options.NumericIds = true; break; case "--exclude": excl.AddExclude(ref options.ExcludeList, args[++i], 0); break; case "--include": excl.AddExclude(ref options.ExcludeList, args[++i], (int)Options.XflgDefInclude); options.ForceDelete = true; break; case "--exclude-from": case "--include-from": var arg = args[i]; excl.AddExcludeFile(ref options.ExcludeList, args[++i], (arg.CompareTo("--exclude-from") == 0) ? 0 : (int)Options.XflgDefInclude); break; case "--safe-links": options.SafeSymlinks = true; break; case "--help": case "-h": WinRsync.Exit(String.Empty, null); break; case "--backup": case "-b": options.MakeBackups = true; break; case "--dry-run": case "-n": options.DryRun = true; break; case "--sparse": case "-S": options.SparseFiles = true; break; case "--cvs-exclude": case "-C": options.CvsExclude = true; break; case "--update": case "-u": options.UpdateOnly = true; break; case "--inplace": options.Inplace = true; break; case "--keep-dirlinks": case "-K": options.KeepDirLinks = true; break; case "--links": case "-l": options.PreserveLinks = true; break; case "--copy-links": case "-L": options.CopyLinks = true; break; case "--whole-file": case "-W": options.WholeFile = 1; break; case "--no-whole-file": options.WholeFile = 0; break; case "--copy-unsafe-links": options.CopyUnsafeLinks = true; break; case "--perms": case "-p": options.PreservePerms = true; break; case "--owner": case "-o": options.PreserveUid = true; break; case "--group": case "-g": options.PreserveGid = true; break; case "--devices": case "-D": options.PreserveDevices = true; break; case "--times": case "-t": options.PreserveTimes = true; break; case "--checksum": case "-c": options.AlwaysChecksum = true; break; case "--verbose": case "-v": options.Verbose++; break; case "--quiet": case "-q": options.Quiet++; break; case "--archive": case "-a": options.ArchiveMode = true; break; case "--server": options.AmServer = true; break; case "--sender": options.AmSender = true; break; case "--recursive": case "-r": options.Recurse = true; break; case "--relative": case "-R": options.RelativePaths = true; break; case "--no-relative": options.RelativePaths = false; break; case "--rsh": case "-e": options.ShellCmd = args[++i]; break; case "--block-size": case "-B": options.BlockSize = Convert.ToInt32(args[++i]); break; case "--max-delete": options.MaxDelete = Convert.ToInt32(args[++i]); break; case "--timeout": options.IoTimeout = Convert.ToInt32(args[++i]); break; case "--temp-dir": case "-T": options.TmpDir = args[++i]; break; case "--compare-dest": options.CompareDest = args[++i]; break; case "--link-dest": options.CompareDest = args[++i]; break; case "--compress": case "-z": options.DoCompression = true; break; case "--stats": options.DoStats = true; break; case "--progress": options.DoProgress = true; break; case "--partial": options.KeepPartial = true; break; case "--partial-dir": options.PartialDir = args[++i]; break; case "--ignore-errors": options.IgnoreErrors = true; break; case "--blocking-io": options.BlockingIo = 1; break; case "--no-blocking-io": options.BlockingIo = 0; break; case "-P": options.DoProgress = true; options.KeepPartial = true; break; case "--log-format": options.LogFormat = args[++i]; break; case "--bwlimit": options.BwLimit = Convert.ToInt32(args[++i]); break; case "--backup-dir": options.BackupDir = args[++i]; break; case "--hard-links": case "-H": options.PreserveHardLinks = true; break; case "--read-batch": options.BatchName = args[++i]; options.ReadBatch = true; break; case "--write-batch": options.BatchName = args[++i]; options.WriteBatch = true; break; case "--files-from": options.FilesFrom = args[++i]; break; case "--from0": options.EolNulls = true; break; case "--no-implied-dirs": options.ImpliedDirs = true; break; case "--protocol": options.ProtocolVersion = Convert.ToInt32(args[++i]); break; case "--checksum-seed": options.ChecksumSeed = Convert.ToInt32(args[++i]); break; case "--daemon": options.AmDaemon = true; break; case "--address": options.BindAddress = args[++i]; break; case "--port": options.RsyncPort = Convert.ToInt32(args[++i]); break; case "--config": options.ConfigFile = args[++i].Trim(); break; default: { argsNotUsed += ParseMergeArgs(args[i], options); break; } } i++; } catch { return(-1); } } if (options.AmSender && !options.AmServer) { WinRsync.Exit(String.Empty, null); } if (options.IoTimeout > 0 && options.IoTimeout < options.SelectTimeout) { options.SelectTimeout = options.IoTimeout; } return(argsNotUsed); }