public static NeoVirtFS CreateNewFile(ObjectId parId, ObjectId volId, byte[] name, ReadOnlySpan <byte> path, mode_t mode, NeoVirtFSContent cont = null) { var id = ObjectId.GenerateNewId(); if (cont == null) { cont = NeoVirtFSContent.NewCache(path, id); } //Console.WriteLine($"Set newId for file to {id}"); var newRec = new NeoVirtFS { _id = id, Name = name, VolumeId = volId, ParentId = parId, Stat = NeoVirtFSStat.FileDefault((uint)mode), Content = cont, MaintLevel = false }; return(newRec); }
public NodeMark(FileNode m, int level, NodeMark[] stack, ObjectId rootOfVolume, IMongoDatabase db) { NeoVirtFSCol = db.NeoVirtFS(); NeoVirtFSDeletedCol = db.NeoVirtFSDeleted(); this.m = m; this.level = level; Name = m.Name; this.rootOfVolume = rootOfVolume; var v = new NeoAssets.Mongo.NeoVirtFS { Name = Name }; if (stack == null) { v.NARPImport = v.Name.GetString(); Console.WriteLine($"NARP Import {v.NARPImport}"); var vol = NeoVirtFSVolumesCol.FindSync(x => x._id == rootOfVolume).FirstOrDefault(); if (vol == null) { throw new Exception($"Can't find volume {v.NARPImport}"); } // Make sure everything exists - this should make the filesystem nodes namespaceId = vol.NameSpace; nodeId = vol.NodeId; v.VolumeId = rootOfVolume; return; } else { v.NARPImport = stack[0].Name.GetString(); //Console.WriteLine($"NARP Import {v.NARPImport}"); v.VolumeId = rootOfVolume; } // Need potential uuid5 handle - build our raw full path var realPath = new List <byte>(Encoding.ASCII.GetBytes("/NARP")); foreach (var p in stack) { realPath.Add((byte)'/'); realPath.AddRange(p.Name); } // Work the contents Broken = true; if (m.IsLnk) { var link = m.SymbolicLink.GetString(); if (link.StartsWith(AssetTag)) { var sha1 = link.Substring(AssetTag.Length); realPath.Add((byte)'/'); realPath.AddRange(m.Name); var fileuuid = GuidUtility.Create(GuidUtility.UrlNamespace, realPath.ToArray()); AssetFiles?baRec = null; try { var theFilter = Builders <AssetFiles> .Filter.Eq("_id", fileuuid); baRec = af.FindSync(theFilter).FirstOrDefault(); } catch (Exception ex) { Console.WriteLine($"Bad assetfile {ex.Message} {Encoding.UTF8.GetString(realPath.ToArray())} - id {fileuuid}"); baRec = null; } if (baRec == null) { Console.WriteLine($"Can't find assetfile {Encoding.UTF8.GetString(realPath.ToArray())} - using file defaults"); v.Stat = NeoVirtFSStat.FileDefault(); } else { baRec.CheckStat(); // Recover old format stat //Console.WriteLine($"Found baRec {baRec._id}"); v.Stat = new NeoVirtFSStat(baRec.Stat).ToFile(); } // We've got to check the asset to see if it's actually annealed -- it could be lost // If we're a mirror we'll skip it var assFilter = Builders <BakedAssets> .Filter.Eq("_id", sha1); var ass = bac.FindSync(assFilter).FirstOrDefault(); if (ass == null) { Console.WriteLine($"Can't find the asset - {Encoding.UTF8.GetString(realPath.ToArray())} / {Encoding.UTF8.GetString(m.Name)}"); v.Stat.st_size = 0; // We could conceivably try to look on the Asset for this - restore will need to fix the stat GenerateAssetFile(m, stack, rootOfVolume, v.Stat, sha1, realPath, true); return; // Should handle as 'lost' node } v.Stat.st_size = ass.FileLength; // RealLength is the compressed size if (!ass.Annealed.Value) { //Console.WriteLine($"Asset lost -- skipping - {Encoding.UTF8.GetString(realPath.ToArray())} / {Encoding.UTF8.GetString(m.Name.ToArray())}"); GenerateAssetFile(m, stack, rootOfVolume, v.Stat, sha1, realPath, true); return; } // If we get to here, we have an annealed asset type, so we need to process Broken = false; GenerateAssetFile(m, stack, rootOfVolume, v.Stat, sha1, realPath, false); return; } else { // Let's see if we can handle the simple link to an archive directory // If the original archive exists we can just do that. var dirs = link.Split("/"); if (dirs.Length == 4 && dirs[3].StartsWith("ARC-")) { Console.WriteLine($"Archive Link: {link} dirs={dirs.Length}"); // ARC-56a6f879e8cb392b22bb7577bc5d4ba117587261-ZIP // 01234567890123456789012345678901234567890123456789 // 000000000011111111112222222222333333333344444444 var sha1 = dirs[3][4..44].ToLowerInvariant();