-
Notifications
You must be signed in to change notification settings - Fork 2
/
pgpass.go
85 lines (82 loc) · 1.42 KB
/
pgpass.go
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
}