예제 #1
0
 public void WriteSumHead(IoStream f, SumStruct sum)
 {
     if (sum == null)
     {
         sum = new SumStruct();
     }
     f.WriteInt(sum.Count);
     f.WriteInt((int)sum.BLength);
     if (_options.ProtocolVersion >= 27)
     {
         f.WriteInt(sum.S2Length);
     }
     f.WriteInt((int)sum.Remainder);
 }
예제 #2
0
 public void SimpleSendToken(IoStream f, int token, MapFile buf, int offset, int n)
 {
     if (n > 0)
     {
         var l = 0;
         while (l < n)
         {
             var n1 = Math.Min(Match.ChunkSize, n - l);
             f.WriteInt(n1);
             var off = buf.MapPtr(offset + l, n1);
             f.Write(buf.P, off, n1);
             l += n1;
         }
     }
     if (token != -2)
     {
         f.WriteInt(-(token + 1));
     }
 }
예제 #3
0
        public void SendExcludeList(IoStream f)
        {
            if (_options.ListOnly && !_options.Recurse)
            {
                AddExclude(ref _options.ExcludeList, "/*/*", 0);
            }

            foreach (var ent in _options.ExcludeList)
            {
                int    l;
                string p;

                if (ent.Pattern.Length == 0 || ent.Pattern.Length > Options.Maxpathlen)
                {
                    continue;
                }
                l = ent.Pattern.Length;
                p = ent.Pattern;
                if ((ent.MatchFlags & Options.MatchflgDirectory) != 0)
                {
                    p += "/\0";
                }

                if ((ent.MatchFlags & Options.MatchflgInclude) != 0)
                {
                    f.WriteInt(l + 2);
                    f.IoPrintf("+ ");
                }
                else if ((p[0] == '-' || p[0] == '+') && p[1] == ' ')
                {
                    f.WriteInt(l + 2);
                    f.IoPrintf("- ");
                }
                else
                {
                    f.WriteInt(l);
                }
                f.IoPrintf(p);
            }
            f.WriteInt(0);
        }
예제 #4
0
        public void GenerateAndSendSums(Stream fd, long len, IoStream f, Stream fCopy)
        {
            long    i;
            MapFile mapBuf;
            var     sum    = new SumStruct();
            long    offset = 0;

            SumSizesSqroot(sum, (UInt64)len);

            if (len > 0)
            {
                mapBuf = new MapFile(fd, (int)len, Options.MaxMapSize, (int)sum.BLength);
            }
            else
            {
                mapBuf = null;
            }

            WriteSumHead(f, sum);

            for (i = 0; i < sum.Count; i++)
            {
                var n1   = (UInt32)Math.Min(len, sum.BLength);
                var off  = mapBuf.MapPtr((int)offset, (int)n1);
                var map  = mapBuf.P;
                var sum1 = CheckSum.GetChecksum1(map, off, (int)n1);
                var sum2 = new byte[CheckSum.SumLength];

                sum2 = _checkSum.GetChecksum2(map, off, (int)n1);
                if (_options.Verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] offset=" + offset + " len=" + n1 + " sum1=" + sum1);
                }
                f.WriteInt((int)sum1);
                f.Write(sum2, 0, sum.S2Length);
                len    -= n1;
                offset += n1;
            }
            if (mapBuf != null)
            {
                mapBuf = null;
            }
        }
예제 #5
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);
        }
예제 #6
0
        public void SendFileEntry(FileStruct file, IoStream ioStream, UInt32 baseflags)
        {
            var flags = baseflags;
            int l1 = 0, l2 = 0;

            if (ioStream == null)
            {
                return;
            }
            if (file == null)
            {
                ioStream.WriteByte(0);
                _lastName = String.Empty;
                return;
            }
            var fileName = file.GetFullName().Replace(":", String.Empty);

            for (l1 = 0;
                 _lastName.Length > l1 && (fileName[l1] == _lastName[l1]) && (l1 < 255);
                 l1++)
            {
            }
            l2 = fileName.Substring(l1).Length;

            flags |= Options.XmitSameName;

            if (l2 > 255)
            {
                flags |= Options.XmitLongName;
            }
            if (_options.ProtocolVersion >= 28)
            {
                if (flags == 0 && !Util.S_ISDIR(file.Mode))
                {
                    flags |= Options.XmitTopDir;
                }

                /*if ((flags & 0xFF00) > 0 || flags == 0)
                 * {
                 *  flags |= Options.XMIT_EXTENDED_FLAGS;
                 *  f.writeByte((byte)flags);
                 *  f.writeByte((byte)(flags >> 8));
                 * }
                 * else					*/
                ioStream.WriteByte((byte)flags);
            }
            else
            {
                if ((flags & 0xFF) == 0 && !Util.S_ISDIR(file.Mode))
                {
                    flags |= Options.XmitTopDir;
                }
                if ((flags & 0xFF) == 0)
                {
                    flags |= Options.XmitLongName;
                }
                ioStream.WriteByte((byte)flags);
            }
            if ((flags & Options.XmitSameName) != 0)
            {
                ioStream.WriteByte((byte)l1);
            }
            if ((flags & Options.XmitLongName) != 0)
            {
                ioStream.WriteInt(l2);
            }
            else
            {
                ioStream.WriteByte((byte)l2);
            }


            var b = Encoding.ASCII.GetBytes(fileName);

            ioStream.Write(b, l1, l2);
            ioStream.WriteLongInt(file.Length);


            if ((flags & Options.XmitSameTime) == 0)
            {
                ioStream.WriteInt(file.ModTime.Second);
            }
            if ((flags & Options.XmitSameMode) == 0)
            {
                ioStream.WriteInt((int)file.Mode);
            }
            if (_options.PreserveUid && (flags & Options.XmitSameUid) == 0)
            {
                ioStream.WriteInt(file.Uid);
            }
            if (_options.PreserveGid && (flags & Options.XmitSameGid) == 0)
            {
                ioStream.WriteInt(file.Gid);
            }
            if (_options.AlwaysChecksum)
            {
                byte[] sum;
                if (!Util.S_ISDIR(file.Mode))
                {
                    sum = file.Sum;
                }
                else if (_options.ProtocolVersion < 28)
                {
                    sum = new byte[16];
                }
                else
                {
                    sum = null;
                }

                if (sum != null)
                {
                    ioStream.Write(sum, 0, _options.ProtocolVersion < 21 ? 2 : CheckSum.Md4SumLength);
                }
            }

            _lastName = fileName;
        }
예제 #7
0
        public void GenerateFiles(IoStream f, List <FileStruct> fileList, string localName)
        {
            int i;
            var phase = 0;


            if (_options.Verbose > 2)
            {
                Log.WriteLine("generator starting count=" + fileList.Count);
            }

            for (i = 0; i < fileList.Count; i++)
            {
                var file = (fileList[i]);
                if (file.BaseName == null)
                {
                    continue;
                }
                if (Util.S_ISDIR(file.Mode))
                {
                    continue;
                }
                ReceiveGenerator(localName != null ? localName : file.GetFullName(), file, i, f);
            }

            phase++;
            _checkSum.Length = CheckSum.SumLength;
            if (_options.Verbose > 2)
            {
                Log.WriteLine("GenerateFiles phase=" + phase);
            }
            f.WriteInt(-1);

            phase++;
            if (_options.Verbose > 2)
            {
                Log.WriteLine("GenerateFiles phase=" + phase);
            }

            f.WriteInt(-1);

            if (_options.ProtocolVersion >= 29 && !_options.DelayUpdates)
            {
                f.WriteInt(-1);
            }

            /* now we need to fix any directory permissions that were
             * modified during the transfer
             * */
            for (i = 0; i < fileList.Count; i++)
            {
                var file = (fileList[i]);
                if (file.BaseName != null || Util.S_ISDIR(file.Mode))
                {
                    continue;
                }
                ReceiveGenerator(localName != null ? localName : file.GetFullName(), file, i, null);
            }

            if (_options.Verbose > 2)
            {
                Log.WriteLine("GenerateFiles finished");
            }
        }
예제 #8
0
        public void ReceiveGenerator(string fileName, FileStruct file, int i, IoStream f)
        {
            fileName = Path.Combine(_options.Dir, fileName);

            if (UnchangedFile(fileName, file))
            {
                return;
            }
            if (_options.Verbose > 2)
            {
                Log.WriteLine("Receive Generator(" + fileName + "," + i + ")\n");
            }
            int statRet;
            var st = new FStat();

            if (_options.DryRun)
            {
                statRet = -1;
            }
            else
            {
                statRet = 0;
                try
                {
                    var fi = new FileInfo(fileName);
                    // TODO: path length
                    st.Size = fi.Length;
                    // TODO: path length
                    st.MTime = fi.LastWriteTime;
                }
                catch
                {
                    statRet = -1;
                }
            }

            if (_options.OnlyExisting && statRet == -1)
            {
                /* we only want to update existing files */
                if (_options.Verbose > 1)
                {
                    Log.WriteLine("not creating new file \"" + fileName + "\"");
                }
                return;
            }
            var fNameCmp = fileName;

            if (_options.WholeFile > 0)
            {
                f.WriteInt(i);
                WriteSumHead(f, null);
                return;
            }
            FileStream fd;

            try
            {
                fd = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read);
            }
            catch
            {
                if (_options.Verbose > 3)
                {
                    Log.WriteLine("failed to open " + Util.FullFileName(fNameCmp) + ", continuing");
                }
                f.WriteInt(i);
                WriteSumHead(f, null);
                return;
            }

            if (_options.Verbose > 3)
            {
                Log.WriteLine("gen mapped " + fNameCmp + " of size " + st.Size);
            }

            if (_options.Verbose > 2)
            {
                Log.WriteLine("generating and sending sums for " + i);
            }

            f.WriteInt(i);
            Stream fCopy = null;

            GenerateAndSendSums(fd, st.Size, f, fCopy);

            if (fCopy != null)
            {
                fCopy.Close();
            }
            fd.Close();
        }