static void Main(string[] args) { MainClass mc = new MainClass(); mc.Run(args); }
/// <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); }
/// <summary> /// /// </summary> /// <param name="options"></param> /// <returns></returns> public bool LoadParm(Options options) { lock (this) { // TODO: path length if (confFile == null || confFile.CompareTo(String.Empty) == 0 || !File.Exists(confFile)) { MainClass.Exit("Can't find .conf file: " + confFile, null); return(false); } try { using (var cf = new System.IO.StreamReader(confFile)) { Module mod = null; if (Modules == null) { Modules = new List <Module>(); } lock (cf) { while (true) { string line = cf.ReadLine(); if (line == null) { break; } line = line.Trim(); if (line.CompareTo(String.Empty) != 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(); } } } catch { MainClass.Exit("failed to open: " + confFile, null); return(false); } } return(true); }
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 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); }
/// <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); }