예제 #1
0
        public static int DoReceive(ClientInfo cInfo, List <FileStruct> fileList, string localName)
        {
            var f        = cInfo.IoStream;
            var options  = cInfo.Options;
            var receiver = new Receiver(options);

            options.CopyLinks = false;
            f.Flush();
            if (!options.DeleteAfter)
            {
                if (options.Recurse && options.DeleteMode && localName == null && fileList.Count > 0)
                {
                    receiver.DeleteFiles(fileList);
                }
            }
            f.IoStartBufferingOut();
            var gen = new Generator(options);

            gen.GenerateFiles(f, fileList, localName);
            f.Flush();
            if (fileList != null && fileList.Count != 0)
            {
                receiver.ReceiveFiles(cInfo, fileList, localName);
            }
            WinRsync.Report(cInfo);
            if (options.ProtocolVersion >= 24)
            {
                /* send a final goodbye message */
                f.WriteInt(-1);
            }
            f.Flush();
            return(0);
        }
예제 #2
0
파일: IO.cs 프로젝트: muratoflu/rsync.net
        /// <summary>
        ///
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public byte[] ReadBuffer(int count)
        {
            var buffer = new byte[count];
            int bytesRead;
            var total = 0;

            while (total < count)
            {
                try
                {
                    bytesRead = ReadSocketUnbuffered(buffer, total, count - total);
                    total    += bytesRead;
                }
                catch (Exception)
                {
                    WinRsync.Exit("Unable to read data from the transport connection", null);
                    if (ClientThread != null)
                    {
                        ClientThread.Abort();
                    }
                    return(null);
                }
            }
            CalculateTotalRead(count);
            return(buffer);
        }
예제 #3
0
        public static void DoServerReceive(ClientInfo cInfo, string[] args)
        {
            var options = cInfo.Options;
            var f       = cInfo.IoStream;

            if (options.Verbose > 2)
            {
                Log.Write("Server receive starting");
            }
            if (options.AmDaemon && Config.ModuleIsReadOnly(options.ModuleId))
            {
                WinRsync.Exit("ERROR: module " + Config.GetModuleName(options.ModuleId) + " is read only", cInfo);
                return;
            }

            f.IoStartBufferingIn();
            if (options.DeleteMode && !options.DeleteExcluded)
            {
                var excl = new Exclude(options);
                excl.ReceiveExcludeList(f);
            }

            var fList    = new FileList(cInfo.Options);
            var fileList = fList.ReceiveFileList(cInfo);

            DoReceive(cInfo, fileList, null);
        }
예제 #4
0
        public static int StartDaemon(ClientInfo clientInfo)
        {
            var stream  = clientInfo.IoStream;
            var options = clientInfo.Options;

            options.AmDaemon = true;

            stream.IoPrintf("@RSYNCD: " + options.ProtocolVersion + "\n");
            var line = stream.ReadLine();

            try
            {
                options.RemoteProtocol = Int32.Parse(line.Substring(9, 2));
            }
            catch
            {
                options.RemoteProtocol = 0;
            }
            var isValidstring = line.StartsWith("@RSYNCD: ") && line.EndsWith("\n") && options.RemoteProtocol > 0;

            if (!isValidstring)
            {
                stream.IoPrintf("@ERROR: protocol startup error\n");
                return(-1);
            }
            if (options.ProtocolVersion > options.RemoteProtocol)
            {
                options.ProtocolVersion = options.RemoteProtocol;
            }
            line = stream.ReadLine();
            if (String.Compare(line, "#list\n", StringComparison.Ordinal) == 0)
            {
                ClientServer.SendListing(stream);
                return(-1);
            }

            if (line[0] == '#')
            {
                stream.IoPrintf("@ERROR: Unknown command '" + line.Replace("\n", String.Empty) + "'\n");
                return(-1);
            }

            var i = Config.GetNumberModule(line.Replace("\n", String.Empty));

            if (i < 0)
            {
                stream.IoPrintf("@ERROR: Unknown module " + line);
                WinRsync.Exit("@ERROR: Unknown module " + line, clientInfo);
            }
            options.DoStats  = true;
            options.ModuleId = i;
            ClientServer.RsyncModule(clientInfo, i);
            clientInfo.IoStream.Close();
            return(1);
        }
예제 #5
0
        public int ClientRun(ClientInfo clientInfo, int pid, string[] args)
        {
            var               options  = clientInfo.Options;
            var               ioStream = clientInfo.IoStream;
            FileList          fList;
            List <FileStruct> fileList;

            WinRsync.SetupProtocol(clientInfo);
            if (options.ProtocolVersion >= 23 && !options.ReadBatch)
            {
                ioStream.IoStartMultiplexIn();
            }
            if (options.AmSender)
            {
                ioStream.IoStartBufferingOut();

                if (options.DeleteMode && !options.DeleteExcluded)
                {
                    var excl = new Exclude(options);
                    excl.SendExcludeList(ioStream);
                }

                if (options.Verbose > 3)
                {
                    Log.Write("File list sent\n");
                }
                ioStream.Flush();
                fList    = new FileList(options);
                fileList = fList.SendFileList(clientInfo, args);
                if (options.Verbose > 3)
                {
                    Log.WriteLine("file list sent");
                }
                ioStream.Flush();
                var sender = new Sender(options);
                sender.SendFiles(fileList, clientInfo);
                ioStream.Flush();
                ioStream.WriteInt(-1);
                return(-1);
            }
            options.Dir = args[0];
            options.Dir = Path.GetFullPath(options.Dir ?? string.Empty);

            if (!options.ReadBatch)
            {
                var excl = new Exclude(options);
                excl.SendExcludeList(ioStream);
            }
            fList    = new FileList(options);
            fileList = fList.ReceiveFileList(clientInfo);
            return(Daemon.DoReceive(clientInfo, fileList, null));
        }
예제 #6
0
        private static void DoServerSender(ClientInfo clientInfo, string[] args)
        {
            var dir      = args[0];
            var ioStream = clientInfo.IoStream;
            var options  = clientInfo.Options;

            if (options.Verbose > 2)
            {
                Log.Write("Server sender starting");
            }
            if (options.AmDaemon && Config.ModuleIsWriteOnly(options.ModuleId))
            {
                WinRsync.Exit("ERROR: module " + Config.GetModuleName(options.ModuleId) + " is write only", clientInfo);
                return;
            }

            if (!options.RelativePaths && !Util.PushDir(dir))
            {
                WinRsync.Exit("Push_dir#3 " + dir + "failed", clientInfo);
                return;
            }

            var fList    = new FileList(options);
            var fileList = fList.SendFileList(clientInfo, args);

            if (options.Verbose > 3)
            {
                Log.WriteLine("File list sent");
            }
            if (fileList.Count == 0)
            {
                WinRsync.Exit("File list is empty", clientInfo);
                return;
            }
            ioStream.IoStartBufferingIn();
            ioStream.IoStartBufferingOut();

            var sender = new Sender(options);

            sender.SendFiles(fileList, clientInfo);
            ioStream.Flush();
            WinRsync.Report(clientInfo);
            if (options.ProtocolVersion >= 24)
            {
                ioStream.ReadInt();
            }
            ioStream.Flush();
        }
예제 #7
0
        public void ReadSumHead(ClientInfo clientInfo, ref SumStruct sum)
        {
            var ioStream = clientInfo.IoStream;

            sum.Count   = ioStream.ReadInt();
            sum.BLength = (UInt32)ioStream.ReadInt();
            if (_options.ProtocolVersion < 27)
            {
                sum.S2Length = _checkSum.Length;
            }
            else
            {
                sum.S2Length = ioStream.ReadInt();
                if (sum.S2Length > CheckSum.Md4SumLength)
                {
                    WinRsync.Exit("Invalid checksum length " + sum.S2Length, clientInfo);
                }
            }
            sum.Remainder = (UInt32)ioStream.ReadInt();
        }
예제 #8
0
        /// <summary>
        /// Returns offset in p array
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public int MapPtr(int offset, int length)
        {
            int numberOfReadBytes;
            int windowStart, readStart;
            int windowSize, readSize, readOffset;

            if (length == 0)
            {
                return(-1);
            }

            if (length > (FileSize - offset))
            {
                length = FileSize - offset;
            }

            if (offset >= _pOffset && offset + length <= _pOffset + _pLength)
            {
                return(offset - _pOffset);
            }

            windowStart = offset;
            windowSize  = _defaultWindowSize;
            if (windowStart + windowSize > FileSize)
            {
                windowSize = FileSize - windowStart;
            }
            if (offset + length > windowStart + windowSize)
            {
                windowSize = (offset + length) - windowStart;
            }

            if (windowSize > _pSize)
            {
                ExtendArray(ref P, windowSize);
                _pSize = windowSize;
            }

            if (windowStart >= _pOffset &&
                windowStart < _pOffset + _pLength &&
                windowStart + windowSize >= _pOffset + _pLength)
            {
                readStart  = _pOffset + _pLength;
                readOffset = readStart - windowStart;
                readSize   = windowSize - readOffset;
                MemoryMove(ref P, P, (_pLength - readOffset), readOffset);
            }
            else
            {
                readStart  = windowStart;
                readSize   = windowSize;
                readOffset = 0;
            }
            if (readSize <= 0)
            {
                Log.WriteLine("Warning: unexpected read size of " + readSize + " in MapPtr");
            }
            else
            {
                if (_pFileDescriptorOffset != readStart)
                {
                    if (_fileDescriptor.Seek(readStart, SeekOrigin.Begin) != readStart)
                    {
                        WinRsync.Exit("Seek failed in MapPtr", null);
                    }
                    _pFileDescriptorOffset = readStart;
                }

                if ((numberOfReadBytes = _fileDescriptor.Read(P, readOffset, readSize)) != readSize)
                {
                    //if (numberOfReadBytes < 0) //@fixed Read never returns <0 so status is false all the time
                    //{
                    //    numberOfReadBytes = 0;
                    //    status = true;
                    //}
                    FillMemory(ref P, readOffset + numberOfReadBytes, 0, readSize - numberOfReadBytes);
                }
                _pFileDescriptorOffset += numberOfReadBytes;
            }

            _pOffset = windowStart;
            _pLength = windowSize;
            return(offset - _pOffset);
        }
예제 #9
0
        public void SendFiles(List <FileStruct> fileList, ClientInfo clientInfo)
        {
            ShowMessage("Processing...");
            try
            {
                var       ioStream = clientInfo.IoStream;
                string    fileName = String.Empty, fileName2 = String.Empty;
                SumStruct s               = null;
                var       phase           = 0;
                var       saveMakeBackups = _options.MakeBackups;
                var       match           = new Match(_options);

                if (_options.Verbose > 2)
                {
                    Log.WriteLine("SendFiles starting");
                }
                while (true)
                {
                    fileName = String.Empty;
                    var i = ioStream.ReadInt();
                    if (i == -1)
                    {
                        if (phase == 0)
                        {
                            phase++;
                            _checkSum.Length = CheckSum.SumLength;
                            ioStream.WriteInt(-1);
                            if (_options.Verbose > 2)
                            {
                                Log.WriteLine("SendFiles phase=" + phase);
                            }
                            _options.MakeBackups = false;
                            continue;
                        }
                        break;
                    }

                    if (i < 0 || i >= fileList.Count)
                    {
                        WinRsync.Exit("Invalid file index " + i + " (count=" + fileList.Count + ")", clientInfo);
                    }

                    var file = fileList[i];

                    Options.Stats.CurrentFileIndex = i;
                    Options.Stats.NumTransferredFiles++;
                    Options.Stats.TotalTransferredSize += file.Length;

                    if (!string.IsNullOrEmpty(file.BaseDir))
                    {
                        fileName = file.BaseDir;
                        if (!fileName.EndsWith("/"))
                        {
                            fileName += "/";
                        }
                    }
                    fileName2 = file.GetFullName();
                    fileName += file.GetFullName();
                    ShowMessage("uploading " + fileName);

                    if (_options.Verbose > 2)
                    {
                        Log.WriteLine("sendFiles(" + i + ", " + fileName + ")");
                    }

                    if (_options.DryRun)
                    {
                        if (!_options.AmServer && _options.Verbose != 0)
                        {
                            Log.WriteLine(fileName2);
                        }
                        ioStream.WriteInt(i);
                        continue;
                    }

                    var initialStats = Options.Stats;
                    s = ReceiveSums(clientInfo);

                    Stream fd;
                    try
                    {
                        fd = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                    }
                    catch (FileNotFoundException)
                    {
                        Log.WriteLine("file has vanished: " + Util.FullFileName(fileName));
                        s = null;
                        continue;
                    }
                    catch (Exception)
                    {
                        Log.WriteLine("SendFiles failed to open " + Util.FullFileName(fileName));
                        s = null;
                        continue;
                    }

                    var st = new FStat();
                    var fi = new FileInfo(fileName);
                    // TODO: path length
                    st.MTime = fi.LastWriteTime;
                    // TODO: path length
                    st.Size = fi.Length;

                    MapFile mbuf = null;
                    if (st.Size != 0)
                    {
                        var mapSize = (int)Math.Max(s.BLength * 3, Options.MaxMapSize);
                        mbuf = new MapFile(fd, (int)st.Size, mapSize, (int)s.BLength);
                    }

                    if (_options.Verbose > 2)
                    {
                        Log.WriteLine("SendFiles mapped " + fileName + " of size " + st.Size);
                    }

                    ioStream.WriteInt(i);
                    var gen = new Generator(_options);
                    gen.WriteSumHead(ioStream, s);

                    if (_options.Verbose > 2)
                    {
                        Log.WriteLine("calling MatchSums " + fileName);
                    }

                    if (!_options.AmServer && _options.Verbose != 0)
                    {
                        Log.WriteLine(fileName2);
                    }

                    var token = new Token(_options);
                    token.SetCompression(fileName);

                    match.MatchSums(ioStream, s, mbuf, (int)st.Size);
                    Log.LogSend(file, initialStats);

                    if (mbuf != null)
                    {
                        var j = mbuf.UnMapFile();
                        if (j)
                        {
                            Log.WriteLine("read errors mapping " + Util.FullFileName(fileName));
                        }
                    }
                    fd.Close();

                    s.Sums = null;

                    if (_options.Verbose > 2)
                    {
                        Log.WriteLine("sender finished " + fileName);
                    }
                }
                _options.MakeBackups = saveMakeBackups;

                if (_options.Verbose > 2)
                {
                    Log.WriteLine("send files finished");
                }

                match.MatchReport(ioStream);
                ioStream.WriteInt(-1);
            }
            finally
            {
                HideMessage();
            }
        }
예제 #10
0
        public int ReceiveFiles(ClientInfo clientInfo, List <FileStruct> fileList, string localName)
        {
            var        st = new FStat();
            FileStruct file;
            var        ioStream = clientInfo.IoStream;

            string fileName;
            string fNameCmp = String.Empty, fNameTmp = String.Empty;
            var    saveMakeBackups = _options.MakeBackups;
            int    i, phase = 0;
            bool   recvOk;

            if (_options.Verbose > 2)
            {
                Log.WriteLine("ReceiveFiles(" + fileList.Count + ") starting");
            }
            while (true)
            {
                i = ioStream.ReadInt();
                if (i == -1)
                {
                    if (phase != 0)
                    {
                        break;
                    }

                    phase            = 1;
                    _checkSum.Length = CheckSum.SumLength;
                    if (_options.Verbose > 2)
                    {
                        Log.WriteLine("ReceiveFiles phase=" + phase);
                    }
                    ioStream.WriteInt(0); //send_msg DONE
                    if (_options.KeepPartial)
                    {
                        _options.MakeBackups = false;
                    }
                    continue;
                }

                if (i < 0 || i >= fileList.Count)
                {
                    WinRsync.Exit("Invalid file index " + i + " in receiveFiles (count=" + fileList.Count + ")", clientInfo);
                }

                file = (fileList[i]);

                Options.Stats.CurrentFileIndex = i;
                Options.Stats.NumTransferredFiles++;
                Options.Stats.TotalTransferredSize += file.Length;

                if (!localName.IsBlank())
                {
                    fileName = localName;
                }
                else
                {
                    fileName = Path.Combine(_options.Dir, LocalizePath(clientInfo, file.GetFullName().Replace(":", String.Empty)).Replace("\\", "/"));
                    //fileName = Path.Combine(options.dir, file.FNameTo().Replace(":",String.Empty)).Replace("\\", "/");
                    // TODO: path length
                    Directory.CreateDirectory(Path.Combine(_options.Dir, LocalizePath(clientInfo, file.DirName.Replace(":", String.Empty))).Replace("\\", "/"));
                    Log.WriteLine(Path.Combine(_options.Dir, file.DirName));
                    //FileSystem.Directory.CreateDirectory(Path.Combine(options.dir,file.dirName.Replace(":",String.Empty)).Replace("\\", "/"));
                }

                if (_options.DryRun)
                {
                    if (!_options.AmServer && _options.Verbose > 0)
                    {
                        Log.WriteLine(fileName);
                    }
                    continue;
                }

                if (_options.Verbose > 2)
                {
                    Log.WriteLine("receiveFiles(" + fileName + ")");
                }

                if (_options.PartialDir != null && _options.PartialDir.CompareTo(String.Empty) != 0)
                {
                }
                else
                {
                    fNameCmp = fileName;
                }

                FileStream fd1 = null;
                try
                {
                    fd1 = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read);
                }
                catch (FileNotFoundException)
                {
                    fNameCmp = fileName;
                    try
                    {
                        fd1 = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read);
                    }
                    catch (FileNotFoundException)
                    {
                    }
                }
                catch (Exception e)
                {
                    Log.Write(e.Message);
                }
                try
                {
                    var fi = new FileInfo(fNameCmp);
                    // TODO: path length
                    st.Size = fi.Length;
                }
                catch { }

                var        tempFileName = GetTmpName(fileName);
                FileStream fd2          = null;
                fd2 = new FileStream(tempFileName, FileMode.OpenOrCreate, FileAccess.Write);

                if (!_options.AmServer && _options.Verbose > 0)
                {
                    Log.WriteLine(fileName);
                }

                /* recv file data */
                recvOk = ReceiveData(clientInfo, fNameCmp, fd1, st.Size,
                                     fileName, fd2, file.Length);

                if (fd1 != null)
                {
                    fd1.Close();
                }
                if (fd2 != null)
                {
                    fd2.Close();
                }
                // TODO: path length
                File.Copy(tempFileName, fileName, true);
                // TODO: path length
                File.Delete(tempFileName);
                if (recvOk || _options.Inplace)
                {
                    FinishTransfer(fileName, fNameTmp, file, recvOk);
                }
            }
            _options.MakeBackups = saveMakeBackups;

            if (_options.DeleteAfter && _options.Recurse && localName == null && fileList.Count > 0)
            {
                DeleteFiles(fileList);
            }

            if (_options.Verbose > 2)
            {
                Log.WriteLine("ReceiveFiles finished");
            }

            return(0);
        }
예제 #11
0
        public bool ReceiveData(ClientInfo clientInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize)
        {
            var     f         = clientInfo.IoStream;
            var     fileSum1  = new byte[CheckSum.Md4SumLength];
            var     fileSum2  = new byte[CheckSum.Md4SumLength];
            var     data      = new byte[Match.ChunkSize];
            var     sumStruct = new SumStruct();
            MapFile mapBuf    = null;
            var     sender    = new Sender(_options);

            sender.ReadSumHead(clientInfo, ref sumStruct);
            var    offset = 0;
            UInt32 len;

            if (fdR != null && sizeR > 0)
            {
                var mapSize = (int)Math.Max(sumStruct.BLength * 2, 16 * 1024);
                mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sumStruct.BLength);
                if (_options.Verbose > 2)
                {
                    Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR);
                }
            }
            var sum = new Sum(_options);

            sum.Init(_options.ChecksumSeed);

            int i;
            var token = new Token(_options);

            while ((i = token.ReceiveToken(f, ref data, 0)) != 0)
            {
                if (_options.DoProgress)
                {
                    Progress.ShowProgress(offset, totalSize);
                }

                if (i > 0)
                {
                    if (_options.Verbose > 3)
                    {
                        Log.WriteLine("data recv " + i + " at " + offset);
                    }
                    Options.Stats.LiteralData += i;
                    sum.Update(data, 0, i);
                    if (fd != null && FileIo.WriteFile(fd, data, 0, i) != i)
                    {
                        goto report_write_error;
                    }
                    offset += i;
                    continue;
                }

                i = -(i + 1);
                var offset2 = (int)(i * sumStruct.BLength);
                len = sumStruct.BLength;
                if (i == sumStruct.Count - 1 && sumStruct.Remainder != 0)
                {
                    len = sumStruct.Remainder;
                }

                Options.Stats.MatchedData += len;

                if (_options.Verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] of size " + len + " at " + offset2 + " offset=" + offset);
                }

                byte[] map = null;
                var    off = 0;
                if (mapBuf != null)
                {
                    off = mapBuf.MapPtr(offset2, (int)len);
                    map = mapBuf.P;

                    token.SeeToken(map, offset, (int)len);
                    sum.Update(map, off, (int)len);
                }

                if (_options.Inplace)
                {
                    if (offset == offset2 && fd != null)
                    {
                        offset += (int)len;
                        if (fd.Seek(len, SeekOrigin.Current) != offset)
                        {
                            WinRsync.Exit("seek failed on " + Util.FullFileName(fileName), clientInfo);
                        }
                        continue;
                    }
                }
                if (fd != null && FileIo.WriteFile(fd, map, off, (int)len) != (int)len)
                {
                    goto report_write_error;
                }
                offset += (int)len;
            }

            if (_options.DoProgress)
            {
                Progress.EndProgress(totalSize);
            }
            if (fd != null && offset > 0 && FileIo.SparseEnd(fd) != 0)
            {
                WinRsync.Exit("write failed on " + Util.FullFileName(fileName), clientInfo);
            }

            fileSum1 = sum.End();

            if (mapBuf != null)
            {
                mapBuf = null;
            }

            fileSum2 = f.ReadBuffer(CheckSum.Md4SumLength);
            if (_options.Verbose > 2)
            {
                Log.WriteLine("got fileSum");
            }
            if (fd != null && Util.MemoryCompare(fileSum1, 0, fileSum2, 0, CheckSum.Md4SumLength) != 0)
            {
                return(false);
            }
            return(true);

report_write_error:
            {
                WinRsync.Exit("write failed on " + Util.FullFileName(fileName), clientInfo);
            }
            return(true);
        }
예제 #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <param name="moduleNumber"></param>
        /// <returns></returns>
        public static void RsyncModule(ClientInfo clientInfo, int moduleNumber)
        //@fixed Why return something if result not used?
        {
            var path = Daemon.Config.GetModule(moduleNumber).Path;
            var name = Daemon.Config.GetModuleName(moduleNumber);
            var ioStream = clientInfo.IoStream;
            var options = clientInfo.Options;
            var args = new string[Options.MaxArgs];
            int argc = 0, maxArgs = Options.MaxArgs;
            var line = String.Empty;

            if (path[0] == '/')
            {
                path = path.Remove(0, 1);
            }
            path = path.Replace("\n", String.Empty);

            var ac = new Access();

            if (
                !ac.AllowAccess(options.RemoteAddr, options.RemoteHost, Daemon.Config.GetHostsAllow(moduleNumber),
                                Daemon.Config.GetHostsDeny(moduleNumber)))
            {
                Log.Write("rsync denied on module " + name + " from " + options.RemoteHost + " (" + options.RemoteAddr +
                          ")");
                ioStream.IoPrintf("@ERROR: access denied to " + name + " from " + options.RemoteHost + " (" +
                                  options.RemoteAddr + ")\n");
                return;
            }

            if (!Authentication.AuthorizeServer(clientInfo, moduleNumber, options.RemoteAddr, "@RSYNCD: AUTHREQD "))
            {
                Log.Write("auth failed on module " + name + " from " + options.RemoteHost + " (" + options.RemoteAddr +
                          ")\n");
                ioStream.IoPrintf("@ERROR: auth failed on module " + name + "\n");
                return;
            }
            // TODO: path length
            if (Directory.Exists(path))
            {
                ioStream.IoPrintf("@RSYNCD: OK\n");
            }
            else
            {
                try
                {
                    // TODO: path length
                    Directory.CreateDirectory(path);
                    ioStream.IoPrintf("@RSYNCD: OK\n");
                }
                catch (Exception)
                {
                    ioStream.IoPrintf("@ERROR: Path not found\n");
                    WinRsync.Exit("@ERROR: Path not found: " + path, clientInfo);
                }
            }
            options.AmServer = true; //to fix error in SetupProtocol
            options.Dir      = path;

            do
            {
                line = ioStream.ReadLine();
                line = line.Substring(0, line.Length - 1);
                if (argc == maxArgs)
                {
                    maxArgs += Options.MaxArgs;
                    MapFile.ExtendArray(ref args, maxArgs);
                }
                args[argc++] = line;
            } while (!string.IsNullOrEmpty(line));

            args[argc++] = path;

            options.Verbose = 0;



            var argsNotUsed = CommandLineParser.ParseArguments(args, options);

            if (argsNotUsed == -1)
            {
                WinRsync.Exit("Error parsing options", clientInfo);
            }

            var args2 = new string[argsNotUsed];

            for (var i = 0; i < argsNotUsed; i++)
            {
                args2[i] = args[args.Length - argsNotUsed + i];
            }



            WinRsync.SetupProtocol(clientInfo);
            ioStream.IoStartMultiplexOut();
            Daemon.StartServer(clientInfo, args2);
        }
예제 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public bool LoadParm(Options options)
        {
            lock (this)
            {
                // TODO: path length
                if (!File.Exists(_confFile))
                {
                    WinRsync.Exit("Can't find .conf file: " + _confFile, null);
                    return(false);
                }
                try
                {
                    using (var cf = new StreamReader(_confFile))
                    {
                        Module mod = null;

                        if (Modules == null)
                        {
                            Modules = new List <Module>();
                        }

                        lock (cf)
                        {
                            while (true)
                            {
                                var line = cf.ReadLine();
                                if (line == null)
                                {
                                    break;
                                }
                                line = line.Trim();
                                if (!line.IsBlank() && !line.StartsWith(";") && !line.StartsWith("#"))
                                {
                                    if (line.StartsWith("[") && line.StartsWith("]"))
                                    {
                                        line = line.TrimStart('[').TrimEnd(']');
                                        var numberModule = -1;
                                        if ((numberModule = GetNumberModule(line)) >= 0)
                                        {
                                            mod = GetModule(numberModule);
                                        }
                                        else
                                        {
                                            mod = new Module(line);
                                            Modules.Add(mod);
                                        }
                                    }
                                    else
                                    {
                                        if (mod != null)
                                        {
                                            var parm = line.Split('=');
                                            if (parm.Length > 2)
                                            {
                                                continue;
                                            }
                                            parm[0] = parm[0].Trim().ToLower();
                                            parm[1] = parm[1].Trim();
                                            switch (parm[0])
                                            {
                                            case "path":
                                                mod.Path = parm[1].Replace(@"\", "/");
                                                break;

                                            case "comment":
                                                mod.Comment = parm[1];
                                                break;

                                            case "read only":
                                                mod.ReadOnly = (parm[1].CompareTo("false") == 0) ? false : true;
                                                break;

                                            case "write only":
                                                mod.WriteOnly = (parm[1].CompareTo("true") == 0) ? true : false;
                                                break;

                                            case "hosts allow":
                                                mod.HostsAllow = parm[1];
                                                break;

                                            case "hosts deny":
                                                mod.HostsDeny = parm[1];
                                                break;

                                            case "auth users":
                                                mod.AuthUsers = parm[1];
                                                break;

                                            case "secrets file":
                                                mod.SecretsFile = Path.GetFileName(parm[1]);
                                                break;

                                            default:
                                                continue;
                                            }
                                        }
                                        else
                                        {
                                            var parm = line.Split('=');
                                            if (parm.Length > 2)
                                            {
                                                continue;
                                            }
                                            parm[0] = parm[0].Trim();
                                            parm[1] = parm[1].Trim();
                                            switch (parm[0])
                                            {
                                            case "log file":
                                                var logFile = parm[1];
                                                try
                                                {
                                                    options.LogFile = new FileStream(logFile, FileMode.OpenOrCreate | FileMode.Append, FileAccess.Write);
                                                }
                                                catch (Exception e)
                                                {
                                                    Log.Write(e.Message);
                                                }
                                                break;

                                            case "port":
                                                Port = parm[1];
                                                options.RsyncPort = Convert.ToInt32(Port);
                                                break;

                                            case "address":
                                                options.BindAddress = Address = parm[1];
                                                break;

                                            default:
                                                continue;
                                            }
                                        }
                                    }
                                }
                            }
                            cf.Close();
                        }
                    }
                }
                catch
                {
                    WinRsync.Exit("failed to open: " + _confFile, null);
                    return(false);
                }
            }
            return(true);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        public static int ParseArguments(string[] args, Options options)
        {
            var argsNotUsed = 0;
            var i           = 0;
            var excl        = new Exclude(options);

            while (i < args.Length)
            {
                try
                {
                    switch (args[i])
                    {
                    case "--suffix":
                        options.BackupSuffix = args[++i];
                        break;

                    case "--rsync-path":
                        options.RsyncPath = args[++i];
                        break;

                    case "--password-file":
                        options.PasswordFile = args[++i];
                        break;

                    case "--ignore-times":
                    case "-I":
                        options.IgnoreTimes = true;
                        break;

                    case "--size-only":
                        options.SizeOnly = true;
                        break;

                    case "--modify-window":
                        options.UsingModifyWindow = true;
                        options.ModifyWindow      = Convert.ToInt32(args[++i]);
                        break;

                    case "--one-file-system":
                    case "-x":
                        options.OneFileSystem = true;
                        break;

                    case "--delete":
                        options.DeleteMode = true;
                        break;

                    case "--existing":
                        options.OnlyExisting = true;
                        break;

                    case "--ignore-existing":
                        options.OptIgnoreExisting = true;
                        break;

                    case "--delete-after":
                        options.DeleteMode  = true;
                        options.DeleteAfter = true;
                        break;

                    case "--delete-excluded":
                        options.DeleteMode     = true;
                        options.DeleteExcluded = true;
                        break;

                    case "--force":
                        options.ForceDelete = true;
                        break;

                    case "--numeric-ids":
                        options.NumericIds = true;
                        break;

                    case "--exclude":
                        excl.AddExclude(ref options.ExcludeList, args[++i], 0);
                        break;

                    case "--include":
                        excl.AddExclude(ref options.ExcludeList, args[++i], (int)Options.XflgDefInclude);
                        options.ForceDelete = true;
                        break;

                    case "--exclude-from":
                    case "--include-from":
                        var arg = args[i];
                        excl.AddExcludeFile(ref options.ExcludeList, args[++i],
                                            (arg.CompareTo("--exclude-from") == 0) ? 0 : (int)Options.XflgDefInclude);
                        break;

                    case "--safe-links":
                        options.SafeSymlinks = true;
                        break;

                    case "--help":
                    case "-h":
                        WinRsync.Exit(String.Empty, null);
                        break;

                    case "--backup":
                    case "-b":
                        options.MakeBackups = true;
                        break;

                    case "--dry-run":
                    case "-n":
                        options.DryRun = true;
                        break;

                    case "--sparse":
                    case "-S":
                        options.SparseFiles = true;
                        break;

                    case "--cvs-exclude":
                    case "-C":
                        options.CvsExclude = true;
                        break;

                    case "--update":
                    case "-u":
                        options.UpdateOnly = true;
                        break;

                    case "--inplace":
                        options.Inplace = true;
                        break;

                    case "--keep-dirlinks":
                    case "-K":
                        options.KeepDirLinks = true;
                        break;

                    case "--links":
                    case "-l":
                        options.PreserveLinks = true;
                        break;

                    case "--copy-links":
                    case "-L":
                        options.CopyLinks = true;
                        break;

                    case "--whole-file":
                    case "-W":
                        options.WholeFile = 1;
                        break;

                    case "--no-whole-file":
                        options.WholeFile = 0;
                        break;

                    case "--copy-unsafe-links":
                        options.CopyUnsafeLinks = true;
                        break;

                    case "--perms":
                    case "-p":
                        options.PreservePerms = true;
                        break;

                    case "--owner":
                    case "-o":
                        options.PreserveUid = true;
                        break;

                    case "--group":
                    case "-g":
                        options.PreserveGid = true;
                        break;

                    case "--devices":
                    case "-D":
                        options.PreserveDevices = true;
                        break;

                    case "--times":
                    case "-t":
                        options.PreserveTimes = true;
                        break;

                    case "--checksum":
                    case "-c":
                        options.AlwaysChecksum = true;
                        break;

                    case "--verbose":
                    case "-v":
                        options.Verbose++;
                        break;

                    case "--quiet":
                    case "-q":
                        options.Quiet++;
                        break;

                    case "--archive":
                    case "-a":
                        options.ArchiveMode = true;
                        break;

                    case "--server":
                        options.AmServer = true;
                        break;

                    case "--sender":
                        options.AmSender = true;
                        break;

                    case "--recursive":
                    case "-r":
                        options.Recurse = true;
                        break;

                    case "--relative":
                    case "-R":
                        options.RelativePaths = true;
                        break;

                    case "--no-relative":
                        options.RelativePaths = false;
                        break;

                    case "--rsh":
                    case "-e":
                        options.ShellCmd = args[++i];
                        break;

                    case "--block-size":
                    case "-B":
                        options.BlockSize = Convert.ToInt32(args[++i]);
                        break;

                    case "--max-delete":
                        options.MaxDelete = Convert.ToInt32(args[++i]);
                        break;

                    case "--timeout":
                        options.IoTimeout = Convert.ToInt32(args[++i]);
                        break;

                    case "--temp-dir":
                    case "-T":
                        options.TmpDir = args[++i];
                        break;

                    case "--compare-dest":
                        options.CompareDest = args[++i];
                        break;

                    case "--link-dest":
                        options.CompareDest = args[++i];
                        break;

                    case "--compress":
                    case "-z":
                        options.DoCompression = true;
                        break;

                    case "--stats":
                        options.DoStats = true;
                        break;

                    case "--progress":
                        options.DoProgress = true;
                        break;

                    case "--partial":
                        options.KeepPartial = true;
                        break;

                    case "--partial-dir":
                        options.PartialDir = args[++i];
                        break;

                    case "--ignore-errors":
                        options.IgnoreErrors = true;
                        break;

                    case "--blocking-io":
                        options.BlockingIo = 1;
                        break;

                    case "--no-blocking-io":
                        options.BlockingIo = 0;
                        break;

                    case "-P":
                        options.DoProgress  = true;
                        options.KeepPartial = true;
                        break;

                    case "--log-format":
                        options.LogFormat = args[++i];
                        break;

                    case "--bwlimit":
                        options.BwLimit = Convert.ToInt32(args[++i]);
                        break;

                    case "--backup-dir":
                        options.BackupDir = args[++i];
                        break;

                    case "--hard-links":
                    case "-H":
                        options.PreserveHardLinks = true;
                        break;

                    case "--read-batch":
                        options.BatchName = args[++i];
                        options.ReadBatch = true;
                        break;

                    case "--write-batch":
                        options.BatchName  = args[++i];
                        options.WriteBatch = true;
                        break;

                    case "--files-from":
                        options.FilesFrom = args[++i];
                        break;

                    case "--from0":
                        options.EolNulls = true;
                        break;

                    case "--no-implied-dirs":
                        options.ImpliedDirs = true;
                        break;

                    case "--protocol":
                        options.ProtocolVersion = Convert.ToInt32(args[++i]);
                        break;

                    case "--checksum-seed":
                        options.ChecksumSeed = Convert.ToInt32(args[++i]);
                        break;

                    case "--daemon":
                        options.AmDaemon = true;
                        break;

                    case "--address":
                        options.BindAddress = args[++i];
                        break;

                    case "--port":
                        options.RsyncPort = Convert.ToInt32(args[++i]);
                        break;

                    case "--config":
                        options.ConfigFile = args[++i].Trim();
                        break;

                    default:
                    {
                        argsNotUsed += ParseMergeArgs(args[i], options);
                        break;
                    }
                    }
                    i++;
                }
                catch { return(-1); }
            }
            if (options.AmSender && !options.AmServer)
            {
                WinRsync.Exit(String.Empty, null);
            }
            if (options.IoTimeout > 0 && options.IoTimeout < options.SelectTimeout)
            {
                options.SelectTimeout = options.IoTimeout;
            }
            return(argsNotUsed);
        }