123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package main
- import (
- "fmt"
- "os"
- "strings"
- "regexp"
- "bufio"
- "strconv"
- "path/filepath"
- )
- const (
- CONFIG_DIRECTORY_DEFAULT string = "~/.config/strlstloltest/it/can/do/more/nesting/"
- CONFIG_FILENAME_DEFAULT string = "strlst"
- CONFIG_EXAMPLE string = `# this is an example configuration with a semantic placeholder in each field
- # lines beginning with a number sign are comments
- # %s is used as a (necessary) placeholder for the url
- url_fmt=https://%s/path/to/files/
- # accessible ip or domain of webserver
- url=somewhere.someplace
- # SSH information is used for file transfer purposes
- ssh_port=22
- ssh_user=strlst
- # path to the identity file for automatic transfer
- ssh_identity_path=~/.ssh/copyservice_rsa
- # destination directory on the remote host
- scp_directory=~/example/target/directory
- secret=examplesecrettobekeptsafe
- `
- )
- type Configuration struct {
- // specifies where to look, and what HTTP structure to insert url in
- url_fmt, url string
- // ssh information used for copy service, specifies port to use
- // and identity file
- ssh_user, ssh_identity_path, scp_directory string
- ssh_port int
- // specifies encryption secret
- secret string
- }
- func GetHomeDir() string {
- // query home directory
- home, err := os.UserHomeDir()
- if err != nil {
- fmt.Fprintf(os.Stderr, "fatal error: user home directory could not be determined\n")
- os.Exit(EXIT_HOME_INVALID)
- }
- return home
- }
- func GetConfigDefaultPath() string {
- return filepath.Join(GetHomeDir(), ".config", "strlst", "strlst")
- }
- func ConfigurationToString(config *Configuration, obfuscate_secret bool) string {
- secret := "***"
- if !obfuscate_secret {
- secret = config.secret
- }
- return fmt.Sprintf(
- "configuration { url_fmt = %s, url = %s, ssh_user = %s, ssh_user = %v, ssh_identity_path = %s, scp_directory = %s, secret = %s }",
- config.url_fmt,
- config.url,
- config.ssh_user,
- config.ssh_port,
- config.ssh_identity_path,
- config.scp_directory,
- secret,
- )
- }
- func GetConfiguration(program *string, path *string) Configuration {
- config := Configuration { ssh_port: -1 }
- // open file for reading
- configuration_file, err := os.Open(*path)
- // if file does not exist
- if os.IsNotExist(err) {
- fmt.Fprintf(os.Stderr, "%s: specified configuration file does not exist\n", *program)
- os.Exit(EXIT_SPECIFIED_PATH_INVALID)
- }
- defer configuration_file.Close()
- // process configuration file line for line
- matchers := [...](*regexp.Regexp) {
- regexp.MustCompile("^#.*$"),
- regexp.MustCompile("^url_fmt *= *([^ ].*)$"),
- regexp.MustCompile("^url *= *([^ ].*)$"),
- regexp.MustCompile("^ssh_user *= *([^ ].*)$"),
- regexp.MustCompile("^ssh_port *= *([0-9]+)$"),
- regexp.MustCompile("^ssh_identity_path *= *([^ ].*)$"),
- regexp.MustCompile("^scp_directory *= *([^ ].*)$"),
- regexp.MustCompile("^secret *= *([^ ].*)$"),
- }
- // create scanner to iterate file contents
- scanner := bufio.NewScanner(configuration_file)
- // iterate file contents
- for scanner.Scan() {
- line := scanner.Text()
- // match line against matchers to parse contents
- for index, matcher := range matchers {
- if matcher.MatchString(line) {
- // comment, skip
- if index == 0 { continue }
- // find submatch (singular) for anything that isn't a comment
- submatches := matchers[index].FindAllStringSubmatch(line, 1)
- if len(submatches) < 1 || len(submatches[0]) < 2 {
- fmt.Fprintf(os.Stderr, "%s: error matching at line: %s\n", *program, line)
- continue
- }
- submatch := submatches[0][1]
- // ugly solution, maybe use maps instead
- switch index {
- case 1: config.url_fmt = submatch
- case 2: config.url = submatch
- case 3: config.ssh_user = submatch
- case 4:
- value, err := strconv.Atoi(submatch)
- if err != nil {
- fmt.Fprintf(os.Stderr, "%s: error parsing port %s\n", *program, submatch)
- os.Exit(EXIT_CONFIG_INVALID)
- }
- config.ssh_port = value
- case 5: config.ssh_identity_path = submatch
- case 6: config.scp_directory = submatch
- case 7: config.secret = submatch
- }
- break
- }
- }
- }
- return config
- }
- func IsConfigurationValid(config *Configuration) bool {
- // very basic validation
- return strings.Contains(config.url_fmt, "http") &&
- strings.Contains(config.url, ".") &&
- config.ssh_user != "" &&
- config.ssh_port > 0 &&
- strings.Contains(config.ssh_identity_path, "/") &&
- strings.Contains(config.scp_directory, "/") &&
- config.secret != ""
- }
|