public Operation(String filePath, String sessionId, long fileLength, DateTime lastWritten, ref TcpComm.Utilities.TcpStream ds) { this.filePath = filePath; this.sessionId = sessionId; this.sessionName = Regex.Split(sessionId, @"\\")[0]; this.dataStreamId = Regex.Split(sessionId, @"\\")[1]; this.length = fileLength; this.lastWritten = lastWritten; this.dataStream = ds; complete = false; String thisFolder = Path.GetDirectoryName(filePath); if (File.Exists(filePath)) { thisFile = new FileInfo(filePath); if (lastWritten.Equals(thisFile.LastWriteTime) && length == thisFile.Length) { throw new Exception("This file (" + Path.GetFileName(filePath) + ") has not been modified since the last transfer attempt."); } } try { if (!Directory.Exists(thisFolder)) { Directory.CreateDirectory(thisFolder); } fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); } catch (Exception ex) { throw new Exception(ex.Message); } running = true; lastbytesIn = DateTime.Now; new Thread(() => { while (running) { if (DateTime.Now > lastbytesIn.AddSeconds(15) || dataStream.State == TcpComm.Utilities.TcpStream.StreamState.Closed) { break; } Thread.Sleep(1); if (bytesIn.Count > 0) { while (bytesIn.Count > 0 && running) { try { lock (bytesLocker) { fs.Write(bytesIn[0].bytesIn, 0, bytesIn[0].numToWrite); bytesIn.RemoveAt(0); lastbytesIn = DateTime.Now; } } catch (Exception) { running = false; } } } } if (!complete) { Abort(); } }).Start(); }
private void DataHandler(Object pd) { PacketData data = (PacketData)pd; byte[] buffer = data.bytes; int numBytesContained = data.numBytes; String sessionId = data.sId; String errMsg = ""; if (buffer == null) { callback(((data.sId != "") ? (data.sId + ": ") : "") + data._tag); return; } if (numBytesContained < 1000) { String msg = TcpComm.Utilities.BytesToString(buffer, numBytesContained); if (msg.StartsWith("<command=")) { if (msg.StartsWith("<command=kill>")) { msg = msg.Replace("<command=kill>", ""); Operation o = null; foreach (KeyValuePair <String, Operation> op in operations) { if (op.Value.dataStreamId.Equals(msg)) { o = op.Value; break; } } if (o != null) { o.Close(0); } return; } if (msg.StartsWith("<command=setpath>")) { msg = msg.Replace("<command=setpath>", ""); currentFolder = msg; } if (msg.StartsWith("<command=new>")) { Operation o = null; String thisPath = ""; String thisTargetFolder = ""; long thisLength = 0; DateTime lastWriteTime = DateTime.Parse("1/1/1970"); if (msg.Contains("<length>")) { thisPath = Regex.Split(msg, "<length>")[1]; thisPath = Regex.Split(thisPath, @"</length>")[0]; try { thisLength = long.Parse(thisPath); thisPath = ""; } catch (Exception) { server.SendText("new:failed: Could not read the file length from the create new command.", Regex.Split(sessionId, @"\\")[0], Regex.Split(sessionId, @"\\")[1], ref errMsg); return; } } if (msg.Contains("<targetfolder>")) { thisTargetFolder = Regex.Split(msg, "<targetfolder>")[1]; thisTargetFolder = Regex.Split(thisTargetFolder, @"</targetfolder>")[0]; if (!Directory.Exists(thisTargetFolder)) { server.SendText("new:failed: The target folder does not exist on the server.", Regex.Split(sessionId, @"\\")[0], Regex.Split(sessionId, @"\\")[1], ref errMsg); return; } } else { thisTargetFolder = currentFolder; } if (msg.Contains("<date>")) { thisPath = Regex.Split(msg, "<date>")[1]; thisPath = Regex.Split(thisPath, @"</date>")[0]; try { lastWriteTime = DateTime.Parse(thisPath); thisPath = ""; } catch (Exception) { server.SendText("new:failed: Could not read the last written time from the create new command.", Regex.Split(sessionId, @"\\")[0], Regex.Split(sessionId, @"\\")[1], ref errMsg); return; } } if (msg.Contains("<path>")) { thisPath = Regex.Split(msg, "<path>")[1]; thisPath = Regex.Split(thisPath, @"</path>")[0]; } if (operations.TryRemove(sessionId, out o)) { if (o != null) { try { o.Abort(); } catch (Exception) { } o = null; } } if (o != null) { try { o.Abort(); } catch (Exception) { } o = null; } // Check to make sure this transfer isn't happening in another datastream: foreach (KeyValuePair <String, Operation> op in operations) { // If we ARE: if (op.Value.filePath.ToLower().Equals(Path.Combine(thisTargetFolder, thisPath.TrimStart(new char[] { '\\' })).ToLower())) { // Remove that operation from the collection, operations.TryRemove(op.Key, out o); // and Abort it. op.Value.Abort(); // Set our operation obkect to null o = null; // And exit the iterator. break; } } try { TcpComm.Utilities.TcpStream thisStream = null; TcpComm.Server.Session thisSession = null; if (server.GetSession(ref thisSession, Regex.Split(sessionId, @"\\")[0])) { if (thisSession.dataStreamCollection.TryGetValue(Regex.Split(sessionId, @"\\")[1], out thisStream)) { o = new Operation(Path.Combine(thisTargetFolder, thisPath.TrimStart(new char[] { '\\' })), sessionId, thisLength, lastWriteTime, ref thisStream); if (operations.TryAdd(sessionId, o)) { server.SendText("new:ok", o.sessionName, o.dataStreamId, ref errMsg); } else { server.SendText("new:failed: Could not add this operation to the collection.", Regex.Split(sessionId, @"\\")[0], Regex.Split(sessionId, @"\\")[1], ref errMsg); } } } else { server.SendText("new:failed: The session could not be retrieved.", Regex.Split(sessionId, @"\\")[1], ref errMsg); } } catch (Exception ex) { server.SendText("new:failed:" + ex.Message, Regex.Split(sessionId, @"\\")[0], Regex.Split(sessionId, @"\\")[1], ref errMsg); } } if (msg.StartsWith("<command=complete>")) { Operation o; long thisFileSize = -1; msg = msg.Replace("<command=complete>", ""); long.TryParse(msg, out thisFileSize); if (operations.TryRemove(sessionId, out o)) { if (o.Close(thisFileSize)) { server.SendText("complete:ok", o.sessionName, o.dataStreamId, ref errMsg); } else { server.SendText("complete:failed", o.sessionName, o.dataStreamId, ref errMsg); } } else { server.SendText("complete:failed", Regex.Split(sessionId, @"\\")[0], Regex.Split(sessionId, @"\\")[1], ref errMsg); } } if (msg.StartsWith("<command=abort>")) { Operation o; if (operations.TryRemove(sessionId, out o)) { o.Abort(); server.SendText("complete:ok", o.sessionName, o.dataStreamId, ref errMsg); } } } else { // These are just bytes of the file: write them. WriteBytes(sessionId, ref buffer, numBytesContained); } } else { // These are just bytes of the file: write them. WriteBytes(sessionId, ref buffer, numBytesContained); } }