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; }
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); } }
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(); } }