public static void DoServerReceive(ClientInfo cInfo, string[] args) { Options options = cInfo.Options; IOStream f = cInfo.IoStream; if (options.verbose > 2) { Log.Write("Server receive starting"); } if (options.amDaemon && config.ModuleIsReadOnly(options.ModuleId)) { MainClass.Exit("ERROR: module " + config.GetModuleName(options.ModuleId) + " is read only", cInfo); return; } f.IOStartBufferingIn(); if (options.deleteMode && !options.deleteExcluded) { Exclude excl = new Exclude(options); excl.ReceiveExcludeList(f); } FileList fList = new FileList(cInfo.Options); List <FileStruct> fileList = fList.receiveFileList(cInfo); DoReceive(cInfo, fileList, null); }
public byte[] ReadBuf(int len) { byte[] data = new byte[len]; int ret; int total = 0; while (total < len) { try { ret = ReadfdUnbuffered(data, total, len - total); total += ret; } catch (Exception e) { MainClass.Exit("Unable to read data from the transport connection", null); if (ClientThread != null) { ClientThread.Abort(); } return(null); } } CalculationTotalRead(len); return(data); }
/// <summary> /// /// </summary> /// <param name="count"></param> /// <returns></returns> public byte[] ReadBuffer(int count) { byte[] buffer = new byte[count]; int bytesRead; int total = 0; while (total < count) { try { bytesRead = ReadSocketUnbuffered(buffer, total, count - total); total += bytesRead; } catch (Exception) { MainClass.Exit("Unable to read data from the transport connection", null); if (ClientThread != null) { ClientThread.Abort(); } return(null); } } CalculateTotalRead(count); return(buffer); }
public static int StartDaemon(ClientInfo clientInfo) { IOStream stream = clientInfo.IoStream; Options options = clientInfo.Options; options.amDaemon = true; stream.IOPrintf("@RSYNCD: " + options.protocolVersion + "\n"); string line = stream.ReadLine(); try { options.remoteProtocol = Int32.Parse(line.Substring(9, 2)); } catch { options.remoteProtocol = 0; } bool 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 (line.CompareTo("#list\n") == 0) { ClientServer.SendListing(stream); return(-1); } if (line[0] == '#') { stream.IOPrintf("@ERROR: Unknown command '" + line.Replace("\n", String.Empty) + "'\n"); return(-1); } int i = config.GetNumberModule(line.Replace("\n", String.Empty)); if (i < 0) { stream.IOPrintf("@ERROR: Unknown module " + line); MainClass.Exit("@ERROR: Unknown module " + line, clientInfo); } options.doStats = true; options.ModuleId = i; ClientServer.RsyncModule(clientInfo, i); clientInfo.IoStream.Close(); return(1); }
public static void StartAcceptLoop(int port) { IPAddress localAddr = IPAddress.Parse(ServerOptions.bindAddress); Server = new TcpListener(localAddr, port); //Switched to this one because TcpListener(port) is obsolete //Server = new TcpListener(port); try { Server.Start(); } catch (Exception) { MainClass.Exit("Can't listening address " + ServerOptions.bindAddress + " on port " + port, null); System.Environment.Exit(0); } Log.WriteLine("WinRSyncd starting, listening on port " + port); StopServer = false; ClientSockets = new List <TCPSocketListener>(); while (!StopServer) { try { Socket soc = Server.AcceptSocket(); if (!config.LoadParm(ServerOptions)) { continue; } TCPSocketListener socketListener = new TCPSocketListener(soc, ref ClientSockets); lock (ClientSockets) { ClientSockets.Add(socketListener); } socketListener.StartSocketListener(); for (int i = 0; i < ClientSockets.Count; i++) { if (ClientSockets[i] == null) { ClientSockets.RemoveAt(i); } } } catch (SocketException) { StopServer = true; } } if (ServerOptions.logFile != null) { ServerOptions.logFile.Close(); } }
static void DoServerSender(ClientInfo clientInfo, string[] args) { string dir = args[0]; IOStream ioStream = clientInfo.IoStream; Options options = clientInfo.Options; if (options.verbose > 2) { Log.Write("Server sender starting"); } if (options.amDaemon && config.ModuleIsWriteOnly(options.ModuleId)) { MainClass.Exit("ERROR: module " + config.GetModuleName(options.ModuleId) + " is write only", clientInfo); return; } if (!options.relativePaths && !Util.pushDir(dir)) { MainClass.Exit("Push_dir#3 " + dir + "failed", clientInfo); return; } FileList fList = new FileList(options); List <FileStruct> fileList = fList.sendFileList(clientInfo, args); if (options.verbose > 3) { Log.WriteLine("File list sent"); } if (fileList.Count == 0) { MainClass.Exit("File list is empty", clientInfo); return; } ioStream.IOStartBufferingIn(); ioStream.IOStartBufferingOut(); Sender sender = new Sender(options); sender.SendFiles(fileList, clientInfo); ioStream.Flush(); MainClass.Report(clientInfo); if (options.protocolVersion >= 24) { ioStream.readInt(); } ioStream.Flush(); }
public static IOStream OpenSocketOut(string host, int port, string bindAddress) { TcpClient client = null; try { client = new TcpClient(host, port); } catch (Exception) { MainClass.Exit("Can't connect to server", null); } IOStream stream = new IOStream(client.GetStream()); return(stream); }
/// <summary> /// /// </summary> /// <param name="cInfo"></param> public static void SetupProtocol(ClientInfo cInfo) { IOStream f = cInfo.IoStream; Options options = cInfo.Options; if (options.remoteProtocol == 0) { if (!options.readBatch) { f.writeInt(options.protocolVersion); } options.remoteProtocol = f.readInt(); if (options.protocolVersion > options.remoteProtocol) { options.protocolVersion = options.remoteProtocol; } } if (options.readBatch && options.remoteProtocol > options.protocolVersion) { MainClass.Exit("The protocol version in the batch file is too new", null); } if (options.verbose > 3) { Log.WriteLine("(" + (options.amServer ? "Server" : "Client") + ") Protocol versions: remote=" + options.remoteProtocol + ", negotiated=" + options.protocolVersion); } if (options.remoteProtocol < Options.MIN_PROTOCOL_VERSION || options.remoteProtocol > Options.MAX_PROTOCOL_VERSION) { MainClass.Exit("Protocol version mistmatch", null); } if (options.amServer) { if (options.checksumSeed == 0) { options.checksumSeed = (int)System.DateTime.Now.Ticks; } f.writeInt(options.checksumSeed); } else { options.checksumSeed = f.readInt(); } }
public void ReadSumHead(ClientInfo clientInfo, ref SumStruct sum) { IOStream ioStream = clientInfo.IoStream; sum.count = ioStream.readInt(); sum.bLength = (UInt32)ioStream.readInt(); if (options.protocolVersion < 27) { sum.s2Length = checkSum.length; } else { sum.s2Length = ioStream.readInt(); if (sum.s2Length > CheckSum.MD4_SUM_LENGTH) { MainClass.Exit("Invalid checksum length " + sum.s2Length, clientInfo); } } sum.remainder = (UInt32)ioStream.readInt(); }
public void Run(string[] args) { opt = new Options(); opt.Init(); if (args.Length == 0) { Usage(); MainClass.Exit(String.Empty, null); } int argsNotUsed = CommandLineParser.ParseArguments(args, opt); if (argsNotUsed == -1) { MainClass.Exit("Error parsing options", null); } string[] args2 = new string[argsNotUsed]; for (int i = 0; i < argsNotUsed; i++) { args2[i] = args[args.Length - argsNotUsed + i]; } if (opt.amDaemon && !opt.amSender) { Daemon.DaemonMain(opt); return; } ClientInfo cInfo = new ClientInfo(); cInfo.Options = opt; StartClient(args2, cInfo); opt.doStats = true; cInfo.IoStream = null; Report(cInfo); Console.Write("Press 'Enter' to exit."); Console.Read(); }
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 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); }
public List <FileStruct> sendFileList(ClientInfo clientInfo, string[] argv) { IOStream ioStream = null; if (clientInfo != null) { ioStream = clientInfo.IoStream; } string dir, oldDir; string lastPath = String.Empty; //@todo_long seems to be Empty all the time string fileName = String.Empty; bool useFFFD = false; //@todo_long seems to be false all the time if (showFileListProgress() && ioStream != null) { startFileListProgress("building file list"); } Int64 startWrite = Options.stats.totalWritten; List <FileStruct> 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])) { MainClass.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) { int 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) { string fileDir = fileName.Substring(0, fileName.LastIndexOf('/')); string slash = fileName; int 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 { bool copyLinksSaved = options.copyLinks; bool 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.XMIT_TOP_DIR); if (!string.IsNullOrEmpty(oldDir)) { fileListDir = null; if (Util.popDir(oldDir)) { MainClass.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); } IOStream f = clientInfo.IoStream; int l1 = 0, l2 = 0; if ((flags & Options.XMIT_SAME_NAME) != 0) { l1 = f.readByte(); } if ((flags & Options.XMIT_LONG_NAME) != 0) { l2 = f.readInt(); } else { l2 = f.readByte(); } if (l2 >= Options.MAXPATHLEN - l1) { MainClass.Exit("overflow: lastname=" + lastName, clientInfo); } string 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); } string baseName = String.Empty; string dirName = String.Empty; if (thisName.LastIndexOf("/") != -1) { baseName = Path.GetFileName(thisName); dirName = Path.GetDirectoryName(thisName); } else { baseName = thisName; dirName = null; } Int64 fileLength = f.ReadLongInt(); if ((flags & Options.XMIT_SAME_TIME) == 0) { modTime = DateTime.FromFileTime(f.readInt()); } if ((flags & Options.XMIT_SAME_MODE) == 0) { mode = (UInt32)f.readInt(); } if (options.preserveUID && (flags & Options.XMIT_SAME_UID) == 0) { int uid = f.readInt(); } if (options.preserveGID && (flags & Options.XMIT_SAME_GID) == 0) { int gid = f.readInt(); } byte[] sum = new byte[0]; if (options.alwaysChecksum && !Util.S_ISDIR(mode)) { sum = new byte[CheckSum.MD4_SUM_LENGTH]; sum = f.ReadBuffer(options.protocolVersion < 21 ? 2 : CheckSum.MD4_SUM_LENGTH); } FileStruct 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); }
/// <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 > (this.fileSize - offset)) { length = this.fileSize - offset; } if (offset >= this.pOffset && offset + length <= this.pOffset + this.pLength) { return(offset - this.pOffset); } windowStart = offset; windowSize = this.defaultWindowSize; if (windowStart + windowSize > this.fileSize) { windowSize = this.fileSize - windowStart; } if (offset + length > windowStart + windowSize) { windowSize = (offset + length) - windowStart; } if (windowSize > this.pSize) { ExtendArray(ref p, windowSize); this.pSize = windowSize; } if (windowStart >= this.pOffset && windowStart < this.pOffset + this.pLength && windowStart + windowSize >= this.pOffset + this.pLength) { readStart = this.pOffset + this.pLength; readOffset = readStart - windowStart; readSize = windowSize - readOffset; MemoryMove(ref this.p, this.p, (this.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 (this.pFileDescriptorOffset != readStart) { if (this.fileDescriptor.Seek(readStart, SeekOrigin.Begin) != readStart) { MainClass.Exit("Seek failed in MapPtr", null); } this.pFileDescriptorOffset = readStart; } if ((numberOfReadBytes = fileDescriptor.Read(this.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 this.p, readOffset + numberOfReadBytes, 0, readSize - numberOfReadBytes); } this.pFileDescriptorOffset += numberOfReadBytes; } this.pOffset = windowStart; this.pLength = windowSize; return(offset - this.pOffset); }
public static int ParseArguments(string[] args, Options options) { int argsNotUsed = 0; int i = 0; Exclude excl = new Exclude(options); while (i < args.Length) { try { switch (args[i]) { case "--version": MainClass.PrintRsyncVersion(); MainClass.Exit("", null); break; 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.XFLG_DEF_INCLUDE); options.forceDelete = true; break; case "--exclude-from": case "--include-from": string arg = args[i]; excl.AddExcludeFile(ref options.excludeList, args[++i], (arg.CompareTo("--exclude-from") == 0) ? 0 :(int)Options.XFLG_DEF_INCLUDE); break; case "--safe-links": options.safeSymlinks = true; break; case "--help": case "-h": MainClass.Usage(); MainClass.Exit("", 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 = 1; break; case "--no-relative": options.relativePaths = 0; 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) { MainClass.Usage(); MainClass.Exit("", null); } if (options.ioTimeout > 0 && options.ioTimeout < options.selectTimeout) { options.selectTimeout = options.ioTimeout; } return(argsNotUsed); }
public bool LoadParm(Options options) { lock (this) { TextReader cf; // TODO: path length if (confFile == null || confFile.CompareTo("") == 0 || !FileSystem.File.Exists(confFile)) { MainClass.Exit("Can't find .conf file: " + confFile, null); return(false); } try { cf = new System.IO.StreamReader(confFile); } catch { MainClass.Exit("failed to open: " + confFile, null); return(false); } Module mod = null; if (Modules == null) { Modules = new ArrayList(); } lock (cf) { while (true) { string line = cf.ReadLine(); if (line == null) { break; } line = line.Trim(); if (line.CompareTo("") != 0 && line[0] != ';' && line[0] != '#') { if (line[0] == '[' && line[line.Length - 1] == ']') { line = line.TrimStart('[').TrimEnd(']'); int numberModule = -1; if ((numberModule = GetNumberModule(line)) >= 0) { mod = GetModule(numberModule); } else { mod = new Module(line); Modules.Add(mod); } } else { if (mod != null) { string[] 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 { string[] parm = line.Split('='); if (parm.Length > 2) { continue; } parm[0] = parm[0].Trim(); parm[1] = parm[1].Trim(); switch (parm[0]) { case "log file": string 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(); } } return(true); }
public int MapPtr(int offset, int len) //returns offset in p array { int nread; int windowStart, readStart; int windowSize, readSize, readOffset; if (len == 0) { return(-1); } if (len > (this.fileSize - offset)) { len = this.fileSize - offset; } if (offset >= this.pOffset && offset + len <= this.pOffset + this.pLen) { return(offset - this.pOffset); } windowStart = offset; windowSize = this.defWindowSize; if (windowStart + windowSize > this.fileSize) { windowSize = this.fileSize - windowStart; } if (offset + len > windowStart + windowSize) { windowSize = (offset + len) - windowStart; } if (windowSize > this.pSize) { ReallocArray(ref p, windowSize); this.pSize = windowSize; } if (windowStart >= this.pOffset && windowStart < this.pOffset + this.pLen && windowStart + windowSize >= this.pOffset + this.pLen) { readStart = this.pOffset + this.pLen; readOffset = readStart - windowStart; readSize = windowSize - readOffset; MemMove(ref this.p, this.p, (this.pLen - readOffset), readOffset); } else { readStart = windowStart; readSize = windowSize; readOffset = 0; } if (readSize <= 0) { Log.WriteLine("Warning: unexpected read size of " + readSize + " in MapPtr"); } else { if (this.pFdOffset != readStart) { if (this.fd.Seek(readStart, SeekOrigin.Begin) != readStart) { MainClass.Exit("Seek failed in MapPtr", null); } this.pFdOffset = readStart; } if ((nread = fd.Read(this.p, readOffset, readSize)) != readSize) { if (nread < 0) { nread = 0; status = true; } FillMem(ref this.p, readOffset + nread, 0, readSize - nread); } this.pFdOffset += nread; } this.pOffset = windowStart; this.pLen = windowSize; return(offset - this.pOffset); }
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 int ReceiveFiles(ClientInfo clientInfo, List <FileStruct> fileList, string localName) { FStat st = new FStat(); FileStruct file; IOStream ioStream = clientInfo.IoStream; string fileName; string fNameCmp = String.Empty, fNameTmp = String.Empty; bool saveMakeBackups = options.makeBackups; int i, phase = 0; bool recv_ok; 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.SUM_LENGTH; 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) { MainClass.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 != null && localName.CompareTo(String.Empty) != 0) { 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 { FileInfo fi = new FileInfo(fNameCmp); // TODO: path length st.size = fi.Length; } catch { } String 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 */ recv_ok = 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 (recv_ok || options.inplace) { FinishTransfer(fileName, fNameTmp, file, recv_ok); } } 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 ArrayList sendFileList(ClientInfo cInfo, string[] argv) { IOStream f = null; if (cInfo != null) { f = cInfo.IoStream; } string dir = "", olddir = ""; string lastPath = ""; string fileName = ""; bool useFFFD = false; if (showFileListP() && f != null) { startFileListProgress("building file list"); } Int64 startWrite = Options.stats.totalWritten; ArrayList fileList = new ArrayList(); if (f != null) { f.IOStartBufferingOut(); if (Options.filesFromFD != null) { if (argv[0] != null && argv[0].CompareTo("") != 0 && !Util.pushDir(argv[0])) { MainClass.Exit("pushDir " + Util.fullFileName(argv[0]) + " failed", cInfo); } useFFFD = true; } } while (true) { if (useFFFD) { if ((fileName = f.readFilesFromLine(Options.filesFromFD, options)).Length == 0) { break; } } else { if (argv.Length == 0) { break; } fileName = argv[0]; argv = (string[])Util.ArrayDeleteFirstElement(argv); if (fileName != null && fileName.CompareTo(".") == 0) { continue; } if (fileName != null) { fileName = fileName.Replace(@"\", "/"); } } // TODO: path length if (FileSystem.Directory.Exists(fileName) && !options.recurse && options.filesFrom == null) { Log.WriteLine("skipping directory " + fileName); continue; } dir = null; olddir = ""; if (options.relativePaths == 0) { int index = fileName.LastIndexOf('/'); if (index != -1) { if (index == 0) { dir = "/"; } else { dir = fileName.Substring(0, index); } fileName = fileName.Substring(index + 1); } } else { if (f != null && options.impliedDirs && fileName.LastIndexOf('/') > 0) { string fn = fileName.Substring(0, fileName.LastIndexOf('/')); string slash = fileName; int i = 0; while (i < fn.Length && i < lastPath.Length && fn[i] == lastPath[i]) { if (fn[i] == '/') { slash = fileName.Substring(i); } i++; } if (i != fileName.LastIndexOf('/') || (i < lastPath.Length && lastPath[i] != '/')) { bool copyLinksSaved = options.copyLinks; bool recurseSaved = options.recurse; options.copyLinks = options.copyUnsafeLinks; options.recurse = true; int j; while ((j = slash.IndexOf('/')) != -1) { sendFileName(f, 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 (dir != null && dir != "") { olddir = Util.currDir; if (!Util.pushDir(dir)) { Log.WriteLine("pushDir " + Util.fullFileName(dir) + " failed"); continue; } if (lastDir != null && lastDir.CompareTo(dir) == 0) { fileListDir = lastDir; } else { fileListDir = lastDir = dir; } } sendFileName(f, fileList, fileName, options.recurse, Options.XMIT_TOP_DIR); if (olddir != null && olddir != "") { fileListDir = null; if (Util.popDir(olddir)) { MainClass.Exit("pop_dir " + Util.fullFileName(dir) + " failed", cInfo); } } } if (f != null) { sendFileEntry(null, f, 0); if (showFileListP()) { finishFileListProgress(fileList); } } cleanFileList(fileList, false, false); if (f != null) { f.writeInt(0); Options.stats.flistSize = (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 static int StartInbandExchange(string user, string path, ClientInfo cInfo, int argc) { Options options = cInfo.Options; IOStream f = cInfo.IoStream; string[] sargs = new string[Options.MAX_ARGS]; int sargc = options.ServerOptions(sargs); sargs[sargc++] = "."; //if(path != null && path.Length>0) //sargs[sargc++] = path; if (argc == 0 && !options.amSender) { options.listOnly = true; } if (path[0] == '/') { Log.WriteLine("ERROR: The remote path must start with a module name"); return(-1); } f.IOPrintf("@RSYNCD: " + options.protocolVersion + "\n"); string line = f.ReadLine(); try { options.remoteProtocol = Int32.Parse(line.Substring(9, 2)); } catch { options.remoteProtocol = 0; } bool isValidstring = line.StartsWith("@RSYNCD: ") && line.EndsWith("\n") && options.remoteProtocol > 0; if (!isValidstring) { f.IOPrintf("@ERROR: protocol startup error\n"); return(-1); } if (options.protocolVersion > options.remoteProtocol) { options.protocolVersion = options.remoteProtocol; } f.IOPrintf(path + "\n"); while (true) { line = f.ReadLine(); if (line.CompareTo("@RSYNCD: OK\n") == 0) { break; } if (line.Length > 18 && line.Substring(0, 18).CompareTo("@RSYNCD: AUTHREQD ") == 0) { string pass = String.Empty; if (user.IndexOf(':') != -1) { pass = user.Substring(user.IndexOf(':') + 1); user = user.Substring(0, user.IndexOf(':')); } f.IOPrintf(user + " " + Authentication.AuthorizeClient(user, pass, line.Substring(18).Replace("\n", String.Empty), options) + "\n"); continue; } if (line.CompareTo("@RSYNCD: EXIT\n") == 0) { MainClass.Exit("@RSYNCD: EXIT", null); } if (line.StartsWith("@ERROR: ")) { MainClass.Exit("Server: " + line.Replace("\n", String.Empty), null); } } for (int i = 0; i < sargc; i++) { f.IOPrintf(sargs[i] + "\n"); } f.IOPrintf("\n"); return(0); }
public static int StartClient(string[] args, ClientInfo cInfo) { Options options = cInfo.Options; if (args[0].StartsWith(Options.URL_PREFIX) && !options.readBatch) //source is remote { string path, user = String.Empty; //string host = args[0].Substring(Options.URL_PREFIX.Length, args[0].Length - Options.URL_PREFIX.Length); //@fixed use 1-param version of Substring string host = args[0].Substring(Options.URL_PREFIX.Length); if (host.LastIndexOf('@') != -1) { user = host.Substring(0, host.LastIndexOf('@')); host = host.Substring(host.LastIndexOf('@') + 1); } else { MainClass.Exit("Unknown host", null); } if (host.IndexOf("/") != -1) { path = host.Substring(host.IndexOf("/") + 1); host = host.Substring(0, host.IndexOf("/")); } else { path = String.Empty; } if (host[0] == '[' && host.IndexOf(']') != -1) { host = host.Remove(host.IndexOf(']'), 1); host = host.Remove(host.IndexOf('['), 1); } if (host.IndexOf(':') != -1) { options.rsyncPort = Convert.ToInt32(host.Substring(host.IndexOf(':'))); host = host.Substring(0, host.IndexOf(':')); } string[] newArgs = Util.DeleteFirstElement(args); return(StartSocketClient(host, path, user, newArgs, cInfo)); } //source is local if (!options.readBatch) { int p = Util.FindColon(args[0]); string user = String.Empty; options.amSender = true; if (args[args.Length - 1].StartsWith(Options.URL_PREFIX) && !options.readBatch) { string path; string host = args[args.Length - 1].Substring(Options.URL_PREFIX.Length); if (host.LastIndexOf('@') != -1) { user = host.Substring(0, host.LastIndexOf('@')); host = host.Substring(host.LastIndexOf('@') + 1); } else { MainClass.Exit("Unknown host", null); } if (host.IndexOf("/") != -1) { path = host.Substring(host.IndexOf("/") + 1); host = host.Substring(0, host.IndexOf("/")); } else { path = String.Empty; } if (host[0] == '[' && host.IndexOf(']') != -1) { host = host.Remove(host.IndexOf(']'), 1); host = host.Remove(host.IndexOf('['), 1); } if (host.IndexOf(':') != -1) { options.rsyncPort = Convert.ToInt32(host.Substring(host.IndexOf(':'))); host = host.Substring(0, host.IndexOf(':')); } string[] newArgs = Util.DeleteLastElement(args); return(StartSocketClient(host, path, user, newArgs, cInfo)); } p = Util.FindColon(args[args.Length - 1]); if (p == -1) //src & dest are local { /* no realized*/ } else if (args[args.Length - 1][p + 1] == ':') { if (options.shellCmd == null) { return(StartSocketClient(args[args.Length - 1].Substring(0, p), args[args.Length - 1].Substring(p + 2), user, args, cInfo)); } } } return(0); }