mirror of
https://github.com/zellyn/diskii.git
synced 2025-04-28 15:37:05 +00:00
Add filetypes, and filetypes and put commands
This commit is contained in:
parent
300358e9bd
commit
10d2a1e027
@ -12,6 +12,8 @@ import (
|
||||
_ "github.com/zellyn/diskii/lib/supermon"
|
||||
)
|
||||
|
||||
var missingok bool // flag for whether to consider deleting a nonexistent file okay
|
||||
|
||||
// deleteCmd represents the delete command, used to delete a file.
|
||||
var deleteCmd = &cobra.Command{
|
||||
Use: "delete",
|
||||
@ -30,6 +32,7 @@ delete disk-image.dsk HELLO
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(deleteCmd)
|
||||
deleteCmd.Flags().BoolVarP(&missingok, "missingok", "f", false, "if true, don't consider deleting a nonexistent file an error")
|
||||
}
|
||||
|
||||
// runDelete performs the actual delete logic.
|
||||
@ -49,8 +52,7 @@ func runDelete(args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !deleted {
|
||||
// TODO(zellyn): implement -f flag to not warn on nonexistence.
|
||||
if !deleted && !missingok {
|
||||
return fmt.Errorf("file %q not found", args[1])
|
||||
}
|
||||
f, err := os.Create(args[0])
|
||||
|
45
cmd/filetypes.go
Normal file
45
cmd/filetypes.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright © 2016 Zellyn Hunter <zellyn@gmail.com>
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/zellyn/diskii/lib/disk"
|
||||
_ "github.com/zellyn/diskii/lib/dos3"
|
||||
_ "github.com/zellyn/diskii/lib/supermon"
|
||||
)
|
||||
|
||||
var all bool // flag for whether to show all filetypes
|
||||
|
||||
// filetypesCmd represents the filetypes command, used to display
|
||||
// valid filetypes recognized by diskii.
|
||||
var filetypesCmd = &cobra.Command{
|
||||
Use: "filetypes",
|
||||
Short: "print a list of filetypes",
|
||||
Long: `Print a list of filetypes understood by diskii`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := runFiletypes(args); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(-1)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(filetypesCmd)
|
||||
filetypesCmd.Flags().BoolVarP(&all, "all", "a", false, "display all types, including SOS types and reserved ranges")
|
||||
}
|
||||
|
||||
// runFiletypes performs the actual listing of filetypes.
|
||||
func runFiletypes(args []string) error {
|
||||
if len(args) != 0 {
|
||||
return fmt.Errorf("filetypes expects no arguments")
|
||||
}
|
||||
for _, typ := range disk.FiletypeNames(all) {
|
||||
fmt.Println(typ)
|
||||
}
|
||||
return nil
|
||||
}
|
35
cmd/put.go
35
cmd/put.go
@ -13,6 +13,9 @@ import (
|
||||
_ "github.com/zellyn/diskii/lib/supermon"
|
||||
)
|
||||
|
||||
var filetypeName string // flag for file type
|
||||
var overwrite bool // flag for whether to overwrite
|
||||
|
||||
// putCmd represents the put command, used to put the raw contents
|
||||
// of a file.
|
||||
var putCmd = &cobra.Command{
|
||||
@ -32,12 +35,14 @@ put disk-image.dsk HELLO <name of file with contents>
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(putCmd)
|
||||
putCmd.Flags().StringVarP(&filetypeName, "type", "t", "B", "Type of file (`diskii filetypes` to list)")
|
||||
putCmd.Flags().BoolVarP(&overwrite, "overwrite", "f", false, "whether to overwrite existing files")
|
||||
}
|
||||
|
||||
// runPut performs the actual put logic.
|
||||
func runPut(args []string) error {
|
||||
if len(args) != 3 {
|
||||
return fmt.Errorf("put expects a disk image filename, an disk-image filename, and a filename to read the contents from")
|
||||
return fmt.Errorf("usage: put <disk image> <target filename> <source filename>")
|
||||
}
|
||||
sd, err := disk.Open(args[0])
|
||||
if err != nil {
|
||||
@ -52,5 +57,33 @@ func runPut(args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
filetype, err := disk.FiletypeForName(filetypeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileInfo := disk.FileInfo{
|
||||
Descriptor: disk.Descriptor{
|
||||
Name: args[1],
|
||||
Length: len(contents),
|
||||
Type: filetype,
|
||||
},
|
||||
Data: contents,
|
||||
}
|
||||
_, err = op.PutFile(fileInfo, overwrite)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = sd.Write(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -48,8 +48,8 @@ const (
|
||||
FiletypeRelocatable Filetype = 0xFE // REL | ProDOS | EDASM relocatable object module file
|
||||
FiletypeSystem Filetype = 0xFF // SYS | ProDOS | System file
|
||||
FiletypeS Filetype = 0x100 // DOS 3.3 Type "S"
|
||||
FiletypeA Filetype = 0x101 // DOS 3.3 Type "new A"
|
||||
FiletypeB Filetype = 0x102 // DOS 3.3 Type "new B"
|
||||
FiletypeNewA Filetype = 0x101 // DOS 3.3 Type "new A"
|
||||
FiletypeNewB Filetype = 0x102 // DOS 3.3 Type "new B"
|
||||
// | 0D-0E | SOS | SOS reserved for future use
|
||||
// | 12-18 | SOS | SOS reserved for future use
|
||||
// | 1C-BF | SOS | SOS reserved for future use
|
||||
@ -64,52 +64,54 @@ type filetypeInfo struct {
|
||||
OneLetter string // The one-letter abbreviation (DOS 3.x)
|
||||
Desc string // The description of the type
|
||||
Stringified string // (Generated) result of calling String() on the Constant
|
||||
Extra bool // If true, exclude from normal display listing
|
||||
}
|
||||
|
||||
// names of Filetype constants above
|
||||
var filetypeInfos = []filetypeInfo{
|
||||
{FiletypeTypeless, "Typeless", "", "", "Typeless file", ""},
|
||||
{FiletypeBadBlocks, "BadBlocks", "", "", "Bad blocks file", ""},
|
||||
{FiletypeSOSPascalCode, "SOSPascalCode", "", "", "PASCAL code file", ""},
|
||||
{FiletypeSOSPascalText, "SOSPascalText", "", "", "PASCAL text file", ""},
|
||||
{FiletypeASCIIText, "ASCIIText", "T", "TXT", "ASCII text file", ""},
|
||||
{FiletypeSOSPascalText2, "SOSPascalText2", "", "", "PASCAL text file", ""},
|
||||
{FiletypeBinary, "Binary", "B", "BIN", "Binary file", ""},
|
||||
{FiletypeFont, "Font", "", "", "Font file", ""},
|
||||
{FiletypeGraphicsScreen, "GraphicsScreen", "", "", "Graphics screen file", ""},
|
||||
{FiletypeBusinessBASIC, "BusinessBASIC", "", "", "Business BASIC program file", ""},
|
||||
{FiletypeBusinessBASICData, "BusinessBASICData", "", "", "Business BASIC data file", ""},
|
||||
{FiletypeSOSWordProcessor, "SOSWordProcessor", "", "", "Word processor file", ""},
|
||||
{FiletypeSOSSystem, "SOSSystem", "", "", "SOS system file", ""},
|
||||
{FiletypeDirectory, "Directory", "", "DIR", "Directory file", ""},
|
||||
{FiletypeRPSData, "RPSData", "", "", "RPS data file", ""},
|
||||
{FiletypeRPSIndex, "RPSIndex", "", "", "RPS index file", ""},
|
||||
{FiletypeAppleWorksDatabase, "AppleWorksDatabase", "", "ADB", "AppleWorks data base file", ""},
|
||||
{FiletypeAppleWorksWordProcessor, "AppleWorksWordProcessor", "", "AWP", "AppleWorks word processing file", ""},
|
||||
{FiletypeAppleWorksSpreadsheet, "AppleWorksSpreadsheet", "", "ASP", "AppleWorks spreadsheet file", ""},
|
||||
{FiletypePascal, "Pascal", "", "PAS", "ProDOS PASCAL file", ""},
|
||||
{FiletypeCommand, "Command", "", "CMD", "Added command file", ""},
|
||||
{FiletypeUserDefinedF1, "UserDefinedF1", "", "", "ProDOS user defined file type F1", ""},
|
||||
{FiletypeUserDefinedF2, "UserDefinedF2", "", "", "ProDOS user defined file type F2", ""},
|
||||
{FiletypeUserDefinedF3, "UserDefinedF3", "", "", "ProDOS user defined file type F3", ""},
|
||||
{FiletypeUserDefinedF4, "UserDefinedF4", "", "", "ProDOS user defined file type F4", ""},
|
||||
{FiletypeUserDefinedF5, "UserDefinedF5", "", "", "ProDOS user defined file type F5", ""},
|
||||
{FiletypeUserDefinedF6, "UserDefinedF6", "", "", "ProDOS user defined file type F6", ""},
|
||||
{FiletypeUserDefinedF7, "UserDefinedF7", "", "", "ProDOS user defined file type F7", ""},
|
||||
{FiletypeUserDefinedF8, "UserDefinedF8", "", "", "ProDOS user defined file type F8", ""},
|
||||
{FiletypeIntegerBASIC, "IntegerBASIC", "I", "INT", "Integer BASIC program file", ""},
|
||||
{FiletypeIntegerBASICVariables, "IntegerBASICVariables", "", "IVR", "Integer BASIC variables file", ""},
|
||||
{FiletypeApplesoftBASIC, "ApplesoftBASIC", "A", "BAS", "Applesoft BASIC program file", ""},
|
||||
{FiletypeApplesoftBASICVariables, "ApplesoftBASICVariables", "", "VAR", "Applesoft BASIC variables file", ""},
|
||||
{FiletypeRelocatable, "Relocatable", "R", "REL", "EDASM relocatable object module file", ""},
|
||||
{FiletypeSystem, "System", "", "SYS", "System file", ""},
|
||||
{FiletypeS, "S", "S", "", `DOS 3.3 Type "S"`, ""},
|
||||
{FiletypeA, "A", "A", "", `DOS 3.3 Type "new A"`, ""},
|
||||
{FiletypeB, "B", "B", "", `DOS 3.3 Type "new B"`, ""},
|
||||
{FiletypeTypeless, "Typeless", "", "", "Typeless file", "", false},
|
||||
{FiletypeBadBlocks, "BadBlocks", "", "", "Bad blocks file", "", false},
|
||||
{FiletypeSOSPascalCode, "SOSPascalCode", "", "", "PASCAL code file", "", true},
|
||||
{FiletypeSOSPascalText, "SOSPascalText", "", "", "PASCAL text file", "", true},
|
||||
{FiletypeASCIIText, "ASCIIText", "T", "TXT", "ASCII text file", "", false},
|
||||
{FiletypeSOSPascalText2, "SOSPascalText2", "", "", "PASCAL text file", "", true},
|
||||
{FiletypeBinary, "Binary", "B", "BIN", "Binary file", "", false},
|
||||
{FiletypeFont, "Font", "", "", "Font file", "", true},
|
||||
{FiletypeGraphicsScreen, "GraphicsScreen", "", "", "Graphics screen file", "", true},
|
||||
{FiletypeBusinessBASIC, "BusinessBASIC", "", "", "Business BASIC program file", "", true},
|
||||
{FiletypeBusinessBASICData, "BusinessBASICData", "", "", "Business BASIC data file", "", true},
|
||||
{FiletypeSOSWordProcessor, "SOSWordProcessor", "", "", "Word processor file", "", true},
|
||||
{FiletypeSOSSystem, "SOSSystem", "", "", "SOS system file", "", true},
|
||||
{FiletypeDirectory, "Directory", "", "DIR", "Directory file", "", false},
|
||||
{FiletypeRPSData, "RPSData", "", "", "RPS data file", "", true},
|
||||
{FiletypeRPSIndex, "RPSIndex", "", "", "RPS index file", "", true},
|
||||
{FiletypeAppleWorksDatabase, "AppleWorksDatabase", "", "ADB", "AppleWorks data base file", "", false},
|
||||
{FiletypeAppleWorksWordProcessor, "AppleWorksWordProcessor", "", "AWP", "AppleWorks word processing file", "", false},
|
||||
{FiletypeAppleWorksSpreadsheet, "AppleWorksSpreadsheet", "", "ASP", "AppleWorks spreadsheet file", "", false},
|
||||
{FiletypePascal, "Pascal", "", "PAS", "ProDOS PASCAL file", "", false},
|
||||
{FiletypeCommand, "Command", "", "CMD", "Added command file", "", false},
|
||||
{FiletypeUserDefinedF1, "UserDefinedF1", "", "", "ProDOS user defined file type F1", "", true},
|
||||
{FiletypeUserDefinedF2, "UserDefinedF2", "", "", "ProDOS user defined file type F2", "", true},
|
||||
{FiletypeUserDefinedF3, "UserDefinedF3", "", "", "ProDOS user defined file type F3", "", true},
|
||||
{FiletypeUserDefinedF4, "UserDefinedF4", "", "", "ProDOS user defined file type F4", "", true},
|
||||
{FiletypeUserDefinedF5, "UserDefinedF5", "", "", "ProDOS user defined file type F5", "", true},
|
||||
{FiletypeUserDefinedF6, "UserDefinedF6", "", "", "ProDOS user defined file type F6", "", true},
|
||||
{FiletypeUserDefinedF7, "UserDefinedF7", "", "", "ProDOS user defined file type F7", "", true},
|
||||
{FiletypeUserDefinedF8, "UserDefinedF8", "", "", "ProDOS user defined file type F8", "", true},
|
||||
{FiletypeIntegerBASIC, "IntegerBASIC", "I", "INT", "Integer BASIC program file", "", false},
|
||||
{FiletypeIntegerBASICVariables, "IntegerBASICVariables", "", "IVR", "Integer BASIC variables file", "", false},
|
||||
{FiletypeApplesoftBASIC, "ApplesoftBASIC", "A", "BAS", "Applesoft BASIC program file", "", false},
|
||||
{FiletypeApplesoftBASICVariables, "ApplesoftBASICVariables", "", "VAR", "Applesoft BASIC variables file", "", false},
|
||||
{FiletypeRelocatable, "Relocatable", "R", "REL", "EDASM relocatable object module file", "", false},
|
||||
{FiletypeSystem, "System", "", "SYS", "System file", "", false},
|
||||
{FiletypeS, "S", "", "S", `DOS 3.3 Type "S"`, "", false},
|
||||
{FiletypeNewA, "NewA", "", "A", `DOS 3.3 Type "new A"`, "", false},
|
||||
{FiletypeNewB, "NewB", "", "B", `DOS 3.3 Type "new B"`, "", false},
|
||||
}
|
||||
|
||||
var filetypeInfosMap map[Filetype]filetypeInfo
|
||||
var filetypeNames []string
|
||||
var filetypeNamesExtras []string
|
||||
|
||||
func init() {
|
||||
sosReserved := []Filetype{0x0D, 0x0E, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}
|
||||
@ -123,45 +125,54 @@ func init() {
|
||||
for _, typ := range sosReserved {
|
||||
info := filetypeInfo{
|
||||
Type: typ,
|
||||
Name: fmt.Sprintf("SOSReserved%02X", typ),
|
||||
Name: fmt.Sprintf("SOSReserved%02X", int(typ)),
|
||||
ThreeLetter: "",
|
||||
OneLetter: "",
|
||||
Desc: fmt.Sprintf("SOS reserved for future use %02X", typ),
|
||||
Desc: fmt.Sprintf("SOS reserved for future use %02X", int(typ)),
|
||||
Extra: true,
|
||||
}
|
||||
filetypeInfos = append(filetypeInfos, info)
|
||||
}
|
||||
for _, typ := range prodosReserved {
|
||||
info := filetypeInfo{
|
||||
Type: typ,
|
||||
Name: fmt.Sprintf("ProDOSReserved%02X", typ),
|
||||
Name: fmt.Sprintf("ProDOSReserved%02X", int(typ)),
|
||||
ThreeLetter: "",
|
||||
OneLetter: "",
|
||||
Desc: fmt.Sprintf("ProDOS reserved for future use %02X", typ),
|
||||
Desc: fmt.Sprintf("ProDOS reserved for future use %02X", int(typ)),
|
||||
Extra: true,
|
||||
}
|
||||
filetypeInfos = append(filetypeInfos, info)
|
||||
}
|
||||
|
||||
seen := map[string]bool{}
|
||||
filetypeInfosMap = make(map[Filetype]filetypeInfo, len(filetypeInfos))
|
||||
for i, info := range filetypeInfos {
|
||||
info.Stringified = info.Desc + " (" + info.Name
|
||||
if info.ThreeLetter != "" {
|
||||
if info.ThreeLetter != "" && !seen[info.ThreeLetter] {
|
||||
info.Stringified += "|" + info.ThreeLetter
|
||||
seen[info.ThreeLetter] = true
|
||||
}
|
||||
if info.OneLetter != "" {
|
||||
if info.OneLetter != "" && info.OneLetter != info.Name && !seen[info.OneLetter] {
|
||||
info.Stringified += "|" + info.OneLetter
|
||||
seen[info.OneLetter] = true
|
||||
}
|
||||
info.Stringified += ")"
|
||||
|
||||
filetypeInfos[i] = info
|
||||
filetypeInfosMap[info.Type] = info
|
||||
filetypeNamesExtras = append(filetypeNamesExtras, info.Stringified)
|
||||
if !info.Extra {
|
||||
filetypeNames = append(filetypeNames, info.Stringified)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f Filetype) String() string {
|
||||
if info, found := filetypeInfosMap[f]; found {
|
||||
return info.Stringified
|
||||
}
|
||||
return fmt.Sprintf("Invalid/unknown filetype %02X", f)
|
||||
return fmt.Sprintf("Invalid/unknown filetype %02X", int(f))
|
||||
}
|
||||
|
||||
// FiletypeForName returns the filetype for a full, three-letter, or
|
||||
@ -176,6 +187,9 @@ func FiletypeForName(name string) (Filetype, error) {
|
||||
}
|
||||
|
||||
// FiletypeNames returns a list of all filetype names.
|
||||
func FiletypeNames() []string {
|
||||
func FiletypeNames(all bool) []string {
|
||||
if all {
|
||||
return filetypeNamesExtras
|
||||
}
|
||||
return filetypeNames
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ type Operator interface {
|
||||
// PutFile writes a file by name. If the file exists and overwrite
|
||||
// is false, it returns with an error. Otherwise it returns true if
|
||||
// an existing file was overwritten.
|
||||
PutFile(filename string, fileInfo FileInfo, overwrite bool) (existed bool, err error)
|
||||
PutFile(fileInfo FileInfo, overwrite bool) (existed bool, err error)
|
||||
}
|
||||
|
||||
// FileInfo represents a file descriptor plus the content.
|
||||
|
@ -374,9 +374,9 @@ func (fd FileDesc) descriptor() disk.Descriptor {
|
||||
case FiletypeRelocatable: // RELOCATABLE object module file
|
||||
desc.Type = disk.FiletypeRelocatable
|
||||
case FiletypeA: // A type file
|
||||
desc.Type = disk.FiletypeA
|
||||
desc.Type = disk.FiletypeNewA
|
||||
case FiletypeB: // B type file
|
||||
desc.Type = disk.FiletypeB
|
||||
desc.Type = disk.FiletypeNewB
|
||||
}
|
||||
return desc
|
||||
}
|
||||
@ -660,7 +660,7 @@ func (o operator) Delete(filename string) (bool, error) {
|
||||
// PutFile writes a file by name. If the file exists and overwrite
|
||||
// is false, it returns with an error. Otherwise it returns true if
|
||||
// an existing file was overwritten.
|
||||
func (o operator) PutFile(filename string, fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
|
||||
func (o operator) PutFile(fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
|
||||
return false, fmt.Errorf("%s does not implement PutFile yet", operatorName)
|
||||
}
|
||||
|
||||
|
@ -662,7 +662,7 @@ func (o operator) Delete(filename string) (bool, error) {
|
||||
// PutFile writes a file by name. If the file exists and overwrite
|
||||
// is false, it returns with an error. Otherwise it returns true if
|
||||
// an existing file was overwritten.
|
||||
func (o operator) PutFile(filename string, fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
|
||||
func (o operator) PutFile(fileInfo disk.FileInfo, overwrite bool) (existed bool, err error) {
|
||||
if fileInfo.Descriptor.Type != disk.FiletypeBinary {
|
||||
return false, fmt.Errorf("%s: only binary file type supported", operatorName)
|
||||
}
|
||||
@ -670,7 +670,7 @@ func (o operator) PutFile(filename string, fileInfo disk.FileInfo, overwrite boo
|
||||
return false, fmt.Errorf("mismatch between FileInfo.Descriptor.Length (%d) and actual length of FileInfo.Data field (%d)", fileInfo.Descriptor.Length, len(fileInfo.Data))
|
||||
}
|
||||
|
||||
numFile, namedFile, symbol, err := o.st.FilesForCompoundName(filename)
|
||||
numFile, namedFile, symbol, err := o.st.FilesForCompoundName(fileInfo.Descriptor.Name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user