mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:42:44 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			232 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "Ext2FileSystem.h"
 | |
| #include "FileBackedDiskDevice.h"
 | |
| #include "VirtualFileSystem.h"
 | |
| #include "FileHandle.h"
 | |
| #include "SyntheticFileSystem.h"
 | |
| #include "ZeroDevice.h"
 | |
| #include "NullDevice.h"
 | |
| #include "FullDevice.h"
 | |
| #include "RandomDevice.h"
 | |
| #include <cstring>
 | |
| #include <AK/SimpleMalloc.h>
 | |
| #include <AK/StdLib.h>
 | |
| #include <AK/kmalloc.h>
 | |
| #include <AK/ktime.h>
 | |
| 
 | |
| static RetainPtr<FileSystem> makeFileSystem(const char* imagePath);
 | |
| 
 | |
| int main(int c, char** v)
 | |
| {
 | |
|     const char* filename = "small.fs";
 | |
|     if (c >= 2)
 | |
|         filename = v[1];
 | |
| 
 | |
|     VirtualFileSystem vfs;
 | |
| 
 | |
|     auto zero = make<ZeroDevice>();
 | |
|     vfs.registerCharacterDevice(1, 5, *zero);
 | |
| 
 | |
|     auto null = make<NullDevice>();
 | |
|     vfs.registerCharacterDevice(1, 3, *null);
 | |
| 
 | |
|     auto full = make<FullDevice>();
 | |
|     vfs.registerCharacterDevice(1, 7, *full);
 | |
| 
 | |
|     auto random = make<RandomDevice>();
 | |
|     vfs.registerCharacterDevice(1, 8, *random);
 | |
| 
 | |
|     if (!vfs.mountRoot(makeFileSystem(filename))) {
 | |
|         printf("Failed to mount root :(\n");
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
| #if 0
 | |
|     auto newFile = vfs.create("/empty");
 | |
|     printf("vfs.create: %p\n", newFile.ptr());
 | |
| #endif
 | |
| #if 1
 | |
|     auto newDir = vfs.mkdir("/mydir");
 | |
|     printf("vfs.mkdir: %p\n", newDir.ptr());
 | |
| #endif
 | |
|     //return 0;
 | |
| 
 | |
|     if (!strcmp(v[0], "./vcat")) {
 | |
|         auto handle = vfs.open(v[2]);
 | |
|         if (!handle) {
 | |
|             printf("failed to open %s inside fs image\n", v[2]);
 | |
|             return 1;
 | |
|         }
 | |
|         auto contents = handle->readEntireFile();
 | |
| 
 | |
|         FILE* fout = fopen(v[3], "w");
 | |
|         if (!fout) {
 | |
|             printf("failed to open %s for output\n", v[3]);
 | |
|             return 1;
 | |
|         }
 | |
|         fwrite(contents.pointer(), sizeof(char), contents.size(), fout);
 | |
|         fclose(fout);
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     auto synthfs = SyntheticFileSystem::create();
 | |
|     bool success = static_cast<FileSystem&>(*synthfs).initialize();
 | |
|     printf("synth->initialize(): returned %u\n", success);
 | |
| 
 | |
|     vfs.mount(std::move(synthfs), "/syn");
 | |
| 
 | |
|     vfs.listDirectory("/");
 | |
|     printf("list /syn:\n");
 | |
|     vfs.listDirectory("/syn");
 | |
| 
 | |
| #if 0
 | |
|     auto handle = vfs.open("/home/andreas/../../home/./andreas/./file2");
 | |
|     printf("handle = %p\n", handle.ptr());
 | |
|     ASSERT(handle);
 | |
| 
 | |
|     auto contents = handle->readEntireFile();
 | |
|     ASSERT(contents);
 | |
| 
 | |
|     printf("contents: '%s'\n", contents->pointer());
 | |
| #endif
 | |
| 
 | |
|     String currentDirectory = "/";
 | |
| 
 | |
|     while (true) {
 | |
|         char cmdbuf[256];
 | |
|         printf("::>");
 | |
|         fflush(stdout);
 | |
|         fgets(cmdbuf, sizeof(cmdbuf), stdin);
 | |
| 
 | |
|         if (cmdbuf[strlen(cmdbuf) - 1] == '\n')
 | |
|             cmdbuf[strlen(cmdbuf) - 1] = '\0';
 | |
| 
 | |
|         String command = cmdbuf;
 | |
|         auto parts = command.split(' ');
 | |
| 
 | |
|         if (parts.isEmpty())
 | |
|             continue;
 | |
| 
 | |
|         String cmd = parts[0];
 | |
| 
 | |
|         if (cmd == "q")
 | |
|             break;
 | |
| 
 | |
|         if (cmd == "pwd") {
 | |
|             printf("%s\n", currentDirectory.characters());
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "ls") {
 | |
|             vfs.listDirectory(currentDirectory);
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "lr") {
 | |
|             vfs.listDirectoryRecursively(currentDirectory);
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "cd" && parts.size() > 1) {
 | |
|             char buf[1024];
 | |
|             sprintf(buf, "%s/%s", currentDirectory.characters(), parts[1].characters());
 | |
|             if (vfs.isDirectory(buf)) {
 | |
|                 currentDirectory = buf;
 | |
|             } else {
 | |
|                 printf("No such directory: %s\n", buf);
 | |
|             }
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "mt" && parts.size() > 1) {
 | |
|             char buf[1024];
 | |
|             sprintf(buf, "%s/%s", currentDirectory.characters(), parts[1].characters());
 | |
|             vfs.touch(buf);
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "stat" && parts.size() > 1) {
 | |
|             char buf[1024];
 | |
|             sprintf(buf, "%s/%s", currentDirectory.characters(), parts[1].characters());
 | |
|             auto handle = vfs.open(buf);
 | |
|             if (!handle) {
 | |
|                 printf("Can't open '%s' :(\n", buf);
 | |
|                 continue;
 | |
|             }
 | |
|             Unix::stat st;
 | |
|             int rc = handle->stat(&st);
 | |
|             if (rc < 0) {
 | |
|                 printf("stat failed: %d\n", rc);
 | |
|                 continue;
 | |
|             }
 | |
|             printf("st_dev:     %u\n", st.st_dev);
 | |
|             printf("st_ino:     %u\n", st.st_ino);
 | |
|             printf("st_mode:    %o\n", st.st_mode);
 | |
|             printf("st_nlink:   %u\n", st.st_nlink);
 | |
|             printf("st_uid:     %u\n", st.st_uid);
 | |
|             printf("st_gid:     %u\n", st.st_gid);
 | |
|             printf("st_rdev:    %u\n", st.st_rdev);
 | |
|             printf("st_size:    %lld\n", st.st_size);
 | |
|             printf("st_blksize: %u\n", st.st_blksize);
 | |
|             printf("st_blocks:  %u\n", st.st_blocks);
 | |
|             printf("st_atime:   %u - %s", st.st_atime, ctime(&st.st_atime));
 | |
|             printf("st_mtime:   %u - %s", st.st_mtime, ctime(&st.st_mtime));
 | |
|             printf("st_ctime:   %u - %s", st.st_ctime, ctime(&st.st_ctime));
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "cat" && parts.size() > 1) {
 | |
|             char pathbuf[1024];
 | |
|             sprintf(pathbuf, "%s/%s", currentDirectory.characters(), parts[1].characters());
 | |
|             auto handle = vfs.open(pathbuf);
 | |
|             if (!handle) {
 | |
|                 printf("failed to open %s\n", pathbuf);
 | |
|                 continue;
 | |
|             }
 | |
|             auto contents = handle->readEntireFile();
 | |
|             fwrite(contents.pointer(), sizeof(char), contents.size(), stdout);
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "kat" && parts.size() > 1) {
 | |
|             char pathbuf[1024];
 | |
|             sprintf(pathbuf, "%s/%s", currentDirectory.characters(), parts[1].characters());
 | |
|             auto handle = vfs.open(pathbuf);
 | |
|             if (!handle) {
 | |
|                 printf("failed to open %s\n", pathbuf);
 | |
|                 continue;
 | |
|             }
 | |
|             ssize_t nread;
 | |
|             byte buffer[512];
 | |
|             for (;;) {
 | |
|                 nread = handle->read(buffer, sizeof(buffer));
 | |
|                 if (nread <= 0)
 | |
|                     break;
 | |
|                 fwrite(buffer, 1, nread, stdout);
 | |
|             }
 | |
|             if (nread < 0)
 | |
|                 printf("ERROR: %d\n", nread);
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (cmd == "ma") {
 | |
|             SimpleMalloc::dump();
 | |
|             continue;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| RetainPtr<FileSystem> makeFileSystem(const char* imagePath)
 | |
| {
 | |
|     auto fsImage = FileBackedDiskDevice::create(imagePath, 512);
 | |
|     if (!fsImage->isValid()) {
 | |
|         fprintf(stderr, "Failed to open fs image file '%s'\n", imagePath);
 | |
|         exit(1);
 | |
|     }
 | |
|     auto ext2 = Ext2FileSystem::create(std::move(fsImage));
 | |
| 
 | |
|     bool success = static_cast<FileSystem&>(*ext2).initialize();
 | |
|     printf("ext2->initialize(): returned %u\n", success);
 | |
|     return ext2;
 | |
| }
 | 
