@@ -41,6 +41,29 @@ var keywords = map[string]int{
4141 "#" : tkComment ,
4242}
4343
44+ type Netrc struct {
45+ pre string
46+ tokens []* token
47+ machines []* Machine
48+ macros Macros
49+ }
50+
51+ func (n * Netrc ) FindMachine (name string ) (* Machine , error ) {
52+ var def * Machine
53+ for _ , m := range n .machines {
54+ if m .Name == name {
55+ return m , nil
56+ }
57+ if m .Name == "" {
58+ def = m
59+ }
60+ }
61+ if def == nil {
62+ return nil , errors .New ("no machine found" )
63+ }
64+ return def , nil
65+ }
66+
4467// Machine contains information about a remote machine.
4568type Machine struct {
4669 Name string
@@ -158,11 +181,11 @@ func getToken(b []byte, pos int) ([]byte, *token, error) {
158181 return b , t , nil
159182}
160183
161- func parse (r io.Reader , pos int ) ([] * Machine , Macros , error ) {
184+ func parse (r io.Reader , pos int ) (* Netrc , error ) {
162185 // TODO(fhs): Clear memory containing password.
163186 b , err := ioutil .ReadAll (r )
164187 if err != nil {
165- return nil , nil , err
188+ return nil , err
166189 }
167190
168191 mach := make ([]* Machine , 0 , 20 )
@@ -173,7 +196,7 @@ func parse(r io.Reader, pos int) ([]*Machine, Macros, error) {
173196 for {
174197 b , t , err = getToken (b , pos )
175198 if err != nil {
176- return nil , nil , err
199+ return nil , err
177200 }
178201 if t == nil {
179202 break
@@ -183,7 +206,7 @@ func parse(r io.Reader, pos int) ([]*Machine, Macros, error) {
183206 mac [t .macroName ] = t .value
184207 case tkDefault :
185208 if defaultSeen {
186- return nil , nil , & Error {pos , "multiple default token" }
209+ return nil , & Error {pos , "multiple default token" }
187210 }
188211 if m != nil {
189212 mach , m = append (mach , m ), nil
@@ -193,7 +216,7 @@ func parse(r io.Reader, pos int) ([]*Machine, Macros, error) {
193216 defaultSeen = true
194217 case tkMachine :
195218 if defaultSeen {
196- return nil , nil , & Error {pos , errBadDefaultOrder }
219+ return nil , & Error {pos , errBadDefaultOrder }
197220 }
198221 if m != nil {
199222 mach , m = append (mach , m ), nil
@@ -202,34 +225,34 @@ func parse(r io.Reader, pos int) ([]*Machine, Macros, error) {
202225 m .Name = t .value
203226 case tkLogin :
204227 if m == nil || m .Login != "" {
205- return nil , nil , & Error {pos , "unexpected token login " }
228+ return nil , & Error {pos , "unexpected token login " }
206229 }
207230 m .Login = t .value
208231 case tkPassword :
209232 if m == nil || m .Password != "" {
210- return nil , nil , & Error {pos , "unexpected token password" }
233+ return nil , & Error {pos , "unexpected token password" }
211234 }
212235 m .Password = t .value
213236 case tkAccount :
214237 if m == nil || m .Account != "" {
215- return nil , nil , & Error {pos , "unexpected token account" }
238+ return nil , & Error {pos , "unexpected token account" }
216239 }
217240 m .Account = t .value
218241 }
219242 }
220243 if m != nil {
221244 mach , m = append (mach , m ), nil
222245 }
223- return mach , mac , nil
246+ return & Netrc { machines : mach , macros : mac } , nil
224247}
225248
226249// ParseFile opens the file at filename and then passes its io.Reader to
227250// Parse().
228- func ParseFile (filename string ) ([] * Machine , Macros , error ) {
251+ func ParseFile (filename string ) (* Netrc , error ) {
229252 // TODO(fhs): Check if file is readable by anyone besides the user if there is password in it.
230253 fd , err := os .Open (filename )
231254 if err != nil {
232- return nil , nil , err
255+ return nil , err
233256 }
234257 defer fd .Close ()
235258 return Parse (fd )
@@ -241,29 +264,17 @@ func ParseFile(filename string) ([]*Machine, Macros, error) {
241264// by an empty machine name. There can be only one ``default'' machine.
242265//
243266// If there is a parsing error, an Error is returned.
244- func Parse (r io.Reader ) ([] * Machine , Macros , error ) {
267+ func Parse (r io.Reader ) (* Netrc , error ) {
245268 return parse (r , 1 )
246269}
247270
248271// FindMachine parses the netrc file identified by filename and returns
249272// the Machine named by name. If no Machine with name name is found, the
250273// ``default'' machine is returned.
251274func FindMachine (filename , name string ) (* Machine , error ) {
252- mach , _ , err := ParseFile (filename )
275+ n , err := ParseFile (filename )
253276 if err != nil {
254277 return nil , err
255278 }
256- var def * Machine
257- for _ , m := range mach {
258- if m .Name == name {
259- return m , nil
260- }
261- if m .Name == "" {
262- def = m
263- }
264- }
265- if def == nil {
266- return nil , errors .New ("no machine found" )
267- }
268- return def , nil
279+ return n .FindMachine (name )
269280}
0 commit comments