@ -1,6 +1,7 @@
package ssh
import (
"bufio"
"bytes"
"code.google.com/p/go.crypto/ssh"
"errors"
@ -106,12 +107,6 @@ func (c *comm) Upload(path string, input io.Reader) error {
return err
}
// Set stderr/stdout to a bytes buffer
stderr := new ( bytes . Buffer )
stdout := new ( bytes . Buffer )
session . Stderr = stderr
session . Stdout = stdout
// We only want to close once, so we nil w after we close it,
// and only close in the defer if it hasn't been closed already.
defer func ( ) {
@ -120,6 +115,17 @@ func (c *comm) Upload(path string, input io.Reader) error {
}
} ( )
// Get a pipe to stdout so that we can get responses back
scp_reader , err := session . StdoutPipe ( )
if err != nil {
return err
}
r := bufio . NewReader ( scp_reader )
// Set stderr to a bytes buffer
stderr := new ( bytes . Buffer )
session . Stderr = stderr
// The target directory and file for talking the SCP protocol
target_dir := filepath . Dir ( path )
target_file := filepath . Base ( path )
@ -143,8 +149,17 @@ func (c *comm) Upload(path string, input io.Reader) error {
// Start the protocol
log . Println ( "Beginning file upload..." )
fmt . Fprintln ( w , "C0644" , input_memory . Len ( ) , target_file )
err = check_response ( r )
if err != nil {
return err
}
io . Copy ( w , input_memory )
fmt . Fprint ( w , "\x00" )
err = check_response ( r )
if err != nil {
return err
}
// TODO(mitchellh): Each step above results in a 0/1/2 being sent by
// the remote side to confirm. We should check for those confirmations.
@ -178,7 +193,6 @@ func (c *comm) Upload(path string, input io.Reader) error {
return err
}
log . Printf ( "scp stdout (length %d): %#v" , stdout . Len ( ) , stdout . Bytes ( ) )
log . Printf ( "scp stderr (length %d): %s" , stderr . Len ( ) , stderr . String ( ) )
return nil
@ -223,3 +237,17 @@ func (c *comm) reconnect() (err error) {
return
}
func check_response ( r * bufio . Reader ) ( err error ) {
scp_status_code , err := r . ReadByte ( )
if err != nil {
return err
}
if scp_status_code != 0 {
// Treat any non-zero (really 1 and 2) as fatal errors
error_message , _ , err := r . ReadLine ( )
err = fmt . Errorf ( string ( error_message [ : ] ) )
return err
}
return nil
}