예제 #1
0
		public void SendToken(IOStream f, int token, MapFile buf, int offset, int n, int toklen)
		{			
			if (!options.doCompression) 
				SimpleSendToken(f,token,buf,offset,n);
			else 
				SendDeflatedToken(f, token, buf, offset, n, toklen);
		}
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="sum"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public bool FileCheckSum(string fileName, ref byte[] sum, int size)
        {
            int    i;
            MDFour mdFour = new MDFour(options);

            sum = new byte[MD4_SUM_LENGTH];
            try
            {
                using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    MapFile buf = new MapFile(fileStream, size, Options.MAX_MAP_SIZE, CSUM_CHUNK);
                    mdFour.Begin();

                    for (i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK)
                    {
                        int offset = buf.MapPtr(i, CSUM_CHUNK);
                        mdFour.Update(buf.p, offset, CSUM_CHUNK);
                    }

                    if (size - i > 0 || options.protocolVersion >= 27)
                    {
                        int offset = buf.MapPtr(i, size - i);
                        mdFour.Update(buf.p, offset, (UInt32)(size - i));
                    }

                    sum = mdFour.Result();

                    fileStream.Close();
                    //buf.UnMapFile(); //@fixed useless string
                    return(true);
                }
            }
            catch (Exception)
            {
            }
            return(false);
        }
예제 #3
0
        public bool FileCheckSum(string fileName, ref byte[] sum, int size)
        {
            int    i;
            MDFour m = new MDFour(options);

            sum = new byte[MD4_SUM_LENGTH];
            Stream fd;

            try
            {
                fd = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            } catch (Exception)
            {
                return(false);
            }
            MapFile buf = new MapFile(fd, size, Options.MAX_MAP_SIZE, CSUM_CHUNK);

            m.Begin();

            for (i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK)
            {
                int offset = buf.MapPtr(i, CSUM_CHUNK);
                m.Update(buf.p, offset, CSUM_CHUNK);
            }

            if (size - i > 0 || options.protocolVersion >= 27)
            {
                int offset = buf.MapPtr(i, size - i);
                m.Update(buf.p, offset, (UInt32)(size - i));
            }

            sum = m.Result();

            fd.Close();
            buf.UnMapFile();
            return(true);
        }
예제 #4
0
 public void SendDeflatedToken(IoStream f, int token, MapFile buf, int offset, int nb, int toklen)
 {
 }
예제 #5
0
파일: Receiver.cs 프로젝트: vmas/rsync.net
        public bool ReceiveData(ClientInfo clientInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize)
        {
            IOStream f = clientInfo.IoStream;

            byte[]    fileSum1  = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[]    fileSum2  = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[]    data      = new byte[Match.CHUNK_SIZE];
            SumStruct sumStruct = new SumStruct();
            MapFile   mapBuf    = null;
            Sender    sender    = new Sender(options);

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

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

            sum.Init(options.checksumSeed);

            int   i;
            Token token = new Token(options);

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

                if (i > 0)
                {
                    if (options.verbose > 3)
                    {
                        Log.WriteLine("data recv " + i + " at " + offset);
                    }
                    Options.stats.literalData += i;
                    sum.Update(data, 0, i);
                    if (fd != null && FileIO.WriteFile(fd, data, 0, i) != i)
                    {
                        goto report_write_error;
                    }
                    offset += i;
                    continue;
                }

                i = -(i + 1);
                int offset2 = (int)(i * sumStruct.bLength);
                len = sumStruct.bLength;
                if (i == sumStruct.count - 1 && sumStruct.remainder != 0)
                {
                    len = sumStruct.remainder;
                }

                Options.stats.matchedData += len;

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

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

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

                if (options.inplace)
                {
                    if (offset == offset2 && fd != null)
                    {
                        offset += (int)len;
                        if (fd.Seek(len, SeekOrigin.Current) != offset)
                        {
                            MainClass.Exit("seek failed on " + Util.fullFileName(fileName), clientInfo);
                        }
                        continue;
                    }
                }
                if (fd != null && FileIO.WriteFile(fd, map, off, (int)len) != (int)len)
                {
                    goto report_write_error;
                }
                offset += (int)len;
            }

            if (options.doProgress)
            {
                Progress.EndProgress(totalSize);
            }
            if (fd != null && offset > 0 && FileIO.SparseEnd(fd) != 0)
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo);
            }

            fileSum1 = sum.End();

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

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

report_write_error:
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo);
            }
            return(true);
        }
예제 #6
0
파일: Match.cs 프로젝트: xcrash/rsync.net
        public void MatchSums(IOStream f, SumStruct s, MapFile buf, int len)
        {
            byte[] fileSum = new byte[CheckSum.MD4_SUM_LENGTH];

            lastMatch    = 0;
            falseAlarms  = 0;
            tagHits      = 0;
            matches      = 0;
            dataTransfer = 0;

            Sum sum = new Sum(options);

            sum.Init(options.checksumSeed);

            if (len > 0 && s.count > 0)
            {
                BuildHashTable(s);

                if (options.verbose > 2)
                {
                    Log.WriteLine("built hash table");
                }

                HashSearch(f, s, buf, len, sum);

                if (options.verbose > 2)
                {
                    Log.WriteLine("done hash search");
                }
            }
            else
            {
                for (int j = 0; j < len - CHUNK_SIZE; j += CHUNK_SIZE)
                {
                    int n1 = Math.Min(CHUNK_SIZE, (len - CHUNK_SIZE) - j);
                    Matched(f, s, buf, j + n1, -2, sum);
                }
                Matched(f, s, buf, len, -1, sum);
            }

            fileSum = sum.End();
            if (buf != null && buf.status)
            {
                fileSum[0]++;
            }

            if (options.verbose > 2)
            {
                Log.WriteLine("sending fileSum");
            }
            f.Write(fileSum, 0, CheckSum.MD4_SUM_LENGTH);

            targets.Clear();

            if (options.verbose > 2)
            {
                Log.WriteLine("falseAlarms=" + falseAlarms + " tagHits=" + tagHits + " matches=" + matches);
            }

            totalTagHits              += tagHits;
            totalFalseAlarms          += falseAlarms;
            totalMatches              += matches;
            Options.stats.literalData += dataTransfer;
        }
예제 #7
0
		public void Matched(IOStream f, SumStruct s, MapFile buf, int offset, int i, Sum sum)
		{
			int n = offset - lastMatch;
			int j;

			if (options.verbose > 2 && i >= 0)
				Log.WriteLine("match at " + offset +" last_match=" + lastMatch + " j=" + i + " len=" + s.sums[i].len + " n=" + n);

			Token token = new Token(options);
			token.SendToken(f,i,buf,lastMatch,n,(int)(i<0?0:s.sums[i].len));
			dataTransfer += n;

			if (i >= 0) 
			{
				Options.stats.matchedData += s.sums[i].len;
				n += (int)s.sums[i].len;
			}

			for (j = 0; j < n; j += CHUNK_SIZE) 
			{
				int n1 = Math.Min(CHUNK_SIZE,n-j);
				int off = buf.MapPtr(lastMatch + j, n1);
				sum.Update(buf.p , off, n1);
			}

			if (i >= 0)
				lastMatch = (int)(offset + s.sums[i].len);
			else
				lastMatch = offset;

			if (buf != null && options.doProgress) 
			{
				Progress.ShowProgress(lastMatch, buf.fileSize);
				if (i == -1)
					Progress.EndProgress(buf.fileSize);
			}
		}
예제 #8
0
        /// <summary>
        /// Reads socket into buffer
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int ReadSocketUnbuffered(byte[] buffer, int offset, int count)
        {
            int tag, result = 0;

            byte[] line = new byte[1024];

            if (IOBufIn == null)
            {
                return(socketIn.Read(buffer, offset, count));
            }

            if (!IOMultiplexingIn && remaining == 0)
            {
                Flush();
                remaining    = socketIn.Read(IOBufIn, 0, IOBufInSize);
                IOBufInIndex = 0;
            }

            while (result == 0)
            {
                if (remaining != 0)
                {
                    count = Math.Min(count, remaining);
                    Util.MemoryCopy(buffer, offset, IOBufIn, IOBufInIndex, count);
                    IOBufInIndex += count;
                    remaining    -= count;
                    result        = count;
                    break;
                }

                ReadLoop(line, 4);
                tag = (int)IVAL(line, 0);

                remaining = tag & 0xFFFFFF;
                tag       = (tag >> 24) - MPLEX_BASE;

                switch ((MsgCode)tag)
                {
                case MsgCode.MSG_DATA:
                    if (remaining > IOBufInSize)
                    {
                        MapFile.ExtendArray(ref IOBufIn, remaining);
                        IOBufInSize = remaining;
                    }
                    ReadLoop(IOBufIn, remaining);
                    IOBufInIndex = 0;
                    break;

                case MsgCode.MSG_INFO:
                case MsgCode.MSG_ERROR:
                    if (remaining >= line.Length)
                    {
                        throw new Exception("Multiplexing overflow " + tag + ":" + remaining);
                    }
                    ReadLoop(line, remaining);
                    remaining = 0;
                    break;

                default:
                    throw new Exception("Read unknown message from stream");
                }
            }

            if (remaining == 0)
            {
                Flush();
            }

            return(result);
        }
예제 #9
0
        public bool ReceiveData(ClientInfo clientInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize)
        {
            IOStream f = clientInfo.IoStream;
            byte[] fileSum1 = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[] fileSum2 = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[] data = new byte[Match.CHUNK_SIZE];
            SumStruct sumStruct = new SumStruct();
            MapFile mapBuf = null;
            Sender sender = new Sender(options);
            sender.ReadSumHead(clientInfo, ref sumStruct);
            int offset = 0;
            UInt32 len;

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

            int i;
            Token token = new Token(options);
            while ((i = token.ReceiveToken(f, ref data, 0)) != 0)
            {
                if (options.doProgress)
                {
                    Progress.ShowProgress(offset, totalSize);
                }

                if (i > 0)
                {
                    if (options.verbose > 3)
                    {
                        Log.WriteLine("data recv " + i + " at " + offset);
                    }
                    Options.stats.literalData += i;
                    sum.Update(data, 0, i);
                    if (fd != null && FileIO.WriteFile(fd, data, 0, i) != i)
                    {
                        goto report_write_error;
                    }
                    offset += i;
                    continue;
                }

                i = -(i + 1);
                int offset2 = (int)(i * sumStruct.bLength);
                len = sumStruct.bLength;
                if (i == sumStruct.count - 1 && sumStruct.remainder != 0)
                {
                    len = sumStruct.remainder;
                }

                Options.stats.matchedData += len;

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

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

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

                if (options.inplace)
                {
                    if (offset == offset2 && fd != null)
                    {
                        offset += (int)len;
                        if (fd.Seek(len, SeekOrigin.Current) != offset)
                        {
                            MainClass.Exit("seek failed on " + Util.fullFileName(fileName), clientInfo);
                        }
                        continue;
                    }
                }
                if (fd != null && FileIO.WriteFile(fd, map, off, (int)len) != (int)len)
                {
                    goto report_write_error;
                }
                offset += (int)len;
            }

            if (options.doProgress)
            {
                Progress.EndProgress(totalSize);
            }
            if (fd != null && offset > 0 && FileIO.SparseEnd(fd) != 0)
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo);
            }

            fileSum1 = sum.End();

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

            fileSum2 = f.ReadBuffer(CheckSum.MD4_SUM_LENGTH);
            if (options.verbose > 2)
            {
                Log.WriteLine("got fileSum");
            }
            if (fd != null && Util.MemoryCompare(fileSum1, 0, fileSum2, 0, CheckSum.MD4_SUM_LENGTH) != 0)
            {
                return false;
            }
            return true;
        report_write_error:
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), clientInfo);
            }
            return true;
        }
예제 #10
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();
            }
        }
예제 #11
0
        public void GenerateAndSendSums(Stream fd, long len, IOStream f, Stream fCopy)
        {
            long i;
            MapFile mapBuf;
            SumStruct sum = new SumStruct();
            long offset = 0;

            SumSizesSqroot(sum, (UInt64)len);

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

            WriteSumHead(f, sum);

            for (i = 0; i < sum.count; i++)
            {
                UInt32 n1 = (UInt32)Math.Min(len, sum.bLength);
                int off = mapBuf.MapPtr((int)offset, (int)n1);
                byte[] map = mapBuf.p;
                UInt32 sum1 = CheckSum.GetChecksum1(map, off, (int)n1);
                byte[] sum2 = new byte[CheckSum.SUM_LENGTH];

                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;
            }
        }
예제 #12
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="sum"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public bool FileCheckSum(string fileName, ref byte[] sum, int size)
        {
            int i;
            MDFour mdFour = new MDFour(options);
            sum = new byte[MD4_SUM_LENGTH];
            try
            {
                using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {

                    MapFile buf = new MapFile(fileStream, size, Options.MAX_MAP_SIZE, CSUM_CHUNK);
                    mdFour.Begin();

                    for (i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK)
                    {
                        int offset = buf.MapPtr(i, CSUM_CHUNK);
                        mdFour.Update(buf.p, offset, CSUM_CHUNK);
                    }

                    if (size - i > 0 || options.protocolVersion >= 27)
                    {
                        int offset = buf.MapPtr(i, size - i);
                        mdFour.Update(buf.p, offset, (UInt32)(size - i));
                    }

                    sum = mdFour.Result();

                    fileStream.Close();
                    //buf.UnMapFile(); //@fixed useless string
                    return true;
                }
            }
            catch (Exception)
            {
            }
            return false;

        }
예제 #13
0
파일: IO.cs 프로젝트: muratoflu/rsync.net
        /// <summary>
        /// Reads socket into buffer
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int ReadSocketUnbuffered(byte[] buffer, int offset, int count)
        {
            int tag, result = 0;
            var line = new byte[1024];

            if (_ioBufIn == null)
            {
                return(_socketIn.Read(buffer, offset, count));
            }

            if (!_ioMultiplexingIn && _remaining == 0)
            {
                Flush();
                _remaining    = _socketIn.Read(_ioBufIn, 0, _ioBufInSize);
                _ioBufInIndex = 0;
            }

            while (result == 0)
            {
                if (_remaining != 0)
                {
                    count = Math.Min(count, _remaining);
                    Util.MemoryCopy(buffer, offset, _ioBufIn, _ioBufInIndex, count);
                    _ioBufInIndex += count;
                    _remaining    -= count;
                    result         = count;
                    break;
                }

                ReadLoop(line, 4);
                tag = (int)Ival(line, 0);

                _remaining = tag & 0xFFFFFF;
                tag        = (tag >> 24) - MplexBase;

                switch ((MsgCode)tag)
                {
                case MsgCode.MsgData:
                    if (_remaining > _ioBufInSize)
                    {
                        MapFile.ExtendArray(ref _ioBufIn, _remaining);
                        _ioBufInSize = _remaining;
                    }
                    ReadLoop(_ioBufIn, _remaining);
                    _ioBufInIndex = 0;
                    break;

                case MsgCode.MsgInfo:
                case MsgCode.MsgError:
                    if (_remaining >= line.Length)
                    {
                        throw new Exception("Multiplexing overflow " + tag + ":" + _remaining);
                    }
                    ReadLoop(line, _remaining);
                    _remaining = 0;
                    break;

                default:
                    throw new Exception("Read unknown message from stream");
                }
            }

            if (_remaining == 0)
            {
                Flush();
            }

            return(result);
        }
예제 #14
0
파일: IO.cs 프로젝트: xcrash/rsync.net
        public int ReadfdUnbuffered(byte[] data, int off, int len)
        {
            int tag, ret = 0;

            byte[] line = new byte[1024];

            if (iobuf_in == null)
            {
                return(sockIn.Read(data, off, len));
            }

            if (!IOMultiplexingIn && remaining == 0)
            {
                Flush();
                remaining    = sockIn.Read(iobuf_in, 0, iobuf_in_siz);
                iobuf_in_ndx = 0;
            }

            while (ret == 0)
            {
                if (remaining != 0)
                {
                    len = Math.Min(len, remaining);
                    Util.MemCpy(data, off, iobuf_in, iobuf_in_ndx, len);
                    iobuf_in_ndx += len;
                    remaining    -= len;
                    ret           = len;
                    break;
                }

                ReadLoop(line, 4);
                tag = (int)IVAL(line, 0);

                remaining = tag & 0xFFFFFF;
                tag       = (tag >> 24) - MPLEX_BASE;

                switch ((MsgCode)tag)
                {
                case MsgCode.MSG_DATA:
                    if (remaining > iobuf_in_siz)
                    {
                        MapFile.ReallocArray(ref iobuf_in, remaining);
                        iobuf_in_siz = remaining;
                    }
                    ReadLoop(iobuf_in, remaining);
                    iobuf_in_ndx = 0;
                    break;

                case MsgCode.MSG_INFO:
                case MsgCode.MSG_ERROR:
                    if (remaining >= line.Length)
                    {
                        throw new Exception("multiplexing overflow " + tag + ":" + remaining);
                    }
                    ReadLoop(line, remaining);
                    remaining = 0;
                    break;

                default:
                    throw new Exception("Read unknown message from stream");
                    break;
                }
            }

            if (remaining == 0)
            {
                Flush();
            }

            return(ret);
        }
예제 #15
0
        public void MatchSums(IoStream f, SumStruct s, MapFile buf, int len)
        {
            var fileSum = new byte[CheckSum.Md4SumLength];

            _lastMatch    = 0;
            _falseAlarms  = 0;
            _tagHits      = 0;
            _matches      = 0;
            _dataTransfer = 0;

            var sum = new Sum(_options);

            sum.Init(_options.ChecksumSeed);

            if (len > 0 && s.Count > 0)
            {
                BuildHashTable(s);

                if (_options.Verbose > 2)
                {
                    Log.WriteLine("built hash table");
                }

                HashSearch(f, s, buf, len, sum);

                if (_options.Verbose > 2)
                {
                    Log.WriteLine("done hash search");
                }
            }
            else
            {
                for (var j = 0; j < len - ChunkSize; j += ChunkSize)
                {
                    var n1 = Math.Min(ChunkSize, (len - ChunkSize) - j);
                    Matched(f, s, buf, j + n1, -2, sum);
                }
                Matched(f, s, buf, len, -1, sum);
            }

            fileSum = sum.End();
            if (buf != null && buf.Status)
            {
                fileSum[0]++;
            }

            if (_options.Verbose > 2)
            {
                Log.WriteLine("sending fileSum");
            }
            f.Write(fileSum, 0, CheckSum.Md4SumLength);

            _targets.Clear();

            if (_options.Verbose > 2)
            {
                Log.WriteLine("falseAlarms=" + _falseAlarms + " tagHits=" + _tagHits + " matches=" + _matches);
            }

            _totalTagHits             += _tagHits;
            _totalFalseAlarms         += _falseAlarms;
            _totalMatches             += _matches;
            Options.Stats.LiteralData += _dataTransfer;
        }
예제 #16
0
        public void HashSearch(IoStream f, SumStruct s, MapFile buf, int len, Sum _sum)
        {
            int    offset, end, backup;
            UInt32 k;
            int    wantI;
            var    sum2 = new byte[CheckSum.SumLength];
            UInt32 s1, s2, sum;
            int    more;

            byte[] map;

            wantI = 0;
            if (_options.Verbose > 2)
            {
                Log.WriteLine("hash search ob=" + s.BLength + " len=" + len);
            }

            k = (UInt32)Math.Min(len, s.BLength);
            var off = buf.MapPtr(0, (int)k);

            map = buf.P;

            var g = s.Sums[0].Sum1;

            sum = CheckSum.GetChecksum1(map, off, (int)k);
            s1  = sum & 0xFFFF;
            s2  = sum >> 16;
            if (_options.Verbose > 3)
            {
                Log.WriteLine("sum=" + sum + " k=" + k);
            }

            offset = 0;
            end    = (int)(len + 1 - s.Sums[s.Count - 1].Len);
            if (_options.Verbose > 3)
            {
                Log.WriteLine("hash search s.bLength=" + s.BLength + " len=" + len + " count=" + s.Count);
            }

            do
            {
                var t         = GetTag2(s1, s2);
                var doneCsum2 = false;
                var j         = _tagTable[t];

                if (_options.Verbose > 4)
                {
                    Log.WriteLine("offset=" + offset + " sum=" + sum);
                }

                if (j == NullTag)
                {
                    goto null_tag;
                }

                sum = (s1 & 0xffff) | (s2 << 16);
                _tagHits++;
                do
                {
                    UInt32 l;
                    var    i = _targets[j].I;

                    if (sum != s.Sums[i].Sum1)
                    {
                        continue;
                    }

                    l = (UInt32)Math.Min(s.BLength, len - offset);
                    if (l != s.Sums[i].Len)
                    {
                        continue;
                    }

                    if (_options.Verbose > 3)
                    {
                        Log.WriteLine("potential match at " + offset + " target=" + j + " " + i + " sum=" + sum);
                    }

                    if (!doneCsum2)
                    {
                        off = buf.MapPtr(offset, (int)l);
                        map = buf.P;
                        var cs = new CheckSum(_options);
                        sum2      = cs.GetChecksum2(map, off, (int)l);
                        doneCsum2 = true;
                    }

                    if (Util.MemoryCompare(sum2, 0, s.Sums[i].Sum2, 0, s.S2Length) != 0)
                    {
                        _falseAlarms++;
                        continue;
                    }

                    if (i != wantI && wantI < s.Count &&
                        (!_options.Inplace || _options.MakeBackups || s.Sums[wantI].Offset >= offset ||
                         (s.Sums[wantI].Flags & SumflgSameOffset) != 0) &&
                        sum == s.Sums[wantI].Sum1 &&
                        Util.MemoryCompare(sum2, 0, s.Sums[wantI].Sum2, 0, s.S2Length) == 0)
                    {
                        i = wantI;
                    }
                    //set_want_i:
                    wantI = i + 1;

                    Matched(f, s, buf, offset, i, _sum);
                    offset += (int)(s.Sums[i].Len - 1);
                    k       = (UInt32)Math.Min(s.BLength, len - offset);
                    off     = buf.MapPtr(offset, (int)k);
                    sum     = CheckSum.GetChecksum1(map, off, (int)k);
                    s1      = sum & 0xFFFF;
                    s2      = sum >> 16;
                    _matches++;
                    break;
                } while (++j < s.Count && _targets[j].T == t);
null_tag:
                backup = offset - _lastMatch;
                if (backup < 0)
                {
                    backup = 0;
                }

                more = (offset + k) < len ? 1 : 0;
                off  = buf.MapPtr(offset - backup, (int)(k + more + backup)) + backup;
                s1  -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CharOffset);
                s2  -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CharOffset);
                off  = (k + off >= map.Length) ? (int)(map.Length - k - 1) : off;
                if (more != 0)
                {
                    s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CharOffset);
                    s2 += s1;
                }
                else
                {
                    --k;
                }

                if (backup >= ChunkSize + s.BLength && end - offset > ChunkSize)
                {
                    Matched(f, s, buf, (int)(offset - s.BLength), -2, _sum);
                }
            } while (++offset < end);

            Matched(f, s, buf, len, -1, _sum);
            buf.MapPtr(len - 1, 1);
        }
예제 #17
0
		public void SendDeflatedToken(IOStream f, int token, MapFile buf, int offset, int nb, int toklen)
		{
		}
예제 #18
0
파일: Sender.cs 프로젝트: vmas/rsync.net
        public void SendFiles(List <FileStruct> fileList, ClientInfo clientInfo)
        {
            ShowMessage("Processing...");
            try
            {
                IOStream  ioStream = clientInfo.IoStream;
                string    fileName = String.Empty, fileName2 = String.Empty;
                SumStruct s               = null;
                int       phase           = 0;
                bool      saveMakeBackups = options.makeBackups;
                Match     match           = new Match(options);

                if (options.verbose > 2)
                {
                    Log.WriteLine("SendFiles starting");
                }
                while (true)
                {
                    fileName = String.Empty;
                    int i = ioStream.readInt();
                    if (i == -1)
                    {
                        if (phase == 0)
                        {
                            phase++;
                            checkSum.length = CheckSum.SUM_LENGTH;
                            ioStream.writeInt(-1);
                            if (options.verbose > 2)
                            {
                                Log.WriteLine("SendFiles phase=" + phase);
                            }
                            options.makeBackups = false;
                            continue;
                        }
                        break;
                    }

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

                    FileStruct file = fileList[i];

                    Options.stats.currentFileIndex = i;
                    Options.stats.numTransferredFiles++;
                    Options.stats.totalTransferredSize += file.length;

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

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

                    if (options.dryRun)
                    {
                        if (!options.amServer && options.verbose != 0)
                        {
                            Log.WriteLine(fileName2);
                        }
                        ioStream.writeInt(i);
                        continue;
                    }

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

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

                    FStat    st = new FStat();
                    FileInfo fi = new FileInfo(fileName);
                    // TODO: path length
                    st.mTime = fi.LastWriteTime;
                    // TODO: path length
                    st.size = fi.Length;

                    MapFile mbuf = null;
                    if (st.size != 0)
                    {
                        int mapSize = (int)Math.Max(s.bLength * 3, Options.MAX_MAP_SIZE);
                        mbuf = new MapFile(fd, (int)st.size, mapSize, (int)s.bLength);
                    }

                    if (options.verbose > 2)
                    {
                        Log.WriteLine("SendFiles mapped " + fileName + " of size " + st.size);
                    }

                    ioStream.writeInt(i);
                    Generator gen = new Generator(options);
                    gen.WriteSumHead(ioStream, s);

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

                    if (!options.amServer && options.verbose != 0)
                    {
                        Log.WriteLine(fileName2);
                    }

                    Token token = new Token(options);
                    token.SetCompression(fileName);

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

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

                    s.sums = null;

                    if (options.verbose > 2)
                    {
                        Log.WriteLine("sender finished " + fileName);
                    }
                }
                options.makeBackups = saveMakeBackups;

                if (options.verbose > 2)
                {
                    Log.WriteLine("send files finished");
                }

                match.MatchReport(ioStream);
                ioStream.writeInt(-1);
            }
            finally
            {
                HideMessage();
            }
        }
예제 #19
0
		public void SimpleSendToken(IOStream f,int token, MapFile buf, int offset, int n)
		{
			if (n > 0) 
			{
				int l = 0;
				while (l < n) 
				{
					int n1 = Math.Min(Match.CHUNK_SIZE,n-l);
					f.writeInt(n1);
					int off = buf.MapPtr(offset + l, n1);
					f.Write(buf.p, off, n1);					
					l += n1;
				}
			}
			if (token != -2) 
				f.writeInt(-(token+1));
		}
예제 #20
0
        public static int RsyncModule(ClientInfo cInfo, int moduleNumber)
        {
            string   path    = Daemon.config.GetModule(moduleNumber).Path;
            string   name    = Daemon.config.GetModuleName(moduleNumber);
            IOStream f       = cInfo.IoStream;
            Options  options = cInfo.Options;

            string[] args = new string[Options.MAX_ARGS];
            int      argc = 0, maxargs = Options.MAX_ARGS;
            string   line = "";

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

            Access ac = new Access();

            if (!ac.AllowAccess(options.remoteAddr, options.remoteHost, Daemon.config.GetHostsAllow(moduleNumber), Daemon.config.GetHostsDeny(moduleNumber)))
            {
                Log.Write("rsync denied on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")");
                f.IOPrintf("@ERROR: access denied to " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n");
                return(-1);
            }

            if (!Authentication.AuthServer(cInfo, moduleNumber, options.remoteAddr, "@RSYNCD: AUTHREQD "))
            {
                Log.Write("auth failed on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n");
                f.IOPrintf("@ERROR: auth failed on module " + name + "\n");
                return(-1);
            }
// TODO: path length
            if (FileSystem.Directory.Exists(path))
            {
                f.IOPrintf("@RSYNCD: OK\n");
            }
            else
            {
                try
                {
                    // TODO: path length
                    FileSystem.Directory.CreateDirectory(path);
                    f.IOPrintf("@RSYNCD: OK\n");
                }
                catch (Exception) {
                    f.IOPrintf("@ERROR: Path not found\n");
                    MainClass.Exit("@ERROR: Path not found: " + path, cInfo);
                }
            }
            options.amServer = true;                    //to fix error in SetupProtocol
            options.dir      = path;

            while (true)
            {
                line = f.ReadLine();
                line = line.Substring(0, line.Length - 1);
                if (line.CompareTo("") == 0)
                {
                    break;
                }
                if (argc == maxargs)
                {
                    maxargs += Options.MAX_ARGS;
                    MapFile.ReallocArrayString(ref args, maxargs);
                }
                args[argc++] = line;
            }
            args[argc++] = path;

            options.verbose = 0;
            int argsNotUsed = CommandLineParser.ParseArguments(args, options);

            if (argsNotUsed == -1)
            {
                MainClass.Exit("Error parsing options", cInfo);
            }
            string[] args2 = new string[argsNotUsed];
            for (int i = 0; i < argsNotUsed; i++)
            {
                args2[i] = args[args.Length - argsNotUsed + i];
            }


            MainClass.SetupProtocol(cInfo);
            f.IOStartMultiplexOut();
            Daemon.StartServer(cInfo, args2);

            return(-1);
        }
예제 #21
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);
        }
예제 #22
0
		public void MatchSums(IOStream f, SumStruct s, MapFile buf, int len)
		{
			byte[] fileSum = new byte[CheckSum.MD4_SUM_LENGTH];

			lastMatch = 0;
			falseAlarms = 0;
			tagHits = 0;
			matches = 0;
			dataTransfer = 0;

			Sum sum = new Sum(options);
			sum.Init(options.checksumSeed);

			if (len > 0 && s.count>0) 
			{
				BuildHashTable(s);

				if (options.verbose > 2)
					Log.WriteLine("built hash table");

				HashSearch(f,s,buf,len, sum);

				if (options.verbose > 2)
					Log.WriteLine("done hash search");
			} 
			else 
			{
				for (int j = 0; j < len - CHUNK_SIZE; j += CHUNK_SIZE) 
				{
					int n1 = Math.Min(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
					Matched(f,s,buf,j+n1,-2, sum);
				}
				Matched(f,s,buf,len,-1,sum);
			}

			fileSum = sum.End();
			if (buf != null && buf.status)
				fileSum[0]++;

			if (options.verbose > 2)
				Log.WriteLine("sending fileSum");
			f.Write(fileSum, 0, CheckSum.MD4_SUM_LENGTH);

			targets.Clear();

			if (options.verbose > 2)
				Log.WriteLine("falseAlarms=" +  falseAlarms + " tagHits=" + tagHits + " matches=" + matches);

			totalTagHits += tagHits;
			totalFalseAlarms += falseAlarms;
			totalMatches += matches;
			Options.stats.literalData += dataTransfer;
		}
예제 #23
0
        public void SendFiles(List<FileStruct> fileList, ClientInfo clientInfo)
        {
            ShowMessage("Processing...");
            try
            {
                IOStream ioStream = clientInfo.IoStream;
                string fileName = String.Empty, fileName2 = String.Empty;
                SumStruct s = null;
                int phase = 0;
                bool saveMakeBackups = options.makeBackups;
                Match match = new Match(options);

                if (options.verbose > 2)
                {
                    Log.WriteLine("SendFiles starting");
                }
                while (true)
                {
                    fileName = String.Empty;
                    int i = ioStream.readInt();
                    if (i == -1)
                    {
                        if (phase == 0)
                        {
                            phase++;
                            checkSum.length = CheckSum.SUM_LENGTH;
                            ioStream.writeInt(-1);
                            if (options.verbose > 2)
                            {
                                Log.WriteLine("SendFiles phase=" + phase);
                            }
                            options.makeBackups = false;
                            continue;
                        }
                        break;
                    }

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

                    FileStruct file = fileList[i];

                    Options.stats.currentFileIndex = i;
                    Options.stats.numTransferredFiles++;
                    Options.stats.totalTransferredSize += file.length;

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

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

                    if (options.dryRun)
                    {
                        if (!options.amServer && options.verbose != 0)
                        {
                            Log.WriteLine(fileName2);
                        }
                        ioStream.writeInt(i);
                        continue;
                    }

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

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

                    FStat st = new FStat();
                    FileInfo fi = new FileInfo(fileName);
                    // TODO: path length
                    st.mTime = fi.LastWriteTime;
                    // TODO: path length
                    st.size = fi.Length;

                    MapFile mbuf = null;
                    if (st.size != 0)
                    {
                        int mapSize = (int)Math.Max(s.bLength * 3, Options.MAX_MAP_SIZE);
                        mbuf = new MapFile(fd, (int)st.size, mapSize, (int)s.bLength);
                    }

                    if (options.verbose > 2)
                    {
                        Log.WriteLine("SendFiles mapped " + fileName + " of size " + st.size);
                    }

                    ioStream.writeInt(i);
                    Generator gen = new Generator(options);
                    gen.WriteSumHead(ioStream, s);

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

                    if (!options.amServer && options.verbose != 0)
                    {
                        Log.WriteLine(fileName2);
                    }

                    Token token = new Token(options);
                    token.SetCompression(fileName);

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

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

                    s.sums = null;

                    if (options.verbose > 2)
                    {
                        Log.WriteLine("sender finished " + fileName);
                    }
                }
                options.makeBackups = saveMakeBackups;

                if (options.verbose > 2)
                {
                    Log.WriteLine("send files finished");
                }

                match.MatchReport(ioStream);
                ioStream.writeInt(-1);
            }
            finally
            {
                HideMessage();
            }
        }
예제 #24
0
		public void HashSearch(IOStream f,SumStruct s, MapFile buf, int len, Sum _sum)
		{
			int offset, end, backup;
			UInt32 k;
			int wantI;
			byte[] sum2 = new byte[CheckSum.SUM_LENGTH];
			UInt32 s1, s2, sum;
			int more;
			byte[] map;
			
			wantI = 0;
			if (options.verbose > 2)
				Log.WriteLine("hash search ob=" + s.bLength +" len=" + len);

			k = (UInt32)Math.Min(len, s.bLength);
			int off = buf.MapPtr(0, (int)k);
			map = buf.p;
			
			UInt32 g = s.sums[0].sum1;
			sum = CheckSum.GetChecksum1(map, off, (int)k);
			s1 = sum & 0xFFFF;
			s2 = sum >> 16;
			if (options.verbose > 3)
				Log.WriteLine("sum=" + sum +" k=" + k);

			offset = 0;
			end = (int)(len + 1 - s.sums[s.count-1].len);
			if (options.verbose > 3)
				Log.WriteLine("hash search s.bLength=" + s.bLength +" len=" + len +" count=" + s.count);

			do 
			{
				UInt32 t = GetTag2(s1,s2);
				bool doneCsum2 = false;
				int j = tagTable[t];

				if (options.verbose > 4)
					Log.WriteLine("offset=" + offset + " sum=" + sum);

				if (j == NULL_TAG)
					goto null_tag;

				sum = (s1 & 0xffff) | (s2 << 16);
				tagHits++;
				do 
				{
					UInt32 l;
					int i = ((Target)targets[j]).i;

					if (sum != s.sums[i].sum1)
						continue;

					l = (UInt32)Math.Min(s.bLength, len-offset);
					if (l != s.sums[i].len)
						continue;

					if (options.verbose > 3)
						Log.WriteLine("potential match at " + offset + " target=" + j +" " + i + " sum=" + sum);

					if (!doneCsum2) 
					{
						off = buf.MapPtr(offset, (int)l);
						map = buf.p;
						CheckSum cs = new CheckSum(options); 
						sum2 = cs.GetChecksum2(map, off, (int)l);
						doneCsum2 = true;
					}

					if (Util.MemCmp(sum2, 0, s.sums[i].sum2, 0, s.s2Length) != 0) 
					{
						falseAlarms++;
						continue;
					}
					
					if (i != wantI && wantI < s.count
						&& (!options.inplace || options.makeBackups || s.sums[wantI].offset >= offset
						|| (s.sums[wantI].flags & SUMFLG_SAME_OFFSET) != 0)
						&& sum == s.sums[wantI].sum1
						&& Util.MemCmp(sum2, 0, s.sums[wantI].sum2, 0, s.s2Length) == 0) 
					{
						i = wantI;
					}
				set_want_i:
					wantI = i + 1;

					Matched(f,s,buf,offset,i,_sum);
					offset += (int)(s.sums[i].len - 1);
					k = (UInt32)Math.Min(s.bLength, len-offset);
					off = buf.MapPtr(offset, (int)k);					
					sum = CheckSum.GetChecksum1(map, off, (int)k);
					s1 = sum & 0xFFFF;
					s2 = sum >> 16;
					matches++;
					break;
				} while (++j < s.count && ((Target)targets[j]).t == t);								
			null_tag:
				backup = offset - lastMatch;
				if (backup < 0)
					backup = 0;

				more = (offset + k) < len ? 1 : 0;
				off = buf.MapPtr(offset - backup, (int)(k + more + backup))+ backup;				
				s1 -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET);
				s2 -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET);				
				off = (k + off >= map.Length) ? (int)(map.Length-k-1) : off;
				if (more != 0) 
				{
					s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CHAR_OFFSET);
					s2 += s1;
				} 
				else
					--k;

				if (backup >= CHUNK_SIZE + s.bLength && end - offset > CHUNK_SIZE)
					Matched(f,s,buf,(int)(offset - s.bLength), -2, _sum);
			} while (++offset < end);

			Matched(f,s,buf,len,-1, _sum);
			buf.MapPtr(len-1,1);
		}
예제 #25
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);
        }
예제 #26
0
파일: Match.cs 프로젝트: xcrash/rsync.net
        public void HashSearch(IOStream f, SumStruct s, MapFile buf, int len, Sum _sum)
        {
            int    offset, end, backup;
            UInt32 k;
            int    wantI;

            byte[] sum2 = new byte[CheckSum.SUM_LENGTH];
            UInt32 s1, s2, sum;
            int    more;

            byte[] map;

            wantI = 0;
            if (options.verbose > 2)
            {
                Log.WriteLine("hash search ob=" + s.bLength + " len=" + len);
            }

            k = (UInt32)Math.Min(len, s.bLength);
            int off = buf.MapPtr(0, (int)k);

            map = buf.p;

            UInt32 g = s.sums[0].sum1;

            sum = CheckSum.GetChecksum1(map, off, (int)k);
            s1  = sum & 0xFFFF;
            s2  = sum >> 16;
            if (options.verbose > 3)
            {
                Log.WriteLine("sum=" + sum + " k=" + k);
            }

            offset = 0;
            end    = (int)(len + 1 - s.sums[s.count - 1].len);
            if (options.verbose > 3)
            {
                Log.WriteLine("hash search s.bLength=" + s.bLength + " len=" + len + " count=" + s.count);
            }

            do
            {
                UInt32 t         = GetTag2(s1, s2);
                bool   doneCsum2 = false;
                int    j         = tagTable[t];

                if (options.verbose > 4)
                {
                    Log.WriteLine("offset=" + offset + " sum=" + sum);
                }

                if (j == NULL_TAG)
                {
                    goto null_tag;
                }

                sum = (s1 & 0xffff) | (s2 << 16);
                tagHits++;
                do
                {
                    UInt32 l;
                    int    i = ((Target)targets[j]).i;

                    if (sum != s.sums[i].sum1)
                    {
                        continue;
                    }

                    l = (UInt32)Math.Min(s.bLength, len - offset);
                    if (l != s.sums[i].len)
                    {
                        continue;
                    }

                    if (options.verbose > 3)
                    {
                        Log.WriteLine("potential match at " + offset + " target=" + j + " " + i + " sum=" + sum);
                    }

                    if (!doneCsum2)
                    {
                        off = buf.MapPtr(offset, (int)l);
                        map = buf.p;
                        CheckSum cs = new CheckSum(options);
                        sum2      = cs.GetChecksum2(map, off, (int)l);
                        doneCsum2 = true;
                    }

                    if (Util.MemCmp(sum2, 0, s.sums[i].sum2, 0, s.s2Length) != 0)
                    {
                        falseAlarms++;
                        continue;
                    }

                    if (i != wantI && wantI < s.count &&
                        (!options.inplace || options.makeBackups || s.sums[wantI].offset >= offset ||
                         (s.sums[wantI].flags & SUMFLG_SAME_OFFSET) != 0) &&
                        sum == s.sums[wantI].sum1 &&
                        Util.MemCmp(sum2, 0, s.sums[wantI].sum2, 0, s.s2Length) == 0)
                    {
                        i = wantI;
                    }
set_want_i:
                    wantI = i + 1;

                    Matched(f, s, buf, offset, i, _sum);
                    offset += (int)(s.sums[i].len - 1);
                    k       = (UInt32)Math.Min(s.bLength, len - offset);
                    off     = buf.MapPtr(offset, (int)k);
                    sum     = CheckSum.GetChecksum1(map, off, (int)k);
                    s1      = sum & 0xFFFF;
                    s2      = sum >> 16;
                    matches++;
                    break;
                } while (++j < s.count && ((Target)targets[j]).t == t);
null_tag:
                backup = offset - lastMatch;
                if (backup < 0)
                {
                    backup = 0;
                }

                more = (offset + k) < len ? 1 : 0;
                off  = buf.MapPtr(offset - backup, (int)(k + more + backup)) + backup;
                s1  -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET);
                s2  -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET);
                off  = (k + off >= map.Length) ? (int)(map.Length - k - 1) : off;
                if (more != 0)
                {
                    s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CHAR_OFFSET);
                    s2 += s1;
                }
                else
                {
                    --k;
                }

                if (backup >= CHUNK_SIZE + s.bLength && end - offset > CHUNK_SIZE)
                {
                    Matched(f, s, buf, (int)(offset - s.bLength), -2, _sum);
                }
            } while (++offset < end);

            Matched(f, s, buf, len, -1, _sum);
            buf.MapPtr(len - 1, 1);
        }
예제 #27
0
		public bool FileCheckSum(string fileName, ref byte[] sum, int size)
		{
			int i;
			MDFour m =new MDFour(options);
			sum = new byte[MD4_SUM_LENGTH];
			Stream fd;
			try
			{
				fd = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
			} catch(Exception)
			{
				return false;
			}
			MapFile buf = new MapFile(fd, size, Options.MAX_MAP_SIZE, CSUM_CHUNK);
			m.Begin();

			for(i = 0; i + CSUM_CHUNK <= size; i += CSUM_CHUNK) 
			{
				int offset = buf.MapPtr(i, CSUM_CHUNK);
				m.Update(buf.p, offset, CSUM_CHUNK);
			}

			if (size - i > 0 || options.protocolVersion >= 27)
			{
				int offset = buf.MapPtr(i, size-i);
				m.Update(buf.p, offset, (UInt32)(size-i));
			}

			sum = m.Result();

			fd.Close();
			buf.UnMapFile();
			return true;
		}