예제 #1
0
        public void BuildHashTable(SumStruct s)
        {
            for (var i = 0; i < s.Count; i++)
            {
                _targets.Add(new Target());
            }

            for (var i = 0; i < s.Count; i++)
            {
                _targets[i].I = i;
                _targets[i].T = GetTag(s.Sums[i].Sum1);
            }

            _targets.Sort(0, s.Count, new TargetComparer());

            for (var i = 0; i < Tablesize; i++)
            {
                _tagTable[i] = NullTag;
            }


            for (var i = s.Count; i-- > 0;)
            {
                _tagTable[_targets[i].T] = i;
            }
        }
예제 #2
0
파일: Match.cs 프로젝트: xcrash/rsync.net
        public void BuildHashTable(SumStruct s)
        {
            for (int i = 0; i < s.count; i++)
            {
                targets.Add(new Target());
            }

            for (int i = 0; i < s.count; i++)
            {
                ((Target)targets[i]).i = i;
                ((Target)targets[i]).t = GetTag(s.sums[i].sum1);
            }

            targets.Sort(0, s.count, new TargetComparer());

            for (int i = 0; i < TABLESIZE; i++)
            {
                tagTable[i] = NULL_TAG;
            }


            for (int i = s.count; i-- > 0;)
            {
                tagTable[((Target)targets[i]).t] = i;
            }
        }
예제 #3
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);
		} 
예제 #4
0
파일: Generator.cs 프로젝트: vmas/rsync.net
 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);
 }
예제 #5
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);
 }
예제 #6
0
        public SumStruct ReceiveSums(ClientInfo cInfo)
        {
            var f = cInfo.IoStream;
            var s = new SumStruct();
            int i;
            var offset = 0;

            ReadSumHead(cInfo, ref s);
            s.Sums = null;

            if (_options.Verbose > 3)
            {
                Log.WriteLine("count=" + s.Count + " n=" + s.BLength + " rem=" + s.Remainder);
            }

            if (s.Count == 0)
            {
                return(s);
            }

            s.Sums = new SumBuf[s.Count];

            for (i = 0; i < s.Count; i++)
            {
                s.Sums[i]        = new SumBuf();
                s.Sums[i].Sum1   = (UInt32)f.ReadInt();
                s.Sums[i].Sum2   = f.ReadBuffer(s.S2Length);
                s.Sums[i].Offset = offset;
                s.Sums[i].Flags  = 0;

                if (i == s.Count - 1 && s.Remainder != 0)
                {
                    s.Sums[i].Len = s.Remainder;
                }
                else
                {
                    s.Sums[i].Len = s.BLength;
                }
                offset += (int)s.Sums[i].Len;

                if (_options.Verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] len=" + s.Sums[i].Len);
                }
            }

            s.FLength = offset;
            return(s);
        }
예제 #7
0
파일: Sender.cs 프로젝트: vmas/rsync.net
        public SumStruct ReceiveSums(ClientInfo cInfo)
        {
            IOStream  f = cInfo.IoStream;
            SumStruct s = new SumStruct();
            int       i;
            int       offset = 0;

            ReadSumHead(cInfo, ref s);
            s.sums = null;

            if (options.verbose > 3)
            {
                Log.WriteLine("count=" + s.count + " n=" + s.bLength + " rem=" + s.remainder);
            }

            if (s.count == 0)
            {
                return(s);
            }

            s.sums = new SumBuf[s.count];

            for (i = 0; i < s.count; i++)
            {
                s.sums[i]        = new SumBuf();
                s.sums[i].sum1   = (UInt32)f.readInt();
                s.sums[i].sum2   = f.ReadBuffer(s.s2Length);
                s.sums[i].offset = offset;
                s.sums[i].flags  = 0;

                if (i == s.count - 1 && s.remainder != 0)
                {
                    s.sums[i].len = s.remainder;
                }
                else
                {
                    s.sums[i].len = s.bLength;
                }
                offset += (int)s.sums[i].len;

                if (options.verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] len=" + s.sums[i].len);
                }
            }

            s.fLength = offset;
            return(s);
        }
예제 #8
0
        public void Matched(IoStream f, SumStruct s, MapFile buf, int offset, int i, Sum sum)
        {
            var 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);
            }

            var 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 += ChunkSize)
            {
                var n1  = Math.Min(ChunkSize, n - j);
                var 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);
                }
            }
        }
예제 #9
0
파일: Match.cs 프로젝트: xcrash/rsync.net
        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);
                }
            }
        }
예제 #10
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;
            }
        }
예제 #11
0
파일: Generator.cs 프로젝트: vmas/rsync.net
        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
        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();
        }
예제 #13
0
파일: Sender.cs 프로젝트: vmas/rsync.net
        public void ReadSumHead(ClientInfo clientInfo, ref SumStruct sum)
        {
            IOStream ioStream = clientInfo.IoStream;

            sum.count   = ioStream.readInt();
            sum.bLength = (UInt32)ioStream.readInt();
            if (options.protocolVersion < 27)
            {
                sum.s2Length = checkSum.length;
            }
            else
            {
                sum.s2Length = ioStream.readInt();
                if (sum.s2Length > CheckSum.MD4_SUM_LENGTH)
                {
                    MainClass.Exit("Invalid checksum length " + sum.s2Length, clientInfo);
                }
            }
            sum.remainder = (UInt32)ioStream.readInt();
        }
예제 #14
0
		public void BuildHashTable(SumStruct s)
		{
			for(int i = 0; i < s.count; i++)
				targets.Add(new Target());

			for (int i = 0; i < s.count; i++) 
			{
				((Target)targets[i]).i = i;
				((Target)targets[i]).t = GetTag(s.sums[i].sum1);
			}

			targets.Sort(0, s.count, new TargetComparer());

			for (int i = 0; i < TABLESIZE; i++)
				tagTable[i] = NULL_TAG;

			
			for (int i = s.count; i-- > 0;)  
			{
				tagTable[((Target)targets[i]).t] = i;
			}
		}
예제 #15
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);
		}
예제 #16
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);
			}
		}
예제 #17
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;
		}
예제 #18
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;
        }
예제 #19
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();
            }
        }
예제 #20
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;
        }
예제 #21
0
 public void ReadSumHead(ClientInfo clientInfo, ref SumStruct sum)
 {
     IOStream ioStream = clientInfo.IoStream;
     sum.count = ioStream.readInt();
     sum.bLength = (UInt32)ioStream.readInt();
     if (options.protocolVersion < 27)
     {
         sum.s2Length = checkSum.length;
     }
     else
     {
         sum.s2Length = ioStream.readInt();
         if (sum.s2Length > CheckSum.MD4_SUM_LENGTH)
         {
             MainClass.Exit("Invalid checksum length " + sum.s2Length, clientInfo);
         }
     }
     sum.remainder = (UInt32)ioStream.readInt();
 }
예제 #22
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);
        }
예제 #23
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);
        }
예제 #24
0
        public void SumSizesSqroot(SumStruct sum, UInt64 len)
        {
            UInt32 bLength;
            int    s2Length;
            UInt32 c;
            UInt64 l;

            if (_options.BlockSize != 0)
            {
                bLength = (UInt32)_options.BlockSize;
            }
            else
            if (len <= Options.MaxBlockSize * Options.MaxBlockSize)
            {
                bLength = Options.MaxBlockSize;
            }
            else
            {
                l = len;
                c = 1;
                while ((l = (l >> 1)) != 0)
                {
                    c <<= 1;
                }
                bLength = 0;
                do
                {
                    bLength |= c;
                    if (len < bLength * bLength)
                    {
                        bLength &= ~c;
                    }
                    c >>= 1;
                } while (c >= 8);       /* round to multiple of 8 */
                bLength = Math.Max(bLength, Options.MaxBlockSize);
            }

            if (_options.ProtocolVersion < 27)
            {
                s2Length = _checkSum.Length;
            }
            else
            {
                if (_checkSum.Length == CheckSum.SumLength)
                {
                    s2Length = CheckSum.SumLength;
                }
                else
                {
                    var b = BlocksumBias;
                    l = len;
                    while ((l = (l >> 1)) != 0)
                    {
                        b += 2;
                    }
                    c = bLength;
                    while ((c = (c >> 1)) != 0 && b != 0)
                    {
                        b--;
                    }
                    s2Length = (b + 1 - 32 + 7) / 8;
                    s2Length = Math.Max(s2Length, _checkSum.Length);
                    s2Length = Math.Min(s2Length, CheckSum.SumLength);
                }
            }

            sum.FLength   = (int)len;
            sum.BLength   = bLength;
            sum.S2Length  = s2Length;
            sum.Count     = (int)((len + (bLength - 1)) / bLength);
            sum.Remainder = (UInt32)(len % bLength);

            if (sum.Count != 0 && _options.Verbose > 2)
            {
                Log.WriteLine("count=" + sum.Count + " rem=" + sum.Remainder + " blength=" + sum.BLength +
                              " s2length=" + sum.S2Length + " flength=" + sum.FLength);
            }
        }
예제 #25
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);
        }
예제 #26
0
        public void SumSizesSqroot(SumStruct sum, UInt64 len)
        {
            UInt32 bLength;
            int s2Length;
            UInt32 c;
            UInt64 l;

            if (options.blockSize != 0)
            {
                bLength = (UInt32)options.blockSize;
            }
            else
                if (len <= Options.BLOCK_SIZE * Options.BLOCK_SIZE)
                {
                    bLength = Options.BLOCK_SIZE;
                }
                else
                {
                    l = len;
                    c = 1;
                    while ((l = (l >> 1)) != 0)
                    {
                        c <<= 1;
                    }
                    bLength = 0;
                    do
                    {
                        bLength |= c;
                        if (len < bLength * bLength)
                        {
                            bLength &= ~c;
                        }
                        c >>= 1;
                    } while (c >= 8);	/* round to multiple of 8 */
                    bLength = Math.Max(bLength, Options.BLOCK_SIZE);
                }

            if (options.protocolVersion < 27)
            {
                s2Length = checkSum.length;
            }
            else
            {
                if (checkSum.length == CheckSum.SUM_LENGTH)
                {
                    s2Length = CheckSum.SUM_LENGTH;
                }
                else
                {
                    int b = BLOCKSUM_BIAS;
                    l = len;
                    while ((l = (l >> 1)) != 0)
                    {
                        b += 2;
                    }
                    c = bLength;
                    while ((c = (c >> 1)) != 0 && b != 0)
                    {
                        b--;
                    }
                    s2Length = (b + 1 - 32 + 7) / 8;
                    s2Length = Math.Max(s2Length, checkSum.length);
                    s2Length = Math.Min(s2Length, CheckSum.SUM_LENGTH);
                }
            }

            sum.fLength = (int)len;
            sum.bLength = bLength;
            sum.s2Length = s2Length;
            sum.count = (int)((len + (bLength - 1)) / bLength);
            sum.remainder = (UInt32)(len % bLength);

            if (sum.count != 0 && options.verbose > 2)
            {
                Log.WriteLine("count=" + sum.count + " rem=" + sum.remainder + " blength=" + sum.bLength +
                    " s2length=" + sum.s2Length + " flength=" + sum.fLength);
            }
        }
예제 #27
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;
        }
예제 #28
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);
        }
예제 #29
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;
            }
        }
예제 #30
0
        public SumStruct ReceiveSums(ClientInfo cInfo)
        {
            IOStream f = cInfo.IoStream;
            SumStruct s = new SumStruct();
            int i;
            int offset = 0;
            ReadSumHead(cInfo, ref s);
            s.sums = null;

            if (options.verbose > 3)
            {
                Log.WriteLine("count=" + s.count + " n=" + s.bLength + " rem=" + s.remainder);
            }

            if (s.count == 0)
            {
                return s;
            }

            s.sums = new SumBuf[s.count];

            for (i = 0; i < s.count; i++)
            {
                s.sums[i] = new SumBuf();
                s.sums[i].sum1 = (UInt32)f.readInt();
                s.sums[i].sum2 = f.ReadBuffer(s.s2Length);
                s.sums[i].offset = offset;
                s.sums[i].flags = 0;

                if (i == s.count - 1 && s.remainder != 0)
                {
                    s.sums[i].len = s.remainder;
                }
                else
                {
                    s.sums[i].len = s.bLength;
                }
                offset += (int)s.sums[i].len;

                if (options.verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] len=" + s.sums[i].len);
                }
            }

            s.fLength = offset;
            return s;
        }
예제 #31
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();
            }
        }
예제 #32
0
파일: Generator.cs 프로젝트: vmas/rsync.net
        public void SumSizesSqroot(SumStruct sum, UInt64 len)
        {
            UInt32 bLength;
            int    s2Length;
            UInt32 c;
            UInt64 l;

            if (options.blockSize != 0)
            {
                bLength = (UInt32)options.blockSize;
            }
            else
            if (len <= Options.BLOCK_SIZE * Options.BLOCK_SIZE)
            {
                bLength = Options.BLOCK_SIZE;
            }
            else
            {
                l = len;
                c = 1;
                while ((l = (l >> 1)) != 0)
                {
                    c <<= 1;
                }
                bLength = 0;
                do
                {
                    bLength |= c;
                    if (len < bLength * bLength)
                    {
                        bLength &= ~c;
                    }
                    c >>= 1;
                } while (c >= 8);       /* round to multiple of 8 */
                bLength = Math.Max(bLength, Options.BLOCK_SIZE);
            }

            if (options.protocolVersion < 27)
            {
                s2Length = checkSum.length;
            }
            else
            {
                if (checkSum.length == CheckSum.SUM_LENGTH)
                {
                    s2Length = CheckSum.SUM_LENGTH;
                }
                else
                {
                    int b = BLOCKSUM_BIAS;
                    l = len;
                    while ((l = (l >> 1)) != 0)
                    {
                        b += 2;
                    }
                    c = bLength;
                    while ((c = (c >> 1)) != 0 && b != 0)
                    {
                        b--;
                    }
                    s2Length = (b + 1 - 32 + 7) / 8;
                    s2Length = Math.Max(s2Length, checkSum.length);
                    s2Length = Math.Min(s2Length, CheckSum.SUM_LENGTH);
                }
            }

            sum.fLength   = (int)len;
            sum.bLength   = bLength;
            sum.s2Length  = s2Length;
            sum.count     = (int)((len + (bLength - 1)) / bLength);
            sum.remainder = (UInt32)(len % bLength);

            if (sum.count != 0 && options.verbose > 2)
            {
                Log.WriteLine("count=" + sum.count + " rem=" + sum.remainder + " blength=" + sum.bLength +
                              " s2length=" + sum.s2Length + " flength=" + sum.fLength);
            }
        }