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); }
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; }