예제 #1
0
        /// <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;
            }
        }
예제 #2
0
        /// <summary>
        /// Called to close the file and cleanup.
        /// </summary>
        /// <param name="InFinalizer">true if called from the finalizer.</param>
        private void Close(bool InFinalizer)
        {
            if (!InFinalizer)
            {
                GC.SuppressFinalize(this);
            }

            if (workStream != null)
            {
                workStream.Close();
                workStream = null;
            }
            // We need to delete the temp file.
            if (workFile != null)
            {
                File.Delete(workFile);
            }
        }
예제 #3
0
        /// <summary>
        /// Called to cleanup any resources and close the file.
        /// </summary>
        /// <param name="InFinalizer"></param>
        /// <param name="commit"></param>
        private SyncNodeStatus Close(bool InFinalizer, bool commit)
        {
            if (!InFinalizer)
            {
                GC.SuppressFinalize(this);
            }

            SyncNodeStatus status = new SyncNodeStatus();

            status.nodeID = node.ID;
            status.status = SyncStatus.ClientError;

            if (stream != null)
            {
                stream.Close();
                stream = null;
            }
            if (workStream != null)
            {
                workStream.Close();
                workStream = null;
            }
            if (commit)
            {
                // backup file for rolling back on failure
                string tmpFile = "";
                if (File.Exists(file))
                {
                    tmpFile = file + ".~stmp";
                    File.Move(file, tmpFile);
                    Log.log.Info("backing up {0}->{1}", file, tmpFile);
                }

                // first try to write the file
                try
                {
                    Log.log.Info("trying to move {0}->{1}", workFile, file);
                    File.Move(workFile, file);
                    workFile = null;
                }
                catch
                {
                    Log.log.Info("Couldn't move {0}->{1}", workFile, file);
                    Log.log.Info("Restoring file {0}", file);
                    try {
                        if (File.Exists(file))
                        {
                            File.Delete(file);                             // delete newly transferred file
                        }
                        if (File.Exists(tmpFile))
                        {
                            File.Move(tmpFile, file);                             // restore backup file into place
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.log.Info("couldn't return to prior state{0}--{1}", ex.Message, ex.StackTrace);
                    };
                    // DELETE HASHMAP ?

                    throw;                      // and don't try to commit
                }
                //  try to collection.commit()
                status.status = SyncStatus.Success;
                try
                {
                    Log.log.Info("trying to commit collection");
                    collection.Commit(node);
                }
                catch (CollisionException ce)
                {
                    commit        = false;
                    status.status = SyncStatus.UpdateConflict;
                    Log.log.Info("Couldn't commit collection: UpdateConflict {0}--{1}", ce.Message, ce.StackTrace);
                }
                catch (Exception ex)
                {
                    commit        = false;
                    status.status = SyncStatus.ServerFailure;
                    Log.log.Info("Couldn't commit collection {0}--{1}", ex.Message, ex.StackTrace);
                }

                /* Note : Restore original file if collection.Commit fails.
                 * Conflict is a valid case for failure. And do not remove
                 * files in workarea as they are needed for conflict resolution. */
                if (!commit && status.status != SyncStatus.UpdateConflict)
                {
                    try {
                        Log.log.Debug("Collection commit failed : Restoring backup file : {0}", file.ToString());
                        // Delete newly transferred file
                        if (File.Exists(file))
                        {
                            File.Delete(file);
                            Log.log.Debug("-- Deleting file : {0}", file.ToString());
                        }
                        // Restore backup file into place
                        if (File.Exists(tmpFile))
                        {
                            File.Move(tmpFile, file);
                            Log.log.Debug("-- Restoring {0} to {1}", tmpFile.ToString(), file.ToString());
                        }
                        // Fixme : Delete hashmap ?
                    }
                    catch (Exception ex)
                    {
                        Log.log.Info("File restore failed : Couldn't return to prior state {0}--{1}", ex.Message, ex.StackTrace);
                    };
                }
                else                  // commit successful, delete the temporary (.~stmp) file.
                {
                    try
                    {
                        // restore backup file into place
                        if (File.Exists(tmpFile))
                        {
                            File.Delete(tmpFile);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.log.Info("problem deleting .~stmp file {0}--{1}", ex.Message, ex.StackTrace);
                    };
                }
                if (commit)
                {
                    FileInfo fi = new FileInfo(file);
                    fi.LastWriteTime = node.LastWriteTime;
                    fi.CreationTime  = node.CreationTime;
                    if (oldNode != null)
                    {
                        // Check if this was a rename.
                        // If the old path does not equal the new path
                        // Delete the old file.
                        string oldPath = oldNode.GetFullPath(collection);
                        try
                        {
                            Log.log.Info("{0} may have been moved to {1}", file, oldPath);
                            if (MyEnvironment.Windows)
                            {
                                if (string.Compare(oldPath, file, true) != 0)
                                {
                                    File.Delete(oldPath);
                                }
                            }
                            else
                            {
                                if (oldPath != file)
                                {
                                    File.Delete(oldPath);
                                }
                            }
                        }
                        catch {};
                    }
                }
            }

            // We need to delete the temp file if we are the master.
            // On the client leave for a delta sync.
            if (workFile != null)
            {
                if (collection.Role == SyncRoles.Master || (collection.Role == SyncRoles.Slave && File.Exists(file)))
                {
                    File.Delete(workFile);
                }
            }

            if (partialFile != null)
            {
                File.Delete(partialFile);
            }

            return(status);
        }
예제 #4
0
        /// <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));
        }