From fa0e76cf84c000823a372ead36154fc39cefccb8 Mon Sep 17 00:00:00 2001 From: Terence Boldt Date: Sun, 6 Jun 2021 20:15:41 -0400 Subject: [PATCH] Add flags to command line --- main.go | 59 ++++++++++++++++++++++++------------------------ prodos/bitmap.go | 37 ++++++++++++++++++++++++++++++ prodos/file.go | 9 +------- prodos/text.go | 18 +++++++++++++++ 4 files changed, 86 insertions(+), 37 deletions(-) create mode 100644 prodos/bitmap.go diff --git a/main.go b/main.go index f1c6436..c8aa727 100644 --- a/main.go +++ b/main.go @@ -1,48 +1,49 @@ package main import ( + "flag" "fmt" + "io/fs" "os" "github.com/tjboldt/ProDOS-Utilities/prodos" ) func main() { - if len(os.Args) < 2 || len(os.Args) > 3 { - fmt.Printf("Usage:\n") - fmt.Printf(" ProDOS-Utilities DRIVE_IMAGE\n") - fmt.Printf(" ProDOS-Utilities DRIVE_IMAGE /FULL_PATH\n") + var fileName string + var pathName string + var command string + var outFileName string + flag.StringVar(&fileName, "driveimage", "", "A ProDOS format drive image") + flag.StringVar(&pathName, "path", "", "Path name in ProDOS drive image") + flag.StringVar(&command, "command", "ls", "Command to execute: ls, get, put, volumebitmap") + flag.StringVar(&outFileName, "outfile", "export.bin", "Name of file to write") + flag.Parse() + + if len(fileName) == 0 { + fmt.Printf("Missing driveimage. Run with --help for more info.\n") os.Exit(1) } - - fileName := os.Args[1] - pathName := "" - - if len(os.Args) == 3 { - pathName = os.Args[2] - } - file, err := os.OpenFile(fileName, os.O_RDWR, 0755) if err != nil { os.Exit(1) } - // empty path or volume name means read root directory - volumeHeader, fileEntries := prodos.ReadDirectory(file, pathName) - - fmt.Printf("VOLUME: %s\n\n", volumeHeader.VolumeName) - fmt.Printf("NAME TYPE BLOCKS MODIFIED CREATED ENDFILE SUBTYPE\n\n") - - for i := 0; i < len(fileEntries); i++ { - fmt.Printf("%-15s %s %7d %s %s %8d %8d\n", - fileEntries[i].FileName, - prodos.FileTypeToString(fileEntries[i].FileType), - fileEntries[i].BlocksUsed, - prodos.TimeToString(fileEntries[i].ModifiedTime), - prodos.TimeToString(fileEntries[i].CreationTime), - fileEntries[i].EndOfFile, - fileEntries[i].AuxType, - ) + switch command { + case "ls": + volumeHeader, fileEntries := prodos.ReadDirectory(file, pathName) + prodos.DumpDirectory(volumeHeader, fileEntries) + case "volumebitmap": + volumeBitmap := prodos.ReadVolumeBitmap(file) + prodos.DumpBlock(volumeBitmap) + case "get": + if len(pathName) == 0 { + fmt.Println("Missing pathname") + os.Exit(1) + } + getFile := prodos.LoadFile(file, pathName) + os.WriteFile(outFileName, getFile, fs.FileMode(os.O_RDWR)) + default: + os.Exit(1) } - fmt.Printf("\n") } diff --git a/prodos/bitmap.go b/prodos/bitmap.go new file mode 100644 index 0000000..1734128 --- /dev/null +++ b/prodos/bitmap.go @@ -0,0 +1,37 @@ +package prodos + +import "os" + +func ReadVolumeBitmap(file *os.File) []byte { + headerBlock := ReadBlock(file, 2) + + volumeHeader := parseVolumeHeader(headerBlock) + + bitmap := make([]byte, volumeHeader.TotalBlocks/8+1) + + totalBitmapBlocks := volumeHeader.TotalBlocks / 8 / 512 + + for i := 0; i <= totalBitmapBlocks; i++ { + bitmapBlock := ReadBlock(file, i+volumeHeader.BitmapStartBlock) + + for j := 0; j < 512; j++ { + bitmap[i*512+j] = bitmapBlock[j] + } + } + + return bitmap +} + +func WriteVolumeBitmap(file *os.File, bitmap []byte) { + headerBlock := ReadBlock(file, 2) + + volumeHeader := parseVolumeHeader(headerBlock) + + for i := 0; i < len(bitmap)/512/8; i++ { + WriteBlock(file, volumeHeader.BitmapStartBlock+1, bitmap[i*512:i*512+513]) + } +} + +func FindFreeBlocks(numberOfBlocks int) []int { + return nil +} diff --git a/prodos/file.go b/prodos/file.go index a7d92e3..6764939 100644 --- a/prodos/file.go +++ b/prodos/file.go @@ -1,7 +1,6 @@ package prodos import ( - "fmt" "os" "strings" ) @@ -20,7 +19,7 @@ func LoadFile(file *os.File, path string) []byte { directory := directoryBuilder.String() fileName := paths[len(paths)-1] - volumeHeader, fileEntries := ReadDirectory(file, directory) + _, fileEntries := ReadDirectory(file, directory) if fileEntries == nil { return nil @@ -34,12 +33,6 @@ func LoadFile(file *os.File, path string) []byte { } } - DumpVolumeHeader(volumeHeader) - - fmt.Println() - - DumpFileEntry(fileEntry) - switch fileEntry.StorageType { case StorageSeedling: return ReadBlock(file, fileEntry.StartingBlock)[0:fileEntry.EndOfFile] diff --git a/prodos/text.go b/prodos/text.go index af61205..6b042a9 100644 --- a/prodos/text.go +++ b/prodos/text.go @@ -120,3 +120,21 @@ func DumpBlock(buffer []byte) { fmt.Printf("\n") } } + +func DumpDirectory(volumeHeader VolumeHeader, fileEntries []FileEntry) { + fmt.Printf("VOLUME: %s\n\n", volumeHeader.VolumeName) + fmt.Printf("NAME TYPE BLOCKS MODIFIED CREATED ENDFILE SUBTYPE\n\n") + + for i := 0; i < len(fileEntries); i++ { + fmt.Printf("%-15s %s %7d %s %s %8d %8d\n", + fileEntries[i].FileName, + FileTypeToString(fileEntries[i].FileType), + fileEntries[i].BlocksUsed, + TimeToString(fileEntries[i].ModifiedTime), + TimeToString(fileEntries[i].CreationTime), + fileEntries[i].EndOfFile, + fileEntries[i].AuxType, + ) + } + fmt.Printf("\n") +}