/// <summary> /// Called to open the file. /// </summary> /// <param name="node">The node that represents the file.</param> /// <param name="sessionID">The unique session ID.</param> protected void Open(BaseFileNode node, string sessionID) { SetupFileNames(node, sessionID); Log.log.Debug("Opening File {0} (OutFile Open)", file); try { FileInfo fi = new FileInfo(file); if (Store.IsEnterpriseServer || fi.Length > (1024 * 100000)) { workStream = new StreamStream(File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read)); workFile = null; } else { // This file is being pushed make a copy to work from. File.Copy(file, workFile, true); File.SetAttributes(workFile, FileAttributes.Normal); workStream = new StreamStream(File.Open(workFile, FileMode.Open, FileAccess.Read)); } } catch (FileNotFoundException e1) { // got an exception - mostly File not found Log.log.Info("IOException for file {2} \n.{0}--{1}, setting Stream to NULL", e1.Message, e1.StackTrace, file); workStream = null; workFile = null; } }
/// <summary> /// Constructor for Hash Map to create from Collection and Node /// </summary> /// <param name="collection">Collection to create hashmap</param> /// <param name="node">File node to add</param> public HashMap(Collection collection, BaseFileNode node) { this.collection = collection; this.node = node; file = Path.Combine(collection.ManagedPath, MapFilePrefix + node.ID); this.mapState = false; }
/// <summary> /// Checks for a name conflict. /// </summary> /// <returns>True if conflict.</returns> protected bool CheckForNameConflict() { if (!NameConflict) { // Look up the FsPath property (StoreFileNodes don't have this property set). Property property = node.Properties.GetSingleProperty(PropertyTags.FileSystemPath); if (property != null) { string path = property.Value.ToString(); ICSList nodeList; nodeList = collection.Search(PropertyTags.FileSystemPath, path, SearchOp.Equal); foreach (ShallowNode sn in nodeList) { FileNode localFileNode = new FileNode(collection.GetNodeByID(sn.ID)); // Set name conflict true if both file doesn't match if (sn.ID != node.ID && String.Compare(new FileNode(node).GetRelativePath(), localFileNode.GetRelativePath(), false) != 0) { conflictingNode = collection.GetNodeByID(sn.ID); nameConflict = true; break; } } // Now make sure we don't have any illegal characters. if (!IsNameValid(path)) { nameConflict = true; } if (nameConflict) { node = Conflict.CreateNameConflict(collection, node) as BaseFileNode; file = Conflict.GetFileConflictPath(collection, node); if (conflictingNode != null) { string cnPath; FileNode tmpFn = conflictingNode as FileNode; DirNode tmpDn = conflictingNode as DirNode; if (tmpFn != null) { cnPath = tmpFn.GetFullPath(collection); } else { cnPath = tmpDn.GetFullPath(collection); } conflictingNode = Conflict.CreateNameConflict(collection, conflictingNode, cnPath); Conflict.LinkConflictingNodes(conflictingNode, node); } } } } return(nameConflict); }
/// <summary> /// Delete ther file and map file. /// </summary> /// <param name="collection">The collection that the node belongs to.</param> /// <param name="node">The node that represents the file.</param> /// <param name="path">The full path to the file.</param> public static void DeleteFile(Collection collection, BaseFileNode node, string path) { if (File.Exists(path)) { File.Delete(path); } try { // Now delete the map file. HashMap.Delete(collection, node); } catch {} }
/// <summary> /// Called to check if the file passes the policy. /// </summary> /// <param name="fNode">The node to check.</param> /// <returns>True if node passes policy.</returns> public bool Allowed(BaseFileNode fNode) { long fSize = fNode.Length; /* If the file is already present on the server, upload size would be * size of file on the server subtracted by size of file to upload */ Store stl = Store.GetStore(); Domain dom = stl.GetDomain(stl.DefaultDomain); Node n1 = dom.GetNodeByID(fNode.ID); if (n1 != null) { FileNode f1 = n1 as FileNode; if (f1.Length <= fSize) { fSize = fSize - f1.Length; } else { fSize = 0; } } if (!GroupDiskQuotaUploadAllowed(fSize)) { reason = PolicyType.Quota; return(false); } if (!dsQuota.Allowed(fSize)) { reason = PolicyType.Quota; return(false); } if (!fsFilter.Allowed(fSize)) { reason = PolicyType.Size; return(false); } if (!ftFilter.Allowed(fNode.GetFileName())) { reason = PolicyType.Type; return(false); } return(true); }
public void BasicNodeInformationIsCorrect() { AbstractFileNode resultNode = new BaseFileNode(); const string content = "this is a##test"; const string rawContent = @" " + content + " #comment"; const int lineNumber = 0; var expectedContentRange = RangeExtensions.From(lineNumber, 4, 19); var expectedCommentRange = RangeExtensions.From(lineNumber, 19, 28); var expectedIndentationRange = RangeExtensions.From(lineNumber, 0, 4); var file = new SkriptFile(new Uri("memory://tests")); NodeContentHelper.ApplyBasicNodeInfoToNode(rawContent, lineNumber, file, ref resultNode); Assert.Equal(content, resultNode.NodeContent); Assert.Equal(expectedContentRange, resultNode.ContentRange); Assert.Equal(expectedCommentRange, resultNode.CommentRange); Assert.Equal(expectedIndentationRange, resultNode.IndentationRange); Assert.Equal(new[] { new NodeIndentation(IndentType.Space, 4) }, resultNode.Indentations); Assert.Single(resultNode.Indentations); }
/// <summary> /// Called to get the name of the file and workFile; /// </summary> /// <param name="node">The node that represents the file.</param> /// <param name="sessionID">The unique session ID.</param> protected void SetupFileNames(BaseFileNode node, string sessionID) { this.node = node; this.nodeID = node.ID; try { this.file = node.GetFullPath(collection); } catch { // If this failed the file name has illegal characters. nameConflict = true; } if (workBin == null) { workBin = Path.Combine(collection.StorePath, workBinDir); if (!Directory.Exists(workBin)) { Directory.CreateDirectory(workBin); } } this.workFile = Path.Combine(workBin, WorkFilePrefix + node.ID + sessionID); }
//--------------------------------------------------------------------------- /// <summary> /// resolve update conflict and commit /// </summary> public void Resolve(bool localChangesWin) { if (conflictNode == null) { return; } if (localChangesWin) { string ucp = UpdateConflictPath; if (ucp != null) { File.Delete(ucp); } node = collection.ResolveCollision(node, conflictNode.LocalIncarnation, true); collection.Commit(node); Log.log.Debug("Local changes win in conflict for {0} node {1}", node.Type, node.Name); return; } // conflict node wins // we may be resolving an update conflict on a node that has a naming conflict string path = NonconflictedPath, fncpath = null; FileInfo fInfo = null; Log.log.Debug("Resolve conflict file ServerChangesWin"); if (path != null) { try { FileNode fileNode = (FileNode)this.node; string fileName = fileNode.GetFullPath(collection); Log.log.Debug("Resolve conflict file name :{0}", fileName); FileNode CNode = (FileNode)this.conflictNode; string Conflictname = CNode.GetFullPath(collection); Log.log.Debug("Resolve conflict Conflict file name :{0}", Conflictname); Log.log.Debug("Resolve conflict Delete File :{0}", fileName); //Delete this client's(local) file File.Delete(fileName); Log.log.Debug("Resolve conflict UpdateConflictPath :{0}", UpdateConflictPath); if (String.Compare(fileName, Conflictname, false) != 0) { Log.log.Debug("Resolve conflict file nameand conflict file name match not found between '{0}'....to.....'{1}'", fileName, Conflictname); Log.log.Debug("Resolve conflict move from '{0}' ....to....'{1}'", UpdateConflictPath, Conflictname); //Move the server file //use the server name File.Move(UpdateConflictPath, Conflictname); fInfo = new FileInfo(Conflictname); } else { Log.log.Debug("Resolve conflict file nameand conflict file name match found between '{0}'....to.....'{1}'", fileName, fileName); Log.log.Debug("Resolve conflict move from '{0}' ....to....'{1}'", UpdateConflictPath, fileName); //Move the server file use the lcoal name File.Move(UpdateConflictPath, fileName); fInfo = new FileInfo(fileName); } Log.log.Debug("Resolve conflict server changed has won"); } catch (Exception ne) { Log.log.Debug("Could not move update conflict file to {0}: {1}", path, ne.Message); fncpath = FileNameConflictPath; File.Delete(fncpath); File.Move(UpdateConflictPath, fncpath); } } node = collection.ResolveCollision(node, conflictNode.LocalIncarnation, false); if (fncpath != null) { Log.log.Debug("Resolve conflict(we may be resolving an update conflict on a node that has a naming conflict) fncpath: {0}", fncpath); node = CreateNameConflict(collection, node, path); } if (fInfo != null) { BaseFileNode bfn = node as BaseFileNode; if (bfn != null) { fInfo.CreationTime = bfn.CreationTime; fInfo.LastWriteTime = bfn.LastWriteTime; } } conflictNode = null; collection.Commit(node); Log.log.Debug("Master update wins in conflict for {0} node {1}", node.Type, node.Name); }
/// <summary> /// Gets the file name for an update conflict. /// </summary> /// <param name="collection">The collection the node belongs to.</param> /// <param name="bfn">The BaseFile Node.</param> /// <returns>The path for the conflict file.</returns> public static string GetUpdateConflictPath(Collection collection, BaseFileNode bfn) { return(Path.Combine(ConflictBin, ConflictUpdatePrefix + bfn.ID + Path.GetExtension(bfn.Name))); }
/// <summary> /// Delete the hash map matching collection and node /// </summary> /// <param name="collection">Collection which has to be removed from hash map</param> /// <param name="node">Node which has to be removed</param> internal static void Delete(Collection collection, BaseFileNode node) { new HashMap(collection, node).Delete(); }
/// <summary> /// Removes this node from the stored policy state. /// </summary> /// <param name="fNode">The node to remove.</param> public void Remove(BaseFileNode fNode) { dsQuota.Allowed(-fNode.Length); }
/// <summary> /// Constructs a ServerFile object that can be used to sync a file in from a client. /// </summary> /// /// <param name="collection">The collection the node belongs to.</param> /// <param name="node">The node to sync down</param> public ServerOutFile(Collection collection, BaseFileNode node) : base(collection) { this.node = node; map = new HashMap(collection, node); }
/// <summary> /// Called to open the file. /// </summary> /// <param name="node">The node that represents the file.</param> protected void Open(BaseFileNode node) { SetupFileNames(node, ""); CheckForNameConflict(); Log.log.Debug("Opening File {0} (InFile Open)", file); // Open the file so that it cannot be modified. oldNode = collection.GetNodeByID(node.ID) as BaseFileNode; try { if (!NameConflict) { stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None); } } catch (FileNotFoundException) { Log.log.Debug("file {0} not found", file); // Check to see if we have a partially downloaded file to delta sync with. if (collection.Role == SyncRoles.Slave && File.Exists(workFile)) { if (File.Exists(partialFile)) { File.Delete(partialFile); } partialFile = workFile + ".part"; try { File.Move(workFile, partialFile); } catch (Exception e) { try { Log.log.Debug("could not move the file, so copy/deleting the source file: {0}. Message: {1} stack: {2}", workFile, e.Message, e.StackTrace); File.Copy(workFile, partialFile); File.Delete(workFile); } catch { File.Delete(workFile); Log.log.Debug("exception while copying workfile so deleted."); //throw e; } } if (File.Exists(partialFile)) { stream = File.Open(partialFile, FileMode.Open, FileAccess.Read, FileShare.None); } Log.log.Debug("file {0} opened", partialFile); } else if (oldNode != null) { // The file may have been renamed. string oldPath = oldNode.GetFullPath(collection); if (oldPath != file) { stream = File.Open(oldPath, FileMode.Open, FileAccess.Read, FileShare.None); Log.log.Debug("file {0} opened", oldPath); isServerFileRenamed = true; } } else { Log.log.Debug("file not {0} opened", file); } } catch (IOException e1) { try { string Fullpath = file; string rootNode = collection.GetRootDirectory().GetFullPath(collection); rootNode = Path.GetDirectoryName(rootNode); int rootPathLength = rootNode.Length; //int fullPathLength = Fullpath.Length; string Relativepath = Fullpath.Substring(rootPathLength); //Relative Path excluding FileName Relativepath = Path.GetDirectoryName(Relativepath); //bool pathExists = false; bool pathCreated = false; //Array of relative parth directory char[] delimiterList = { '/' }; string[] dirArray = Relativepath.Split(delimiterList); string tempPath = rootNode; //Maintaining progressive relative path, starting from root string FsPath = null; //List of node matching the Search criteria ICSList nodeList = null; foreach (string dir in dirArray) { if (FsPath != null) { //Creating incremental path, starting form Parent, excluding system path FsPath = Path.Combine(FsPath, dir); } else { FsPath = dir; //Initilizing if atleast on directory exist pathCreated = true; } //Creating incremental path, including system path tempPath = Path.Combine(tempPath, dir); //Verify if Directory exists, starting for root parent if (!System.IO.Directory.Exists(tempPath)) { //Verify if directory node exisit, then only create actual directory nodeList = collection.Search(PropertyTags.FileSystemPath, FsPath, SearchOp.Equal); if (nodeList != null) { //Create directory as Node exist System.IO.Directory.CreateDirectory(tempPath); } else { pathCreated = false; Log.log.Debug("Node doesn't exist for path:{0}", FsPath); //As parent node doesn't exist, no need to iterate for child break; } } } if (pathCreated == true) { Log.log.Debug("Final path created is :{0}", tempPath); } } catch (Exception excep) { Log.log.Info("Exception while re-creating missing directory: message {0}-- stacktrace:{1}", excep.Message, excep.StackTrace); } //throw below exception to log the failure Log.log.Info("IOException.{0}--{1}. The file is already open by some other thread.", e1.Message, e1.StackTrace); throw; } // Create the file in the parent directory and then move to the work area. // This will insure that the proper attributes are set. // This was added to support EFS (Encrypted File System). string createName = Path.Combine(Path.GetDirectoryName(file), Path.GetFileName(workFile)); FileStream tmpStream = File.Open(createName, FileMode.Create, FileAccess.ReadWrite, FileShare.None); if (File.Exists(workFile)) { File.Delete(workFile); } // Make sure we have enough space for the file. try { tmpStream.SetLength(node.Length); tmpStream.Close(); tmpStream = null; #if MONO if (MyEnvironment.Unix) { if (node.Properties.GetSingleProperty(SyncFile.ModeProperty) != null) { // Get the posix mode flags for the file. Stat sStat; if (Syscall.stat(createName, out sStat) == 0) { // Now or in the execute bit and set it on the file. FilePermissions fp = sStat.st_mode | FilePermissions.S_IXUSR; Syscall.chmod(createName, fp); } } } #endif File.Move(createName, workFile); } catch (IOException) { if (tmpStream != null) { tmpStream.Close(); } throw new InsufficientStorageException(); } workStream = new StreamStream(File.Open(workFile, FileMode.Truncate, FileAccess.ReadWrite, FileShare.None)); }
public override void DoWork(SkriptFile file, int lineNumber, string rawContent, FileParseContext context) { AbstractFileNode resultNode = new BaseFileNode(); NodeContentHelper.ApplyBasicNodeInfoToNode(rawContent, lineNumber, file, ref resultNode); if (resultNode.NodeContent.IsEmpty() && !resultNode.RawComment.IsEmpty()) { AbstractFileNode commentNode = new CommentLineNode(); NodeContentHelper.ApplyBasicNodeInfoToOtherNode(resultNode, ref commentNode); resultNode = commentNode; } else if (resultNode.NodeContent.IsEmpty() && resultNode.RawComment.IsEmpty()) { AbstractFileNode emptyLineNode = new EmptyLineNode(); emptyLineNode.MatchedSyntax = new SyntaxMatch(SignatureElements.EmptyLine, ParseResult.Success(context)); NodeContentHelper.ApplyBasicNodeInfoToOtherNode(resultNode, ref emptyLineNode); resultNode = emptyLineNode; } else { if (file.IsNodeVisible(resultNode)) { var ctx = ParseContext.FromCode(rawContent); var signatureMatches = new List <(bool isSectionMismatch, AbstractFileNode node)>(); //Try to match to one of our known signatures foreach (var(signatureNodeType, signatureDelegate) in NodeSignaturesManager.Instance.SignatureTypes ) { ctx.Matches.Clear(); ctx.CurrentPosition = context.IndentationChars; var isSectionTypeMismatch = resultNode.IsSectionNode != (signatureNodeType.GetCustomAttribute <SectionNodeAttribute>() != null); var tryParseResult = signatureDelegate.DynamicInvoke(ctx); // We matched one signature if (tryParseResult != null && ctx.HasFinishedLine) { var instance = signatureNodeType.NewInstance(tryParseResult); if (instance is AbstractFileNode fileNode) { NodeContentHelper.ApplyBasicNodeInfoToOtherNode(resultNode, ref fileNode); signatureMatches.Add((isSectionTypeMismatch, fileNode)); } if (!isSectionTypeMismatch) { break; } } } var resultingNode = signatureMatches.FirstOrDefault(x => !x.isSectionMismatch).node; if (resultingNode != null) { resultNode = resultingNode; } } } file.Nodes[lineNumber] = resultNode; }