package commands import ( "fmt" "io" "os" "path/filepath" ) type UploadFileArgs struct { Command string `json:"command"` LocalFilepath string `json:"local_filepath"` DestinationFilepath string `json:"destination_filepath"` PrivateKeyFile string `json:"private_key_file"` Username string `json:"username"` Host string `json:"host"` } func (ufa *UploadFileArgs) ReadArgs() { if len(os.Args) != 7 { fmt.Fprintf(os.Stderr, "Usage: %s upload_file \n", os.Args[0]) os.Exit(1) } ufa.Command = os.Args[1] ufa.LocalFilepath = os.Args[2] ufa.DestinationFilepath = os.Args[3] ufa.PrivateKeyFile = os.Args[4] ufa.Username = os.Args[5] ufa.Host = os.Args[6] } func UploadFile(args UploadFileArgs, stdout, stderr io.Writer) error { client, err := GetClient(args.PrivateKeyFile, args.Username, args.Host) if err != nil { return err } defer client.Close() session, err := client.NewSession() if err != nil { return fmt.Errorf("error creating SSH session: %w", err) } defer session.Close() source_file, err := os.Open(args.LocalFilepath) if err != nil { return fmt.Errorf("error opening local file: %w", err) } defer source_file.Close() info, err := source_file.Stat() if err != nil { return fmt.Errorf("error stating local file: %w", err) } w, err := session.StdinPipe() if err != nil { return fmt.Errorf("error creating stdin pipe: %w", err) } if err := session.Start("scp -t " + args.DestinationFilepath); err != nil { return fmt.Errorf("error starting scp: %w", err) } fmt.Fprintf(w, "C0644 %d %s\n", info.Size(), filepath.Base(args.LocalFilepath)) if _, err := io.Copy(w, source_file); err != nil { return fmt.Errorf("error sending file: %w", err) } fmt.Fprint(w, "\x00") w.Close() if err := session.Wait(); err != nil { return fmt.Errorf("error during scp transfer: %w", err) } fmt.Fprintln(stdout, "Success") return nil }