Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / cmd / auth / netrcauth / netrcauth.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // netrcauth uses a .netrc file (or _netrc file on Windows) to implement the
6 // GOAUTH protocol described in https://golang.org/issue/26232.
7 // It expects the location of the file as the first command-line argument.
8 //
9 // Example GOAUTH usage:
10 //      export GOAUTH="netrcauth $HOME/.netrc"
11 //
12 // See https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html
13 // or run 'man 5 netrc' for a description of the .netrc file format.
14 package main
15
16 import (
17         "fmt"
18         "io/ioutil"
19         "log"
20         "net/http"
21         "net/url"
22         "os"
23         "strings"
24 )
25
26 func main() {
27         if len(os.Args) < 2 {
28                 fmt.Fprintf(os.Stderr, "usage: %s NETRCFILE [URL]", os.Args[0])
29                 os.Exit(2)
30         }
31
32         log.SetPrefix("netrcauth: ")
33
34         if len(os.Args) != 2 {
35                 // An explicit URL was passed on the command line, but netrcauth does not
36                 // have any URL-specific output: it dumps the entire .netrc file at the
37                 // first call.
38                 return
39         }
40
41         path := os.Args[1]
42
43         data, err := ioutil.ReadFile(path)
44         if err != nil {
45                 if os.IsNotExist(err) {
46                         return
47                 }
48                 log.Fatalf("failed to read %s: %v\n", path, err)
49         }
50
51         u := &url.URL{Scheme: "https"}
52         lines := parseNetrc(string(data))
53         for _, l := range lines {
54                 u.Host = l.machine
55                 fmt.Printf("%s\n\n", u)
56
57                 req := &http.Request{Header: make(http.Header)}
58                 req.SetBasicAuth(l.login, l.password)
59                 req.Header.Write(os.Stdout)
60                 fmt.Println()
61         }
62 }
63
64 // The following functions were extracted from src/cmd/go/internal/web2/web.go
65 // as of https://golang.org/cl/161698.
66
67 type netrcLine struct {
68         machine  string
69         login    string
70         password string
71 }
72
73 func parseNetrc(data string) []netrcLine {
74         // See https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html
75         // for documentation on the .netrc format.
76         var nrc []netrcLine
77         var l netrcLine
78         inMacro := false
79         for _, line := range strings.Split(data, "\n") {
80                 if inMacro {
81                         if line == "" {
82                                 inMacro = false
83                         }
84                         continue
85                 }
86
87                 f := strings.Fields(line)
88                 i := 0
89                 for ; i < len(f)-1; i += 2 {
90                         // Reset at each "machine" token.
91                         // “The auto-login process searches the .netrc file for a machine token
92                         // that matches […]. Once a match is made, the subsequent .netrc tokens
93                         // are processed, stopping when the end of file is reached or another
94                         // machine or a default token is encountered.”
95                         switch f[i] {
96                         case "machine":
97                                 l = netrcLine{machine: f[i+1]}
98                         case "default":
99                                 break
100                         case "login":
101                                 l.login = f[i+1]
102                         case "password":
103                                 l.password = f[i+1]
104                         case "macdef":
105                                 // “A macro is defined with the specified name; its contents begin with
106                                 // the next .netrc line and continue until a null line (consecutive
107                                 // new-line characters) is encountered.”
108                                 inMacro = true
109                         }
110                         if l.machine != "" && l.login != "" && l.password != "" {
111                                 nrc = append(nrc, l)
112                                 l = netrcLine{}
113                         }
114                 }
115
116                 if i < len(f) && f[i] == "default" {
117                         // “There can be only one default token, and it must be after all machine tokens.”
118                         break
119                 }
120         }
121
122         return nrc
123 }