| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-01 22:17:37 +02:00
										 |  |  | 	"restic/errors" | 
					
						
							| 
									
										
										
										
											2017-04-13 23:55:32 +02:00
										 |  |  | 	"restic/options" | 
					
						
							| 
									
										
										
										
											2015-12-28 15:51:24 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Config collects all information required to connect to an sftp server. | 
					
						
							|  |  |  | type Config struct { | 
					
						
							| 
									
										
										
										
											2017-04-10 22:41:06 +02:00
										 |  |  | 	User, Host, Path string | 
					
						
							| 
									
										
										
										
											2017-04-13 23:55:32 +02:00
										 |  |  | 	Layout           string `option:"layout" help:"use this backend directory layout (default: auto-detect)"` | 
					
						
							|  |  |  | 	Command          string `option:"command" help:"specify command to create sftp connection"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  | // supported configuration formats are sftp://user@host/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) { | 
					
						
							| 
									
										
										
										
											2016-02-15 07:58:13 -08:00
										 |  |  | 	var user, host, dir string | 
					
						
							|  |  |  | 	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() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		host = url.Host | 
					
						
							| 
									
										
										
										
											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 "@" | 
					
						
							|  |  |  | 		data = strings.SplitN(host, "@", 2) | 
					
						
							|  |  |  | 		if len(data) == 2 { | 
					
						
							|  |  |  | 			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
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-02-15 07:58:13 -08:00
										 |  |  | 	return Config{ | 
					
						
							|  |  |  | 		User: user, | 
					
						
							|  |  |  | 		Host: host, | 
					
						
							| 
									
										
										
										
											2017-04-10 22:41:06 +02:00
										 |  |  | 		Path: path.Clean(dir), | 
					
						
							| 
									
										
										
										
											2016-02-15 07:58:13 -08:00
										 |  |  | 	}, nil | 
					
						
							| 
									
										
										
										
											2015-12-28 15:51:24 +01:00
										 |  |  | } |