--- /dev/null
+/*
+ * Acess2 DiskTool
+ * - By John Hodge (thePowersGang)
+ *
+ * actions.c
+ * - High level actions that call the VFS
+ * # Kernel-space compiled
+ */
+#include <acess.h>
+#include <disktool_common.h>
+#include <Storage/LVM/include/lvm.h>
+
+// === IMPORTS ===
+extern int NativeFS_Install(char **Arguments);
+extern int LVM_Cleanup(void);
+
+// === PROTOTYPES ===
+void DiskTool_Initialise(void) __attribute__((constructor(101)));
+void DiskTool_Cleanup(void);
+ int DiskTool_int_TranslateOpen(const char *File, int Mode);
+ int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest);
+ int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest);
+void DiskTool_LVM_Cleanup(void *Handle);
+
+// === GLOBALS ===
+tLVM_VolType gDiskTool_VolumeType = {
+ .Name = "DiskTool",
+ .Read = DiskTool_LVM_Read,
+ .Write = DiskTool_LVM_Write,
+ .Cleanup = DiskTool_LVM_Cleanup
+};
+
+// === CODE ===
+void DiskTool_Initialise(void)
+{
+ VFS_Init();
+ NativeFS_Install(NULL);
+ VFS_MkDir("/Native");
+ VFS_Mount("/", "/Native", "nativefs", "");
+}
+
+void DiskTool_Cleanup(void)
+{
+ int vfs_rv, lvm_rv;
+ int nNochangeLoop = 0;
+ // Unmount all
+ do {
+ lvm_rv = LVM_Cleanup();
+ vfs_rv = VFS_UnmountAll();
+ Log_Debug("DiskTool", "Unmounted %i volumes", vfs_rv);
+ if( vfs_rv == 0 && lvm_rv == 0 ) {
+ nNochangeLoop ++;
+ if(nNochangeLoop == 2) {
+ Log_Error("DiskTool", "Possible handle leak");
+ break;
+ }
+ }
+ else {
+ nNochangeLoop = 0;
+ }
+ }
+ while( vfs_rv >= 0 || lvm_rv != 0 );
+}
+
+int DiskTool_RegisterLVM(const char *Identifier, const char *Path)
+{
+ int fd = DiskTool_int_TranslateOpen(Path, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
+ if(fd == -1) {
+ Log_Notice("DiskTool", "Can't open '%s' for LVM %s", Path, Identifier);
+ return -1;
+ }
+ VFS_Seek(fd, 0, SEEK_END);
+ LVM_AddVolume( &gDiskTool_VolumeType, Identifier, (void*)(tVAddr)fd, 512, VFS_Tell(fd)/512);
+ Log_Debug("DiskTool", "Registered '%s' for LVM %s", Path, Identifier);
+ return 0;
+}
+
+int DiskTool_MountImage(const char *Identifier, const char *Path)
+{
+ // Validate Identifier and make mountpoint string
+ char mountpoint[sizeof("/Mount/") + strlen(Identifier) + 1];
+ strcpy(mountpoint, "/Mount/");
+ strcat(mountpoint, Identifier);
+
+ // Translate path
+ size_t tpath_len = DiskTool_int_TranslatePath(NULL, Path);
+ char tpath[tpath_len-1];
+ DiskTool_int_TranslatePath(tpath, Path);
+
+ // Call mount
+ VFS_MkDir(mountpoint);
+ // TODO: Detect filesystem?
+ return VFS_Mount(tpath, mountpoint, "", "");
+}
+
+int DiskTool_MkDir(const char *Directory)
+{
+ return -1;
+}
+
+int DiskTool_Copy(const char *Source, const char *Destination)
+{
+ int src = DiskTool_int_TranslateOpen(Source, VFS_OPENFLAG_READ);
+ if( src == -1 ) {
+ Log_Error("DiskTool", "Unable to open %s for reading", Source);
+ return -1;
+ }
+ int dst = DiskTool_int_TranslateOpen(Destination, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_CREATE);
+ if( dst == -1 ) {
+ Log_Error("DiskTool", "Unable to open %s for writing", Destination);
+ VFS_Close(src);
+ return -1;
+ }
+
+ char buf[1024];
+ size_t len, total = 0;
+ while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
+ VFS_Write(dst, len, buf);
+ total += len;
+ }
+ VFS_Write(dst, len, buf), total += len;
+
+ Log_Notice("DiskTool", "Copied %i from %s to %s", total, Source, Destination);
+
+ VFS_Close(dst);
+ VFS_Close(src);
+
+ return 0;
+}
+
+int DiskTool_ListDirectory(const char *Directory)
+{
+ int fd = DiskTool_int_TranslateOpen(Directory, VFS_OPENFLAG_READ|VFS_OPENFLAG_DIRECTORY);
+ if(fd == -1) {
+// fprintf(stderr, "Can't open '%s'\n", Directory);
+ return -1;
+ }
+
+ Log("Directory listing of '%s'", Directory);
+
+ char name[256];
+ while( VFS_ReadDir(fd, name) )
+ {
+ tFInfo fi;
+ int child = VFS_OpenChild(fd, name, 0);
+ if( child != -1 )
+ {
+ VFS_FInfo(child, &fi, 0);
+ VFS_Close(child);
+ }
+ Log("- %02x %6lli %s", fi.flags, fi.size, name);
+ }
+
+ VFS_Close(fd);
+
+ return 0;
+}
+
+int DiskTool_Cat(const char *File)
+{
+ int src = DiskTool_int_TranslateOpen(File, VFS_OPENFLAG_READ);
+ if( src == -1 ) {
+ Log_Error("DiskTool", "Unable to open %s for reading", File);
+ return -1;
+ }
+
+ char buf[1024];
+ size_t len, total = 0;
+ while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
+ _fwrite_stdout(len, buf);
+ total += len;
+ }
+ _fwrite_stdout(len, buf);
+ total += len;
+
+ Log_Notice("DiskTool", "%i bytes from %s", total, File);
+
+ VFS_Close(src);
+ return 0;
+}
+
+int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest)
+{
+ return VFS_ReadAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
+}
+int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest)
+{
+ return VFS_WriteAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
+}
+void DiskTool_LVM_Cleanup(void *Handle)
+{
+ VFS_Close( (int)(tVAddr)Handle );
+}
+
+// --- Internal helpers ---
+int DiskTool_int_TranslateOpen(const char *File, int Flags)
+{
+ size_t tpath_len = DiskTool_int_TranslatePath(NULL, File);
+ if(tpath_len == 0)
+ return -1;
+ char tpath[tpath_len-1];
+ DiskTool_int_TranslatePath(tpath, File);
+
+ return VFS_Open(tpath, Flags);
+}
+