예제 #1
0
        public virtual NfsPacket ReadDirectory(NfsPacket packet)
        {
            FileHandle fh     = new FileHandle(packet);
            uint       cookie = packet.GetUInt();
            uint       count  = packet.GetUInt();
            uint       xId    = packet.XID;

            // if this is a new call to readdir (cookie=0) or it is a new directory to read, replace the cache.
            string dirName = GetNameFromHandle(fh.Handle, xId);

            //Console.Write("Reading dir " + dirName + " cookie=" + cookie + " count=" + count + "\n");

            if (cookie == 0 || (dirName.Equals(_cachedDirectories) == false))
            {
                if (!Directory.Exists(dirName))
                {
                    throw new NFSException(xId, (uint)NfsReply.ERR_NOENT);
                }

                List <String> dirFiles = Directory.GetFiles(dirName).Select(f => new FileInfo(f).Name).ToList();
                dirFiles.AddRange(Directory.GetDirectories(dirName).Select(d => new DirectoryInfo(d).Name));

                if (dirFiles == null)
                {
                    throw new NFSException(xId, (uint)NfsReply.ERR_NOENT);
                }

                //Console.WriteLine("dir has " + dirFiles.Count + " entries");

                if (dirFiles.Count <= 0)
                {
                    throw new NFSException(xId, (uint)NfsReply.ERR_NOENT);
                }

                dirFiles.BubbleSort();
                //dirFiles.Insert(0, "..");
                //dirFiles.Insert(0, ".");

                _cachedFiles       = dirFiles;
                _cachedDirectories = dirName;
            }

            // prepare the reply packet.
            NfsPacket reply = new NfsPacket((int)count);

            reply.AddReplyHeader(xId);
            reply.SetUInt((uint)NfsReply.OK);

            // Add files to the list until there are no more files or all of the count bytes have been used.

            int  current = reply.Length;
            bool more    = false;          // are there more files to get

            // if there are any files to add
            if (_cachedFiles != null && _cachedFiles.Count > 0)
            {
                for (int i = (int)cookie; i < _cachedFiles.Count; i++)
                {
                    // see if there is enough room for another file - 3 longs of id,
                    //   the name (rounded up to 4 bytes) and a trailing long
                    //   indicating whether there are more files to get
                    int needed = 3 * 4 + (_cachedFiles[i].Length + 3) + 8;
                    if (needed + current >= count)
                    {
                        more = true;
                        break;
                    }
                    // get the handle for this file
                    string fileName = Path.Combine(_cachedDirectories, _cachedFiles[i]);
                    uint   handle   = HandleManager.Current.GetHandle(fileName);

                    Console.WriteLine("Read handle for: " + fileName + " -> " + handle);

                    // add an entry to the packet for this file
                    reply.SetUInt(NfsHandler.NFS_TRUE);
                    reply.SetUInt(handle);
                    reply.Set(_cachedFiles[i]);
                    reply.SetUInt((uint)i + 1);                     // this is the cookie

                    current = reply.Length;
                }
            }
            reply.SetUInt(NfsHandler.NFS_FALSE);             // no more entries in this packet

            // tell the client if this packet has returned the last of the files
            if (more)
            {
                reply.SetUInt(NfsHandler.NFS_FALSE);
            }
            else
            {
                reply.SetUInt(NfsHandler.NFS_TRUE);
            }

            return(reply);
        }
예제 #2
0
        public virtual NfsPacket ReadDirectory(NfsPacket packet)
        {
            FileHandle fh = new FileHandle(packet);
            uint cookie = packet.GetUInt();
            uint count = packet.GetUInt();
            uint xId = packet.XID;

            // if this is a new call to readdir (cookie=0) or it is a new directory to read, replace the cache.
            string dirName = GetNameFromHandle(fh.Handle, xId);

            //Console.Write("Reading dir " + dirName + " cookie=" + cookie + " count=" + count + "\n");

            if (cookie == 0 || (dirName.Equals(_cachedDirectories) == false)) {

                if (!Directory.Exists(dirName)) {
                    throw new NFSException(xId, (uint)NfsReply.ERR_NOENT);
                }

                List<String> dirFiles = Directory.GetFiles(dirName).Select(f => new FileInfo(f).Name).ToList();
                dirFiles.AddRange(Directory.GetDirectories(dirName).Select(d => new DirectoryInfo(d).Name));

                if (dirFiles == null) {
                    throw new NFSException(xId, (uint)NfsReply.ERR_NOENT);
                }

                //Console.WriteLine("dir has " + dirFiles.Count + " entries");

                if (dirFiles.Count <= 0) {
                    throw new NFSException(xId, (uint)NfsReply.ERR_NOENT);
                }

                dirFiles.BubbleSort();
                //dirFiles.Insert(0, "..");
                //dirFiles.Insert(0, ".");

                _cachedFiles = dirFiles;
                _cachedDirectories = dirName;
            }

            // prepare the reply packet.
            NfsPacket reply = new NfsPacket((int)count);
            reply.AddReplyHeader(xId);
            reply.SetUInt((uint)NfsReply.OK);

            // Add files to the list until there are no more files or all of the count bytes have been used.

            int current = reply.Length;
            bool more = false; // are there more files to get

            // if there are any files to add
            if (_cachedFiles != null && _cachedFiles.Count > 0) {
                for (int i = (int)cookie; i < _cachedFiles.Count; i++) {
                    // see if there is enough room for another file - 3 longs of id,
                    //   the name (rounded up to 4 bytes) and a trailing long
                    //   indicating whether there are more files to get
                    int needed = 3 * 4 + (_cachedFiles[i].Length + 3) + 8;
                    if (needed + current >= count) {
                        more = true;
                        break;
                    }
                    // get the handle for this file
                    string fileName = Path.Combine(_cachedDirectories, _cachedFiles[i]);
                    uint handle = HandleManager.Current.GetHandle(fileName);

                    Console.WriteLine("Read handle for: " + fileName + " -> " + handle);

                    // add an entry to the packet for this file
                    reply.SetUInt(NfsHandler.NFS_TRUE);
                    reply.SetUInt(handle);
                    reply.Set(_cachedFiles[i]);
                    reply.SetUInt((uint)i + 1); // this is the cookie

                    current = reply.Length;
                }
            }
            reply.SetUInt(NfsHandler.NFS_FALSE); // no more entries in this packet

            // tell the client if this packet has returned the last of the files
            if (more) {
                reply.SetUInt(NfsHandler.NFS_FALSE);
            }
            else {
                reply.SetUInt(NfsHandler.NFS_TRUE);
            }

            return reply;
        }