コード例 #1
0
        public NfsPacket Read(NfsPacket packet)
        {
            try {
                FileHandle fh         = new FileHandle(packet);
                uint       offset     = packet.GetUInt();
                uint       count      = packet.GetUInt();
                uint       totalCount = packet.GetUInt();           // not used
                uint       xId        = packet.XID;
                int        numberRead;
                byte[]     readbuf;
                String     filePath = HandleManager.Current.GetName(fh.Handle);

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

                if (count <= 0)
                {
                    Console.Error.WriteLine("\tNfsIO.Read: invalid value for count " + count);
                    throw new NFSException(xId, (uint)NfsReply.ERR_IO);
                }

                using (StreamReader sr = new StreamReader(filePath)) {
                    sr.BaseStream.Seek(offset, SeekOrigin.Begin);
                    readbuf    = new byte[(int)count];
                    numberRead = sr.BaseStream.Read(readbuf, 0, (int)count);
                }

                if (numberRead < 0)
                {
                    Console.Error.WriteLine("\tNfsIO.Read: number read is " + numberRead);
                    numberRead = 0;
                }

                NfsFileAttributes attributes = new NfsFileAttributes(filePath);
                NfsPacket         reply      = new NfsPacket(128 + numberRead);

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

                attributes.Emit(ref reply);

                reply.SetData(numberRead, readbuf);

                return(reply);
            }
            catch (FileNotFoundException) {
                throw new NFSException(packet.XID, (uint)NfsReply.ERR_NOENT);
            }
            catch (IOException) {
                throw new NFSException(packet.XID, (uint)NfsReply.ERR_IO);
            }
        }
コード例 #2
0
ファイル: FileHandle.cs プロジェクト: jklemmack/Snarf
        internal virtual bool Read(NfsPacket packet)
        {
            root      = packet.GetUInt();        // the first long in the packet is the handle of the root
            handle    = packet.GetUInt();        // the next long is the handle of the file
            @readonly = packet.GetUInt();        // the next is a read only flag

            // The rest is nothing. There are 32 bytes in a FileHandle and this has read in 3 words, or 12 bytes.
            packet.Advance(32 - 3 * 4);

            return(true);
        }
コード例 #3
0
ファイル: NfsIO.cs プロジェクト: shellscape/Snarf
        public NfsPacket Read(NfsPacket packet)
        {
            try {
                FileHandle fh = new FileHandle(packet);
                uint offset = packet.GetUInt();
                uint count = packet.GetUInt();
                uint totalCount = packet.GetUInt(); // not used
                uint xId = packet.XID;
                int numberRead;
                byte[] readbuf;
                String filePath = HandleManager.Current.GetName(fh.Handle);

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

                if (count <= 0) {
                    Console.Error.WriteLine("\tNfsIO.Read: invalid value for count " + count);
                    throw new NFSException(xId, (uint)NfsReply.ERR_IO);
                }

                using (StreamReader sr = new StreamReader(filePath)) {
                    sr.BaseStream.Seek(offset, SeekOrigin.Begin);
                    readbuf = new byte[(int)count];
                    numberRead = sr.BaseStream.Read(readbuf, 0, (int)count);
                }

                if (numberRead < 0) {
                    Console.Error.WriteLine("\tNfsIO.Read: number read is " + numberRead);
                    numberRead = 0;
                }

                NfsFileAttributes attributes = new NfsFileAttributes(filePath);
                NfsPacket reply = new NfsPacket(128 + numberRead);

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

                attributes.Emit(ref reply);

                reply.SetData(numberRead, readbuf);

                return reply;
            }
            catch (FileNotFoundException) {
                throw new NFSException(packet.XID, (uint)NfsReply.ERR_NOENT);
            }
            catch (IOException) {
                throw new NFSException(packet.XID, (uint)NfsReply.ERR_IO);
            }
        }
コード例 #4
0
        public NfsPacket Write(uint xid, NfsPacket packet)
        {
            string fileName = null;

            try {
                // read info out of packet
                FileHandle fh          = new FileHandle(packet);
                uint       beginoffset = packet.GetUInt();
                uint       offset      = packet.GetUInt();
                uint       totalcount  = packet.GetUInt();
                // next comes the data which is a uint of size and the bytes.
                uint datalen      = packet.GetUInt();
                uint packetOffset = (uint)packet.Position;
                packet.Advance(datalen);

                // carry out the write operation
                fileName = HandleManager.Current.GetName(fh.Handle);
                if (fileName == null)
                {
                    throw new NFSException(xid, (uint)NfsReply.ERR_STALE);
                }
                // XXX comment out print lines to improve performance
                // System.out.print("Write(" + fileName + ", " + offset + ", " +
                //		     datalen + ")\n");
                using (StreamWriter sw = new StreamWriter(fileName)) {
                    sw.BaseStream.Seek(offset, SeekOrigin.Begin);
                    sw.BaseStream.Write(packet.Data, (int)packetOffset, (int)datalen);
                }

                // load in new file attributes
                NfsFileAttributes fa = new NfsFileAttributes();
                fa.Load(fileName);

                // create the reply packet
                NfsPacket result = new NfsPacket(128);
                result.Reset();
                result.AddReplyHeader(xid);
                result.SetUInt((uint)NfsReply.OK);
                fa.Emit(ref result);

                return(result);
            }
            catch (IOException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_IO);
            }
            catch (System.Security.SecurityException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_PERM);
            }
        }
コード例 #5
0
ファイル: NfsIO.cs プロジェクト: shellscape/Snarf
        public NfsPacket Write(uint xid, NfsPacket packet)
        {
            string fileName = null;

            try {
                // read info out of packet
                FileHandle fh = new FileHandle(packet);
                uint beginoffset = packet.GetUInt();
                uint offset = packet.GetUInt();
                uint totalcount = packet.GetUInt();
                // next comes the data which is a uint of size and the bytes.
                uint datalen = packet.GetUInt();
                uint packetOffset = (uint)packet.Position;
                packet.Advance(datalen);

                // carry out the write operation
                fileName = HandleManager.Current.GetName(fh.Handle);
                if (fileName == null) {
                    throw new NFSException(xid, (uint)NfsReply.ERR_STALE);
                }
                // XXX comment out print lines to improve performance
                // System.out.print("Write(" + fileName + ", " + offset + ", " +
                //		     datalen + ")\n");
                using (StreamWriter sw = new StreamWriter(fileName)) {
                    sw.BaseStream.Seek(offset, SeekOrigin.Begin);
                    sw.BaseStream.Write(packet.Data, (int)packetOffset, (int)datalen);
                }

                // load in new file attributes
                NfsFileAttributes fa = new NfsFileAttributes();
                fa.Load(fileName);

                // create the reply packet
                NfsPacket result = new NfsPacket(128);
                result.Reset();
                result.AddReplyHeader(xid);
                result.SetUInt((uint)NfsReply.OK);
                fa.Emit(ref result);

                return result;
            }
            catch (IOException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_IO);
            }
            catch (System.Security.SecurityException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_PERM);
            }
        }
コード例 #6
0
ファイル: NfsDirectory.cs プロジェクト: jklemmack/Snarf
        public virtual NfsPacket SetAttr(uint xid, NfsPacket packet)
        {
            try {
                FileHandle f        = new FileHandle(packet);
                String     fileName = GetNameFromHandle(f.Handle, xid);

                // the attributes
                int     mode  = (int)packet.GetUInt();
                int     uid   = (int)packet.GetUInt();
                int     gid   = (int)packet.GetUInt();
                int     size  = (int)packet.GetUInt();
                NfsTime atime = new NfsTime(packet);
                NfsTime mtime = new NfsTime(packet);

                // the only attribute that can be set is the size can be set to 0 to truncate the file
                if (size == 0)
                {
                    // truncate by deleting and recreating the file
                    using (var fs = new FileStream(fileName, FileMode.Truncate, FileAccess.ReadWrite)) { }
                }

                NfsPacket reply = new NfsPacket(128);
                reply.AddReplyHeader(xid);
                reply.SetUInt((uint)NfsReply.OK);

                NfsFileAttributes fa = new NfsFileAttributes();
                fa.Load(fileName);
                fa.Emit(ref reply);

                return(reply);
            }
            catch (FileNotFoundException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_NOENT);
            }
            catch (IOException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_PERM);
            }
        }
コード例 #7
0
ファイル: NfsFileAttributes.cs プロジェクト: jklemmack/Snarf
        public bool Read(NfsPacket packet)
        {
            type      = (FileType)packet.GetUInt();
            mode      = (FilePermissions)packet.GetUInt();
            nlink     = packet.GetUInt();
            uid       = packet.GetUInt();
            gid       = packet.GetUInt();
            size      = packet.GetUInt();
            blocksize = packet.GetUInt();
            rdev      = packet.GetUInt();
            blocks    = packet.GetUInt();
            fsid      = packet.GetUInt();
            fileid    = packet.GetUInt();

            if (!lastAccessed.Read(packet))
            {
                return(false);
            }
            if (!lastModified.Read(packet))
            {
                return(false);
            }
            if (!lastChanged.Read(packet))
            {
                return(false);
            }

            return(true);
        }
コード例 #8
0
ファイル: NfsDirectory.cs プロジェクト: jklemmack/Snarf
        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);
        }
コード例 #9
0
ファイル: NfsFileAttributes.cs プロジェクト: shellscape/Snarf
        public bool Read(NfsPacket packet)
        {
            type = (FileType)packet.GetUInt();
            mode = (FilePermissions)packet.GetUInt();
            nlink = packet.GetUInt();
            uid = packet.GetUInt();
            gid = packet.GetUInt();
            size = packet.GetUInt();
            blocksize = packet.GetUInt();
            rdev = packet.GetUInt();
            blocks = packet.GetUInt();
            fsid = packet.GetUInt();
            fileid = packet.GetUInt();

            if (!lastAccessed.Read(packet)) {
                return false;
            }
            if (!lastModified.Read(packet)) {
                return false;
            }
            if (!lastChanged.Read(packet)) {
                return false;
            }

            return true;
        }
コード例 #10
0
ファイル: FileHandle.cs プロジェクト: shellscape/Snarf
        internal virtual bool Read(NfsPacket packet)
        {
            root = packet.GetUInt(); // the first long in the packet is the handle of the root
            handle = packet.GetUInt(); // the next long is the handle of the file
            @readonly = packet.GetUInt(); // the next is a read only flag

            // The rest is nothing. There are 32 bytes in a FileHandle and this has read in 3 words, or 12 bytes.
            packet.Advance(32 - 3 * 4);

            return true;
        }
コード例 #11
0
ファイル: NfsDirectory.cs プロジェクト: shellscape/Snarf
        public virtual NfsPacket SetAttr(uint xid, NfsPacket packet)
        {
            try {
                FileHandle f = new FileHandle(packet);
                String fileName = GetNameFromHandle(f.Handle, xid);

                // the attributes
                int mode = (int)packet.GetUInt();
                int uid = (int)packet.GetUInt();
                int gid = (int)packet.GetUInt();
                int size = (int)packet.GetUInt();
                NfsTime atime = new NfsTime(packet);
                NfsTime mtime = new NfsTime(packet);

                // the only attribute that can be set is the size can be set to 0 to truncate the file
                if (size == 0) {
                    // truncate by deleting and recreating the file
                    using (var fs = new FileStream(fileName, FileMode.Truncate, FileAccess.ReadWrite)) { }
                }

                NfsPacket reply = new NfsPacket(128);
                reply.AddReplyHeader(xid);
                reply.SetUInt((uint)NfsReply.OK);

                NfsFileAttributes fa = new NfsFileAttributes();
                fa.Load(fileName);
                fa.Emit(ref reply);

                return reply;
            }
            catch (FileNotFoundException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_NOENT);
            }
            catch (IOException) {
                throw new NFSException(xid, (uint)NfsReply.ERR_PERM);
            }
        }
コード例 #12
0
ファイル: NfsDirectory.cs プロジェクト: shellscape/Snarf
        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;
        }