public TCPSocketListener(Socket client, ref List<TCPSocketListener> clientSockets) { Client = client; ClientSockets = clientSockets; ClientInfo = new ClientInfo(); ClientInfo.Options = new Options(); }
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 int ClientRun(ClientInfo cInfo, int pid, string[] args) { Options options = cInfo.Options; IOStream f = cInfo.IoStream; FileList fList; ArrayList fileList; MainClass.SetupProtocol(cInfo); if(options.protocolVersion >= 23 && !options.readBatch) f.IOStartMultiplexIn(); if(options.amSender) { f.IOStartBufferingOut(); if (options.deleteMode && !options.deleteExcluded) { Exclude excl = new Exclude(options); excl.SendExcludeList(f); } if (options.verbose > 3) Log.Write("File list sent\n"); f.Flush(); fList = new FileList(options); fileList = fList.sendFileList(cInfo, args); if(options.verbose > 3) Log.WriteLine("file list sent"); f.Flush(); Sender sender = new Sender(options); sender.SendFiles(fileList, cInfo); f.Flush(); f.writeInt(-1); return -1; } options.dir = args[0]; if(options.dir.CompareTo("") != 0 && options.dir.IndexOf(':') == -1) { if(options.dir[0] == '/') options.dir = "c:" + options.dir; else if(options.dir.IndexOf('/') != -1) { options.dir = options.dir.Insert(options.dir.IndexOf('/') - 1,":"); } } if(!options.readBatch) { Exclude excl = new Exclude(options); excl.SendExcludeList(f); } fList = new FileList(options); fileList = fList.receiveFileList(cInfo); return Daemon.DoReceive(cInfo,fileList,null); }
private string LocalizePath(ClientInfo cInfo, string path) { string normalized = cInfo.Options.dir.Replace('\\', '/').Replace(":", "").ToLower(); string ret=""; if (path.ToLower().IndexOf(normalized)!=-1) ret = path.Substring(path.ToLower().IndexOf(normalized) + normalized.Length).Replace('/', Path.DirectorySeparatorChar); if (ret == "") return path.TrimEnd('\\'); if (ret[0] == Path.DirectorySeparatorChar) ret = ret.Substring(1); return ret; }
public static void Report(ClientInfo cInfo) { IOStream f = cInfo.IoStream; Options options = cInfo.Options; Int64 totalWritten = Options.stats.totalWritten; Int64 totalRead = Options.stats.totalRead; if (options.amServer && f != null) { if (options.amSender) { f.WriteLongInt(totalRead); f.WriteLongInt(totalWritten); f.WriteLongInt(Options.stats.totalSize); } return; } if (!options.amSender && f != null) { /* Read the first two in opposite order because the meaning of * read/write swaps when switching from sender to receiver. */ totalWritten = f.ReadLongInt(); totalRead = f.ReadLongInt(); Options.stats.totalSize = f.ReadLongInt(); } if (options.doStats) { Log.WriteLine("Number of files: " + Options.stats.numFiles); Log.WriteLine("Number of files transferred: " + Options.stats.numTransferredFiles); Log.WriteLine("Total file size: " + Options.stats.totalSize); Log.WriteLine("Total transferred file size: " + Options.stats.totalTransferredSize); Log.WriteLine("Literal data: " + Options.stats.literalData); Log.WriteLine("Matched data: " + Options.stats.matchedData); Log.WriteLine("File list size: " + Options.stats.fileListSize); Log.WriteLine("Total bytes written: " + totalWritten); Log.WriteLine("Total bytes received: " + totalRead); } }
public static bool AuthServer(ClientInfo cInfo, int moduleNumber, string addr, string leader) { string users = Daemon.config.GetAuthUsers(moduleNumber).Trim(); string challenge; string b64_challenge; IOStream f = cInfo.IoStream; string line; string user = ""; string secret = ""; string pass = ""; string pass2 = ""; string[] listUsers; string tok = ""; /* if no auth list then allow anyone in! */ if (users == null || users.CompareTo("") == 0) { return(true); } challenge = gen_challenge(addr, cInfo.Options); b64_challenge = base64_encode(challenge); f.IOPrintf(leader + b64_challenge + "\n"); line = f.ReadLine(); if (line.IndexOf(' ') > 0) { user = line.Substring(0, line.IndexOf(' ')); pass = line.Substring(line.IndexOf(' ')).Trim('\n').Trim(); } else { return(false); } listUsers = users.Split(','); for (int i = 0; i < listUsers.Length; i++) { tok = listUsers[i]; if (user.CompareTo(tok) == 0) { break; } tok = null; } if (tok == null || tok.CompareTo("") == 0) { return(false); } if ((secret = GetSecret(moduleNumber, user)) == null) { return(false); } pass2 = generate_hash(secret, b64_challenge, cInfo.Options); if (pass.CompareTo(pass2) == 0) { return(true); } return(false); }
/// <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 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); }
/// <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? { string path = Daemon.config.GetModule(moduleNumber).Path; string name = Daemon.config.GetModuleName(moduleNumber); IOStream ioStream = clientInfo.IoStream; Options options = clientInfo.Options; string[] args = new string[Options.MAX_ARGS]; int argc = 0, maxArgs = Options.MAX_ARGS; string line = String.Empty; if (path[0] == '/') { path = path.Remove(0, 1); } path = path.Replace("\n", String.Empty); 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 + ")"); 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"); MainClass.Exit("@ERROR: Path not found: " + path, clientInfo); } } options.amServer = true; //to fix error in SetupProtocol options.dir = path; while (true) { line = ioStream.ReadLine(); line = line.Substring(0, line.Length - 1); if (line.CompareTo(String.Empty) == 0) { break; } if (argc == maxArgs) { maxArgs += Options.MAX_ARGS; MapFile.ExtendArray(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", clientInfo); } string[] args2 = new string[argsNotUsed]; for (int i = 0; i < argsNotUsed; i++) { args2[i] = args[args.Length - argsNotUsed + i]; } MainClass.SetupProtocol(clientInfo); ioStream.IOStartMultiplexOut(); Daemon.StartServer(clientInfo, args2); }
public static int StartSocketClient(string host, string path, string user, string[] args, ClientInfo cInfo) { Options options = cInfo.Options; if (path.CompareTo(String.Empty) != 0 && path[0] == '/') { Log.WriteLine("ERROR: The remote path must start with a module name not a /"); return -1; } cInfo.IoStream = OpenSocketOutWrapped(host, options.rsyncPort, options.bindAddress); if (cInfo.IoStream != null) { StartInbandExchange(user, path, cInfo, args.Length); } Client client = new Client(); return client.ClientRun(cInfo, -1, args); }
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 FileStruct receiveFileEntry(UInt32 flags, ClientInfo cInfo) { if(cInfo == null) { lastName = ""; return null; } IOStream f = cInfo.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, cInfo); } string thisName = lastName.Substring(0, l1); thisName += f.ReadSBuf(l2); lastName = thisName; thisName = Util.cleanFileName(thisName, false); if(options.sanitizePath) thisName = Util.sanitizePath(thisName, "", 0); string baseName = ""; string dirName = ""; if (thisName.LastIndexOf("/") != -1) { baseName = Path.GetFileName(thisName); dirName = FileSystem.Directory.GetDirectoryName(thisName).Replace(@"\","/").Replace(":",""); } 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.ReadBuf(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; }
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 static int DoReceive(ClientInfo cInfo, List<FileStruct> fileList, string localName) { IOStream f = cInfo.IoStream; Options options = cInfo.Options; Receiver 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(); Generator gen = new Generator(options); gen.GenerateFiles(f, fileList, localName); f.Flush(); if (fileList != null && fileList.Count != 0) { receiver.ReceiveFiles(cInfo, fileList, localName); } MainClass.Report(cInfo); if (options.protocolVersion >= 24) { /* send a final goodbye message */ f.writeInt(-1); } f.Flush(); return 0; }
public static void StartServer(ClientInfo cInfo, string[] args) { IOStream f = cInfo.IoStream; Options options = cInfo.Options; if (options.protocolVersion >= 23) { f.IOStartMultiplexOut(); } if (options.amSender) { options.keepDirLinks = false; /* Must be disabled on the sender. */ Exclude excl = new Exclude(options); excl.ReceiveExcludeList(f); DoServerSender(cInfo, args); } else { DoServerReceive(cInfo, args); } }
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 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; }
/// <summary> /// Server-side authorization check /// </summary> /// <param name="clientInfo"></param> /// <param name="moduleNumber"></param> /// <param name="addr"></param> /// <param name="leader"></param> /// <returns></returns> public static bool AuthorizeServer(ClientInfo clientInfo, int moduleNumber, string addr, string leader) { string users = Daemon.config.GetAuthUsers(moduleNumber).Trim(); //string challenge; string b64Challenge; IOStream ioStream = clientInfo.IoStream; string line; string user = String.Empty; string secret = String.Empty; string pass = String.Empty; string pass2 = String.Empty; string[] listUsers; string token = String.Empty; /* if no auth list then allow anyone in! */ if (string.IsNullOrEmpty(users)) { return true; } b64Challenge = Base64Encode(GenerateChallenge(addr, clientInfo.Options)); ioStream.IOPrintf(leader + b64Challenge + "\n"); line = ioStream.ReadLine(); if (line.IndexOf(' ') > 0) { user = line.Substring(0, line.IndexOf(' ')); pass = line.Substring(line.IndexOf(' ')).Trim('\n').Trim(); } else { return false; } listUsers = users.Split(','); for (int i = 0; i < listUsers.Length; i++) { token = listUsers[i]; if (user.Equals(token)) { break; } token = null; } if (string.IsNullOrEmpty(token)) { return false; } if ((secret = GetSecret(moduleNumber, user)) == null) { return false; } pass2 = GenerateHash(secret, b64Challenge, clientInfo.Options); if (pass.Equals(pass2)) { return true; } return false; }
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 SumStruct ReceiveSums(ClientInfo cInfo) { IOStream f = cInfo.IoStream; SumStruct s = new SumStruct(); int i; int offset = 0; ReadSumHead(cInfo, ref s); s.sums = null; if (options.verbose > 3) { Log.WriteLine("count=" + s.count + " n=" + s.bLength + " rem=" + s.remainder); } if (s.count == 0) { return s; } s.sums = new SumBuf[s.count]; for (i = 0; i < s.count; i++) { s.sums[i] = new SumBuf(); s.sums[i].sum1 = (UInt32)f.readInt(); s.sums[i].sum2 = f.ReadBuffer(s.s2Length); s.sums[i].offset = offset; s.sums[i].flags = 0; if (i == s.count - 1 && s.remainder != 0) { s.sums[i].len = s.remainder; } else { s.sums[i].len = s.bLength; } offset += (int)s.sums[i].len; if (options.verbose > 3) { Log.WriteLine("chunk[" + i + "] len=" + s.sums[i].len); } } s.fLength = offset; return s; }
public static bool AuthServer(ClientInfo cInfo, int moduleNumber, string addr, string leader) { string users = Daemon.config.GetAuthUsers(moduleNumber).Trim(); string challenge; string b64_challenge; IOStream f = cInfo.IoStream; string line; string user = ""; string secret = ""; string pass = ""; string pass2 = ""; string[] listUsers; string tok = ""; /* if no auth list then allow anyone in! */ if (users == null || users.CompareTo("") == 0) return true; challenge = gen_challenge(addr, cInfo.Options); b64_challenge = base64_encode(challenge); f.IOPrintf(leader + b64_challenge + "\n"); line = f.ReadLine(); if(line.IndexOf(' ') > 0) { user = line.Substring(0,line.IndexOf(' ')); pass = line.Substring(line.IndexOf(' ')).Trim('\n').Trim(); } else return false; listUsers = users.Split(','); for (int i = 0; i < listUsers.Length; i++) { tok = listUsers[i]; if (user.CompareTo(tok) == 0) break; tok = null; } if (tok == null || tok.CompareTo("") == 0) return false; if ((secret = GetSecret(moduleNumber, user)) == null) { return false; } pass2 = generate_hash(secret, b64_challenge, cInfo.Options); if (pass.CompareTo(pass2) == 0) return true; return false; }
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 int ReceiveFiles(ClientInfo cInfo, ArrayList fileList, string localName) { FStat st = new FStat(); FileStruct file; IOStream f = cInfo.IoStream; string fileName; string fNameCmp = "", fNameTmp = ""; bool saveMakeBackups = options.makeBackups; int i, phase = 0; bool recv_ok; if (options.verbose > 2) { Log.WriteLine("ReceiveFiles(" + fileList.Count + ") starting"); } while (true) { i = f.readInt(); if (i == -1) { if (phase != 0) { break; } phase = 1; checkSum.cSumLength = CheckSum.SUM_LENGTH; if (options.verbose > 2) { Log.WriteLine("ReceiveFiles phase=" + phase); } f.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 + ")", cInfo); } file = ((FileStruct)fileList[i]); Options.stats.currentFileIndex = i; Options.stats.numTransferredFiles++; Options.stats.totalTransferredSize += file.length; if (localName != null && localName.CompareTo("") != 0) { fileName = localName; } else { fileName = Path.Combine(options.dir, LocalizePath(cInfo, file.FNameTo().Replace(":", "")).Replace("\\", "/")); //fileName = Path.Combine(options.dir, file.FNameTo().Replace(":","")).Replace("\\", "/"); // TODO: path length FileSystem.Directory.CreateDirectory(Path.Combine(options.dir, LocalizePath(cInfo, file.dirName.Replace(":", ""))).Replace("\\", "/")); Log.WriteLine(Path.Combine(options.dir, file.dirName)); //FileSystem.Directory.CreateDirectory(Path.Combine(options.dir,file.dirName.Replace(":","")).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("") != 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 { FileSystem.FileInfo fi = new FileSystem.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(cInfo, fNameCmp, fd1, st.size, fileName, fd2, file.length); if (fd1 != null) { fd1.Close(); } if (fd2 != null) { fd2.Close(); } // TODO: path length FileSystem.File.Copy(tempFileName, fileName, true); // TODO: path length FileSystem.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 receiveFileList(ClientInfo cInfo) { IOStream f = cInfo.IoStream; ArrayList fileList = new ArrayList(); if(showFileListP()) startFileListProgress("receiving file list"); Int64 startRead = Options.stats.totalRead; UInt32 flags; while((flags = f.readByte()) != 0) { if (options.protocolVersion >= 28 && (flags & Options.XMIT_EXTENDED_FLAGS) != 0) flags |= (UInt32)(f.readByte() << 8); FileStruct file = receiveFileEntry(flags,cInfo); if(file == null) continue; fileList.Add(file); Options.stats.totalSize += ((FileStruct)fileList[fileList.Count-1]).length; mayBeEmitFileListProgress(fileList); if(options.verbose > 2) Log.WriteLine("receiveFileName(" + ((FileStruct)fileList[fileList.Count-1]).FNameTo() + ")"); } receiveFileEntry(0, null); if(options.verbose > 2) Log.WriteLine("received " + fileList.Count + " names"); if(showFileListP()) finishFileListProgress(fileList); cleanFileList(fileList, (options.relativePaths == 0) ? false : true, true); if ( f != null) { f.readInt(); } if (options.verbose > 3) outputFileList(fileList); if(options.listOnly) for(int i = 0; i < fileList.Count; i++) listFileEntry((FileStruct)fileList[i]); if(options.verbose > 2) Log.WriteLine("receiveFileList done"); Options.stats.flistSize = (int)(Options.stats.totalRead - startRead); Options.stats.numFiles = fileList.Count; return fileList; }
public static void Exit(string message, ClientInfo clientInfo) { Log.Write(message); if (!opt.amDaemon) { Console.Read(); System.Environment.Exit(0); } else { if (clientInfo != null && clientInfo.IoStream != null && clientInfo.IoStream.ClientThread != null) { clientInfo.IoStream.ClientThread.Abort(); } } }
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 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 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; }
public bool ReceiveData(ClientInfo cInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize) { IOStream f = cInfo.IoStream; byte[] file_sum1 = new byte[CheckSum.MD4_SUM_LENGTH]; byte[] file_sum2 = new byte[CheckSum.MD4_SUM_LENGTH]; byte[] data = new byte[Match.CHUNK_SIZE]; SumStruct sum = new SumStruct(); MapFile mapBuf = null; Sender sender = new Sender(options); sender.ReadSumHead(cInfo, ref sum); int offset = 0; UInt32 len; if (fdR != null && sizeR > 0) { int mapSize = (int)Math.Max(sum.bLength * 2, 16 * 1024); mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sum.bLength); if (options.verbose > 2) { Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR); } ; } Sum s = new Sum(options); s.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; s.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 * sum.bLength); len = sum.bLength; if (i == sum.count - 1 && sum.remainder != 0) { len = sum.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); s.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), cInfo); } 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), cInfo); } file_sum1 = s.End(); if (mapBuf != null) { mapBuf = null; } file_sum2 = f.ReadBuf(CheckSum.MD4_SUM_LENGTH); if (options.verbose > 2) { Log.WriteLine("got fileSum"); } if (fd != null && Util.MemCmp(file_sum1, 0, file_sum2, 0, CheckSum.MD4_SUM_LENGTH) != 0) { return(false); } return(true); report_write_error: { MainClass.Exit("write failed on " + Util.fullFileName(fileName), cInfo); } return(true); }
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 int ClientRun(ClientInfo cInfo, int pid, string[] args) { Options options = cInfo.Options; IOStream f = cInfo.IoStream; FileList fList; ArrayList fileList; MainClass.SetupProtocol(cInfo); if (options.protocolVersion >= 23 && !options.readBatch) { f.IOStartMultiplexIn(); } if (options.amSender) { f.IOStartBufferingOut(); if (options.deleteMode && !options.deleteExcluded) { Exclude excl = new Exclude(options); excl.SendExcludeList(f); } if (options.verbose > 3) { Log.Write("File list sent\n"); } f.Flush(); fList = new FileList(options); fileList = fList.sendFileList(cInfo, args); if (options.verbose > 3) { Log.WriteLine("file list sent"); } f.Flush(); Sender sender = new Sender(options); sender.SendFiles(fileList, cInfo); f.Flush(); f.writeInt(-1); return(-1); } options.dir = args[0]; if (options.dir.CompareTo("") != 0 && options.dir.IndexOf(':') == -1) { if (options.dir[0] == '/') { options.dir = "c:" + options.dir; } else if (options.dir.IndexOf('/') != -1) { options.dir = options.dir.Insert(options.dir.IndexOf('/') - 1, ":"); } } if (!options.readBatch) { Exclude excl = new Exclude(options); excl.SendExcludeList(f); } fList = new FileList(options); fileList = fList.receiveFileList(cInfo); return(Daemon.DoReceive(cInfo, fileList, null)); }
public ArrayList receiveFileList(ClientInfo cInfo) { IOStream f = cInfo.IoStream; ArrayList fileList = new ArrayList(); if (showFileListP()) { startFileListProgress("receiving file list"); } Int64 startRead = Options.stats.totalRead; UInt32 flags; while ((flags = f.readByte()) != 0) { if (options.protocolVersion >= 28 && (flags & Options.XMIT_EXTENDED_FLAGS) != 0) { flags |= (UInt32)(f.readByte() << 8); } FileStruct file = receiveFileEntry(flags, cInfo); if (file == null) { continue; } fileList.Add(file); Options.stats.totalSize += ((FileStruct)fileList[fileList.Count - 1]).length; mayBeEmitFileListProgress(fileList); if (options.verbose > 2) { Log.WriteLine("receiveFileName(" + ((FileStruct)fileList[fileList.Count - 1]).FNameTo() + ")"); } } receiveFileEntry(0, null); if (options.verbose > 2) { Log.WriteLine("received " + fileList.Count + " names"); } if (showFileListP()) { finishFileListProgress(fileList); } cleanFileList(fileList, (options.relativePaths == 0) ? false : true, true); if (f != null) { f.readInt(); } if (options.verbose > 3) { outputFileList(fileList); } if (options.listOnly) { for (int i = 0; i < fileList.Count; i++) { listFileEntry((FileStruct)fileList[i]); } } if (options.verbose > 2) { Log.WriteLine("receiveFileList done"); } Options.stats.flistSize = (int)(Options.stats.totalRead - startRead); Options.stats.numFiles = fileList.Count; return(fileList); }
/// <summary> /// /// </summary> /// <param name="clientInfo"></param> /// <returns></returns> public List <FileStruct> ReceiveFileList(ClientInfo clientInfo) { var ioStream = clientInfo.IoStream; var fileList = new List <FileStruct>(); if (ShowFileListProgress()) { StartFileListProgress("receiving file list"); } var startRead = Options.Stats.TotalRead; UInt32 flags; while ((flags = ioStream.ReadByte()) != 0) { if (_options.ProtocolVersion >= 28 && (flags & Options.XmitExtendedFlags) != 0) { flags |= (UInt32)(ioStream.ReadByte() << 8); } var file = ReceiveFileEntry(flags, clientInfo); if (file == null) { continue; } fileList.Add(file); Options.Stats.TotalSize += (fileList[fileList.Count - 1]).Length; EmitFileListProgress(fileList); if (_options.Verbose > 2) { Log.WriteLine("receiveFileName(" + (fileList[fileList.Count - 1]).GetFullName() + ")"); } } ReceiveFileEntry(0, null); if (_options.Verbose > 2) { Log.WriteLine("received " + fileList.Count + " names"); } if (ShowFileListProgress()) { FinishFileListProgress(fileList); } CleanFileList(fileList, _options.RelativePaths, true); if (ioStream != null) { ioStream.ReadInt(); } if (_options.Verbose > 3) { OutputFileList(fileList); } if (_options.ListOnly) { LogFileList(fileList); } if (_options.Verbose > 2) { Log.WriteLine("receiveFileList done"); } Options.Stats.FileListSize = (int)(Options.Stats.TotalRead - startRead); Options.Stats.NumFiles = fileList.Count; return(fileList); }
public FileStruct receiveFileEntry(UInt32 flags, ClientInfo cInfo) { if (cInfo == null) { lastName = ""; return(null); } IOStream f = cInfo.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, cInfo); } string thisName = lastName.Substring(0, l1); thisName += f.ReadSBuf(l2); lastName = thisName; thisName = Util.cleanFileName(thisName, false); if (options.sanitizePath) { thisName = Util.sanitizePath(thisName, "", 0); } string baseName = ""; string dirName = ""; if (thisName.LastIndexOf("/") != -1) { baseName = Path.GetFileName(thisName); dirName = FileSystem.Directory.GetDirectoryName(thisName).Replace(@"\", "/").Replace(":", ""); } 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.ReadBuf(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); }
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 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; }