feat: initial goget release — modern IPv6-first download utility
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
//go:build linux || freebsd
|
||||
// +build linux freebsd
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NetrcEntry holds credentials for a single machine entry in .netrc.
|
||||
type NetrcEntry struct {
|
||||
Machine string
|
||||
Login string
|
||||
Password string
|
||||
}
|
||||
|
||||
// LoadNetrc reads ~/.netrc and returns entries keyed by machine name.
|
||||
func LoadNetrc() (map[string]*NetrcEntry, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
path := filepath.Join(home, ".netrc")
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
entries := make(map[string]*NetrcEntry)
|
||||
var current *NetrcEntry
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
// Skip comments and empty lines
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
fields := strings.Fields(line)
|
||||
|
||||
// "default" is also valid but we treat it as a machine
|
||||
if len(fields) >= 2 && (fields[0] == "machine" || fields[0] == "default") {
|
||||
if current != nil && current.Machine != "" {
|
||||
entries[current.Machine] = current
|
||||
}
|
||||
name := fields[1]
|
||||
if fields[0] == "default" {
|
||||
name = "default"
|
||||
}
|
||||
current = &NetrcEntry{Machine: name}
|
||||
// Rest of line may have login/password
|
||||
parseNetrcLine(fields[2:], current)
|
||||
} else if current != nil {
|
||||
parseNetrcLine(fields, current)
|
||||
}
|
||||
}
|
||||
if current != nil && current.Machine != "" {
|
||||
entries[current.Machine] = current
|
||||
}
|
||||
|
||||
return entries, scanner.Err()
|
||||
}
|
||||
|
||||
func parseNetrcLine(fields []string, entry *NetrcEntry) {
|
||||
for i := 0; i < len(fields); i++ {
|
||||
switch fields[i] {
|
||||
case "login":
|
||||
if i+1 < len(fields) {
|
||||
entry.Login = fields[i+1]
|
||||
i++
|
||||
}
|
||||
case "password":
|
||||
if i+1 < len(fields) {
|
||||
entry.Password = fields[i+1]
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LookupNetrc returns credentials from .netrc for a given hostname.
|
||||
func LookupNetrc(host string) (login, password string, found bool) {
|
||||
entries, err := LoadNetrc()
|
||||
if err != nil || entries == nil {
|
||||
return "", "", false
|
||||
}
|
||||
// Exact match first
|
||||
if e, ok := entries[host]; ok {
|
||||
return e.Login, e.Password, true
|
||||
}
|
||||
// Default entry
|
||||
if e, ok := entries["default"]; ok {
|
||||
return e.Login, e.Password, true
|
||||
}
|
||||
return "", "", false
|
||||
}
|
||||
Reference in New Issue
Block a user