Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #117 #118

Merged
merged 2 commits into from
Feb 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ Get a released version on: https://github.com/moul/advanced-ssh-config/releases

### master (unreleased)

* Fix: Allow `$(...)` syntax in the `ResolveCommand` function ([#117](https://github.com/moul/advanced-ssh-config/issues/117))
* Printing the error of a failing `ResolveCommand` ([#117](https://github.com/moul/advanced-ssh-config/issues/117))
* Fix: `Gateways` field is no longer ignored when the `HostName` field is present ([#102](https://github.com/moul/advanced-ssh-config/issues/102))
* Ignore SIGHUP, close goroutines and export written bytes ([#112](https://github.com/moul/advanced-ssh-config/pull/112)) ([@QuentinPerez](https://github.com/QuentinPerez))
* Various documentation improvements ([@ashmatadeen](https://github.com/ashmatadeen), [@loliee](https://github.com/loliee), [@cerisier](https://github.com/cerisier))
Expand Down
12 changes: 9 additions & 3 deletions pkg/commands/proxy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package commands

import (
"bytes"
"fmt"
"io"
"net"
Expand Down Expand Up @@ -178,12 +179,17 @@ func hostPrepare(host *config.Host) error {
return err
}

out, err := exec.Command(args[0], args[1:]...).Output()
if err != nil {
cmd := exec.Command(args[0], args[1:]...)
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
Logger.Errorf("ResolveCommand failed: %s", stderr.String())
return err
}

host.HostName = strings.TrimSpace(fmt.Sprintf("%s", out))
host.HostName = strings.TrimSpace(fmt.Sprintf("%s", stdout.String()))
Logger.Debugf("Resolved host is: %s", host.HostName)
}
return nil
Expand Down
51 changes: 51 additions & 0 deletions pkg/config/imported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This file contains imported functions
// The license and copyright is reported for each functions in the comments.

package config

// Imported and unmodified from https://golang.org/src/os/env.go
// Function under the BSD-License - Copyrighted by the Go Authors
// isShellSpecialVar reports whether the character identifies a special
// shell variable such as $*.
func isShellSpecialVar(c uint8) bool {
switch c {
case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return true
}
return false
}

// Imported and unmodified from https://golang.org/src/os/env.go
// Function under the BSD-License - Copyrighted by the Go Authors
// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
func isAlphaNum(c uint8) bool {
return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
}

// Imported and unmodified from https://golang.org/src/os/env.go
// Function under the BSD-License - Copyrighted by the Go Authors
// getShellName returns the name that begins the string and the number of bytes
// consumed to extract it. If the name is enclosed in {}, it's part of a ${}
// expansion and two more bytes are needed than the length of the name.
func getShellName(s string) (string, int) {
switch {
case s[0] == '{':
if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
return s[1:2], 3
}
// Scan to closing brace
for i := 1; i < len(s); i++ {
if s[i] == '}' {
return s[1:i], i + 1
}
}
return "", 1 // Bad syntax; just eat the brace.
case isShellSpecialVar(s[0]):
return s[0:1], 1
}
// Scan alphanumerics.
var i int
for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
}
return s[:i], i
}
24 changes: 22 additions & 2 deletions pkg/config/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,29 @@ func GetHomeDir() string {
return ""
}

// ExpandEnvSafe replaces ${var} or $var in the string according to the values
// of the current environment variables.
// As opposed to os.ExpandEnv, ExpandEnvSafe won't remove the dollar in '$(...)'
// See https://golang.org/src/os/env.go?s=963:994#L22 for the original function
func ExpandEnvSafe(s string) string {
buf := make([]byte, 0, 2*len(s))
i := 0
for j := 0; j < len(s); j++ {
// the following line is the only one changing
if s[j] == '$' && j+1 < len(s) && s[j+1] != '(' {
buf = append(buf, s[i:j]...)
name, w := getShellName(s[j+1:])
buf = append(buf, os.Getenv(name)...)
j += w
i = j + 1
}
}
return string(buf) + s[i:]
}

func expandUser(path string) (string, error) {
// Expand variables
path = os.ExpandEnv(path)
path = ExpandEnvSafe(path)

if path[:2] == "~/" {
homeDir := GetHomeDir()
Expand All @@ -37,5 +57,5 @@ func expandField(input string) string {
if input == "" {
return ""
}
return os.ExpandEnv(input)
return ExpandEnvSafe(input)
}