func (c *ConfigFile) SaveFile() (err error) {
	if exists, err := PassConfigExists(); err != nil {
		log.Fatalf("Could not find config file: %s", err.Error())
	} else {
		if !exists {
			log.Fatalf("pass config could not be found: %s", err.Error())
		}
	}
	cBytes, err := json.MarshalIndent(c, "", "\t")
	if err != nil {
		log.Fatalf("Could not marshal config file: %s", err.Error())
	}
	path, err := GetConfigPath()
	if err != nil {
		log.Fatalf("Could not get config file path: %s", err.Error())
	}
	err = ioutil.WriteFile(path, cBytes, 0666)
	return
}
SaveFile is used by ConfigFiles to update the secman config.
package pio
import (
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"os/user"
	"path/filepath"
	"github.com/atotto/clipboard"
	"golang.org/x/crypto/ssh/terminal"
)
const (
	SECDIR = "SECDIR"
	ConfigFileName = "config"
	SiteFileName = "sites.json"
	EncryptedFileDir = "files"
)
var (
	MasterPassPrompt = "Enter master password"
)
type PassFile interface {
	SaveFile() (err error)
}
type ConfigFile struct {
	MasterKeyPrivSealed []byte
	PubKeyHmac          []byte
	SiteHmac            []byte
	MasterPubKey        [32]byte
	MasterPassKeySalt   [32]byte
	HmacSalt            [32]byte
	SiteHmacSalt        [32]byte
}
type SiteInfo struct {
	PubKey     [32]byte
	PassSealed []byte
	Name       string
	FileName   string
	IsFile     bool
}
type SiteFile []SiteInfo
func PassFileDirExists() (bool, error) {
	d, err := GetEncryptedFilesDir()
	if err != nil {
		return false, err
	}
	dirInfo, err := os.Stat(d)
	if err == nil {
		if dirInfo.IsDir() {
			return true, nil
		}
	} else {
		if os.IsNotExist(err) {
			return false, nil
		}
	}
	return false, err
}
func PassDirExists() (bool, error) {
	d, err := GetPassDir()
	if err != nil {
		return false, err
	}
	dirInfo, err := os.Stat(d)
	if err == nil {
		if !dirInfo.IsDir() {
			return true, nil
		}
	} else {
		if os.IsNotExist(err) {
			return false, nil
		}
	}
	return false, err
}
func PassConfigExists() (bool, error) {
	c, err := GetConfigPath()
	if err != nil {
		return false, err
	}
	_, err = os.Stat(c)
	if err != nil {
		return false, err
	}
	return true, nil
}
func SitesVaultExists() (bool, error) {
	c, err := GetConfigPath()
	if err != nil {
		return false, err
	}
	sitesFilePath := filepath.Join(c, SiteFileName)
	_, err = os.Stat(sitesFilePath)
	if err != nil {
		return false, err
	}
	return true, nil
}
func GetHomeDir() (d string, err error) {
	usr, err := user.Current()
	if err == nil {
		d = usr.HomeDir
	}
	return
}
func GetPassDir() (d string, err error) {
	d, ok := os.LookupEnv(SECDIR)
	if !ok {
		home, err := GetHomeDir()
		if err == nil {
			d = filepath.Join(home, ".secman")
		}
	}
	return
}
func GetConfigPath() (p string, err error) {
	d, err := GetPassDir()
	if err == nil {
		p = filepath.Join(d, ConfigFileName)
	}
	return
}
func GetEncryptedFilesDir() (p string, err error) {
	d, err := GetPassDir()
	if err == nil {
		p = filepath.Join(d, EncryptedFileDir)
	}
	return
}
func GetSitesFile() (d string, err error) {
	p, err := GetPassDir()
	if err == nil {
		d = filepath.Join(p, SiteFileName)
	}
	return
}
func (s *SiteInfo) AddFile(fileBytes []byte, filename string) error {
	encFileDir, err := GetEncryptedFilesDir()
	if err != nil {
		return err
	}
	fileDirExists, err := PassFileDirExists()
	if err != nil {
		return err
	}
	if !fileDirExists {
		err = os.Mkdir(encFileDir, 0700)
		if err != nil {
			log.Fatalf("Could not create secman encrypted file dir: %s", err.Error())
		}
	}
	encFilePath := filepath.Join(encFileDir, filename)
	dir, _ := filepath.Split(encFilePath)
	err = os.MkdirAll(dir, 0700)
	if err != nil {
		log.Fatalf("Could not create subdirectory: %s", err.Error())
	}
	err = ioutil.WriteFile(encFilePath, fileBytes, 0666)
	if err != nil {
		return err
	}
	return s.AddSite()
}
func (s *SiteInfo) AddSite() (err error) {
	siteFile := GetVault()
	for _, si := range siteFile {
		if s.Name == si.Name {
			return errors.New("Could not add site with duplicate name")
		}
	}
	siteFile = append(siteFile, *s)
	return UpdateVault(siteFile)
}
func GetVault() (s SiteFile) {
	si, err := GetSitesFile()
	if err != nil {
		log.Fatalf("Could not get pass dir: %s", err.Error())
	}
	siteFileContents, err := ioutil.ReadFile(si)
	if err != nil {
		if os.IsNotExist(err) {
			log.Fatalf("Could not open site file. Run secman init.: %s", err.Error())
		}
		log.Fatalf("Could not read site file: %s", err.Error())
	}
	err = json.Unmarshal(siteFileContents, &s)
	if err != nil {
		log.Fatalf("Could not unmarshal site info: %s", err.Error())
	}
	return
}
func GetSiteFileBytes() (b []byte) {
	si, err := GetSitesFile()
	if err != nil {
		log.Fatalf("Could not get pass dir: %s", err.Error())
	}
	f, err := os.OpenFile(si, os.O_RDWR, 0600)
	if err != nil {
		log.Fatalf("Could not open site file: %s", err.Error())
	}
	defer f.Close()
	b, err = ioutil.ReadAll(f)
	if err != nil {
		log.Fatalf("Could not read site file: %s", err.Error())
	}
	return
}
func UpdateVault(s SiteFile) (err error) {
	si, err := GetSitesFile()
	if err != nil {
		log.Fatalf("Could not get pass dir: %s", err.Error())
	}
	siteFileContents, err := json.MarshalIndent(s, "", "\t")
	if err != nil {
		log.Fatalf("Could not marshal site info: %s", err.Error())
	}
	err = ioutil.WriteFile(si, siteFileContents, 0666)
	return
}