mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Allow pulling files off disk.
This commit is contained in:
		| @@ -59,6 +59,23 @@ public: | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| 	Bytes getFile(const Path& path) | ||||
| 	{ | ||||
| 		auto dirent = findFile(path); | ||||
| 		int sectors = (dirent->length + 255) / 256; | ||||
|  | ||||
| 		Bytes data; | ||||
| 		ByteWriter bw(data); | ||||
| 		for (int i = 0; i < sectors; i++) | ||||
| 		{ | ||||
| 			auto sector = getLogicalSector(dirent->start_sector + i); | ||||
| 			bw.append(sector); | ||||
| 		} | ||||
|  | ||||
| 		data.resize(dirent->length); | ||||
| 		return data; | ||||
| 	} | ||||
|  | ||||
| 	std::map<std::string, std::string> getMetadata(const Path& path) | ||||
| 	{ | ||||
| 		std::map<std::string, std::string> attributes; | ||||
|   | ||||
| @@ -6,7 +6,10 @@ | ||||
| /* Number of sectors on a 120kB disk. */ | ||||
| static constexpr int SECTOR_COUNT = 468; | ||||
|  | ||||
| /* Start sector for data (after the directory */ | ||||
| /* Start sector for the FAT (after the directory) */ | ||||
| static constexpr int FAT_START_SECTOR = 8; | ||||
|  | ||||
| /* Start sector for data (after the FAT) */ | ||||
| static constexpr int DATA_START_SECTOR = 14; | ||||
|  | ||||
| /* Size of a sector */ | ||||
| @@ -15,6 +18,9 @@ static constexpr int SECTOR_SIZE = 256; | ||||
| /* Number of dirents in a directory. */ | ||||
| static constexpr int DIRECTORY_SIZE = 128; | ||||
|  | ||||
| /* Number of sectors in the FAT. */ | ||||
| static constexpr int FAT_SECTORS = 4; | ||||
|  | ||||
| /* Number of sectors in a directory. */ | ||||
| static constexpr int DIRECTORY_SECTORS = 8; | ||||
|  | ||||
| @@ -68,6 +74,23 @@ public: | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| 	Bytes getFile(const Path& path) | ||||
| 	{ | ||||
| 		auto fat = readFat(); | ||||
| 		auto dirent = findFile(path); | ||||
| 		int sector = dirent->start_sector; | ||||
|  | ||||
| 		Bytes data; | ||||
| 		ByteWriter bw(data); | ||||
| 		while ((sector != 0) && (sector != 0xffff)) | ||||
| 		{ | ||||
| 			bw += getLogicalSector(sector - 1); | ||||
| 			sector = fat.at(sector); | ||||
| 		} | ||||
|  | ||||
| 		return data; | ||||
| 	} | ||||
|  | ||||
| 	std::map<std::string, std::string> getMetadata(const Path& path) | ||||
| 	{ | ||||
| 		std::map<std::string, std::string> attributes; | ||||
| @@ -85,6 +108,19 @@ public: | ||||
| 	} | ||||
|  | ||||
| private: | ||||
| 	std::vector<uint32_t> readFat() | ||||
| 	{ | ||||
| 		Bytes bytes = getLogicalSector(FAT_START_SECTOR, FAT_SECTORS); | ||||
| 		ByteReader br(bytes); | ||||
| 		std::vector<uint32_t> table; | ||||
|  | ||||
| 		table.push_back(0xffff); | ||||
| 		for (int sector = 1; sector != SECTOR_COUNT; sector++) | ||||
| 			table.push_back(br.read_be16()); | ||||
|  | ||||
| 		return table; | ||||
| 	} | ||||
|  | ||||
|     std::vector<std::unique_ptr<Brother120Dirent>> findAllFiles() | ||||
|     { | ||||
| 		std::vector<std::unique_ptr<Brother120Dirent>> result; | ||||
|   | ||||
| @@ -68,13 +68,19 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystem( | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Bytes Filesystem::getLogicalSector(uint32_t number) | ||||
| Bytes Filesystem::getLogicalSector(uint32_t number, uint32_t count) | ||||
| { | ||||
| 	if (number >= _locations.size()) | ||||
| 	if ((number+count) > _locations.size()) | ||||
| 		throw BadFilesystemException(); | ||||
|  | ||||
| 	auto& i = _locations[number]; | ||||
| 	return _sectors->get(std::get<0>(i), std::get<1>(i), std::get<2>(i))->data; | ||||
| 	Bytes data; | ||||
| 	ByteWriter bw(data); | ||||
| 	for (int i = 0; i < count; i++) | ||||
| 	{ | ||||
| 		auto& it = _locations[number + i]; | ||||
| 		bw += _sectors->get(std::get<0>(it), std::get<1>(it), std::get<2>(it))->data; | ||||
| 	} | ||||
| 	return data; | ||||
| } | ||||
|  | ||||
| void Filesystem::putLogicalSector(uint32_t number, const Bytes& data) | ||||
|   | ||||
| @@ -59,22 +59,22 @@ public: | ||||
|     virtual std::vector<std::unique_ptr<Dirent>> list(const Path& path) | ||||
| 	{ throw UnimplementedFilesystemException(); } | ||||
|  | ||||
|     virtual Bytes read(const Path& path) | ||||
|     virtual Bytes getFile(const Path& path) | ||||
| 	{ throw UnimplementedFilesystemException(); } | ||||
|  | ||||
|     virtual void write(const Path& path, const Bytes& data) | ||||
|     virtual void putFile(const Path& path, const Bytes& data) | ||||
| 	{ throw UnimplementedFilesystemException(); } | ||||
|  | ||||
| 	virtual std::map<std::string, std::string> getMetadata(const Path& path) | ||||
| 	{ throw UnimplementedFilesystemException(); } | ||||
|  | ||||
| 	virtual void setMetadata(const Path& path, const std::map<std::string, std::string>& metadata) | ||||
| 	virtual void putMetadata(const Path& path, const std::map<std::string, std::string>& metadata) | ||||
| 	{ throw UnimplementedFilesystemException(); } | ||||
|  | ||||
| protected: | ||||
| 	Filesystem(std::shared_ptr<SectorInterface> sectors); | ||||
|  | ||||
| 	Bytes getLogicalSector(uint32_t number); | ||||
| 	Bytes getLogicalSector(uint32_t number, uint32_t count = 1); | ||||
| 	void putLogicalSector(uint32_t number, const Bytes& data); | ||||
|  | ||||
| private: | ||||
|   | ||||
| @@ -3,6 +3,7 @@ include src/formats/build.mk | ||||
| FLUXENGINE_SRCS = \ | ||||
| 	src/fe-analysedriveresponse.cc \ | ||||
| 	src/fe-analyselayout.cc \ | ||||
| 	src/fe-getfile.cc \ | ||||
| 	src/fe-getfileinfo.cc \ | ||||
| 	src/fe-inspect.cc \ | ||||
| 	src/fe-ls.cc \ | ||||
|   | ||||
							
								
								
									
										44
									
								
								src/fe-getfile.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/fe-getfile.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| #include "globals.h" | ||||
| #include "flags.h" | ||||
| #include "fluxmap.h" | ||||
| #include "sector.h" | ||||
| #include "proto.h" | ||||
| #include "readerwriter.h" | ||||
| #include "imagereader/imagereader.h" | ||||
| #include "imagewriter/imagewriter.h" | ||||
| #include "lib/fluxsource/fluxsource.h" | ||||
| #include "lib/decoders/decoders.h" | ||||
| #include "fmt/format.h" | ||||
| #include "fluxengine.h" | ||||
| #include "lib/vfs/sectorinterface.h" | ||||
| #include "lib/vfs/vfs.h" | ||||
| #include "src/fileutils.h" | ||||
| #include <google/protobuf/text_format.h> | ||||
| #include <fstream> | ||||
|  | ||||
| static FlagGroup flags({ &fileFlags }); | ||||
|  | ||||
| static StringFlag directory({"-p", "--path"}, "path to work on", ""); | ||||
| static StringFlag output({"-o", "--output"}, "local filename to write to", ""); | ||||
|  | ||||
| int mainGetFile(int argc, const char* argv[]) | ||||
| { | ||||
|     if (argc == 1) | ||||
|         showProfiles("getfile", formats); | ||||
|     flags.parseFlagsWithConfigFiles(argc, argv, formats); | ||||
|  | ||||
| 	Path inputFilename(directory); | ||||
| 	if (inputFilename.size() == 0) | ||||
| 		Error() << "you must supply a filename to read"; | ||||
|  | ||||
| 	std::string outputFilename = output; | ||||
| 	if (outputFilename.empty()) | ||||
| 		outputFilename = inputFilename.back(); | ||||
| 	fmt::print("{}\n", outputFilename); | ||||
| 		 | ||||
| 	auto filesystem = createFilesystemFromConfig(); | ||||
| 	auto data = filesystem->getFile(inputFilename); | ||||
| 	data.writeToFile(outputFilename); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
| @@ -23,7 +23,7 @@ static StringFlag directory({"-p", "--path"}, "path to work on", ""); | ||||
| int mainGetFileInfo(int argc, const char* argv[]) | ||||
| { | ||||
|     if (argc == 1) | ||||
|         showProfiles("ls", formats); | ||||
|         showProfiles("getfileinfo", formats); | ||||
|     flags.parseFlagsWithConfigFiles(argc, argv, formats); | ||||
|  | ||||
| 	auto filesystem = createFilesystemFromConfig(); | ||||
|   | ||||
| @@ -6,6 +6,7 @@ typedef int command_cb(int agrc, const char* argv[]); | ||||
|  | ||||
| extern command_cb mainAnalyseDriveResponse; | ||||
| extern command_cb mainAnalyseLayout; | ||||
| extern command_cb mainGetFile; | ||||
| extern command_cb mainGetFileInfo; | ||||
| extern command_cb mainInspect; | ||||
| extern command_cb mainLs; | ||||
| @@ -37,6 +38,7 @@ static std::vector<Command> commands = | ||||
| 	{ "rawread",           mainRawRead,           "Reads raw flux from a disk. Warning: you can't use this to copy disks.", }, | ||||
|     { "rawwrite",          mainRawWrite,          "Writes a flux file to a disk. Warning: you can't use this to copy disks.", }, | ||||
| 	{ "ls",                mainLs,                "Show files on disk (or image).", }, | ||||
| 	{ "getfile",           mainGetFile,           "Read a file off a disk (or image).", }, | ||||
| 	{ "getfileinfo",       mainGetFileInfo,       "Read file metadata off a disk (or image).", }, | ||||
|     { "rpm",               mainRpm,               "Measures the disk rotational speed.", }, | ||||
|     { "seek",              mainSeek,              "Moves the disk head.", }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user