From be46b0d6b29a16f1a5dd9ae08a63069ac7626a12 Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Tue, 13 Aug 2024 20:21:11 -0400 Subject: [PATCH] Fix init if devices directory does not exist/is empty --- core/configParser.go | 12 ++++++++---- core/init.go | 10 ++++++++-- core/utilitiesMisc.go | 3 +-- libmuttonserver.go | 4 +++- sync/init.go | 13 +++++-------- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/core/configParser.go b/core/configParser.go index 2ab583f..2b07ecb 100644 --- a/core/configParser.go +++ b/core/configParser.go @@ -51,13 +51,17 @@ func ParseConfig(valuesRequested [][2]string, missingValueError string) []string } // GenDeviceIDList returns a pointer to a slice of all registered device IDs. -// Requires: errorOnFail (set to true to throw an error if the device ID list cannot be generated) +// Requires: errorOnFail (set to true to throw an error if the devices directory cannot be read/does not exist) func GenDeviceIDList(errorOnFail bool) *[]fs.DirEntry { // create a slice of all registered devices deviceIDList, err := os.ReadDir(ConfigDir + PathSeparator + "devices") - if err != nil && errorOnFail { - fmt.Println(AnsiError+"Failed to read the devices directory:", err.Error()+AnsiReset) - os.Exit(101) + if err != nil { + if errorOnFail { + fmt.Println(AnsiError+"Failed to read the devices directory:", err.Error()+AnsiReset) + os.Exit(101) + } else { + return nil // a nil return value indicates that the devices directory could not be read/does not exist + } } return &deviceIDList } diff --git a/core/init.go b/core/init.go index f445381..3f3f662 100644 --- a/core/init.go +++ b/core/init.go @@ -53,7 +53,7 @@ func GpgKeyGen() string { } // DirInit creates the libmutton directories. -// Returns: oldDeviceID (from before the directory reset). +// Returns: oldDeviceID (from before the directory reset; will be sync.FSMisc if there is no pre-existing ID). func DirInit(preserveOldConfigDir bool) string { // create EntryRoot err := os.MkdirAll(EntryRoot, 0700) @@ -63,7 +63,13 @@ func DirInit(preserveOldConfigDir bool) string { } // get old device ID before its potential removal - oldDeviceID := (*GenDeviceIDList(false))[0].Name() // errorOnFail set to false to ignore error if device ID directory does not exist (error non-critical for this function) + oldDeviceIDList := GenDeviceIDList(false) // errorOnFail is false so that nil is received when the devices directory does not exist + var oldDeviceID string + if oldDeviceIDList != nil && len(*oldDeviceIDList) > 0 { // ensure not derferencing nil, which occurs when the devices directory does not exist + oldDeviceID = (*oldDeviceIDList)[0].Name() + } else { + oldDeviceID = "\u259f" // sync.FSMisc cannot be used directly due to import cycle; indicates to server that no device ID is being replaced + } // remove existing config directory (if it exists and not in append mode) if !preserveOldConfigDir { diff --git a/core/utilitiesMisc.go b/core/utilitiesMisc.go index c391f51..60b8b56 100644 --- a/core/utilitiesMisc.go +++ b/core/utilitiesMisc.go @@ -20,9 +20,8 @@ func TargetIsFile(targetLocation string, errorOnFail bool, failCondition uint8) if errorOnFail { fmt.Println(AnsiError + "Failed to access \"" + targetLocation + "\" - Ensure it exists and has the correct permissions" + AnsiReset) os.Exit(105) - } else { - return false, false } + return false, false } if targetInfo.IsDir() { if errorOnFail && failCondition == 2 { diff --git a/libmuttonserver.go b/libmuttonserver.go index 0e7cc59..0ca829d 100644 --- a/libmuttonserver.go +++ b/libmuttonserver.go @@ -59,7 +59,9 @@ func main() { // stdin[1] is expected to be the old device ID (for removal) fileToClose, _ := os.OpenFile(core.ConfigDir+core.PathSeparator+"devices"+core.PathSeparator+stdin[0], os.O_CREATE|os.O_WRONLY, 0600) // errors ignored; failure unlikely to occur if init was successful; "register" is not a user-facing argument and thus the error would not be visible _ = fileToClose.Close() - _ = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + stdin[1]) + if stdin[1] != sync.FSMisc { // sync.FSMisc is used to indicate that no device ID is being replaced + _ = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + stdin[1]) + } // print EntryRoot and bool indicating OS type to stdout for client to store in config fmt.Print(core.EntryRoot + sync.FSSpace + strconv.FormatBool(core.IsWindows)) case "init": diff --git a/sync/init.go b/sync/init.go index f3e77d8..2c7ad0f 100644 --- a/sync/init.go +++ b/sync/init.go @@ -9,7 +9,6 @@ import ( "time" "github.com/rwinkhart/libmutton/core" - "golang.org/x/crypto/ssh" ) // DeviceIDGen generates a new client device ID and registers it with the server (will replace existing one). @@ -34,14 +33,12 @@ func DeviceIDGen(oldDeviceID string) (string, string) { // also removes the old device ID file (remotely) // manualSync is true so the user is alerted if device ID registration fails sshClient, _, _ := GetSSHClient(true) - defer func(sshClient *ssh.Client) { - err = sshClient.Close() - if err != nil { - fmt.Println(core.AnsiError+"Init failed - Unable to close SSH client:", err.Error()+core.AnsiReset) - os.Exit(104) - } - }(sshClient) sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput(sshClient, "libmuttonserver register", newDeviceID+"\n"+oldDeviceID), FSSpace) + err = sshClient.Close() + if err != nil { + fmt.Println(core.AnsiError+"Init failed - Unable to close SSH client:", err.Error()+core.AnsiReset) + os.Exit(104) + } // remove old device ID file (locally; may not exist) err = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + oldDeviceID)