Пример #1
0
        private void DisposeShareObject(ShareObject shareObject)
        {
            if (NfsServerLog.sharedFileSystemLogger != null)
            {
                NfsServerLog.sharedFileSystemLogger.WriteLine("[SharedFileSystem] Disposing Share Object: {0}", shareObject);
            }

            filesDictionary.Dispose(shareObject.fileID);
            shareObjectsByLocalPath.Remove(shareObject.localPathAndName);
            shareObjectsByHandle.Remove(shareObject.fileHandleBytes);
        }
Пример #2
0
        public ShareObject[] CreateArrayOfShareObjects()
        {
            ShareObject[] shareObjects = new ShareObject[shareObjectsByLocalPath.Count];
            int           i            = 0;

            foreach (KeyValuePair <String, ShareObject> pair in shareObjectsByLocalPath)
            {
                shareObjects[i] = pair.Value;
                i++;
            }
            return(shareObjects);
        }
Пример #3
0
        /*
         * public Nfs3Procedure.Status TryGetShareDirectory(Byte[] handle, out RootShareDirectory rootShareDirectory, out ShareObject shareDirectoryObject)
         * {
         *  ShareObject shareObject;
         *  Nfs3Procedure.Status status = TryGetSharedObject(handle, out shareObject);
         *  if (status != Nfs3Procedure.Status.Ok) { outputShareDirectory = null; return status; }
         *  if (shareObject == null) { outputShareDirectory = null; return Nfs3Procedure.Status.ErrorNoSuchFileOrDirectory; }
         *
         *  //
         *  // Check that the share object is a root share directory
         *  //
         *  for (int i = 0; i < shareDirectories.Length; i++)
         *  {
         *      ShareDirectory shareDirectory = shareDirectories[i];
         *      if (shareDirectory.shareObject == shareObject)
         *      {
         *          outputShareDirectory = shareDirectory;
         *          return Nfs3Procedure.Status.Ok;
         *      }
         *  }
         *
         *  outputShareDirectory = null;
         *  return Nfs3Procedure.Status.ErrorBadHandle;
         * }
         */


        private ShareObject CreateNewShareObject(FileType fileType, String localPathAndName, String shareName)
        {
            FileID newFileID;

            Byte[] newFileHandle = filesDictionary.NewFileHandle(out newFileID);

            ShareObject shareObject = new ShareObject(fileType, newFileID, newFileHandle, localPathAndName, shareName);

            shareObjectsByLocalPath.Add(shareObject.localPathAndName, shareObject);
            shareObjectsByHandle.Add(shareObject.fileHandleBytes, shareObject);

            if (NfsServerLog.sharedFileSystemLogger != null)
            {
                NfsServerLog.sharedFileSystemLogger.WriteLine("[SharedFileSystem] New Share Object: {0}", shareObject);
            }
            return(shareObject);
        }
Пример #4
0
        public Nfs3Procedure.Status TryGetSharedObject(Byte[] handle, out ShareObject shareObject)
        {
            if (!shareObjectsByHandle.TryGetValue(handle, out shareObject))
            {
                if (NfsServerLog.sharedFileSystemLogger != null)
                {
                    NfsServerLog.sharedFileSystemLogger.WriteLine("[SharedFileSystem] [Warning] File handle not found in dictionary: {0}", BitConverter.ToString(handle));
                }
                return(Nfs3Procedure.Status.ErrorBadHandle);
            }

            Nfs3Procedure.Status status = shareObject.CheckStatus();
            if (status != Nfs3Procedure.Status.Ok)
            {
                DisposeShareObject(shareObject);
            }
            return(status);
        }
Пример #5
0
        public SharedFileSystem(IFileIDsAndHandlesDictionary filesDictionary, IPermissions permissions, RootShareDirectory[] rootShareDirectories)
        {
            this.filesDictionary = filesDictionary;
            this.permissions     = permissions;

            this.rootShareDirectories = rootShareDirectories;

            shareObjectsByHandle    = new Dictionary <Byte[], ShareObject>(filesDictionary);
            shareObjectsByLocalPath = new Dictionary <String, ShareObject>();
            for (int i = 0; i < rootShareDirectories.Length; i++)
            {
                RootShareDirectory rootShareDirectory = rootShareDirectories[i];
                ShareObject        shareObject        = CreateNewShareObject(FileType.Directory, rootShareDirectory.localShareDirectory, rootShareDirectory.shareName);
                if (shareObject == null)
                {
                    throw new DirectoryNotFoundException(String.Format(
                                                             "You are trying to share local directory '{0}', but it either does not exist or is not a directory", rootShareDirectory.localShareDirectory));
                }
                rootShareDirectory.shareObject = shareObject;
            }
        }
Пример #6
0
        public void UpdateShareObjectPathAndName(ShareObject shareObject, String newLocalPathAndName, String newName)
        {
            // Dispose share object at new location
            ShareObject overwriteShareObject;

            if (shareObjectsByLocalPath.TryGetValue(newLocalPathAndName, out overwriteShareObject))
            {
                DisposeShareObject(overwriteShareObject);
            }

            // Update share object with new location
            String oldLocalPathAndName = shareObject.localPathAndName;

            shareObjectsByLocalPath.Remove(shareObject.localPathAndName);

            shareObject.UpdatePathAndName(newLocalPathAndName, newName);
            shareObjectsByLocalPath.Add(newLocalPathAndName, shareObject);

            if (NfsServerLog.sharedFileSystemLogger != null)
            {
                NfsServerLog.sharedFileSystemLogger.WriteLine("[SharedFileSystem] Updated Share Object: '{0}' to '{1}'", oldLocalPathAndName, newLocalPathAndName);
            }
        }
Пример #7
0
        public ReadDirPlusReply READDIRPLUS(ReadDirPlusCall readDirPlusCall)
        {
            ShareObject directoryShareObject;
            Status      status = sharedFileSystem.TryGetSharedObject(readDirPlusCall.directoryHandle, out directoryShareObject);

            if (status != Status.Ok)
            {
                return(new ReadDirPlusReply(status, OptionalFileAttributes.None));
            }

            UInt64 cookie = readDirPlusCall.cookie;

            EntryPlus lastEntry = null;
            GenericArrayBuilder <EntryPlus> entriesBuilder = new GenericArrayBuilder <EntryPlus>();

            UInt32 directoryInfoByteCount = 0;

            Boolean foundCookieObject;

            if (cookie > 0)
            {
                if (cookie == directoryShareObject.cookie)
                {
                    foundCookieObject = true;
                }
                else
                {
                    foundCookieObject = false;
                }
            }
            else
            {
                foundCookieObject = true; // This is the first call so there is no cookie to look for

                // Handle the '.' directory (will always be included if cookie is 0)
                if (lastEntry != null)
                {
                    lastEntry.IsNotLastEntry();
                }
                lastEntry = new EntryPlus(
                    directoryShareObject.fileID,
                    ".",
                    directoryShareObject.cookie,
                    directoryShareObject.optionalFileAttributes,
                    directoryShareObject.optionalFileHandleClass);
                entriesBuilder.Add(lastEntry);

                directoryInfoByteCount += 16 + (UInt32)directoryShareObject.shareLeafName.Length;
            }

            FileType currentFileType = FileType.Directory;

            String[] objectNames = Directory.GetDirectories(directoryShareObject.localPathAndName);

            while (true)
            {
                for (int i = 0; i < objectNames.Length; i++)
                {
                    String      objectName  = objectNames[i];
                    ShareObject shareObject = sharedFileSystem.TryGetSharedObject(currentFileType, directoryShareObject.localPathAndName, objectName);
                    if (shareObject == null)
                    {
                        if (NfsServerLog.warningLogger != null)
                        {
                            NfsServerLog.warningLogger.WriteLine("[{0}] [Warning] Could not create or access share object for local directory '{1}'", serviceName, objectName);
                        }
                        continue;
                    }

                    if (!foundCookieObject)
                    {
                        if (shareObject.cookie == cookie)
                        {
                            foundCookieObject = true;
                        }
                    }
                    else
                    {
                        UInt32 entryInfoByteCount = 16 + (UInt32)shareObject.shareLeafName.Length;
                        if (directoryInfoByteCount + entryInfoByteCount > readDirPlusCall.maxDirectoryBytes)
                        {
                            return(new ReadDirPlusReply(directoryShareObject.optionalFileAttributes, null, entriesBuilder.Build(), false));
                        }

                        directoryInfoByteCount += entryInfoByteCount;

                        shareObject.RefreshFileAttributes(sharedFileSystem.permissions);

                        if (lastEntry != null)
                        {
                            lastEntry.IsNotLastEntry();
                        }
                        lastEntry = new EntryPlus(
                            shareObject.fileID,
                            shareObject.shareLeafName,
                            shareObject.cookie,
                            shareObject.optionalFileAttributes,//OptionalFileAttributes.None,
                            shareObject.optionalFileHandleClass);
                        entriesBuilder.Add(lastEntry);
                    }
                }

                if (currentFileType == FileType.Directory)
                {
                    objectNames     = Directory.GetFiles(directoryShareObject.localPathAndName);
                    currentFileType = FileType.Regular;
                }
                else
                {
                    break;
                }
            }

            directoryShareObject.RefreshFileAttributes(sharedFileSystem.permissions);

            if (!foundCookieObject)
            {
                return(new ReadDirPlusReply(Status.ErrorBadCookie, directoryShareObject.optionalFileAttributes));
            }

            return(new ReadDirPlusReply(directoryShareObject.optionalFileAttributes, null, entriesBuilder.Build(), true));
        }
Пример #8
0
 public ModeFlags GetPermissions(ShareObject shareObject)
 {
     return((shareObject.fileType == FileType.Directory) ? defaultDirectoryPermissions :
            defaultFilePermissions);
 }
Пример #9
0
 public Nfs3Procedure.Status TryGetSharedObject(String localPathAndName, String shareName, out ShareObject shareObject)
 {
     if (shareObjectsByLocalPath.TryGetValue(localPathAndName, out shareObject))
     {
         Nfs3Procedure.Status status = shareObject.CheckStatus();
         if (status != Nfs3Procedure.Status.Ok)
         {
             DisposeShareObject(shareObject);
         }
         return(status);
     }
     else
     {
         if (File.Exists(localPathAndName))
         {
             shareObject = CreateNewShareObject(FileType.Regular, localPathAndName, shareName);
             return(Nfs3Procedure.Status.Ok);
         }
         else if (Directory.Exists(localPathAndName))
         {
             shareObject = CreateNewShareObject(FileType.Directory, localPathAndName, shareName);
             return(Nfs3Procedure.Status.Ok);
         }
         else
         {
             return(Nfs3Procedure.Status.ErrorNoSuchFileOrDirectory);
         }
     }
 }
Пример #10
0
 public Nfs3Procedure.Status TryGetSharedObject(String localPathAndName, out ShareObject shareObject)
 {
     return(TryGetSharedObject(localPathAndName, NfsPath.LeafName(localPathAndName), out shareObject));
 }
Пример #11
0
        public Nfs3Procedure.Status TryGetDirectory(String shareDirectoryName, out RootShareDirectory rootShareDirectory, out ShareObject shareDirectoryObject)
        {
            String subPath;
            String rootShareName = NfsPath.SplitShareNameAndSubPath(shareDirectoryName, out subPath);

            if (rootShareName == null)
            {
                rootShareDirectory   = null;
                shareDirectoryObject = null;
                return(Nfs3Procedure.Status.ErrorInvalidArgument);
            }

            Nfs3Procedure.Status status = TryGetRootSharedDirectory(rootShareName, out rootShareDirectory);
            if (status != Nfs3Procedure.Status.Ok)
            {
                shareDirectoryObject = null; return(status);
            }
            if (rootShareDirectory == null)
            {
                shareDirectoryObject = null; return(Nfs3Procedure.Status.ErrorNoSuchFileOrDirectory);
            }

            if (subPath == null)
            {
                shareDirectoryObject = rootShareDirectory.shareObject;
            }
            else
            {
                String localPathAndName = PlatformPath.LocalCombine(rootShareDirectory.localShareDirectory, subPath);

                status = TryGetSharedObject(localPathAndName, subPath, out shareDirectoryObject);
                if (status != Nfs3Procedure.Status.Ok)
                {
                    return(status);
                }
                if (shareDirectoryObject == null)
                {
                    return(Nfs3Procedure.Status.ErrorNoSuchFileOrDirectory);
                }

                shareDirectoryObject.RefreshFileAttributes(permissions);
            }
            return(Nfs3Procedure.Status.Ok);
        }
Пример #12
0
        public Nfs3Procedure.Status Move(ShareObject oldParentShareObject, String oldName,
                                         ShareObject newParentShareObject, String newName)
        {
            Nfs3Procedure.Status status;

            status = newParentShareObject.CheckStatus();
            if (status != Nfs3Procedure.Status.Ok)
            {
                DisposeShareObject(newParentShareObject);
                return(status);
            }

            status = oldParentShareObject.CheckStatus();
            if (status != Nfs3Procedure.Status.Ok)
            {
                DisposeShareObject(oldParentShareObject);
                return(status);
            }

            //
            // Get Old Share Object
            //
            String oldLocalPathAndName = PlatformPath.LocalCombine(oldParentShareObject.localPathAndName, oldName);

            ShareObject oldShareObject;

            if (!shareObjectsByLocalPath.TryGetValue(oldLocalPathAndName, out oldShareObject))
            {
                return(Nfs3Procedure.Status.ErrorNoSuchFileOrDirectory);
            }

            status = oldShareObject.CheckStatus();
            if (status != Nfs3Procedure.Status.Ok)
            {
                DisposeShareObject(oldShareObject);
                return(status);
            }

            //
            // Move
            //
            String   newLocalPathAndName = PlatformPath.LocalCombine(newParentShareObject.localPathAndName, newName);
            FileType fileType            = oldShareObject.fileType;

            if (Directory.Exists(newLocalPathAndName))
            {
                if (oldShareObject.fileType != FileType.Directory)
                {
                    return(Nfs3Procedure.Status.ErrorAlreadyExists);
                }

                try
                {
                    Directory.Delete(newLocalPathAndName);
                }
                catch (IOException)
                {
                    return(Nfs3Procedure.Status.ErrorDirectoryNotEmpty); // The directory is not empty
                }

                Directory.Move(oldLocalPathAndName, newLocalPathAndName);
            }
            else if (File.Exists(newLocalPathAndName))
            {
                if (oldShareObject.fileType != FileType.Regular)
                {
                    return(Nfs3Procedure.Status.ErrorAlreadyExists);
                }

                File.Delete(newLocalPathAndName);

                File.Move(oldLocalPathAndName, newLocalPathAndName);
            }
            else
            {
                if (oldShareObject.fileType == FileType.Regular)
                {
                    File.Move(oldLocalPathAndName, newLocalPathAndName);
                }
                else if (oldShareObject.fileType == FileType.Directory)
                {
                    Directory.Move(oldLocalPathAndName, newLocalPathAndName);
                }
                else
                {
                    return(Nfs3Procedure.Status.ErrorInvalidArgument);
                }
            }

            //
            // Update the share object and return
            //
            UpdateShareObjectPathAndName(oldShareObject, newLocalPathAndName, newName);
            oldShareObject.RefreshFileAttributes(permissions);
            status = oldShareObject.CheckStatus();
            if (status != Nfs3Procedure.Status.Ok)
            {
                DisposeShareObject(oldShareObject);
            }
            return(status);
        }