package commands import ( "fmt" "os" "path" "git.cheetah.cat/cheetah/moto-flash-data/flashpart" "git.cheetah.cat/cheetah/moto-flash-data/s19" "github.com/rs/zerolog/log" ) type S19IsolateAllPartitionsCommand struct { FileName string `long:"file" short:"f" required:"true" description:"s19 filename"` } func (command *S19IsolateAllPartitionsCommand) Execute(args []string) error { log.Info().Str("fileName", command.FileName).Msg("S19-Isolate") s19File, err := s19.NewS19Reader(command.FileName) if err != nil { return err } defer s19File.Close() log.Info().Int64("fileSize", s19File.OsSize).Msg("Reading file...") // records, err := s19File.ReadAllRecords() if err != nil { return err } records = records[1:] // skip first ?? ranges := s19File.DetectAddressRanges(records) // err = os.MkdirAll(path.Join("s19-dump", path.Base(command.FileName)), 0700) if err != nil { return err } for index, segment := range ranges { log.Info().Msg( fmt.Sprintf("Index: %d, Start: 0x%08X, End: 0x%08X, Size: %d bytes, Slice: %d-%d", index, segment.StartAddress, segment.EndAddress, segment.Size, segment.SliceStart, segment.SliceEnd, ), ) // fpHeader := flashpart.ParseFlashPartHeader(records[segment.SliceStart].Data) log.Info().Msg( fmt.Sprintf("Index: %d, Media-ID: 0x%02X, Partition Size: 0x%08X / %d bytes, Partition Tag: %s", index, fpHeader.MediaID, fpHeader.TotalSize, fpHeader.TotalSize, fpHeader.VersionText, ), ) // if fpHeader.TotalSize == 0 { // log.Warn().Msg("cannot extract a partition thats empty") // continue // } // { outMBarFile, err := os.Create(path.Join("s19-dump", path.Base(command.FileName), fmt.Sprintf("part%d.mpar", index))) if err != nil { return err } defer outMBarFile.Close() for _, record := range records[segment.SliceStart : segment.SliceEnd+1] { outMBarFile.Write(record.Data) } // if we have more than just the partition header, write a convenient bin file if segment.SliceStart+1 < segment.SliceEnd { outBinFile, err := os.Create(path.Join("s19-dump", path.Base(command.FileName), fmt.Sprintf("part%d.bin", index))) if err != nil { return err } defer outBinFile.Close() for _, record := range records[segment.SliceStart+1 : segment.SliceEnd+1] { outBinFile.Write(record.Data) } } } } return nil }