Move fs-filo to filo-fs

Signed-off-by: Thomas Heijligen <src@posteo.de>
diff --git a/src/filo-fs-ext2.adb b/src/filo-fs-ext2.adb
new file mode 100644
index 0000000..7bd2c15
--- /dev/null
+++ b/src/filo-fs-ext2.adb
@@ -0,0 +1,201 @@
+-- Derived from GRUB  --  GRand Unified Bootloader
+-- Copyright (C) 1999, 2001, 2003  Free Software Foundation, Inc.
+-- Copyright (C) 2023 secunet Security Networks AG
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+
+with System;
+with Interfaces;
+with Interfaces.C;
+with Interfaces.C.Strings;
+
+with FILO.Blockdev;
+with FILO.FS.VFS;
+
+use Interfaces.C;
+
+package body FILO.FS.Ext2 is
+
+   function Is_Mounted (State : T) return Boolean is (State.S >= Mounted);
+   function Is_Open (State : T) return Boolean is (State.S = File_Opened);
+
+   --------------------------------------------------------------------------
+
+   SUPERBLOCK_SIZE            : constant := 1024;
+   SUPERBLOCK_BLOCKS          : constant := SUPERBLOCK_SIZE / BLOCK_SIZE;
+
+   SUPERBLOCK_MAGIC           : constant := 16#ef53#;
+   OLD_REV                    : constant := 0;
+   DYNAMIC_REV                : constant := 1;
+   FEATURE_INCOMPAT_EXTENTS   : constant := 16#0040#;
+   FEATURE_INCOMPAT_64BIT     : constant := 16#0080#;
+
+   procedure Mount
+     (State    : in out T;
+      Part_Len : in     Partition_Length;
+      Success  :    out Boolean)
+   is
+      Super_Block : Buffer_Type (0 .. SUPERBLOCK_SIZE - 1) := (others => 0);
+   begin
+      if Part_Len < 2 * SUPERBLOCK_SIZE then
+         Success := False;
+         return;
+      end if;
+
+      Blockdev.Read (Super_Block, 1 * SUPERBLOCK_SIZE, Success);
+      if not Success then
+         return;
+      end if;
+
+      if Read_LE16 (Super_Block, 14 * 4) /= 16#ef53# then
+         Success := False;
+         return;
+      end if;
+
+      State.Part_Len := Part_Len;
+      State.First_Data_Block := Block_Offset (Read_LE32 (Super_Block, 5 * 4));
+
+      declare
+         S_Log_Block_Size : constant Unsigned_32 := Read_LE32 (Super_Block, 6 * 4);
+      begin
+         if S_Log_Block_Size <= Unsigned_32 (Log_Block_Size'Last - 10) then
+            State.Block_Size_Bits := Log_Block_Size (S_Log_Block_Size + 10);
+         else
+            Success := False;
+            return;
+         end if;
+      end;
+
+      declare
+         S_Inodes_Per_Group : constant Unsigned_32 := Read_LE32 (Super_Block, 10 * 4);
+      begin
+         if S_Inodes_Per_Group in 1 .. Unsigned_32 (Positive'Last) then
+            State.Inodes_Per_Group := Positive (S_Inodes_Per_Group);
+         else
+            Success := False;
+            return;
+         end if;
+      end;
+
+      declare
+         S_Rev_Level : constant Unsigned_32 := Read_LE32 (Super_Block, 19 * 4);
+      begin
+         if S_Rev_Level >= DYNAMIC_REV then
+            declare
+               S_Inode_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 22 * 4);
+            begin
+               if S_Inode_Size in
+                  Unsigned_16 (Inode_Size'First) .. Unsigned_16 (Inode_Size'Last)
+               then
+                  State.Inode_Size := Inode_Size (S_Inode_Size);
+               else
+                  Success := False;
+                  return;
+               end if;
+            end;
+         else
+            State.Inode_Size := Inode_Size'First;
+         end if;
+      end;
+
+      declare
+         S_Feature_Incompat : constant Unsigned_32 := Read_LE32 (Super_Block, 24 * 4);
+      begin
+         State.Feature_Extents := (S_Feature_Incompat and FEATURE_INCOMPAT_EXTENTS) /= 0;
+         State.Feature_64Bit     := (S_Feature_Incompat and FEATURE_INCOMPAT_64BIT) /= 0;
+         if State.Feature_64Bit then
+            declare
+               S_Desc_Size : constant Unsigned_16 := Read_LE16 (Super_Block, 63 * 4 + 2);
+            begin
+               if S_Desc_Size in
+                  Unsigned_16 (Desc_Size'First) .. Unsigned_16 (Desc_Size'Last)
+               then
+                  State.Desc_Size := Desc_Size (S_Desc_Size);
+               else
+                  Success := False;
+                  return;
+               end if;
+            end;
+         else
+            State.Desc_Size := Desc_Size'First;
+         end if;
+      end;
+
+      State.S := Mounted;
+   end Mount;
+
+   procedure Open
+     (State       : in out T;
+      File_Len    :    out File_Length;
+      File_Path   : in     String;
+      Success     : out    Boolean)
+   is
+   begin
+      File_Len := 0;
+      Success := False;
+   end Open;
+
+   procedure Close (State : in out T) is
+   begin
+      State.S := Mounted;
+   end Close;
+
+   procedure Read
+     (State    : in out T;
+      File_Len : in     File_Length;
+      File_Pos : in out File_Offset;
+      Buf      :    out Buffer_Type;
+      Len      :    out Natural)
+   is
+   begin
+      Buf := (others => 0);
+      Len := 0;
+   end Read;
+
+   --------------------------------------------------------------------------
+
+   package C is new VFS (T => T, Initial => (S => Unmounted, others => <>));
+
+   function C_Mount return int
+   with
+      Export,
+      Convention => C,
+      External_Name => "ext2fs_mount";
+   function C_Mount return int
+   with
+      SPARK_Mode => Off
+   is
+   begin
+      return C.C_Mount;
+   end C_Mount;
+
+   function C_Open (File_Path : Strings.chars_ptr) return int
+   with
+      Export,
+      Convention => C,
+      External_Name => "ext2fs_dir";
+   function C_Open (File_Path : Strings.chars_ptr) return int
+   with
+      SPARK_Mode => Off
+   is
+   begin
+      return C.C_Open (File_Path);
+   end C_Open;
+
+   function C_Read (Buf : System.Address; Len : int) return int
+   with
+      Export,
+      Convention => C,
+      External_Name => "ext2fs_read";
+   function C_Read (Buf : System.Address; Len : int) return int
+   with
+      SPARK_Mode => Off
+   is
+   begin
+      return C.C_Read (Buf, Len);
+   end C_Read;
+
+end FILO.FS.Ext2;