2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  sftp  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-15 07:58:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-21 17:46:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-23 14:21:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/restic/restic/internal/errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/restic/restic/internal/options" 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Config collects all information required to connect to an sftp server.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Config  struct  {  
						 
					
						
							
								
									
										
										
										
											2020-02-19 15:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									User ,  Host ,  Port ,  Path  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Layout   string  ` option:"layout" help:"use this backend directory layout (default: auto-detect)" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Command  string  ` option:"command" help:"specify command to create sftp connection" ` 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-07 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Connections  uint  ` option:"connections" help:"set a limit for the number of concurrent connections (default: 5)" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewConfig returns a new config with default options applied.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewConfig ( )  Config  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  Config { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Connections :  5 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 23:55:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  init ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									options . Register ( "sftp" ,  Config { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-15 07:58:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ParseConfig parses the string s and extracts the sftp config. The  
						 
					
						
							
								
									
										
										
										
											2020-02-19 15:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// supported configuration formats are sftp://user@host[:port]/directory  
						 
					
						
							
								
									
										
										
										
											2017-03-25 09:06:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  and sftp:user@host:directory.  The directory will be path Cleaned and can  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  be an absolute path if it starts with a '/' (e.g.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  sftp://user@host//absolute and sftp:user@host:/absolute).  
						 
					
						
							
								
									
										
										
										
											2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ParseConfig ( s  string )  ( interface { } ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-02-19 15:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  user ,  host ,  port ,  dir  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-15 07:58:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  strings . HasPrefix ( s ,  "sftp://" ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// parse the "sftp://user@host/path" url format 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										url ,  err  :=  url . Parse ( s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-29 21:54:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  errors . Wrap ( err ,  "url.Parse" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-15 07:58:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  url . User  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											user  =  url . User . Username ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-19 15:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										host  =  url . Hostname ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										port  =  url . Port ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-28 12:02:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dir  =  url . Path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dir  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-21 17:48:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  errors . Errorf ( "invalid backend %q, no directory specified" ,  s ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-28 12:02:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dir  =  dir [ 1 : ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-15 07:58:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  strings . HasPrefix ( s ,  "sftp:" ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// parse the sftp:user@host:path format, which means we'll get 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// "user@host:path" in s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  =  s [ 5 : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// split user@host and path at the colon 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										data  :=  strings . SplitN ( s ,  ":" ,  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( data )  <  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . New ( "sftp: invalid format, hostname or path not found" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										host  =  data [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dir  =  data [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// split user and host at the "@" 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-26 12:23:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										data  =  strings . SplitN ( host ,  "@" ,  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( data )  ==  3  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											user  =  data [ 0 ]  +  "@"  +  data [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											host  =  data [ 2 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  len ( data )  ==  2  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-15 07:58:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											user  =  data [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											host  =  data [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . New ( ` invalid format, does not start with "sftp:" ` ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-30 10:34:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p  :=  path . Clean ( dir ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  strings . HasPrefix ( p ,  "~" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Fatal ( "sftp path starts with the tilde (~) character, that fails for most sftp servers.\nUse a relative directory, most servers interpret this as relative to the user's home directory." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-07 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg  :=  NewConfig ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . User  =  user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . Host  =  host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . Port  =  port 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg . Path  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cfg ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-28 15:51:24 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}