toggledlog: assume command of color handling
We want to use colored error messages also outside of main, so let's handle it in the logging package. The fatal logger now automatically prints red.
This commit is contained in:
parent
c89455063c
commit
09e88f31d1
|
@ -16,9 +16,6 @@ const (
|
||||||
exitCode = 9
|
exitCode = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO
|
|
||||||
var colorReset, colorRed string
|
|
||||||
|
|
||||||
// Once() tries to get a password from the user, either from the terminal,
|
// Once() tries to get a password from the user, either from the terminal,
|
||||||
// extpass or stdin.
|
// extpass or stdin.
|
||||||
func Once(extpass string) string {
|
func Once(extpass string) string {
|
||||||
|
@ -43,7 +40,7 @@ func Twice(extpass string) string {
|
||||||
p1 := readPasswordTerminal("Password: ")
|
p1 := readPasswordTerminal("Password: ")
|
||||||
p2 := readPasswordTerminal("Repeat: ")
|
p2 := readPasswordTerminal("Repeat: ")
|
||||||
if p1 != p2 {
|
if p1 != p2 {
|
||||||
toggledlog.Fatal.Println(colorRed + "Passwords do not match" + colorReset)
|
toggledlog.Fatal.Println("Passwords do not match")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
return p1
|
return p1
|
||||||
|
@ -57,12 +54,12 @@ func readPasswordTerminal(prompt string) string {
|
||||||
// terminal.ReadPassword removes the trailing newline
|
// terminal.ReadPassword removes the trailing newline
|
||||||
p, err := terminal.ReadPassword(fd)
|
p, err := terminal.ReadPassword(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Could not read password from terminal: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Could not read password from terminal: %v\n", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "\n")
|
fmt.Fprintf(os.Stderr, "\n")
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
toggledlog.Fatal.Println(colorRed + "Password is empty" + colorReset)
|
toggledlog.Fatal.Println("Password is empty")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
return string(p)
|
return string(p)
|
||||||
|
@ -75,7 +72,7 @@ func readPasswordStdin() string {
|
||||||
p := readLineUnbuffered(os.Stdin)
|
p := readLineUnbuffered(os.Stdin)
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
fmt.Fprintf(os.Stderr, "FOOOOOO\n")
|
fmt.Fprintf(os.Stderr, "FOOOOOO\n")
|
||||||
toggledlog.Fatal.Println(colorRed + "Got empty password from stdin" + colorReset)
|
toggledlog.Fatal.Println("Got empty password from stdin")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
|
@ -91,19 +88,19 @@ func readPasswordExtpass(extpass string) string {
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
pipe, err := cmd.StdoutPipe()
|
pipe, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"extpass pipe setup failed: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("extpass pipe setup failed: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
err = cmd.Start()
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"extpass cmd start failed: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("extpass cmd start failed: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
p := readLineUnbuffered(pipe)
|
p := readLineUnbuffered(pipe)
|
||||||
pipe.Close()
|
pipe.Close()
|
||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
toggledlog.Fatal.Println(colorRed + "extpass: password is empty" + colorReset)
|
toggledlog.Fatal.Println("extpass: password is empty")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
|
@ -119,7 +116,7 @@ func readLineUnbuffered(r io.Reader) (l string) {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"readLineUnbuffered: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("readLineUnbuffered: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -12,6 +14,10 @@ const (
|
||||||
wpanicMsg = "-wpanic turns this warning into a panic: "
|
wpanicMsg = "-wpanic turns this warning into a panic: "
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Escape sequences for terminal colors. These will be empty strings if stdout
|
||||||
|
// is not a terminal.
|
||||||
|
var ColorReset, ColorGrey, ColorRed, ColorGreen, ColorYellow string
|
||||||
|
|
||||||
func JSONDump(obj interface{}) string {
|
func JSONDump(obj interface{}) string {
|
||||||
b, err := json.MarshalIndent(obj, "", "\t")
|
b, err := json.MarshalIndent(obj, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,6 +33,10 @@ type toggledLogger struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
// Panic after logging a message, useful in regression tests
|
// Panic after logging a message, useful in regression tests
|
||||||
Wpanic bool
|
Wpanic bool
|
||||||
|
// Private prefix and postfix are used for coloring
|
||||||
|
prefix string
|
||||||
|
postfix string
|
||||||
|
|
||||||
*log.Logger
|
*log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +44,7 @@ func (l *toggledLogger) Printf(format string, v ...interface{}) {
|
||||||
if !l.Enabled {
|
if !l.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.Logger.Printf(format, v...)
|
l.Logger.Printf(l.prefix + fmt.Sprintf(format, v...) + l.postfix)
|
||||||
if l.Wpanic {
|
if l.Wpanic {
|
||||||
l.Logger.Panic(wpanicMsg + fmt.Sprintf(format, v...))
|
l.Logger.Panic(wpanicMsg + fmt.Sprintf(format, v...))
|
||||||
}
|
}
|
||||||
|
@ -43,9 +53,9 @@ func (l *toggledLogger) Println(v ...interface{}) {
|
||||||
if !l.Enabled {
|
if !l.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.Logger.Println(v...)
|
l.Logger.Println(l.prefix + fmt.Sprint(v...) + l.postfix)
|
||||||
if l.Wpanic {
|
if l.Wpanic {
|
||||||
l.Logger.Panic(wpanicMsg + fmt.Sprintln(v...))
|
l.Logger.Panic(wpanicMsg + fmt.Sprint(v...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +75,29 @@ var Warn *toggledLogger
|
||||||
var Fatal *toggledLogger
|
var Fatal *toggledLogger
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Debug = &toggledLogger{false, false, log.New(os.Stdout, "", 0)}
|
if terminal.IsTerminal(int(os.Stdout.Fd())) {
|
||||||
Info = &toggledLogger{true, false, log.New(os.Stdout, "", 0)}
|
ColorReset = "\033[0m"
|
||||||
Warn = &toggledLogger{true, false, log.New(os.Stderr, "", 0)}
|
ColorGrey = "\033[2m"
|
||||||
Fatal = &toggledLogger{true, false, log.New(os.Stderr, "", 0)}
|
ColorRed = "\033[31m"
|
||||||
|
ColorGreen = "\033[32m"
|
||||||
|
ColorYellow = "\033[33m"
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug = &toggledLogger{
|
||||||
|
Logger: log.New(os.Stdout, "", 0),
|
||||||
|
}
|
||||||
|
Info = &toggledLogger{
|
||||||
|
Enabled: true,
|
||||||
|
Logger: log.New(os.Stdout, "", 0),
|
||||||
|
}
|
||||||
|
Warn = &toggledLogger{
|
||||||
|
Enabled: true,
|
||||||
|
Logger: log.New(os.Stderr, "", 0),
|
||||||
|
}
|
||||||
|
Fatal = &toggledLogger{
|
||||||
|
Enabled: true,
|
||||||
|
Logger: log.New(os.Stderr, "", 0),
|
||||||
|
prefix: ColorRed,
|
||||||
|
postfix: ColorReset,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
48
main.go
48
main.go
|
@ -16,8 +16,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
|
|
||||||
"github.com/hanwen/go-fuse/fuse"
|
"github.com/hanwen/go-fuse/fuse"
|
||||||
"github.com/hanwen/go-fuse/fuse/nodefs"
|
"github.com/hanwen/go-fuse/fuse/nodefs"
|
||||||
"github.com/hanwen/go-fuse/fuse/pathfs"
|
"github.com/hanwen/go-fuse/fuse/pathfs"
|
||||||
|
@ -61,7 +59,7 @@ var GitVersionFuse = "[version not set - please compile using ./build.bash]"
|
||||||
func initDir(args *argContainer) {
|
func initDir(args *argContainer) {
|
||||||
err := checkDirEmpty(args.cipherdir)
|
err := checkDirEmpty(args.cipherdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf("Invalid cipherdir: %v\n", err)
|
toggledlog.Fatal.Printf("Invalid cipherdir: %v", err)
|
||||||
os.Exit(ERREXIT_INIT)
|
os.Exit(ERREXIT_INIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +86,7 @@ func initDir(args *argContainer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggledlog.Info.Printf(colorGreen + "The filesystem has been created successfully." + colorReset)
|
toggledlog.Info.Printf(toggledlog.ColorGreen + "The filesystem has been created successfully." + toggledlog.ColorReset)
|
||||||
wd, _ := os.Getwd()
|
wd, _ := os.Getwd()
|
||||||
friendlyPath, _ := filepath.Rel(wd, args.cipherdir)
|
friendlyPath, _ := filepath.Rel(wd, args.cipherdir)
|
||||||
if strings.HasPrefix(friendlyPath, "../") {
|
if strings.HasPrefix(friendlyPath, "../") {
|
||||||
|
@ -96,7 +94,7 @@ func initDir(args *argContainer) {
|
||||||
// keep the absolute path.
|
// keep the absolute path.
|
||||||
friendlyPath = args.cipherdir
|
friendlyPath = args.cipherdir
|
||||||
}
|
}
|
||||||
toggledlog.Info.Printf(colorGrey+"You can now mount it using: %s %s MOUNTPOINT"+colorReset,
|
toggledlog.Info.Printf(toggledlog.ColorGrey+"You can now mount it using: %s %s MOUNTPOINT"+toggledlog.ColorReset,
|
||||||
toggledlog.ProgramName, friendlyPath)
|
toggledlog.ProgramName, friendlyPath)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
@ -118,14 +116,14 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf
|
||||||
// Check if the file exists at all before prompting for a password
|
// Check if the file exists at all before prompting for a password
|
||||||
_, err := os.Stat(args.config)
|
_, err := os.Stat(args.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Config file not found: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Config file not found: %v", err)
|
||||||
os.Exit(ERREXIT_LOADCONF)
|
os.Exit(ERREXIT_LOADCONF)
|
||||||
}
|
}
|
||||||
pw := readpassword.Once(args.extpass)
|
pw := readpassword.Once(args.extpass)
|
||||||
toggledlog.Info.Println("Decrypting master key")
|
toggledlog.Info.Println("Decrypting master key")
|
||||||
masterkey, confFile, err = configfile.LoadConfFile(args.config, pw)
|
masterkey, confFile, err = configfile.LoadConfFile(args.config, pw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Println(colorRed + err.Error() + colorReset)
|
toggledlog.Fatal.Println(err.Error())
|
||||||
os.Exit(ERREXIT_LOADCONF)
|
os.Exit(ERREXIT_LOADCONF)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +156,6 @@ func main() {
|
||||||
runtime.GOMAXPROCS(4)
|
runtime.GOMAXPROCS(4)
|
||||||
var err error
|
var err error
|
||||||
var args argContainer
|
var args argContainer
|
||||||
setupColors()
|
|
||||||
|
|
||||||
// Parse command line arguments
|
// Parse command line arguments
|
||||||
var opensslAuto string
|
var opensslAuto string
|
||||||
|
@ -202,7 +199,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
args.openssl, err = strconv.ParseBool(opensslAuto)
|
args.openssl, err = strconv.ParseBool(opensslAuto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Invalid \"-openssl\" setting: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Invalid \"-openssl\" setting: %v", err)
|
||||||
os.Exit(ERREXIT_USAGE)
|
os.Exit(ERREXIT_USAGE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +226,7 @@ func main() {
|
||||||
args.cipherdir, _ = filepath.Abs(flagSet.Arg(0))
|
args.cipherdir, _ = filepath.Abs(flagSet.Arg(0))
|
||||||
err = checkDir(args.cipherdir)
|
err = checkDir(args.cipherdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Invalid cipherdir: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Invalid cipherdir: %v", err)
|
||||||
os.Exit(ERREXIT_CIPHERDIR)
|
os.Exit(ERREXIT_CIPHERDIR)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -244,7 +241,7 @@ func main() {
|
||||||
if args.config != "" {
|
if args.config != "" {
|
||||||
args.config, err = filepath.Abs(args.config)
|
args.config, err = filepath.Abs(args.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Invalid \"-config\" setting: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Invalid \"-config\" setting: %v", err)
|
||||||
os.Exit(ERREXIT_INIT)
|
os.Exit(ERREXIT_INIT)
|
||||||
}
|
}
|
||||||
toggledlog.Info.Printf("Using config file at custom location %s", args.config)
|
toggledlog.Info.Printf("Using config file at custom location %s", args.config)
|
||||||
|
@ -291,7 +288,7 @@ func main() {
|
||||||
// "-init"
|
// "-init"
|
||||||
if args.init {
|
if args.init {
|
||||||
if flagSet.NArg() > 1 {
|
if flagSet.NArg() > 1 {
|
||||||
toggledlog.Fatal.Printf("Usage: %s -init [OPTIONS] CIPHERDIR\n", toggledlog.ProgramName)
|
toggledlog.Fatal.Printf("Usage: %s -init [OPTIONS] CIPHERDIR", toggledlog.ProgramName)
|
||||||
os.Exit(ERREXIT_USAGE)
|
os.Exit(ERREXIT_USAGE)
|
||||||
}
|
}
|
||||||
initDir(&args) // does not return
|
initDir(&args) // does not return
|
||||||
|
@ -299,7 +296,7 @@ func main() {
|
||||||
// "-passwd"
|
// "-passwd"
|
||||||
if args.passwd {
|
if args.passwd {
|
||||||
if flagSet.NArg() > 1 {
|
if flagSet.NArg() > 1 {
|
||||||
toggledlog.Fatal.Printf("Usage: %s -passwd [OPTIONS] CIPHERDIR\n", toggledlog.ProgramName)
|
toggledlog.Fatal.Printf("Usage: %s -passwd [OPTIONS] CIPHERDIR", toggledlog.ProgramName)
|
||||||
os.Exit(ERREXIT_USAGE)
|
os.Exit(ERREXIT_USAGE)
|
||||||
}
|
}
|
||||||
changePassword(&args) // does not return
|
changePassword(&args) // does not return
|
||||||
|
@ -307,17 +304,17 @@ func main() {
|
||||||
// Mount
|
// Mount
|
||||||
// Check mountpoint
|
// Check mountpoint
|
||||||
if flagSet.NArg() != 2 {
|
if flagSet.NArg() != 2 {
|
||||||
toggledlog.Fatal.Printf("Usage: %s [OPTIONS] CIPHERDIR MOUNTPOINT\n", toggledlog.ProgramName)
|
toggledlog.Fatal.Printf("Usage: %s [OPTIONS] CIPHERDIR MOUNTPOINT", toggledlog.ProgramName)
|
||||||
os.Exit(ERREXIT_USAGE)
|
os.Exit(ERREXIT_USAGE)
|
||||||
}
|
}
|
||||||
args.mountpoint, err = filepath.Abs(flagSet.Arg(1))
|
args.mountpoint, err = filepath.Abs(flagSet.Arg(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Invalid mountpoint: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Invalid mountpoint: %v", err)
|
||||||
os.Exit(ERREXIT_MOUNTPOINT)
|
os.Exit(ERREXIT_MOUNTPOINT)
|
||||||
}
|
}
|
||||||
err = checkDirEmpty(args.mountpoint)
|
err = checkDirEmpty(args.mountpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toggledlog.Fatal.Printf(colorRed+"Invalid mountpoint: %v\n"+colorReset, err)
|
toggledlog.Fatal.Printf("Invalid mountpoint: %v", err)
|
||||||
os.Exit(ERREXIT_MOUNTPOINT)
|
os.Exit(ERREXIT_MOUNTPOINT)
|
||||||
}
|
}
|
||||||
// Get master key
|
// Get master key
|
||||||
|
@ -341,7 +338,7 @@ func main() {
|
||||||
// Initialize FUSE server
|
// Initialize FUSE server
|
||||||
toggledlog.Debug.Printf("cli args: %v", args)
|
toggledlog.Debug.Printf("cli args: %v", args)
|
||||||
srv := initFuseFrontend(masterkey, args, confFile)
|
srv := initFuseFrontend(masterkey, args, confFile)
|
||||||
toggledlog.Info.Println(colorGreen + "Filesystem mounted and ready." + colorReset)
|
toggledlog.Info.Println(toggledlog.ColorGreen + "Filesystem mounted and ready." + toggledlog.ColorReset)
|
||||||
// We are ready - send USR1 signal to our parent and switch to syslog
|
// We are ready - send USR1 signal to our parent and switch to syslog
|
||||||
if args.notifypid > 0 {
|
if args.notifypid > 0 {
|
||||||
sendUsr1(args.notifypid)
|
sendUsr1(args.notifypid)
|
||||||
|
@ -410,8 +407,8 @@ func initFuseFrontend(key []byte, args argContainer, confFile *configfile.ConfFi
|
||||||
var mOpts fuse.MountOptions
|
var mOpts fuse.MountOptions
|
||||||
mOpts.AllowOther = false
|
mOpts.AllowOther = false
|
||||||
if args.allow_other {
|
if args.allow_other {
|
||||||
toggledlog.Info.Printf(colorYellow + "The option \"-allow_other\" is set. Make sure the file " +
|
toggledlog.Info.Printf(toggledlog.ColorYellow + "The option \"-allow_other\" is set. Make sure the file " +
|
||||||
"permissions protect your data from unwanted access." + colorReset)
|
"permissions protect your data from unwanted access." + toggledlog.ColorReset)
|
||||||
mOpts.AllowOther = true
|
mOpts.AllowOther = true
|
||||||
// Make the kernel check the file permissions for us
|
// Make the kernel check the file permissions for us
|
||||||
mOpts.Options = append(mOpts.Options, "default_permissions")
|
mOpts.Options = append(mOpts.Options, "default_permissions")
|
||||||
|
@ -455,16 +452,3 @@ func handleSigint(srv *fuse.Server, mountpoint string) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Escape sequences for terminal colors
|
|
||||||
var colorReset, colorGrey, colorRed, colorGreen, colorYellow string
|
|
||||||
|
|
||||||
func setupColors() {
|
|
||||||
if terminal.IsTerminal(int(os.Stdout.Fd())) {
|
|
||||||
colorReset = "\033[0m"
|
|
||||||
colorGrey = "\033[2m"
|
|
||||||
colorRed = "\033[31m"
|
|
||||||
colorGreen = "\033[32m"
|
|
||||||
colorYellow = "\033[33m"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ If the gocryptfs.conf file becomes corrupted or you ever forget your password,
|
||||||
there is only one hope for recovery: The master key. Print it to a piece of
|
there is only one hope for recovery: The master key. Print it to a piece of
|
||||||
paper and store it in a drawer.
|
paper and store it in a drawer.
|
||||||
|
|
||||||
`, colorGrey+hChunked+colorReset)
|
`, toggledlog.ColorGrey+hChunked+toggledlog.ColorReset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseMasterKey - Parse a hex-encoded master key that was passed on the command line
|
// parseMasterKey - Parse a hex-encoded master key that was passed on the command line
|
||||||
|
|
Loading…
Reference in New Issue