public override int Write(ReadOnlySpan <byte> path, ulong off, ReadOnlySpan <byte> buffer, ref FuseFileInfo fi, Guid fileGuid)
        {
            path = base.TransformPath(path);

            if (debug)
            {
                Console.WriteLine($"NeoFS::Write()");
            }
            if (fi.fh == 0)
            {
                var newFd = LibC.open(toBp(path), fi.flags);
                if (newFd > 0)
                {
                    fi.fh = (ulong)newFd;
                }
                else
                {
                    return(-LibC.errno);
                }
            }

            ssize_t res;

            fixed(void *vbuf = buffer)
            {
                res = LibC.pwrite((int)fi.fh, vbuf, buffer.Length, (long)off);
            }

            if (res < 0)
            {
                return(-LibC.errno);
            }

            return((int)res);
        }
示例#2
0
        public unsafe static byte[] GetSha1(byte[] path)
        {
            var ps    = PenguinSanitizer.Extensions.ToBytePtr(path);
            var newFd = LibC.open(ps, LibC.O_RDONLY);

            // Tap the stream so we can get a hash on it.

            var hash = HashAlgorithm.Create("SHA1");

            var buf = new Byte[32 * 1024 * 1024];

            while (true)
            {
                ssize_t rd = 0;
                fixed(void *b = buf)
                {
                    rd = LibC.read(newFd, b, buf.Length);

                    hash.TransformBlock(buf, 0, (int)rd, buf, 0);
                }

                if (rd < 1)
                {
                    break;
                }
            }

            LibC.close(newFd);
            buf = null;

            hash.TransformFinalBlock(buf, 0, 0);
            return(hash.Hash);
        }
        public override int FAllocate(ReadOnlySpan <byte> path, int mode, ulong offset, long length, ref FuseFileInfo fi, Guid fileGuid)
        {
            path = base.TransformPath(path);

            if (debug)
            {
                Console.WriteLine($"NeoFS::FAllocate()");
            }

            if (fi.fh == 0)
            {
                var newFd = LibC.open(toBp(path), fi.flags);
                if (newFd > 0)
                {
                    fi.fh = (ulong)newFd;
                }
                else
                {
                    return(-LibC.errno);
                }
            }


            var res = LibC.fallocate((int)fi.fh, mode, (long)offset, length);


            if (res < 0)
            {
                return(-LibC.errno);
            }

            return((int)res);
        }
        // Write
        public override int Create(ReadOnlySpan <byte> path, mode_t mode, ref FuseFileInfo fi, Guid fileGuid)
        {
            path = base.TransformPath(path);

            if (debug)
            {
                Console.WriteLine($"NeoFS::Create()");
            }

            fi.fh = 0;

            var res = LibC.open(toBp(path), fi.flags, mode);

            if (res < 0)
            {
                return(-LibC.errno);
            }

            fi.fh = (ulong)res;

            // Make these settable (these actually come in on the Init method, which TDMS isn't handling yet)
            var uid = (uid_t)10010;
            var gid = (gid_t)10010;

            res = LibC.chown(toBp(path), uid, gid);

            return(0);
        }
示例#5
0
        // private IEnumerator<string> pathStr(string )

        public unsafe int Create(FileDescriptor fds, mode_t mode, int flags)
        {
            Console.WriteLine($"[Cache-Create {Encoding.ASCII.GetString(fds.FileNode.Content.CacheFile)}]");

            var fileg = fds.FileNode.Content.CachePoolGuid.Value.ToString().ToLower();

            // Intermediate directories probably don't exist - this needs to be much smarter
            var ca1 = $"/ua/NeoVirtCache/{fileg.Substring(0, 3)}";
            //var ca2 = $"/ua/NeoVirtCache/{fileg.Substring(0, 2)}/{fileg.Substring(2, 2)}";
            //var ca3 = $"/ua/NeoVirtCache/{fileg.Substring(0, 2)}/{fileg.Substring(2, 2)}/{fileg.Substring(4, 2)}";
            //var ca4 = $"/ua/NeoVirtCache/{fileg.Substring(0, 2)}/{fileg.Substring(2, 2)}/{fileg.Substring(4, 2)}/{fileg.Substring(6, 2)}/";

            var ret = LibC.mkdir(toBp(Encoding.ASCII.GetBytes(ca1)), 0b111_101_000);

            //ret = LibC.mkdir(toBp(Encoding.ASCII.GetBytes(ca2)), 0b111_101_000);
            //ret = LibC.mkdir(toBp(Encoding.ASCII.GetBytes(ca3)), 0b111_101_000);
            //ret = LibC.mkdir(toBp(Encoding.ASCII.GetBytes(ca4)), 0b111_101_000);

            iot = LibC.open(toBp(fds.FileNode.Content.CacheFile), flags, 0b110_100_000);
            if (iot < 0)
            {
                return(iot);
            }

            return(0);
        }
示例#6
0
        public static int Open(IVfsPath path, int flags, mode_t mode = default)
        {
            var fd = LibC.open(path.toNullTerm(), 0);

            if (LibC.errno != 0)
            {
                return(-LibC.errno);
            }
            return(fd);
        }
示例#7
0
        private void CallOpen()
        {
            var    data    = machine.SystemBus.ReadBytes((ulong)buffer.Value, (int)bufferSize.Value);
            IntPtr dataPtr = Marshal.AllocHGlobal(data.Length);

            Marshal.Copy(data, 0, dataPtr, data.Length);

            int current_status = LibC.open(dataPtr, TransformOpenFlags(), (int)pmode.Value);

            fd.Value = (uint)current_status;
            if (current_status == -1)
            {
                SetErrorNumber();
            }

            Marshal.FreeHGlobal(dataPtr);
            call = Call.Done;
        }
        public override int Read(ReadOnlySpan <byte> path, ulong offset, Span <byte> buffer, ref FuseFileInfo fi, Guid fileGuid)
        {
            var context = FileContexts[fi.fh];

            path = base.TransformPath(path);

            if (debug)
            {
                Console.WriteLine($"NeoFS::Read()");
            }

            if (context.ExtAssetSha1 != null)  // Asset Mode
            {
                return(base.AssetRead(path, offset, buffer, ref fi, fileGuid));
            }

            if (fi.fh == 0)
            {
                var newFd = LibC.open(toBp(path), fi.flags);
                if (newFd > 0)
                {
                    fi.fh = (ulong)newFd;
                }
                else
                {
                    return(-LibC.errno);
                }
            }

            ssize_t res;

            fixed(void *vbuf = buffer)
            {
                res = LibC.pread((int)fi.fh, vbuf, buffer.Length, (long)offset);
            }

            if (res < 0)
            {
                return(-LibC.errno);
            }

            return((int)res);
        }
        // File read

        public override int Open(ReadOnlySpan <byte> path, ref FuseFileInfo fi, Guid fileGuid)
        {
            path = base.TransformPath(path);
            if (path.Length < 1)
            {
                return(-LibC.ENOENT);
            }

            if (debug)
            {
                Console.WriteLine($"NeoFS::Open()");
            }

            // Stat the file

            var stat = new stat();

            var lc = LibC.lstat(toBp(path), &stat);

            if (lc < 0)
            {
                return(-LibC.errno);
            }

            string extAssetSha1 = null;

            // Intercept an asset - we must provide the asset's Attr, not the link of the baked file
            if ((stat.st_mode & LibC.S_IFMT) == LibC.S_IFLNK)
            {
                if (debug)
                {
                    Console.WriteLine($"Stat mode={stat.st_mode}, S_IFMT={LibC.S_IFMT}, link={LibC.S_IFLNK}");
                }

                // Get the link

                ssize_t retl;
                var     buffer = new byte[1024];
                fixed(byte *b = buffer)
                {
                    retl = LibC.readlink(toBp(path), b, buffer.Length);
                }

                // Trying to do something like startswith for bytes that's fast
                var link = MemoryExtensions.AsSpan <byte>(buffer, 0, assetTag.Length);

                if (debug)
                {
                    Console.WriteLine($"NeoFS::GetAttr Asset Detected - ({RawDirs.HR(path)}, {RawDirs.HR(link)}");
                }

                if (link.SequenceEqual(assetTag))
                {
                    link = MemoryExtensions.AsSpan <byte>(buffer, 0, (int)retl);
                    if (debug)
                    {
                        Console.WriteLine($"Found ASSET {RawDirs.HR(link)}");
                    }

                    var asset = link.Slice(assetTag.Length);
                    extAssetSha1 = Encoding.ASCII.GetString(asset);
                }
                else
                {
                    link = MemoryExtensions.AsSpan <byte>(buffer, 0, (int)retl);

                    //path = base.TransformPath()   - have to figure out how to pass to our mountmapper
                    // Probably a dependancy injection
                    // These links shouldn't happen, but it would be a nice attack vector
                }
            }

            // See if asset -- if so, set to asset mode and call base

            if (extAssetSha1 != null)  // Asset Mode
            {
                var fakeFd = LibC.open(toBp(fakeFile), 0);
                if (fakeFd > 0)
                {
                    fi.fh = (ulong)fakeFd;
                    FileContexts.Add(fi.fh, new FileContext
                    {
                        AssetLink     = null,
                        ExtAssetSha1  = extAssetSha1,
                        ExtFileHandle = null,
                    });
                    //Console.WriteLine($"Create Context (sha1) ID={fi.fh}");
                }
                else
                {
                    Console.WriteLine($"Error Opening /dev/null?  Error={LibC.errno}");
                }
                return(base.AssetOpen(path, ref fi, fileGuid));
            }

            // transform the link

            var newFd = LibC.open(toBp(path), fi.flags);

            if (newFd > 0)
            {
                fi.fh = (ulong)newFd;

                // Make a context anyway
                FileContexts.Add(fi.fh, new FileContext
                {
                    AssetLink     = null,
                    ExtAssetSha1  = null,
                    ExtFileHandle = null,
                });
                //Console.WriteLine($"Create Context (null) ID={fi.fh}");

                return(0);
            }

            return(-LibC.errno);
        }