From 8e822c39f82ec548d81641f7ffe191b90f395f0f Mon Sep 17 00:00:00 2001 From: Felicitas Pojtinger Date: Fri, 19 Nov 2021 14:42:13 +0100 Subject: [PATCH] feat: Add `eject` cmd --- cmd/stbak/cmd/eject.go | 36 ++++++++++++++++++++++++++++++++++++ cmd/stbak/cmd/tell.go | 2 +- pkg/controllers/tape.go | 18 ++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 cmd/stbak/cmd/eject.go diff --git a/cmd/stbak/cmd/eject.go b/cmd/stbak/cmd/eject.go new file mode 100644 index 0000000..3c13159 --- /dev/null +++ b/cmd/stbak/cmd/eject.go @@ -0,0 +1,36 @@ +package cmd + +import ( + "os" + + "github.com/pojntfx/stfs/pkg/controllers" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ejectCmd = &cobra.Command{ + Use: "eject", + Aliases: []string{"e"}, + Short: "Eject the tape (tape only)", + RunE: func(cmd *cobra.Command, args []string) error { + if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil { + return err + } + + f, err := os.OpenFile(viper.GetString(tapeFlag), os.O_RDONLY, os.ModeCharDevice) + if err != nil { + panic(err) + } + defer f.Close() + + return controllers.EjectTape(f) + }, +} + +func init() { + ejectCmd.PersistentFlags().StringP(tapeFlag, "t", "/dev/nst0", "Tape drive to get the current record from") + + viper.AutomaticEnv() + + rootCmd.AddCommand(ejectCmd) +} diff --git a/cmd/stbak/cmd/tell.go b/cmd/stbak/cmd/tell.go index 24d7e00..b05544a 100644 --- a/cmd/stbak/cmd/tell.go +++ b/cmd/stbak/cmd/tell.go @@ -11,7 +11,7 @@ import ( var tellCmd = &cobra.Command{ Use: "tell", - Aliases: []string{"tell"}, + Aliases: []string{"t"}, Short: "Get the current record (tape only)", RunE: func(cmd *cobra.Command, args []string) error { if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil { diff --git a/pkg/controllers/tape.go b/pkg/controllers/tape.go index af58c50..b029234 100644 --- a/pkg/controllers/tape.go +++ b/pkg/controllers/tape.go @@ -12,6 +12,7 @@ const ( mtioCtop = 0x40086d01 // Do magnetic tape operation mtFsf = 1 // Forward space over FileMark, position at first record of next file + mtOffl = 7 // Rewind and put the drive offline (eject?) mtEom = 12 // Goto end of recorded media (for appending files) mtSeek = 22 // Seek to block @@ -96,3 +97,20 @@ func SeekToRecordOnTape(f *os.File, record int32) error { return nil } + +func EjectTape(f *os.File) error { + if _, _, err := syscall.Syscall( + syscall.SYS_IOCTL, + f.Fd(), + mtioCtop, + uintptr(unsafe.Pointer( + &operation{ + op: mtOffl, + }, + )), + ); err != 0 { + return err + } + + return nil +}