forked from TrueCloudLab/restic
68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package sftp
|
|
|
|
import (
|
|
"errors"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// Config collects all information required to connect to an sftp server.
|
|
type Config struct {
|
|
User, Host, Dir string
|
|
}
|
|
|
|
// ParseConfig extracts all information for the sftp connection from the string s.
|
|
func ParseConfig(s string) (interface{}, error) {
|
|
if strings.HasPrefix(s, "sftp://") {
|
|
return parseFormat1(s)
|
|
}
|
|
|
|
// otherwise parse in the sftp:user@host:path format, which means we'll get
|
|
// "user@host:path" in s
|
|
return parseFormat2(s)
|
|
}
|
|
|
|
// parseFormat1 parses the first format, starting with a slash, so the user
|
|
// either specified "sftp://host/path", so we'll get everything after the first
|
|
// colon character
|
|
func parseFormat1(s string) (Config, error) {
|
|
url, err := url.Parse(s)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
cfg := Config{
|
|
Host: url.Host,
|
|
Dir: url.Path[1:],
|
|
}
|
|
if url.User != nil {
|
|
cfg.User = url.User.Username()
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
// parseFormat2 parses the second format, sftp:user@host:path
|
|
func parseFormat2(s string) (cfg Config, err error) {
|
|
// split user/host and path at the second colon
|
|
data := strings.SplitN(s, ":", 3)
|
|
if len(data) < 3 {
|
|
return Config{}, errors.New("sftp: invalid format, hostname or path not found")
|
|
}
|
|
|
|
if data[0] != "sftp" {
|
|
return Config{}, errors.New(`invalid format, does not start with "sftp:"`)
|
|
}
|
|
|
|
userhost := data[1]
|
|
cfg.Dir = data[2]
|
|
|
|
data = strings.SplitN(userhost, "@", 2)
|
|
if len(data) == 2 {
|
|
cfg.User = data[0]
|
|
cfg.Host = data[1]
|
|
} else {
|
|
cfg.Host = userhost
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|