Beispiel #1
0
        internal ConcurrentDictionary <string, CachedMedia> GetMediasFromMachine(ulong id)
        {
            _machineMediasCache.TryGetValue(id, out ConcurrentDictionary <string, CachedMedia> cachedMachineMedias);

            if (cachedMachineMedias != null)
            {
                return(cachedMachineMedias);
            }

            using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);

            cachedMachineMedias = new ConcurrentDictionary <string, CachedMedia>();

            foreach (MediaByMachine machineMedia in ctx.MediasByMachines.Where(mbm => mbm.Machine.Id == id &&
                                                                               mbm.Media.IsInRepo &&
                                                                               mbm.Media.Size != null))
            {
                var cachedDisk = new CachedMedia
                {
                    Id        = machineMedia.Media.Id,
                    Md5       = machineMedia.Media.Md5,
                    Sha1      = machineMedia.Media.Sha1,
                    Sha256    = machineMedia.Media.Sha256,
                    SpamSum   = machineMedia.Media.SpamSum,
                    Size      = machineMedia.Media.Size ?? 0,
                    CreatedOn = machineMedia.Media.CreatedOn,
                    UpdatedOn = machineMedia.Media.UpdatedOn
                };

                cachedMachineMedias[machineMedia.Name] = cachedDisk;
            }

            _machineMediasCache[id] = cachedMachineMedias;

            return(cachedMachineMedias);
        }
Beispiel #2
0
        protected override Errno OnGetPathStatus(string path, out Stat stat)
        {
            stat = new Stat();

            string[] pieces = _vfs.SplitPath(path);

            if (pieces.Length == 0)
            {
                stat.st_mode  = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555");
                stat.st_nlink = 2;

                return(0);
            }

            long romSetId = _vfs.GetRomSetId(pieces[0]);

            if (romSetId <= 0)
            {
                if (pieces[0] != ".fuse_umount" ||
                    _umountToken == null)
                {
                    return(Errno.ENOENT);
                }

                stat = new Stat
                {
                    st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                    st_nlink   = 1,
                    st_ctime   = NativeConvert.ToTimeT(DateTime.UtcNow),
                    st_mtime   = NativeConvert.ToTimeT(DateTime.UtcNow),
                    st_blksize = 0,
                    st_blocks  = 0,
                    st_ino     = 0,
                    st_size    = 0
                };

                return(0);
            }

            RomSet romSet = _vfs.GetRomSet(romSetId);

            if (romSet == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 1)
            {
                stat.st_mode  = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555");
                stat.st_nlink = 2;
                stat.st_ctime = NativeConvert.ToTimeT(romSet.CreatedOn.ToUniversalTime());
                stat.st_mtime = NativeConvert.ToTimeT(romSet.UpdatedOn.ToUniversalTime());

                return(0);
            }

            CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);

            if (machine == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 2)
            {
                stat = new Stat
                {
                    st_mode  = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
                    st_nlink = 2,
                    st_ctime = NativeConvert.ToTimeT(machine.CreationDate.ToUniversalTime()),
                    st_mtime = NativeConvert.ToTimeT(machine.ModificationDate.ToUniversalTime())
                };

                return(0);
            }

            CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);

            if (file != null)
            {
                if (pieces.Length != 3)
                {
                    return(Errno.ENOSYS);
                }

                stat = new Stat
                {
                    st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                    st_nlink   = 1,
                    st_ctime   = NativeConvert.ToTimeT(file.CreatedOn.ToUniversalTime()),
                    st_mtime   = NativeConvert.ToTimeT(file.FileLastModification?.ToUniversalTime() ?? file.UpdatedOn.ToUniversalTime()),
                    st_blksize = 512,
                    st_blocks  = (long)(file.Size / 512),
                    st_ino     = file.Id,
                    st_size    = (long)file.Size
                };

                return(0);
            }

            CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);

            if (disk != null)
            {
                if (pieces.Length != 3)
                {
                    return(Errno.ENOSYS);
                }

                stat = new Stat
                {
                    st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                    st_nlink   = 1,
                    st_ctime   = NativeConvert.ToTimeT(disk.CreatedOn.ToUniversalTime()),
                    st_mtime   = NativeConvert.ToTimeT(disk.UpdatedOn.ToUniversalTime()),
                    st_blksize = 512,
                    st_blocks  = (long)(disk.Size / 512),
                    st_ino     = disk.Id,
                    st_size    = (long)disk.Size
                };

                return(0);
            }

            CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);

            if (media == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length != 3)
            {
                return(Errno.ENOSYS);
            }

            stat = new Stat
            {
                st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                st_nlink   = 1,
                st_ctime   = NativeConvert.ToTimeT(media.CreatedOn.ToUniversalTime()),
                st_mtime   = NativeConvert.ToTimeT(media.UpdatedOn.ToUniversalTime()),
                st_blksize = 512,
                st_blocks  = (long)(media.Size / 512),
                st_ino     = media.Id,
                st_size    = (long)media.Size
            };

            return(0);
        }
Beispiel #3
0
        protected override Errno OnListPathExtendedAttributes(string path, out string[] names)
        {
            names = null;

            string[] pieces = _vfs.SplitPath(path);

            if (pieces.Length == 0)
            {
                return(0);
            }

            long romSetId = _vfs.GetRomSetId(pieces[0]);

            if (romSetId <= 0)
            {
                return(Errno.ENOENT);
            }

            RomSet romSet = _vfs.GetRomSet(romSetId);

            if (romSet == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 1)
            {
                return(0);
            }

            CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);

            if (machine == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 2)
            {
                return(0);
            }

            List <string> xattrs = new List <string>();

            CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);

            if (file != null)
            {
                if (pieces.Length > 3)
                {
                    return(Errno.ENOSYS);
                }

                if (file.Crc32 != null)
                {
                    xattrs.Add("user.crc32");
                }

                if (file.Md5 != null)
                {
                    xattrs.Add("user.md5");
                }

                if (file.Sha1 != null)
                {
                    xattrs.Add("user.sha1");
                }

                if (file.Sha256 != null)
                {
                    xattrs.Add("user.sha256");
                }

                if (file.Sha384 != null)
                {
                    xattrs.Add("user.sha384");
                }

                if (file.Sha512 != null)
                {
                    xattrs.Add("user.sha512");
                }

                names = xattrs.ToArray();

                return(0);
            }

            CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);

            if (disk != null)
            {
                if (pieces.Length > 3)
                {
                    return(Errno.ENOSYS);
                }

                if (disk.Md5 != null)
                {
                    xattrs.Add("user.md5");
                }

                if (disk.Sha1 != null)
                {
                    xattrs.Add("user.sha1");
                }

                names = xattrs.ToArray();

                return(0);
            }

            CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);

            if (media == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length > 3)
            {
                return(Errno.ENOSYS);
            }

            if (media.Md5 != null)
            {
                xattrs.Add("user.md5");
            }

            if (media.Sha1 != null)
            {
                xattrs.Add("user.sha1");
            }

            if (media.Sha256 != null)
            {
                xattrs.Add("user.sha256");
            }

            if (media.SpamSum != null)
            {
                xattrs.Add("user.spamsum");
            }

            names = xattrs.ToArray();

            return(0);
        }
Beispiel #4
0
        protected override Errno OnGetPathExtendedAttribute(string path, string name, byte[] value,
                                                            out int bytesWritten)
        {
            bytesWritten = 0;

            string[] pieces = _vfs.SplitPath(path);

            if (pieces.Length == 0)
            {
                return(Errno.ENODATA);
            }

            long romSetId = _vfs.GetRomSetId(pieces[0]);

            if (romSetId <= 0)
            {
                return(Errno.ENOENT);
            }

            RomSet romSet = _vfs.GetRomSet(romSetId);

            if (romSet == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 1)
            {
                return(Errno.ENODATA);
            }

            CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);

            if (machine == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 2)
            {
                return(Errno.ENODATA);
            }

            CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);

            string hash = null;

            if (file != null)
            {
                if (pieces.Length > 3)
                {
                    return(Errno.ENOSYS);
                }

                switch (name)
                {
                case "user.crc32":
                    hash = file.Crc32;

                    break;

                case "user.md5":
                    hash = file.Md5;

                    break;

                case "user.sha1":
                    hash = file.Sha1;

                    break;

                case "user.sha256":
                    hash = file.Sha256;

                    break;

                case "user.sha384":
                    hash = file.Sha384;

                    break;

                case "user.sha512":
                    hash = file.Sha512;

                    break;
                }
            }
            else
            {
                CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);

                if (disk != null)
                {
                    switch (name)
                    {
                    case "user.md5":
                        hash = disk.Md5;

                        break;

                    case "user.sha1":
                        hash = disk.Sha1;

                        break;
                    }
                }
                else
                {
                    CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);

                    if (media == null)
                    {
                        return(Errno.ENOENT);
                    }

                    switch (name)
                    {
                    case "user.md5":
                        hash = media.Md5;

                        break;

                    case "user.sha1":
                        hash = media.Sha1;

                        break;

                    case "user.sha256":
                        hash = media.Sha256;

                        break;

                    case "user.spamsum":
                        hash = media.SpamSum;

                        break;
                    }
                }
            }

            if (hash == null)
            {
                return(Errno.ENODATA);
            }

            byte[] xattr = null;

            if (name == "user.spamsum")
            {
                xattr = Encoding.ASCII.GetBytes(hash);
            }
            else
            {
                xattr = new byte[hash.Length / 2];

                for (int i = 0; i < xattr.Length; i++)
                {
                    if (hash[i * 2] >= 0x30 &&
                        hash[i * 2] <= 0x39)
                    {
                        xattr[i] = (byte)((hash[i * 2] - 0x30) * 0x10);
                    }
                    else if (hash[i * 2] >= 0x41 &&
                             hash[i * 2] <= 0x46)
                    {
                        xattr[i] = (byte)((hash[i * 2] - 0x37) * 0x10);
                    }
                    else if (hash[i * 2] >= 0x61 &&
                             hash[i * 2] <= 0x66)
                    {
                        xattr[i] = (byte)((hash[i * 2] - 0x57) * 0x10);
                    }

                    if (hash[(i * 2) + 1] >= 0x30 &&
                        hash[(i * 2) + 1] <= 0x39)
                    {
                        xattr[i] += (byte)(hash[(i * 2) + 1] - 0x30);
                    }
                    else if (hash[(i * 2) + 1] >= 0x41 &&
                             hash[(i * 2) + 1] <= 0x46)
                    {
                        xattr[i] += (byte)(hash[(i * 2) + 1] - 0x37);
                    }
                    else if (hash[(i * 2) + 1] >= 0x61 &&
                             hash[(i * 2) + 1] <= 0x66)
                    {
                        xattr[i] += (byte)(hash[(i * 2) + 1] - 0x57);
                    }
                }
            }

            if (value == null)
            {
                bytesWritten = xattr.Length;

                return(0);
            }

            int maxSize = value.Length > xattr.Length ? xattr.Length : value.Length;

            Array.Copy(xattr, 0, value, 0, maxSize);
            bytesWritten = maxSize;

            return(0);
        }
Beispiel #5
0
        protected override Errno OnOpenHandle(string path, OpenedPathInfo info)
        {
            string[] pieces = _vfs.SplitPath(path);

            if (pieces.Length == 0)
            {
                return(Errno.EISDIR);
            }

            long romSetId = _vfs.GetRomSetId(pieces[0]);

            if (romSetId <= 0)
            {
                return(Errno.ENOENT);
            }

            RomSet romSet = _vfs.GetRomSet(romSetId);

            if (romSet == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 1)
            {
                return(Errno.EISDIR);
            }

            CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);

            if (machine == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 2)
            {
                return(Errno.EISDIR);
            }

            long handle = 0;
            Stat stat;

            CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);

            if (file != null)
            {
                if (pieces.Length > 3)
                {
                    return(Errno.ENOSYS);
                }

                if (file.Sha384 == null)
                {
                    return(Errno.ENOENT);
                }

                if (info.OpenAccess.HasFlag(OpenFlags.O_APPEND) ||
                    info.OpenAccess.HasFlag(OpenFlags.O_CREAT) ||
                    info.OpenAccess.HasFlag(OpenFlags.O_EXCL) ||
                    info.OpenAccess.HasFlag(OpenFlags.O_TRUNC))
                {
                    return(Errno.EROFS);
                }

                handle = _vfs.Open(file.Sha384, (long)file.Size);

                stat = new Stat
                {
                    st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                    st_nlink   = 1,
                    st_ctime   = NativeConvert.ToTimeT(file.CreatedOn.ToUniversalTime()),
                    st_mtime   = NativeConvert.ToTimeT(file.FileLastModification?.ToUniversalTime() ?? file.UpdatedOn.ToUniversalTime()),
                    st_blksize = 512,
                    st_blocks  = (long)(file.Size / 512),
                    st_ino     = file.Id,
                    st_size    = (long)file.Size
                };
            }
            else
            {
                CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);

                if (disk != null)
                {
                    if (pieces.Length > 3)
                    {
                        return(Errno.ENOSYS);
                    }

                    if (disk.Sha1 == null &&
                        disk.Md5 == null)
                    {
                        return(Errno.ENOENT);
                    }

                    if (info.OpenAccess.HasFlag(OpenFlags.O_APPEND) ||
                        info.OpenAccess.HasFlag(OpenFlags.O_CREAT) ||
                        info.OpenAccess.HasFlag(OpenFlags.O_EXCL) ||
                        info.OpenAccess.HasFlag(OpenFlags.O_TRUNC))
                    {
                        return(Errno.EROFS);
                    }

                    handle = _vfs.OpenDisk(disk.Sha1, disk.Md5);

                    stat = new Stat
                    {
                        st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                        st_nlink   = 1,
                        st_ctime   = NativeConvert.ToTimeT(disk.CreatedOn.ToUniversalTime()),
                        st_mtime   = NativeConvert.ToTimeT(disk.UpdatedOn.ToUniversalTime()),
                        st_blksize = 512,
                        st_blocks  = (long)(disk.Size / 512),
                        st_ino     = disk.Id,
                        st_size    = (long)disk.Size
                    };
                }
                else
                {
                    CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);

                    if (media == null)
                    {
                        return(Errno.ENOENT);
                    }

                    if (pieces.Length > 3)
                    {
                        return(Errno.ENOSYS);
                    }

                    if (media.Sha256 == null &&
                        media.Sha1 == null &&
                        media.Md5 == null)
                    {
                        return(Errno.ENOENT);
                    }

                    if (info.OpenAccess.HasFlag(OpenFlags.O_APPEND) ||
                        info.OpenAccess.HasFlag(OpenFlags.O_CREAT) ||
                        info.OpenAccess.HasFlag(OpenFlags.O_EXCL) ||
                        info.OpenAccess.HasFlag(OpenFlags.O_TRUNC))
                    {
                        return(Errno.EROFS);
                    }

                    handle = _vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5);

                    stat = new Stat
                    {
                        st_mode    = FilePermissions.S_IFREG | NativeConvert.FromOctalPermissionString("0444"),
                        st_nlink   = 1,
                        st_ctime   = NativeConvert.ToTimeT(media.CreatedOn.ToUniversalTime()),
                        st_mtime   = NativeConvert.ToTimeT(media.UpdatedOn.ToUniversalTime()),
                        st_blksize = 512,
                        st_blocks  = (long)(media.Size / 512),
                        st_ino     = media.Id,
                        st_size    = (long)media.Size
                    };
                }
            }

            if (handle <= 0)
            {
                return(Errno.ENOENT);
            }

            info.Handle = new IntPtr(handle);

            _fileStatHandleCache[handle] = stat;

            return(0);
        }
Beispiel #6
0
        protected override Errno OnAccessPath(string path, AccessModes mode)
        {
            string[] pieces = _vfs.SplitPath(path);

            if (pieces.Length == 0)
            {
                return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0);
            }

            long romSetId = _vfs.GetRomSetId(pieces[0]);

            if (romSetId <= 0)
            {
                return(Errno.ENOENT);
            }

            RomSet romSet = _vfs.GetRomSet(romSetId);

            if (romSet == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 1)
            {
                return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0);
            }

            CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);

            if (machine == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length == 2)
            {
                return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0);
            }

            CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);

            if (file != null)
            {
                if (pieces.Length > 3)
                {
                    return(Errno.ENOSYS);
                }

                return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0);
            }

            CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);

            if (disk != null)
            {
                if (pieces.Length > 3)
                {
                    return(Errno.ENOSYS);
                }

                return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0);
            }

            CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);

            if (media == null)
            {
                return(Errno.ENOENT);
            }

            if (pieces.Length > 3)
            {
                return(Errno.ENOSYS);
            }

            return(mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0);
        }