// LoadFiles will try to glob the pattern and load each matching entries func (c *Config) LoadFiles(pattern string) error { // Resolve '~' and '$HOME' expandedPattern, err := utils.ExpandUser(pattern) if err != nil { return err } // Globbing filepaths, err := filepath.Glob(expandedPattern) if err != nil { return err } // Load files iteratively for _, filepath := range filepaths { if err := c.LoadFile(filepath); err != nil { Logger.Warnf("Cannot include %q: %v", filepath, err) } } if c.ASSHBinaryPath != "" { path, err := utils.ExpandUser(c.ASSHBinaryPath) if err != nil { return err } asshBinaryPath = path } return nil }
func translateControlPath(input string) string { controlPath, err := utils.ExpandUser(input) if err != nil { return input } controlPath = strings.Replace(controlPath, "%h", "**/*", -1) for _, component := range []string{"%L", "%p", "%n", "%C", "%l", "%r"} { controlPath = strings.Replace(controlPath, component, "*", -1) } return controlPath }
// SaveSSHConfig saves the configuration to ~/.ssh/config func (c *Config) SaveSSHConfig() error { if c.sshConfigPath == "" { return fmt.Errorf("no Config.sshConfigPath configured") } filepath, err := utils.ExpandUser(c.sshConfigPath) if err != nil { return err } file, err := os.Create(filepath) if err != nil { return err } defer file.Close() Logger.Debugf("Writing SSH config file to %q", filepath) return c.WriteSSHConfigTo(file) }
// SaveNewKnownHost registers the target as a new known host and save the full known hosts list on disk func (c *Config) SaveNewKnownHost(target string) { c.addKnownHost(target) path, err := utils.ExpandUser(c.ASSHKnownHostFile) if err != nil { Logger.Errorf("Cannot append host %q, unknown ASSH known_hosts file: %v", target, err) } file, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660) if err != nil { Logger.Errorf("Cannot append host %q to %q (performance degradation): %v", target, c.ASSHKnownHostFile, err) return } fmt.Fprintln(file, target) file.Close() }
// LoadFile loads the content of a configuration file in the Config object func (c *Config) LoadFile(filename string) error { beforeHostsCount := len(c.Hosts) // Resolve '~' and '$HOME' filepath, err := utils.ExpandUser(filename) if err != nil { return err } // Anti-loop protection if _, ok := c.includedFiles[filepath]; ok { return nil } c.includedFiles[filepath] = false Logger.Debugf("Loading config file '%s'", filepath) // Read file source, err := os.Open(filepath) if err != nil { return err } // Load config stream err = c.LoadConfig(source) if err != nil { return err } // Successful loading c.includedFiles[filepath] = true afterHostsCount := len(c.Hosts) diffHostsCount := afterHostsCount - beforeHostsCount Logger.Debugf("Loaded config file '%s' (%d + %d => %d hosts)", filepath, beforeHostsCount, afterHostsCount, diffHostsCount) // Handling includes for _, include := range c.Includes { if err = c.LoadFiles(include); err != nil { return err } } return nil }
// LoadKnownHosts loads known hosts list from disk func (c *Config) LoadKnownHosts() error { path, err := utils.ExpandUser(c.ASSHKnownHostFile) if err != nil { return err } file, err := os.Open(path) if err != nil { return err } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { c.addKnownHost(scanner.Text()) } return scanner.Err() }
// isSSHConfigOutdated returns true if assh.yml or an included file has a // modification date more recent than .ssh/config func (c *Config) isSSHConfigOutdated() (bool, error) { filepath, err := utils.ExpandUser(c.sshConfigPath) if err != nil { return false, err } sshConfigStat, err := os.Stat(filepath) if err != nil { return false, err } sshConfigModTime := sshConfigStat.ModTime() for filepath := range c.includedFiles { asshConfigStat, err := os.Stat(filepath) if err != nil { return false, err } if asshConfigStat.ModTime().After(sshConfigModTime) { return true, nil } } return false, nil }