aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/jackc/pgx/pgpass.go
blob: b6f028d272b0a597c8bb897e778708fb11380c2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package pgx

import (
	"bufio"
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strings"
)

func parsepgpass(cfg *ConnConfig, line string) *string {
	const (
		backslash = "\r"
		colon     = "\n"
	)
	const (
		host int = iota
		port
		database
		username
		pw
	)
	line = strings.Replace(line, `\:`, colon, -1)
	line = strings.Replace(line, `\\`, backslash, -1)
	parts := strings.Split(line, `:`)
	if len(parts) != 5 {
		return nil
	}
	for i := range parts {
		if parts[i] == `*` {
			continue
		}
		parts[i] = strings.Replace(strings.Replace(parts[i], backslash, `\`, -1), colon, `:`, -1)
		switch i {
		case host:
			if parts[i] != cfg.Host {
				return nil
			}
		case port:
			portstr := fmt.Sprintf(`%v`, cfg.Port)
			if portstr == "0" {
				portstr = "5432"
			}
			if parts[i] != portstr {
				return nil
			}
		case database:
			if parts[i] != cfg.Database {
				return nil
			}
		case username:
			if parts[i] != cfg.User {
				return nil
			}
		}
	}
	return &parts[4]
}

func pgpass(cfg *ConnConfig) (found bool) {
	passfile := os.Getenv("PGPASSFILE")
	if passfile == "" {
		u, err := user.Current()
		if err != nil {
			return
		}
		passfile = filepath.Join(u.HomeDir, ".pgpass")
	}
	f, err := os.Open(passfile)
	if err != nil {
		return
	}
	defer f.Close()
	scanner := bufio.NewScanner(f)
	var pw *string
	for scanner.Scan() {
		pw = parsepgpass(cfg, scanner.Text())
		if pw != nil {
			cfg.Password = *pw
			return true
		}
	}
	return false
}