123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- package config
- import (
- "fmt"
- "log"
- "os/exec"
- "strconv"
- "strings"
- "github.com/BurntSushi/toml"
- )
- // maybeInt is an integer that may be nil
- type maybeInt struct {
- int
- bool
- }
- func (m maybeInt) empty() bool {
- return !m.bool
- }
- func (m maybeInt) value() int {
- return m.int
- }
- func initMaybeInt(value int) maybeInt {
- return maybeInt{value, true}
- }
- func (m *maybeInt) UnmarshalText(text []byte) error {
- var err error
- var i int64
- if text != nil {
- str := string(text)
- i, err = strconv.ParseInt(str, 10, 64)
- m.int = int(i)
- m.bool = true
- }
- return err
- }
- type fileConfig struct {
- Default string `toml:"default_account"`
- MailboxPath string `toml:"mailbox_path"`
- Accounts []account `toml:"account"`
- DefaultMessages maybeInt `toml:"default_messages"`
- }
- type account struct {
- Name string `toml:"name"`
- MailboxPath string `toml:"mailbox_path"`
- ConnectionInfo *connectionInfo `toml:"connection"`
- ExcludedFolders []string `toml:"excluded_folders"`
- Messages maybeInt `toml:"messages"`
- }
- type connectionInfo struct {
- Host string `toml:"hostname"`
- Port int `toml:"port"`
- Username string `toml:"username"`
- PasswordExec *ShellScript `toml:"password_exec"`
- PasswordFile string `toml:"password_file"`
- Password string `toml:"password"`
- }
- func (c *connectionInfo) String() string {
- var res string
- res += "{"
- res += fmt.Sprintf("Host: %s, ", c.Host)
- res += fmt.Sprintf("Port: %d, ", c.Port)
- res += fmt.Sprintf("Username: %s, ", c.Username)
- res += fmt.Sprintf("Password: **********, ")
- res += fmt.Sprintf("PasswordFile: %s, ", c.PasswordFile)
- res += fmt.Sprintf("PasswordExec: %s}", c.PasswordExec)
- return res
- }
- // ShellScript might be either:
- // - the path to an executable
- // - an executable in path
- // - a shell command with its argument
- // all these must return on stdout the password after successful execution.
- type ShellScript struct {
- Executable string
- }
- func (s *ShellScript) UnmarshalText(text []byte) error {
- s.Executable = string(text)
- return nil
- }
- func (s *ShellScript) String() string {
- return s.Executable
- }
- // Present indicates if the value has been filled in into the config
- func (s *ShellScript) Present() bool {
- if s != nil {
- return s.Executable != ""
- }
- return false
- }
- // Run tries to execute the command, first looking for a corresponding executable and
- // invoking it, then invoking the string as a command followed by its parameters.
- func (s *ShellScript) Run() (string, error) {
- if path, err := exec.LookPath(s.Executable); err == nil {
- return doExec(path)
- }
- parts := strings.Split(s.Executable, " ")
- return doExec(parts[0], parts[1:]...)
- }
- func doExec(path string, args ...string) (string, error) {
- cmd := exec.Command(path, args...)
- out, err := cmd.Output()
- if err != nil {
- log.Println("Error running:", cmd)
- return "", err
- }
- return string(out), nil
- }
- // parseFile reads the given config file and, if succeeding, returns a *FileConfig.
- func parseFile(path string) (*fileConfig, error) {
- newConfig := fileConfig{}
- _, err := toml.DecodeFile(path, &newConfig)
- return &newConfig, err
- }
|